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