diff mbox series

[v1,2/2] spi: fsl-spi: Implement trailing clock mode

Message ID f66ae24b31f10f7c3a999a77a6cfab7b2d073c6a.1645950971.git.christophe.leroy@csgroup.eu
State New
Headers show
Series None | expand

Commit Message

Christophe Leroy Feb. 27, 2022, 10 a.m. UTC
In order to support IDT 801034 QUAD PCM CODEC, implement the
trailing clock mode.

On fsl SPI, the minimum we can implement is a 4 bits shot.

Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
 drivers/spi/spi-fsl-lib.c |  2 +-
 drivers/spi/spi-fsl-spi.c | 15 +++++++++++++--
 2 files changed, 14 insertions(+), 3 deletions(-)

Comments

Mark Brown Feb. 28, 2022, 1:20 p.m. UTC | #1
On Sun, Feb 27, 2022 at 11:00:35AM +0100, Christophe Leroy wrote:

> +	if (!status && spi->mode & SPI_TRAILING) {
> +		struct spi_transfer t = {
> +			.len = 1,
> +			.tx_buf = "",
> +			.bits_per_word = 4
> +		};
> +
> +		status = fsl_spi_setup_transfer(spi, &t);
> +		if (!status)
> +			status = fsl_spi_bufs(spi, &t, 0);
> +	}
> +	m->status = status;

This seems to be begging for a generic implementation in the core rather
than being driver specific - drivers would for the most part need
updating to advertise less than 8 bit per word transfers but the basic
operation isn't really device specific and it pretty much fits with the
existing interfaces.
diff mbox series

Patch

diff --git a/drivers/spi/spi-fsl-lib.c b/drivers/spi/spi-fsl-lib.c
index 76e1192eb025..a13f3b4db55f 100644
--- a/drivers/spi/spi-fsl-lib.c
+++ b/drivers/spi/spi-fsl-lib.c
@@ -88,7 +88,7 @@  void mpc8xxx_spi_probe(struct device *dev, struct resource *mem,
 
 	/* the spi->mode bits understood by this driver: */
 	master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH
-			| SPI_LSB_FIRST | SPI_LOOP;
+			| SPI_LSB_FIRST | SPI_LOOP | SPI_TRAILING;
 
 	master->dev.of_node = dev->of_node;
 
diff --git a/drivers/spi/spi-fsl-spi.c b/drivers/spi/spi-fsl-spi.c
index bdf94cc7be1a..6a52955d9051 100644
--- a/drivers/spi/spi-fsl-spi.c
+++ b/drivers/spi/spi-fsl-spi.c
@@ -424,13 +424,24 @@  static int fsl_spi_do_one_msg(struct spi_master *master,
 		}
 	}
 
-	m->status = status;
-
 	if (status || !cs_change) {
 		ndelay(nsecs);
 		fsl_spi_chipselect(spi, BITBANG_CS_INACTIVE);
 	}
 
+	if (!status && spi->mode & SPI_TRAILING) {
+		struct spi_transfer t = {
+			.len = 1,
+			.tx_buf = "",
+			.bits_per_word = 4
+		};
+
+		status = fsl_spi_setup_transfer(spi, &t);
+		if (!status)
+			status = fsl_spi_bufs(spi, &t, 0);
+	}
+	m->status = status;
+
 	fsl_spi_setup_transfer(spi, NULL);
 	spi_finalize_current_message(master);
 	return 0;