1 /* $NetBSD: epgpio.c,v 1.1 2005/11/12 05:33:23 hamajima Exp $ */ 2 3 /* 4 * Copyright (c) 2005 HAMAJIMA Katsuomi. 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 __KERNEL_RCSID(0, "$NetBSD: epgpio.c,v 1.1 2005/11/12 05:33:23 hamajima Exp $"); 30 31 #include <sys/param.h> 32 #include <sys/systm.h> 33 #include <sys/kernel.h> 34 #include <sys/device.h> 35 #include <machine/bus.h> 36 #include <machine/intr.h> 37 #include <dev/gpio/gpiovar.h> 38 #include <arm/ep93xx/ep93xxvar.h> 39 #include <arm/ep93xx/epsocvar.h> 40 #include <arm/ep93xx/epgpioreg.h> 41 #include <arm/ep93xx/epgpiovar.h> 42 #include "gpio.h" 43 #if NGPIO > 0 44 #include <sys/gpio.h> 45 #endif 46 #include "locators.h" 47 48 #ifdef EPGPIO_DEBUG 49 int epgpio_debug = EPGPIO_DEBUG; 50 #define DPRINTFN(n,x) if (epgpio_debug>(n)) printf x; 51 #else 52 #define DPRINTFN(n,x) 53 #endif 54 55 #define EPGPIO_NPORTS 8 56 #define EPGPIO_NPINS 8 57 58 struct port_info { 59 struct epgpio_softc *sc; 60 int unit; 61 #if NGPIO > 0 62 struct gpio_chipset_tag gpio_chipset; 63 gpio_pin_t pins[EPGPIO_NPINS]; 64 #endif 65 bus_size_t pxdr; 66 bus_size_t pxddr; 67 bus_size_t xinten; 68 bus_size_t xinttype1; 69 bus_size_t xinttype2; 70 bus_size_t xeoi; 71 bus_size_t xdb; 72 }; 73 74 struct intr_req { 75 int irq; 76 int (*ih_func)(void *); 77 int (*ireq_func)(void *); 78 void *ireq_arg; 79 void *cookie; 80 }; 81 82 struct epgpio_softc { 83 struct device sc_dev; 84 bus_space_tag_t sc_iot; 85 bus_space_handle_t sc_ioh; 86 struct port_info sc_port[EPGPIO_NPORTS]; 87 struct intr_req sc_ireq_combine; 88 struct intr_req sc_ireq_f[EPGPIO_NPINS]; 89 }; 90 91 static int epgpio_match(struct device *, struct cfdata *, void *); 92 static void epgpio_attach(struct device *, struct device *, void *); 93 94 #if NGPIO > 0 95 static int epgpiobus_print(void *, const char *); 96 static int epgpio_pin_read(void *, int); 97 static void epgpio_pin_write(void *, int, int); 98 static void epgpio_pin_ctl(void *, int, int); 99 #endif 100 101 static int epgpio_search(struct device *, struct cfdata *, const int *, void *); 102 static int epgpio_print(void *, const char *); 103 104 static int epgpio_intr_combine(void* arg); 105 static int epgpio_intr_f(void* arg, int); 106 static int epgpio_intr_0(void* arg); 107 static int epgpio_intr_1(void* arg); 108 static int epgpio_intr_2(void* arg); 109 static int epgpio_intr_3(void* arg); 110 static int epgpio_intr_4(void* arg); 111 static int epgpio_intr_5(void* arg); 112 static int epgpio_intr_6(void* arg); 113 static int epgpio_intr_7(void* arg); 114 115 static void epgpio_bit_set(struct epgpio_softc *, bus_size_t, int); 116 static void epgpio_bit_clear(struct epgpio_softc *, bus_size_t, int); 117 118 CFATTACH_DECL(epgpio, sizeof(struct epgpio_softc), 119 epgpio_match, epgpio_attach, NULL, NULL); 120 121 static int 122 epgpio_match(struct device *parent, struct cfdata *match, void *aux) 123 { 124 return 2; 125 } 126 127 static void 128 epgpio_attach(struct device *parent, struct device *self, void *aux) 129 { 130 struct epgpio_softc *sc = (struct epgpio_softc*)self; 131 struct epsoc_attach_args *sa = aux; 132 struct port_info *pi; 133 #if NGPIO > 0 134 struct gpiobus_attach_args gba; 135 int dir, val; 136 int i, j; 137 #endif 138 139 printf("\n"); 140 sc->sc_iot = sa->sa_iot; 141 142 if (bus_space_map(sa->sa_iot, sa->sa_addr, 143 sa->sa_size, 0, &sc->sc_ioh)){ 144 printf("%s: Cannot map registers", self->dv_xname); 145 return; 146 } 147 148 /* PORT A */ 149 pi = &sc->sc_port[0]; 150 pi->unit = 0; 151 pi->sc = sc; 152 pi->pxdr = EP93XX_GPIO_PADR; 153 pi->pxddr = EP93XX_GPIO_PADDR; 154 pi->xinten = EP93XX_GPIO_AIntEn; 155 pi->xinttype1 = EP93XX_GPIO_AIntType1; 156 pi->xinttype2 = EP93XX_GPIO_AIntType2; 157 pi->xeoi = EP93XX_GPIO_AEOI; 158 pi->xdb = EP93XX_GPIO_ADB; 159 bus_space_write_4(sc->sc_iot, sc->sc_ioh, pi->xinten, 0); 160 /* PORT B */ 161 pi = &sc->sc_port[1]; 162 pi->unit = 1; 163 pi->sc = sc; 164 pi->pxdr = EP93XX_GPIO_PBDR; 165 pi->pxddr = EP93XX_GPIO_PBDDR; 166 pi->xinten = EP93XX_GPIO_BIntEn; 167 pi->xinttype1 = EP93XX_GPIO_BIntType1; 168 pi->xinttype2 = EP93XX_GPIO_BIntType2; 169 pi->xeoi = EP93XX_GPIO_BEOI; 170 pi->xdb = EP93XX_GPIO_BDB; 171 bus_space_write_4(sc->sc_iot, sc->sc_ioh, pi->xinten, 0); 172 /* PORT C */ 173 pi = &sc->sc_port[2]; 174 pi->unit = 2; 175 pi->sc = sc; 176 pi->pxdr = EP93XX_GPIO_PCDR; 177 pi->pxddr = EP93XX_GPIO_PCDDR; 178 pi->xinten = pi->xinttype1 = pi->xinttype2 = pi->xeoi = pi->xdb = -1; 179 /* PORT D */ 180 pi = &sc->sc_port[3]; 181 pi->unit = 3; 182 pi->sc = sc; 183 pi->pxdr = EP93XX_GPIO_PDDR; 184 pi->pxddr = EP93XX_GPIO_PDDDR; 185 pi->xinten = pi->xinttype1 = pi->xinttype2 = pi->xeoi = pi->xdb = -1; 186 /* PORT E */ 187 pi = &sc->sc_port[4]; 188 pi->unit = 4; 189 pi->sc = sc; 190 pi->pxdr = EP93XX_GPIO_PEDR; 191 pi->pxddr = EP93XX_GPIO_PEDDR; 192 pi->xinten = pi->xinttype1 = pi->xinttype2 = pi->xeoi = pi->xdb = -1; 193 /* PORT F */ 194 pi = &sc->sc_port[5]; 195 pi->unit = 5; 196 pi->sc = sc; 197 pi->pxdr = EP93XX_GPIO_PFDR; 198 pi->pxddr = EP93XX_GPIO_PFDDR; 199 pi->xinten = EP93XX_GPIO_FIntEn; 200 pi->xinttype1 = EP93XX_GPIO_FIntType1; 201 pi->xinttype2 = EP93XX_GPIO_FIntType2; 202 pi->xeoi = EP93XX_GPIO_FEOI; 203 pi->xdb = EP93XX_GPIO_FDB; 204 bus_space_write_4(sc->sc_iot, sc->sc_ioh, pi->xinten, 0); 205 /* PORT G */ 206 pi = &sc->sc_port[6]; 207 pi->unit = 6; 208 pi->sc = sc; 209 pi->pxdr = EP93XX_GPIO_PGDR; 210 pi->pxddr = EP93XX_GPIO_PGDDR; 211 pi->xinten = pi->xinttype1 = pi->xinttype2 = pi->xeoi = pi->xdb = -1; 212 /* PORT H */ 213 pi = &sc->sc_port[7]; 214 pi->unit = 7; 215 pi->sc = sc; 216 pi->pxdr = EP93XX_GPIO_PHDR; 217 pi->pxddr = EP93XX_GPIO_PHDDR; 218 pi->xinten = pi->xinttype1 = pi->xinttype2 = pi->xeoi = pi->xdb = -1; 219 220 /* PORT A & B */ 221 sc->sc_ireq_combine.irq = EP93XX_GPIO_INTR; 222 sc->sc_ireq_combine.ih_func = epgpio_intr_combine; 223 /* PORT F */ 224 sc->sc_ireq_f[0].irq = EP93XX_GPIO0_INTR; 225 sc->sc_ireq_f[0].ih_func = epgpio_intr_0; 226 sc->sc_ireq_f[1].irq = EP93XX_GPIO1_INTR; 227 sc->sc_ireq_f[1].ih_func = epgpio_intr_1; 228 sc->sc_ireq_f[2].irq = EP93XX_GPIO2_INTR; 229 sc->sc_ireq_f[2].ih_func = epgpio_intr_2; 230 sc->sc_ireq_f[3].irq = EP93XX_GPIO3_INTR; 231 sc->sc_ireq_f[3].ih_func = epgpio_intr_3; 232 sc->sc_ireq_f[4].irq = EP93XX_GPIO4_INTR; 233 sc->sc_ireq_f[4].ih_func = epgpio_intr_4; 234 sc->sc_ireq_f[5].irq = EP93XX_GPIO5_INTR; 235 sc->sc_ireq_f[5].ih_func = epgpio_intr_5; 236 sc->sc_ireq_f[6].irq = EP93XX_GPIO6_INTR; 237 sc->sc_ireq_f[6].ih_func = epgpio_intr_6; 238 sc->sc_ireq_f[7].irq = EP93XX_GPIO7_INTR; 239 sc->sc_ireq_f[7].ih_func = epgpio_intr_7; 240 241 #if NGPIO > 0 242 /* initialize and attach gpio(4) */ 243 for (i = 0; i < EPGPIO_NPORTS; i++) { 244 pi = &sc->sc_port[i]; 245 dir = bus_space_read_4(sc->sc_iot, sc->sc_ioh, pi->pxddr) & 0xff; 246 val = bus_space_read_4(sc->sc_iot, sc->sc_ioh, pi->pxdr) & 0xff; 247 for (j = 0; j < EPGPIO_NPINS; j++) { 248 pi->pins[j].pin_num = j; 249 pi->pins[j].pin_caps = (GPIO_PIN_INPUT 250 | GPIO_PIN_OUTPUT); 251 if((dir >> j) & 0x01) 252 pi->pins[j].pin_flags = GPIO_PIN_OUTPUT; 253 else 254 pi->pins[j].pin_flags = GPIO_PIN_INPUT; 255 if((val >> j) & 0x01) 256 pi->pins[j].pin_state = GPIO_PIN_HIGH; 257 else 258 pi->pins[j].pin_state = GPIO_PIN_LOW; 259 } 260 pi->gpio_chipset.gp_cookie = pi; 261 pi->gpio_chipset.gp_pin_read = epgpio_pin_read; 262 pi->gpio_chipset.gp_pin_write = epgpio_pin_write; 263 pi->gpio_chipset.gp_pin_ctl = epgpio_pin_ctl; 264 gba.gba_gc = &pi->gpio_chipset; 265 gba.gba_pins = pi->pins; 266 gba.gba_npins = EPGPIO_NPINS; 267 config_found_ia(self, "gpiobus", &gba, epgpiobus_print); 268 } 269 #endif 270 271 /* attach device */ 272 config_search_ia(epgpio_search, self, "epgpio", epgpio_print); 273 } 274 275 #if NGPIO > 0 276 static int 277 epgpiobus_print(void *aux, const char *name) 278 { 279 struct gpiobus_attach_args *gba = aux; 280 struct port_info *pi = (struct port_info *)gba->gba_gc->gp_cookie; 281 282 gpiobus_print(aux, name); 283 aprint_normal(": port %c", pi->unit+'A'); 284 285 return (UNCONF); 286 } 287 #endif 288 289 290 static int 291 epgpio_search(struct device *parent, struct cfdata *cf, 292 const int *ldesc, void *aux) 293 { 294 struct epgpio_softc *sc = (struct epgpio_softc*)parent; 295 struct epgpio_attach_args ga; 296 297 ga.ga_gc = sc; 298 ga.ga_iot = sc->sc_iot; 299 ga.ga_port = cf->cf_loc[EPGPIOCF_PORT]; 300 ga.ga_bit1 = cf->cf_loc[EPGPIOCF_BIT1]; 301 ga.ga_bit2 = cf->cf_loc[EPGPIOCF_BIT2]; 302 303 if (config_match(parent, cf, &ga) > 0) 304 config_attach(parent, cf, &ga, epgpio_print); 305 306 return 0; 307 } 308 309 static int 310 epgpio_print(void *aux, const char *name) 311 { 312 struct epgpio_attach_args *ga = (struct epgpio_attach_args*)aux; 313 struct epgpio_softc *sc = (struct epgpio_softc*)ga->ga_gc; 314 315 aprint_normal(":"); 316 if (ga->ga_port > -1) 317 aprint_normal(" port %c", sc->sc_port[ga->ga_port].unit+'A'); 318 if (ga->ga_bit1 > -1) 319 aprint_normal(" bit1 %d", ga->ga_bit1); 320 if (ga->ga_bit2 > -1) 321 aprint_normal(" bit2 %d", ga->ga_bit2); 322 323 return (UNCONF); 324 } 325 326 int 327 epgpio_read(struct epgpio_softc *sc, epgpio_port port, int bit) 328 { 329 struct port_info *pi = &sc->sc_port[port]; 330 331 #if NGPIO > 0 332 pi->pins[bit].pin_caps = 0; 333 #endif 334 return (bus_space_read_4(sc->sc_iot, sc->sc_ioh, pi->pxdr) >> bit) & 1; 335 } 336 337 void 338 epgpio_set(struct epgpio_softc *sc, epgpio_port port, int bit) 339 { 340 struct port_info *pi = &sc->sc_port[port]; 341 342 #if NGPIO > 0 343 pi->pins[bit].pin_caps = 0; 344 #endif 345 epgpio_bit_set(sc, pi->pxdr, bit); 346 } 347 348 void 349 epgpio_clear(struct epgpio_softc *sc, epgpio_port port, int bit) 350 { 351 struct port_info *pi = &sc->sc_port[port]; 352 353 #if NGPIO > 0 354 pi->pins[bit].pin_caps = 0; 355 #endif 356 epgpio_bit_clear(sc, pi->pxdr, bit); 357 } 358 359 void 360 epgpio_in(struct epgpio_softc *sc, epgpio_port port, int bit) 361 { 362 struct port_info *pi = &sc->sc_port[port]; 363 364 #if NGPIO > 0 365 pi->pins[bit].pin_caps = 0; 366 #endif 367 epgpio_bit_clear(sc, pi->pxddr, bit); 368 } 369 370 void 371 epgpio_out(struct epgpio_softc *sc, epgpio_port port, int bit) 372 { 373 struct port_info *pi = &sc->sc_port[port]; 374 375 #if NGPIO > 0 376 pi->pins[bit].pin_caps = 0; 377 #endif 378 epgpio_bit_set(sc, pi->pxddr, bit); 379 } 380 381 void * 382 epgpio_intr_establish(struct epgpio_softc *sc, epgpio_port port, int bit, 383 int flag, int ipl, int (*ireq_func)(void *), void *arg) { 384 struct port_info *pi; 385 struct intr_req *intq; 386 387 DPRINTFN(1, ("epgpio_intr_establish: port=%d, bit=%d, flag=%#x\n",port,bit,flag)); 388 389 if (bit < 0 || bit >= EPGPIO_NPINS) 390 return 0; 391 392 switch (port) { 393 case PORT_A: 394 case PORT_B: 395 intq = &sc->sc_ireq_combine; 396 break; 397 case PORT_F: 398 intq = &sc->sc_ireq_f[bit]; 399 break; 400 default: 401 return 0; 402 }; 403 404 if (intq->ireq_func) 405 return 0; /* already used */ 406 407 intq->ireq_func = ireq_func; 408 intq->ireq_arg = arg; 409 410 pi = &sc->sc_port[port]; 411 epgpio_bit_clear(sc, pi->xinten, bit); 412 epgpio_in(sc, port, bit); 413 #if NGPIO > 0 414 pi->pins[bit].pin_caps = 0; 415 #endif 416 417 if (flag & EDGE_TRIGGER) 418 epgpio_bit_set(sc, pi->xinttype1, bit); 419 else /* LEVEL_SENSE */ 420 epgpio_bit_clear(sc, pi->xinttype1, bit); 421 if (flag & RISING_EDGE) /* or HIGH_LEVEL */ 422 epgpio_bit_set(sc, pi->xinttype2, bit); 423 else /* FALLING_EDGE or LOW_LEVEL */ 424 epgpio_bit_clear(sc, pi->xinttype2, bit); 425 if (flag & DEBOUNCE) 426 epgpio_bit_set(sc, pi->xdb, bit); 427 else 428 epgpio_bit_clear(sc, pi->xdb, bit); 429 430 if (!intq->cookie) 431 intq->cookie = ep93xx_intr_establish(intq->irq, ipl, 432 intq->ih_func, pi); 433 bus_space_write_4(sc->sc_iot, sc->sc_ioh, pi->xeoi, 1 << bit); 434 epgpio_bit_set(sc, pi->xinten, bit); 435 return intq->cookie; 436 } 437 438 void 439 epgpio_intr_disestablish(struct epgpio_softc *sc, epgpio_port port, int bit) 440 { 441 struct port_info *pi; 442 struct intr_req *intq; 443 444 DPRINTFN(1, ("epgpio_intr_disestablish: port=%d, bit=%d\n",port,bit)); 445 446 if (bit < 0 || bit >= EPGPIO_NPINS) 447 return; 448 449 switch (port) { 450 case PORT_A: 451 case PORT_B: 452 intq = &sc->sc_ireq_combine; 453 break; 454 case PORT_F: 455 intq = &sc->sc_ireq_f[bit]; 456 break; 457 default: 458 return; 459 }; 460 461 if (!intq->ireq_func) 462 return; 463 464 pi = &sc->sc_port[port]; 465 epgpio_bit_clear(sc, pi->xinten, bit); 466 intq->ireq_func = 0; 467 intq->ireq_arg = 0; 468 ep93xx_intr_disestablish(intq->cookie); 469 intq->cookie = 0; 470 } 471 472 static int 473 epgpio_intr_combine(void *arg) 474 { 475 struct port_info *pi = arg; 476 struct epgpio_softc *sc = pi->sc; 477 struct intr_req *intq = &sc->sc_ireq_combine; 478 int err = 0; 479 480 DPRINTFN(1, ("epgpio_intr_combine\n")); 481 482 if (intq->ireq_func) 483 err = (*intq->ireq_func)(intq->ireq_arg); 484 epgpio_bit_set(sc, pi->xeoi, 0xff); 485 return err; 486 } 487 488 static int 489 epgpio_intr_f(void *arg, int bit) 490 { 491 struct port_info *pi = arg; 492 struct epgpio_softc *sc = pi->sc; 493 struct intr_req *intq = &sc->sc_ireq_f[bit]; 494 int err = 0; 495 496 DPRINTFN(1, ("epgpio_intr_%d\n", bit)); 497 498 if (intq->ireq_func) 499 err = (*intq->ireq_func)(intq->ireq_arg); 500 epgpio_bit_set(sc, pi->xeoi, bit); 501 return err; 502 } 503 504 static int 505 epgpio_intr_0(void *arg) 506 { 507 return epgpio_intr_f(arg, 0); 508 } 509 510 static int 511 epgpio_intr_1(void *arg) 512 { 513 return epgpio_intr_f(arg, 1); 514 } 515 516 static int 517 epgpio_intr_2(void *arg) 518 { 519 return epgpio_intr_f(arg, 2); 520 } 521 522 static int 523 epgpio_intr_3(void *arg) 524 { 525 return epgpio_intr_f(arg, 3); 526 } 527 528 static int 529 epgpio_intr_4(void *arg) 530 { 531 return epgpio_intr_f(arg, 4); 532 } 533 534 static int 535 epgpio_intr_5(void *arg) 536 { 537 return epgpio_intr_f(arg, 5); 538 } 539 540 static int 541 epgpio_intr_6(void *arg) 542 { 543 return epgpio_intr_f(arg, 6); 544 } 545 546 static int 547 epgpio_intr_7(void *arg) 548 { 549 return epgpio_intr_f(arg, 7); 550 } 551 552 #if NGPIO > 0 553 static int 554 epgpio_pin_read(void *arg, int pin) 555 { 556 struct port_info *pi = arg; 557 struct epgpio_softc *sc = pi->sc; 558 559 pin %= EPGPIO_NPINS; 560 if (!pi->pins[pin].pin_caps) 561 return 0; /* EBUSY? */ 562 563 return (bus_space_read_4(sc->sc_iot, sc->sc_ioh, 564 pi->pxdr) >> pin) & 1; 565 } 566 567 static void 568 epgpio_pin_write(void *arg, int pin, int val) 569 { 570 struct port_info *pi = arg; 571 struct epgpio_softc *sc = pi->sc; 572 573 pin %= EPGPIO_NPINS; 574 if (!pi->pins[pin].pin_caps) 575 return; 576 577 if (val) 578 epgpio_bit_set(sc, pi->pxdr, pin); 579 else 580 epgpio_bit_clear(sc, pi->pxdr, pin); 581 } 582 583 static void 584 epgpio_pin_ctl(void *arg, int pin, int flags) 585 { 586 struct port_info *pi = arg; 587 struct epgpio_softc *sc = pi->sc; 588 589 pin %= EPGPIO_NPINS; 590 if (!pi->pins[pin].pin_caps) 591 return; 592 593 if (flags & GPIO_PIN_INPUT) 594 epgpio_bit_clear(sc, pi->pxddr, pin); 595 else if (flags & GPIO_PIN_OUTPUT) 596 epgpio_bit_set(sc, pi->pxddr, pin); 597 } 598 #endif 599 600 static void 601 epgpio_bit_set(struct epgpio_softc *sc, bus_size_t reg, int bit) 602 { 603 int t = bus_space_read_4(sc->sc_iot, sc->sc_ioh, reg) & 0xff; 604 bus_space_write_4(sc->sc_iot, sc->sc_ioh, reg, t | (1 << bit)); 605 } 606 607 static void 608 epgpio_bit_clear(struct epgpio_softc *sc, bus_size_t reg, int bit) 609 { 610 int t = bus_space_read_4(sc->sc_iot, sc->sc_ioh, reg) & 0xff; 611 bus_space_write_4(sc->sc_iot, sc->sc_ioh, reg, t & ~(1 << bit)); 612 } 613