Skip to content

Commit e69d380

Browse files
ts-krisgregkh
authored andcommitted
spi: spi-gpio: Don't set MOSI as an input if not 3WIRE mode
[ Upstream commit 3a6f994 ] The addition of 3WIRE support would affect MOSI direction even when still in standard (4 wire) mode. This can lead to MOSI being at an invalid logic level when a device driver sets an SPI message with a NULL tx_buf. spi.h states that if tx_buf is NULL then "zeros will be shifted out ... " If MOSI is tristated then the data shifted out is subject to pull resistors, keepers, or in the absence of those, noise. This issue came to light when using spi-gpio connected to an ADS7843 touchscreen controller. MOSI pulled high when clocking MISO data in caused the SPI device to interpret this as a command which would put the device in an unexpected and non-functional state. Fixes: 4b859db ("spi: spi-gpio: add SPI_3WIRE support") Fixes: 5132b3d ("spi: gpio: Support 3WIRE high-impedance turn-around") Signed-off-by: Kris Bahnsen <kris@embeddedTS.com> Link: https://lore.kernel.org/r/20221207230853.6174-1-kris@embeddedTS.com Signed-off-by: Mark Brown <broonie@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent 4e501a3 commit e69d380

File tree

1 file changed

+13
-3
lines changed

1 file changed

+13
-3
lines changed

drivers/spi/spi-gpio.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -244,9 +244,19 @@ static int spi_gpio_set_direction(struct spi_device *spi, bool output)
244244
if (output)
245245
return gpiod_direction_output(spi_gpio->mosi, 1);
246246

247-
ret = gpiod_direction_input(spi_gpio->mosi);
248-
if (ret)
249-
return ret;
247+
/*
248+
* Only change MOSI to an input if using 3WIRE mode.
249+
* Otherwise, MOSI could be left floating if there is
250+
* no pull resistor connected to the I/O pin, or could
251+
* be left logic high if there is a pull-up. Transmitting
252+
* logic high when only clocking MISO data in can put some
253+
* SPI devices in to a bad state.
254+
*/
255+
if (spi->mode & SPI_3WIRE) {
256+
ret = gpiod_direction_input(spi_gpio->mosi);
257+
if (ret)
258+
return ret;
259+
}
250260
/*
251261
* Send a turnaround high impedance cycle when switching
252262
* from output to input. Theoretically there should be

0 commit comments

Comments
 (0)