Skip to content

Commit 4b859db

Browse files
LorenzoBianconibroonie
authored andcommitted
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>
1 parent 304d343 commit 4b859db

File tree

3 files changed

+33
-1
lines changed

3 files changed

+33
-1
lines changed

drivers/spi/spi-bitbang.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,23 @@ static int spi_bitbang_bufs(struct spi_device *spi, struct spi_transfer *t)
243243
{
244244
struct spi_bitbang_cs *cs = spi->controller_state;
245245
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;
246251

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+
}
247263
return cs->txrx_bufs(spi, cs->txrx_word, nsecs, t, 0);
248264
}
249265

drivers/spi/spi-gpio.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,10 @@ static inline int getmiso(const struct spi_device *spi)
121121
{
122122
struct spi_gpio *spi_gpio = spi_to_spi_gpio(spi);
123123

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);
125128
}
126129

127130
/*
@@ -250,6 +253,16 @@ static int spi_gpio_setup(struct spi_device *spi)
250253
return status;
251254
}
252255

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+
253266
static void spi_gpio_cleanup(struct spi_device *spi)
254267
{
255268
spi_bitbang_cleanup(spi);
@@ -395,6 +408,7 @@ static int spi_gpio_probe(struct platform_device *pdev)
395408
return status;
396409

397410
master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32);
411+
master->mode_bits = SPI_3WIRE | SPI_CPHA | SPI_CPOL;
398412
master->flags = master_flags;
399413
master->bus_num = pdev->id;
400414
/* 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)
407421

408422
spi_gpio->bitbang.master = master;
409423
spi_gpio->bitbang.chipselect = spi_gpio_chipselect;
424+
spi_gpio->bitbang.set_line_direction = spi_gpio_set_direction;
410425

411426
if ((master_flags & (SPI_MASTER_NO_TX | SPI_MASTER_NO_RX)) == 0) {
412427
spi_gpio->bitbang.txrx_word[SPI_MODE_0] = spi_gpio_txrx_word_mode0;

include/linux/spi/spi_bitbang.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ struct spi_bitbang {
3131
u32 (*txrx_word[4])(struct spi_device *spi,
3232
unsigned nsecs,
3333
u32 word, u8 bits, unsigned flags);
34+
int (*set_line_direction)(struct spi_device *spi, bool output);
3435
};
3536

3637
/* you can call these default bitbang->master methods from your custom

0 commit comments

Comments
 (0)