Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

spi: new spi->mode bits

Add two new spi_device.mode bits to accomodate more protocol options, and
pass them through to usermode drivers:

* SPI_NO_CS ... a second 3-wire variant, where the chipselect
line is removed instead of a data line; transfers are still
full duplex.

This obviously has STRONG protocol implications since the
chipselect transitions can't be used to synchronize state
transitions with the SPI master.

* SPI_READY ... defines open drain signal that's pulled low
to pause the clock. This defines a 5-wire variant (normal
4-wire SPI plus READY) and two 4-wire variants (READY plus
each of the 3-wire flavors).

Such hardware flow control can be a big win. There are ADC
converters and flash chips that expose READY signals, but not
many host controllers support it today.

The spi_bitbang code should be changed to use SPI_NO_CS instead of its
current nonportable hack. That's a mode most hardware can easily support
(unlike SPI_READY).

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Cc: "Paulraj, Sandeep" <s-paulraj@ti.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

David Brownell and committed by
Linus Torvalds
b55f627f c4956823

+24 -7
+9 -1
Documentation/spi/spidev_test.c
··· 99 99 { "lsb", 0, 0, 'L' }, 100 100 { "cs-high", 0, 0, 'C' }, 101 101 { "3wire", 0, 0, '3' }, 102 + { "no-cs", 0, 0, 'N' }, 103 + { "ready", 0, 0, 'R' }, 102 104 { NULL, 0, 0, 0 }, 103 105 }; 104 106 int c; 105 107 106 - c = getopt_long(argc, argv, "D:s:d:b:lHOLC3", lopts, NULL); 108 + c = getopt_long(argc, argv, "D:s:d:b:lHOLC3NR", lopts, NULL); 107 109 108 110 if (c == -1) 109 111 break; ··· 140 138 break; 141 139 case '3': 142 140 mode |= SPI_3WIRE; 141 + break; 142 + case 'N': 143 + mode |= SPI_NO_CS; 144 + break; 145 + case 'R': 146 + mode |= SPI_READY; 143 147 break; 144 148 default: 145 149 print_usage(argv[0]);
+11 -6
drivers/spi/spidev.c
··· 58 58 59 59 60 60 /* Bit masks for spi_device.mode management. Note that incorrect 61 - * settings for CS_HIGH and 3WIRE can cause *lots* of trouble for other 62 - * devices on a shared bus: CS_HIGH, because this device will be 63 - * active when it shouldn't be; 3WIRE, because when active it won't 64 - * behave as it should. 61 + * settings for some settings can cause *lots* of trouble for other 62 + * devices on a shared bus: 65 63 * 66 - * REVISIT should changing those two modes be privileged? 64 + * - CS_HIGH ... this device will be active when it shouldn't be 65 + * - 3WIRE ... when active, it won't behave as it should 66 + * - NO_CS ... there will be no explicit message boundaries; this 67 + * is completely incompatible with the shared bus model 68 + * - READY ... transfers may proceed when they shouldn't. 69 + * 70 + * REVISIT should changing those flags be privileged? 67 71 */ 68 72 #define SPI_MODE_MASK (SPI_CPHA | SPI_CPOL | SPI_CS_HIGH \ 69 - | SPI_LSB_FIRST | SPI_3WIRE | SPI_LOOP) 73 + | SPI_LSB_FIRST | SPI_3WIRE | SPI_LOOP \ 74 + | SPI_NO_CS | SPI_READY) 70 75 71 76 struct spidev_data { 72 77 dev_t devt;
+2
include/linux/spi/spi.h
··· 80 80 #define SPI_LSB_FIRST 0x08 /* per-word bits-on-wire */ 81 81 #define SPI_3WIRE 0x10 /* SI/SO signals shared */ 82 82 #define SPI_LOOP 0x20 /* loopback mode */ 83 + #define SPI_NO_CS 0x40 /* 1 dev/bus, no chipselect */ 84 + #define SPI_READY 0x80 /* slave pulls low to pause */ 83 85 u8 bits_per_word; 84 86 int irq; 85 87 void *controller_state;
+2
include/linux/spi/spidev.h
··· 40 40 #define SPI_LSB_FIRST 0x08 41 41 #define SPI_3WIRE 0x10 42 42 #define SPI_LOOP 0x20 43 + #define SPI_NO_CS 0x40 44 + #define SPI_READY 0x80 43 45 44 46 /*---------------------------------------------------------------------------*/ 45 47