/** * intel_mid_i2s_flush - This is the I2S flush request * @drv_data : pointer on private i2s driver data (by i2s_open function) * * It will flush the TX FIFO * WARNING: this function is used in a Burst Mode context where it is called * between Bursts i.e. when there is no FMSYNC, no transfer ongoing at * that time * If you need a flush while SSP configured in I2S is BUSY and FMSYNC are * generated, you have to write another function * (loop on BUSY bit and do not limit the flush to at most 16 samples) * * Output parameters * int : number of samples flushed */ int intel_mid_i2s_flush(struct intel_mid_i2s_hdl *drv_data) { u32 sssr, data; u32 num = 0; void __iomem *reg; WARN(!drv_data, "Driver data=NULL\n"); if (!drv_data) return 0; reg = drv_data->ioaddr; sssr = read_SSSR(reg); dev_warn(&drv_data->pdev->dev, "in flush sssr=0x%08X\n", sssr); /* * Flush "by hand" was generating spurious DMA SERV REQUEST * from SSP to DMA => then buggy retrieval of data for next dma_req * Disable: RX Service Request from RX fifo to DMA * as we will flush by hand */ clear_SSCR1_reg(reg, RSRE); /* i2s_flush is called in between 2 bursts * => no FMSYNC at that time (i.e. SSP not busy) * => at most 16 samples in the FIFO */ while ((read_SSSR(reg) & (SSSR_RNE_MASK<<SSSR_RNE_SHIFT)) && (num < FIFO_SIZE)) { data = read_SSDR(reg); num++; } /* Enable: RX Service Request from RX fifo to DMA * as flush by hand is done */ set_SSCR1_reg(reg, RSRE); sssr = read_SSSR(reg); dev_dbg(&drv_data->pdev->dev, "out flush sssr=0x%08X\n", sssr); return num; }
static int u32_reader(struct driver_data *drv_data) { void __iomem *reg = drv_data->ioaddr; while ((read_SSSR(reg) & SSSR_RNE) && (drv_data->rx < drv_data->rx_end)) { *(u32 *)(drv_data->rx) = read_SSDR(reg); drv_data->rx += 4; } return drv_data->rx == drv_data->rx_end; }
static int null_reader(struct driver_data *drv_data) { void __iomem *reg = drv_data->ioaddr; u8 n_bytes = drv_data->n_bytes; while ((read_SSSR(reg) & SSSR_RNE) && (drv_data->rx < drv_data->rx_end)) { read_SSDR(reg); drv_data->rx += n_bytes; } return drv_data->rx == drv_data->rx_end; }
int pxa2xx_spi_flush(struct driver_data *drv_data) { unsigned long limit = loops_per_jiffy << 1; void __iomem *reg = drv_data->ioaddr; do { while (read_SSSR(reg) & SSSR_RNE) { read_SSDR(reg); } } while ((read_SSSR(reg) & SSSR_BSY) && --limit); write_SSSR_CS(drv_data, SSSR_ROR); return limit; }
static int flush(struct driver_data *drv_data) { unsigned long limit = loops_per_jiffy << 1; void __iomem *reg = drv_data->ioaddr; do { while (read_SSSR(reg) & SSSR_RNE) { read_SSDR(reg); } } while ((read_SSSR(reg) & SSSR_BSY) && limit--); write_SSSR(SSSR_ROR, reg); return limit; }