Переглянути джерело

spi: omap2-mcspi: Fix FIFO support for transmit-and-receive mode

This patch fixes MCSPI FIFO buffer support when transmit-and-receive
(full duplex) mode is used. In this mode FIFO can be used for RX or
for TX or for both directions. If FIFO used for both directions the buffer
is split into two 32-byte buffers - one for each direction.
Also for full duplex mode both AEL and AFL need to be set in CHCONF0 register.

Signed-off-by: Illia Smyrnov <illia.smyrnov@globallogic.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
Illia Smyrnov 12 роки тому
батько
коміт
5db542ed85
1 змінених файлів з 9 додано та 3 видалено
  1. 9 3
      drivers/spi/spi-omap2-mcspi.c

+ 9 - 3
drivers/spi/spi-omap2-mcspi.c

@@ -276,7 +276,7 @@ static void omap2_mcspi_set_fifo(const struct spi_device *spi,
 	struct omap2_mcspi_cs *cs = spi->controller_state;
 	struct omap2_mcspi_cs *cs = spi->controller_state;
 	struct omap2_mcspi *mcspi;
 	struct omap2_mcspi *mcspi;
 	unsigned int wcnt;
 	unsigned int wcnt;
-	int fifo_depth, bytes_per_word;
+	int max_fifo_depth, fifo_depth, bytes_per_word;
 	u32 chconf, xferlevel;
 	u32 chconf, xferlevel;
 
 
 	mcspi = spi_master_get_devdata(master);
 	mcspi = spi_master_get_devdata(master);
@@ -287,7 +287,12 @@ static void omap2_mcspi_set_fifo(const struct spi_device *spi,
 		if (t->len % bytes_per_word != 0)
 		if (t->len % bytes_per_word != 0)
 			goto disable_fifo;
 			goto disable_fifo;
 
 
-		fifo_depth = gcd(t->len, OMAP2_MCSPI_MAX_FIFODEPTH);
+		if (t->rx_buf != NULL && t->tx_buf != NULL)
+			max_fifo_depth = OMAP2_MCSPI_MAX_FIFODEPTH / 2;
+		else
+			max_fifo_depth = OMAP2_MCSPI_MAX_FIFODEPTH;
+
+		fifo_depth = gcd(t->len, max_fifo_depth);
 		if (fifo_depth < 2 || fifo_depth % bytes_per_word != 0)
 		if (fifo_depth < 2 || fifo_depth % bytes_per_word != 0)
 			goto disable_fifo;
 			goto disable_fifo;
 
 
@@ -299,7 +304,8 @@ static void omap2_mcspi_set_fifo(const struct spi_device *spi,
 		if (t->rx_buf != NULL) {
 		if (t->rx_buf != NULL) {
 			chconf |= OMAP2_MCSPI_CHCONF_FFER;
 			chconf |= OMAP2_MCSPI_CHCONF_FFER;
 			xferlevel |= (fifo_depth - 1) << 8;
 			xferlevel |= (fifo_depth - 1) << 8;
-		} else {
+		}
+		if (t->tx_buf != NULL) {
 			chconf |= OMAP2_MCSPI_CHCONF_FFET;
 			chconf |= OMAP2_MCSPI_CHCONF_FFET;
 			xferlevel |= fifo_depth - 1;
 			xferlevel |= fifo_depth - 1;
 		}
 		}