This patch adds support for dual output read mode. It was successfully tested on a P1014-based device with a S25FL128S spi nor flash. Signed-off-by: Heiner Kallweit <hkallweit1@xxxxxxxxx> --- v2: - rebased - extended commit message --- drivers/spi/spi-fsl-espi.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c index e32dc30..5753b1e 100644 --- a/drivers/spi/spi-fsl-espi.c +++ b/drivers/spi/spi-fsl-espi.c @@ -205,10 +205,11 @@ static int fsl_espi_check_message(struct spi_message *m) } static void fsl_espi_check_rxskip_mode(struct spi_message *m, - struct mpc8xxx_spi *mspi) + struct mpc8xxx_spi *mspi, + struct spi_transfer *tr) { struct spi_transfer *t; - unsigned int i = 0, rxskip_len = 0; + unsigned int i = 0, rxskip_len = 0, rx_nbits = SPI_NBITS_SINGLE; mspi->rxskip = 0; @@ -222,6 +223,9 @@ static void fsl_espi_check_rxskip_mode(struct spi_message *m, * low-level transfer implementation. * This constraint doesn't affect SPI NOR reads as typical use case * for rxskip mode as the read command has only few bytes. + * + * Store rx_nbits of the read transfer for later assessment + * whether single or dual mode is requested. */ list_for_each_entry(t, &m->transfers, transfer_list) { if (i == 0) { @@ -232,12 +236,15 @@ static void fsl_espi_check_rxskip_mode(struct spi_message *m, } else if (i == 1) { if (t->tx_buf || !t->rx_buf) return; + rx_nbits = t->rx_nbits; } i++; } - if (i == 2) + if (i == 2) { mspi->rxskip = rxskip_len; + tr->rx_nbits = rx_nbits; + } } static void fsl_espi_fill_tx_fifo(struct mpc8xxx_spi *mspi, u32 events) @@ -340,6 +347,8 @@ static int fsl_espi_bufs(struct spi_device *spi, struct spi_transfer *t) mpc8xxx_spi->tx_len = mpc8xxx_spi->rxskip; mpc8xxx_spi->rx_len = t->len - mpc8xxx_spi->rxskip; mpc8xxx_spi->rx = t->rx_buf + mpc8xxx_spi->rxskip; + if (t->rx_nbits == SPI_NBITS_DUAL) + spcom |= SPCOM_DO; } fsl_espi_write_reg(mpc8xxx_spi, ESPI_SPCOM, spcom); @@ -374,7 +383,7 @@ static int fsl_espi_trans(struct spi_message *m, struct spi_transfer *trans) struct spi_device *spi = m->spi; int ret; - fsl_espi_check_rxskip_mode(m, mspi); + fsl_espi_check_rxskip_mode(m, mspi, trans); fsl_espi_copy_to_buf(m, mspi); fsl_espi_setup_transfer(spi, trans); @@ -588,6 +597,7 @@ static int fsl_espi_probe(struct device *dev, struct resource *mem, mpc8xxx_spi_probe(dev, mem, irq); + master->mode_bits |= SPI_RX_DUAL; master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 16); master->setup = fsl_espi_setup; master->cleanup = fsl_espi_cleanup; -- 2.10.1 -- To unsubscribe from this list: send the line "unsubscribe linux-spi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html