FreeBSD/Linux Kernel Cross Reference
sys/dev/gpio/gpiospi.c
1 /*-
2 * Copyright (c) 2011, Aleksandr Rybalko <ray@dlink.ua>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice unmodified, this list of conditions, and the following
10 * disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
30
31 #include "opt_gpio.h"
32
33 #include <sys/param.h>
34 #include <sys/systm.h>
35
36 #include <sys/bus.h>
37 #include <sys/kernel.h>
38 #include <sys/module.h>
39 #include <sys/rman.h>
40 #include <sys/sysctl.h>
41
42 #include <sys/gpio.h>
43 #include "gpiobus_if.h"
44
45 #include <dev/gpio/gpiobusvar.h>
46
47 #include <dev/spibus/spi.h>
48 #include <dev/spibus/spibusvar.h>
49 #include "spibus_if.h"
50
51 #ifdef GPIO_SPI_DEBUG
52 #define dprintf printf
53 #else
54 #define dprintf(x, arg...)
55 #endif /* GPIO_SPI_DEBUG */
56
57 struct gpio_spi_softc {
58 device_t sc_dev;
59 device_t sc_busdev;
60 int sc_freq;
61 uint8_t sc_sclk;
62 uint8_t sc_miso;
63 uint8_t sc_mosi;
64 uint8_t sc_cs0;
65 uint8_t sc_cs1;
66 uint8_t sc_cs2;
67 uint8_t sc_cs3;
68 };
69
70 static void gpio_spi_chip_activate(struct gpio_spi_softc *, int);
71 static void gpio_spi_chip_deactivate(struct gpio_spi_softc *, int);
72
73 static int
74 gpio_spi_probe(device_t dev)
75 {
76 device_set_desc(dev, "GPIO SPI bit-banging driver");
77 return (0);
78 }
79
80 static void
81 gpio_delay(struct gpio_spi_softc *sc)
82 {
83 int d;
84
85 d = sc->sc_freq / 1000000;
86 if (d == 0)
87 d = 1;
88
89 DELAY(d);
90 }
91
92 static int
93 gpio_spi_attach(device_t dev)
94 {
95 uint32_t value;
96 struct gpio_spi_softc *sc;
97
98 sc = device_get_softc(dev);
99 sc->sc_dev = dev;
100 sc->sc_busdev = device_get_parent(dev);
101
102 /* Required variables */
103 if (resource_int_value(device_get_name(dev),
104 device_get_unit(dev), "sclk", &value))
105 return (ENXIO);
106 sc->sc_sclk = value & 0xff;
107
108 if (resource_int_value(device_get_name(dev),
109 device_get_unit(dev), "mosi", &value))
110 return (ENXIO);
111 sc->sc_mosi = value & 0xff;
112
113 /* Handle no miso; we just never read back from the device */
114 if (resource_int_value(device_get_name(dev),
115 device_get_unit(dev), "miso", &value))
116 value = 0xff;
117 sc->sc_miso = value & 0xff;
118
119 if (resource_int_value(device_get_name(dev),
120 device_get_unit(dev), "cs0", &value))
121 return (ENXIO);
122 sc->sc_cs0 = value & 0xff;
123
124 /* Optional variables */
125 if (resource_int_value(device_get_name(dev),
126 device_get_unit(dev), "cs1", &value))
127 value = 0xff;
128 sc->sc_cs1 = value & 0xff;
129
130 if (resource_int_value(device_get_name(dev),
131 device_get_unit(dev), "cs2", &value))
132 value = 0xff;
133 sc->sc_cs2 = value & 0xff;
134
135 if (resource_int_value(device_get_name(dev),
136 device_get_unit(dev), "cs3", &value))
137 value = 0xff;
138 sc->sc_cs3 = value & 0xff;
139
140 /* Default to 100KHz */
141 if (resource_int_value(device_get_name(dev),
142 device_get_unit(dev), "freq", &value)) {
143 value = 100000;
144 }
145 sc->sc_freq = value;
146
147 if (bootverbose) {
148 device_printf(dev, "frequency: %d Hz\n",
149 sc->sc_freq);
150 device_printf(dev,
151 "Use GPIO pins: sclk=%d, mosi=%d, miso=%d, "
152 "cs0=%d, cs1=%d, cs2=%d, cs3=%d\n",
153 sc->sc_sclk, sc->sc_mosi, sc->sc_miso,
154 sc->sc_cs0, sc->sc_cs1, sc->sc_cs2, sc->sc_cs3);
155 }
156
157 /* Set directions */
158 GPIOBUS_PIN_SETFLAGS(sc->sc_busdev, sc->sc_dev, sc->sc_sclk,
159 GPIO_PIN_OUTPUT|GPIO_PIN_PULLDOWN);
160 GPIOBUS_PIN_SETFLAGS(sc->sc_busdev, sc->sc_dev, sc->sc_mosi,
161 GPIO_PIN_OUTPUT|GPIO_PIN_PULLDOWN);
162 if (sc->sc_miso != 0xff) {
163 GPIOBUS_PIN_SETFLAGS(sc->sc_busdev, sc->sc_dev, sc->sc_miso,
164 GPIO_PIN_INPUT|GPIO_PIN_PULLDOWN);
165 }
166
167 GPIOBUS_PIN_SETFLAGS(sc->sc_busdev, sc->sc_dev, sc->sc_cs0,
168 GPIO_PIN_OUTPUT|GPIO_PIN_PULLUP);
169
170 if (sc->sc_cs1 != 0xff)
171 GPIOBUS_PIN_SETFLAGS(sc->sc_busdev, sc->sc_dev, sc->sc_cs1,
172 GPIO_PIN_OUTPUT|GPIO_PIN_PULLUP);
173 if (sc->sc_cs2 != 0xff)
174 GPIOBUS_PIN_SETFLAGS(sc->sc_busdev, sc->sc_dev, sc->sc_cs2,
175 GPIO_PIN_OUTPUT|GPIO_PIN_PULLUP);
176 if (sc->sc_cs3 != 0xff)
177 GPIOBUS_PIN_SETFLAGS(sc->sc_busdev, sc->sc_dev, sc->sc_cs3,
178 GPIO_PIN_OUTPUT|GPIO_PIN_PULLUP);
179
180 gpio_spi_chip_deactivate(sc, -1);
181
182 device_add_child(dev, "spibus", -1);
183 return (bus_generic_attach(dev));
184 }
185
186 static int
187 gpio_spi_detach(device_t dev)
188 {
189
190 return (0);
191 }
192
193 static void
194 gpio_spi_chip_activate(struct gpio_spi_softc *sc, int cs)
195 {
196
197 /* called with locked gpiobus */
198 switch (cs) {
199 case 0:
200 GPIOBUS_PIN_SET(sc->sc_busdev, sc->sc_dev,
201 sc->sc_cs0, 0);
202 break;
203 case 1:
204 GPIOBUS_PIN_SET(sc->sc_busdev, sc->sc_dev,
205 sc->sc_cs1, 0);
206 break;
207 case 2:
208 GPIOBUS_PIN_SET(sc->sc_busdev, sc->sc_dev,
209 sc->sc_cs2, 0);
210 break;
211 case 3:
212 GPIOBUS_PIN_SET(sc->sc_busdev, sc->sc_dev,
213 sc->sc_cs3, 0);
214 break;
215 default:
216 device_printf(sc->sc_dev, "don't have CS%d\n", cs);
217 }
218
219 gpio_delay(sc);
220 }
221
222 static void
223 gpio_spi_chip_deactivate(struct gpio_spi_softc *sc, int cs)
224 {
225
226 /* called wth locked gpiobus */
227 /*
228 * Put CSx to high
229 */
230 switch (cs) {
231 case -1:
232 /* All CS */
233 GPIOBUS_PIN_SET(sc->sc_busdev, sc->sc_dev,
234 sc->sc_cs0, 1);
235 if (sc->sc_cs1 == 0xff) break;
236 GPIOBUS_PIN_SET(sc->sc_busdev, sc->sc_dev,
237 sc->sc_cs1, 1);
238 if (sc->sc_cs2 == 0xff) break;
239 GPIOBUS_PIN_SET(sc->sc_busdev, sc->sc_dev,
240 sc->sc_cs2, 1);
241 if (sc->sc_cs3 == 0xff) break;
242 GPIOBUS_PIN_SET(sc->sc_busdev, sc->sc_dev,
243 sc->sc_cs3, 1);
244 break;
245 case 0:
246 GPIOBUS_PIN_SET(sc->sc_busdev, sc->sc_dev,
247 sc->sc_cs0, 1);
248 break;
249 case 1:
250 GPIOBUS_PIN_SET(sc->sc_busdev, sc->sc_dev,
251 sc->sc_cs1, 1);
252 break;
253 case 2:
254 GPIOBUS_PIN_SET(sc->sc_busdev, sc->sc_dev,
255 sc->sc_cs2, 1);
256 break;
257 case 3:
258 GPIOBUS_PIN_SET(sc->sc_busdev, sc->sc_dev,
259 sc->sc_cs3, 1);
260 break;
261 default:
262 device_printf(sc->sc_dev, "don't have CS%d\n", cs);
263 }
264 }
265
266 static uint8_t
267 gpio_spi_txrx(struct gpio_spi_softc *sc, int cs, int mode, uint8_t data)
268 {
269 uint32_t mask, out = 0;
270 unsigned int bit;
271
272
273 /* called with locked gpiobus */
274
275 for (mask = 0x80; mask > 0; mask >>= 1) {
276 if ((mode == SPIBUS_MODE_CPOL) ||
277 (mode == SPIBUS_MODE_CPHA)) {
278 /* If mode 1 or 2 */
279
280 /* first step */
281 GPIOBUS_PIN_SET(sc->sc_busdev, sc->sc_dev,
282 sc->sc_mosi, (data & mask)?1:0);
283 GPIOBUS_PIN_SET(sc->sc_busdev, sc->sc_dev,
284 sc->sc_sclk, 0);
285 gpio_delay(sc);
286 /* second step */
287 if (sc->sc_miso != 0xff) {
288 GPIOBUS_PIN_GET(sc->sc_busdev, sc->sc_dev,
289 sc->sc_miso, &bit);
290 out |= bit?mask:0;
291 }
292 /* Data captured */
293 gpio_delay(sc);
294 GPIOBUS_PIN_SET(sc->sc_busdev, sc->sc_dev,
295 sc->sc_sclk, 1);
296 gpio_delay(sc);
297 } else {
298 /* If mode 0 or 3 */
299
300 /* first step */
301 GPIOBUS_PIN_SET(sc->sc_busdev, sc->sc_dev,
302 sc->sc_mosi, (data & mask)?1:0);
303 GPIOBUS_PIN_SET(sc->sc_busdev, sc->sc_dev,
304 sc->sc_sclk, 1);
305 gpio_delay(sc);
306 /* second step */
307 if (sc->sc_miso != 0xff) {
308 GPIOBUS_PIN_GET(sc->sc_busdev, sc->sc_dev,
309 sc->sc_miso, &bit);
310 out |= bit?mask:0;
311 }
312 /* Data captured */
313 gpio_delay(sc);
314 GPIOBUS_PIN_SET(sc->sc_busdev, sc->sc_dev,
315 sc->sc_sclk, 0);
316 gpio_delay(sc);
317 }
318 }
319
320 return (out & 0xff);
321 }
322
323 static int
324 gpio_spi_transfer(device_t dev, device_t child, struct spi_command *cmd)
325 {
326 struct gpio_spi_softc *sc;
327 uint8_t *buf_in, *buf_out;
328 struct spibus_ivar *devi = SPIBUS_IVAR(child);
329 int i;
330
331 sc = device_get_softc(dev);
332
333 KASSERT(cmd->tx_cmd_sz == cmd->rx_cmd_sz,
334 ("TX/RX command sizes should be equal"));
335 KASSERT(cmd->tx_data_sz == cmd->rx_data_sz,
336 ("TX/RX data sizes should be equal"));
337
338 gpio_spi_chip_activate(sc, devi->cs);
339
340 /* Preset pins */
341 if ((devi->mode == SPIBUS_MODE_CPOL) ||
342 (devi->mode == SPIBUS_MODE_CPHA)) {
343 GPIOBUS_PIN_SET(sc->sc_busdev, sc->sc_dev,
344 sc->sc_sclk, 1);
345 } else {
346 GPIOBUS_PIN_SET(sc->sc_busdev, sc->sc_dev,
347 sc->sc_sclk, 0);
348 }
349
350 /*
351 * Transfer command
352 */
353 buf_out = (uint8_t *)cmd->tx_cmd;
354 buf_in = (uint8_t *)cmd->rx_cmd;
355
356 for (i = 0; i < cmd->tx_cmd_sz; i++)
357 buf_in[i] = gpio_spi_txrx(sc, devi->cs, devi->mode, buf_out[i]);
358
359 /*
360 * Receive/transmit data (depends on command)
361 */
362 buf_out = (uint8_t *)cmd->tx_data;
363 buf_in = (uint8_t *)cmd->rx_data;
364 for (i = 0; i < cmd->tx_data_sz; i++)
365 buf_in[i] = gpio_spi_txrx(sc, devi->cs, devi->mode, buf_out[i]);
366
367 /* Return pins to mode default */
368 if ((devi->mode == SPIBUS_MODE_CPOL) ||
369 (devi->mode == SPIBUS_MODE_CPHA)) {
370 GPIOBUS_PIN_SET(sc->sc_busdev, sc->sc_dev,
371 sc->sc_sclk, 1);
372 } else {
373 GPIOBUS_PIN_SET(sc->sc_busdev, sc->sc_dev,
374 sc->sc_sclk, 0);
375 }
376
377 gpio_spi_chip_deactivate(sc, devi->cs);
378
379 return (0);
380 }
381
382 static device_method_t gpio_spi_methods[] = {
383 /* Device interface */
384 DEVMETHOD(device_probe, gpio_spi_probe),
385 DEVMETHOD(device_attach, gpio_spi_attach),
386 DEVMETHOD(device_detach, gpio_spi_detach),
387
388 DEVMETHOD(spibus_transfer, gpio_spi_transfer),
389
390 {0, 0}
391 };
392
393 static driver_t gpio_spi_driver = {
394 "gpiospi",
395 gpio_spi_methods,
396 sizeof(struct gpio_spi_softc),
397 };
398
399 static devclass_t gpio_spi_devclass;
400
401 DRIVER_MODULE(gpiospi, gpiobus, gpio_spi_driver, gpio_spi_devclass, 0, 0);
402 DRIVER_MODULE(spibus, gpiospi, spibus_driver, spibus_devclass, 0, 0);
403 MODULE_DEPEND(spi, gpiospi, 1, 1, 1);
404 MODULE_DEPEND(gpiobus, gpiospi, 1, 1, 1);
Cache object: a6ad4f8a002857d3b364c2f2326dffaa
|