Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
drivers
spi
spi-bitbang-txrx.h
Go to the documentation of this file.
1
/*
2
* Mix this utility code with some glue code to get one of several types of
3
* simple SPI master driver. Two do polled word-at-a-time I/O:
4
*
5
* - GPIO/parport bitbangers. Provide chipselect() and txrx_word[](),
6
* expanding the per-word routines from the inline templates below.
7
*
8
* - Drivers for controllers resembling bare shift registers. Provide
9
* chipselect() and txrx_word[](), with custom setup()/cleanup() methods
10
* that use your controller's clock and chipselect registers.
11
*
12
* Some hardware works well with requests at spi_transfer scope:
13
*
14
* - Drivers leveraging smarter hardware, with fifos or DMA; or for half
15
* duplex (MicroWire) controllers. Provide chipselect() and txrx_bufs(),
16
* and custom setup()/cleanup() methods.
17
*/
18
19
/*
20
* The code that knows what GPIO pins do what should have declared four
21
* functions, ideally as inlines, before including this header:
22
*
23
* void setsck(struct spi_device *, int is_on);
24
* void setmosi(struct spi_device *, int is_on);
25
* int getmiso(struct spi_device *);
26
* void spidelay(unsigned);
27
*
28
* setsck()'s is_on parameter is a zero/nonzero boolean.
29
*
30
* setmosi()'s is_on parameter is a zero/nonzero boolean.
31
*
32
* getmiso() is required to return 0 or 1 only. Any other value is invalid
33
* and will result in improper operation.
34
*
35
* A non-inlined routine would call bitbang_txrx_*() routines. The
36
* main loop could easily compile down to a handful of instructions,
37
* especially if the delay is a NOP (to run at peak speed).
38
*
39
* Since this is software, the timings may not be exactly what your board's
40
* chips need ... there may be several reasons you'd need to tweak timings
41
* in these routines, not just make to make it faster or slower to match a
42
* particular CPU clock rate.
43
*/
44
45
static
inline
u32
46
bitbang_txrx_be_cpha0(
struct
spi_device
*
spi
,
47
unsigned
nsecs
,
unsigned
cpol,
unsigned
flags
,
48
u32
word
,
u8
bits
)
49
{
50
/* if (cpol == 0) this is SPI_MODE_0; else this is SPI_MODE_2 */
51
52
/* clock starts at inactive polarity */
53
for
(word <<= (32 - bits);
likely
(bits); bits--) {
54
55
/* setup MSB (to slave) on trailing edge */
56
if
((flags &
SPI_MASTER_NO_TX
) == 0)
57
setmosi(spi, word & (1 << 31));
58
spidelay
(nsecs);
/* T(setup) */
59
60
setsck(spi, !cpol);
61
spidelay
(nsecs);
62
63
/* sample MSB (from slave) on leading edge */
64
word <<= 1;
65
if
((flags &
SPI_MASTER_NO_RX
) == 0)
66
word |= getmiso(spi);
67
setsck(spi, cpol);
68
}
69
return
word
;
70
}
71
72
static
inline
u32
73
bitbang_txrx_be_cpha1(
struct
spi_device
*spi,
74
unsigned
nsecs,
unsigned
cpol,
unsigned
flags,
75
u32
word,
u8
bits)
76
{
77
/* if (cpol == 0) this is SPI_MODE_1; else this is SPI_MODE_3 */
78
79
/* clock starts at inactive polarity */
80
for
(word <<= (32 - bits);
likely
(bits); bits--) {
81
82
/* setup MSB (to slave) on leading edge */
83
setsck(spi, !cpol);
84
if
((flags & SPI_MASTER_NO_TX) == 0)
85
setmosi(spi, word & (1 << 31));
86
spidelay
(nsecs);
/* T(setup) */
87
88
setsck(spi, cpol);
89
spidelay
(nsecs);
90
91
/* sample MSB (from slave) on trailing edge */
92
word <<= 1;
93
if
((flags &
SPI_MASTER_NO_RX
) == 0)
94
word |= getmiso(spi);
95
}
96
return
word
;
97
}
Generated on Thu Jan 10 2013 14:25:31 for Linux Kernel by
1.8.2