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

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.29-rc1 146 lines 4.4 kB view raw
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 22#include <linux/workqueue.h> 23 24struct spi_bitbang { 25 struct workqueue_struct *workqueue; 26 struct work_struct work; 27 28 spinlock_t lock; 29 struct list_head queue; 30 u8 busy; 31 u8 use_dma; 32 u8 flags; /* extra spi->mode support */ 33 34 struct spi_master *master; 35 36 /* setup_transfer() changes clock and/or wordsize to match settings 37 * for this transfer; zeroes restore defaults from spi_device. 38 */ 39 int (*setup_transfer)(struct spi_device *spi, 40 struct spi_transfer *t); 41 42 void (*chipselect)(struct spi_device *spi, int is_on); 43#define BITBANG_CS_ACTIVE 1 /* normally nCS, active low */ 44#define BITBANG_CS_INACTIVE 0 45 46 /* txrx_bufs() may handle dma mapping for transfers that don't 47 * already have one (transfer.{tx,rx}_dma is zero), or use PIO 48 */ 49 int (*txrx_bufs)(struct spi_device *spi, struct spi_transfer *t); 50 51 /* txrx_word[SPI_MODE_*]() just looks like a shift register */ 52 u32 (*txrx_word[4])(struct spi_device *spi, 53 unsigned nsecs, 54 u32 word, u8 bits); 55}; 56 57/* you can call these default bitbang->master methods from your custom 58 * methods, if you like. 59 */ 60extern int spi_bitbang_setup(struct spi_device *spi); 61extern void spi_bitbang_cleanup(struct spi_device *spi); 62extern int spi_bitbang_transfer(struct spi_device *spi, struct spi_message *m); 63extern int spi_bitbang_setup_transfer(struct spi_device *spi, 64 struct spi_transfer *t); 65 66/* start or stop queue processing */ 67extern int spi_bitbang_start(struct spi_bitbang *spi); 68extern int spi_bitbang_stop(struct spi_bitbang *spi); 69 70#endif /* __SPI_BITBANG_H */ 71 72/*-------------------------------------------------------------------------*/ 73 74#ifdef EXPAND_BITBANG_TXRX 75 76/* 77 * The code that knows what GPIO pins do what should have declared four 78 * functions, ideally as inlines, before #defining EXPAND_BITBANG_TXRX 79 * and including this header: 80 * 81 * void setsck(struct spi_device *, int is_on); 82 * void setmosi(struct spi_device *, int is_on); 83 * int getmiso(struct spi_device *); 84 * void spidelay(unsigned); 85 * 86 * A non-inlined routine would call bitbang_txrx_*() routines. The 87 * main loop could easily compile down to a handful of instructions, 88 * especially if the delay is a NOP (to run at peak speed). 89 * 90 * Since this is software, the timings may not be exactly what your board's 91 * chips need ... there may be several reasons you'd need to tweak timings 92 * in these routines, not just make to make it faster or slower to match a 93 * particular CPU clock rate. 94 */ 95 96static inline u32 97bitbang_txrx_be_cpha0(struct spi_device *spi, 98 unsigned nsecs, unsigned cpol, 99 u32 word, u8 bits) 100{ 101 /* if (cpol == 0) this is SPI_MODE_0; else this is SPI_MODE_2 */ 102 103 /* clock starts at inactive polarity */ 104 for (word <<= (32 - bits); likely(bits); bits--) { 105 106 /* setup MSB (to slave) on trailing edge */ 107 setmosi(spi, word & (1 << 31)); 108 spidelay(nsecs); /* T(setup) */ 109 110 setsck(spi, !cpol); 111 spidelay(nsecs); 112 113 /* sample MSB (from slave) on leading edge */ 114 word <<= 1; 115 word |= getmiso(spi); 116 setsck(spi, cpol); 117 } 118 return word; 119} 120 121static inline u32 122bitbang_txrx_be_cpha1(struct spi_device *spi, 123 unsigned nsecs, unsigned cpol, 124 u32 word, u8 bits) 125{ 126 /* if (cpol == 0) this is SPI_MODE_1; else this is SPI_MODE_3 */ 127 128 /* clock starts at inactive polarity */ 129 for (word <<= (32 - bits); likely(bits); bits--) { 130 131 /* setup MSB (to slave) on leading edge */ 132 setsck(spi, !cpol); 133 setmosi(spi, word & (1 << 31)); 134 spidelay(nsecs); /* T(setup) */ 135 136 setsck(spi, cpol); 137 spidelay(nsecs); 138 139 /* sample MSB (from slave) on trailing edge */ 140 word <<= 1; 141 word |= getmiso(spi); 142 } 143 return word; 144} 145 146#endif /* EXPAND_BITBANG_TXRX */