static int omap2_mcspi_set_rxfifo(const struct spi_device *spi, int buf_size, int enable, int bytes_per_wl ) { u32 l, rw, s; unsigned short revert = 0; struct spi_master *master = spi->master; struct omap2_mcspi *mcspi = spi_master_get_devdata(master); buf_size = buf_size/bytes_per_wl; // l = mcspi_read_cs_reg(spi, OMAP2_MCSPI_CHCONF0); l = mcspi_cached_chconf0(spi); s = mcspi_read_cs_reg(spi, OMAP2_MCSPI_CHCTRL0); if (enable == 1) { /* FIFO cannot be enabled for both TX and RX * simultaneously */ // if (l & OMAP2_MCSPI_CHCONF_FFET) // return -EPERM; /* Channel needs to be disabled and enabled * for FIFO setting to take affect */ if (s & OMAP2_MCSPI_CHCTRL_EN) { omap2_mcspi_set_enable(spi, 0); revert = 1; } if (buf_size < mcspi->fifo_depth) mcspi_write_reg(master, OMAP2_MCSPI_XFERLEVEL, ((buf_size << 16) | (buf_size - 1) << 8)); else mcspi_write_reg(master, OMAP2_MCSPI_XFERLEVEL, ((buf_size << 16) | //(mcspi->fifo_depth - 1) << 8)); ((mcspi->fifo_depth - 1) << 8) | ((mcspi->fifo_depth - 1) << 0) )); } rw = OMAP2_MCSPI_CHCONF_FFER; MOD_REG_BIT(l, rw, enable); // mcspi_write_cs_reg(spi, OMAP2_MCSPI_CHCONF0, l); mcspi_write_chconf0(spi,l); if (revert) omap2_mcspi_set_enable(spi, 1); return 0; }
static int omap2_mcspi_set_rxfifo(const struct spi_device *spi, int buf_size, int wl_bytes, int enable) { u32 l, rw, s, xfer_ael; unsigned short revert = 0; struct spi_master *master = spi->master; struct omap2_mcspi *mcspi = spi_master_get_devdata(master); u32 wcnt = buf_size/wl_bytes; l = mcspi_cached_chconf0(spi); s = mcspi_read_cs_reg(spi, OMAP2_MCSPI_CHCTRL0); /* Read settings for TX FIFO */ xfer_ael = mcspi_read_reg(master, OMAP2_MCSPI_XFERLEVEL) & 0xff; if (enable == 1) { /* Channel needs to be disabled and enabled * for FIFO setting to take affect */ if (s & OMAP2_MCSPI_CHCTRL_EN) { omap2_mcspi_set_enable(spi, 0); revert = 1; } if (buf_size < mcspi->fifo_depth) mcspi_write_reg(master, OMAP2_MCSPI_XFERLEVEL, ((wcnt << 16) | (buf_size - 1) << 8) | xfer_ael); else mcspi_write_reg(master, OMAP2_MCSPI_XFERLEVEL, ((wcnt << 16) | (mcspi->fifo_depth - 1) << 8) | xfer_ael); } else { /* Reset register value for disable case */ mcspi_write_reg(master, OMAP2_MCSPI_XFERLEVEL, xfer_ael); } rw = OMAP2_MCSPI_CHCONF_FFER; MOD_REG_BIT(l, rw, enable); mcspi_write_chconf0(spi, l); if (revert) omap2_mcspi_set_enable(spi, 1); return 0; }
static void omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) { struct omap2_mcspi * mcspi; struct omap2_mcspi_cs * cs = spi->controller_state; struct omap2_mcspi_dma * mcspi_dma; unsigned int count, c; unsigned long base, tx_reg, rx_reg; int word_len, data_type, element_count; u8 * rx; const u8 * tx; u32 l; mcspi = class_get_devdata(&spi->master->cdev); mcspi_dma = &mcspi->dma_channels[spi->chip_select]; count = xfer->len; c = count; word_len = cs->word_len; l = mcspi_read_cs_reg(spi, OMAP2_MCSPI_CHCONF0); l &= ~OMAP2_MCSPI_CHCONF_TRM_MASK; if (xfer->tx_buf == NULL) l |= OMAP2_MCSPI_CHCONF_TRM_RX_ONLY; else if (xfer->rx_buf == NULL) l |= OMAP2_MCSPI_CHCONF_TRM_TX_ONLY; mcspi_write_cs_reg(spi, OMAP2_MCSPI_CHCONF0, l); omap2_mcspi_set_enable(spi, 1); base = io_v2p(mcspi->base) + spi->chip_select * 0x14; tx_reg = base + OMAP2_MCSPI_TX0; rx_reg = base + OMAP2_MCSPI_RX0; rx = xfer->rx_buf; tx = xfer->tx_buf; if (word_len <= 8) { data_type = OMAP_DMA_DATA_TYPE_S8; element_count = count; } else if (word_len <= 16) { data_type = OMAP_DMA_DATA_TYPE_S16; element_count = count >> 1; } else if (word_len <= 32) {