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