| David Brownell | 9904f22 | 2006-01-08 13:34:26 -0800 | [diff] [blame] | 1 | #ifndef	__SPI_BITBANG_H | 
|  | 2 | #define	__SPI_BITBANG_H | 
|  | 3 |  | 
|  | 4 | /* | 
|  | 5 | * Mix this utility code with some glue code to get one of several types of | 
|  | 6 | * simple SPI master driver.  Two do polled word-at-a-time I/O: | 
|  | 7 | * | 
|  | 8 | *   -	GPIO/parport bitbangers.  Provide chipselect() and txrx_word[](), | 
|  | 9 | *	expanding the per-word routines from the inline templates below. | 
|  | 10 | * | 
|  | 11 | *   -	Drivers for controllers resembling bare shift registers.  Provide | 
|  | 12 | *	chipselect() and txrx_word[](), with custom setup()/cleanup() methods | 
|  | 13 | *	that use your controller's clock and chipselect registers. | 
|  | 14 | * | 
|  | 15 | * Some hardware works well with requests at spi_transfer scope: | 
|  | 16 | * | 
|  | 17 | *   -	Drivers leveraging smarter hardware, with fifos or DMA; or for half | 
|  | 18 | *	duplex (MicroWire) controllers.  Provide chipslect() and txrx_bufs(), | 
|  | 19 | *	and custom setup()/cleanup() methods. | 
|  | 20 | */ | 
|  | 21 | struct spi_bitbang { | 
|  | 22 | struct workqueue_struct	*workqueue; | 
|  | 23 | struct work_struct	work; | 
|  | 24 |  | 
|  | 25 | spinlock_t		lock; | 
|  | 26 | struct list_head	queue; | 
|  | 27 | u8			busy; | 
| David Brownell | 9904f22 | 2006-01-08 13:34:26 -0800 | [diff] [blame] | 28 | u8			use_dma; | 
| David Brownell | dccd573 | 2007-07-17 04:04:02 -0700 | [diff] [blame] | 29 | u8			flags;		/* extra spi->mode support */ | 
| David Brownell | 9904f22 | 2006-01-08 13:34:26 -0800 | [diff] [blame] | 30 |  | 
|  | 31 | struct spi_master	*master; | 
|  | 32 |  | 
| Imre Deak | 4cff33f | 2006-02-17 10:02:18 -0800 | [diff] [blame] | 33 | /* setup_transfer() changes clock and/or wordsize to match settings | 
|  | 34 | * for this transfer; zeroes restore defaults from spi_device. | 
|  | 35 | */ | 
|  | 36 | int	(*setup_transfer)(struct spi_device *spi, | 
|  | 37 | struct spi_transfer *t); | 
|  | 38 |  | 
| David Brownell | 9904f22 | 2006-01-08 13:34:26 -0800 | [diff] [blame] | 39 | void	(*chipselect)(struct spi_device *spi, int is_on); | 
| Vitaly Wool | 8275c64 | 2006-01-08 13:34:28 -0800 | [diff] [blame] | 40 | #define	BITBANG_CS_ACTIVE	1	/* normally nCS, active low */ | 
|  | 41 | #define	BITBANG_CS_INACTIVE	0 | 
| David Brownell | 9904f22 | 2006-01-08 13:34:26 -0800 | [diff] [blame] | 42 |  | 
| Vitaly Wool | 8275c64 | 2006-01-08 13:34:28 -0800 | [diff] [blame] | 43 | /* txrx_bufs() may handle dma mapping for transfers that don't | 
|  | 44 | * already have one (transfer.{tx,rx}_dma is zero), or use PIO | 
|  | 45 | */ | 
| David Brownell | 9904f22 | 2006-01-08 13:34:26 -0800 | [diff] [blame] | 46 | int	(*txrx_bufs)(struct spi_device *spi, struct spi_transfer *t); | 
| Vitaly Wool | 8275c64 | 2006-01-08 13:34:28 -0800 | [diff] [blame] | 47 |  | 
|  | 48 | /* txrx_word[SPI_MODE_*]() just looks like a shift register */ | 
| David Brownell | 9904f22 | 2006-01-08 13:34:26 -0800 | [diff] [blame] | 49 | u32	(*txrx_word[4])(struct spi_device *spi, | 
|  | 50 | unsigned nsecs, | 
|  | 51 | u32 word, u8 bits); | 
|  | 52 | }; | 
|  | 53 |  | 
|  | 54 | /* you can call these default bitbang->master methods from your custom | 
|  | 55 | * methods, if you like. | 
|  | 56 | */ | 
|  | 57 | extern int spi_bitbang_setup(struct spi_device *spi); | 
| Hans-Peter Nilsson | 0ffa028 | 2007-02-12 00:52:45 -0800 | [diff] [blame] | 58 | extern void spi_bitbang_cleanup(struct spi_device *spi); | 
| David Brownell | 9904f22 | 2006-01-08 13:34:26 -0800 | [diff] [blame] | 59 | extern int spi_bitbang_transfer(struct spi_device *spi, struct spi_message *m); | 
| Kumar Gala | ff9f477 | 2006-04-02 16:06:35 -0500 | [diff] [blame] | 60 | extern int spi_bitbang_setup_transfer(struct spi_device *spi, | 
|  | 61 | struct spi_transfer *t); | 
| David Brownell | 9904f22 | 2006-01-08 13:34:26 -0800 | [diff] [blame] | 62 |  | 
|  | 63 | /* start or stop queue processing */ | 
|  | 64 | extern int spi_bitbang_start(struct spi_bitbang *spi); | 
|  | 65 | extern int spi_bitbang_stop(struct spi_bitbang *spi); | 
|  | 66 |  | 
|  | 67 | #endif	/* __SPI_BITBANG_H */ | 
|  | 68 |  | 
|  | 69 | /*-------------------------------------------------------------------------*/ | 
|  | 70 |  | 
|  | 71 | #ifdef	EXPAND_BITBANG_TXRX | 
|  | 72 |  | 
|  | 73 | /* | 
|  | 74 | * The code that knows what GPIO pins do what should have declared four | 
|  | 75 | * functions, ideally as inlines, before #defining EXPAND_BITBANG_TXRX | 
|  | 76 | * and including this header: | 
|  | 77 | * | 
|  | 78 | *  void setsck(struct spi_device *, int is_on); | 
|  | 79 | *  void setmosi(struct spi_device *, int is_on); | 
|  | 80 | *  int getmiso(struct spi_device *); | 
|  | 81 | *  void spidelay(unsigned); | 
|  | 82 | * | 
|  | 83 | * A non-inlined routine would call bitbang_txrx_*() routines.  The | 
|  | 84 | * main loop could easily compile down to a handful of instructions, | 
|  | 85 | * especially if the delay is a NOP (to run at peak speed). | 
|  | 86 | * | 
|  | 87 | * Since this is software, the timings may not be exactly what your board's | 
|  | 88 | * chips need ... there may be several reasons you'd need to tweak timings | 
|  | 89 | * in these routines, not just make to make it faster or slower to match a | 
|  | 90 | * particular CPU clock rate. | 
|  | 91 | */ | 
|  | 92 |  | 
|  | 93 | static inline u32 | 
|  | 94 | bitbang_txrx_be_cpha0(struct spi_device *spi, | 
|  | 95 | unsigned nsecs, unsigned cpol, | 
|  | 96 | u32 word, u8 bits) | 
|  | 97 | { | 
|  | 98 | /* if (cpol == 0) this is SPI_MODE_0; else this is SPI_MODE_2 */ | 
|  | 99 |  | 
|  | 100 | /* clock starts at inactive polarity */ | 
|  | 101 | for (word <<= (32 - bits); likely(bits); bits--) { | 
|  | 102 |  | 
|  | 103 | /* setup MSB (to slave) on trailing edge */ | 
|  | 104 | setmosi(spi, word & (1 << 31)); | 
|  | 105 | spidelay(nsecs);	/* T(setup) */ | 
|  | 106 |  | 
|  | 107 | setsck(spi, !cpol); | 
|  | 108 | spidelay(nsecs); | 
|  | 109 |  | 
|  | 110 | /* sample MSB (from slave) on leading edge */ | 
|  | 111 | word <<= 1; | 
|  | 112 | word |= getmiso(spi); | 
|  | 113 | setsck(spi, cpol); | 
|  | 114 | } | 
|  | 115 | return word; | 
|  | 116 | } | 
|  | 117 |  | 
|  | 118 | static inline u32 | 
|  | 119 | bitbang_txrx_be_cpha1(struct spi_device *spi, | 
|  | 120 | unsigned nsecs, unsigned cpol, | 
|  | 121 | u32 word, u8 bits) | 
|  | 122 | { | 
|  | 123 | /* if (cpol == 0) this is SPI_MODE_1; else this is SPI_MODE_3 */ | 
|  | 124 |  | 
|  | 125 | /* clock starts at inactive polarity */ | 
|  | 126 | for (word <<= (32 - bits); likely(bits); bits--) { | 
|  | 127 |  | 
|  | 128 | /* setup MSB (to slave) on leading edge */ | 
|  | 129 | setsck(spi, !cpol); | 
|  | 130 | setmosi(spi, word & (1 << 31)); | 
|  | 131 | spidelay(nsecs); /* T(setup) */ | 
|  | 132 |  | 
|  | 133 | setsck(spi, cpol); | 
|  | 134 | spidelay(nsecs); | 
|  | 135 |  | 
|  | 136 | /* sample MSB (from slave) on trailing edge */ | 
|  | 137 | word <<= 1; | 
|  | 138 | word |= getmiso(spi); | 
|  | 139 | } | 
|  | 140 | return word; | 
|  | 141 | } | 
|  | 142 |  | 
|  | 143 | #endif	/* EXPAND_BITBANG_TXRX */ |