This patch adds support to the spi-bitbang driver for explicitly setting
what data is transmitted when the tx buffer is empty.
Either zeroes (the default), or ones (if SPI_TX_1 is set)
Signed-Off-By: Steve Bennett <[EMAIL PROTECTED]>
diff -urN uClinux-dist.orig/linux-2.6.x/include/linux/spi/spi.h
uClinux-dist/linux-2.6.x/include/linux/spi/spi.h
--- uClinux-dist.orig/linux-2.6.x/include/linux/spi/spi.h 2006-10-09
10:01:37.000000000 +1000
+++ uClinux-dist/linux-2.6.x/include/linux/spi/spi.h 2007-05-11
16:12:05.000000000 +1000
@@ -71,6 +71,7 @@
#define SPI_MODE_3 (SPI_CPOL|SPI_CPHA)
#define SPI_CS_HIGH 0x04 /* chipselect active
high? */
#define SPI_LSB_FIRST 0x08 /* per-word
bits-on-wire */
+#define SPI_TX_1 0x10 /* shift out ones on
rx-only */
u8 bits_per_word;
int irq;
void *controller_state;
@@ -289,8 +290,9 @@
* the data being transferred; that may reduce overhead, when the
* underlying driver uses dma.
*
- * If the transmit buffer is null, undefined data will be shifted out
- * while filling rx_buf. If the receive buffer is null, the data
+ * If the transmit buffer is null, zeroes will be shifted out while
+ * filling rx_buf, unless SPI_TX_1 is set in spi->mode (in which case
+ * ones will be shifted out). If the receive buffer is null, the data
* shifted in will be discarded. Only "len" bytes shift out (or in).
* It's an error to try to shift out a partial word. (For example, by
* shifting out three bytes with word size of sixteen or twenty bits;
diff -urN uClinux-dist.orig/linux-2.6.x/drivers/spi/spi_bitbang.c
uClinux-dist/linux-2.6.x/drivers/spi/spi_bitbang.c
--- uClinux-dist.orig/linux-2.6.x/drivers/spi/spi_bitbang.c 2006-10-09
10:01:44.000000000 +1000
+++ uClinux-dist/linux-2.6.x/drivers/spi/spi_bitbang.c 2007-05-11
16:12:05.000000000 +1000
@@ -73,10 +73,14 @@
u8 *rx = t->rx_buf;
while (likely(count > 0)) {
- u8 word = 0;
+ u8 word;
if (tx)
word = *tx++;
+ else if (spi->mode & SPI_TX_1)
+ word = ~0;
+ else
+ word = 0;
word = txrx_word(spi, ns, word, bits);
if (rx)
*rx++ = word;
@@ -99,10 +103,14 @@
u16 *rx = t->rx_buf;
while (likely(count > 1)) {
- u16 word = 0;
+ u16 word;
if (tx)
word = *tx++;
+ else if (spi->mode & SPI_TX_1)
+ word = ~0;
+ else
+ word = 0;
word = txrx_word(spi, ns, word, bits);
if (rx)
*rx++ = word;
@@ -125,10 +133,14 @@
u32 *rx = t->rx_buf;
while (likely(count > 3)) {
- u32 word = 0;
+ u32 word;
if (tx)
word = *tx++;
+ else if (spi->mode & SPI_TX_1)
+ word = ~0;
+ else
+ word = 0;
word = txrx_word(spi, ns, word, bits);
if (rx)
*rx++ = word;
@@ -176,6 +188,8 @@
}
EXPORT_SYMBOL_GPL(spi_bitbang_setup_transfer);
+#define MODEBITS (SPI_CPHA | SPI_CPOL | SPI_CS_HIGH | SPI_TX_1)
+
/**
* spi_bitbang_setup - default setup for per-word I/O loops
*/
@@ -192,8 +206,11 @@
* just bitbang_txrx_le_cphaX() routines shifting the other way, and
* some hardware controllers also have this support.
*/
- if ((spi->mode & SPI_LSB_FIRST) != 0)
+ if (spi->mode & ~MODEBITS) {
+ dev_dbg(&spi->dev, "unsupported SPI mode bits %04x\n",
+ spi->mode & ~MODEBITS);
return -EINVAL;
+ }
if (!cs) {
cs = kzalloc(sizeof *cs, SLAB_KERNEL);
_______________________________________________
uClinux-dev mailing list
[email protected]
http://mailman.uclinux.org/mailman/listinfo/uclinux-dev
This message was resent by [email protected]
To unsubscribe see:
http://mailman.uclinux.org/mailman/options/uclinux-dev