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