Skip to content

Commit fb3e2f1

Browse files
committed
spi: bitbang: Implement support for MOSI idle state configuration
Some SPI peripherals may require strict MOSI line state when the controller is not clocking out data. Implement support for MOSI idle state configuration (low or high) by setting the data output line level on controller setup and after transfers. Bitbang operations now call controller specific set_mosi_idle() callback to set MOSI to its idle state. The MOSI line is kept at its idle state if no tx buffer is provided. Acked-by: Nuno Sa <nuno.sa@analog.com> Reviewed-by: David Lechner <dlechner@baylibre.com> Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Signed-off-by: Marcelo Schmitt <marcelo.schmitt@analog.com>
1 parent 5fe9255 commit fb3e2f1

File tree

2 files changed

+25
-0
lines changed

2 files changed

+25
-0
lines changed

drivers/spi/spi-bitbang.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,21 +54,28 @@ static unsigned int bitbang_txrx_8(struct spi_device *spi,
5454
struct spi_transfer *t,
5555
unsigned int flags)
5656
{
57+
struct spi_bitbang *bitbang;
5758
unsigned int bits = t->bits_per_word;
5859
unsigned int count = t->len;
5960
const u8 *tx = t->tx_buf;
6061
u8 *rx = t->rx_buf;
6162

63+
bitbang = spi_controller_get_devdata(spi->controller);
6264
while (likely(count > 0)) {
6365
u8 word = 0;
6466

6567
if (tx)
6668
word = *tx++;
69+
else
70+
word = spi->mode & SPI_MOSI_IDLE_HIGH ? 0xFF : 0;
6771
word = txrx_word(spi, ns, word, bits, flags);
6872
if (rx)
6973
*rx++ = word;
7074
count -= 1;
7175
}
76+
if (bitbang->set_mosi_idle)
77+
bitbang->set_mosi_idle(spi);
78+
7279
return t->len - count;
7380
}
7481

@@ -78,21 +85,28 @@ static unsigned int bitbang_txrx_16(struct spi_device *spi,
7885
struct spi_transfer *t,
7986
unsigned int flags)
8087
{
88+
struct spi_bitbang *bitbang;
8189
unsigned int bits = t->bits_per_word;
8290
unsigned int count = t->len;
8391
const u16 *tx = t->tx_buf;
8492
u16 *rx = t->rx_buf;
8593

94+
bitbang = spi_controller_get_devdata(spi->controller);
8695
while (likely(count > 1)) {
8796
u16 word = 0;
8897

8998
if (tx)
9099
word = *tx++;
100+
else
101+
word = spi->mode & SPI_MOSI_IDLE_HIGH ? 0xFFFF : 0;
91102
word = txrx_word(spi, ns, word, bits, flags);
92103
if (rx)
93104
*rx++ = word;
94105
count -= 2;
95106
}
107+
if (bitbang->set_mosi_idle)
108+
bitbang->set_mosi_idle(spi);
109+
96110
return t->len - count;
97111
}
98112

@@ -102,21 +116,28 @@ static unsigned int bitbang_txrx_32(struct spi_device *spi,
102116
struct spi_transfer *t,
103117
unsigned int flags)
104118
{
119+
struct spi_bitbang *bitbang;
105120
unsigned int bits = t->bits_per_word;
106121
unsigned int count = t->len;
107122
const u32 *tx = t->tx_buf;
108123
u32 *rx = t->rx_buf;
109124

125+
bitbang = spi_controller_get_devdata(spi->controller);
110126
while (likely(count > 3)) {
111127
u32 word = 0;
112128

113129
if (tx)
114130
word = *tx++;
131+
else
132+
word = spi->mode & SPI_MOSI_IDLE_HIGH ? 0xFFFFFFFF : 0;
115133
word = txrx_word(spi, ns, word, bits, flags);
116134
if (rx)
117135
*rx++ = word;
118136
count -= 4;
119137
}
138+
if (bitbang->set_mosi_idle)
139+
bitbang->set_mosi_idle(spi);
140+
120141
return t->len - count;
121142
}
122143

@@ -192,6 +213,9 @@ int spi_bitbang_setup(struct spi_device *spi)
192213
goto err_free;
193214
}
194215

216+
if (bitbang->set_mosi_idle)
217+
bitbang->set_mosi_idle(spi);
218+
195219
dev_dbg(&spi->dev, "%s, %u nsec/bit\n", __func__, 2 * cs->nsecs);
196220

197221
return 0;

include/linux/spi/spi_bitbang.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ struct spi_bitbang {
2424
#define BITBANG_CS_ACTIVE 1 /* normally nCS, active low */
2525
#define BITBANG_CS_INACTIVE 0
2626

27+
void (*set_mosi_idle)(struct spi_device *spi);
2728
/* txrx_bufs() may handle dma mapping for transfers that don't
2829
* already have one (transfer.{tx,rx}_dma is zero), or use PIO
2930
*/

0 commit comments

Comments
 (0)