Commit b55f627feeb9d48fdbde3835e18afbc76712e49b

Authored by David Brownell
Committed by Linus Torvalds
1 parent c49568235d

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>

Showing 4 changed files with 24 additions and 7 deletions Side-by-side Diff

Documentation/spi/spidev_test.c
... ... @@ -99,11 +99,13 @@
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;
... ... @@ -138,6 +140,12 @@
138 140 break;
139 141 case '3':
140 142 mode |= SPI_3WIRE;
  143 + break;
  144 + case 'N':
  145 + mode |= SPI_NO_CS;
  146 + break;
  147 + case 'R':
  148 + mode |= SPI_READY;
141 149 break;
142 150 default:
143 151 print_usage(argv[0]);
drivers/spi/spidev.c
... ... @@ -58,15 +58,20 @@
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;
include/linux/spi/spi.h
... ... @@ -80,6 +80,8 @@
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;
include/linux/spi/spidev.h
... ... @@ -40,6 +40,8 @@
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