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: 1847e3046c
("spi: gpio: Implement LSB First bitbang support")
Signed-off-by: Robin Murphy <robin.murphy@arm.com>
Link: https://lore.kernel.org/r/28324d8622da80461cce35a82859b003d6f6c4b0.1659538737.git.robin.murphy@arm.com
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
568035b01c
commit
46f7ac3d78
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue