1/* $NetBSD: igpio.c,v 1.5 2023/01/07 03:27:01 msaitoh Exp $ */ 2 3/* 4 * Copyright (c) 2021,2022 Emmanuel Dreyfus 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 20 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 23 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 25 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 26 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29#include <sys/cdefs.h> 30 31#include <sys/param.h> 32#include <sys/bus.h> 33#include <sys/device.h> 34#include <sys/intr.h> 35#include <sys/systm.h> 36#include <sys/kernel.h> 37#include <sys/kmem.h> 38#include <sys/endian.h> 39#include <sys/gpio.h> 40 41#include <dev/gpio/gpiovar.h> 42#include "gpio.h" 43 44#include <dev/ic/igpiovar.h> 45#include <dev/ic/igpioreg.h> 46 47struct igpio_intr { 48 int (*ii_func)(void *); 49 void *ii_arg; 50 struct igpio_bank *ii_bank; 51 int ii_pin; 52}; 53 54struct igpio_bank { 55 int ib_barno; 56 int ib_revid; 57 int ib_cap; 58 int ib_padbar; 59 struct igpio_bank_setup *ib_setup; 60 struct igpio_softc *ib_sc; 61 struct igpio_intr *ib_intr; 62 kmutex_t ib_mtx; 63}; 64 65 66static int igpio_debug = 0; 67#define DPRINTF(x) if (igpio_debug) printf x; 68 69static char * 70igpio_padcfg0_print(uint32_t val, int idx) 71{ 72 uint32_t rxev, pmode; 73 static char buf0[256]; 74 static char buf1[256]; 75 char *buf = (idx % 2) ? &buf0[0] : &buf1[0]; 76 size_t len = sizeof(buf0) - 1; 77 size_t wr = 0; 78 uint32_t unknown_bits = 79 __BITS(3,7)|__BITS(14,16)|__BITS(21,22)|__BITS(27,31); 80 int b; 81 82 rxev = 83 (val & IGPIO_PADCFG0_RXEVCFG_MASK) >> IGPIO_PADCFG0_RXEVCFG_SHIFT; 84 wr += snprintf(buf + wr, len - wr, "rxev "); 85 switch (rxev) { 86 case IGPIO_PADCFG0_RXEVCFG_LEVEL: 87 wr += snprintf(buf + wr, len - wr, "level"); 88 break; 89 case IGPIO_PADCFG0_RXEVCFG_EDGE: 90 wr += snprintf(buf + wr, len - wr, "edge"); 91 break; 92 case IGPIO_PADCFG0_RXEVCFG_DISABLED: 93 wr += snprintf(buf + wr, len - wr, "disabled"); 94 break; 95 case IGPIO_PADCFG0_RXEVCFG_EDGE_BOTH: 96 wr += snprintf(buf + wr, len - wr, "edge both"); 97 break; 98 default: 99 break; 100 } 101 102 if (val & IGPIO_PADCFG0_PREGFRXSEL) 103 wr += snprintf(buf + wr, len - wr, ", pregfrxsel"); 104 105 if (val & IGPIO_PADCFG0_RXINV) 106 wr += snprintf(buf + wr, len - wr, ", rxinv"); 107 108 if (val & (IGPIO_PADCFG0_GPIROUTIOXAPIC|IGPIO_PADCFG0_GPIROUTSCI| 109 IGPIO_PADCFG0_GPIROUTSMI|IGPIO_PADCFG0_GPIROUTNMI)) { 110 wr += snprintf(buf + wr, len - wr, ", gpirout"); 111 112 if (val & IGPIO_PADCFG0_GPIROUTIOXAPIC) 113 wr += snprintf(buf + wr, len - wr, " ioxapic"); 114 115 if (val & IGPIO_PADCFG0_GPIROUTSCI) 116 wr += snprintf(buf + wr, len - wr, " sci"); 117 118 if (val & IGPIO_PADCFG0_GPIROUTSMI) 119 wr += snprintf(buf + wr, len - wr, " smi"); 120 121 if (val & IGPIO_PADCFG0_GPIROUTNMI) 122 wr += snprintf(buf + wr, len - wr, " nmi"); 123 } 124 125 pmode = 126 (val & IGPIO_PADCFG0_PMODE_MASK) >> IGPIO_PADCFG0_PMODE_SHIFT; 127 switch (pmode) { 128 case IGPIO_PADCFG0_PMODE_GPIO: 129 wr += snprintf(buf + wr, len - wr, ", pmode gpio"); 130 break; 131 default: 132 wr += snprintf(buf + wr, len - wr, ", pmode %d", pmode); 133 break; 134 } 135 136 if (val & IGPIO_PADCFG0_GPIORXDIS) 137 wr += snprintf(buf + wr, len - wr, ", rx disabled"); 138 else 139 wr += snprintf(buf + wr, len - wr, ", rx %d", 140 !!(val & IGPIO_PADCFG0_GPIORXSTATE)); 141 142 if (val & IGPIO_PADCFG0_GPIOTXDIS) 143 wr += snprintf(buf + wr, len - wr, ", tx disabled"); 144 else 145 wr += snprintf(buf + wr, len - wr, ", tx %d", 146 !!(val & IGPIO_PADCFG0_GPIOTXSTATE)); 147 148 if (val & unknown_bits) { 149 wr += snprintf(buf + wr, len - wr, ", unknown bits"); 150 for (b = 0; b < 32; b++) { 151 if (!(__BIT(b) & unknown_bits & val)) 152 continue; 153 wr += snprintf(buf + wr, len - wr, " %d", b); 154 } 155 } 156 157 return buf; 158} 159 160 161static struct igpio_bank_setup * 162igpio_find_bank_setup(struct igpio_bank *ib, int barno) 163{ 164 struct igpio_bank_setup *ibs; 165 166 for (ibs = igpio_bank_setup; ibs->ibs_acpi_hid; ibs++) { 167 if (strcmp(ib->ib_sc->sc_acpi_hid, ibs->ibs_acpi_hid) != 0) 168 continue; 169 if (ibs->ibs_barno != barno) 170 continue; 171 172 return ibs; 173 } 174 175 return NULL; 176} 177 178static struct igpio_bank * 179igpio_find_bank(struct igpio_softc *sc, int pin) 180{ 181 int i; 182 struct igpio_bank *ib; 183 184 for (i = 0; i < sc->sc_nbar; i++) { 185 ib = &sc->sc_banks[i]; 186 if (pin >= ib->ib_setup->ibs_first_pin && 187 pin <= ib->ib_setup->ibs_last_pin) 188 goto out; 189 } 190 191 ib = NULL; 192out: 193 return ib; 194} 195 196static int 197igpio_bank_pin(struct igpio_bank *ib, int pin) 198{ 199 return pin - ib->ib_setup->ibs_first_pin; 200} 201 202#if 0 203static void 204igpio_hexdump(struct igpio_softc *sc, int n) 205{ 206 int i, j; 207 uint8_t v; 208 size_t len = MIN(sc->sc_length[n], 2048); 209 210 printf("bar %d\n", n); 211 for (j = 0; j < len; j += 16) { 212 printf("%04x ", j); 213 for (i = 0; i < 16 && i + j < len; i++) { 214 v = bus_space_read_1(sc->sc_bst, sc->sc_bsh[n], i + j); 215 printf("%02x ", v); 216 } 217 printf("\n"); 218 } 219} 220#endif 221 222void 223igpio_attach(struct igpio_softc *sc) 224{ 225 device_t self = sc->sc_dev; 226 int i,j; 227 struct gpiobus_attach_args gba; 228 int success = 0; 229 230 sc->sc_banks = 231 kmem_zalloc(sizeof(*sc->sc_banks) * sc->sc_nbar, KM_SLEEP); 232 233 sc->sc_npins = 0; 234 235 for (i = 0; i < sc->sc_nbar; i++) { 236 struct igpio_bank *ib = &sc->sc_banks[i]; 237 struct igpio_bank_setup *ibs; 238 bus_size_t reg; 239 uint32_t val; 240 int error; 241 int npins; 242 243 ib->ib_barno = i; 244 ib->ib_sc = sc; 245 246 mutex_init(&ib->ib_mtx, MUTEX_DEFAULT, IPL_VM); 247 248 error = bus_space_map(sc->sc_bst, sc->sc_base[i], 249 sc->sc_length[i], 0, &sc->sc_bsh[i]); 250 if (error) { 251 aprint_error_dev(self, "couldn't map registers\n"); 252 goto out; 253 } 254 255 reg = IGPIO_REVID; 256 val = bus_space_read_4(sc->sc_bst, sc->sc_bsh[i], reg); 257 if (val == 0) { 258 aprint_error_dev(self, "couldn't find revid\n"); 259 goto out; 260 } 261 ib->ib_revid = val >> 16; 262 263 DPRINTF(("revid[%d] = #%x\n", i, ib->ib_revid)); 264 265 if (ib->ib_revid > 0x94) { 266 ib->ib_cap |= IGPIO_PINCTRL_FEATURE_DEBOUNCE; 267 ib->ib_cap |= IGPIO_PINCTRL_FEATURE_1K_PD; 268 } 269 270 reg = IGPIO_CAPLIST; 271 do { 272 /* higher 16 bits: value, lower 16 bits, next reg */ 273 val = bus_space_read_4(sc->sc_bst, sc->sc_bsh[i], reg); 274 275 reg = val & 0xffff; 276 val = val >> 16; 277 278 switch (val) { 279 case IGPIO_CAPLIST_ID_GPIO_HW_INFO: 280 ib->ib_cap |= 281 IGPIO_PINCTRL_FEATURE_GPIO_HW_INFO; 282 break; 283 case IGPIO_CAPLIST_ID_PWM: 284 ib->ib_cap |= IGPIO_PINCTRL_FEATURE_PWM; 285 break; 286 case IGPIO_CAPLIST_ID_BLINK: 287 ib->ib_cap |= IGPIO_PINCTRL_FEATURE_BLINK; 288 break; 289 case IGPIO_CAPLIST_ID_EXP: 290 ib->ib_cap |= IGPIO_PINCTRL_FEATURE_EXP; 291 break; 292 default: 293 break; 294 } 295 } while (reg); 296 DPRINTF(("cap[%d] = #%x\n", i, ib->ib_cap)); 297 298 reg = IGPIO_PADBAR; 299 val = bus_space_read_4(sc->sc_bst, sc->sc_bsh[i], reg); 300 ib->ib_padbar = val; 301 DPRINTF(("padbar[%d] = #%x\n", i, ib->ib_padbar)); 302 if (ib->ib_padbar > sc->sc_length[i]) { 303 printf("PADBAR = #%x higher than max #%lx\n", 304 ib->ib_padbar, sc->sc_length[i]); 305 goto out; 306 } 307 308 ib->ib_setup = igpio_find_bank_setup(ib, i); 309 if (ib->ib_setup == NULL) { 310 printf("Missing BAR %d\n", i); 311 goto out; 312 } 313 314 ibs = ib->ib_setup; 315 316 DPRINTF(("setup[%d] = " 317 "{ barno = %d, first_pin = %d, last_pin = %d }\n", 318 i, ibs->ibs_barno, ibs->ibs_first_pin, ibs->ibs_last_pin)); 319 320 npins = 1 + ibs->ibs_last_pin - ibs->ibs_first_pin; 321 322 ib->ib_intr = 323 kmem_zalloc(sizeof(*ib->ib_intr) * npins, KM_SLEEP); 324 325 sc->sc_npins += npins; 326 } 327 328 if (sc->sc_npins < 1 || sc->sc_npins > 4096) { 329 printf("Unexpected pin count %d\n", sc->sc_npins); 330 goto out; 331 } 332 333 sc->sc_pins = 334 kmem_zalloc(sizeof(*sc->sc_pins) * sc->sc_npins, KM_SLEEP); 335 336 for (j = 0; j < sc->sc_npins; j++) { 337 sc->sc_pins[j].pin_num = j; 338 sc->sc_pins[j].pin_caps = 339 GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | GPIO_PIN_INOUT | 340 GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN | GPIO_PIN_INVIN; 341 sc->sc_pins[j].pin_intrcaps = 342 GPIO_INTR_POS_EDGE | GPIO_INTR_NEG_EDGE | 343 GPIO_INTR_DOUBLE_EDGE | GPIO_INTR_HIGH_LEVEL | 344 GPIO_INTR_LOW_LEVEL | GPIO_INTR_MPSAFE; 345 sc->sc_pins[j].pin_state = igpio_pin_read(sc, j); 346 } 347 348 sc->sc_gc.gp_cookie = sc; 349 sc->sc_gc.gp_pin_read = igpio_pin_read; 350 sc->sc_gc.gp_pin_write = igpio_pin_write; 351 sc->sc_gc.gp_pin_ctl = igpio_pin_ctl; 352 sc->sc_gc.gp_intr_establish = igpio_intr_establish; 353 sc->sc_gc.gp_intr_disestablish = igpio_intr_disestablish; 354 sc->sc_gc.gp_intr_str = igpio_intr_str; 355 356 memset(&gba, 0, sizeof(gba)); 357 gba.gba_gc = &sc->sc_gc; 358 gba.gba_pins = sc->sc_pins; 359 gba.gba_npins = sc->sc_npins; 360 361#if NGPIO > 0 362 config_found(sc->sc_dev, &gba, gpiobus_print, CFARGS_NONE); 363#endif 364 365 success = 1; 366out: 367 if (!success) 368 igpio_detach(sc); 369 370 return; 371} 372 373void 374igpio_detach(struct igpio_softc *sc) 375{ 376 int i; 377 378 for (i = 0; i < sc->sc_nbar; i++) { 379 struct igpio_bank *ib = &sc->sc_banks[i]; 380 struct igpio_bank_setup *ibs = ib->ib_setup; 381 int npins = 1 + ibs->ibs_last_pin - ibs->ibs_first_pin; 382 383 if (ib->ib_intr != NULL) { 384 kmem_free(ib->ib_intr, sizeof(*ib->ib_intr) * npins); 385 ib->ib_intr = NULL; 386 } 387 } 388 389 if (sc->sc_pins != NULL) { 390 kmem_free(sc->sc_pins, sizeof(*sc->sc_pins) * sc->sc_npins); 391 sc->sc_pins = NULL; 392 } 393 394 if (sc->sc_banks != NULL) { 395 kmem_free(sc->sc_banks, sizeof(*sc->sc_banks) * sc->sc_nbar); 396 sc->sc_banks = NULL; 397 } 398 399 return; 400} 401 402static bus_addr_t 403igpio_pincfg(struct igpio_bank *ib, int pin, int reg) 404{ 405 int nregs = (ib->ib_cap & IGPIO_PINCTRL_FEATURE_DEBOUNCE) ? 4 : 2; 406 bus_addr_t pincfg; 407 408 pincfg = ib->ib_padbar + reg + (pin * nregs * 4); 409#if 0 410 DPRINTF(("%s bar %d pin %d reg #%x pincfg = %p\n", 411 __func__, ib->ib_barno, pin, reg, (void *)pincfg)); 412#endif 413 return pincfg; 414} 415 416#if notyet 417static struct igpio_pin_group * 418igpio_find_group(struct igpio_bank *ib, int pin) 419{ 420 struct igpio_bank_setup *ibs = ib->ib_setup; 421 struct igpio_pin_group *found_ipg = NULL; 422 struct igpio_pin_group *ipg; 423 424 if (pin > ibs->ibs_last_pin) { 425 DPRINTF(("%s: barno %d, pin = %d > past pin = %d\n", __func__, 426 ibs->ibs_barno, pin, ibs->ibs_last_pin)); 427 return NULL; 428 } 429 430 for (ipg = igpio_pin_group; ipg->ipg_acpi_hid; ipg++) { 431 if (strcmp(ipg->ipg_acpi_hid, ibs->ibs_acpi_hid) != 0) 432 continue; 433 434 if (pin > ipg->ipg_first_pin) { 435 found_ipg = ipg; 436 continue; 437 } 438 } 439 440 return found_ipg; 441} 442 443static bus_addr_t 444igpio_groupcfg(struct igpio_bank *ib, int pin) 445{ 446 struct igpio_bank_setup *ibs = ib->ib_setup; 447 struct igpio_pin_group *ipg; 448 bus_addr_t groupcfg; 449 450 if ((ipg = igpio_find_group(ib, pin)) == NULL) 451 return (bus_addr_t)NULL; 452 453 groupcfg = ib->ib_padbar 454 + (ipg->ipg_groupno * 4) 455 + (pin - ipg->ipg_first_pin) / 2; 456 457 DPRINTF(("%s: barno %d, pin = %d, found group %d \"%s\", cfg %p\n", \ 458 __func__, ibs->ibs_barno, pin, ipg->ipg_groupno, \ 459 ipg->ipg_name, (void *)groupcfg)); 460 461 return groupcfg; 462} 463#endif 464 465 466int 467igpio_pin_read(void *priv, int pin) 468{ 469 struct igpio_softc *sc = priv; 470 struct igpio_bank *ib = igpio_find_bank(sc, pin); 471 bus_addr_t cfg0; 472 uint32_t val; 473 474 pin = igpio_bank_pin(ib, pin); 475 cfg0 = igpio_pincfg(ib, pin, IGPIO_PADCFG0); 476 477 mutex_enter(&ib->ib_mtx); 478 479 val = bus_space_read_4(sc->sc_bst, sc->sc_bsh[ib->ib_barno], cfg0); 480 DPRINTF(("%s: bar %d pin %d val #%x (%s)\n", __func__, 481 ib->ib_barno, pin, val, igpio_padcfg0_print(val, 0))); 482 483 if (val & IGPIO_PADCFG0_GPIOTXDIS) 484 val = (val & IGPIO_PADCFG0_GPIORXSTATE) ? 1 : 0; 485 else 486 val = (val & IGPIO_PADCFG0_GPIOTXSTATE) ? 1 : 0; 487 488 mutex_exit(&ib->ib_mtx); 489 490 return val; 491} 492 493void 494igpio_pin_write(void *priv, int pin, int value) 495{ 496 struct igpio_softc *sc = priv; 497 struct igpio_bank *ib = igpio_find_bank(sc, pin); 498 bus_addr_t cfg0; 499 uint32_t val, newval; 500 501 pin = igpio_bank_pin(ib, pin); 502 cfg0 = igpio_pincfg(ib, pin, IGPIO_PADCFG0); 503 504 mutex_enter(&ib->ib_mtx); 505 506 val = bus_space_read_4(sc->sc_bst, sc->sc_bsh[ib->ib_barno], cfg0); 507 508 if (value) 509 newval = val | IGPIO_PADCFG0_GPIOTXSTATE; 510 else 511 newval = val & ~IGPIO_PADCFG0_GPIOTXSTATE; 512 513 DPRINTF(("%s: bar %d pin %d value %d val #%x (%s) -> #%x (%s)\n", 514 __func__, ib->ib_barno, pin, value, 515 val, igpio_padcfg0_print(val, 0), 516 newval, igpio_padcfg0_print(newval, 1))); 517 518 bus_space_write_4(sc->sc_bst, sc->sc_bsh[ib->ib_barno], cfg0, newval); 519 520 mutex_exit(&ib->ib_mtx); 521 522 return; 523} 524 525void 526igpio_pin_ctl(void *priv, int pin, int flags) 527{ 528 struct igpio_softc *sc = priv; 529 struct igpio_bank *ib = igpio_find_bank(sc, pin); 530 bus_addr_t cfg0, cfg1; 531 uint32_t val0, newval0; 532 uint32_t val1, newval1; 533 534 pin = igpio_bank_pin(ib, pin); 535 cfg0 = igpio_pincfg(ib, pin, IGPIO_PADCFG0); 536 cfg1 = igpio_pincfg(ib, pin, IGPIO_PADCFG1); 537 538 mutex_enter(&ib->ib_mtx); 539 540 val0 = bus_space_read_4(sc->sc_bst, sc->sc_bsh[ib->ib_barno], cfg0); 541 val1 = bus_space_read_4(sc->sc_bst, sc->sc_bsh[ib->ib_barno], cfg1); 542 543 newval0 = val0; 544 newval1 = val1; 545 546 newval0 &= ~IGPIO_PADCFG0_PMODE_MASK; 547 newval0 |= IGPIO_PADCFG0_PMODE_GPIO; 548 549 newval0 |= IGPIO_PADCFG0_GPIORXDIS; 550 newval0 |= IGPIO_PADCFG0_GPIOTXDIS; 551 552 newval0 &= ~(IGPIO_PADCFG0_GPIROUTIOXAPIC | IGPIO_PADCFG0_GPIROUTSCI); 553 newval0 &= ~(IGPIO_PADCFG0_GPIROUTSMI | IGPIO_PADCFG0_GPIROUTNMI); 554 555 if (flags & GPIO_PIN_INPUT) { 556 newval0 &= ~IGPIO_PADCFG0_GPIORXDIS; 557 newval0 |= IGPIO_PADCFG0_GPIOTXDIS; 558 } 559 560 if (flags & GPIO_PIN_OUTPUT) { 561 newval0 &= ~IGPIO_PADCFG0_GPIOTXDIS; 562 newval0 |= IGPIO_PADCFG0_GPIORXDIS; 563 } 564 565 if (flags & GPIO_PIN_INOUT) { 566 newval0 &= ~IGPIO_PADCFG0_GPIOTXDIS; 567 newval0 &= ~IGPIO_PADCFG0_GPIORXDIS; 568 } 569 570 if (flags & GPIO_PIN_INVIN) 571 newval0 |= IGPIO_PADCFG0_RXINV; 572 else 573 newval0 &= ~IGPIO_PADCFG0_RXINV; 574 575 newval1 &= ~IGPIO_PADCFG1_TERM_MASK; 576 if (flags & GPIO_PIN_PULLUP) { 577 newval1 |= IGPIO_PADCFG1_TERM_UP; 578 newval1 |= IGPIO_PADCFG1_TERM_5K; 579 } 580 581 if (flags & GPIO_PIN_PULLDOWN) { 582 newval1 &= ~IGPIO_PADCFG1_TERM_UP; 583 newval1 |= IGPIO_PADCFG1_TERM_5K; 584 } 585 586 DPRINTF(("%s: bar %d pin %d flags #%x val0 #%x (%s) -> #%x (%s), " 587 "val1 #%x -> #%x\n", __func__, ib->ib_barno, pin, flags, 588 val0, igpio_padcfg0_print(val0, 0), 589 newval0, igpio_padcfg0_print(newval0, 1), 590 val1, newval1)); 591 592 bus_space_write_4(sc->sc_bst, sc->sc_bsh[ib->ib_barno], cfg0, newval0); 593 bus_space_write_4(sc->sc_bst, sc->sc_bsh[ib->ib_barno], cfg1, newval1); 594 595 mutex_exit(&ib->ib_mtx); 596 597 return; 598} 599 600void * 601igpio_intr_establish(void *priv, int pin, int ipl, int irqmode, 602 int (*func)(void *), void *arg) 603{ 604 struct igpio_softc *sc = priv; 605 struct igpio_bank *ib = igpio_find_bank(sc, pin); 606 bus_addr_t cfg0; 607 uint32_t val, newval; 608 struct igpio_intr *ii; 609 610 pin = igpio_bank_pin(ib, pin); 611 cfg0 = igpio_pincfg(ib, pin, IGPIO_PADCFG0); 612 613 ii = &ib->ib_intr[pin]; 614 ii->ii_func = func; 615 ii->ii_arg = arg; 616 ii->ii_pin = pin; 617 ii->ii_bank = ib; 618 619 mutex_enter(&ib->ib_mtx); 620 621 val = bus_space_read_4(sc->sc_bst, sc->sc_bsh[ib->ib_barno], cfg0); 622 newval = val; 623 624 newval &= ~IGPIO_PADCFG0_PMODE_MASK; 625 newval |= IGPIO_PADCFG0_PMODE_GPIO; 626 627 newval &= ~IGPIO_PADCFG0_GPIORXDIS; 628 newval |= IGPIO_PADCFG0_GPIOTXDIS; 629 630 newval |= (IGPIO_PADCFG0_GPIROUTIOXAPIC | IGPIO_PADCFG0_GPIROUTSCI); 631 newval |= (IGPIO_PADCFG0_GPIROUTSMI | IGPIO_PADCFG0_GPIROUTNMI); 632 633 newval &= ~IGPIO_PADCFG0_RXINV; 634 newval &= ~IGPIO_PADCFG0_RXEVCFG_EDGE; 635 newval &= ~IGPIO_PADCFG0_RXEVCFG_LEVEL; 636 newval &= ~IGPIO_PADCFG0_RXEVCFG_DISABLED; 637 638 switch (irqmode & GPIO_INTR_EDGE_MASK) { 639 case GPIO_INTR_DOUBLE_EDGE: 640 newval |= IGPIO_PADCFG0_RXEVCFG_EDGE_BOTH; 641 break; 642 case GPIO_INTR_NEG_EDGE: 643 newval |= IGPIO_PADCFG0_RXEVCFG_EDGE; 644 newval |= IGPIO_PADCFG0_RXINV; 645 break; 646 case GPIO_INTR_POS_EDGE: 647 newval |= IGPIO_PADCFG0_RXEVCFG_EDGE; 648 break; 649 default: 650 switch (irqmode & GPIO_INTR_LEVEL_MASK) { 651 case GPIO_INTR_HIGH_LEVEL: 652 newval |= IGPIO_PADCFG0_RXEVCFG_LEVEL; 653 break; 654 case GPIO_INTR_LOW_LEVEL: 655 newval |= IGPIO_PADCFG0_RXEVCFG_LEVEL; 656 newval |= IGPIO_PADCFG0_RXINV; 657 break; 658 default: 659 newval |= IGPIO_PADCFG0_RXEVCFG_DISABLED; 660 break; 661 } 662 break; 663 } 664 665 666 DPRINTF(("%s: bar %d pin %d val #%x (%s) -> #%x (%s)\n", 667 __func__, ib->ib_barno, pin, 668 val, igpio_padcfg0_print(val, 0), 669 newval, igpio_padcfg0_print(newval, 1))); 670 671 bus_space_write_4(sc->sc_bst, sc->sc_bsh[ib->ib_barno], cfg0, newval); 672 673 mutex_exit(&ib->ib_mtx); 674 675 return ii; 676} 677 678void 679igpio_intr_disestablish(void *priv, void *ih) 680{ 681 struct igpio_softc *sc = priv; 682 struct igpio_bank *ib; 683 struct igpio_intr *ii = ih; 684 int pin; 685 bus_addr_t cfg0; 686 uint32_t val, newval; 687 688 if (ih == NULL) 689 return; 690 691 pin = ii->ii_pin; 692 ib = igpio_find_bank(sc, pin); 693 pin = igpio_bank_pin(ib, pin); 694 cfg0 = igpio_pincfg(ib, pin, IGPIO_PADCFG0); 695 696 mutex_enter(&ib->ib_mtx); 697 698 val = bus_space_read_4(sc->sc_bst, sc->sc_bsh[ib->ib_barno], cfg0); 699 newval = val; 700 701 newval &= ~IGPIO_PADCFG0_PMODE_MASK; 702 newval |= IGPIO_PADCFG0_PMODE_GPIO; 703 704 newval &= ~(IGPIO_PADCFG0_GPIROUTIOXAPIC | IGPIO_PADCFG0_GPIROUTSCI); 705 newval &= ~(IGPIO_PADCFG0_GPIROUTSMI | IGPIO_PADCFG0_GPIROUTNMI); 706 707 DPRINTF(("%s: bar %d pin %d val #%x (%s) -> #%x (%s)\n", \ 708 __func__, ib->ib_barno, pin, 709 val, igpio_padcfg0_print(val, 0), 710 newval, igpio_padcfg0_print(newval, 1))); 711 712 bus_space_write_4(sc->sc_bst, sc->sc_bsh[ib->ib_barno], cfg0, newval); 713 714 mutex_exit(&ib->ib_mtx); 715 716 ii->ii_func = NULL; 717 ii->ii_arg = NULL; 718 719 return; 720} 721 722bool 723igpio_intr_str(void *priv, int pin, int irqmode, 724 char *buf, size_t buflen) 725{ 726 struct igpio_softc *sc = priv; 727 const char *name = device_xname(sc->sc_dev); 728 int rv; 729 730 rv = snprintf(buf, buflen, "%s pin %d", name, pin); 731 732 return (rv < buflen); 733} 734 735int 736igpio_intr(void *priv) 737{ 738 struct igpio_softc *sc = priv; 739 int i; 740 int ret = 0; 741 742 for (i = 0; i < sc->sc_nbar; i++) { 743 struct igpio_bank *ib = &sc->sc_banks[i]; 744 struct igpio_bank_setup *ibs = ib->ib_setup; 745 bus_space_handle_t bsh = sc->sc_bsh[i]; 746 struct igpio_pin_group *ipg; 747 748 mutex_enter(&ib->ib_mtx); 749 750 for (ipg = igpio_pin_group; ipg->ipg_acpi_hid; ipg++) { 751 int offset; 752 bus_addr_t is_reg; 753 bus_addr_t ie_reg; 754 uint32_t raised; 755 uint32_t pending; 756 uint32_t enabled; 757 int b; 758 759 if (strcmp(ipg->ipg_acpi_hid, 760 ibs->ibs_acpi_hid) != 0) 761 continue; 762 763 offset = ib->ib_padbar + ipg->ipg_groupno * 4; 764 is_reg = offset + ibs->ibs_gpi_is; 765 ie_reg = offset + ibs->ibs_gpi_ie; 766 767 raised = bus_space_read_4(sc->sc_bst, bsh, is_reg); 768 enabled = bus_space_read_4(sc->sc_bst, bsh, ie_reg); 769 770 /* 771 * find pins for which interrupt is pending 772 * and enabled 773 */ 774 pending = raised & enabled; 775 776 for (b = 0; b < 32; b++) { 777 int pin; 778 int (*func)(void *); 779 void *arg; 780 781 if ((pending & (1 << b)) == 0) 782 continue; 783 784 pin = ipg->ipg_first_pin + b; 785 func = ib->ib_intr[pin].ii_func; 786 arg = ib->ib_intr[pin].ii_arg; 787 788 /* XXX ack intr, handled or not? */ 789 raised &= ~(1 << b); 790 791 if (func == NULL) 792 continue; 793 794 ret |= func(arg); 795 } 796 797 bus_space_write_4(sc->sc_bst, bsh, is_reg, raised); 798 799 } 800 801 mutex_exit(&ib->ib_mtx); 802 803 } 804 805 return ret; 806} 807