Message ID | b08e21823638c241228f4bc27a7bf5d4ed88d54a.1719686465.git.marcelo.schmitt@analog.com |
---|---|
State | Superseded |
Headers | show |
Series | Add support for AD4000 series of ADCs | expand |
On Sat, 29 Jun 2024 16:05:05 -0300 Marcelo Schmitt <marcelo.schmitt@analog.com> wrote: > 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() call back > to set MOSI to its idle state. > The MOSI line is kept at its idle state if no tx buffer is provided. Slightly odd wrapping - this doesn't warrant 3 paragraphs, so I'd just reflow it into one. I'm not a fan of counting F's, so would have gone with GENMASK for those but it's not the local style, so fair enough to hard code them. FWIW given it's been a long time since I messed around in SPI controller drivers... Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> > > Acked-by: Nuno Sa <nuno.sa@analog.com> > Reviewed-by: David Lechner <dlechner@baylibre.com> > Signed-off-by: Marcelo Schmitt <marcelo.schmitt@analog.com>
On 6/29/24 2:05 PM, Marcelo Schmitt wrote: > 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() call back > 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> > Signed-off-by: Marcelo Schmitt <marcelo.schmitt@analog.com> > --- FYI, this doesn't apply cleanly to spi-next and needs to be rebased. (conflicts with https://lore.kernel.org/all/20240517194104.747328-3-andriy.shevchenko@linux.intel.com/)
diff --git a/drivers/spi/spi-bitbang.c b/drivers/spi/spi-bitbang.c index ca5cc67555c5..8cc522bf444c 100644 --- a/drivers/spi/spi-bitbang.c +++ b/drivers/spi/spi-bitbang.c @@ -63,21 +63,28 @@ static unsigned bitbang_txrx_8( unsigned flags ) { + struct spi_bitbang *bitbang; unsigned bits = t->bits_per_word; unsigned count = t->len; const u8 *tx = t->tx_buf; u8 *rx = t->rx_buf; + bitbang = spi_controller_get_devdata(spi->controller); while (likely(count > 0)) { u8 word = 0; if (tx) word = *tx++; + else + word = spi->mode & SPI_MOSI_IDLE_HIGH ? 0xFF : 0; word = txrx_word(spi, ns, word, bits, flags); if (rx) *rx++ = word; count -= 1; } + if (bitbang->set_mosi_idle) + bitbang->set_mosi_idle(spi); + return t->len - count; } @@ -92,21 +99,28 @@ static unsigned bitbang_txrx_16( unsigned flags ) { + struct spi_bitbang *bitbang; unsigned bits = t->bits_per_word; unsigned count = t->len; const u16 *tx = t->tx_buf; u16 *rx = t->rx_buf; + bitbang = spi_controller_get_devdata(spi->controller); while (likely(count > 1)) { u16 word = 0; if (tx) word = *tx++; + else + word = spi->mode & SPI_MOSI_IDLE_HIGH ? 0xFFFF : 0; word = txrx_word(spi, ns, word, bits, flags); if (rx) *rx++ = word; count -= 2; } + if (bitbang->set_mosi_idle) + bitbang->set_mosi_idle(spi); + return t->len - count; } @@ -121,21 +135,28 @@ static unsigned bitbang_txrx_32( unsigned flags ) { + struct spi_bitbang *bitbang; unsigned bits = t->bits_per_word; unsigned count = t->len; const u32 *tx = t->tx_buf; u32 *rx = t->rx_buf; + bitbang = spi_controller_get_devdata(spi->controller); while (likely(count > 3)) { u32 word = 0; if (tx) word = *tx++; + else + word = spi->mode & SPI_MOSI_IDLE_HIGH ? 0xFFFFFFFF : 0; word = txrx_word(spi, ns, word, bits, flags); if (rx) *rx++ = word; count -= 4; } + if (bitbang->set_mosi_idle) + bitbang->set_mosi_idle(spi); + return t->len - count; } @@ -211,6 +232,9 @@ int spi_bitbang_setup(struct spi_device *spi) goto err_free; } + if (bitbang->set_mosi_idle) + bitbang->set_mosi_idle(spi); + dev_dbg(&spi->dev, "%s, %u nsec/bit\n", __func__, 2 * cs->nsecs); return 0; diff --git a/include/linux/spi/spi_bitbang.h b/include/linux/spi/spi_bitbang.h index b930eca2ef7b..1a54b593c691 100644 --- a/include/linux/spi/spi_bitbang.h +++ b/include/linux/spi/spi_bitbang.h @@ -22,6 +22,7 @@ struct spi_bitbang { #define BITBANG_CS_ACTIVE 1 /* normally nCS, active low */ #define BITBANG_CS_INACTIVE 0 + void (*set_mosi_idle)(struct spi_device *spi); /* txrx_bufs() may handle dma mapping for transfers that don't * already have one (transfer.{tx,rx}_dma is zero), or use PIO */