From 46f7ac3d7892e808c9ba01c39da6bb85cda26ecd Mon Sep 17 00:00:00 2001 From: Robin Murphy Date: Wed, 3 Aug 2022 15:58:57 +0100 Subject: [PATCH] spi: bitbang: Fix lsb-first Rx Shifting the recieved bit by "bits" inserts it at the top of the *currently remaining* Tx data, so we end up accumulating the whole transfer into bit 0 of the output word. Oops. For the algorithm to work as intended, we need to remember where the top of the *original* word was, and shift Rx to there. Fixes: 1847e3046c52 ("spi: gpio: Implement LSB First bitbang support") Signed-off-by: Robin Murphy Link: https://lore.kernel.org/r/28324d8622da80461cce35a82859b003d6f6c4b0.1659538737.git.robin.murphy@arm.com Signed-off-by: Mark Brown --- drivers/spi/spi-bitbang-txrx.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/spi/spi-bitbang-txrx.h b/drivers/spi/spi-bitbang-txrx.h index 267342d..2dcbe16 100644 --- a/drivers/spi/spi-bitbang-txrx.h +++ b/drivers/spi/spi-bitbang-txrx.h @@ -116,6 +116,7 @@ bitbang_txrx_le_cpha0(struct spi_device *spi, { /* if (cpol == 0) this is SPI_MODE_0; else this is SPI_MODE_2 */ + u8 rxbit = bits - 1; u32 oldbit = !(word & 1); /* clock starts at inactive polarity */ for (; likely(bits); bits--) { @@ -135,7 +136,7 @@ bitbang_txrx_le_cpha0(struct spi_device *spi, /* sample LSB (from slave) on leading edge */ word >>= 1; if ((flags & SPI_MASTER_NO_RX) == 0) - word |= getmiso(spi) << (bits - 1); + word |= getmiso(spi) << rxbit; setsck(spi, cpol); } return word; @@ -148,6 +149,7 @@ bitbang_txrx_le_cpha1(struct spi_device *spi, { /* if (cpol == 0) this is SPI_MODE_1; else this is SPI_MODE_3 */ + u8 rxbit = bits - 1; u32 oldbit = !(word & 1); /* clock starts at inactive polarity */ for (; likely(bits); bits--) { @@ -168,7 +170,7 @@ bitbang_txrx_le_cpha1(struct spi_device *spi, /* sample LSB (from slave) on trailing edge */ word >>= 1; if ((flags & SPI_MASTER_NO_RX) == 0) - word |= getmiso(spi) << (bits - 1); + word |= getmiso(spi) << rxbit; } return word; } -- 2.7.4