diff options
| author | David Brownell <dbrownell@users.sourceforge.net> | 2009-06-30 11:41:26 -0700 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-30 18:56:00 -0700 | 
| commit | b55f627feeb9d48fdbde3835e18afbc76712e49b (patch) | |
| tree | 1c6084d44f23c5e70040e5d62c93718f77ad09da | |
| parent | c49568235dd7b4a2ffad63aa950562f4ffb9455f (diff) | |
| download | olio-linux-3.10-b55f627feeb9d48fdbde3835e18afbc76712e49b.tar.xz olio-linux-3.10-b55f627feeb9d48fdbde3835e18afbc76712e49b.zip  | |
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>
| -rw-r--r-- | Documentation/spi/spidev_test.c | 10 | ||||
| -rw-r--r-- | drivers/spi/spidev.c | 17 | ||||
| -rw-r--r-- | include/linux/spi/spi.h | 2 | ||||
| -rw-r--r-- | include/linux/spi/spidev.h | 2 | 
4 files changed, 24 insertions, 7 deletions
diff --git a/Documentation/spi/spidev_test.c b/Documentation/spi/spidev_test.c index cf0e3ce0d52..c1a5aad3c75 100644 --- a/Documentation/spi/spidev_test.c +++ b/Documentation/spi/spidev_test.c @@ -99,11 +99,13 @@ void parse_opts(int argc, char *argv[])  			{ "lsb",     0, 0, 'L' },  			{ "cs-high", 0, 0, 'C' },  			{ "3wire",   0, 0, '3' }, +			{ "no-cs",   0, 0, 'N' }, +			{ "ready",   0, 0, 'R' },  			{ NULL, 0, 0, 0 },  		};  		int c; -		c = getopt_long(argc, argv, "D:s:d:b:lHOLC3", lopts, NULL); +		c = getopt_long(argc, argv, "D:s:d:b:lHOLC3NR", lopts, NULL);  		if (c == -1)  			break; @@ -139,6 +141,12 @@ void parse_opts(int argc, char *argv[])  		case '3':  			mode |= SPI_3WIRE;  			break; +		case 'N': +			mode |= SPI_NO_CS; +			break; +		case 'R': +			mode |= SPI_READY; +			break;  		default:  			print_usage(argv[0]);  			break; diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c index 5d869c4d3eb..606e7a40a8d 100644 --- a/drivers/spi/spidev.c +++ b/drivers/spi/spidev.c @@ -58,15 +58,20 @@ static unsigned long	minors[N_SPI_MINORS / BITS_PER_LONG];  /* Bit masks for spi_device.mode management.  Note that incorrect - * settings for CS_HIGH and 3WIRE can cause *lots* of trouble for other - * devices on a shared bus:  CS_HIGH, because this device will be - * active when it shouldn't be;  3WIRE, because when active it won't - * behave as it should. + * settings for some settings can cause *lots* of trouble for other + * devices on a shared bus:   * - * REVISIT should changing those two modes be privileged? + *  - CS_HIGH ... this device will be active when it shouldn't be + *  - 3WIRE ... when active, it won't behave as it should + *  - NO_CS ... there will be no explicit message boundaries; this + *	is completely incompatible with the shared bus model + *  - READY ... transfers may proceed when they shouldn't. + * + * REVISIT should changing those flags be privileged?   */  #define SPI_MODE_MASK		(SPI_CPHA | SPI_CPOL | SPI_CS_HIGH \ -				| SPI_LSB_FIRST | SPI_3WIRE | SPI_LOOP) +				| SPI_LSB_FIRST | SPI_3WIRE | SPI_LOOP \ +				| SPI_NO_CS | SPI_READY)  struct spidev_data {  	dev_t			devt; diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index 9c4cd27f468..743c933ac4e 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -80,6 +80,8 @@ struct spi_device {  #define	SPI_LSB_FIRST	0x08			/* per-word bits-on-wire */  #define	SPI_3WIRE	0x10			/* SI/SO signals shared */  #define	SPI_LOOP	0x20			/* loopback mode */ +#define	SPI_NO_CS	0x40			/* 1 dev/bus, no chipselect */ +#define	SPI_READY	0x80			/* slave pulls low to pause */  	u8			bits_per_word;  	int			irq;  	void			*controller_state; diff --git a/include/linux/spi/spidev.h b/include/linux/spi/spidev.h index 95251ccd5a0..bf0570a84f7 100644 --- a/include/linux/spi/spidev.h +++ b/include/linux/spi/spidev.h @@ -40,6 +40,8 @@  #define SPI_LSB_FIRST		0x08  #define SPI_3WIRE		0x10  #define SPI_LOOP		0x20 +#define SPI_NO_CS		0x40 +#define SPI_READY		0x80  /*---------------------------------------------------------------------------*/  |