aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSanchayan Maity <maitysanchayan@gmail.com>2016-11-22 02:01:31 -0500
committerMark Brown <broonie@kernel.org>2016-11-22 11:47:25 -0500
commitccf7d8ee3d6eb600338a184e9a192ec1d5aee924 (patch)
treeee3a4dbd2cbf0c9e12690d57de32097d6e3a8a34
parent1eaccf210c59e04eb6e9b5469a60d6609c95ac61 (diff)
spi: spi-fsl-dspi: Fix continuous selection format
Current DMA implementation was not handling the continuous selection format viz. SPI chip select would be deasserted even between sequential serial transfers. Use existing dspi_data_to_pushr function to restructure the transmit code path and set or reset the CONT bit on same lines as code path in EOQ mode does. This correctly implements continuous selection format while also correcting and cleaning up the transmit code path. Signed-off-by: Sanchayan Maity <maitysanchayan@gmail.com> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--drivers/spi/spi-fsl-dspi.c20
1 files changed, 6 insertions, 14 deletions
diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index cb41c327bd77..7ada112bfd85 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -196,6 +196,8 @@ struct fsl_dspi {
196 struct fsl_dspi_dma *dma; 196 struct fsl_dspi_dma *dma;
197}; 197};
198 198
199static u32 dspi_data_to_pushr(struct fsl_dspi *dspi, int tx_word);
200
199static inline int is_double_byte_mode(struct fsl_dspi *dspi) 201static inline int is_double_byte_mode(struct fsl_dspi *dspi)
200{ 202{
201 unsigned int val; 203 unsigned int val;
@@ -242,24 +244,15 @@ static int dspi_next_xfer_dma_submit(struct fsl_dspi *dspi)
242 int time_left; 244 int time_left;
243 int tx_word; 245 int tx_word;
244 int i; 246 int i;
245 u16 val;
246 247
247 tx_word = is_double_byte_mode(dspi); 248 tx_word = is_double_byte_mode(dspi);
248 249
249 for (i = 0; i < dma->curr_xfer_len - 1; i++) { 250 for (i = 0; i < dma->curr_xfer_len; i++) {
250 val = tx_word ? *(u16 *) dspi->tx : *(u8 *) dspi->tx; 251 dspi->dma->tx_dma_buf[i] = dspi_data_to_pushr(dspi, tx_word);
251 dspi->dma->tx_dma_buf[i] = 252 if ((dspi->cs_change) && (!dspi->len))
252 SPI_PUSHR_TXDATA(val) | SPI_PUSHR_PCS(dspi->cs) | 253 dspi->dma->tx_dma_buf[i] &= ~SPI_PUSHR_CONT;
253 SPI_PUSHR_CTAS(0) | SPI_PUSHR_CONT;
254 dspi->tx += tx_word + 1;
255 } 254 }
256 255
257 val = tx_word ? *(u16 *) dspi->tx : *(u8 *) dspi->tx;
258 dspi->dma->tx_dma_buf[i] = SPI_PUSHR_TXDATA(val) |
259 SPI_PUSHR_PCS(dspi->cs) |
260 SPI_PUSHR_CTAS(0);
261 dspi->tx += tx_word + 1;
262
263 dma->tx_desc = dmaengine_prep_slave_single(dma->chan_tx, 256 dma->tx_desc = dmaengine_prep_slave_single(dma->chan_tx,
264 dma->tx_dma_phys, 257 dma->tx_dma_phys,
265 dma->curr_xfer_len * 258 dma->curr_xfer_len *
@@ -351,7 +344,6 @@ static int dspi_dma_xfer(struct fsl_dspi *dspi)
351 curr_remaining_bytes -= dma->curr_xfer_len * word; 344 curr_remaining_bytes -= dma->curr_xfer_len * word;
352 if (curr_remaining_bytes < 0) 345 if (curr_remaining_bytes < 0)
353 curr_remaining_bytes = 0; 346 curr_remaining_bytes = 0;
354 dspi->len = curr_remaining_bytes;
355 } 347 }
356 } 348 }
357 349