diff options
| -rw-r--r-- | drivers/spi/spi-bitbang.c | 16 | ||||
| -rw-r--r-- | drivers/spi/spi-gpio.c | 17 | ||||
| -rw-r--r-- | include/linux/spi/spi_bitbang.h | 1 |
3 files changed, 33 insertions, 1 deletions
diff --git a/drivers/spi/spi-bitbang.c b/drivers/spi/spi-bitbang.c index 76f1b534bdd7..f29176000b8d 100644 --- a/drivers/spi/spi-bitbang.c +++ b/drivers/spi/spi-bitbang.c | |||
| @@ -243,7 +243,23 @@ static int spi_bitbang_bufs(struct spi_device *spi, struct spi_transfer *t) | |||
| 243 | { | 243 | { |
| 244 | struct spi_bitbang_cs *cs = spi->controller_state; | 244 | struct spi_bitbang_cs *cs = spi->controller_state; |
| 245 | unsigned nsecs = cs->nsecs; | 245 | unsigned nsecs = cs->nsecs; |
| 246 | struct spi_bitbang *bitbang; | ||
| 247 | |||
| 248 | bitbang = spi_master_get_devdata(spi->master); | ||
| 249 | if (bitbang->set_line_direction) { | ||
| 250 | int err; | ||
| 246 | 251 | ||
| 252 | err = bitbang->set_line_direction(spi, !!(t->tx_buf)); | ||
| 253 | if (err < 0) | ||
| 254 | return err; | ||
| 255 | } | ||
| 256 | |||
| 257 | if (spi->mode & SPI_3WIRE) { | ||
| 258 | unsigned flags; | ||
| 259 | |||
| 260 | flags = t->tx_buf ? SPI_MASTER_NO_RX : SPI_MASTER_NO_TX; | ||
| 261 | return cs->txrx_bufs(spi, cs->txrx_word, nsecs, t, flags); | ||
| 262 | } | ||
| 247 | return cs->txrx_bufs(spi, cs->txrx_word, nsecs, t, 0); | 263 | return cs->txrx_bufs(spi, cs->txrx_word, nsecs, t, 0); |
| 248 | } | 264 | } |
| 249 | 265 | ||
diff --git a/drivers/spi/spi-gpio.c b/drivers/spi/spi-gpio.c index be68298cbd9c..0626e6e3ea0c 100644 --- a/drivers/spi/spi-gpio.c +++ b/drivers/spi/spi-gpio.c | |||
| @@ -121,7 +121,10 @@ static inline int getmiso(const struct spi_device *spi) | |||
| 121 | { | 121 | { |
| 122 | struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi); | 122 | struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi); |
| 123 | 123 | ||
| 124 | return !!gpiod_get_value_cansleep(spi_gpio->miso); | 124 | if (spi->mode & SPI_3WIRE) |
| 125 | return !!gpiod_get_value_cansleep(spi_gpio->mosi); | ||
| 126 | else | ||
| 127 | return !!gpiod_get_value_cansleep(spi_gpio->miso); | ||
| 125 | } | 128 | } |
| 126 | 129 | ||
| 127 | /* | 130 | /* |
| @@ -250,6 +253,16 @@ static int spi_gpio_setup(struct spi_device *spi) | |||
| 250 | return status; | 253 | return status; |
| 251 | } | 254 | } |
| 252 | 255 | ||
| 256 | static int spi_gpio_set_direction(struct spi_device *spi, bool output) | ||
| 257 | { | ||
| 258 | struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi); | ||
| 259 | |||
| 260 | if (output) | ||
| 261 | return gpiod_direction_output(spi_gpio->mosi, 1); | ||
| 262 | else | ||
| 263 | return gpiod_direction_input(spi_gpio->mosi); | ||
| 264 | } | ||
| 265 | |||
| 253 | static void spi_gpio_cleanup(struct spi_device *spi) | 266 | static void spi_gpio_cleanup(struct spi_device *spi) |
| 254 | { | 267 | { |
| 255 | spi_bitbang_cleanup(spi); | 268 | spi_bitbang_cleanup(spi); |
| @@ -395,6 +408,7 @@ static int spi_gpio_probe(struct platform_device *pdev) | |||
| 395 | return status; | 408 | return status; |
| 396 | 409 | ||
| 397 | master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32); | 410 | master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32); |
| 411 | master->mode_bits = SPI_3WIRE | SPI_CPHA | SPI_CPOL; | ||
| 398 | master->flags = master_flags; | 412 | master->flags = master_flags; |
| 399 | master->bus_num = pdev->id; | 413 | master->bus_num = pdev->id; |
| 400 | /* The master needs to think there is a chipselect even if not connected */ | 414 | /* The master needs to think there is a chipselect even if not connected */ |
| @@ -407,6 +421,7 @@ static int spi_gpio_probe(struct platform_device *pdev) | |||
| 407 | 421 | ||
| 408 | spi_gpio->bitbang.master = master; | 422 | spi_gpio->bitbang.master = master; |
| 409 | spi_gpio->bitbang.chipselect = spi_gpio_chipselect; | 423 | spi_gpio->bitbang.chipselect = spi_gpio_chipselect; |
| 424 | spi_gpio->bitbang.set_line_direction = spi_gpio_set_direction; | ||
| 410 | 425 | ||
| 411 | if ((master_flags & (SPI_MASTER_NO_TX | SPI_MASTER_NO_RX)) == 0) { | 426 | if ((master_flags & (SPI_MASTER_NO_TX | SPI_MASTER_NO_RX)) == 0) { |
| 412 | spi_gpio->bitbang.txrx_word[SPI_MODE_0] = spi_gpio_txrx_word_mode0; | 427 | spi_gpio->bitbang.txrx_word[SPI_MODE_0] = spi_gpio_txrx_word_mode0; |
diff --git a/include/linux/spi/spi_bitbang.h b/include/linux/spi/spi_bitbang.h index 5847f00ef9cf..b7e021b274dc 100644 --- a/include/linux/spi/spi_bitbang.h +++ b/include/linux/spi/spi_bitbang.h | |||
| @@ -31,6 +31,7 @@ struct spi_bitbang { | |||
| 31 | u32 (*txrx_word[4])(struct spi_device *spi, | 31 | u32 (*txrx_word[4])(struct spi_device *spi, |
| 32 | unsigned nsecs, | 32 | unsigned nsecs, |
| 33 | u32 word, u8 bits, unsigned flags); | 33 | u32 word, u8 bits, unsigned flags); |
| 34 | int (*set_line_direction)(struct spi_device *spi, bool output); | ||
| 34 | }; | 35 | }; |
| 35 | 36 | ||
| 36 | /* you can call these default bitbang->master methods from your custom | 37 | /* you can call these default bitbang->master methods from your custom |
