cxgbe/t4_tom: Read the chip's DDP page sizes and save them in a
[freebsd-src.git] / sys / arm / lpc / lpc_gpio.c
blob88f37b6cbf57d8a87191ccc6b6bad664a658d42f
1 /*-
2 * Copyright (c) 2011 Jakub Wojciech Klama <jceel@FreeBSD.org>
3 * All rights reserved.
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.
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.
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/output pins (GPIO_00..GPIO_05)
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)
52 #include <sys/cdefs.h>
53 __FBSDID("$FreeBSD$");
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>
75 #include <machine/bus.h>
76 #include <machine/cpu.h>
77 #include <machine/cpufunc.h>
78 #include <machine/resource.h>
79 #include <machine/intr.h>
80 #include <machine/fdt.h>
82 #include <dev/gpio/gpiobusvar.h>
83 #include <dev/ofw/ofw_bus.h>
84 #include <dev/ofw/ofw_bus_subr.h>
86 #include <arm/lpc/lpcreg.h>
87 #include <arm/lpc/lpcvar.h>
89 #include "gpio_if.h"
91 struct lpc_gpio_softc
93 device_t lg_dev;
94 device_t lg_busdev;
95 struct resource * lg_res;
96 bus_space_tag_t lg_bst;
97 bus_space_handle_t lg_bsh;
100 struct lpc_gpio_pinmap
102 int lp_start_idx;
103 int lp_pin_count;
104 int lp_port;
105 int lp_start_bit;
106 int lp_flags;
109 static const struct lpc_gpio_pinmap lpc_gpio_pins[] = {
110 { 0, 10, 3, 0, GPIO_PIN_INPUT },
111 { 10, 9, 3, 15, GPIO_PIN_INPUT },
112 { 19, 1, 3, 25, GPIO_PIN_INPUT },
113 { 20, 2, 3, 27, GPIO_PIN_INPUT },
114 { 22, 24, 3, 0, GPIO_PIN_OUTPUT },
116 * -1 below is to mark special case for Port3 GPIO pins, as they
117 * have other bits in Port 3 registers as inputs and as outputs
119 { 46, 6, 3, -1, GPIO_PIN_INPUT | GPIO_PIN_OUTPUT },
120 { 52, 13, 2, 0, GPIO_PIN_INPUT | GPIO_PIN_OUTPUT },
121 { 65, 24, 1, 0, GPIO_PIN_INPUT | GPIO_PIN_OUTPUT },
122 { 89, 8, 0, 0, GPIO_PIN_INPUT | GPIO_PIN_OUTPUT },
123 { -1, -1, -1, -1, -1 },
126 #define LPC_GPIO_NPINS \
127 (LPC_GPIO_P0_COUNT + LPC_GPIO_P1_COUNT + \
128 LPC_GPIO_P2_COUNT + LPC_GPIO_P3_COUNT)
130 #define LPC_GPIO_PIN_IDX(_map, _idx) \
131 (_idx - _map->lp_start_idx)
133 #define LPC_GPIO_PIN_BIT(_map, _idx) \
134 (_map->lp_start_bit + LPC_GPIO_PIN_IDX(_map, _idx))
136 static int lpc_gpio_probe(device_t);
137 static int lpc_gpio_attach(device_t);
138 static int lpc_gpio_detach(device_t);
140 static device_t lpc_gpio_get_bus(device_t);
141 static int lpc_gpio_pin_max(device_t, int *);
142 static int lpc_gpio_pin_getcaps(device_t, uint32_t, uint32_t *);
143 static int lpc_gpio_pin_getflags(device_t, uint32_t, uint32_t *);
144 static int lpc_gpio_pin_setflags(device_t, uint32_t, uint32_t);
145 static int lpc_gpio_pin_getname(device_t, uint32_t, char *);
146 static int lpc_gpio_pin_get(device_t, uint32_t, uint32_t *);
147 static int lpc_gpio_pin_set(device_t, uint32_t, uint32_t);
148 static int lpc_gpio_pin_toggle(device_t, uint32_t);
150 static const struct lpc_gpio_pinmap *lpc_gpio_get_pinmap(int);
152 static struct lpc_gpio_softc *lpc_gpio_sc = NULL;
154 #define lpc_gpio_read_4(_sc, _reg) \
155 bus_space_read_4(_sc->lg_bst, _sc->lg_bsh, _reg)
156 #define lpc_gpio_write_4(_sc, _reg, _val) \
157 bus_space_write_4(_sc->lg_bst, _sc->lg_bsh, _reg, _val)
158 #define lpc_gpio_get_4(_sc, _test, _reg1, _reg2) \
159 lpc_gpio_read_4(_sc, ((_test) ? _reg1 : _reg2))
160 #define lpc_gpio_set_4(_sc, _test, _reg1, _reg2, _val) \
161 lpc_gpio_write_4(_sc, ((_test) ? _reg1 : _reg2), _val)
163 static int
164 lpc_gpio_probe(device_t dev)
167 if (!ofw_bus_status_okay(dev))
168 return (ENXIO);
170 if (!ofw_bus_is_compatible(dev, "lpc,gpio"))
171 return (ENXIO);
173 device_set_desc(dev, "LPC32x0 GPIO");
174 return (BUS_PROBE_DEFAULT);
177 static int
178 lpc_gpio_attach(device_t dev)
180 struct lpc_gpio_softc *sc = device_get_softc(dev);
181 int rid;
183 sc->lg_dev = dev;
185 rid = 0;
186 sc->lg_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
187 RF_ACTIVE);
188 if (!sc->lg_res) {
189 device_printf(dev, "cannot allocate memory window\n");
190 return (ENXIO);
193 sc->lg_bst = rman_get_bustag(sc->lg_res);
194 sc->lg_bsh = rman_get_bushandle(sc->lg_res);
196 lpc_gpio_sc = sc;
198 sc->lg_busdev = gpiobus_attach_bus(dev);
199 if (sc->lg_busdev == NULL) {
200 bus_release_resource(dev, SYS_RES_MEMORY, rid, sc->lg_res);
201 return (ENXIO);
204 return (0);
207 static int
208 lpc_gpio_detach(device_t dev)
210 return (EBUSY);
213 static device_t
214 lpc_gpio_get_bus(device_t dev)
216 struct lpc_gpio_softc *sc;
218 sc = device_get_softc(dev);
220 return (sc->lg_busdev);
223 static int
224 lpc_gpio_pin_max(device_t dev, int *npins)
226 *npins = LPC_GPIO_NPINS - 1;
227 return (0);
230 static int
231 lpc_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
233 const struct lpc_gpio_pinmap *map;
235 if (pin > LPC_GPIO_NPINS)
236 return (ENODEV);
238 map = lpc_gpio_get_pinmap(pin);
240 *caps = map->lp_flags;
241 return (0);
244 static int
245 lpc_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
247 struct lpc_gpio_softc *sc = device_get_softc(dev);
248 const struct lpc_gpio_pinmap *map;
249 uint32_t state;
250 int dir;
252 if (pin > LPC_GPIO_NPINS)
253 return (ENODEV);
255 map = lpc_gpio_get_pinmap(pin);
257 /* Check whether it's bidirectional pin */
258 if ((map->lp_flags & (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) !=
259 (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) {
260 *flags = map->lp_flags;
261 return (0);
264 switch (map->lp_port) {
265 case 0:
266 state = lpc_gpio_read_4(sc, LPC_GPIO_P0_DIR_STATE);
267 dir = (state & (1 << LPC_GPIO_PIN_BIT(map, pin)));
268 break;
269 case 1:
270 state = lpc_gpio_read_4(sc, LPC_GPIO_P1_DIR_STATE);
271 dir = (state & (1 << LPC_GPIO_PIN_BIT(map, pin)));
272 break;
273 case 2:
274 state = lpc_gpio_read_4(sc, LPC_GPIO_P2_DIR_STATE);
275 dir = (state & (1 << LPC_GPIO_PIN_BIT(map, pin)));
276 break;
277 case 3:
278 state = lpc_gpio_read_4(sc, LPC_GPIO_P2_DIR_STATE);
279 dir = (state & (1 << (25 + LPC_GPIO_PIN_IDX(map, pin))));
280 break;
281 default:
282 panic("unknown GPIO port");
285 *flags = dir ? GPIO_PIN_OUTPUT : GPIO_PIN_INPUT;
287 return (0);
290 static int
291 lpc_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
293 struct lpc_gpio_softc *sc = device_get_softc(dev);
294 const struct lpc_gpio_pinmap *map;
295 uint32_t dir, state;
297 if (pin > LPC_GPIO_NPINS)
298 return (ENODEV);
300 map = lpc_gpio_get_pinmap(pin);
302 /* Check whether it's bidirectional pin */
303 if ((map->lp_flags & (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) !=
304 (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT))
305 return (ENOTSUP);
307 if (flags & GPIO_PIN_INPUT)
308 dir = 0;
310 if (flags & GPIO_PIN_OUTPUT)
311 dir = 1;
313 switch (map->lp_port) {
314 case 0:
315 state = (1 << LPC_GPIO_PIN_IDX(map, pin));
316 lpc_gpio_set_4(sc, dir, LPC_GPIO_P0_DIR_SET,
317 LPC_GPIO_P0_DIR_CLR, state);
318 break;
319 case 1:
320 state = (1 << LPC_GPIO_PIN_IDX(map, pin));
321 lpc_gpio_set_4(sc, dir, LPC_GPIO_P1_DIR_SET,
322 LPC_GPIO_P0_DIR_CLR, state);
323 break;
324 case 2:
325 state = (1 << LPC_GPIO_PIN_IDX(map, pin));
326 lpc_gpio_set_4(sc, dir, LPC_GPIO_P2_DIR_SET,
327 LPC_GPIO_P0_DIR_CLR, state);
328 break;
329 case 3:
330 state = (1 << (25 + (pin - map->lp_start_idx)));
331 lpc_gpio_set_4(sc, dir, LPC_GPIO_P2_DIR_SET,
332 LPC_GPIO_P0_DIR_CLR, state);
333 break;
336 return (0);
339 static int
340 lpc_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
342 const struct lpc_gpio_pinmap *map;
343 int idx;
345 map = lpc_gpio_get_pinmap(pin);
346 idx = LPC_GPIO_PIN_IDX(map, pin);
348 switch (map->lp_port) {
349 case 0:
350 case 1:
351 case 2:
352 snprintf(name, GPIOMAXNAME - 1, "P%d.%d", map->lp_port,
353 map->lp_start_bit + LPC_GPIO_PIN_IDX(map, pin));
354 break;
355 case 3:
356 if (map->lp_start_bit == -1) {
357 snprintf(name, GPIOMAXNAME - 1, "GPIO_%02d", idx);
358 break;
361 snprintf(name, GPIOMAXNAME - 1, "GP%c_%02d",
362 (map->lp_flags & GPIO_PIN_INPUT) ? 'I' : 'O',
363 map->lp_start_bit + idx);
364 break;
367 return (0);
370 static int
371 lpc_gpio_pin_get(device_t dev, uint32_t pin, uint32_t *value)
373 struct lpc_gpio_softc *sc = device_get_softc(dev);
374 const struct lpc_gpio_pinmap *map;
375 uint32_t state, flags;
376 int dir;
378 map = lpc_gpio_get_pinmap(pin);
380 if (lpc_gpio_pin_getflags(dev, pin, &flags))
381 return (ENXIO);
383 if (flags & GPIO_PIN_OUTPUT)
384 dir = 1;
386 if (flags & GPIO_PIN_INPUT)
387 dir = 0;
389 switch (map->lp_port) {
390 case 0:
391 state = lpc_gpio_get_4(sc, dir, LPC_GPIO_P0_OUTP_STATE,
392 LPC_GPIO_P0_INP_STATE);
393 *value = !!(state & (1 << LPC_GPIO_PIN_BIT(map, pin)));
394 case 1:
395 state = lpc_gpio_get_4(sc, dir, LPC_GPIO_P1_OUTP_STATE,
396 LPC_GPIO_P1_INP_STATE);
397 *value = !!(state & (1 << LPC_GPIO_PIN_BIT(map, pin)));
398 case 2:
399 state = lpc_gpio_read_4(sc, LPC_GPIO_P2_INP_STATE);
400 *value = !!(state & (1 << LPC_GPIO_PIN_BIT(map, pin)));
401 case 3:
402 state = lpc_gpio_get_4(sc, dir, LPC_GPIO_P3_OUTP_STATE,
403 LPC_GPIO_P3_INP_STATE);
404 if (map->lp_start_bit == -1) {
405 if (dir)
406 *value = !!(state & (1 << (25 +
407 LPC_GPIO_PIN_IDX(map, pin))));
408 else
409 *value = !!(state & (1 << (10 +
410 LPC_GPIO_PIN_IDX(map, pin))));
413 *value = !!(state & (1 << LPC_GPIO_PIN_BIT(map, pin)));
416 return (0);
419 static int
420 lpc_gpio_pin_set(device_t dev, uint32_t pin, uint32_t value)
422 struct lpc_gpio_softc *sc = device_get_softc(dev);
423 const struct lpc_gpio_pinmap *map;
424 uint32_t state, flags;
426 map = lpc_gpio_get_pinmap(pin);
428 if (lpc_gpio_pin_getflags(dev, pin, &flags))
429 return (ENXIO);
431 if ((flags & GPIO_PIN_OUTPUT) == 0)
432 return (EINVAL);
434 state = (1 << LPC_GPIO_PIN_BIT(map, pin));
436 switch (map->lp_port) {
437 case 0:
438 lpc_gpio_set_4(sc, value, LPC_GPIO_P0_OUTP_SET,
439 LPC_GPIO_P0_OUTP_CLR, state);
440 break;
441 case 1:
442 lpc_gpio_set_4(sc, value, LPC_GPIO_P1_OUTP_SET,
443 LPC_GPIO_P1_OUTP_CLR, state);
444 break;
445 case 2:
446 lpc_gpio_set_4(sc, value, LPC_GPIO_P2_OUTP_SET,
447 LPC_GPIO_P2_OUTP_CLR, state);
448 break;
449 case 3:
450 if (map->lp_start_bit == -1)
451 state = (1 << (25 + LPC_GPIO_PIN_IDX(map, pin)));
453 lpc_gpio_set_4(sc, value, LPC_GPIO_P3_OUTP_SET,
454 LPC_GPIO_P3_OUTP_CLR, state);
455 break;
458 return (0);
461 static int
462 lpc_gpio_pin_toggle(device_t dev, uint32_t pin)
464 const struct lpc_gpio_pinmap *map;
465 uint32_t flags;
467 map = lpc_gpio_get_pinmap(pin);
469 if (lpc_gpio_pin_getflags(dev, pin, &flags))
470 return (ENXIO);
472 if ((flags & GPIO_PIN_OUTPUT) == 0)
473 return (EINVAL);
475 panic("not implemented yet");
477 return (0);
481 static const struct lpc_gpio_pinmap *
482 lpc_gpio_get_pinmap(int pin)
484 const struct lpc_gpio_pinmap *map;
486 for (map = &lpc_gpio_pins[0]; map->lp_start_idx != -1; map++) {
487 if (pin >= map->lp_start_idx &&
488 pin < map->lp_start_idx + map->lp_pin_count)
489 return map;
492 panic("pin number %d out of range", pin);
496 lpc_gpio_set_flags(device_t dev, int pin, int flags)
498 if (lpc_gpio_sc == NULL)
499 return (ENXIO);
501 return lpc_gpio_pin_setflags(lpc_gpio_sc->lg_dev, pin, flags);
505 lpc_gpio_set_state(device_t dev, int pin, int state)
507 if (lpc_gpio_sc == NULL)
508 return (ENXIO);
510 return lpc_gpio_pin_set(lpc_gpio_sc->lg_dev, pin, state);
514 lpc_gpio_get_state(device_t dev, int pin, int *state)
516 if (lpc_gpio_sc == NULL)
517 return (ENXIO);
519 return lpc_gpio_pin_get(lpc_gpio_sc->lg_dev, pin, state);
522 void
523 lpc_gpio_init()
525 bus_space_tag_t bst;
526 bus_space_handle_t bsh;
528 bst = fdtbus_bs_tag;
530 /* Preset SPI devices CS pins to one */
531 bus_space_map(bst, LPC_GPIO_PHYS_BASE, LPC_GPIO_SIZE, 0, &bsh);
532 bus_space_write_4(bst, bsh, LPC_GPIO_P3_OUTP_SET,
533 1 << (SSD1289_CS_PIN - LPC_GPIO_GPO_00(0)) |
534 1 << (SSD1289_DC_PIN - LPC_GPIO_GPO_00(0)) |
535 1 << (ADS7846_CS_PIN - LPC_GPIO_GPO_00(0)));
536 bus_space_unmap(bst, bsh, LPC_GPIO_SIZE);
539 static device_method_t lpc_gpio_methods[] = {
540 /* Device interface */
541 DEVMETHOD(device_probe, lpc_gpio_probe),
542 DEVMETHOD(device_attach, lpc_gpio_attach),
543 DEVMETHOD(device_detach, lpc_gpio_detach),
545 /* GPIO interface */
546 DEVMETHOD(gpio_get_bus, lpc_gpio_get_bus),
547 DEVMETHOD(gpio_pin_max, lpc_gpio_pin_max),
548 DEVMETHOD(gpio_pin_getcaps, lpc_gpio_pin_getcaps),
549 DEVMETHOD(gpio_pin_getflags, lpc_gpio_pin_getflags),
550 DEVMETHOD(gpio_pin_setflags, lpc_gpio_pin_setflags),
551 DEVMETHOD(gpio_pin_getname, lpc_gpio_pin_getname),
552 DEVMETHOD(gpio_pin_set, lpc_gpio_pin_set),
553 DEVMETHOD(gpio_pin_get, lpc_gpio_pin_get),
554 DEVMETHOD(gpio_pin_toggle, lpc_gpio_pin_toggle),
556 { 0, 0 }
559 static devclass_t lpc_gpio_devclass;
561 static driver_t lpc_gpio_driver = {
562 "lpcgpio",
563 lpc_gpio_methods,
564 sizeof(struct lpc_gpio_softc),
567 extern devclass_t gpiobus_devclass, gpioc_devclass;
568 extern driver_t gpiobus_driver, gpioc_driver;
570 DRIVER_MODULE(lpcgpio, simplebus, lpc_gpio_driver, lpc_gpio_devclass, 0, 0);
571 DRIVER_MODULE(gpiobus, lpcgpio, gpiobus_driver, gpiobus_devclass, 0, 0);
572 DRIVER_MODULE(gpioc, lpcgpio, gpioc_driver, gpioc_devclass, 0, 0);
573 MODULE_VERSION(lpcgpio, 1);