Generalise three-wire interface to generic SPI interface.
[people/xl0/gpxe.git] / src / include / gpxe / spi.h
1 #ifndef _GPXE_SPI_H
2 #define _GPXE_SPI_H
3
4 /** @file
5  *
6  * SPI interface
7  *
8  */
9
10 #include <gpxe/bitbash.h>
11
12 /** An SPI interface */
13 struct spi_interface {
14         /** SPI interface mode
15          *
16          * This is the bitwise OR of zero or more of @c SPI_MODE_CPHA
17          * and @c SPI_MODE_CPOL.  It is also the number conventionally
18          * used to describe the SPI interface mode.  For example, SPI
19          * mode 1 is the mode in which CPOL=0 and CPHA=1, which
20          * therefore corresponds to a mode value of (0|SPI_MODE_CPHA)
21          * which, happily, equals 1.
22          */
23         unsigned int mode;
24         /**
25          * Select slave
26          *
27          * @v spi               SPI interface
28          * @v slave             Slave number
29          */
30         void ( * select_slave ) ( struct spi_interface *spi,
31                                   unsigned int slave );
32         /**
33          * Deselect slave
34          *
35          * @v spi               SPI interface
36          */
37         void ( * deselect_slave ) ( struct spi_interface *spi );
38         /**
39          * Transfer bits over SPI bit-bashing interface
40          *
41          * @v spi               SPI interface
42          * @v data_out          TX data buffer (or NULL)
43          * @v data_in           RX data buffer (or NULL)
44          * @v len               Length of transfer (in @b bits)
45          */
46         void ( * transfer ) ( struct spi_interface *spi, const void *data_out,
47                               void *data_in, unsigned int len );
48 };
49
50 /** Clock phase (CPHA) mode bit
51  *
52  * Phase 0 is sample on rising edge, shift data on falling edge.
53  *
54  * Phase 1 is shift data on rising edge, sample data on falling edge.
55  */
56 #define SPI_MODE_CPHA 0x01
57
58 /** Clock polarity (CPOL) mode bit
59  *
60  * This bit reflects the idle state of the clock line (SCLK).
61  */
62 #define SPI_MODE_CPOL 0x02
63
64 /** Slave select polarity mode bit
65  *
66  * This bit reflects that active state of the slave select lines.  It
67  * is not part of the normal SPI mode number (which covers only @c
68  * SPI_MODE_CPOL and @c SPI_MODE_CPHA), but is included here for
69  * convenience.
70  */
71 #define SPI_MODE_SSPOL 0x10
72
73 /** Microwire-compatible mode
74  *
75  * This is SPI mode 1 (i.e. CPOL=0, CPHA=1), and is compatible with
76  * the original Microwire protocol.
77  */
78 #define SPI_MODE_MICROWIRE 1
79
80 /** Microwire/Plus-compatible mode
81  *
82  * This is SPI mode 0 (i.e. CPOL=0, CPHA=0), and is compatible with
83  * the Microwire/Plus protocol
84  */
85 #define SPI_MODE_MICROWIRE_PLUS 0
86
87 /** Threewire-compatible mode
88  *
89  * This mode is compatible with Atmel's series of "three-wire"
90  * interfaces.
91  */
92 #define SPI_MODE_THREEWIRE ( SPI_MODE_MICROWIRE_PLUS | SPI_MODE_SSPOL )
93
94 /** A bit-bashing SPI interface */
95 struct spi_bit_basher {
96         /** SPI interface */
97         struct spi_interface spi;
98         /** Bit-bashing interface */
99         struct bit_basher basher;
100         /** Currently selected slave
101          *
102          * Valid only when a slave is actually selected.
103          */
104         unsigned int slave;
105 };
106
107 /** Bit indices used for SPI bit-bashing interface */
108 enum {
109         /** Serial clock */
110         SPI_BIT_SCLK = 0,
111         /** Master Out Slave In */
112         SPI_BIT_MOSI,
113         /** Master In Slave Out */
114         SPI_BIT_MISO,
115         /** Slave 0 select */
116         SPI_BIT_SS0,
117 };
118
119 /**
120  * Determine bit index for a particular slave
121  *
122  * @v slave             Slave number
123  * @ret index           Bit index (i.e. SPI_BIT_SSN, where N=slave) 
124  */
125 #define SPI_BIT_SS( slave ) ( SPI_BIT_SS0 + (slave) )
126
127 /** Delay between SCLK transitions */
128 #define SPI_UDELAY 1
129
130 extern void init_spi_bit_basher ( struct spi_bit_basher *spibit );
131
132 #endif /* _GPXE_SPI_H */