1 /* $NetBSD: pxa2x0_gpio.c,v 1.16 2012/11/12 18:00:38 skrll Exp $ */ 2 3 /* 4 * Copyright 2003 Wasabi Systems, Inc. 5 * All rights reserved. 6 * 7 * Written by Steve C. Woodford for Wasabi Systems, Inc. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. All advertising materials mentioning features or use of this software 18 * must display the following acknowledgement: 19 * This product includes software developed for the NetBSD Project by 20 * Wasabi Systems, Inc. 21 * 4. The name of Wasabi Systems, Inc. may not be used to endorse 22 * or promote products derived from this software without specific prior 23 * written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 27 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 28 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 29 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 * POSSIBILITY OF SUCH DAMAGE. 36 */ 37 38 #include <sys/cdefs.h> 39 __KERNEL_RCSID(0, "$NetBSD: pxa2x0_gpio.c,v 1.16 2012/11/12 18:00:38 skrll Exp $"); 40 41 #include "opt_pxa2x0_gpio.h" 42 43 #include <sys/param.h> 44 #include <sys/systm.h> 45 #include <sys/device.h> 46 #include <sys/malloc.h> 47 48 #include <machine/intr.h> 49 #include <sys/bus.h> 50 51 #include <arm/xscale/pxa2x0cpu.h> 52 #include <arm/xscale/pxa2x0reg.h> 53 #include <arm/xscale/pxa2x0var.h> 54 #include <arm/xscale/pxa2x0_gpio.h> 55 56 #include "locators.h" 57 58 struct gpio_irq_handler { 59 struct gpio_irq_handler *gh_next; 60 int (*gh_func)(void *); 61 void *gh_arg; 62 int gh_spl; 63 u_int gh_gpio; 64 int gh_level; 65 }; 66 67 struct pxagpio_softc { 68 device_t sc_dev; 69 bus_space_tag_t sc_bust; 70 bus_space_handle_t sc_bush; 71 void *sc_irqcookie[4]; 72 uint32_t sc_mask[4]; 73 #ifdef PXAGPIO_HAS_GPION_INTRS 74 struct gpio_irq_handler *sc_handlers[GPIO_NPINS]; 75 #else 76 struct gpio_irq_handler *sc_handlers[2]; 77 #endif 78 }; 79 80 static int pxagpio_match(device_t, cfdata_t, void *); 81 static void pxagpio_attach(device_t, device_t, void *); 82 83 CFATTACH_DECL_NEW(pxagpio, sizeof(struct pxagpio_softc), 84 pxagpio_match, pxagpio_attach, NULL, NULL); 85 86 static struct pxagpio_softc *pxagpio_softc; 87 static vaddr_t pxagpio_regs; 88 #define GPIO_BOOTSTRAP_REG(reg) \ 89 (*((volatile uint32_t *)(pxagpio_regs + (reg)))) 90 91 static int gpio_intr0(void *); 92 static int gpio_intr1(void *); 93 #ifdef PXAGPIO_HAS_GPION_INTRS 94 static int gpio_dispatch(struct pxagpio_softc *, int); 95 static int gpio_intrN(void *); 96 #endif 97 98 static inline uint32_t 99 pxagpio_reg_read(struct pxagpio_softc *sc, int reg) 100 { 101 if (__predict_true(sc != NULL)) 102 return (bus_space_read_4(sc->sc_bust, sc->sc_bush, reg)); 103 else 104 if (pxagpio_regs) 105 return (GPIO_BOOTSTRAP_REG(reg)); 106 panic("pxagpio_reg_read: not bootstrapped"); 107 } 108 109 static inline void 110 pxagpio_reg_write(struct pxagpio_softc *sc, int reg, uint32_t val) 111 { 112 if (__predict_true(sc != NULL)) 113 bus_space_write_4(sc->sc_bust, sc->sc_bush, reg, val); 114 else 115 if (pxagpio_regs) 116 GPIO_BOOTSTRAP_REG(reg) = val; 117 else 118 panic("pxagpio_reg_write: not bootstrapped"); 119 return; 120 } 121 122 static int 123 pxagpio_match(device_t parent, cfdata_t cf, void *aux) 124 { 125 struct pxaip_attach_args *pxa = aux; 126 127 if (pxagpio_softc != NULL || pxa->pxa_addr != PXA2X0_GPIO_BASE) 128 return (0); 129 130 pxa->pxa_size = PXA2X0_GPIO_SIZE; 131 132 return (1); 133 } 134 135 static void 136 pxagpio_attach(device_t parent, device_t self, void *aux) 137 { 138 struct pxagpio_softc *sc = device_private(self); 139 struct pxaip_attach_args *pxa = aux; 140 141 sc->sc_dev = self; 142 sc->sc_bust = pxa->pxa_iot; 143 144 aprint_normal(": GPIO Controller\n"); 145 146 if (bus_space_map(sc->sc_bust, pxa->pxa_addr, pxa->pxa_size, 0, 147 &sc->sc_bush)) { 148 aprint_error_dev(self, "Can't map registers!\n"); 149 return; 150 } 151 152 pxagpio_regs = (vaddr_t)bus_space_vaddr(sc->sc_bust, sc->sc_bush); 153 154 memset(sc->sc_handlers, 0, sizeof(sc->sc_handlers)); 155 156 /* 157 * Disable all GPIO interrupts 158 */ 159 pxagpio_reg_write(sc, GPIO_GRER0, 0); 160 pxagpio_reg_write(sc, GPIO_GRER1, 0); 161 pxagpio_reg_write(sc, GPIO_GRER2, 0); 162 pxagpio_reg_write(sc, GPIO_GFER0, 0); 163 pxagpio_reg_write(sc, GPIO_GFER1, 0); 164 pxagpio_reg_write(sc, GPIO_GFER2, 0); 165 pxagpio_reg_write(sc, GPIO_GEDR0, ~0); 166 pxagpio_reg_write(sc, GPIO_GEDR1, ~0); 167 pxagpio_reg_write(sc, GPIO_GEDR2, ~0); 168 #ifdef CPU_XSCALE_PXA270 169 if (CPU_IS_PXA270) { 170 pxagpio_reg_write(sc, GPIO_GRER3, 0); 171 pxagpio_reg_write(sc, GPIO_GFER3, 0); 172 pxagpio_reg_write(sc, GPIO_GEDR3, ~0); 173 } 174 #endif 175 176 #ifdef PXAGPIO_HAS_GPION_INTRS 177 sc->sc_irqcookie[2] = pxa2x0_intr_establish(PXA2X0_INT_GPION, IPL_BIO, 178 gpio_intrN, sc); 179 if (sc->sc_irqcookie[2] == NULL) { 180 aprint_error_dev(self, "failed to hook main GPIO interrupt\n"); 181 return; 182 } 183 #endif 184 185 sc->sc_irqcookie[0] = sc->sc_irqcookie[1] = NULL; 186 187 pxagpio_softc = sc; 188 } 189 190 void 191 pxa2x0_gpio_bootstrap(vaddr_t gpio_regs) 192 { 193 194 pxagpio_regs = gpio_regs; 195 } 196 197 void * 198 pxa2x0_gpio_intr_establish(u_int gpio, int level, int spl, int (*func)(void *), 199 void *arg) 200 { 201 struct pxagpio_softc *sc = pxagpio_softc; 202 struct gpio_irq_handler *gh; 203 uint32_t bit, reg; 204 205 #ifdef PXAGPIO_HAS_GPION_INTRS 206 if (gpio >= GPIO_NPINS) 207 panic("pxa2x0_gpio_intr_establish: bad pin number: %d", gpio); 208 #else 209 if (gpio > 1) 210 panic("pxa2x0_gpio_intr_establish: bad pin number: %d", gpio); 211 #endif 212 213 if (!GPIO_IS_GPIO_IN(pxa2x0_gpio_get_function(gpio))) 214 panic("pxa2x0_gpio_intr_establish: Pin %d not GPIO_IN", gpio); 215 216 switch (level) { 217 case IST_EDGE_FALLING: 218 case IST_EDGE_RISING: 219 case IST_EDGE_BOTH: 220 break; 221 222 default: 223 panic("pxa2x0_gpio_intr_establish: bad level: %d", level); 224 break; 225 } 226 227 if (sc->sc_handlers[gpio] != NULL) 228 panic("pxa2x0_gpio_intr_establish: illegal shared interrupt"); 229 230 gh = malloc(sizeof(struct gpio_irq_handler), M_DEVBUF, M_NOWAIT); 231 232 gh->gh_func = func; 233 gh->gh_arg = arg; 234 gh->gh_spl = spl; 235 gh->gh_gpio = gpio; 236 gh->gh_level = level; 237 gh->gh_next = sc->sc_handlers[gpio]; 238 sc->sc_handlers[gpio] = gh; 239 240 if (gpio == 0) { 241 KDASSERT(sc->sc_irqcookie[0] == NULL); 242 sc->sc_irqcookie[0] = pxa2x0_intr_establish(PXA2X0_INT_GPIO0, 243 spl, gpio_intr0, sc); 244 KDASSERT(sc->sc_irqcookie[0]); 245 } else 246 if (gpio == 1) { 247 KDASSERT(sc->sc_irqcookie[1] == NULL); 248 sc->sc_irqcookie[1] = pxa2x0_intr_establish(PXA2X0_INT_GPIO1, 249 spl, gpio_intr1, sc); 250 KDASSERT(sc->sc_irqcookie[1]); 251 } 252 253 bit = GPIO_BIT(gpio); 254 sc->sc_mask[GPIO_BANK(gpio)] |= bit; 255 256 switch (level) { 257 case IST_EDGE_FALLING: 258 reg = pxagpio_reg_read(sc, GPIO_REG(GPIO_GFER0, gpio)); 259 pxagpio_reg_write(sc, GPIO_REG(GPIO_GFER0, gpio), reg | bit); 260 break; 261 262 case IST_EDGE_RISING: 263 reg = pxagpio_reg_read(sc, GPIO_REG(GPIO_GRER0, gpio)); 264 pxagpio_reg_write(sc, GPIO_REG(GPIO_GRER0, gpio), reg | bit); 265 break; 266 267 case IST_EDGE_BOTH: 268 reg = pxagpio_reg_read(sc, GPIO_REG(GPIO_GFER0, gpio)); 269 pxagpio_reg_write(sc, GPIO_REG(GPIO_GFER0, gpio), reg | bit); 270 reg = pxagpio_reg_read(sc, GPIO_REG(GPIO_GRER0, gpio)); 271 pxagpio_reg_write(sc, GPIO_REG(GPIO_GRER0, gpio), reg | bit); 272 break; 273 } 274 275 return (gh); 276 } 277 278 void 279 pxa2x0_gpio_intr_disestablish(void *cookie) 280 { 281 struct pxagpio_softc *sc = pxagpio_softc; 282 struct gpio_irq_handler *gh = cookie; 283 uint32_t bit, reg; 284 285 bit = GPIO_BIT(gh->gh_gpio); 286 287 reg = pxagpio_reg_read(sc, GPIO_REG(GPIO_GFER0, gh->gh_gpio)); 288 reg &= ~bit; 289 pxagpio_reg_write(sc, GPIO_REG(GPIO_GFER0, gh->gh_gpio), reg); 290 reg = pxagpio_reg_read(sc, GPIO_REG(GPIO_GRER0, gh->gh_gpio)); 291 reg &= ~bit; 292 pxagpio_reg_write(sc, GPIO_REG(GPIO_GRER0, gh->gh_gpio), reg); 293 294 pxagpio_reg_write(sc, GPIO_REG(GPIO_GEDR0, gh->gh_gpio), bit); 295 296 sc->sc_mask[GPIO_BANK(gh->gh_gpio)] &= ~bit; 297 sc->sc_handlers[gh->gh_gpio] = NULL; 298 299 if (gh->gh_gpio == 0) { 300 #if 0 301 pxa2x0_intr_disestablish(sc->sc_irqcookie[0]); 302 sc->sc_irqcookie[0] = NULL; 303 #else 304 panic("pxa2x0_gpio_intr_disestablish: can't unhook GPIO#0"); 305 #endif 306 } else 307 if (gh->gh_gpio == 1) { 308 #if 0 309 pxa2x0_intr_disestablish(sc->sc_irqcookie[1]); 310 sc->sc_irqcookie[1] = NULL; 311 #else 312 panic("pxa2x0_gpio_intr_disestablish: can't unhook GPIO#1"); 313 #endif 314 } 315 316 free(gh, M_DEVBUF); 317 } 318 319 static int 320 gpio_intr0(void *arg) 321 { 322 struct pxagpio_softc *sc = arg; 323 324 #ifdef DIAGNOSTIC 325 if (sc->sc_handlers[0] == NULL) { 326 aprint_error_dev(sc->sc_dev, "stray GPIO#0 edge interrupt\n"); 327 return (0); 328 } 329 #endif 330 331 bus_space_write_4(sc->sc_bust, sc->sc_bush, GPIO_REG(GPIO_GEDR0, 0), 332 GPIO_BIT(0)); 333 334 return ((sc->sc_handlers[0]->gh_func)(sc->sc_handlers[0]->gh_arg)); 335 } 336 337 static int 338 gpio_intr1(void *arg) 339 { 340 struct pxagpio_softc *sc = arg; 341 342 #ifdef DIAGNOSTIC 343 if (sc->sc_handlers[1] == NULL) { 344 aprint_error_dev(sc->sc_dev, "stray GPIO#1 edge interrupt\n"); 345 return (0); 346 } 347 #endif 348 349 bus_space_write_4(sc->sc_bust, sc->sc_bush, GPIO_REG(GPIO_GEDR0, 1), 350 GPIO_BIT(1)); 351 352 return ((sc->sc_handlers[1]->gh_func)(sc->sc_handlers[1]->gh_arg)); 353 } 354 355 #ifdef PXAGPIO_HAS_GPION_INTRS 356 static int 357 gpio_dispatch(struct pxagpio_softc *sc, int gpio_base) 358 { 359 struct gpio_irq_handler **ghp, *gh; 360 int i, s, nhandled, handled, pins; 361 uint32_t gedr, mask; 362 int bank; 363 364 /* Fetch bitmap of pending interrupts on this GPIO bank */ 365 gedr = pxagpio_reg_read(sc, GPIO_REG(GPIO_GEDR0, gpio_base)); 366 367 /* Don't handle GPIO 0/1 here */ 368 if (gpio_base == 0) 369 gedr &= ~(GPIO_BIT(0) | GPIO_BIT(1)); 370 371 /* Bail early if there are no pending interrupts in this bank */ 372 if (gedr == 0) 373 return (0); 374 375 /* Acknowledge pending interrupts. */ 376 pxagpio_reg_write(sc, GPIO_REG(GPIO_GEDR0, gpio_base), gedr); 377 378 bank = GPIO_BANK(gpio_base); 379 380 /* 381 * We're only interested in those for which we have a handler 382 * registered 383 */ 384 #ifdef DEBUG 385 if ((gedr & sc->sc_mask[bank]) == 0) { 386 aprint_error_dev(sc->sc_dev, 387 "stray GPIO interrupt. Bank %d, GEDR 0x%08x, mask 0x%08x\n", 388 bank, gedr, sc->sc_mask[bank]); 389 return (1); /* XXX: Pretend we dealt with it */ 390 } 391 #endif 392 393 gedr &= sc->sc_mask[bank]; 394 ghp = &sc->sc_handlers[gpio_base]; 395 if (CPU_IS_PXA270) 396 pins = (gpio_base < 96) ? 32 : 25; 397 else 398 pins = (gpio_base < 64) ? 32 : 17; 399 handled = 0; 400 401 for (i = 0, mask = 1; i < pins && gedr; i++, ghp++, mask <<= 1) { 402 if ((gedr & mask) == 0) 403 continue; 404 gedr &= ~mask; 405 406 if ((gh = *ghp) == NULL) { 407 aprint_error_dev(sc->sc_dev, 408 "unhandled GPIO interrupt. GPIO#%d\n", 409 gpio_base + i); 410 continue; 411 } 412 413 s = _splraise(gh->gh_spl); 414 do { 415 nhandled = (gh->gh_func)(gh->gh_arg); 416 handled |= nhandled; 417 gh = gh->gh_next; 418 } while (gh != NULL); 419 splx(s); 420 } 421 422 return (handled); 423 } 424 425 static int 426 gpio_intrN(void *arg) 427 { 428 struct pxagpio_softc *sc = arg; 429 int handled; 430 431 handled = gpio_dispatch(sc, 0); 432 handled |= gpio_dispatch(sc, 32); 433 handled |= gpio_dispatch(sc, 64); 434 if (CPU_IS_PXA270) 435 handled |= gpio_dispatch(sc, 96); 436 return (handled); 437 } 438 #endif /* PXAGPIO_HAS_GPION_INTRS */ 439 440 u_int 441 pxa2x0_gpio_get_function(u_int gpio) 442 { 443 struct pxagpio_softc *sc = pxagpio_softc; 444 uint32_t rv, io; 445 446 KDASSERT(gpio < GPIO_NPINS); 447 448 rv = pxagpio_reg_read(sc, GPIO_FN_REG(gpio)) >> GPIO_FN_SHIFT(gpio); 449 rv = GPIO_FN(rv); 450 451 io = pxagpio_reg_read(sc, GPIO_REG(GPIO_GPDR0, gpio)); 452 if (io & GPIO_BIT(gpio)) 453 rv |= GPIO_OUT; 454 455 io = pxagpio_reg_read(sc, GPIO_REG(GPIO_GPLR0, gpio)); 456 if (io & GPIO_BIT(gpio)) 457 rv |= GPIO_SET; 458 459 return (rv); 460 } 461 462 u_int 463 pxa2x0_gpio_set_function(u_int gpio, u_int fn) 464 { 465 struct pxagpio_softc *sc = pxagpio_softc; 466 uint32_t rv, bit; 467 u_int oldfn; 468 469 KDASSERT(gpio < GPIO_NPINS); 470 471 oldfn = pxa2x0_gpio_get_function(gpio); 472 473 if (GPIO_FN(fn) == GPIO_FN(oldfn) && 474 GPIO_FN_IS_OUT(fn) == GPIO_FN_IS_OUT(oldfn)) { 475 /* 476 * The pin's function is not changing. 477 * For Alternate Functions and GPIO input, we can just 478 * return now. 479 * For GPIO output pins, check the initial state is 480 * the same. 481 * 482 * Return 'fn' instead of 'oldfn' so the caller can 483 * reliably detect that we didn't change anything. 484 * (The initial state might be different for non- 485 * GPIO output pins). 486 */ 487 if (!GPIO_IS_GPIO_OUT(fn) || 488 GPIO_FN_IS_SET(fn) == GPIO_FN_IS_SET(oldfn)) 489 return (fn); 490 } 491 492 /* 493 * See section 4.1.3.7 of the PXA2x0 Developer's Manual for 494 * the correct procedure for changing GPIO pin functions. 495 */ 496 497 bit = GPIO_BIT(gpio); 498 499 /* 500 * 1. Configure the correct set/clear state of the pin 501 */ 502 if (GPIO_FN_IS_SET(fn)) 503 pxagpio_reg_write(sc, GPIO_REG(GPIO_GPSR0, gpio), bit); 504 else 505 pxagpio_reg_write(sc, GPIO_REG(GPIO_GPCR0, gpio), bit); 506 507 /* 508 * 2. Configure the pin as an input or output as appropriate 509 */ 510 rv = pxagpio_reg_read(sc, GPIO_REG(GPIO_GPDR0, gpio)) & ~bit; 511 if (GPIO_FN_IS_OUT(fn)) 512 rv |= bit; 513 pxagpio_reg_write(sc, GPIO_REG(GPIO_GPDR0, gpio), rv); 514 515 /* 516 * 3. Configure the pin's function 517 */ 518 bit = GPIO_FN_MASK << GPIO_FN_SHIFT(gpio); 519 fn = GPIO_FN(fn) << GPIO_FN_SHIFT(gpio); 520 rv = pxagpio_reg_read(sc, GPIO_FN_REG(gpio)) & ~bit; 521 pxagpio_reg_write(sc, GPIO_FN_REG(gpio), rv | fn); 522 523 return (oldfn); 524 } 525 526 /* 527 * Quick function to read pin value 528 */ 529 int 530 pxa2x0_gpio_get_bit(u_int gpio) 531 { 532 struct pxagpio_softc *sc = pxagpio_softc; 533 int bit; 534 535 bit = GPIO_BIT(gpio); 536 if (pxagpio_reg_read(sc, GPIO_REG(GPIO_GPLR0, gpio)) & bit) 537 return 1; 538 else 539 return 0; 540 } 541 542 /* 543 * Quick function to set pin to 1 544 */ 545 void 546 pxa2x0_gpio_set_bit(u_int gpio) 547 { 548 struct pxagpio_softc *sc = pxagpio_softc; 549 int bit; 550 551 bit = GPIO_BIT(gpio); 552 pxagpio_reg_write(sc, GPIO_REG(GPIO_GPSR0, gpio), bit); 553 } 554 555 /* 556 * Quick function to set pin to 0 557 */ 558 void 559 pxa2x0_gpio_clear_bit(u_int gpio) 560 { 561 struct pxagpio_softc *sc = pxagpio_softc; 562 int bit; 563 564 bit = GPIO_BIT(gpio); 565 pxagpio_reg_write(sc, GPIO_REG(GPIO_GPCR0, gpio), bit); 566 } 567 568 /* 569 * Quick function to change pin direction 570 */ 571 void 572 pxa2x0_gpio_set_dir(u_int gpio, int dir) 573 { 574 struct pxagpio_softc *sc = pxagpio_softc; 575 int bit; 576 uint32_t reg; 577 578 bit = GPIO_BIT(gpio); 579 580 reg = pxagpio_reg_read(sc, GPIO_REG(GPIO_GPDR0, gpio)) & ~bit; 581 if (GPIO_FN_IS_OUT(dir)) 582 reg |= bit; 583 pxagpio_reg_write(sc, GPIO_REG(GPIO_GPDR0, gpio), reg); 584 } 585 586 /* 587 * Quick function to clear interrupt status on a pin 588 * GPIO pins may be toggle in an interrupt and we dont want 589 * extra spurious interrupts to occur. 590 * Suppose this causes a slight race if a key is pressed while 591 * the interrupt handler is running. (yes this is for the keyboard driver) 592 */ 593 void 594 pxa2x0_gpio_clear_intr(u_int gpio) 595 { 596 struct pxagpio_softc *sc = pxagpio_softc; 597 int bit; 598 599 bit = GPIO_BIT(gpio); 600 pxagpio_reg_write(sc, GPIO_REG(GPIO_GEDR0, gpio), bit); 601 } 602 603 /* 604 * Quick function to mask (disable) a GPIO interrupt 605 */ 606 void 607 pxa2x0_gpio_intr_mask(void *v) 608 { 609 struct gpio_irq_handler *gh = (struct gpio_irq_handler *)v; 610 611 pxa2x0_gpio_set_intr_level(gh->gh_gpio, IPL_NONE); 612 } 613 614 /* 615 * Quick function to unmask (enable) a GPIO interrupt 616 */ 617 void 618 pxa2x0_gpio_intr_unmask(void *v) 619 { 620 struct gpio_irq_handler *gh = (struct gpio_irq_handler *)v; 621 622 pxa2x0_gpio_set_intr_level(gh->gh_gpio, gh->gh_level); 623 } 624 625 /* 626 * Configure the edge sensitivity of interrupt pins 627 */ 628 void 629 pxa2x0_gpio_set_intr_level(u_int gpio, int level) 630 { 631 struct pxagpio_softc *sc = pxagpio_softc; 632 uint32_t bit; 633 uint32_t gfer; 634 uint32_t grer; 635 int s; 636 637 s = splhigh(); 638 639 bit = GPIO_BIT(gpio); 640 gfer = pxagpio_reg_read(sc, GPIO_REG(GPIO_GFER0, gpio)); 641 grer = pxagpio_reg_read(sc, GPIO_REG(GPIO_GRER0, gpio)); 642 643 switch (level) { 644 case IST_NONE: 645 gfer &= ~bit; 646 grer &= ~bit; 647 break; 648 case IST_EDGE_FALLING: 649 gfer |= bit; 650 grer &= ~bit; 651 break; 652 case IST_EDGE_RISING: 653 gfer &= ~bit; 654 grer |= bit; 655 break; 656 case IST_EDGE_BOTH: 657 gfer |= bit; 658 grer |= bit; 659 break; 660 default: 661 panic("pxa2x0_gpio_set_intr_level: bad level: %d", level); 662 break; 663 } 664 665 pxagpio_reg_write(sc, GPIO_REG(GPIO_GFER0, gpio), gfer); 666 pxagpio_reg_write(sc, GPIO_REG(GPIO_GRER0, gpio), grer); 667 668 splx(s); 669 } 670 671 672 #if defined(CPU_XSCALE_PXA250) 673 /* 674 * Configurations of GPIO for PXA25x 675 */ 676 struct pxa2x0_gpioconf pxa25x_com_btuart_gpioconf[] = { 677 { 42, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* BTRXD */ 678 { 43, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* BTTXD */ 679 680 #if 0 /* optional */ 681 { 44, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* BTCTS */ 682 { 45, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* BTRTS */ 683 #endif 684 685 { -1 } 686 }; 687 688 struct pxa2x0_gpioconf pxa25x_com_ffuart_gpioconf[] = { 689 { 34, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* FFRXD */ 690 691 #if 0 /* optional */ 692 { 35, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* CTS */ 693 { 36, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* DCD */ 694 { 37, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* DSR */ 695 { 38, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* RI */ 696 #endif 697 698 { 39, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* FFTXD */ 699 700 #if 0 /* optional */ 701 { 40, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* DTR */ 702 { 41, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* RTS */ 703 #endif 704 705 { -1 } 706 }; 707 708 struct pxa2x0_gpioconf pxa25x_com_hwuart_gpioconf[] = { 709 #if 0 /* We can select and/or. */ 710 { 42, GPIO_CLR | GPIO_ALT_FN_3_IN }, /* HWRXD */ 711 { 49, GPIO_CLR | GPIO_ALT_FN_2_IN }, /* HWRXD */ 712 713 { 43, GPIO_CLR | GPIO_ALT_FN_3_OUT }, /* HWTXD */ 714 { 48, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* HWTXD */ 715 716 #if 0 /* optional */ 717 { 44, GPIO_CLR | GPIO_ALT_FN_3_IN }, /* HWCST */ 718 { 51, GPIO_CLR | GPIO_ALT_FN_3_IN }, /* HWCST */ 719 720 { 45, GPIO_CLR | GPIO_ALT_FN_3_OUT }, /* HWRST */ 721 { 52, GPIO_CLR | GPIO_ALT_FN_3_OUT }, /* HWRST */ 722 #endif 723 #endif 724 725 { -1 } 726 }; 727 728 struct pxa2x0_gpioconf pxa25x_com_stuart_gpioconf[] = { 729 { 46, GPIO_CLR | GPIO_ALT_FN_2_IN }, /* RXD */ 730 { 47, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* TXD */ 731 { -1 } 732 }; 733 734 struct pxa2x0_gpioconf pxa25x_i2c_gpioconf[] = { 735 { -1 } 736 }; 737 738 struct pxa2x0_gpioconf pxa25x_i2s_gpioconf[] = { 739 { 28, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* BITCLK */ 740 { 29, GPIO_CLR | GPIO_ALT_FN_2_IN }, /* SDATA_IN */ 741 { 30, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* SDATA_OUT */ 742 { 31, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* SYNC */ 743 { 32, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* SYSCLK */ 744 { -1 } 745 }; 746 747 struct pxa2x0_gpioconf pxa25x_pcic_gpioconf[] = { 748 { 48, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* nPOE */ 749 { 49, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* nPWE */ 750 { 50, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* nPIOR */ 751 { 51, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* nPIOW */ 752 753 #if 0 /* We can select and/or. */ 754 { 52, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* nPCE1 */ 755 { 53, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* nPCE2 */ 756 #endif 757 758 { 54, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* pSKTSEL */ 759 { 55, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* nPREG */ 760 { 56, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* nPWAIT */ 761 { 57, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* nIOIS16 */ 762 { -1 } 763 }; 764 765 struct pxa2x0_gpioconf pxa25x_pxaacu_gpioconf[] = { 766 { 28, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* BITCLK */ 767 { 30, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* SDATA_OUT */ 768 { 31, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* SYNC */ 769 770 #if 0 /* We can select and/or. */ 771 { 29, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* SDATA_IN0 */ 772 { 32, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* SDATA_IN1 */ 773 #endif 774 775 { -1 } 776 }; 777 778 struct pxa2x0_gpioconf pxa25x_pxamci_gpioconf[] = { 779 #if 0 /* We can select and/or. */ 780 { 6, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* MMCCLK */ 781 { 53, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* MMCCLK */ 782 { 54, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* MMCCLK */ 783 784 { 8, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* MMCCS0 */ 785 { 34, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* MMCCS0 */ 786 { 67, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* MMCCS0 */ 787 788 { 9, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* MMCCS1 */ 789 { 39, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* MMCCS1 */ 790 { 68, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* MMCCS1 */ 791 #endif 792 793 { -1 } 794 }; 795 #endif 796 797 #if defined(CPU_XSCALE_PXA270) 798 /* 799 * Configurations of GPIO for PXA27x 800 */ 801 struct pxa2x0_gpioconf pxa27x_com_btuart_gpioconf[] = { 802 { 42, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* BTRXD */ 803 { 43, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* BTTXD */ 804 805 #if 0 /* optional */ 806 { 44, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* BTCTS */ 807 { 45, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* BTRTS */ 808 #endif 809 810 { -1 } 811 }; 812 813 struct pxa2x0_gpioconf pxa27x_com_ffuart_gpioconf[] = { 814 #if 0 /* We can select and/or. */ 815 { 16, GPIO_CLR | GPIO_ALT_FN_3_OUT }, /* FFTXD */ 816 { 37, GPIO_CLR | GPIO_ALT_FN_3_OUT }, /* FFTXD */ 817 { 39, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* FFTXD */ 818 { 83, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* FFTXD */ 819 { 99, GPIO_CLR | GPIO_ALT_FN_3_OUT }, /* FFTXD */ 820 821 { 19, GPIO_CLR | GPIO_ALT_FN_3_IN }, /* FFRXD */ 822 { 33, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* FFRXD */ 823 { 34, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* FFRXD */ 824 { 41, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* FFRXD */ 825 { 53, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* FFRXD */ 826 { 85, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* FFRXD */ 827 { 96, GPIO_CLR | GPIO_ALT_FN_3_IN }, /* FFRXD */ 828 { 102, GPIO_CLR | GPIO_ALT_FN_3_IN }, /* FFRXD */ 829 830 { 9, GPIO_CLR | GPIO_ALT_FN_3_IN }, /* FFCTS */ 831 { 26, GPIO_CLR | GPIO_ALT_FN_3_IN }, /* FFCTS */ 832 { 35, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* FFCTS */ 833 { 100, GPIO_CLR | GPIO_ALT_FN_3_IN }, /* FFCTS */ 834 835 { 27, GPIO_CLR | GPIO_ALT_FN_3_OUT }, /* FFRTS */ 836 { 41, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* FFRTS */ 837 { 83, GPIO_CLR | GPIO_ALT_FN_3_OUT }, /* FFRTS */ 838 { 98, GPIO_CLR | GPIO_ALT_FN_3_OUT }, /* FFRTS */ 839 840 { 40, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* FFDTR */ 841 { 82, GPIO_CLR | GPIO_ALT_FN_3_OUT }, /* FFDTR */ 842 843 { 36, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* FFDCD */ 844 845 { 33, GPIO_CLR | GPIO_ALT_FN_2_IN }, /* FFDSR */ 846 { 37, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* FFDSR */ 847 848 { 38, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* FFRI */ 849 #endif 850 { -1 } 851 }; 852 853 struct pxa2x0_gpioconf pxa27x_com_stuart_gpioconf[] = { 854 { 46, GPIO_CLR | GPIO_ALT_FN_2_IN }, /* STD_RXD */ 855 { 47, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* STD_TXD */ 856 { -1 } 857 }; 858 859 struct pxa2x0_gpioconf pxa27x_i2c_gpioconf[] = { 860 { 117, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* SCL */ 861 { 118, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* SDA */ 862 { -1 } 863 }; 864 865 struct pxa2x0_gpioconf pxa27x_i2s_gpioconf[] = { 866 { 28, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* I2S_BITCLK */ 867 { 29, GPIO_CLR | GPIO_ALT_FN_2_IN }, /* I2S_SDATA_IN */ 868 { 30, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* I2S_SDATA_OUT */ 869 { 31, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* I2S_SYNC */ 870 { 113, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* I2S_SYSCLK */ 871 { -1 } 872 }; 873 874 struct pxa2x0_gpioconf pxa27x_ohci_gpioconf[] = { 875 #if 0 /* We can select and/or. */ 876 { 88, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* USBHPWR1 */ 877 { 89, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* USBHPEN1 */ 878 { 119, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* USBHPWR2 */ 879 { 120, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* USBHPEN2 */ 880 #endif 881 { -1 } 882 }; 883 884 struct pxa2x0_gpioconf pxa27x_pcic_gpioconf[] = { 885 { 48, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* nPOE */ 886 { 49, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* nPWE */ 887 { 50, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* nPIOR */ 888 { 51, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* nPIOW */ 889 { 55, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* nPREG */ 890 { 56, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* nPWAIT */ 891 { 57, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* nIOIS16 */ 892 893 #if 0 /* We can select and/or. */ 894 { 85, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* nPCE1 */ 895 { 86, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* nPCE1 */ 896 { 102, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* nPCE1 */ 897 898 { 54, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* nPCE2 */ 899 { 78, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* nPCE2 */ 900 { 105, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* nPCE2 */ 901 902 { 79, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* pSKTSEL */ 903 { 104, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* pSKTSEL */ 904 #endif 905 906 { -1 } 907 }; 908 909 struct pxa2x0_gpioconf pxa27x_pxaacu_gpioconf[] = { 910 { 28, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* BITCLK */ 911 { 30, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* SDATA_OUT */ 912 913 #if 0 /* We can select and/or. */ 914 { 31, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* SYNC */ 915 { 94, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* SYNC */ 916 917 { 29, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* SDATA_IN0 */ 918 { 116, GPIO_CLR | GPIO_ALT_FN_2_IN }, /* SDATA_IN0 */ 919 920 { 32, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* SDATA_IN1 */ 921 { 99, GPIO_CLR | GPIO_ALT_FN_2_IN }, /* SDATA_IN1 */ 922 923 { 95, GPIO_CLR | GPIO_ALT_FN_1_OUT }, /* RESET_n */ 924 { 113, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* RESET_n */ 925 #endif 926 927 { -1 } 928 }; 929 930 struct pxa2x0_gpioconf pxa27x_pxamci_gpioconf[] = { 931 { 32, GPIO_CLR | GPIO_ALT_FN_2_OUT }, /* MMCLK */ 932 { 92, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* MMDAT<0> */ 933 { 109, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* MMDAT<1> */ 934 { 110, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* MMDAT<2>/MMCCS<0> */ 935 { 111, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* MMDAT<3>/MMCCS<1> */ 936 { 112, GPIO_CLR | GPIO_ALT_FN_1_IN }, /* MMCMD */ 937 938 { -1 } 939 }; 940 #endif 941 942 void 943 pxa2x0_gpio_config(struct pxa2x0_gpioconf **conflist) 944 { 945 int i, j; 946 947 for (i = 0; conflist[i] != NULL; i++) 948 for (j = 0; conflist[i][j].pin != -1; j++) 949 pxa2x0_gpio_set_function(conflist[i][j].pin, 950 conflist[i][j].value); 951 } 952