spi: spi-gpio: Don't set MOSI as an input if not 3WIRE mode
[ Upstream commit 3a6f994f848a69deb2bf3cd9d130dd0c09730e55 ] 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:4b859db2c6
("spi: spi-gpio: add SPI_3WIRE support") Fixes:5132b3d283
("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>
This commit is contained in:
parent
a00b4e0fa2
commit
9e8440a657
@ -244,9 +244,19 @@ static int spi_gpio_set_direction(struct spi_device *spi, bool output)
|
||||
if (output)
|
||||
return gpiod_direction_output(spi_gpio->mosi, 1);
|
||||
|
||||
ret = gpiod_direction_input(spi_gpio->mosi);
|
||||
if (ret)
|
||||
return ret;
|
||||
/*
|
||||
* Only change MOSI to an input if using 3WIRE mode.
|
||||
* Otherwise, MOSI could be left floating if there is
|
||||
* no pull resistor connected to the I/O pin, or could
|
||||
* be left logic high if there is a pull-up. Transmitting
|
||||
* logic high when only clocking MISO data in can put some
|
||||
* SPI devices in to a bad state.
|
||||
*/
|
||||
if (spi->mode & SPI_3WIRE) {
|
||||
ret = gpiod_direction_input(spi_gpio->mosi);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
/*
|
||||
* Send a turnaround high impedance cycle when switching
|
||||
* from output to input. Theoretically there should be
|
||||
|
Loading…
Reference in New Issue
Block a user