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