xref: /freebsd/sys/arm/broadcom/bcm2835/bcm2835_gpio.c (revision 12f110aa1ad3c9d0ead55bf80f2f994b4b845ffb)
1 /*-
2  * Copyright (c) 2012 Oleksandr Tymoshenko <gonzo@freebsd.org>
3  * Copyright (c) 2012 Luiz Otavio O Souza.
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 
35 #include <sys/kernel.h>
36 #include <sys/module.h>
37 #include <sys/rman.h>
38 #include <sys/lock.h>
39 #include <sys/mutex.h>
40 #include <sys/gpio.h>
41 #include <sys/sysctl.h>
42 
43 #include <machine/bus.h>
44 #include <machine/cpu.h>
45 #include <machine/cpufunc.h>
46 #include <machine/resource.h>
47 #include <machine/fdt.h>
48 #include <machine/frame.h>
49 #include <machine/intr.h>
50 
51 #include <dev/fdt/fdt_common.h>
52 #include <dev/ofw/ofw_bus.h>
53 #include <dev/ofw/ofw_bus_subr.h>
54 
55 #include "gpio_if.h"
56 
57 #undef	DEBUG
58 
59 #ifdef DEBUG
60 #define dprintf(fmt, args...) do { printf("%s(): ", __func__);   \
61     printf(fmt,##args); } while (0)
62 #else
63 #define dprintf(fmt, args...)
64 #endif
65 
66 #define	BCM_GPIO_PINS		54
67 #define	BCM_GPIO_DEFAULT_CAPS	(GPIO_PIN_INPUT | GPIO_PIN_OUTPUT |	\
68     GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN)
69 
70 struct bcm_gpio_sysctl {
71 	struct bcm_gpio_softc	*sc;
72 	uint32_t		pin;
73 };
74 
75 struct bcm_gpio_softc {
76 	device_t		sc_dev;
77 	struct mtx		sc_mtx;
78 	struct resource *	sc_mem_res;
79 	struct resource *	sc_irq_res;
80 	bus_space_tag_t		sc_bst;
81 	bus_space_handle_t	sc_bsh;
82 	void *			sc_intrhand;
83 	int			sc_gpio_npins;
84 	int			sc_ro_npins;
85 	int			sc_ro_pins[BCM_GPIO_PINS];
86 	struct gpio_pin		sc_gpio_pins[BCM_GPIO_PINS];
87 	struct bcm_gpio_sysctl	sc_sysctl[BCM_GPIO_PINS];
88 };
89 
90 enum bcm_gpio_fsel {
91 	BCM_GPIO_INPUT,
92 	BCM_GPIO_OUTPUT,
93 	BCM_GPIO_ALT5,
94 	BCM_GPIO_ALT4,
95 	BCM_GPIO_ALT0,
96 	BCM_GPIO_ALT1,
97 	BCM_GPIO_ALT2,
98 	BCM_GPIO_ALT3,
99 };
100 
101 enum bcm_gpio_pud {
102 	BCM_GPIO_NONE,
103 	BCM_GPIO_PULLDOWN,
104 	BCM_GPIO_PULLUP,
105 };
106 
107 #define	BCM_GPIO_LOCK(_sc)	mtx_lock(&_sc->sc_mtx)
108 #define	BCM_GPIO_UNLOCK(_sc)	mtx_unlock(&_sc->sc_mtx)
109 #define	BCM_GPIO_LOCK_ASSERT(_sc)	mtx_assert(&_sc->sc_mtx, MA_OWNED)
110 
111 #define	BCM_GPIO_GPFSEL(_bank)	0x00 + _bank * 4
112 #define	BCM_GPIO_GPSET(_bank)	0x1c + _bank * 4
113 #define	BCM_GPIO_GPCLR(_bank)	0x28 + _bank * 4
114 #define	BCM_GPIO_GPLEV(_bank)	0x34 + _bank * 4
115 #define	BCM_GPIO_GPPUD(_bank)	0x94
116 #define	BCM_GPIO_GPPUDCLK(_bank)	0x98 + _bank * 4
117 
118 #define	BCM_GPIO_WRITE(_sc, _off, _val)		\
119     bus_space_write_4(_sc->sc_bst, _sc->sc_bsh, _off, _val)
120 #define	BCM_GPIO_READ(_sc, _off)		\
121     bus_space_read_4(_sc->sc_bst, _sc->sc_bsh, _off)
122 
123 static int
124 bcm_gpio_pin_is_ro(struct bcm_gpio_softc *sc, int pin)
125 {
126 	int i;
127 
128 	for (i = 0; i < sc->sc_ro_npins; i++)
129 		if (pin == sc->sc_ro_pins[i])
130 			return (1);
131 	return (0);
132 }
133 
134 static uint32_t
135 bcm_gpio_get_function(struct bcm_gpio_softc *sc, uint32_t pin)
136 {
137 	uint32_t bank, func, offset;
138 
139 	/* Five banks, 10 pins per bank, 3 bits per pin. */
140 	bank = pin / 10;
141 	offset = (pin - bank * 10) * 3;
142 
143 	BCM_GPIO_LOCK(sc);
144 	func = (BCM_GPIO_READ(sc, BCM_GPIO_GPFSEL(bank)) >> offset) & 7;
145 	BCM_GPIO_UNLOCK(sc);
146 
147 	return (func);
148 }
149 
150 static void
151 bcm_gpio_func_str(uint32_t nfunc, char *buf, int bufsize)
152 {
153 
154 	switch (nfunc) {
155 	case BCM_GPIO_INPUT:
156 		strncpy(buf, "input", bufsize);
157 		break;
158 	case BCM_GPIO_OUTPUT:
159 		strncpy(buf, "output", bufsize);
160 		break;
161 	case BCM_GPIO_ALT0:
162 		strncpy(buf, "alt0", bufsize);
163 		break;
164 	case BCM_GPIO_ALT1:
165 		strncpy(buf, "alt1", bufsize);
166 		break;
167 	case BCM_GPIO_ALT2:
168 		strncpy(buf, "alt2", bufsize);
169 		break;
170 	case BCM_GPIO_ALT3:
171 		strncpy(buf, "alt3", bufsize);
172 		break;
173 	case BCM_GPIO_ALT4:
174 		strncpy(buf, "alt4", bufsize);
175 		break;
176 	case BCM_GPIO_ALT5:
177 		strncpy(buf, "alt5", bufsize);
178 		break;
179 	default:
180 		strncpy(buf, "invalid", bufsize);
181 	}
182 }
183 
184 static int
185 bcm_gpio_str_func(char *func, uint32_t *nfunc)
186 {
187 
188 	if (strcasecmp(func, "input") == 0)
189 		*nfunc = BCM_GPIO_INPUT;
190 	else if (strcasecmp(func, "output") == 0)
191 		*nfunc = BCM_GPIO_OUTPUT;
192 	else if (strcasecmp(func, "alt0") == 0)
193 		*nfunc = BCM_GPIO_ALT0;
194 	else if (strcasecmp(func, "alt1") == 0)
195 		*nfunc = BCM_GPIO_ALT1;
196 	else if (strcasecmp(func, "alt2") == 0)
197 		*nfunc = BCM_GPIO_ALT2;
198 	else if (strcasecmp(func, "alt3") == 0)
199 		*nfunc = BCM_GPIO_ALT3;
200 	else if (strcasecmp(func, "alt4") == 0)
201 		*nfunc = BCM_GPIO_ALT4;
202 	else if (strcasecmp(func, "alt5") == 0)
203 		*nfunc = BCM_GPIO_ALT5;
204 	else
205 		return (-1);
206 
207 	return (0);
208 }
209 
210 static uint32_t
211 bcm_gpio_func_flag(uint32_t nfunc)
212 {
213 
214 	switch (nfunc) {
215 	case BCM_GPIO_INPUT:
216 		return (GPIO_PIN_INPUT);
217 	case BCM_GPIO_OUTPUT:
218 		return (GPIO_PIN_OUTPUT);
219 	}
220 	return (0);
221 }
222 
223 static void
224 bcm_gpio_set_function(struct bcm_gpio_softc *sc, uint32_t pin, uint32_t f)
225 {
226 	uint32_t bank, data, offset;
227 
228 	/* Must be called with lock held. */
229 	BCM_GPIO_LOCK_ASSERT(sc);
230 
231 	/* Five banks, 10 pins per bank, 3 bits per pin. */
232 	bank = pin / 10;
233 	offset = (pin - bank * 10) * 3;
234 
235 	data = BCM_GPIO_READ(sc, BCM_GPIO_GPFSEL(bank));
236 	data &= ~(7 << offset);
237 	data |= (f << offset);
238 	BCM_GPIO_WRITE(sc, BCM_GPIO_GPFSEL(bank), data);
239 }
240 
241 static void
242 bcm_gpio_set_pud(struct bcm_gpio_softc *sc, uint32_t pin, uint32_t state)
243 {
244 	uint32_t bank, offset;
245 
246 	/* Must be called with lock held. */
247 	BCM_GPIO_LOCK_ASSERT(sc);
248 
249 	bank = pin / 32;
250 	offset = pin - 32 * bank;
251 
252 	BCM_GPIO_WRITE(sc, BCM_GPIO_GPPUD(0), state);
253 	DELAY(10);
254 	BCM_GPIO_WRITE(sc, BCM_GPIO_GPPUDCLK(bank), (1 << offset));
255 	DELAY(10);
256 	BCM_GPIO_WRITE(sc, BCM_GPIO_GPPUD(0), 0);
257 	BCM_GPIO_WRITE(sc, BCM_GPIO_GPPUDCLK(bank), 0);
258 }
259 
260 static void
261 bcm_gpio_pin_configure(struct bcm_gpio_softc *sc, struct gpio_pin *pin,
262     unsigned int flags)
263 {
264 
265 	BCM_GPIO_LOCK(sc);
266 
267 	/*
268 	 * Manage input/output.
269 	 */
270 	if (flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) {
271 		pin->gp_flags &= ~(GPIO_PIN_INPUT|GPIO_PIN_OUTPUT);
272 		if (flags & GPIO_PIN_OUTPUT) {
273 			pin->gp_flags |= GPIO_PIN_OUTPUT;
274 			bcm_gpio_set_function(sc, pin->gp_pin,
275 			    BCM_GPIO_OUTPUT);
276 		} else {
277 			pin->gp_flags |= GPIO_PIN_INPUT;
278 			bcm_gpio_set_function(sc, pin->gp_pin,
279 			    BCM_GPIO_INPUT);
280 		}
281 	}
282 
283 	/* Manage Pull-up/pull-down. */
284 	pin->gp_flags &= ~(GPIO_PIN_PULLUP|GPIO_PIN_PULLDOWN);
285 	if (flags & (GPIO_PIN_PULLUP|GPIO_PIN_PULLDOWN)) {
286 		if (flags & GPIO_PIN_PULLUP) {
287 			pin->gp_flags |= GPIO_PIN_PULLUP;
288 			bcm_gpio_set_pud(sc, pin->gp_pin, BCM_GPIO_PULLUP);
289 		} else {
290 			pin->gp_flags |= GPIO_PIN_PULLDOWN;
291 			bcm_gpio_set_pud(sc, pin->gp_pin, BCM_GPIO_PULLDOWN);
292 		}
293 	} else
294 		bcm_gpio_set_pud(sc, pin->gp_pin, BCM_GPIO_NONE);
295 
296 	BCM_GPIO_UNLOCK(sc);
297 }
298 
299 static int
300 bcm_gpio_pin_max(device_t dev, int *maxpin)
301 {
302 
303 	*maxpin = BCM_GPIO_PINS - 1;
304 	return (0);
305 }
306 
307 static int
308 bcm_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
309 {
310 	struct bcm_gpio_softc *sc = device_get_softc(dev);
311 	int i;
312 
313 	for (i = 0; i < sc->sc_gpio_npins; i++) {
314 		if (sc->sc_gpio_pins[i].gp_pin == pin)
315 			break;
316 	}
317 
318 	if (i >= sc->sc_gpio_npins)
319 		return (EINVAL);
320 
321 	BCM_GPIO_LOCK(sc);
322 	*caps = sc->sc_gpio_pins[i].gp_caps;
323 	BCM_GPIO_UNLOCK(sc);
324 
325 	return (0);
326 }
327 
328 static int
329 bcm_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
330 {
331 	struct bcm_gpio_softc *sc = device_get_softc(dev);
332 	int i;
333 
334 	for (i = 0; i < sc->sc_gpio_npins; i++) {
335 		if (sc->sc_gpio_pins[i].gp_pin == pin)
336 			break;
337 	}
338 
339 	if (i >= sc->sc_gpio_npins)
340 		return (EINVAL);
341 
342 	BCM_GPIO_LOCK(sc);
343 	*flags = sc->sc_gpio_pins[i].gp_flags;
344 	BCM_GPIO_UNLOCK(sc);
345 
346 	return (0);
347 }
348 
349 static int
350 bcm_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
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 	memcpy(name, sc->sc_gpio_pins[i].gp_name, GPIOMAXNAME);
365 	BCM_GPIO_UNLOCK(sc);
366 
367 	return (0);
368 }
369 
370 static int
371 bcm_gpio_pin_setflags(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 	/* We never touch on read-only/reserved pins. */
385 	if (bcm_gpio_pin_is_ro(sc, pin))
386 		return (EINVAL);
387 
388 	/* Filter out unwanted flags. */
389 	if ((flags &= sc->sc_gpio_pins[i].gp_caps) != flags)
390 		return (EINVAL);
391 
392 	/* Can't mix input/output together. */
393 	if ((flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) ==
394 	    (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT))
395 		return (EINVAL);
396 
397 	/* Can't mix pull-up/pull-down together. */
398 	if ((flags & (GPIO_PIN_PULLUP|GPIO_PIN_PULLDOWN)) ==
399 	    (GPIO_PIN_PULLUP|GPIO_PIN_PULLDOWN))
400 		return (EINVAL);
401 
402 	bcm_gpio_pin_configure(sc, &sc->sc_gpio_pins[i], flags);
403 
404 	return (0);
405 }
406 
407 static int
408 bcm_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value)
409 {
410 	struct bcm_gpio_softc *sc = device_get_softc(dev);
411 	uint32_t bank, offset;
412 	int i;
413 
414 	for (i = 0; i < sc->sc_gpio_npins; i++) {
415 		if (sc->sc_gpio_pins[i].gp_pin == pin)
416 			break;
417 	}
418 
419 	if (i >= sc->sc_gpio_npins)
420 		return (EINVAL);
421 
422 	/* We never write to read-only/reserved pins. */
423 	if (bcm_gpio_pin_is_ro(sc, pin))
424 		return (EINVAL);
425 
426 	bank = pin / 32;
427 	offset = pin - 32 * bank;
428 
429 	BCM_GPIO_LOCK(sc);
430 	if (value)
431 		BCM_GPIO_WRITE(sc, BCM_GPIO_GPSET(bank), (1 << offset));
432 	else
433 		BCM_GPIO_WRITE(sc, BCM_GPIO_GPCLR(bank), (1 << offset));
434 	BCM_GPIO_UNLOCK(sc);
435 
436 	return (0);
437 }
438 
439 static int
440 bcm_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val)
441 {
442 	struct bcm_gpio_softc *sc = device_get_softc(dev);
443 	uint32_t bank, offset, reg_data;
444 	int i;
445 
446 	for (i = 0; i < sc->sc_gpio_npins; i++) {
447 		if (sc->sc_gpio_pins[i].gp_pin == pin)
448 			break;
449 	}
450 
451 	if (i >= sc->sc_gpio_npins)
452 		return (EINVAL);
453 
454 	bank = pin / 32;
455 	offset = pin - 32 * bank;
456 
457 	BCM_GPIO_LOCK(sc);
458 	reg_data = BCM_GPIO_READ(sc, BCM_GPIO_GPLEV(bank));
459 	BCM_GPIO_UNLOCK(sc);
460 	*val = (reg_data & (1 << offset)) ? 1 : 0;
461 
462 	return (0);
463 }
464 
465 static int
466 bcm_gpio_pin_toggle(device_t dev, uint32_t pin)
467 {
468 	struct bcm_gpio_softc *sc = device_get_softc(dev);
469 	uint32_t bank, data, offset;
470 	int i;
471 
472 	for (i = 0; i < sc->sc_gpio_npins; i++) {
473 		if (sc->sc_gpio_pins[i].gp_pin == pin)
474 			break;
475 	}
476 
477 	if (i >= sc->sc_gpio_npins)
478 		return (EINVAL);
479 
480 	/* We never write to read-only/reserved pins. */
481 	if (bcm_gpio_pin_is_ro(sc, pin))
482 		return (EINVAL);
483 
484 	bank = pin / 32;
485 	offset = pin - 32 * bank;
486 
487 	BCM_GPIO_LOCK(sc);
488 	data = BCM_GPIO_READ(sc, BCM_GPIO_GPLEV(bank));
489 	if (data & (1 << offset))
490 		BCM_GPIO_WRITE(sc, BCM_GPIO_GPCLR(bank), (1 << offset));
491 	else
492 		BCM_GPIO_WRITE(sc, BCM_GPIO_GPSET(bank), (1 << offset));
493 	BCM_GPIO_UNLOCK(sc);
494 
495 	return (0);
496 }
497 
498 static int
499 bcm_gpio_get_ro_pins(struct bcm_gpio_softc *sc)
500 {
501 	int i, len;
502 	pcell_t pins[BCM_GPIO_PINS];
503 	phandle_t gpio;
504 
505 	/* Find the gpio node to start. */
506 	gpio = ofw_bus_get_node(sc->sc_dev);
507 
508 	len = OF_getproplen(gpio, "broadcom,read-only");
509 	if (len < 0 || len > sizeof(pins))
510 		return (-1);
511 
512 	if (OF_getprop(gpio, "broadcom,read-only", &pins, len) < 0)
513 		return (-1);
514 
515 	sc->sc_ro_npins = len / sizeof(pcell_t);
516 
517 	device_printf(sc->sc_dev, "read-only pins: ");
518 	for (i = 0; i < sc->sc_ro_npins; i++) {
519 		sc->sc_ro_pins[i] = fdt32_to_cpu(pins[i]);
520 		if (i > 0)
521 			printf(",");
522 		printf("%d", sc->sc_ro_pins[i]);
523 	}
524 	if (i > 0)
525 		printf(".");
526 	printf("\n");
527 
528 	return (0);
529 }
530 
531 static int
532 bcm_gpio_func_proc(SYSCTL_HANDLER_ARGS)
533 {
534 	char buf[16];
535 	struct bcm_gpio_softc *sc;
536 	struct bcm_gpio_sysctl *sc_sysctl;
537 	uint32_t nfunc;
538 	int i, error;
539 
540 	sc_sysctl = arg1;
541 	sc = sc_sysctl->sc;
542 
543 	/* Get the current pin function. */
544 	nfunc = bcm_gpio_get_function(sc, sc_sysctl->pin);
545 	bcm_gpio_func_str(nfunc, buf, sizeof(buf));
546 
547 	error = sysctl_handle_string(oidp, buf, sizeof(buf), req);
548 	if (error != 0 || req->newptr == NULL)
549 		return (error);
550 
551 	/* Parse the user supplied string and check for a valid pin function. */
552 	if (bcm_gpio_str_func(buf, &nfunc) != 0)
553 		return (EINVAL);
554 
555 	BCM_GPIO_LOCK(sc);
556 
557 	/* Disable pull-up or pull-down on pin. */
558 	bcm_gpio_set_pud(sc, sc_sysctl->pin, BCM_GPIO_NONE);
559 
560 	/* And now set the pin function. */
561 	bcm_gpio_set_function(sc, sc_sysctl->pin, nfunc);
562 
563 	/* Update the pin flags. */
564 	for (i = 0; i < sc->sc_gpio_npins; i++) {
565 		if (sc->sc_gpio_pins[i].gp_pin == sc_sysctl->pin)
566 			break;
567 	}
568 	if (i < sc->sc_gpio_npins)
569 		sc->sc_gpio_pins[i].gp_flags = bcm_gpio_func_flag(nfunc);
570 
571 	BCM_GPIO_UNLOCK(sc);
572 
573 	return (0);
574 }
575 
576 static void
577 bcm_gpio_sysctl_init(struct bcm_gpio_softc *sc)
578 {
579 	char pinbuf[3];
580 	struct bcm_gpio_sysctl *sc_sysctl;
581 	struct sysctl_ctx_list *ctx;
582 	struct sysctl_oid *tree_node, *pin_node, *pinN_node;
583 	struct sysctl_oid_list *tree, *pin_tree, *pinN_tree;
584 	int i;
585 
586 	/*
587 	 * Add per-pin sysctl tree/handlers.
588 	 */
589 	ctx = device_get_sysctl_ctx(sc->sc_dev);
590  	tree_node = device_get_sysctl_tree(sc->sc_dev);
591  	tree = SYSCTL_CHILDREN(tree_node);
592 	pin_node = SYSCTL_ADD_NODE(ctx, tree, OID_AUTO, "pin",
593 	    CTLFLAG_RW, NULL, "GPIO Pins");
594 	pin_tree = SYSCTL_CHILDREN(pin_node);
595 
596 	for (i = 0; i < sc->sc_gpio_npins; i++) {
597 
598 		snprintf(pinbuf, sizeof(pinbuf), "%d", i);
599 		pinN_node = SYSCTL_ADD_NODE(ctx, pin_tree, OID_AUTO, pinbuf,
600 		    CTLFLAG_RD, NULL, "GPIO Pin");
601 		pinN_tree = SYSCTL_CHILDREN(pinN_node);
602 
603 		sc->sc_sysctl[i].sc = sc;
604 		sc_sysctl = &sc->sc_sysctl[i];
605 		sc_sysctl->sc = sc;
606 		sc_sysctl->pin = sc->sc_gpio_pins[i].gp_pin;
607 		SYSCTL_ADD_PROC(ctx, pinN_tree, OID_AUTO, "function",
608 		    CTLFLAG_RW | CTLTYPE_STRING, sc_sysctl,
609 		    sizeof(struct bcm_gpio_sysctl), bcm_gpio_func_proc,
610 		    "A", "Pin Function");
611 	}
612 }
613 
614 static int
615 bcm_gpio_get_reserved_pins(struct bcm_gpio_softc *sc)
616 {
617 	int i, j, len, npins;
618 	pcell_t pins[BCM_GPIO_PINS];
619 	phandle_t gpio, node, reserved;
620 	char name[32];
621 
622 	/* Get read-only pins. */
623 	if (bcm_gpio_get_ro_pins(sc) != 0)
624 		return (-1);
625 
626 	/* Find the gpio/reserved pins node to start. */
627 	gpio = ofw_bus_get_node(sc->sc_dev);
628 	node = OF_child(gpio);
629 
630 	/*
631 	 * Find reserved node
632 	 */
633 	reserved = 0;
634 	while ((node != 0) && (reserved == 0)) {
635 		len = OF_getprop(node, "name", name,
636 		    sizeof(name) - 1);
637 		name[len] = 0;
638 		if (strcmp(name, "reserved") == 0)
639 			reserved = node;
640 		node = OF_peer(node);
641 	}
642 
643 	if (reserved == 0)
644 		return (-1);
645 
646 	/* Get the reserved pins. */
647 	len = OF_getproplen(reserved, "broadcom,pins");
648 	if (len < 0 || len > sizeof(pins))
649 		return (-1);
650 
651 	if (OF_getprop(reserved, "broadcom,pins", &pins, len) < 0)
652 		return (-1);
653 
654 	npins = len / sizeof(pcell_t);
655 
656 	j = 0;
657 	device_printf(sc->sc_dev, "reserved pins: ");
658 	for (i = 0; i < npins; i++) {
659 		if (i > 0)
660 			printf(",");
661 		printf("%d", fdt32_to_cpu(pins[i]));
662 		/* Some pins maybe already on the list of read-only pins. */
663 		if (bcm_gpio_pin_is_ro(sc, fdt32_to_cpu(pins[i])))
664 			continue;
665 		sc->sc_ro_pins[j++ + sc->sc_ro_npins] = fdt32_to_cpu(pins[i]);
666 	}
667 	sc->sc_ro_npins += j;
668 	if (i > 0)
669 		printf(".");
670 	printf("\n");
671 
672 	return (0);
673 }
674 
675 static int
676 bcm_gpio_probe(device_t dev)
677 {
678 	if (!ofw_bus_is_compatible(dev, "broadcom,bcm2835-gpio"))
679 		return (ENXIO);
680 
681 	device_set_desc(dev, "BCM2708/2835 GPIO controller");
682 	return (BUS_PROBE_DEFAULT);
683 }
684 
685 static int
686 bcm_gpio_attach(device_t dev)
687 {
688 	struct bcm_gpio_softc *sc = device_get_softc(dev);
689 	uint32_t func;
690 	int i, j, rid;
691 	phandle_t gpio;
692 
693 	sc->sc_dev = dev;
694 
695 	mtx_init(&sc->sc_mtx, "bcm gpio", "gpio", MTX_DEF);
696 
697 	rid = 0;
698 	sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
699 	    RF_ACTIVE);
700 	if (!sc->sc_mem_res) {
701 		device_printf(dev, "cannot allocate memory window\n");
702 		return (ENXIO);
703 	}
704 
705 	sc->sc_bst = rman_get_bustag(sc->sc_mem_res);
706 	sc->sc_bsh = rman_get_bushandle(sc->sc_mem_res);
707 
708 	rid = 0;
709 	sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
710 	    RF_ACTIVE);
711 	if (!sc->sc_irq_res) {
712 		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
713 		device_printf(dev, "cannot allocate interrupt\n");
714 		return (ENXIO);
715 	}
716 
717 	/* Find our node. */
718 	gpio = ofw_bus_get_node(sc->sc_dev);
719 
720 	if (!OF_hasprop(gpio, "gpio-controller"))
721 		/* Node is not a GPIO controller. */
722 		goto fail;
723 
724 	/*
725 	 * Find the read-only pins.  These are pins we never touch or bad
726 	 * things could happen.
727 	 */
728 	if (bcm_gpio_get_reserved_pins(sc) == -1)
729 		goto fail;
730 
731 	/* Initialize the software controlled pins. */
732 	for (i = 0, j = 0; j < BCM_GPIO_PINS - 1; j++) {
733 		if (bcm_gpio_pin_is_ro(sc, j))
734 			continue;
735 		snprintf(sc->sc_gpio_pins[i].gp_name, GPIOMAXNAME,
736 		    "pin %d", j);
737 		func = bcm_gpio_get_function(sc, j);
738 		sc->sc_gpio_pins[i].gp_pin = j;
739 		sc->sc_gpio_pins[i].gp_caps = BCM_GPIO_DEFAULT_CAPS;
740 		sc->sc_gpio_pins[i].gp_flags = bcm_gpio_func_flag(func);
741 		i++;
742 	}
743 	sc->sc_gpio_npins = i;
744 
745 	bcm_gpio_sysctl_init(sc);
746 
747 	device_add_child(dev, "gpioc", device_get_unit(dev));
748 	device_add_child(dev, "gpiobus", device_get_unit(dev));
749 	return (bus_generic_attach(dev));
750 
751 fail:
752 	if (sc->sc_irq_res)
753 		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res);
754 	if (sc->sc_mem_res)
755 		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res);
756 	return (ENXIO);
757 }
758 
759 static int
760 bcm_gpio_detach(device_t dev)
761 {
762 
763 	return (EBUSY);
764 }
765 
766 static device_method_t bcm_gpio_methods[] = {
767 	/* Device interface */
768 	DEVMETHOD(device_probe,		bcm_gpio_probe),
769 	DEVMETHOD(device_attach,	bcm_gpio_attach),
770 	DEVMETHOD(device_detach,	bcm_gpio_detach),
771 
772 	/* GPIO protocol */
773 	DEVMETHOD(gpio_pin_max,		bcm_gpio_pin_max),
774 	DEVMETHOD(gpio_pin_getname,	bcm_gpio_pin_getname),
775 	DEVMETHOD(gpio_pin_getflags,	bcm_gpio_pin_getflags),
776 	DEVMETHOD(gpio_pin_getcaps,	bcm_gpio_pin_getcaps),
777 	DEVMETHOD(gpio_pin_setflags,	bcm_gpio_pin_setflags),
778 	DEVMETHOD(gpio_pin_get,		bcm_gpio_pin_get),
779 	DEVMETHOD(gpio_pin_set,		bcm_gpio_pin_set),
780 	DEVMETHOD(gpio_pin_toggle,	bcm_gpio_pin_toggle),
781 
782 	DEVMETHOD_END
783 };
784 
785 static devclass_t bcm_gpio_devclass;
786 
787 static driver_t bcm_gpio_driver = {
788 	"gpio",
789 	bcm_gpio_methods,
790 	sizeof(struct bcm_gpio_softc),
791 };
792 
793 DRIVER_MODULE(bcm_gpio, simplebus, bcm_gpio_driver, bcm_gpio_devclass, 0, 0);
794