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: 4b859db2c606 ("spi: spi-gpio: add SPI_3WIRE support")
Fixes: 5132b3d28371 ("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>

authored by Kris Bahnsen and committed by Mark Brown 3a6f994f 8330e9e8

Changed files
+13 -3
drivers
+13 -3
drivers/spi/spi-gpio.c
··· 268 268 if (output) 269 269 return gpiod_direction_output(spi_gpio->mosi, 1); 270 270 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 + } 274 284 /* 275 285 * Send a turnaround high impedance cycle when switching 276 286 * from output to input. Theoretically there should be