1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27#include <common.h>
28#include <spi.h>
29
30#if defined(CONFIG_SOFT_SPI)
31
32#include <malloc.h>
33
34
35
36
37
38#ifdef DEBUG_SPI
39#define PRINTD(fmt,args...) printf (fmt ,##args)
40#else
41#define PRINTD(fmt,args...)
42#endif
43
44struct soft_spi_slave {
45 struct spi_slave slave;
46 unsigned int mode;
47};
48
49static inline struct soft_spi_slave *to_soft_spi(struct spi_slave *slave)
50{
51 return container_of(slave, struct soft_spi_slave, slave);
52}
53
54
55
56
57
58
59
60
61void spi_init (void)
62{
63#ifdef SPI_INIT
64 volatile immap_t *immr = (immap_t *)CFG_IMMR;
65
66 SPI_INIT;
67#endif
68}
69
70struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
71 unsigned int max_hz, unsigned int mode)
72{
73 struct soft_spi_slave *ss;
74
75 if (!spi_cs_is_valid(bus, cs))
76 return NULL;
77
78 ss = malloc(sizeof(struct soft_spi_slave));
79 if (!ss)
80 return NULL;
81
82 ss->slave.bus = bus;
83 ss->slave.cs = cs;
84 ss->mode = mode;
85
86
87
88 return &ss->slave;
89}
90
91void spi_free_slave(struct spi_slave *slave)
92{
93 struct soft_spi_slave *ss = to_soft_spi(slave);
94
95 free(ss);
96}
97
98int spi_claim_bus(struct spi_slave *slave)
99{
100#ifdef CFG_IMMR
101 volatile immap_t *immr = (immap_t *)CFG_IMMR;
102#endif
103 struct soft_spi_slave *ss = to_soft_spi(slave);
104
105
106
107
108
109 if (ss->mode & SPI_CPOL)
110 SPI_SCL(1);
111 else
112 SPI_SCL(0);
113
114 return 0;
115}
116
117void spi_release_bus(struct spi_slave *slave)
118{
119
120}
121
122
123
124
125
126
127
128
129
130
131
132
133
134int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
135 const void *dout, void *din, unsigned long flags)
136{
137#ifdef CFG_IMMR
138 volatile immap_t *immr = (immap_t *)CFG_IMMR;
139#endif
140 struct soft_spi_slave *ss = to_soft_spi(slave);
141 uchar tmpdin = 0;
142 uchar tmpdout = 0;
143 const u8 *txd = dout;
144 u8 *rxd = din;
145 int cpol = ss->mode & SPI_CPOL;
146 int cpha = ss->mode & SPI_CPHA;
147 unsigned int j;
148
149 PRINTD("spi_xfer: slave %u:%u dout %08X din %08X bitlen %u\n",
150 slave->bus, slave->cs, *(uint *)txd, *(uint *)rxd, bitlen);
151
152 if (flags & SPI_XFER_BEGIN)
153 spi_cs_activate(slave);
154
155 for(j = 0; j < bitlen; j++) {
156
157
158
159 if((j % 8) == 0) {
160 tmpdout = *txd++;
161 if(j != 0) {
162 *rxd++ = tmpdin;
163 }
164 tmpdin = 0;
165 }
166
167 if (!cpha)
168 SPI_SCL(!cpol);
169 SPI_SDA(tmpdout & 0x80);
170 SPI_DELAY;
171 if (cpha)
172 SPI_SCL(!cpol);
173 else
174 SPI_SCL(cpol);
175 tmpdin <<= 1;
176 tmpdin |= SPI_READ;
177 tmpdout <<= 1;
178 SPI_DELAY;
179 if (cpha)
180 SPI_SCL(cpol);
181 }
182
183
184
185
186
187 if((bitlen % 8) != 0)
188 tmpdin <<= 8 - (bitlen % 8);
189 *rxd++ = tmpdin;
190
191 if (flags & SPI_XFER_END)
192 spi_cs_deactivate(slave);
193
194 return(0);
195}
196
197#endif
198