diff options
author | Lorenzo Bianconi <lorenzo.bianconi@redhat.com> | 2018-07-28 04:19:14 -0400 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2018-08-01 09:50:28 -0400 |
commit | 4b859db2c60692560afbfef1b030d0ddef57b7ee (patch) | |
tree | 70a19c5a126a3eacdfda8f8112a13950cdca0a05 /drivers/spi/spi-gpio.c | |
parent | 304d34360b099020a12af2abb7e1ac506f4ba16d (diff) |
spi: spi-gpio: add SPI_3WIRE support
Add SPI_3WIRE support to spi-gpio controller introducing
set_line_direction function pointer in spi_bitbang data structure.
Spi-gpio controller has been tested using hts221 temp/rh iio sensor
running in 3wire mode and lsm6dsm running in 4wire mode
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'drivers/spi/spi-gpio.c')
-rw-r--r-- | drivers/spi/spi-gpio.c | 17 |
1 files changed, 16 insertions, 1 deletions
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; |