summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2018-09-09 18:28:05 -0400
committerMark Brown <broonie@kernel.org>2018-09-10 07:29:58 -0400
commitabf5feef3ff0cefade0c76be53b59e55fdd46093 (patch)
tree1b196610d4318c4b0f544beed19a0c9566f8df5d
parentb9a947dd756b7af84ababa57e0524788f91a5382 (diff)
spi: gpio: No MISO does not imply no RX
There is a logical problem in spi-gpio with host just assigning a MOSI line and no MISO: this is interpreted as the host cannot do RX and the host is flagged with SPI_MASTER_NO_RX. This is wrong: since GPIO lines can switch direction, in 3WIRE operation the host will simply reverse the direction of the GPIO line and start reading from it, there is even code for doing this in the driver, but it went unnoticed because it was tested by using a master with 4 wires but a device using just 3 wires. Remove the offending flag. Cc: Andrzej Hajda <a.hajda@samsung.com> Cc: Lorenzo Bianconi <lorenzo.bianconi@redhat.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--drivers/spi/spi-gpio.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/drivers/spi/spi-gpio.c b/drivers/spi/spi-gpio.c
index d0c6d71b6c0f..a2b08b464857 100644
--- a/drivers/spi/spi-gpio.c
+++ b/drivers/spi/spi-gpio.c
@@ -295,9 +295,11 @@ static int spi_gpio_request(struct device *dev,
295 spi_gpio->miso = devm_gpiod_get_optional(dev, "miso", GPIOD_IN); 295 spi_gpio->miso = devm_gpiod_get_optional(dev, "miso", GPIOD_IN);
296 if (IS_ERR(spi_gpio->miso)) 296 if (IS_ERR(spi_gpio->miso))
297 return PTR_ERR(spi_gpio->miso); 297 return PTR_ERR(spi_gpio->miso);
298 if (!spi_gpio->miso) 298 /*
299 /* HW configuration without MISO pin */ 299 * No setting SPI_MASTER_NO_RX here - if there is only a MOSI
300 *mflags |= SPI_MASTER_NO_RX; 300 * pin connected the host can still do RX by changing the
301 * direction of the line.
302 */
301 303
302 spi_gpio->sck = devm_gpiod_get(dev, "sck", GPIOD_OUT_LOW); 304 spi_gpio->sck = devm_gpiod_get(dev, "sck", GPIOD_OUT_LOW);
303 if (IS_ERR(spi_gpio->mosi)) 305 if (IS_ERR(spi_gpio->mosi))
@@ -423,7 +425,7 @@ static int spi_gpio_probe(struct platform_device *pdev)
423 spi_gpio->bitbang.chipselect = spi_gpio_chipselect; 425 spi_gpio->bitbang.chipselect = spi_gpio_chipselect;
424 spi_gpio->bitbang.set_line_direction = spi_gpio_set_direction; 426 spi_gpio->bitbang.set_line_direction = spi_gpio_set_direction;
425 427
426 if ((master_flags & (SPI_MASTER_NO_TX | SPI_MASTER_NO_RX)) == 0) { 428 if ((master_flags & SPI_MASTER_NO_TX) == 0) {
427 spi_gpio->bitbang.txrx_word[SPI_MODE_0] = spi_gpio_txrx_word_mode0; 429 spi_gpio->bitbang.txrx_word[SPI_MODE_0] = spi_gpio_txrx_word_mode0;
428 spi_gpio->bitbang.txrx_word[SPI_MODE_1] = spi_gpio_txrx_word_mode1; 430 spi_gpio->bitbang.txrx_word[SPI_MODE_1] = spi_gpio_txrx_word_mode1;
429 spi_gpio->bitbang.txrx_word[SPI_MODE_2] = spi_gpio_txrx_word_mode2; 431 spi_gpio->bitbang.txrx_word[SPI_MODE_2] = spi_gpio_txrx_word_mode2;