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