From c818662c362f5cd0801d3293f734e8f96c9418a3 Mon Sep 17 00:00:00 2001 From: Siarhei Volkau Date: Sat, 9 May 2026 20:53:47 +0300 Subject: [PATCH 1/2] spi: fsl-lpspi: support LSB-first The driver currently doesn't support SPI_LSB_FIRST feature but it can be easily added. Signed-off-by: Siarhei Volkau --- drivers/spi/spi-fsl-lpspi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/spi/spi-fsl-lpspi.c b/drivers/spi/spi-fsl-lpspi.c index 5e96913fd9466..205b48c7c6659 100644 --- a/drivers/spi/spi-fsl-lpspi.c +++ b/drivers/spi/spi-fsl-lpspi.c @@ -78,6 +78,7 @@ #define RSR_RXEMPTY BIT(1) #define TCR_CPOL BIT(31) #define TCR_CPHA BIT(30) +#define TCR_LSBF BIT(23) #define TCR_CONT BIT(21) #define TCR_CONTC BIT(20) #define TCR_RXMSK BIT(19) @@ -280,6 +281,7 @@ static void fsl_lpspi_set_cmd(struct fsl_lpspi_data *fsl_lpspi) temp |= fsl_lpspi->config.bpw - 1; temp |= (fsl_lpspi->config.mode & 0x3) << 30; temp |= (fsl_lpspi->config.chip_select & 0x3) << 24; + temp |= (fsl_lpspi->config.mode & SPI_LSB_FIRST) ? TCR_LSBF : 0; if (!fsl_lpspi->is_target) { temp |= fsl_lpspi->config.prescale << 27; /* @@ -937,7 +939,7 @@ static int fsl_lpspi_probe(struct platform_device *pdev) controller->transfer_one = fsl_lpspi_transfer_one; controller->prepare_transfer_hardware = lpspi_prepare_xfer_hardware; controller->unprepare_transfer_hardware = lpspi_unprepare_xfer_hardware; - controller->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; + controller->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LSB_FIRST; controller->flags = SPI_CONTROLLER_MUST_RX | SPI_CONTROLLER_MUST_TX; controller->dev.of_node = pdev->dev.of_node; controller->bus_num = pdev->id; From bded1e0e597881e80ad801827ef2c15e92060ed4 Mon Sep 17 00:00:00 2001 From: Siarhei Volkau Date: Sat, 9 May 2026 21:05:38 +0300 Subject: [PATCH 2/2] spi: fsl-lpspi: fix broken PCS behavior in DMA mode In DMA mode LPSPI splits out transaction on per-word basis. This is because TCR_CONT is not set. When TCR_CONT set, it starts work properly. However, CS stays active much longer than required, for ~80us on imx95. I guess DMA completion handler resets it. Also I observed that TCR_CONTC flag logic is broken but don't know how to fix it. Signed-off-by: Siarhei Volkau --- drivers/spi/spi-fsl-lpspi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/spi/spi-fsl-lpspi.c b/drivers/spi/spi-fsl-lpspi.c index 205b48c7c6659..1d0121abbc27a 100644 --- a/drivers/spi/spi-fsl-lpspi.c +++ b/drivers/spi/spi-fsl-lpspi.c @@ -289,8 +289,8 @@ static void fsl_lpspi_set_cmd(struct fsl_lpspi_data *fsl_lpspi) * For the first transfer, clear TCR_CONTC to assert SS. * For subsequent transfer, set TCR_CONTC to keep SS asserted. */ + temp |= TCR_CONT; if (!fsl_lpspi->usedma) { - temp |= TCR_CONT; if (fsl_lpspi->is_first_byte) temp &= ~TCR_CONTC; else