Deleted Added
full compact
lpc_gpio.c (239278) lpc_gpio.c (242692)
1/*-
2 * Copyright (c) 2011 Jakub Wojciech Klama <jceel@FreeBSD.org>
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, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 */
27
28/*
29 * GPIO on LPC32x0 consist of 4 ports:
30 * - Port0 with 8 input/output pins
31 * - Port1 with 24 input/output pins
32 * - Port2 with 13 input/output pins
33 * - Port3 with:
34 * - 26 input pins (GPI_00..GPI_09 + GPI_15..GPI_23 + GPI_25 + GPI_27..GPI_28)
35 * - 24 output pins (GPO_00..GPO_23)
1/*-
2 * Copyright (c) 2011 Jakub Wojciech Klama <jceel@FreeBSD.org>
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, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 */
27
28/*
29 * GPIO on LPC32x0 consist of 4 ports:
30 * - Port0 with 8 input/output pins
31 * - Port1 with 24 input/output pins
32 * - Port2 with 13 input/output pins
33 * - Port3 with:
34 * - 26 input pins (GPI_00..GPI_09 + GPI_15..GPI_23 + GPI_25 + GPI_27..GPI_28)
35 * - 24 output pins (GPO_00..GPO_23)
36 * - 6 input/ouput pins (GPIO_00..GPIO_05)
36 * - 6 input/output pins (GPIO_00..GPIO_05)
37 *
38 * Pins are mapped to logical pin number as follows:
39 * [0..9] -> GPI_00..GPI_09 (port 3)
40 * [10..18] -> GPI_15..GPI_23 (port 3)
41 * [19] -> GPI_25 (port 3)
42 * [20..21] -> GPI_27..GPI_28 (port 3)
43 * [22..45] -> GPO_00..GPO_23 (port 3)
44 * [46..51] -> GPIO_00..GPIO_05 (port 3)
45 * [52..64] -> P2.0..P2.12 (port 2)
46 * [65..88] -> P1.0..P1.23 (port 1)
47 * [89..96] -> P0.0..P0.7 (port 0)
48 *
49 */
50
51
52#include <sys/cdefs.h>
37 *
38 * Pins are mapped to logical pin number as follows:
39 * [0..9] -> GPI_00..GPI_09 (port 3)
40 * [10..18] -> GPI_15..GPI_23 (port 3)
41 * [19] -> GPI_25 (port 3)
42 * [20..21] -> GPI_27..GPI_28 (port 3)
43 * [22..45] -> GPO_00..GPO_23 (port 3)
44 * [46..51] -> GPIO_00..GPIO_05 (port 3)
45 * [52..64] -> P2.0..P2.12 (port 2)
46 * [65..88] -> P1.0..P1.23 (port 1)
47 * [89..96] -> P0.0..P0.7 (port 0)
48 *
49 */
50
51
52#include <sys/cdefs.h>
53__FBSDID("$FreeBSD: head/sys/arm/lpc/lpc_gpio.c 239278 2012-08-15 05:37:10Z gonzo $");
53__FBSDID("$FreeBSD: head/sys/arm/lpc/lpc_gpio.c 242692 2012-11-07 07:00:59Z kevlo $");
54
55#include <sys/param.h>
56#include <sys/systm.h>
57#include <sys/bio.h>
58#include <sys/bus.h>
59#include <sys/conf.h>
60#include <sys/endian.h>
61#include <sys/kernel.h>
62#include <sys/kthread.h>
63#include <sys/lock.h>
64#include <sys/malloc.h>
65#include <sys/module.h>
66#include <sys/mutex.h>
67#include <sys/queue.h>
68#include <sys/resource.h>
69#include <sys/rman.h>
70#include <sys/time.h>
71#include <sys/timetc.h>
72#include <sys/watchdog.h>
73#include <sys/gpio.h>
74
75#include <machine/bus.h>
76#include <machine/cpu.h>
77#include <machine/cpufunc.h>
78#include <machine/resource.h>
79#include <machine/frame.h>
80#include <machine/intr.h>
81#include <machine/fdt.h>
82
83#include <dev/ofw/ofw_bus.h>
84#include <dev/ofw/ofw_bus_subr.h>
85
86#include <arm/lpc/lpcreg.h>
87#include <arm/lpc/lpcvar.h>
88
89#include "gpio_if.h"
90
91struct lpc_gpio_softc
92{
93 device_t lg_dev;
94 struct resource * lg_res;
95 bus_space_tag_t lg_bst;
96 bus_space_handle_t lg_bsh;
97};
98
99struct lpc_gpio_pinmap
100{
101 int lp_start_idx;
102 int lp_pin_count;
103 int lp_port;
104 int lp_start_bit;
105 int lp_flags;
106};
107
108static const struct lpc_gpio_pinmap lpc_gpio_pins[] = {
109 { 0, 10, 3, 0, GPIO_PIN_INPUT },
110 { 10, 9, 3, 15, GPIO_PIN_INPUT },
111 { 19, 1, 3, 25, GPIO_PIN_INPUT },
112 { 20, 2, 3, 27, GPIO_PIN_INPUT },
113 { 22, 24, 3, 0, GPIO_PIN_OUTPUT },
114 /*
115 * -1 below is to mark special case for Port3 GPIO pins, as they
116 * have other bits in Port 3 registers as inputs and as outputs
117 */
118 { 46, 6, 3, -1, GPIO_PIN_INPUT | GPIO_PIN_OUTPUT },
119 { 52, 13, 2, 0, GPIO_PIN_INPUT | GPIO_PIN_OUTPUT },
120 { 65, 24, 1, 0, GPIO_PIN_INPUT | GPIO_PIN_OUTPUT },
121 { 89, 8, 0, 0, GPIO_PIN_INPUT | GPIO_PIN_OUTPUT },
122 { -1, -1, -1, -1, -1 },
123};
124
125#define LPC_GPIO_NPINS \
126 (LPC_GPIO_P0_COUNT + LPC_GPIO_P1_COUNT + \
127 LPC_GPIO_P2_COUNT + LPC_GPIO_P3_COUNT)
128
129#define LPC_GPIO_PIN_IDX(_map, _idx) \
130 (_idx - _map->lp_start_idx)
131
132#define LPC_GPIO_PIN_BIT(_map, _idx) \
133 (_map->lp_start_bit + LPC_GPIO_PIN_IDX(_map, _idx))
134
135static int lpc_gpio_probe(device_t);
136static int lpc_gpio_attach(device_t);
137static int lpc_gpio_detach(device_t);
138
139static int lpc_gpio_pin_max(device_t, int *);
140static int lpc_gpio_pin_getcaps(device_t, uint32_t, uint32_t *);
141static int lpc_gpio_pin_getflags(device_t, uint32_t, uint32_t *);
142static int lpc_gpio_pin_setflags(device_t, uint32_t, uint32_t);
143static int lpc_gpio_pin_getname(device_t, uint32_t, char *);
144static int lpc_gpio_pin_get(device_t, uint32_t, uint32_t *);
145static int lpc_gpio_pin_set(device_t, uint32_t, uint32_t);
146static int lpc_gpio_pin_toggle(device_t, uint32_t);
147
148static const struct lpc_gpio_pinmap *lpc_gpio_get_pinmap(int);
149
150static struct lpc_gpio_softc *lpc_gpio_sc = NULL;
151
152#define lpc_gpio_read_4(_sc, _reg) \
153 bus_space_read_4(_sc->lg_bst, _sc->lg_bsh, _reg)
154#define lpc_gpio_write_4(_sc, _reg, _val) \
155 bus_space_write_4(_sc->lg_bst, _sc->lg_bsh, _reg, _val)
156#define lpc_gpio_get_4(_sc, _test, _reg1, _reg2) \
157 lpc_gpio_read_4(_sc, ((_test) ? _reg1 : _reg2))
158#define lpc_gpio_set_4(_sc, _test, _reg1, _reg2, _val) \
159 lpc_gpio_write_4(_sc, ((_test) ? _reg1 : _reg2), _val)
160
161static int
162lpc_gpio_probe(device_t dev)
163{
164 if (!ofw_bus_is_compatible(dev, "lpc,gpio"))
165 return (ENXIO);
166
167 device_set_desc(dev, "LPC32x0 GPIO");
168 return (BUS_PROBE_DEFAULT);
169}
170
171static int
172lpc_gpio_attach(device_t dev)
173{
174 struct lpc_gpio_softc *sc = device_get_softc(dev);
175 int rid;
176
177 sc->lg_dev = dev;
178
179 rid = 0;
180 sc->lg_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
181 RF_ACTIVE);
182 if (!sc->lg_res) {
183 device_printf(dev, "cannot allocate memory window\n");
184 return (ENXIO);
185 }
186
187 sc->lg_bst = rman_get_bustag(sc->lg_res);
188 sc->lg_bsh = rman_get_bushandle(sc->lg_res);
189
190 lpc_gpio_sc = sc;
191
192 device_add_child(dev, "gpioc", device_get_unit(dev));
193 device_add_child(dev, "gpiobus", device_get_unit(dev));
194
195 return (bus_generic_attach(dev));
196}
197
198static int
199lpc_gpio_detach(device_t dev)
200{
201 return (EBUSY);
202}
203
204static int
205lpc_gpio_pin_max(device_t dev, int *npins)
206{
207 *npins = LPC_GPIO_NPINS - 1;
208 return (0);
209}
210
211static int
212lpc_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
213{
214 const struct lpc_gpio_pinmap *map;
215
216 if (pin > LPC_GPIO_NPINS)
217 return (ENODEV);
218
219 map = lpc_gpio_get_pinmap(pin);
220
221 *caps = map->lp_flags;
222 return (0);
223}
224
225static int
226lpc_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
227{
228 struct lpc_gpio_softc *sc = device_get_softc(dev);
229 const struct lpc_gpio_pinmap *map;
230 uint32_t state;
231 int dir;
232
233 if (pin > LPC_GPIO_NPINS)
234 return (ENODEV);
235
236 map = lpc_gpio_get_pinmap(pin);
237
238 /* Check whether it's bidirectional pin */
239 if ((map->lp_flags & (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) !=
240 (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) {
241 *flags = map->lp_flags;
242 return (0);
243 }
244
245 switch (map->lp_port) {
246 case 0:
247 state = lpc_gpio_read_4(sc, LPC_GPIO_P0_DIR_STATE);
248 dir = (state & (1 << LPC_GPIO_PIN_BIT(map, pin)));
249 break;
250 case 1:
251 state = lpc_gpio_read_4(sc, LPC_GPIO_P1_DIR_STATE);
252 dir = (state & (1 << LPC_GPIO_PIN_BIT(map, pin)));
253 break;
254 case 2:
255 state = lpc_gpio_read_4(sc, LPC_GPIO_P2_DIR_STATE);
256 dir = (state & (1 << LPC_GPIO_PIN_BIT(map, pin)));
257 break;
258 case 3:
259 state = lpc_gpio_read_4(sc, LPC_GPIO_P2_DIR_STATE);
260 dir = (state & (1 << (25 + LPC_GPIO_PIN_IDX(map, pin))));
261 break;
262 default:
263 panic("unknown GPIO port");
264 }
265
266 *flags = dir ? GPIO_PIN_OUTPUT : GPIO_PIN_INPUT;
267
268 return (0);
269}
270
271static int
272lpc_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
273{
274 struct lpc_gpio_softc *sc = device_get_softc(dev);
275 const struct lpc_gpio_pinmap *map;
276 uint32_t dir, state;
277
278 if (pin > LPC_GPIO_NPINS)
279 return (ENODEV);
280
281 map = lpc_gpio_get_pinmap(pin);
282
283 /* Check whether it's bidirectional pin */
284 if ((map->lp_flags & (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) !=
285 (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT))
286 return (ENOTSUP);
287
288 if (flags & GPIO_PIN_INPUT)
289 dir = 0;
290
291 if (flags & GPIO_PIN_OUTPUT)
292 dir = 1;
293
294 switch (map->lp_port) {
295 case 0:
296 state = (1 << LPC_GPIO_PIN_IDX(map, pin));
297 lpc_gpio_set_4(sc, dir, LPC_GPIO_P0_DIR_SET,
298 LPC_GPIO_P0_DIR_CLR, state);
299 break;
300 case 1:
301 state = (1 << LPC_GPIO_PIN_IDX(map, pin));
302 lpc_gpio_set_4(sc, dir, LPC_GPIO_P1_DIR_SET,
303 LPC_GPIO_P0_DIR_CLR, state);
304 break;
305 case 2:
306 state = (1 << LPC_GPIO_PIN_IDX(map, pin));
307 lpc_gpio_set_4(sc, dir, LPC_GPIO_P2_DIR_SET,
308 LPC_GPIO_P0_DIR_CLR, state);
309 break;
310 case 3:
311 state = (1 << (25 + (pin - map->lp_start_idx)));
312 lpc_gpio_set_4(sc, dir, LPC_GPIO_P2_DIR_SET,
313 LPC_GPIO_P0_DIR_CLR, state);
314 break;
315 }
316
317 return (0);
318}
319
320static int
321lpc_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
322{
323 const struct lpc_gpio_pinmap *map;
324 int idx;
325
326 map = lpc_gpio_get_pinmap(pin);
327 idx = LPC_GPIO_PIN_IDX(map, pin);
328
329 switch (map->lp_port) {
330 case 0:
331 case 1:
332 case 2:
333 snprintf(name, GPIOMAXNAME - 1, "P%d.%d", map->lp_port,
334 map->lp_start_bit + LPC_GPIO_PIN_IDX(map, pin));
335 break;
336 case 3:
337 if (map->lp_start_bit == -1) {
338 snprintf(name, GPIOMAXNAME - 1, "GPIO_%02d", idx);
339 break;
340 }
341
342 snprintf(name, GPIOMAXNAME - 1, "GP%c_%02d",
343 (map->lp_flags & GPIO_PIN_INPUT) ? 'I' : 'O',
344 map->lp_start_bit + idx);
345 break;
346 }
347
348 return (0);
349}
350
351static int
352lpc_gpio_pin_get(device_t dev, uint32_t pin, uint32_t *value)
353{
354 struct lpc_gpio_softc *sc = device_get_softc(dev);
355 const struct lpc_gpio_pinmap *map;
356 uint32_t state, flags;
357 int dir;
358
359 map = lpc_gpio_get_pinmap(pin);
360
361 if (lpc_gpio_pin_getflags(dev, pin, &flags))
362 return (ENXIO);
363
364 if (flags & GPIO_PIN_OUTPUT)
365 dir = 1;
366
367 if (flags & GPIO_PIN_INPUT)
368 dir = 0;
369
370 switch (map->lp_port) {
371 case 0:
372 state = lpc_gpio_get_4(sc, dir, LPC_GPIO_P0_OUTP_STATE,
373 LPC_GPIO_P0_INP_STATE);
374 *value = !!(state & (1 << LPC_GPIO_PIN_BIT(map, pin)));
375 case 1:
376 state = lpc_gpio_get_4(sc, dir, LPC_GPIO_P1_OUTP_STATE,
377 LPC_GPIO_P1_INP_STATE);
378 *value = !!(state & (1 << LPC_GPIO_PIN_BIT(map, pin)));
379 case 2:
380 state = lpc_gpio_read_4(sc, LPC_GPIO_P2_INP_STATE);
381 *value = !!(state & (1 << LPC_GPIO_PIN_BIT(map, pin)));
382 case 3:
383 state = lpc_gpio_get_4(sc, dir, LPC_GPIO_P3_OUTP_STATE,
384 LPC_GPIO_P3_INP_STATE);
385 if (map->lp_start_bit == -1) {
386 if (dir)
387 *value = !!(state & (1 << (25 +
388 LPC_GPIO_PIN_IDX(map, pin))));
389 else
390 *value = !!(state & (1 << (10 +
391 LPC_GPIO_PIN_IDX(map, pin))));
392 }
393
394 *value = !!(state & (1 << LPC_GPIO_PIN_BIT(map, pin)));
395 }
396
397 return (0);
398}
399
400static int
401lpc_gpio_pin_set(device_t dev, uint32_t pin, uint32_t value)
402{
403 struct lpc_gpio_softc *sc = device_get_softc(dev);
404 const struct lpc_gpio_pinmap *map;
405 uint32_t state, flags;
406
407 map = lpc_gpio_get_pinmap(pin);
408
409 if (lpc_gpio_pin_getflags(dev, pin, &flags))
410 return (ENXIO);
411
412 if ((flags & GPIO_PIN_OUTPUT) == 0)
413 return (EINVAL);
414
415 state = (1 << LPC_GPIO_PIN_BIT(map, pin));
416
417 switch (map->lp_port) {
418 case 0:
419 lpc_gpio_set_4(sc, value, LPC_GPIO_P0_OUTP_SET,
420 LPC_GPIO_P0_OUTP_CLR, state);
421 break;
422 case 1:
423 lpc_gpio_set_4(sc, value, LPC_GPIO_P1_OUTP_SET,
424 LPC_GPIO_P1_OUTP_CLR, state);
425 break;
426 case 2:
427 lpc_gpio_set_4(sc, value, LPC_GPIO_P2_OUTP_SET,
428 LPC_GPIO_P2_OUTP_CLR, state);
429 break;
430 case 3:
431 if (map->lp_start_bit == -1)
432 state = (1 << (25 + LPC_GPIO_PIN_IDX(map, pin)));
433
434 lpc_gpio_set_4(sc, value, LPC_GPIO_P3_OUTP_SET,
435 LPC_GPIO_P3_OUTP_CLR, state);
436 break;
437 }
438
439 return (0);
440}
441
442static int
443lpc_gpio_pin_toggle(device_t dev, uint32_t pin)
444{
445 const struct lpc_gpio_pinmap *map;
446 uint32_t flags;
447
448 map = lpc_gpio_get_pinmap(pin);
449
450 if (lpc_gpio_pin_getflags(dev, pin, &flags))
451 return (ENXIO);
452
453 if ((flags & GPIO_PIN_OUTPUT) == 0)
454 return (EINVAL);
455
456 panic("not implemented yet");
457
458 return (0);
459
460}
461
462static const struct lpc_gpio_pinmap *
463lpc_gpio_get_pinmap(int pin)
464{
465 const struct lpc_gpio_pinmap *map;
466
467 for (map = &lpc_gpio_pins[0]; map->lp_start_idx != -1; map++) {
468 if (pin >= map->lp_start_idx &&
469 pin < map->lp_start_idx + map->lp_pin_count)
470 return map;
471 }
472
473 panic("pin number %d out of range", pin);
474}
475
476int
477lpc_gpio_set_flags(device_t dev, int pin, int flags)
478{
479 if (lpc_gpio_sc == NULL)
480 return (ENXIO);
481
482 return lpc_gpio_pin_setflags(lpc_gpio_sc->lg_dev, pin, flags);
483}
484
485int
486lpc_gpio_set_state(device_t dev, int pin, int state)
487{
488 if (lpc_gpio_sc == NULL)
489 return (ENXIO);
490
491 return lpc_gpio_pin_set(lpc_gpio_sc->lg_dev, pin, state);
492}
493
494int
495lpc_gpio_get_state(device_t dev, int pin, int *state)
496{
497 if (lpc_gpio_sc == NULL)
498 return (ENXIO);
499
500 return lpc_gpio_pin_get(lpc_gpio_sc->lg_dev, pin, state);
501}
502
503void
504platform_gpio_init()
505{
506 /* Preset SPI devices CS pins to one */
507 bus_space_write_4(fdtbus_bs_tag,
508 LPC_GPIO_BASE, LPC_GPIO_P3_OUTP_SET,
509 1 << (SSD1289_CS_PIN - LPC_GPIO_GPO_00(0)) |
510 1 << (SSD1289_DC_PIN - LPC_GPIO_GPO_00(0)) |
511 1 << (ADS7846_CS_PIN - LPC_GPIO_GPO_00(0)));
512}
513
514static device_method_t lpc_gpio_methods[] = {
515 /* Device interface */
516 DEVMETHOD(device_probe, lpc_gpio_probe),
517 DEVMETHOD(device_attach, lpc_gpio_attach),
518 DEVMETHOD(device_detach, lpc_gpio_detach),
519
520 /* GPIO interface */
521 DEVMETHOD(gpio_pin_max, lpc_gpio_pin_max),
522 DEVMETHOD(gpio_pin_getcaps, lpc_gpio_pin_getcaps),
523 DEVMETHOD(gpio_pin_getflags, lpc_gpio_pin_getflags),
524 DEVMETHOD(gpio_pin_setflags, lpc_gpio_pin_setflags),
525 DEVMETHOD(gpio_pin_getname, lpc_gpio_pin_getname),
526 DEVMETHOD(gpio_pin_set, lpc_gpio_pin_set),
527 DEVMETHOD(gpio_pin_get, lpc_gpio_pin_get),
528 DEVMETHOD(gpio_pin_toggle, lpc_gpio_pin_toggle),
529
530 { 0, 0 }
531};
532
533static devclass_t lpc_gpio_devclass;
534
535static driver_t lpc_gpio_driver = {
536 "lpcgpio",
537 lpc_gpio_methods,
538 sizeof(struct lpc_gpio_softc),
539};
540
541extern devclass_t gpiobus_devclass, gpioc_devclass;
542extern driver_t gpiobus_driver, gpioc_driver;
543
544DRIVER_MODULE(lpcgpio, simplebus, lpc_gpio_driver, lpc_gpio_devclass, 0, 0);
545DRIVER_MODULE(gpiobus, lpcgpio, gpiobus_driver, gpiobus_devclass, 0, 0);
546DRIVER_MODULE(gpioc, lpcgpio, gpioc_driver, gpioc_devclass, 0, 0);
547MODULE_VERSION(lpcgpio, 1);
54
55#include <sys/param.h>
56#include <sys/systm.h>
57#include <sys/bio.h>
58#include <sys/bus.h>
59#include <sys/conf.h>
60#include <sys/endian.h>
61#include <sys/kernel.h>
62#include <sys/kthread.h>
63#include <sys/lock.h>
64#include <sys/malloc.h>
65#include <sys/module.h>
66#include <sys/mutex.h>
67#include <sys/queue.h>
68#include <sys/resource.h>
69#include <sys/rman.h>
70#include <sys/time.h>
71#include <sys/timetc.h>
72#include <sys/watchdog.h>
73#include <sys/gpio.h>
74
75#include <machine/bus.h>
76#include <machine/cpu.h>
77#include <machine/cpufunc.h>
78#include <machine/resource.h>
79#include <machine/frame.h>
80#include <machine/intr.h>
81#include <machine/fdt.h>
82
83#include <dev/ofw/ofw_bus.h>
84#include <dev/ofw/ofw_bus_subr.h>
85
86#include <arm/lpc/lpcreg.h>
87#include <arm/lpc/lpcvar.h>
88
89#include "gpio_if.h"
90
91struct lpc_gpio_softc
92{
93 device_t lg_dev;
94 struct resource * lg_res;
95 bus_space_tag_t lg_bst;
96 bus_space_handle_t lg_bsh;
97};
98
99struct lpc_gpio_pinmap
100{
101 int lp_start_idx;
102 int lp_pin_count;
103 int lp_port;
104 int lp_start_bit;
105 int lp_flags;
106};
107
108static const struct lpc_gpio_pinmap lpc_gpio_pins[] = {
109 { 0, 10, 3, 0, GPIO_PIN_INPUT },
110 { 10, 9, 3, 15, GPIO_PIN_INPUT },
111 { 19, 1, 3, 25, GPIO_PIN_INPUT },
112 { 20, 2, 3, 27, GPIO_PIN_INPUT },
113 { 22, 24, 3, 0, GPIO_PIN_OUTPUT },
114 /*
115 * -1 below is to mark special case for Port3 GPIO pins, as they
116 * have other bits in Port 3 registers as inputs and as outputs
117 */
118 { 46, 6, 3, -1, GPIO_PIN_INPUT | GPIO_PIN_OUTPUT },
119 { 52, 13, 2, 0, GPIO_PIN_INPUT | GPIO_PIN_OUTPUT },
120 { 65, 24, 1, 0, GPIO_PIN_INPUT | GPIO_PIN_OUTPUT },
121 { 89, 8, 0, 0, GPIO_PIN_INPUT | GPIO_PIN_OUTPUT },
122 { -1, -1, -1, -1, -1 },
123};
124
125#define LPC_GPIO_NPINS \
126 (LPC_GPIO_P0_COUNT + LPC_GPIO_P1_COUNT + \
127 LPC_GPIO_P2_COUNT + LPC_GPIO_P3_COUNT)
128
129#define LPC_GPIO_PIN_IDX(_map, _idx) \
130 (_idx - _map->lp_start_idx)
131
132#define LPC_GPIO_PIN_BIT(_map, _idx) \
133 (_map->lp_start_bit + LPC_GPIO_PIN_IDX(_map, _idx))
134
135static int lpc_gpio_probe(device_t);
136static int lpc_gpio_attach(device_t);
137static int lpc_gpio_detach(device_t);
138
139static int lpc_gpio_pin_max(device_t, int *);
140static int lpc_gpio_pin_getcaps(device_t, uint32_t, uint32_t *);
141static int lpc_gpio_pin_getflags(device_t, uint32_t, uint32_t *);
142static int lpc_gpio_pin_setflags(device_t, uint32_t, uint32_t);
143static int lpc_gpio_pin_getname(device_t, uint32_t, char *);
144static int lpc_gpio_pin_get(device_t, uint32_t, uint32_t *);
145static int lpc_gpio_pin_set(device_t, uint32_t, uint32_t);
146static int lpc_gpio_pin_toggle(device_t, uint32_t);
147
148static const struct lpc_gpio_pinmap *lpc_gpio_get_pinmap(int);
149
150static struct lpc_gpio_softc *lpc_gpio_sc = NULL;
151
152#define lpc_gpio_read_4(_sc, _reg) \
153 bus_space_read_4(_sc->lg_bst, _sc->lg_bsh, _reg)
154#define lpc_gpio_write_4(_sc, _reg, _val) \
155 bus_space_write_4(_sc->lg_bst, _sc->lg_bsh, _reg, _val)
156#define lpc_gpio_get_4(_sc, _test, _reg1, _reg2) \
157 lpc_gpio_read_4(_sc, ((_test) ? _reg1 : _reg2))
158#define lpc_gpio_set_4(_sc, _test, _reg1, _reg2, _val) \
159 lpc_gpio_write_4(_sc, ((_test) ? _reg1 : _reg2), _val)
160
161static int
162lpc_gpio_probe(device_t dev)
163{
164 if (!ofw_bus_is_compatible(dev, "lpc,gpio"))
165 return (ENXIO);
166
167 device_set_desc(dev, "LPC32x0 GPIO");
168 return (BUS_PROBE_DEFAULT);
169}
170
171static int
172lpc_gpio_attach(device_t dev)
173{
174 struct lpc_gpio_softc *sc = device_get_softc(dev);
175 int rid;
176
177 sc->lg_dev = dev;
178
179 rid = 0;
180 sc->lg_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
181 RF_ACTIVE);
182 if (!sc->lg_res) {
183 device_printf(dev, "cannot allocate memory window\n");
184 return (ENXIO);
185 }
186
187 sc->lg_bst = rman_get_bustag(sc->lg_res);
188 sc->lg_bsh = rman_get_bushandle(sc->lg_res);
189
190 lpc_gpio_sc = sc;
191
192 device_add_child(dev, "gpioc", device_get_unit(dev));
193 device_add_child(dev, "gpiobus", device_get_unit(dev));
194
195 return (bus_generic_attach(dev));
196}
197
198static int
199lpc_gpio_detach(device_t dev)
200{
201 return (EBUSY);
202}
203
204static int
205lpc_gpio_pin_max(device_t dev, int *npins)
206{
207 *npins = LPC_GPIO_NPINS - 1;
208 return (0);
209}
210
211static int
212lpc_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
213{
214 const struct lpc_gpio_pinmap *map;
215
216 if (pin > LPC_GPIO_NPINS)
217 return (ENODEV);
218
219 map = lpc_gpio_get_pinmap(pin);
220
221 *caps = map->lp_flags;
222 return (0);
223}
224
225static int
226lpc_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
227{
228 struct lpc_gpio_softc *sc = device_get_softc(dev);
229 const struct lpc_gpio_pinmap *map;
230 uint32_t state;
231 int dir;
232
233 if (pin > LPC_GPIO_NPINS)
234 return (ENODEV);
235
236 map = lpc_gpio_get_pinmap(pin);
237
238 /* Check whether it's bidirectional pin */
239 if ((map->lp_flags & (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) !=
240 (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) {
241 *flags = map->lp_flags;
242 return (0);
243 }
244
245 switch (map->lp_port) {
246 case 0:
247 state = lpc_gpio_read_4(sc, LPC_GPIO_P0_DIR_STATE);
248 dir = (state & (1 << LPC_GPIO_PIN_BIT(map, pin)));
249 break;
250 case 1:
251 state = lpc_gpio_read_4(sc, LPC_GPIO_P1_DIR_STATE);
252 dir = (state & (1 << LPC_GPIO_PIN_BIT(map, pin)));
253 break;
254 case 2:
255 state = lpc_gpio_read_4(sc, LPC_GPIO_P2_DIR_STATE);
256 dir = (state & (1 << LPC_GPIO_PIN_BIT(map, pin)));
257 break;
258 case 3:
259 state = lpc_gpio_read_4(sc, LPC_GPIO_P2_DIR_STATE);
260 dir = (state & (1 << (25 + LPC_GPIO_PIN_IDX(map, pin))));
261 break;
262 default:
263 panic("unknown GPIO port");
264 }
265
266 *flags = dir ? GPIO_PIN_OUTPUT : GPIO_PIN_INPUT;
267
268 return (0);
269}
270
271static int
272lpc_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
273{
274 struct lpc_gpio_softc *sc = device_get_softc(dev);
275 const struct lpc_gpio_pinmap *map;
276 uint32_t dir, state;
277
278 if (pin > LPC_GPIO_NPINS)
279 return (ENODEV);
280
281 map = lpc_gpio_get_pinmap(pin);
282
283 /* Check whether it's bidirectional pin */
284 if ((map->lp_flags & (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) !=
285 (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT))
286 return (ENOTSUP);
287
288 if (flags & GPIO_PIN_INPUT)
289 dir = 0;
290
291 if (flags & GPIO_PIN_OUTPUT)
292 dir = 1;
293
294 switch (map->lp_port) {
295 case 0:
296 state = (1 << LPC_GPIO_PIN_IDX(map, pin));
297 lpc_gpio_set_4(sc, dir, LPC_GPIO_P0_DIR_SET,
298 LPC_GPIO_P0_DIR_CLR, state);
299 break;
300 case 1:
301 state = (1 << LPC_GPIO_PIN_IDX(map, pin));
302 lpc_gpio_set_4(sc, dir, LPC_GPIO_P1_DIR_SET,
303 LPC_GPIO_P0_DIR_CLR, state);
304 break;
305 case 2:
306 state = (1 << LPC_GPIO_PIN_IDX(map, pin));
307 lpc_gpio_set_4(sc, dir, LPC_GPIO_P2_DIR_SET,
308 LPC_GPIO_P0_DIR_CLR, state);
309 break;
310 case 3:
311 state = (1 << (25 + (pin - map->lp_start_idx)));
312 lpc_gpio_set_4(sc, dir, LPC_GPIO_P2_DIR_SET,
313 LPC_GPIO_P0_DIR_CLR, state);
314 break;
315 }
316
317 return (0);
318}
319
320static int
321lpc_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
322{
323 const struct lpc_gpio_pinmap *map;
324 int idx;
325
326 map = lpc_gpio_get_pinmap(pin);
327 idx = LPC_GPIO_PIN_IDX(map, pin);
328
329 switch (map->lp_port) {
330 case 0:
331 case 1:
332 case 2:
333 snprintf(name, GPIOMAXNAME - 1, "P%d.%d", map->lp_port,
334 map->lp_start_bit + LPC_GPIO_PIN_IDX(map, pin));
335 break;
336 case 3:
337 if (map->lp_start_bit == -1) {
338 snprintf(name, GPIOMAXNAME - 1, "GPIO_%02d", idx);
339 break;
340 }
341
342 snprintf(name, GPIOMAXNAME - 1, "GP%c_%02d",
343 (map->lp_flags & GPIO_PIN_INPUT) ? 'I' : 'O',
344 map->lp_start_bit + idx);
345 break;
346 }
347
348 return (0);
349}
350
351static int
352lpc_gpio_pin_get(device_t dev, uint32_t pin, uint32_t *value)
353{
354 struct lpc_gpio_softc *sc = device_get_softc(dev);
355 const struct lpc_gpio_pinmap *map;
356 uint32_t state, flags;
357 int dir;
358
359 map = lpc_gpio_get_pinmap(pin);
360
361 if (lpc_gpio_pin_getflags(dev, pin, &flags))
362 return (ENXIO);
363
364 if (flags & GPIO_PIN_OUTPUT)
365 dir = 1;
366
367 if (flags & GPIO_PIN_INPUT)
368 dir = 0;
369
370 switch (map->lp_port) {
371 case 0:
372 state = lpc_gpio_get_4(sc, dir, LPC_GPIO_P0_OUTP_STATE,
373 LPC_GPIO_P0_INP_STATE);
374 *value = !!(state & (1 << LPC_GPIO_PIN_BIT(map, pin)));
375 case 1:
376 state = lpc_gpio_get_4(sc, dir, LPC_GPIO_P1_OUTP_STATE,
377 LPC_GPIO_P1_INP_STATE);
378 *value = !!(state & (1 << LPC_GPIO_PIN_BIT(map, pin)));
379 case 2:
380 state = lpc_gpio_read_4(sc, LPC_GPIO_P2_INP_STATE);
381 *value = !!(state & (1 << LPC_GPIO_PIN_BIT(map, pin)));
382 case 3:
383 state = lpc_gpio_get_4(sc, dir, LPC_GPIO_P3_OUTP_STATE,
384 LPC_GPIO_P3_INP_STATE);
385 if (map->lp_start_bit == -1) {
386 if (dir)
387 *value = !!(state & (1 << (25 +
388 LPC_GPIO_PIN_IDX(map, pin))));
389 else
390 *value = !!(state & (1 << (10 +
391 LPC_GPIO_PIN_IDX(map, pin))));
392 }
393
394 *value = !!(state & (1 << LPC_GPIO_PIN_BIT(map, pin)));
395 }
396
397 return (0);
398}
399
400static int
401lpc_gpio_pin_set(device_t dev, uint32_t pin, uint32_t value)
402{
403 struct lpc_gpio_softc *sc = device_get_softc(dev);
404 const struct lpc_gpio_pinmap *map;
405 uint32_t state, flags;
406
407 map = lpc_gpio_get_pinmap(pin);
408
409 if (lpc_gpio_pin_getflags(dev, pin, &flags))
410 return (ENXIO);
411
412 if ((flags & GPIO_PIN_OUTPUT) == 0)
413 return (EINVAL);
414
415 state = (1 << LPC_GPIO_PIN_BIT(map, pin));
416
417 switch (map->lp_port) {
418 case 0:
419 lpc_gpio_set_4(sc, value, LPC_GPIO_P0_OUTP_SET,
420 LPC_GPIO_P0_OUTP_CLR, state);
421 break;
422 case 1:
423 lpc_gpio_set_4(sc, value, LPC_GPIO_P1_OUTP_SET,
424 LPC_GPIO_P1_OUTP_CLR, state);
425 break;
426 case 2:
427 lpc_gpio_set_4(sc, value, LPC_GPIO_P2_OUTP_SET,
428 LPC_GPIO_P2_OUTP_CLR, state);
429 break;
430 case 3:
431 if (map->lp_start_bit == -1)
432 state = (1 << (25 + LPC_GPIO_PIN_IDX(map, pin)));
433
434 lpc_gpio_set_4(sc, value, LPC_GPIO_P3_OUTP_SET,
435 LPC_GPIO_P3_OUTP_CLR, state);
436 break;
437 }
438
439 return (0);
440}
441
442static int
443lpc_gpio_pin_toggle(device_t dev, uint32_t pin)
444{
445 const struct lpc_gpio_pinmap *map;
446 uint32_t flags;
447
448 map = lpc_gpio_get_pinmap(pin);
449
450 if (lpc_gpio_pin_getflags(dev, pin, &flags))
451 return (ENXIO);
452
453 if ((flags & GPIO_PIN_OUTPUT) == 0)
454 return (EINVAL);
455
456 panic("not implemented yet");
457
458 return (0);
459
460}
461
462static const struct lpc_gpio_pinmap *
463lpc_gpio_get_pinmap(int pin)
464{
465 const struct lpc_gpio_pinmap *map;
466
467 for (map = &lpc_gpio_pins[0]; map->lp_start_idx != -1; map++) {
468 if (pin >= map->lp_start_idx &&
469 pin < map->lp_start_idx + map->lp_pin_count)
470 return map;
471 }
472
473 panic("pin number %d out of range", pin);
474}
475
476int
477lpc_gpio_set_flags(device_t dev, int pin, int flags)
478{
479 if (lpc_gpio_sc == NULL)
480 return (ENXIO);
481
482 return lpc_gpio_pin_setflags(lpc_gpio_sc->lg_dev, pin, flags);
483}
484
485int
486lpc_gpio_set_state(device_t dev, int pin, int state)
487{
488 if (lpc_gpio_sc == NULL)
489 return (ENXIO);
490
491 return lpc_gpio_pin_set(lpc_gpio_sc->lg_dev, pin, state);
492}
493
494int
495lpc_gpio_get_state(device_t dev, int pin, int *state)
496{
497 if (lpc_gpio_sc == NULL)
498 return (ENXIO);
499
500 return lpc_gpio_pin_get(lpc_gpio_sc->lg_dev, pin, state);
501}
502
503void
504platform_gpio_init()
505{
506 /* Preset SPI devices CS pins to one */
507 bus_space_write_4(fdtbus_bs_tag,
508 LPC_GPIO_BASE, LPC_GPIO_P3_OUTP_SET,
509 1 << (SSD1289_CS_PIN - LPC_GPIO_GPO_00(0)) |
510 1 << (SSD1289_DC_PIN - LPC_GPIO_GPO_00(0)) |
511 1 << (ADS7846_CS_PIN - LPC_GPIO_GPO_00(0)));
512}
513
514static device_method_t lpc_gpio_methods[] = {
515 /* Device interface */
516 DEVMETHOD(device_probe, lpc_gpio_probe),
517 DEVMETHOD(device_attach, lpc_gpio_attach),
518 DEVMETHOD(device_detach, lpc_gpio_detach),
519
520 /* GPIO interface */
521 DEVMETHOD(gpio_pin_max, lpc_gpio_pin_max),
522 DEVMETHOD(gpio_pin_getcaps, lpc_gpio_pin_getcaps),
523 DEVMETHOD(gpio_pin_getflags, lpc_gpio_pin_getflags),
524 DEVMETHOD(gpio_pin_setflags, lpc_gpio_pin_setflags),
525 DEVMETHOD(gpio_pin_getname, lpc_gpio_pin_getname),
526 DEVMETHOD(gpio_pin_set, lpc_gpio_pin_set),
527 DEVMETHOD(gpio_pin_get, lpc_gpio_pin_get),
528 DEVMETHOD(gpio_pin_toggle, lpc_gpio_pin_toggle),
529
530 { 0, 0 }
531};
532
533static devclass_t lpc_gpio_devclass;
534
535static driver_t lpc_gpio_driver = {
536 "lpcgpio",
537 lpc_gpio_methods,
538 sizeof(struct lpc_gpio_softc),
539};
540
541extern devclass_t gpiobus_devclass, gpioc_devclass;
542extern driver_t gpiobus_driver, gpioc_driver;
543
544DRIVER_MODULE(lpcgpio, simplebus, lpc_gpio_driver, lpc_gpio_devclass, 0, 0);
545DRIVER_MODULE(gpiobus, lpcgpio, gpiobus_driver, gpiobus_devclass, 0, 0);
546DRIVER_MODULE(gpioc, lpcgpio, gpioc_driver, gpioc_devclass, 0, 0);
547MODULE_VERSION(lpcgpio, 1);