]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/arm/broadcom/bcm2835/bcm2835_gpio.c
MFH
[FreeBSD/FreeBSD.git] / sys / arm / broadcom / bcm2835 / bcm2835_gpio.c
1 /*-
2  * Copyright (c) 2012 Oleksandr Tymoshenko <gonzo@FreeBSD.org>
3  * Copyright (c) 2012-2015 Luiz Otavio O Souza <loos@FreeBSD.org>
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following 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 <sys/param.h>
32 #include <sys/systm.h>
33 #include <sys/bus.h>
34 #include <sys/gpio.h>
35 #include <sys/interrupt.h>
36 #include <sys/kernel.h>
37 #include <sys/lock.h>
38 #include <sys/module.h>
39 #include <sys/mutex.h>
40 #include <sys/rman.h>
41 #include <sys/sysctl.h>
42
43 #include <machine/bus.h>
44
45 #include <dev/gpio/gpiobusvar.h>
46 #include <dev/ofw/ofw_bus.h>
47
48 #include <arm/broadcom/bcm2835/bcm2835_gpio.h>
49
50 #include "gpio_if.h"
51
52 #ifdef DEBUG
53 #define dprintf(fmt, args...) do { printf("%s(): ", __func__);   \
54     printf(fmt,##args); } while (0)
55 #else
56 #define dprintf(fmt, args...)
57 #endif
58
59 #define BCM_GPIO_IRQS           4
60 #define BCM_GPIO_PINS           54
61 #define BCM_GPIO_PINS_PER_BANK  32
62 #define BCM_GPIO_DEFAULT_CAPS   (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT |     \
63     GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN)
64
65 static struct resource_spec bcm_gpio_res_spec[] = {
66         { SYS_RES_MEMORY, 0, RF_ACTIVE },
67         { SYS_RES_IRQ, 0, RF_ACTIVE },
68         { SYS_RES_IRQ, 1, RF_ACTIVE },
69         { SYS_RES_IRQ, 2, RF_ACTIVE },
70         { SYS_RES_IRQ, 3, RF_ACTIVE },
71         { -1, 0, 0 }
72 };
73
74 struct bcm_gpio_sysctl {
75         struct bcm_gpio_softc   *sc;
76         uint32_t                pin;
77 };
78
79 struct bcm_gpio_softc {
80         device_t                sc_dev;
81         device_t                sc_busdev;
82         struct mtx              sc_mtx;
83         struct resource *       sc_res[BCM_GPIO_IRQS + 1];
84         bus_space_tag_t         sc_bst;
85         bus_space_handle_t      sc_bsh;
86         void *                  sc_intrhand[BCM_GPIO_IRQS];
87         int                     sc_gpio_npins;
88         int                     sc_ro_npins;
89         int                     sc_ro_pins[BCM_GPIO_PINS];
90         struct gpio_pin         sc_gpio_pins[BCM_GPIO_PINS];
91         struct intr_event *     sc_events[BCM_GPIO_PINS];
92         struct bcm_gpio_sysctl  sc_sysctl[BCM_GPIO_PINS];
93         enum intr_trigger       sc_irq_trigger[BCM_GPIO_PINS];
94         enum intr_polarity      sc_irq_polarity[BCM_GPIO_PINS];
95 };
96
97 enum bcm_gpio_pud {
98         BCM_GPIO_NONE,
99         BCM_GPIO_PULLDOWN,
100         BCM_GPIO_PULLUP,
101 };
102
103 #define BCM_GPIO_LOCK(_sc)      mtx_lock_spin(&(_sc)->sc_mtx)
104 #define BCM_GPIO_UNLOCK(_sc)    mtx_unlock_spin(&(_sc)->sc_mtx)
105 #define BCM_GPIO_LOCK_ASSERT(_sc)       mtx_assert(&(_sc)->sc_mtx, MA_OWNED)
106 #define BCM_GPIO_WRITE(_sc, _off, _val)         \
107     bus_space_write_4((_sc)->sc_bst, (_sc)->sc_bsh, _off, _val)
108 #define BCM_GPIO_READ(_sc, _off)                \
109     bus_space_read_4((_sc)->sc_bst, (_sc)->sc_bsh, _off)
110 #define BCM_GPIO_CLEAR_BITS(_sc, _off, _bits)   \
111     BCM_GPIO_WRITE(_sc, _off, BCM_GPIO_READ(_sc, _off) & ~(_bits))
112 #define BCM_GPIO_SET_BITS(_sc, _off, _bits)     \
113     BCM_GPIO_WRITE(_sc, _off, BCM_GPIO_READ(_sc, _off) | _bits)
114 #define BCM_GPIO_BANK(a)        (a / BCM_GPIO_PINS_PER_BANK)
115 #define BCM_GPIO_MASK(a)        (1U << (a % BCM_GPIO_PINS_PER_BANK))
116
117 #define BCM_GPIO_GPFSEL(_bank)  (0x00 + _bank * 4)      /* Function Select */
118 #define BCM_GPIO_GPSET(_bank)   (0x1c + _bank * 4)      /* Pin Out Set */
119 #define BCM_GPIO_GPCLR(_bank)   (0x28 + _bank * 4)      /* Pin Out Clear */
120 #define BCM_GPIO_GPLEV(_bank)   (0x34 + _bank * 4)      /* Pin Level */
121 #define BCM_GPIO_GPEDS(_bank)   (0x40 + _bank * 4)      /* Event Status */
122 #define BCM_GPIO_GPREN(_bank)   (0x4c + _bank * 4)      /* Rising Edge irq */
123 #define BCM_GPIO_GPFEN(_bank)   (0x58 + _bank * 4)      /* Falling Edge irq */
124 #define BCM_GPIO_GPHEN(_bank)   (0x64 + _bank * 4)      /* High Level irq */
125 #define BCM_GPIO_GPLEN(_bank)   (0x70 + _bank * 4)      /* Low Level irq */
126 #define BCM_GPIO_GPAREN(_bank)  (0x7c + _bank * 4)      /* Async Rising Edge */
127 #define BCM_GPIO_GPAFEN(_bank)  (0x88 + _bank * 4)      /* Async Falling Egde */
128 #define BCM_GPIO_GPPUD(_bank)   (0x94)                  /* Pin Pull up/down */
129 #define BCM_GPIO_GPPUDCLK(_bank) (0x98 + _bank * 4)     /* Pin Pull up clock */
130
131 static struct bcm_gpio_softc *bcm_gpio_sc = NULL;
132
133 static int
134 bcm_gpio_pin_is_ro(struct bcm_gpio_softc *sc, int pin)
135 {
136         int i;
137
138         for (i = 0; i < sc->sc_ro_npins; i++)
139                 if (pin == sc->sc_ro_pins[i])
140                         return (1);
141         return (0);
142 }
143
144 static uint32_t
145 bcm_gpio_get_function(struct bcm_gpio_softc *sc, uint32_t pin)
146 {
147         uint32_t bank, func, offset;
148
149         /* Five banks, 10 pins per bank, 3 bits per pin. */
150         bank = pin / 10;
151         offset = (pin - bank * 10) * 3;
152
153         BCM_GPIO_LOCK(sc);
154         func = (BCM_GPIO_READ(sc, BCM_GPIO_GPFSEL(bank)) >> offset) & 7;
155         BCM_GPIO_UNLOCK(sc);
156
157         return (func);
158 }
159
160 static void
161 bcm_gpio_func_str(uint32_t nfunc, char *buf, int bufsize)
162 {
163
164         switch (nfunc) {
165         case BCM_GPIO_INPUT:
166                 strncpy(buf, "input", bufsize);
167                 break;
168         case BCM_GPIO_OUTPUT:
169                 strncpy(buf, "output", bufsize);
170                 break;
171         case BCM_GPIO_ALT0:
172                 strncpy(buf, "alt0", bufsize);
173                 break;
174         case BCM_GPIO_ALT1:
175                 strncpy(buf, "alt1", bufsize);
176                 break;
177         case BCM_GPIO_ALT2:
178                 strncpy(buf, "alt2", bufsize);
179                 break;
180         case BCM_GPIO_ALT3:
181                 strncpy(buf, "alt3", bufsize);
182                 break;
183         case BCM_GPIO_ALT4:
184                 strncpy(buf, "alt4", bufsize);
185                 break;
186         case BCM_GPIO_ALT5:
187                 strncpy(buf, "alt5", bufsize);
188                 break;
189         default:
190                 strncpy(buf, "invalid", bufsize);
191         }
192 }
193
194 static int
195 bcm_gpio_str_func(char *func, uint32_t *nfunc)
196 {
197
198         if (strcasecmp(func, "input") == 0)
199                 *nfunc = BCM_GPIO_INPUT;
200         else if (strcasecmp(func, "output") == 0)
201                 *nfunc = BCM_GPIO_OUTPUT;
202         else if (strcasecmp(func, "alt0") == 0)
203                 *nfunc = BCM_GPIO_ALT0;
204         else if (strcasecmp(func, "alt1") == 0)
205                 *nfunc = BCM_GPIO_ALT1;
206         else if (strcasecmp(func, "alt2") == 0)
207                 *nfunc = BCM_GPIO_ALT2;
208         else if (strcasecmp(func, "alt3") == 0)
209                 *nfunc = BCM_GPIO_ALT3;
210         else if (strcasecmp(func, "alt4") == 0)
211                 *nfunc = BCM_GPIO_ALT4;
212         else if (strcasecmp(func, "alt5") == 0)
213                 *nfunc = BCM_GPIO_ALT5;
214         else
215                 return (-1);
216
217         return (0);
218 }
219
220 static uint32_t
221 bcm_gpio_func_flag(uint32_t nfunc)
222 {
223
224         switch (nfunc) {
225         case BCM_GPIO_INPUT:
226                 return (GPIO_PIN_INPUT);
227         case BCM_GPIO_OUTPUT:
228                 return (GPIO_PIN_OUTPUT);
229         }
230         return (0);
231 }
232
233 static void
234 bcm_gpio_set_function(struct bcm_gpio_softc *sc, uint32_t pin, uint32_t f)
235 {
236         uint32_t bank, data, offset;
237
238         /* Must be called with lock held. */
239         BCM_GPIO_LOCK_ASSERT(sc);
240
241         /* Five banks, 10 pins per bank, 3 bits per pin. */
242         bank = pin / 10;
243         offset = (pin - bank * 10) * 3;
244
245         data = BCM_GPIO_READ(sc, BCM_GPIO_GPFSEL(bank));
246         data &= ~(7 << offset);
247         data |= (f << offset);
248         BCM_GPIO_WRITE(sc, BCM_GPIO_GPFSEL(bank), data);
249 }
250
251 static void
252 bcm_gpio_set_pud(struct bcm_gpio_softc *sc, uint32_t pin, uint32_t state)
253 {
254         uint32_t bank;
255
256         /* Must be called with lock held. */
257         BCM_GPIO_LOCK_ASSERT(sc);
258
259         bank = BCM_GPIO_BANK(pin);
260         BCM_GPIO_WRITE(sc, BCM_GPIO_GPPUD(0), state);
261         BCM_GPIO_WRITE(sc, BCM_GPIO_GPPUDCLK(bank), BCM_GPIO_MASK(pin));
262         BCM_GPIO_WRITE(sc, BCM_GPIO_GPPUD(0), 0);
263         BCM_GPIO_WRITE(sc, BCM_GPIO_GPPUDCLK(bank), 0);
264 }
265
266 void
267 bcm_gpio_set_alternate(device_t dev, uint32_t pin, uint32_t nfunc)
268 {
269         struct bcm_gpio_softc *sc;
270         int i;
271
272         sc = device_get_softc(dev);
273         BCM_GPIO_LOCK(sc);
274
275         /* Disable pull-up or pull-down on pin. */
276         bcm_gpio_set_pud(sc, pin, BCM_GPIO_NONE);
277
278         /* And now set the pin function. */
279         bcm_gpio_set_function(sc, pin, nfunc);
280
281         /* Update the pin flags. */
282         for (i = 0; i < sc->sc_gpio_npins; i++) {
283                 if (sc->sc_gpio_pins[i].gp_pin == pin)
284                         break;
285         }
286         if (i < sc->sc_gpio_npins)
287                 sc->sc_gpio_pins[i].gp_flags = bcm_gpio_func_flag(nfunc);
288
289         BCM_GPIO_UNLOCK(sc);
290 }
291
292 static void
293 bcm_gpio_pin_configure(struct bcm_gpio_softc *sc, struct gpio_pin *pin,
294     unsigned int flags)
295 {
296
297         BCM_GPIO_LOCK(sc);
298
299         /*
300          * Manage input/output.
301          */
302         if (flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) {
303                 pin->gp_flags &= ~(GPIO_PIN_INPUT|GPIO_PIN_OUTPUT);
304                 if (flags & GPIO_PIN_OUTPUT) {
305                         pin->gp_flags |= GPIO_PIN_OUTPUT;
306                         bcm_gpio_set_function(sc, pin->gp_pin,
307                             BCM_GPIO_OUTPUT);
308                 } else {
309                         pin->gp_flags |= GPIO_PIN_INPUT;
310                         bcm_gpio_set_function(sc, pin->gp_pin,
311                             BCM_GPIO_INPUT);
312                 }
313         }
314
315         /* Manage Pull-up/pull-down. */
316         pin->gp_flags &= ~(GPIO_PIN_PULLUP|GPIO_PIN_PULLDOWN);
317         if (flags & (GPIO_PIN_PULLUP|GPIO_PIN_PULLDOWN)) {
318                 if (flags & GPIO_PIN_PULLUP) {
319                         pin->gp_flags |= GPIO_PIN_PULLUP;
320                         bcm_gpio_set_pud(sc, pin->gp_pin, BCM_GPIO_PULLUP);
321                 } else {
322                         pin->gp_flags |= GPIO_PIN_PULLDOWN;
323                         bcm_gpio_set_pud(sc, pin->gp_pin, BCM_GPIO_PULLDOWN);
324                 }
325         } else 
326                 bcm_gpio_set_pud(sc, pin->gp_pin, BCM_GPIO_NONE);
327
328         BCM_GPIO_UNLOCK(sc);
329 }
330
331 static device_t
332 bcm_gpio_get_bus(device_t dev)
333 {
334         struct bcm_gpio_softc *sc;
335
336         sc = device_get_softc(dev);
337
338         return (sc->sc_busdev);
339 }
340
341 static int
342 bcm_gpio_pin_max(device_t dev, int *maxpin)
343 {
344
345         *maxpin = BCM_GPIO_PINS - 1;
346         return (0);
347 }
348
349 static int
350 bcm_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
351 {
352         struct bcm_gpio_softc *sc = device_get_softc(dev);
353         int i;
354
355         for (i = 0; i < sc->sc_gpio_npins; i++) {
356                 if (sc->sc_gpio_pins[i].gp_pin == pin)
357                         break;
358         }
359
360         if (i >= sc->sc_gpio_npins)
361                 return (EINVAL);
362
363         BCM_GPIO_LOCK(sc);
364         *caps = sc->sc_gpio_pins[i].gp_caps;
365         BCM_GPIO_UNLOCK(sc);
366
367         return (0);
368 }
369
370 static int
371 bcm_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
372 {
373         struct bcm_gpio_softc *sc = device_get_softc(dev);
374         int i;
375
376         for (i = 0; i < sc->sc_gpio_npins; i++) {
377                 if (sc->sc_gpio_pins[i].gp_pin == pin)
378                         break;
379         }
380
381         if (i >= sc->sc_gpio_npins)
382                 return (EINVAL);
383
384         BCM_GPIO_LOCK(sc);
385         *flags = sc->sc_gpio_pins[i].gp_flags;
386         BCM_GPIO_UNLOCK(sc);
387
388         return (0);
389 }
390
391 static int
392 bcm_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
393 {
394         struct bcm_gpio_softc *sc = device_get_softc(dev);
395         int i;
396
397         for (i = 0; i < sc->sc_gpio_npins; i++) {
398                 if (sc->sc_gpio_pins[i].gp_pin == pin)
399                         break;
400         }
401
402         if (i >= sc->sc_gpio_npins)
403                 return (EINVAL);
404
405         BCM_GPIO_LOCK(sc);
406         memcpy(name, sc->sc_gpio_pins[i].gp_name, GPIOMAXNAME);
407         BCM_GPIO_UNLOCK(sc);
408
409         return (0);
410 }
411
412 static int
413 bcm_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
414 {
415         struct bcm_gpio_softc *sc = device_get_softc(dev);
416         int i;
417
418         for (i = 0; i < sc->sc_gpio_npins; i++) {
419                 if (sc->sc_gpio_pins[i].gp_pin == pin)
420                         break;
421         }
422
423         if (i >= sc->sc_gpio_npins)
424                 return (EINVAL);
425
426         /* We never touch on read-only/reserved pins. */
427         if (bcm_gpio_pin_is_ro(sc, pin))
428                 return (EINVAL);
429
430         bcm_gpio_pin_configure(sc, &sc->sc_gpio_pins[i], flags);
431
432         return (0);
433 }
434
435 static int
436 bcm_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value)
437 {
438         struct bcm_gpio_softc *sc = device_get_softc(dev);
439         uint32_t bank, reg;
440         int i;
441
442         for (i = 0; i < sc->sc_gpio_npins; i++) {
443                 if (sc->sc_gpio_pins[i].gp_pin == pin)
444                         break;
445         }
446         if (i >= sc->sc_gpio_npins)
447                 return (EINVAL);
448         /* We never write to read-only/reserved pins. */
449         if (bcm_gpio_pin_is_ro(sc, pin))
450                 return (EINVAL);
451         BCM_GPIO_LOCK(sc);
452         bank = BCM_GPIO_BANK(pin);
453         if (value)
454                 reg = BCM_GPIO_GPSET(bank);
455         else
456                 reg = BCM_GPIO_GPCLR(bank);
457         BCM_GPIO_WRITE(sc, reg, BCM_GPIO_MASK(pin));
458         BCM_GPIO_UNLOCK(sc);
459
460         return (0);
461 }
462
463 static int
464 bcm_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val)
465 {
466         struct bcm_gpio_softc *sc = device_get_softc(dev);
467         uint32_t bank, reg_data;
468         int i;
469
470         for (i = 0; i < sc->sc_gpio_npins; i++) {
471                 if (sc->sc_gpio_pins[i].gp_pin == pin)
472                         break;
473         }
474         if (i >= sc->sc_gpio_npins)
475                 return (EINVAL);
476         bank = BCM_GPIO_BANK(pin);
477         BCM_GPIO_LOCK(sc);
478         reg_data = BCM_GPIO_READ(sc, BCM_GPIO_GPLEV(bank));
479         BCM_GPIO_UNLOCK(sc);
480         *val = (reg_data & BCM_GPIO_MASK(pin)) ? 1 : 0;
481
482         return (0);
483 }
484
485 static int
486 bcm_gpio_pin_toggle(device_t dev, uint32_t pin)
487 {
488         struct bcm_gpio_softc *sc = device_get_softc(dev);
489         uint32_t bank, data, reg;
490         int i;
491
492         for (i = 0; i < sc->sc_gpio_npins; i++) {
493                 if (sc->sc_gpio_pins[i].gp_pin == pin)
494                         break;
495         }
496         if (i >= sc->sc_gpio_npins)
497                 return (EINVAL);
498         /* We never write to read-only/reserved pins. */
499         if (bcm_gpio_pin_is_ro(sc, pin))
500                 return (EINVAL);
501         BCM_GPIO_LOCK(sc);
502         bank = BCM_GPIO_BANK(pin);
503         data = BCM_GPIO_READ(sc, BCM_GPIO_GPLEV(bank));
504         if (data & BCM_GPIO_MASK(pin))
505                 reg = BCM_GPIO_GPCLR(bank);
506         else
507                 reg = BCM_GPIO_GPSET(bank);
508         BCM_GPIO_WRITE(sc, reg, BCM_GPIO_MASK(pin));
509         BCM_GPIO_UNLOCK(sc);
510
511         return (0);
512 }
513
514 static int
515 bcm_gpio_func_proc(SYSCTL_HANDLER_ARGS)
516 {
517         char buf[16];
518         struct bcm_gpio_softc *sc;
519         struct bcm_gpio_sysctl *sc_sysctl;
520         uint32_t nfunc;
521         int error;
522
523         sc_sysctl = arg1;
524         sc = sc_sysctl->sc;
525
526         /* Get the current pin function. */
527         nfunc = bcm_gpio_get_function(sc, sc_sysctl->pin);
528         bcm_gpio_func_str(nfunc, buf, sizeof(buf));
529
530         error = sysctl_handle_string(oidp, buf, sizeof(buf), req);
531         if (error != 0 || req->newptr == NULL)
532                 return (error);
533         /* Ignore changes on read-only pins. */
534         if (bcm_gpio_pin_is_ro(sc, sc_sysctl->pin))
535                 return (0);
536         /* Parse the user supplied string and check for a valid pin function. */
537         if (bcm_gpio_str_func(buf, &nfunc) != 0)
538                 return (EINVAL);
539
540         /* Update the pin alternate function. */
541         bcm_gpio_set_alternate(sc->sc_dev, sc_sysctl->pin, nfunc);
542
543         return (0);
544 }
545
546 static void
547 bcm_gpio_sysctl_init(struct bcm_gpio_softc *sc)
548 {
549         char pinbuf[3];
550         struct bcm_gpio_sysctl *sc_sysctl;
551         struct sysctl_ctx_list *ctx;
552         struct sysctl_oid *tree_node, *pin_node, *pinN_node;
553         struct sysctl_oid_list *tree, *pin_tree, *pinN_tree;
554         int i;
555
556         /*
557          * Add per-pin sysctl tree/handlers.
558          */
559         ctx = device_get_sysctl_ctx(sc->sc_dev);
560         tree_node = device_get_sysctl_tree(sc->sc_dev);
561         tree = SYSCTL_CHILDREN(tree_node);
562         pin_node = SYSCTL_ADD_NODE(ctx, tree, OID_AUTO, "pin",
563             CTLFLAG_RD, NULL, "GPIO Pins");
564         pin_tree = SYSCTL_CHILDREN(pin_node);
565
566         for (i = 0; i < sc->sc_gpio_npins; i++) {
567
568                 snprintf(pinbuf, sizeof(pinbuf), "%d", i);
569                 pinN_node = SYSCTL_ADD_NODE(ctx, pin_tree, OID_AUTO, pinbuf,
570                     CTLFLAG_RD, NULL, "GPIO Pin");
571                 pinN_tree = SYSCTL_CHILDREN(pinN_node);
572
573                 sc->sc_sysctl[i].sc = sc;
574                 sc_sysctl = &sc->sc_sysctl[i];
575                 sc_sysctl->sc = sc;
576                 sc_sysctl->pin = sc->sc_gpio_pins[i].gp_pin;
577                 SYSCTL_ADD_PROC(ctx, pinN_tree, OID_AUTO, "function",
578                     CTLFLAG_RW | CTLTYPE_STRING, sc_sysctl,
579                     sizeof(struct bcm_gpio_sysctl), bcm_gpio_func_proc,
580                     "A", "Pin Function");
581         }
582 }
583
584 static int
585 bcm_gpio_get_ro_pins(struct bcm_gpio_softc *sc, phandle_t node,
586         const char *propname, const char *label)
587 {
588         int i, need_comma, npins, range_start, range_stop;
589         pcell_t *pins;
590
591         /* Get the property data. */
592         npins = OF_getencprop_alloc(node, propname, sizeof(*pins),
593             (void **)&pins);
594         if (npins < 0)
595                 return (-1);
596         if (npins == 0) {
597                 free(pins, M_OFWPROP);
598                 return (0);
599         }
600         for (i = 0; i < npins; i++)
601                 sc->sc_ro_pins[i + sc->sc_ro_npins] = pins[i];
602         sc->sc_ro_npins += npins;
603         need_comma = 0;
604         device_printf(sc->sc_dev, "%s pins: ", label);
605         range_start = range_stop = pins[0];
606         for (i = 1; i < npins; i++) {
607                 if (pins[i] != range_stop + 1) {
608                         if (need_comma)
609                                 printf(",");
610                         if (range_start != range_stop)
611                                 printf("%d-%d", range_start, range_stop);
612                         else
613                                 printf("%d", range_start);
614                         range_start = range_stop = pins[i];
615                         need_comma = 1;
616                 } else
617                         range_stop++;
618         }
619         if (need_comma)
620                 printf(",");
621         if (range_start != range_stop)
622                 printf("%d-%d.\n", range_start, range_stop);
623         else
624                 printf("%d.\n", range_start);
625         free(pins, M_OFWPROP);
626
627         return (0);
628 }
629
630 static int
631 bcm_gpio_get_reserved_pins(struct bcm_gpio_softc *sc)
632 {
633         char *name;
634         phandle_t gpio, node, reserved;
635         ssize_t len;
636
637         /* Get read-only pins. */
638         gpio = ofw_bus_get_node(sc->sc_dev);
639         if (bcm_gpio_get_ro_pins(sc, gpio, "broadcom,read-only",
640             "read-only") != 0)
641                 return (-1);
642         /* Traverse the GPIO subnodes to find the reserved pins node. */
643         reserved = 0;
644         node = OF_child(gpio);
645         while ((node != 0) && (reserved == 0)) {
646                 len = OF_getprop_alloc(node, "name", 1, (void **)&name);
647                 if (len == -1)
648                         return (-1);
649                 if (strcmp(name, "reserved") == 0)
650                         reserved = node;
651                 free(name, M_OFWPROP);
652                 node = OF_peer(node);
653         }
654         if (reserved == 0)
655                 return (-1);
656         /* Get the reserved pins. */
657         if (bcm_gpio_get_ro_pins(sc, reserved, "broadcom,pins",
658             "reserved") != 0)
659                 return (-1);
660
661         return (0);
662 }
663
664 static int
665 bcm_gpio_intr(void *arg)
666 {
667         int bank_last, irq;
668         struct bcm_gpio_softc *sc;
669         struct intr_event *event;
670         uint32_t bank, mask, reg;
671
672         sc = (struct bcm_gpio_softc *)arg;
673         reg = 0;
674         bank_last = -1;
675         for (irq = 0; irq < BCM_GPIO_PINS; irq++) {
676                 bank = BCM_GPIO_BANK(irq);
677                 mask = BCM_GPIO_MASK(irq);
678                 if (bank != bank_last) {
679                         reg = BCM_GPIO_READ(sc, BCM_GPIO_GPEDS(bank));
680                         bank_last = bank;
681                 }
682                 if (reg & mask) {
683                         event = sc->sc_events[irq];
684                         if (event != NULL && !TAILQ_EMPTY(&event->ie_handlers))
685                                 intr_event_handle(event, NULL);
686                         else {
687                                 device_printf(sc->sc_dev, "Stray IRQ %d\n",
688                                     irq);
689                         }
690                         /* Clear the Status bit by writing '1' to it. */
691                         BCM_GPIO_WRITE(sc, BCM_GPIO_GPEDS(bank), mask);
692                 }
693         }
694
695         return (FILTER_HANDLED);
696 }
697
698 static int
699 bcm_gpio_probe(device_t dev)
700 {
701
702         if (!ofw_bus_status_okay(dev))
703                 return (ENXIO);
704
705         if (!ofw_bus_is_compatible(dev, "broadcom,bcm2835-gpio"))
706                 return (ENXIO);
707
708         device_set_desc(dev, "BCM2708/2835 GPIO controller");
709         return (BUS_PROBE_DEFAULT);
710 }
711
712 static int
713 bcm_gpio_intr_attach(device_t dev)
714 {
715         struct bcm_gpio_softc *sc;
716         int i;
717
718         sc = device_get_softc(dev);
719         for (i = 0; i < BCM_GPIO_IRQS; i++) {
720                 if (bus_setup_intr(dev, sc->sc_res[i + 1],
721                     INTR_TYPE_MISC | INTR_MPSAFE, bcm_gpio_intr,
722                     NULL, sc, &sc->sc_intrhand[i]) != 0) {
723                         return (-1);
724                 }
725         }
726
727         return (0);
728 }
729
730 static void
731 bcm_gpio_intr_detach(device_t dev)
732 {
733         struct bcm_gpio_softc *sc;
734         int i;
735
736         sc = device_get_softc(dev);
737         for (i = 0; i < BCM_GPIO_IRQS; i++) {
738                 if (sc->sc_intrhand[i]) {
739                         bus_teardown_intr(dev, sc->sc_res[i + 1],
740                             sc->sc_intrhand[i]);
741                 }
742         }
743 }
744
745 static int
746 bcm_gpio_attach(device_t dev)
747 {
748         int i, j;
749         phandle_t gpio;
750         struct bcm_gpio_softc *sc;
751         uint32_t func;
752
753         if (bcm_gpio_sc != NULL)
754                 return (ENXIO);
755
756         bcm_gpio_sc = sc = device_get_softc(dev);
757         sc->sc_dev = dev;
758         mtx_init(&sc->sc_mtx, "bcm gpio", "gpio", MTX_SPIN);
759         if (bus_alloc_resources(dev, bcm_gpio_res_spec, sc->sc_res) != 0) {
760                 device_printf(dev, "cannot allocate resources\n");
761                 goto fail;
762         }
763         sc->sc_bst = rman_get_bustag(sc->sc_res[0]);
764         sc->sc_bsh = rman_get_bushandle(sc->sc_res[0]);
765         /* Setup the GPIO interrupt handler. */
766         if (bcm_gpio_intr_attach(dev)) {
767                 device_printf(dev, "unable to setup the gpio irq handler\n");
768                 goto fail;
769         }
770         /* Find our node. */
771         gpio = ofw_bus_get_node(sc->sc_dev);
772         if (!OF_hasprop(gpio, "gpio-controller"))
773                 /* Node is not a GPIO controller. */
774                 goto fail;
775         /*
776          * Find the read-only pins.  These are pins we never touch or bad
777          * things could happen.
778          */
779         if (bcm_gpio_get_reserved_pins(sc) == -1)
780                 goto fail;
781         /* Initialize the software controlled pins. */
782         for (i = 0, j = 0; j < BCM_GPIO_PINS; j++) {
783                 snprintf(sc->sc_gpio_pins[i].gp_name, GPIOMAXNAME,
784                     "pin %d", j);
785                 func = bcm_gpio_get_function(sc, j);
786                 sc->sc_gpio_pins[i].gp_pin = j;
787                 sc->sc_gpio_pins[i].gp_caps = BCM_GPIO_DEFAULT_CAPS;
788                 sc->sc_gpio_pins[i].gp_flags = bcm_gpio_func_flag(func);
789                 /* The default is active-low interrupts. */
790                 sc->sc_irq_trigger[i] = INTR_TRIGGER_LEVEL;
791                 sc->sc_irq_polarity[i] = INTR_POLARITY_LOW;
792                 i++;
793         }
794         sc->sc_gpio_npins = i;
795         bcm_gpio_sysctl_init(sc);
796         sc->sc_busdev = gpiobus_attach_bus(dev);
797         if (sc->sc_busdev == NULL)
798                 goto fail;
799
800         return (0);
801
802 fail:
803         bcm_gpio_intr_detach(dev);
804         bus_release_resources(dev, bcm_gpio_res_spec, sc->sc_res);
805         mtx_destroy(&sc->sc_mtx);
806
807         return (ENXIO);
808 }
809
810 static int
811 bcm_gpio_detach(device_t dev)
812 {
813
814         return (EBUSY);
815 }
816
817 static uint32_t
818 bcm_gpio_intr_reg(struct bcm_gpio_softc *sc, unsigned int irq, uint32_t bank)
819 {
820
821         if (irq > BCM_GPIO_PINS)
822                 return (0);
823         if (sc->sc_irq_trigger[irq] == INTR_TRIGGER_LEVEL) {
824                 if (sc->sc_irq_polarity[irq] == INTR_POLARITY_LOW)
825                         return (BCM_GPIO_GPLEN(bank));
826                 else if (sc->sc_irq_polarity[irq] == INTR_POLARITY_HIGH)
827                         return (BCM_GPIO_GPHEN(bank));
828         } else if (sc->sc_irq_trigger[irq] == INTR_TRIGGER_EDGE) {
829                 if (sc->sc_irq_polarity[irq] == INTR_POLARITY_LOW)
830                         return (BCM_GPIO_GPFEN(bank));
831                 else if (sc->sc_irq_polarity[irq] == INTR_POLARITY_HIGH)
832                         return (BCM_GPIO_GPREN(bank));
833         }
834
835         return (0);
836 }
837
838 static void
839 bcm_gpio_mask_irq(void *source)
840 {
841         uint32_t bank, mask, reg;
842         unsigned int irq;
843
844         irq = (unsigned int)source;
845         if (irq > BCM_GPIO_PINS)
846                 return;
847         if (bcm_gpio_pin_is_ro(bcm_gpio_sc, irq))
848                 return;
849         bank = BCM_GPIO_BANK(irq);
850         mask = BCM_GPIO_MASK(irq);
851         BCM_GPIO_LOCK(bcm_gpio_sc);
852         reg = bcm_gpio_intr_reg(bcm_gpio_sc, irq, bank);
853         if (reg != 0)
854                 BCM_GPIO_CLEAR_BITS(bcm_gpio_sc, reg, mask);
855         BCM_GPIO_UNLOCK(bcm_gpio_sc);
856 }
857
858 static void
859 bcm_gpio_unmask_irq(void *source)
860 {
861         uint32_t bank, mask, reg;
862         unsigned int irq;
863
864         irq = (unsigned int)source;
865         if (irq > BCM_GPIO_PINS)
866                 return;
867         if (bcm_gpio_pin_is_ro(bcm_gpio_sc, irq))
868                 return;
869         bank = BCM_GPIO_BANK(irq);
870         mask = BCM_GPIO_MASK(irq);
871         BCM_GPIO_LOCK(bcm_gpio_sc);
872         reg = bcm_gpio_intr_reg(bcm_gpio_sc, irq, bank);
873         if (reg != 0)
874                 BCM_GPIO_SET_BITS(bcm_gpio_sc, reg, mask);
875         BCM_GPIO_UNLOCK(bcm_gpio_sc);
876 }
877
878 static int
879 bcm_gpio_activate_resource(device_t bus, device_t child, int type, int rid,
880         struct resource *res)
881 {
882         int pin;
883
884         if (type != SYS_RES_IRQ)
885                 return (ENXIO);
886         /* Unmask the interrupt. */
887         pin = rman_get_start(res);
888         bcm_gpio_unmask_irq((void *)pin);
889
890         return (0);
891 }
892
893 static int
894 bcm_gpio_deactivate_resource(device_t bus, device_t child, int type, int rid,
895         struct resource *res)
896 {
897         int pin;
898
899         if (type != SYS_RES_IRQ)
900                 return (ENXIO);
901         /* Mask the interrupt. */
902         pin = rman_get_start(res);
903         bcm_gpio_mask_irq((void *)pin);
904
905         return (0);
906 }
907
908 static int
909 bcm_gpio_config_intr(device_t dev, int irq, enum intr_trigger trig,
910         enum intr_polarity pol)
911 {
912         int bank;
913         struct bcm_gpio_softc *sc;
914         uint32_t mask, oldreg, reg;
915
916         if (irq > BCM_GPIO_PINS)
917                 return (EINVAL);
918         /* There is no standard trigger or polarity. */
919         if (trig == INTR_TRIGGER_CONFORM || pol == INTR_POLARITY_CONFORM)
920                 return (EINVAL);
921         sc = device_get_softc(dev);
922         if (bcm_gpio_pin_is_ro(sc, irq))
923                 return (EINVAL);
924         bank = BCM_GPIO_BANK(irq);
925         mask = BCM_GPIO_MASK(irq);
926         BCM_GPIO_LOCK(sc);
927         oldreg = bcm_gpio_intr_reg(sc, irq, bank);
928         sc->sc_irq_trigger[irq] = trig;
929         sc->sc_irq_polarity[irq] = pol;
930         reg = bcm_gpio_intr_reg(sc, irq, bank);
931         if (reg != 0)
932                 BCM_GPIO_SET_BITS(sc, reg, mask);
933         if (reg != oldreg && oldreg != 0)
934                 BCM_GPIO_CLEAR_BITS(sc, oldreg, mask);
935         BCM_GPIO_UNLOCK(sc);
936
937         return (0);
938 }
939
940 static int
941 bcm_gpio_setup_intr(device_t bus, device_t child, struct resource *ires,
942         int flags, driver_filter_t *filt, driver_intr_t *handler,
943         void *arg, void **cookiep)
944 {
945         struct bcm_gpio_softc *sc;
946         struct intr_event *event;
947         int pin, error;
948
949         sc = device_get_softc(bus);
950         pin = rman_get_start(ires);
951         if (pin > BCM_GPIO_PINS)
952                 panic("%s: bad pin %d", __func__, pin);
953         event = sc->sc_events[pin];
954         if (event == NULL) {
955                 error = intr_event_create(&event, (void *)pin, 0, pin, 
956                     bcm_gpio_mask_irq, bcm_gpio_unmask_irq, NULL, NULL,
957                     "gpio%d pin%d:", device_get_unit(bus), pin);
958                 if (error != 0)
959                         return (error);
960                 sc->sc_events[pin] = event;
961         }
962         intr_event_add_handler(event, device_get_nameunit(child), filt,
963             handler, arg, intr_priority(flags), flags, cookiep);
964
965         return (0);
966 }
967
968 static int
969 bcm_gpio_teardown_intr(device_t dev, device_t child, struct resource *ires,
970         void *cookie)
971 {
972         struct bcm_gpio_softc *sc;
973         int pin, err;
974
975         sc = device_get_softc(dev);
976         pin = rman_get_start(ires);
977         if (pin > BCM_GPIO_PINS)
978                 panic("%s: bad pin %d", __func__, pin);
979         if (sc->sc_events[pin] == NULL)
980                 panic("Trying to teardown unoccupied IRQ");
981         err = intr_event_remove_handler(cookie);
982         if (!err)
983                 sc->sc_events[pin] = NULL;
984
985         return (err);
986 }
987
988 static phandle_t
989 bcm_gpio_get_node(device_t bus, device_t dev)
990 {
991
992         /* We only have one child, the GPIO bus, which needs our own node. */
993         return (ofw_bus_get_node(bus));
994 }
995
996 static device_method_t bcm_gpio_methods[] = {
997         /* Device interface */
998         DEVMETHOD(device_probe,         bcm_gpio_probe),
999         DEVMETHOD(device_attach,        bcm_gpio_attach),
1000         DEVMETHOD(device_detach,        bcm_gpio_detach),
1001
1002         /* GPIO protocol */
1003         DEVMETHOD(gpio_get_bus,         bcm_gpio_get_bus),
1004         DEVMETHOD(gpio_pin_max,         bcm_gpio_pin_max),
1005         DEVMETHOD(gpio_pin_getname,     bcm_gpio_pin_getname),
1006         DEVMETHOD(gpio_pin_getflags,    bcm_gpio_pin_getflags),
1007         DEVMETHOD(gpio_pin_getcaps,     bcm_gpio_pin_getcaps),
1008         DEVMETHOD(gpio_pin_setflags,    bcm_gpio_pin_setflags),
1009         DEVMETHOD(gpio_pin_get,         bcm_gpio_pin_get),
1010         DEVMETHOD(gpio_pin_set,         bcm_gpio_pin_set),
1011         DEVMETHOD(gpio_pin_toggle,      bcm_gpio_pin_toggle),
1012
1013         /* Bus interface */
1014         DEVMETHOD(bus_activate_resource,        bcm_gpio_activate_resource),
1015         DEVMETHOD(bus_deactivate_resource,      bcm_gpio_deactivate_resource),
1016         DEVMETHOD(bus_config_intr,      bcm_gpio_config_intr),
1017         DEVMETHOD(bus_setup_intr,       bcm_gpio_setup_intr),
1018         DEVMETHOD(bus_teardown_intr,    bcm_gpio_teardown_intr),
1019
1020         /* ofw_bus interface */
1021         DEVMETHOD(ofw_bus_get_node,     bcm_gpio_get_node),
1022
1023         DEVMETHOD_END
1024 };
1025
1026 static devclass_t bcm_gpio_devclass;
1027
1028 static driver_t bcm_gpio_driver = {
1029         "gpio",
1030         bcm_gpio_methods,
1031         sizeof(struct bcm_gpio_softc),
1032 };
1033
1034 DRIVER_MODULE(bcm_gpio, simplebus, bcm_gpio_driver, bcm_gpio_devclass, 0, 0);