1 /* $OpenBSD: omgpio.c,v 1.10 2016/08/12 03:22:41 jsg Exp $ */ 2 /* 3 * Copyright (c) 2007,2009 Dale Rahn <drahn@openbsd.org> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #include <sys/param.h> 19 #include <sys/systm.h> 20 #include <sys/queue.h> 21 #include <sys/device.h> 22 #include <sys/malloc.h> 23 #include <sys/evcount.h> 24 #include <sys/gpio.h> 25 26 #include <arm/cpufunc.h> 27 28 #include <machine/bus.h> 29 #include <machine/fdt.h> 30 #include <machine/intr.h> 31 32 #include <dev/gpio/gpiovar.h> 33 34 #include <armv7/armv7/armv7var.h> 35 #include <armv7/omap/prcmvar.h> 36 #include <armv7/omap/omgpiovar.h> 37 38 #include <dev/ofw/fdt.h> 39 #include <dev/ofw/openfirm.h> 40 41 #include "gpio.h" 42 43 /* OMAP3 registers */ 44 #define GPIO3_REVISION 0x00 45 #define GPIO3_SYSCONFIG 0x10 46 #define GPIO3_SYSSTATUS 0x14 47 #define GPIO3_IRQSTATUS1 0x18 48 #define GPIO3_IRQENABLE1 0x1C 49 #define GPIO3_WAKEUPENABLE 0x20 50 #define GPIO3_IRQSTATUS2 0x28 51 #define GPIO3_IRQENABLE2 0x2C 52 #define GPIO3_CTRL 0x30 53 #define GPIO3_OE 0x34 54 #define GPIO3_DATAIN 0x38 55 #define GPIO3_DATAOUT 0x3C 56 #define GPIO3_LEVELDETECT0 0x40 57 #define GPIO3_LEVELDETECT1 0x44 58 #define GPIO3_RISINGDETECT 0x48 59 #define GPIO3_FALLINGDETECT 0x4C 60 #define GPIO3_DEBOUNCENABLE 0x50 61 #define GPIO3_DEBOUNCINGTIME 0x54 62 #define GPIO3_CLEARIRQENABLE1 0x60 63 #define GPIO3_SETIRQENABLE1 0x64 64 #define GPIO3_CLEARIRQENABLE2 0x70 65 #define GPIO3_SETIRQENABLE2 0x74 66 #define GPIO3_CLEARWKUENA 0x80 67 #define GPIO3_SETWKUENA 0x84 68 #define GPIO3_CLEARDATAOUT 0x90 69 #define GPIO3_SETDATAOUT 0x94 70 71 /* OMAP4 registers */ 72 #define GPIO4_REVISION 0x00 73 #define GPIO4_SYSCONFIG 0x10 74 #define GPIO4_IRQSTATUS_RAW_0 0x24 75 #define GPIO4_IRQSTATUS_RAW_1 0x28 76 #define GPIO4_IRQSTATUS_0 0x2C 77 #define GPIO4_IRQSTATUS_1 0x30 78 #define GPIO4_IRQSTATUS_SET_0 0x34 79 #define GPIO4_IRQSTATUS_SET_1 0x38 80 #define GPIO4_IRQSTATUS_CLR_0 0x3C 81 #define GPIO4_IRQSTATUS_CLR_1 0x40 82 #define GPIO4_IRQWAKEN_0 0x44 83 #define GPIO4_IRQWAKEN_1 0x48 84 #define GPIO4_SYSSTATUS 0x114 85 #define GPIO4_WAKEUPENABLE 0x120 86 #define GPIO4_CTRL 0x130 87 #define GPIO4_OE 0x134 88 #define GPIO4_DATAIN 0x138 89 #define GPIO4_DATAOUT 0x13C 90 #define GPIO4_LEVELDETECT0 0x140 91 #define GPIO4_LEVELDETECT1 0x144 92 #define GPIO4_RISINGDETECT 0x148 93 #define GPIO4_FALLINGDETECT 0x14C 94 #define GPIO4_DEBOUNCENABLE 0x150 95 #define GPIO4_DEBOUNCINGTIME 0x154 96 #define GPIO4_CLEARWKUPENA 0x180 97 #define GPIO4_SETWKUENA 0x184 98 #define GPIO4_CLEARDATAOUT 0x190 99 #define GPIO4_SETDATAOUT 0x194 100 101 /* AM335X registers */ 102 #define GPIO_AM335X_REVISION 0x00 103 #define GPIO_AM335X_SYSCONFIG 0x10 104 #define GPIO_AM335X_IRQSTATUS_RAW_0 0x24 105 #define GPIO_AM335X_IRQSTATUS_RAW_1 0x28 106 #define GPIO_AM335X_IRQSTATUS_0 0x2C 107 #define GPIO_AM335X_IRQSTATUS_1 0x30 108 #define GPIO_AM335X_IRQSTATUS_SET_0 0x34 109 #define GPIO_AM335X_IRQSTATUS_SET_1 0x38 110 #define GPIO_AM335X_IRQSTATUS_CLR_0 0x3c 111 #define GPIO_AM335X_IRQSTATUS_CLR_1 0x40 112 #define GPIO_AM335X_IRQWAKEN_0 0x44 113 #define GPIO_AM335X_IRQWAKEN_1 0x48 114 #define GPIO_AM335X_SYSSTATUS 0x114 115 #define GPIO_AM335X_CTRL 0x130 116 #define GPIO_AM335X_OE 0x134 117 #define GPIO_AM335X_DATAIN 0x138 118 #define GPIO_AM335X_DATAOUT 0x13C 119 #define GPIO_AM335X_LEVELDETECT0 0x140 120 #define GPIO_AM335X_LEVELDETECT1 0x144 121 #define GPIO_AM335X_RISINGDETECT 0x148 122 #define GPIO_AM335X_FALLINGDETECT 0x14C 123 #define GPIO_AM335X_DEBOUNCENABLE 0x150 124 #define GPIO_AM335X_DEBOUNCINGTIME 0x154 125 #define GPIO_AM335X_CLEARDATAOUT 0x190 126 #define GPIO_AM335X_SETDATAOUT 0x194 127 128 #define GPIO_NUM_PINS 32 129 130 struct intrhand { 131 int (*ih_func)(void *); /* handler */ 132 void *ih_arg; /* arg for handler */ 133 int ih_ipl; /* IPL_* */ 134 int ih_irq; /* IRQ number */ 135 int ih_gpio; /* gpio pin */ 136 struct evcount ih_count; 137 char *ih_name; 138 }; 139 140 struct omgpio_regs { 141 u_int32_t revision; 142 u_int32_t sysconfig; 143 u_int32_t irqstatus_raw0; /* omap4/am335x only */ 144 u_int32_t irqstatus_raw1; /* omap4/am335x only */ 145 u_int32_t irqstatus0; 146 u_int32_t irqstatus1; 147 u_int32_t irqstatus_set0; 148 u_int32_t irqstatus_set1; 149 u_int32_t irqstatus_clear0; 150 u_int32_t irqstatus_clear1; 151 u_int32_t irqwaken0; 152 u_int32_t irqwaken1; 153 u_int32_t sysstatus; 154 u_int32_t wakeupenable; /* omap3/omap4 only */ 155 u_int32_t ctrl; 156 u_int32_t oe; 157 u_int32_t datain; 158 u_int32_t dataout; 159 u_int32_t leveldetect0; 160 u_int32_t leveldetect1; 161 u_int32_t risingdetect; 162 u_int32_t fallingdetect; 163 u_int32_t debounceenable; 164 u_int32_t debouncingtime; 165 u_int32_t clearwkupena; /* omap3/omap4 only */ 166 u_int32_t setwkupena; /* omap3/omap4 only */ 167 u_int32_t cleardataout; 168 u_int32_t setdataout; 169 }; 170 171 struct omgpio_softc { 172 struct device sc_dev; 173 bus_space_tag_t sc_iot; 174 bus_space_handle_t sc_ioh; 175 void *sc_ih_h; 176 void *sc_ih_l; 177 int sc_max_il; 178 int sc_min_il; 179 int sc_node; 180 struct intrhand *sc_handlers[GPIO_NUM_PINS]; 181 int sc_omap_ver; 182 struct gpio_chipset_tag sc_gpio_gc; 183 gpio_pin_t sc_gpio_pins[GPIO_NUM_PINS]; 184 struct omgpio_regs sc_regs; 185 int (*sc_padconf_set_gpioflags)(uint32_t, uint32_t); 186 }; 187 188 #define GPIO_PIN_TO_INST(x) ((x) >> 5) 189 #define GPIO_PIN_TO_OFFSET(x) ((x) & 0x1f) 190 #define DEVNAME(sc) ((sc)->sc_dev.dv_xname) 191 #define READ4(sc, reg) omgpio_read4(sc, reg) 192 #define WRITE4(sc, reg, val) omgpio_write4(sc, reg, val) 193 194 u_int32_t omgpio_read4(struct omgpio_softc *, u_int32_t); 195 void omgpio_write4(struct omgpio_softc *, u_int32_t, u_int32_t); 196 int omgpio_match(struct device *, void *, void *); 197 void omgpio_attach(struct device *, struct device *, void *); 198 void omgpio_recalc_interrupts(struct omgpio_softc *); 199 int omgpio_irq(void *); 200 int omgpio_irq_dummy(void *); 201 int omgpio_pin_dir_read(struct omgpio_softc *, unsigned int); 202 void omgpio_pin_dir_write(struct omgpio_softc *, unsigned int, unsigned int); 203 204 struct cfattach omgpio_ca = { 205 sizeof (struct omgpio_softc), omgpio_match, omgpio_attach 206 }; 207 208 struct cfdriver omgpio_cd = { 209 NULL, "omgpio", DV_DULL 210 }; 211 212 const char *omgpio_compatible[] = { 213 "ti,omap3-gpio", 214 "ti,omap4-gpio", 215 NULL 216 }; 217 218 u_int32_t 219 omgpio_read4(struct omgpio_softc *sc, u_int32_t reg) 220 { 221 if(reg == -1) 222 panic("%s: Invalid register address", DEVNAME(sc)); 223 224 return bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg)); 225 } 226 227 void 228 omgpio_write4(struct omgpio_softc *sc, u_int32_t reg, u_int32_t val) 229 { 230 if(reg == -1) 231 panic("%s: Invalid register address", DEVNAME(sc)); 232 233 bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (val)); 234 } 235 236 int 237 omgpio_match(struct device *parent, void *match, void *aux) 238 { 239 struct fdt_attach_args *faa = aux; 240 int i; 241 242 for (i = 0; omgpio_compatible[i] != NULL; i++) { 243 if (OF_is_compatible(faa->fa_node, omgpio_compatible[i])) 244 return 1; 245 } 246 return 0; 247 } 248 249 void 250 omgpio_attach(struct device *parent, struct device *self, void *aux) 251 { 252 struct fdt_attach_args *faa = aux; 253 struct omgpio_softc *sc = (struct omgpio_softc *) self; 254 struct gpiobus_attach_args gba; 255 u_int32_t rev; 256 int i, len, unit; 257 char hwmods[64]; 258 259 if (faa->fa_nreg < 1) 260 return; 261 262 unit = 0; 263 if ((len = OF_getprop(faa->fa_node, "ti,hwmods", hwmods, 264 sizeof(hwmods))) == 6) { 265 if ((strncmp(hwmods, "gpio", 4) == 0) && 266 (hwmods[4] > '0') && (hwmods[4] <= '9')) 267 unit = hwmods[4] - '1'; 268 } 269 270 prcm_enablemodule(PRCM_GPIO0 + unit); 271 272 sc->sc_node = faa->fa_node; 273 sc->sc_iot = faa->fa_iot; 274 if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr, 275 faa->fa_reg[0].size, 0, &sc->sc_ioh)) 276 panic("%s: bus_space_map failed!", DEVNAME(sc)); 277 278 if (OF_is_compatible(faa->fa_node, "ti,omap3-gpio")) { 279 sc->sc_padconf_set_gpioflags = NULL; 280 sc->sc_regs.revision = GPIO3_REVISION; 281 sc->sc_regs.sysconfig = GPIO3_SYSCONFIG; 282 sc->sc_regs.irqstatus_raw0 = -1; 283 sc->sc_regs.irqstatus_raw1 = -1; 284 sc->sc_regs.irqstatus0 = GPIO3_IRQSTATUS1; 285 sc->sc_regs.irqstatus1 = GPIO3_IRQSTATUS2; 286 sc->sc_regs.irqstatus_set0 = GPIO3_SETIRQENABLE1; 287 sc->sc_regs.irqstatus_set1 = GPIO3_SETIRQENABLE2; 288 sc->sc_regs.irqstatus_clear0 = GPIO3_CLEARIRQENABLE1; 289 sc->sc_regs.irqstatus_clear1 = GPIO3_CLEARIRQENABLE2; 290 sc->sc_regs.irqwaken0 = -1; 291 sc->sc_regs.irqwaken1 = -1; 292 sc->sc_regs.sysstatus = GPIO3_SYSSTATUS; 293 sc->sc_regs.wakeupenable = GPIO3_WAKEUPENABLE; 294 sc->sc_regs.ctrl = GPIO3_CTRL; 295 sc->sc_regs.oe = GPIO3_OE; 296 sc->sc_regs.datain = GPIO3_DATAIN; 297 sc->sc_regs.dataout = GPIO3_DATAOUT; 298 sc->sc_regs.leveldetect0 = GPIO3_LEVELDETECT0; 299 sc->sc_regs.leveldetect1 = GPIO3_LEVELDETECT1; 300 sc->sc_regs.risingdetect = GPIO3_RISINGDETECT; 301 sc->sc_regs.fallingdetect = GPIO3_FALLINGDETECT; 302 sc->sc_regs.debounceenable = GPIO3_DEBOUNCENABLE; 303 sc->sc_regs.debouncingtime = GPIO3_DEBOUNCINGTIME; 304 sc->sc_regs.clearwkupena = GPIO3_CLEARWKUENA; 305 sc->sc_regs.setwkupena = GPIO3_SETWKUENA; 306 sc->sc_regs.cleardataout = GPIO3_CLEARDATAOUT; 307 sc->sc_regs.setdataout = GPIO3_SETDATAOUT; 308 } else if (OF_is_compatible(faa->fa_node, "ti,omap4-gpio")) { 309 sc->sc_padconf_set_gpioflags = NULL; 310 sc->sc_regs.revision = GPIO4_REVISION; 311 sc->sc_regs.sysconfig = GPIO4_SYSCONFIG; 312 sc->sc_regs.irqstatus_raw0 = GPIO4_IRQSTATUS_RAW_0; 313 sc->sc_regs.irqstatus_raw1 = GPIO4_IRQSTATUS_RAW_1; 314 sc->sc_regs.irqstatus0 = GPIO4_IRQSTATUS_0; 315 sc->sc_regs.irqstatus1 = GPIO4_IRQSTATUS_1; 316 sc->sc_regs.irqstatus_set0 = GPIO4_IRQSTATUS_SET_0; 317 sc->sc_regs.irqstatus_set1 = GPIO4_IRQSTATUS_SET_1; 318 sc->sc_regs.irqstatus_clear0 = GPIO4_IRQSTATUS_CLR_0; 319 sc->sc_regs.irqstatus_clear1 = GPIO4_IRQSTATUS_CLR_1; 320 sc->sc_regs.irqwaken0 = GPIO4_IRQWAKEN_0; 321 sc->sc_regs.irqwaken1 = GPIO4_IRQWAKEN_1; 322 sc->sc_regs.sysstatus = GPIO4_SYSSTATUS; 323 sc->sc_regs.wakeupenable = -1; 324 sc->sc_regs.ctrl = GPIO4_CTRL; 325 sc->sc_regs.oe = GPIO4_OE; 326 sc->sc_regs.datain = GPIO4_DATAIN; 327 sc->sc_regs.dataout = GPIO4_DATAOUT; 328 sc->sc_regs.leveldetect0 = GPIO4_LEVELDETECT0; 329 sc->sc_regs.leveldetect1 = GPIO4_LEVELDETECT1; 330 sc->sc_regs.risingdetect = GPIO4_RISINGDETECT; 331 sc->sc_regs.fallingdetect = GPIO4_FALLINGDETECT; 332 sc->sc_regs.debounceenable = GPIO4_DEBOUNCENABLE; 333 sc->sc_regs.debouncingtime = GPIO4_DEBOUNCINGTIME; 334 sc->sc_regs.clearwkupena = -1; 335 sc->sc_regs.setwkupena = -1; 336 sc->sc_regs.cleardataout = GPIO4_CLEARDATAOUT; 337 sc->sc_regs.setdataout = GPIO4_SETDATAOUT; 338 } else 339 panic("%s: could not find a compatible soc", 340 sc->sc_dev.dv_xname); 341 342 rev = READ4(sc, sc->sc_regs.revision); 343 344 printf(": rev %d.%d\n", rev >> 4 & 0xf, rev & 0xf); 345 346 WRITE4(sc, sc->sc_regs.irqstatus_clear0, ~0); 347 WRITE4(sc, sc->sc_regs.irqstatus_clear1, ~0); 348 349 /* XXX - SYSCONFIG */ 350 /* XXX - CTRL */ 351 /* XXX - DEBOUNCE */ 352 353 for (i = 0; i < GPIO_NUM_PINS; i++) { 354 sc->sc_gpio_pins[i].pin_num = i; 355 sc->sc_gpio_pins[i].pin_caps = GPIO_PIN_INPUT | 356 GPIO_PIN_OUTPUT | GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN; 357 sc->sc_gpio_pins[i].pin_state = omgpio_pin_read(sc, i) ? 358 GPIO_PIN_HIGH : GPIO_PIN_LOW; 359 sc->sc_gpio_pins[i].pin_flags = GPIO_PIN_SET; 360 } 361 362 sc->sc_gpio_gc.gp_cookie = sc; 363 sc->sc_gpio_gc.gp_pin_read = omgpio_pin_read; 364 sc->sc_gpio_gc.gp_pin_write = omgpio_pin_write; 365 sc->sc_gpio_gc.gp_pin_ctl = omgpio_pin_ctl; 366 367 gba.gba_name = "gpio"; 368 gba.gba_gc = &sc->sc_gpio_gc; 369 gba.gba_pins = sc->sc_gpio_pins; 370 gba.gba_npins = GPIO_NUM_PINS; 371 372 #if NGPIO > 0 373 config_found(&sc->sc_dev, &gba, gpiobus_print); 374 #endif 375 } 376 377 /* XXX - This assumes MCU INTERRUPTS are IRQ1, and DSP are IRQ2 */ 378 379 #if 0 380 /* XXX - FIND THESE REGISTERS !!! */ 381 unsigned int 382 omgpio_get_function(unsigned int gpio, unsigned int fn) 383 { 384 return 0; 385 } 386 387 void 388 omgpio_set_function(unsigned int gpio, unsigned int fn) 389 { 390 } 391 #endif 392 393 unsigned int 394 omgpio_get_bit(unsigned int gpio) 395 { 396 struct omgpio_softc *sc = omgpio_cd.cd_devs[GPIO_PIN_TO_INST(gpio)]; 397 398 return omgpio_pin_read(sc, GPIO_PIN_TO_OFFSET(gpio)); 399 } 400 401 void 402 omgpio_set_bit(unsigned int gpio) 403 { 404 struct omgpio_softc *sc = omgpio_cd.cd_devs[GPIO_PIN_TO_INST(gpio)]; 405 406 omgpio_pin_write(sc, GPIO_PIN_TO_OFFSET(gpio), GPIO_PIN_HIGH); 407 } 408 409 void 410 omgpio_clear_bit(unsigned int gpio) 411 { 412 struct omgpio_softc *sc = omgpio_cd.cd_devs[GPIO_PIN_TO_INST(gpio)]; 413 414 omgpio_pin_write(sc, GPIO_PIN_TO_OFFSET(gpio), GPIO_PIN_LOW); 415 } 416 417 void 418 omgpio_set_dir(unsigned int gpio, unsigned int dir) 419 { 420 struct omgpio_softc *sc = omgpio_cd.cd_devs[GPIO_PIN_TO_INST(gpio)]; 421 422 omgpio_pin_dir_write(sc, GPIO_PIN_TO_OFFSET(gpio), dir); 423 } 424 425 int 426 omgpio_pin_read(void *arg, int pin) 427 { 428 struct omgpio_softc *sc = arg; 429 u_int32_t reg; 430 431 if(omgpio_pin_dir_read(sc, pin) == OMGPIO_DIR_IN) 432 reg = READ4(sc, sc->sc_regs.datain); 433 else 434 reg = READ4(sc, sc->sc_regs.dataout); 435 return (reg >> GPIO_PIN_TO_OFFSET(pin)) & 0x1; 436 } 437 438 void 439 omgpio_pin_write(void *arg, int pin, int value) 440 { 441 struct omgpio_softc *sc = arg; 442 443 if (value) 444 WRITE4(sc, sc->sc_regs.setdataout, 445 1 << GPIO_PIN_TO_OFFSET(pin)); 446 else 447 WRITE4(sc, sc->sc_regs.cleardataout, 448 1 << GPIO_PIN_TO_OFFSET(pin)); 449 } 450 451 void 452 omgpio_pin_ctl(void *arg, int pin, int flags) 453 { 454 struct omgpio_softc *sc = arg; 455 456 if (flags & GPIO_PIN_INPUT) 457 omgpio_pin_dir_write(sc, pin, OMGPIO_DIR_IN); 458 else if (flags & GPIO_PIN_OUTPUT) 459 omgpio_pin_dir_write(sc, pin, OMGPIO_DIR_OUT); 460 461 if (sc->sc_padconf_set_gpioflags) 462 sc->sc_padconf_set_gpioflags( 463 sc->sc_dev.dv_unit * GPIO_NUM_PINS + pin, flags); 464 } 465 466 void 467 omgpio_pin_dir_write(struct omgpio_softc *sc, unsigned int gpio, 468 unsigned int dir) 469 { 470 int s; 471 u_int32_t reg; 472 473 s = splhigh(); 474 475 reg = READ4(sc, sc->sc_regs.oe); 476 if (dir == OMGPIO_DIR_IN) 477 reg |= 1 << GPIO_PIN_TO_OFFSET(gpio); 478 else 479 reg &= ~(1 << GPIO_PIN_TO_OFFSET(gpio)); 480 WRITE4(sc, sc->sc_regs.oe, reg); 481 482 splx(s); 483 } 484 485 int 486 omgpio_pin_dir_read(struct omgpio_softc *sc, unsigned int gpio) 487 { 488 u_int32_t reg; 489 reg = READ4(sc, sc->sc_regs.oe); 490 if (reg & (1 << GPIO_PIN_TO_OFFSET(gpio))) 491 return OMGPIO_DIR_IN; 492 else 493 return OMGPIO_DIR_OUT; 494 } 495 496 #if 0 497 void 498 omgpio_clear_intr(struct omgpio_softc *sc, unsigned int gpio) 499 { 500 struct omgpio_softc *sc = omgpio_cd.cd_devs[GPIO_PIN_TO_INST(gpio)]; 501 502 WRITE4(sc, sc->sc_regs.irqstatus0, 1 << GPIO_PIN_TO_OFFSET(gpio)); 503 } 504 505 void 506 omgpio_intr_mask(struct omgpio_softc *sc, unsigned int gpio) 507 { 508 struct omgpio_softc *sc = omgpio_cd.cd_devs[GPIO_PIN_TO_INST(gpio)]; 509 510 WRITE4(sc, sc->sc_regs.irqstatus_clear0, 1 << GPIO_PIN_TO_OFFSET(gpio)); 511 } 512 513 void 514 omgpio_intr_unmask(struct omgpio_softc *sc, unsigned int gpio) 515 { 516 struct omgpio_softc *sc = omgpio_cd.cd_devs[GPIO_PIN_TO_INST(gpio)]; 517 518 WRITE4(sc, sc->sc_regs.irqstatus_set0, 1 << GPIO_PIN_TO_OFFSET(gpio)); 519 } 520 521 void 522 omgpio_intr_level(struct omgpio_softc *sc, unsigned int gpio, unsigned int level) 523 { 524 u_int32_t fe, re, l0, l1, bit; 525 struct omgpio_softc *sc = omgpio_cd.cd_devs[GPIO_PIN_TO_INST(gpio)]; 526 int s; 527 528 s = splhigh(); 529 530 fe = READ4(sc, sc->sc_regs.fallingdetect); 531 re = READ4(sc, sc->sc_regs.risingdetect); 532 l0 = READ4(sc, sc->sc_regs.leveldetect0); 533 l1 = READ4(sc, sc->sc_regs.leveldetect1); 534 535 bit = 1 << GPIO_PIN_TO_OFFSET(gpio); 536 537 switch (level) { 538 case IST_NONE: 539 fe &= ~bit; 540 re &= ~bit; 541 l0 &= ~bit; 542 l1 &= ~bit; 543 break; 544 case IST_EDGE_FALLING: 545 fe |= bit; 546 re &= ~bit; 547 l0 &= ~bit; 548 l1 &= ~bit; 549 break; 550 case IST_EDGE_RISING: 551 fe &= ~bit; 552 re |= bit; 553 l0 &= ~bit; 554 l1 &= ~bit; 555 break; 556 case IST_PULSE: /* XXX */ 557 /* FALLTHRU */ 558 case IST_EDGE_BOTH: 559 fe |= bit; 560 re |= bit; 561 l0 &= ~bit; 562 l1 &= ~bit; 563 break; 564 case IST_LEVEL_LOW: 565 fe &= ~bit; 566 re &= ~bit; 567 l0 |= bit; 568 l1 &= ~bit; 569 break; 570 case IST_LEVEL_HIGH: 571 fe &= ~bit; 572 re &= ~bit; 573 l0 &= ~bit; 574 l1 |= bit; 575 break; 576 default: 577 panic("omgpio_intr_level: bad level: %d", level); 578 break; 579 } 580 581 WRITE4(sc, sc->sc_regs.fallingdetect, fe); 582 WRITE4(sc, sc->sc_regs.risingdetect, re); 583 WRITE4(sc, sc->sc_regs.leveldetect0, l0); 584 WRITE4(sc, sc->sc_regs.leveldetect1, l1); 585 586 splx(s); 587 } 588 589 void * 590 omgpio_intr_establish(struct omgpio_softc *sc, unsigned int gpio, int level, int spl, 591 int (*func)(void *), void *arg, char *name) 592 { 593 int psw; 594 struct intrhand *ih; 595 struct omgpio_softc *sc; 596 597 /* 598 * XXX - is gpio here the pin or the interrupt number 599 * which is 96 + gpio pin? 600 */ 601 602 if (GPIO_PIN_TO_INST(gpio) > omgpio_cd.cd_ndevs) 603 panic("omgpio_intr_establish: bogus irqnumber %d: %s", 604 gpio, name); 605 606 sc = omgpio_cd.cd_devs[GPIO_PIN_TO_INST(gpio)]; 607 608 if (sc->sc_handlers[GPIO_PIN_TO_OFFSET(gpio)] != NULL) 609 panic("omgpio_intr_establish: gpio pin busy %d old %s new %s", 610 gpio, sc->sc_handlers[GPIO_PIN_TO_OFFSET(gpio)]->ih_name, 611 name); 612 613 psw = disable_interrupts(PSR_I); 614 615 ih = malloc(sizeof(*ih), M_DEVBUF, M_WAITOK); 616 ih->ih_func = func; 617 ih->ih_arg = arg; 618 ih->ih_ipl = level; 619 ih->ih_gpio = gpio; 620 ih->ih_irq = gpio + 512; 621 ih->ih_name = name; 622 623 sc->sc_handlers[GPIO_PIN_TO_OFFSET(gpio)] = ih; 624 625 evcount_attach(&ih->ih_count, name, &ih->ih_irq); 626 627 omgpio_intr_level(gpio, level); 628 omgpio_intr_unmask(gpio); 629 630 omgpio_recalc_interrupts(sc); 631 632 restore_interrupts(psw); 633 634 return (ih); 635 } 636 637 void 638 omgpio_intr_disestablish(struct omgpio_softc *sc, void *cookie) 639 { 640 int psw; 641 struct intrhand *ih = cookie; 642 struct omgpio_softc *sc = omgpio_cd.cd_devs[GPIO_PIN_TO_INST(ih->ih_gpio)]; 643 int gpio = ih->ih_gpio; 644 psw = disable_interrupts(PSR_I); 645 646 ih = sc->sc_handlers[GPIO_PIN_TO_OFFSET(gpio)]; 647 sc->sc_handlers[GPIO_PIN_TO_OFFSET(gpio)] = NULL; 648 649 evcount_detach(&ih->ih_count); 650 651 free(ih, M_DEVBUF, 0); 652 653 omgpio_intr_level(gpio, IST_NONE); 654 omgpio_intr_mask(gpio); 655 omgpio_clear_intr(gpio); /* Just in case */ 656 657 omgpio_recalc_interrupts(sc); 658 659 restore_interrupts(psw); 660 } 661 662 int 663 omgpio_irq(void *v) 664 { 665 struct omgpio_softc *sc = v; 666 u_int32_t pending; 667 struct intrhand *ih; 668 int bit; 669 670 pending = READ4(sc, omgpio.irqstatus0); 671 672 while (pending != 0) { 673 bit = ffs(pending) - 1; 674 ih = sc->sc_handlers[bit]; 675 676 if (ih != NULL) { 677 if (ih->ih_func(ih->ih_arg)) 678 ih->ih_count.ec_count++; 679 omgpio_clear_intr(ih->ih_gpio); 680 } else { 681 panic("omgpio: irq fired no handler, gpio %x %x %x", 682 sc->sc_dev.dv_unit * 32 + bit, pending, 683 READ4(sc, omgpio.irqstatus0) 684 685 ); 686 } 687 pending &= ~(1 << bit); 688 } 689 return 1; 690 } 691 692 int 693 omgpio_irq_dummy(void *v) 694 { 695 return 0; 696 } 697 698 void 699 omgpio_recalc_interrupts(struct omgpio_softc *sc) 700 { 701 struct intrhand *ih; 702 int max = IPL_NONE; 703 int min = IPL_HIGH; 704 int i; 705 706 for (i = 0; i < GPIO_NUM_PINS; i++) { 707 ih = sc->sc_handlers[i]; 708 if (ih != NULL) { 709 if (ih->ih_ipl > max) 710 max = ih->ih_ipl; 711 712 if (ih->ih_ipl < min) 713 min = ih->ih_ipl; 714 } 715 } 716 if (max == IPL_NONE) 717 min = IPL_NONE; 718 719 #if 0 720 if ((max == IPL_NONE || max != sc->sc_max_il) && sc->sc_ih_h != NULL) 721 arm_intr_disestablish_fdt(sc->sc_ih_h); 722 723 if (max != IPL_NONE && max != sc->sc_max_il) { 724 sc->sc_ih_h = arm_intr_establish_fdt(sc->sc_node, max, omgpio_irq, 725 sc, NULL); 726 } 727 #else 728 if (sc->sc_ih_h != NULL) 729 arm_intr_disestablish_fdt(sc->sc_ih_h); 730 731 if (max != IPL_NONE) { 732 sc->sc_ih_h = arm_intr_establish_fdt(sc->sc_node, max, omgpio_irq, 733 sc, NULL); 734 } 735 #endif 736 737 sc->sc_max_il = max; 738 739 if (sc->sc_ih_l != NULL) 740 arm_intr_disestablish_fdt(sc->sc_ih_l); 741 742 if (max != min) { 743 sc->sc_ih_h = arm_intr_establish_fdt(sc->sc_node, min, 744 omgpio_irq_dummy, sc, NULL); 745 } 746 sc->sc_min_il = min; 747 } 748 #endif 749