diff options
Diffstat (limited to 'drivers/spi/spi-bitbang-txrx.h')
-rw-r--r-- | drivers/spi/spi-bitbang-txrx.h | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/drivers/spi/spi-bitbang-txrx.h b/drivers/spi/spi-bitbang-txrx.h index ae61d72c7d28..267342dfa738 100644 --- a/drivers/spi/spi-bitbang-txrx.h +++ b/drivers/spi/spi-bitbang-txrx.h @@ -41,6 +41,8 @@ * chips need ... there may be several reasons you'd need to tweak timings * in these routines, not just to make it faster or slower to match a * particular CPU clock rate. + * + * ToDo: Maybe the bitrev macros can be used to improve the code? */ static inline u32 @@ -106,3 +108,67 @@ bitbang_txrx_be_cpha1(struct spi_device *spi, } return word; } + +static inline u32 +bitbang_txrx_le_cpha0(struct spi_device *spi, + unsigned int nsecs, unsigned int cpol, unsigned int flags, + u32 word, u8 bits) +{ + /* if (cpol == 0) this is SPI_MODE_0; else this is SPI_MODE_2 */ + + u32 oldbit = !(word & 1); + /* clock starts at inactive polarity */ + for (; likely(bits); bits--) { + + /* setup LSB (to slave) on trailing edge */ + if ((flags & SPI_MASTER_NO_TX) == 0) { + if ((word & 1) != oldbit) { + setmosi(spi, word & 1); + oldbit = word & 1; + } + } + spidelay(nsecs); /* T(setup) */ + + setsck(spi, !cpol); + spidelay(nsecs); + + /* sample LSB (from slave) on leading edge */ + word >>= 1; + if ((flags & SPI_MASTER_NO_RX) == 0) + word |= getmiso(spi) << (bits - 1); + setsck(spi, cpol); + } + return word; +} + +static inline u32 +bitbang_txrx_le_cpha1(struct spi_device *spi, + unsigned int nsecs, unsigned int cpol, unsigned int flags, + u32 word, u8 bits) +{ + /* if (cpol == 0) this is SPI_MODE_1; else this is SPI_MODE_3 */ + + u32 oldbit = !(word & 1); + /* clock starts at inactive polarity */ + for (; likely(bits); bits--) { + + /* setup LSB (to slave) on leading edge */ + setsck(spi, !cpol); + if ((flags & SPI_MASTER_NO_TX) == 0) { + if ((word & 1) != oldbit) { + setmosi(spi, word & 1); + oldbit = word & 1; + } + } + spidelay(nsecs); /* T(setup) */ + + setsck(spi, cpol); + spidelay(nsecs); + + /* sample LSB (from slave) on trailing edge */ + word >>= 1; + if ((flags & SPI_MASTER_NO_RX) == 0) + word |= getmiso(spi) << (bits - 1); + } + return word; +} |