Skip to content

Commit 3a6f994

Browse files
ts-krisbroonie
authored andcommitted
spi: spi-gpio: Don't set MOSI as an input if not 3WIRE mode
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>
1 parent 8330e9e commit 3a6f994

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
@@ -268,9 +268,19 @@ static int spi_gpio_set_direction(struct spi_device *spi, bool output)
268268
if (output)
269269
return gpiod_direction_output(spi_gpio->mosi, 1);
270270

271-
ret = gpiod_direction_input(spi_gpio->mosi);
272-
if (ret)
273-
return ret;
271+
/*
272+
* Only change MOSI to an input if using 3WIRE mode.
273+
* Otherwise, MOSI could be left floating if there is
274+
* no pull resistor connected to the I/O pin, or could
275+
* be left logic high if there is a pull-up. Transmitting
276+
* logic high when only clocking MISO data in can put some
277+
* SPI devices in to a bad state.
278+
*/
279+
if (spi->mode & SPI_3WIRE) {
280+
ret = gpiod_direction_input(spi_gpio->mosi);
281+
if (ret)
282+
return ret;
283+
}
274284
/*
275285
* Send a turnaround high impedance cycle when switching
276286
* from output to input. Theoretically there should be

0 commit comments

Comments
 (0)