1 /* $NetBSD: sunxi_gpio.c,v 1.38 2022/06/28 05:19:03 skrll Exp $ */ 2 3 /*- 4 * Copyright (c) 2017 Jared McNeill <jmcneill@invisible.ca> 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 AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #include "opt_soc.h" 30 31 #include <sys/cdefs.h> 32 __KERNEL_RCSID(0, "$NetBSD: sunxi_gpio.c,v 1.38 2022/06/28 05:19:03 skrll Exp $"); 33 34 #include <sys/param.h> 35 #include <sys/bus.h> 36 #include <sys/device.h> 37 #include <sys/intr.h> 38 #include <sys/systm.h> 39 #include <sys/mutex.h> 40 #include <sys/kmem.h> 41 #include <sys/gpio.h> 42 #include <sys/bitops.h> 43 #include <sys/lwp.h> 44 45 #include <dev/fdt/fdtvar.h> 46 #include <dev/gpio/gpiovar.h> 47 48 #include <arm/sunxi/sunxi_gpio.h> 49 50 #define SUNXI_GPIO_MAX_EINT_BANK 5 51 #define SUNXI_GPIO_MAX_EINT 32 52 53 #define SUNXI_GPIO_MAX_BANK 26 54 55 #define SUNXI_GPIO_PORT(port) (0x24 * (port)) 56 #define SUNXI_GPIO_CFG(port, pin) (SUNXI_GPIO_PORT(port) + 0x00 + (0x4 * ((pin) / 8))) 57 #define SUNXI_GPIO_CFG_PINMASK(pin) (0x7U << (((pin) % 8) * 4)) 58 #define SUNXI_GPIO_DATA(port) (SUNXI_GPIO_PORT(port) + 0x10) 59 #define SUNXI_GPIO_DRV(port, pin) (SUNXI_GPIO_PORT(port) + 0x14 + (0x4 * ((pin) / 16))) 60 #define SUNXI_GPIO_DRV_PINMASK(pin) (0x3U << (((pin) % 16) * 2)) 61 #define SUNXI_GPIO_PULL(port, pin) (SUNXI_GPIO_PORT(port) + 0x1c + (0x4 * ((pin) / 16))) 62 #define SUNXI_GPIO_PULL_DISABLE 0 63 #define SUNXI_GPIO_PULL_UP 1 64 #define SUNXI_GPIO_PULL_DOWN 2 65 #define SUNXI_GPIO_PULL_PINMASK(pin) (0x3U << (((pin) % 16) * 2)) 66 #define SUNXI_GPIO_INT_CFG(bank, eint) (0x200 + (0x20 * (bank)) + (0x4 * ((eint) / 8))) 67 #define SUNXI_GPIO_INT_MODEMASK(eint) (0xfU << (((eint) % 8) * 4)) 68 #define SUNXI_GPIO_INT_MODE_POS_EDGE 0x0 69 #define SUNXI_GPIO_INT_MODE_NEG_EDGE 0x1 70 #define SUNXI_GPIO_INT_MODE_HIGH_LEVEL 0x2 71 #define SUNXI_GPIO_INT_MODE_LOW_LEVEL 0x3 72 #define SUNXI_GPIO_INT_MODE_DOUBLE_EDGE 0x4 73 #define SUNXI_GPIO_INT_CTL(bank) (0x210 + 0x20 * (bank)) 74 #define SUNXI_GPIO_INT_STATUS(bank) (0x214 + 0x20 * (bank)) 75 #define SUNXI_GPIO_INT_DEBOUNCE(bank) (0x218 + 0x20 * (bank)) 76 #define SUNXI_GPIO_INT_DEBOUNCE_CLK_PRESCALE __BITS(6,4) 77 #define SUNXI_GPIO_INT_DEBOUNCE_CLK_SEL __BIT(0) 78 #define SUNXI_GPIO_GRP_CONFIG(bank) (0x300 + 0x4 * (bank)) 79 #define SUNXI_GPIO_GRP_IO_BIAS_CONFIGMASK 0xf 80 81 static const struct device_compatible_entry compat_data[] = { 82 #ifdef SOC_SUN4I_A10 83 { .compat = "allwinner,sun4i-a10-pinctrl", 84 .data = &sun4i_a10_padconf }, 85 #endif 86 #ifdef SOC_SUN5I_A13 87 { .compat = "allwinner,sun5i-a13-pinctrl", 88 .data = &sun5i_a13_padconf }, 89 { .compat = "nextthing,gr8-pinctrl", 90 .data = &sun5i_a13_padconf }, 91 #endif 92 #ifdef SOC_SUN6I_A31 93 { .compat = "allwinner,sun6i-a31-pinctrl", 94 .data = &sun6i_a31_padconf }, 95 { .compat = "allwinner,sun6i-a31-r-pinctrl", 96 .data = &sun6i_a31_r_padconf }, 97 #endif 98 #ifdef SOC_SUN7I_A20 99 { .compat = "allwinner,sun7i-a20-pinctrl", 100 .data = &sun7i_a20_padconf }, 101 #endif 102 #ifdef SOC_SUN8I_A83T 103 { .compat = "allwinner,sun8i-a83t-pinctrl", 104 .data = &sun8i_a83t_padconf }, 105 { .compat = "allwinner,sun8i-a83t-r-pinctrl", 106 .data = &sun8i_a83t_r_padconf }, 107 #endif 108 #ifdef SOC_SUN8I_H3 109 { .compat = "allwinner,sun8i-h3-pinctrl", 110 .data = &sun8i_h3_padconf }, 111 { .compat = "allwinner,sun8i-h3-r-pinctrl", 112 .data = &sun8i_h3_r_padconf }, 113 #endif 114 #ifdef SOC_SUN8I_V3S 115 { .compat = "allwinner,sun8i-v3s-pinctrl", 116 .data = &sun8i_v3s_padconf }, 117 #endif 118 #ifdef SOC_SUN9I_A80 119 { .compat = "allwinner,sun9i-a80-pinctrl", 120 .data = &sun9i_a80_padconf }, 121 { .compat = "allwinner,sun9i-a80-r-pinctrl", 122 .data = &sun9i_a80_r_padconf }, 123 #endif 124 #ifdef SOC_SUN50I_A64 125 { .compat = "allwinner,sun50i-a64-pinctrl", 126 .data = &sun50i_a64_padconf }, 127 { .compat = "allwinner,sun50i-a64-r-pinctrl", 128 .data = &sun50i_a64_r_padconf }, 129 #endif 130 #ifdef SOC_SUN50I_H5 131 { .compat = "allwinner,sun50i-h5-pinctrl", 132 .data = &sun8i_h3_padconf }, 133 { .compat = "allwinner,sun50i-h5-r-pinctrl", 134 .data = &sun8i_h3_r_padconf }, 135 #endif 136 #ifdef SOC_SUN50I_H6 137 { .compat = "allwinner,sun50i-h6-pinctrl", 138 .data = &sun50i_h6_padconf }, 139 { .compat = "allwinner,sun50i-h6-r-pinctrl", 140 .data = &sun50i_h6_r_padconf }, 141 #endif 142 DEVICE_COMPAT_EOL 143 }; 144 145 struct sunxi_gpio_eint { 146 int (*eint_func)(void *); 147 void *eint_arg; 148 bool eint_mpsafe; 149 int eint_bank; 150 int eint_num; 151 }; 152 153 struct sunxi_gpio_softc { 154 device_t sc_dev; 155 bus_space_tag_t sc_bst; 156 bus_space_handle_t sc_bsh; 157 int sc_phandle; 158 const struct sunxi_gpio_padconf *sc_padconf; 159 kmutex_t sc_lock; 160 161 struct gpio_chipset_tag sc_gp; 162 gpio_pin_t *sc_pins; 163 device_t sc_gpiodev; 164 165 struct fdtbus_regulator *sc_pin_supply[SUNXI_GPIO_MAX_BANK]; 166 167 u_int sc_eint_bank_max; 168 169 void *sc_ih; 170 struct sunxi_gpio_eint sc_eint[SUNXI_GPIO_MAX_EINT_BANK][SUNXI_GPIO_MAX_EINT]; 171 }; 172 173 struct sunxi_gpio_pin { 174 struct sunxi_gpio_softc *pin_sc; 175 const struct sunxi_gpio_pins *pin_def; 176 int pin_flags; 177 bool pin_actlo; 178 }; 179 180 #define GPIO_READ(sc, reg) \ 181 bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg)) 182 #define GPIO_WRITE(sc, reg, val) \ 183 bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val)) 184 185 static int sunxi_gpio_match(device_t, cfdata_t, void *); 186 static void sunxi_gpio_attach(device_t, device_t, void *); 187 188 CFATTACH_DECL_NEW(sunxi_gpio, sizeof(struct sunxi_gpio_softc), 189 sunxi_gpio_match, sunxi_gpio_attach, NULL, NULL); 190 191 static const struct sunxi_gpio_pins * 192 sunxi_gpio_lookup(struct sunxi_gpio_softc *sc, uint8_t port, uint8_t pin) 193 { 194 const struct sunxi_gpio_pins *pin_def; 195 u_int n; 196 197 for (n = 0; n < sc->sc_padconf->npins; n++) { 198 pin_def = &sc->sc_padconf->pins[n]; 199 if (pin_def->port == port && pin_def->pin == pin) 200 return pin_def; 201 } 202 203 return NULL; 204 } 205 206 static const struct sunxi_gpio_pins * 207 sunxi_gpio_lookup_byname(struct sunxi_gpio_softc *sc, const char *name) 208 { 209 const struct sunxi_gpio_pins *pin_def; 210 u_int n; 211 212 for (n = 0; n < sc->sc_padconf->npins; n++) { 213 pin_def = &sc->sc_padconf->pins[n]; 214 if (strcmp(pin_def->name, name) == 0) 215 return pin_def; 216 } 217 218 return NULL; 219 } 220 221 static int 222 sunxi_gpio_setfunc(struct sunxi_gpio_softc *sc, 223 const struct sunxi_gpio_pins *pin_def, const char *func) 224 { 225 uint32_t cfg; 226 u_int n; 227 228 KASSERT(mutex_owned(&sc->sc_lock)); 229 230 const bus_size_t cfg_reg = SUNXI_GPIO_CFG(pin_def->port, pin_def->pin); 231 const uint32_t cfg_mask = SUNXI_GPIO_CFG_PINMASK(pin_def->pin); 232 233 for (n = 0; n < SUNXI_GPIO_MAXFUNC; n++) { 234 if (pin_def->functions[n] == NULL) 235 continue; 236 if (strcmp(pin_def->functions[n], func) == 0) { 237 cfg = GPIO_READ(sc, cfg_reg); 238 cfg &= ~cfg_mask; 239 cfg |= __SHIFTIN(n, cfg_mask); 240 #ifdef SUNXI_GPIO_DEBUG 241 device_printf(sc->sc_dev, "P%c%02d cfg %08x -> %08x\n", 242 pin_def->port + 'A', pin_def->pin, GPIO_READ(sc, cfg_reg), cfg); 243 #endif 244 GPIO_WRITE(sc, cfg_reg, cfg); 245 return 0; 246 } 247 } 248 249 /* Function not found */ 250 device_printf(sc->sc_dev, "function '%s' not supported on P%c%02d\n", 251 func, pin_def->port + 'A', pin_def->pin); 252 253 return ENXIO; 254 } 255 256 static int 257 sunxi_gpio_setpull(struct sunxi_gpio_softc *sc, 258 const struct sunxi_gpio_pins *pin_def, int flags) 259 { 260 uint32_t pull; 261 262 KASSERT(mutex_owned(&sc->sc_lock)); 263 264 const bus_size_t pull_reg = SUNXI_GPIO_PULL(pin_def->port, pin_def->pin); 265 const uint32_t pull_mask = SUNXI_GPIO_PULL_PINMASK(pin_def->pin); 266 267 pull = GPIO_READ(sc, pull_reg); 268 pull &= ~pull_mask; 269 if (flags & GPIO_PIN_PULLUP) 270 pull |= __SHIFTIN(SUNXI_GPIO_PULL_UP, pull_mask); 271 else if (flags & GPIO_PIN_PULLDOWN) 272 pull |= __SHIFTIN(SUNXI_GPIO_PULL_DOWN, pull_mask); 273 else 274 pull |= __SHIFTIN(SUNXI_GPIO_PULL_DISABLE, pull_mask); 275 #ifdef SUNXI_GPIO_DEBUG 276 device_printf(sc->sc_dev, "P%c%02d pull %08x -> %08x\n", 277 pin_def->port + 'A', pin_def->pin, GPIO_READ(sc, pull_reg), pull); 278 #endif 279 GPIO_WRITE(sc, pull_reg, pull); 280 281 return 0; 282 } 283 284 static int 285 sunxi_gpio_setdrv(struct sunxi_gpio_softc *sc, 286 const struct sunxi_gpio_pins *pin_def, int drive_strength) 287 { 288 uint32_t drv; 289 290 KASSERT(mutex_owned(&sc->sc_lock)); 291 292 if (drive_strength < 10 || drive_strength > 40) 293 return EINVAL; 294 295 const bus_size_t drv_reg = SUNXI_GPIO_DRV(pin_def->port, pin_def->pin); 296 const uint32_t drv_mask = SUNXI_GPIO_DRV_PINMASK(pin_def->pin); 297 298 drv = GPIO_READ(sc, drv_reg); 299 drv &= ~drv_mask; 300 drv |= __SHIFTIN((drive_strength / 10) - 1, drv_mask); 301 #ifdef SUNXI_GPIO_DEBUG 302 device_printf(sc->sc_dev, "P%c%02d drv %08x -> %08x\n", 303 pin_def->port + 'A', pin_def->pin, GPIO_READ(sc, drv_reg), drv); 304 #endif 305 GPIO_WRITE(sc, drv_reg, drv); 306 307 return 0; 308 } 309 310 static int 311 sunxi_gpio_ctl(struct sunxi_gpio_softc *sc, const struct sunxi_gpio_pins *pin_def, 312 int flags) 313 { 314 KASSERT(mutex_owned(&sc->sc_lock)); 315 316 if (flags & GPIO_PIN_INPUT) 317 return sunxi_gpio_setfunc(sc, pin_def, "gpio_in"); 318 if (flags & GPIO_PIN_OUTPUT) 319 return sunxi_gpio_setfunc(sc, pin_def, "gpio_out"); 320 321 return EINVAL; 322 } 323 324 static void * 325 sunxi_gpio_acquire(device_t dev, const void *data, size_t len, int flags) 326 { 327 struct sunxi_gpio_softc * const sc = device_private(dev); 328 const struct sunxi_gpio_pins *pin_def; 329 struct sunxi_gpio_pin *gpin; 330 const u_int *gpio = data; 331 int error; 332 333 if (len != 16) 334 return NULL; 335 336 const uint8_t port = be32toh(gpio[1]) & 0xff; 337 const uint8_t pin = be32toh(gpio[2]) & 0xff; 338 const bool actlo = be32toh(gpio[3]) & 1; 339 340 pin_def = sunxi_gpio_lookup(sc, port, pin); 341 if (pin_def == NULL) 342 return NULL; 343 344 mutex_enter(&sc->sc_lock); 345 error = sunxi_gpio_ctl(sc, pin_def, flags); 346 mutex_exit(&sc->sc_lock); 347 348 if (error != 0) 349 return NULL; 350 351 gpin = kmem_zalloc(sizeof(*gpin), KM_SLEEP); 352 gpin->pin_sc = sc; 353 gpin->pin_def = pin_def; 354 gpin->pin_flags = flags; 355 gpin->pin_actlo = actlo; 356 357 return gpin; 358 } 359 360 static void 361 sunxi_gpio_release(device_t dev, void *priv) 362 { 363 struct sunxi_gpio_softc * const sc = device_private(dev); 364 struct sunxi_gpio_pin *pin = priv; 365 366 mutex_enter(&sc->sc_lock); 367 sunxi_gpio_ctl(pin->pin_sc, pin->pin_def, GPIO_PIN_INPUT); 368 mutex_exit(&sc->sc_lock); 369 370 kmem_free(pin, sizeof(*pin)); 371 } 372 373 static int 374 sunxi_gpio_read(device_t dev, void *priv, bool raw) 375 { 376 struct sunxi_gpio_softc * const sc = device_private(dev); 377 struct sunxi_gpio_pin *pin = priv; 378 const struct sunxi_gpio_pins *pin_def = pin->pin_def; 379 uint32_t data; 380 int val; 381 382 KASSERT(sc == pin->pin_sc); 383 384 const bus_size_t data_reg = SUNXI_GPIO_DATA(pin_def->port); 385 const uint32_t data_mask = __BIT(pin_def->pin); 386 387 /* No lock required for reads */ 388 data = GPIO_READ(sc, data_reg); 389 val = __SHIFTOUT(data, data_mask); 390 if (!raw && pin->pin_actlo) 391 val = !val; 392 393 #ifdef SUNXI_GPIO_DEBUG 394 device_printf(dev, "P%c%02d rd %08x (%d %d)\n", 395 pin_def->port + 'A', pin_def->pin, data, 396 __SHIFTOUT(val, data_mask), val); 397 #endif 398 399 return val; 400 } 401 402 static void 403 sunxi_gpio_write(device_t dev, void *priv, int val, bool raw) 404 { 405 struct sunxi_gpio_softc * const sc = device_private(dev); 406 struct sunxi_gpio_pin *pin = priv; 407 const struct sunxi_gpio_pins *pin_def = pin->pin_def; 408 uint32_t data; 409 410 KASSERT(sc == pin->pin_sc); 411 412 const bus_size_t data_reg = SUNXI_GPIO_DATA(pin_def->port); 413 const uint32_t data_mask = __BIT(pin_def->pin); 414 415 if (!raw && pin->pin_actlo) 416 val = !val; 417 418 mutex_enter(&sc->sc_lock); 419 data = GPIO_READ(sc, data_reg); 420 data &= ~data_mask; 421 data |= __SHIFTIN(val, data_mask); 422 #ifdef SUNXI_GPIO_DEBUG 423 device_printf(dev, "P%c%02d wr %08x -> %08x\n", 424 pin_def->port + 'A', pin_def->pin, GPIO_READ(sc, data_reg), data); 425 #endif 426 GPIO_WRITE(sc, data_reg, data); 427 mutex_exit(&sc->sc_lock); 428 } 429 430 static struct fdtbus_gpio_controller_func sunxi_gpio_funcs = { 431 .acquire = sunxi_gpio_acquire, 432 .release = sunxi_gpio_release, 433 .read = sunxi_gpio_read, 434 .write = sunxi_gpio_write, 435 }; 436 437 static int 438 sunxi_gpio_intr(void *priv) 439 { 440 struct sunxi_gpio_softc * const sc = priv; 441 struct sunxi_gpio_eint *eint; 442 uint32_t status, bit; 443 u_int bank; 444 int ret = 0; 445 446 for (bank = 0; bank <= sc->sc_eint_bank_max; bank++) { 447 status = GPIO_READ(sc, SUNXI_GPIO_INT_STATUS(bank)); 448 if (status == 0) 449 continue; 450 GPIO_WRITE(sc, SUNXI_GPIO_INT_STATUS(bank), status); 451 452 while ((bit = ffs32(status)) != 0) { 453 status &= ~__BIT(bit - 1); 454 eint = &sc->sc_eint[bank][bit - 1]; 455 if (eint->eint_func == NULL) 456 continue; 457 if (!eint->eint_mpsafe) 458 KERNEL_LOCK(1, curlwp); 459 ret |= eint->eint_func(eint->eint_arg); 460 if (!eint->eint_mpsafe) 461 KERNEL_UNLOCK_ONE(curlwp); 462 } 463 } 464 465 return ret; 466 } 467 468 static void * 469 sunxi_intr_enable(struct sunxi_gpio_softc *sc, 470 const struct sunxi_gpio_pins *pin_def, u_int mode, bool mpsafe, 471 int (*func)(void *), void *arg) 472 { 473 uint32_t val; 474 struct sunxi_gpio_eint *eint; 475 476 if (pin_def->functions[pin_def->eint_func] == NULL || 477 strcmp(pin_def->functions[pin_def->eint_func], "irq") != 0) 478 return NULL; 479 480 KASSERT(pin_def->eint_num < SUNXI_GPIO_MAX_EINT); 481 482 mutex_enter(&sc->sc_lock); 483 484 eint = &sc->sc_eint[pin_def->eint_bank][pin_def->eint_num]; 485 if (eint->eint_func != NULL) { 486 mutex_exit(&sc->sc_lock); 487 return NULL; /* in use */ 488 } 489 490 /* Set function */ 491 if (sunxi_gpio_setfunc(sc, pin_def, "irq") != 0) { 492 mutex_exit(&sc->sc_lock); 493 return NULL; 494 } 495 496 eint->eint_func = func; 497 eint->eint_arg = arg; 498 eint->eint_mpsafe = mpsafe; 499 eint->eint_bank = pin_def->eint_bank; 500 eint->eint_num = pin_def->eint_num; 501 502 /* Configure eint mode */ 503 val = GPIO_READ(sc, SUNXI_GPIO_INT_CFG(eint->eint_bank, eint->eint_num)); 504 val &= ~SUNXI_GPIO_INT_MODEMASK(eint->eint_num); 505 val |= __SHIFTIN(mode, SUNXI_GPIO_INT_MODEMASK(eint->eint_num)); 506 GPIO_WRITE(sc, SUNXI_GPIO_INT_CFG(eint->eint_bank, eint->eint_num), val); 507 508 val = SUNXI_GPIO_INT_DEBOUNCE_CLK_SEL; 509 GPIO_WRITE(sc, SUNXI_GPIO_INT_DEBOUNCE(eint->eint_bank), val); 510 511 /* Enable eint */ 512 val = GPIO_READ(sc, SUNXI_GPIO_INT_CTL(eint->eint_bank)); 513 val |= __BIT(eint->eint_num); 514 GPIO_WRITE(sc, SUNXI_GPIO_INT_CTL(eint->eint_bank), val); 515 516 mutex_exit(&sc->sc_lock); 517 518 return eint; 519 } 520 521 static void 522 sunxi_intr_disable(struct sunxi_gpio_softc *sc, struct sunxi_gpio_eint *eint) 523 { 524 uint32_t val; 525 526 KASSERT(eint->eint_func != NULL); 527 528 mutex_enter(&sc->sc_lock); 529 530 /* Disable eint */ 531 val = GPIO_READ(sc, SUNXI_GPIO_INT_CTL(eint->eint_bank)); 532 val &= ~__BIT(eint->eint_num); 533 GPIO_WRITE(sc, SUNXI_GPIO_INT_CTL(eint->eint_bank), val); 534 GPIO_WRITE(sc, SUNXI_GPIO_INT_STATUS(eint->eint_bank), __BIT(eint->eint_num)); 535 536 eint->eint_func = NULL; 537 eint->eint_arg = NULL; 538 eint->eint_mpsafe = false; 539 540 mutex_exit(&sc->sc_lock); 541 } 542 543 static void * 544 sunxi_fdt_intr_establish(device_t dev, u_int *specifier, int ipl, int flags, 545 int (*func)(void *), void *arg, const char *xname) 546 { 547 struct sunxi_gpio_softc * const sc = device_private(dev); 548 bool mpsafe = (flags & FDT_INTR_MPSAFE) != 0; 549 const struct sunxi_gpio_pins *pin_def; 550 u_int mode; 551 552 if (ipl != IPL_VM) { 553 aprint_error_dev(dev, "%s: wrong IPL %d (expected %d)\n", 554 __func__, ipl, IPL_VM); 555 return NULL; 556 } 557 558 /* 1st cell is the bank */ 559 /* 2nd cell is the pin */ 560 /* 3rd cell is flags */ 561 const u_int port = be32toh(specifier[0]); 562 const u_int pin = be32toh(specifier[1]); 563 const u_int type = be32toh(specifier[2]) & 0xf; 564 565 switch (type) { 566 case FDT_INTR_TYPE_POS_EDGE: 567 mode = SUNXI_GPIO_INT_MODE_POS_EDGE; 568 break; 569 case FDT_INTR_TYPE_NEG_EDGE: 570 mode = SUNXI_GPIO_INT_MODE_NEG_EDGE; 571 break; 572 case FDT_INTR_TYPE_DOUBLE_EDGE: 573 mode = SUNXI_GPIO_INT_MODE_DOUBLE_EDGE; 574 break; 575 case FDT_INTR_TYPE_HIGH_LEVEL: 576 mode = SUNXI_GPIO_INT_MODE_HIGH_LEVEL; 577 break; 578 case FDT_INTR_TYPE_LOW_LEVEL: 579 mode = SUNXI_GPIO_INT_MODE_LOW_LEVEL; 580 break; 581 default: 582 aprint_error_dev(dev, "%s: unsupported irq type 0x%x\n", 583 __func__, type); 584 return NULL; 585 } 586 587 pin_def = sunxi_gpio_lookup(sc, port, pin); 588 if (pin_def == NULL) 589 return NULL; 590 591 return sunxi_intr_enable(sc, pin_def, mode, mpsafe, func, arg); 592 } 593 594 static void 595 sunxi_fdt_intr_disestablish(device_t dev, void *ih) 596 { 597 struct sunxi_gpio_softc * const sc = device_private(dev); 598 struct sunxi_gpio_eint * const eint = ih; 599 600 sunxi_intr_disable(sc, eint); 601 } 602 603 static bool 604 sunxi_fdt_intrstr(device_t dev, u_int *specifier, char *buf, size_t buflen) 605 { 606 struct sunxi_gpio_softc * const sc = device_private(dev); 607 const struct sunxi_gpio_pins *pin_def; 608 609 /* 1st cell is the bank */ 610 /* 2nd cell is the pin */ 611 /* 3rd cell is flags */ 612 if (!specifier) 613 return false; 614 const u_int port = be32toh(specifier[0]); 615 const u_int pin = be32toh(specifier[1]); 616 617 pin_def = sunxi_gpio_lookup(sc, port, pin); 618 if (pin_def == NULL) 619 return false; 620 621 snprintf(buf, buflen, "GPIO %s", pin_def->name); 622 623 return true; 624 } 625 626 static struct fdtbus_interrupt_controller_func sunxi_gpio_intrfuncs = { 627 .establish = sunxi_fdt_intr_establish, 628 .disestablish = sunxi_fdt_intr_disestablish, 629 .intrstr = sunxi_fdt_intrstr, 630 }; 631 632 static void * 633 sunxi_gpio_intr_establish(void *vsc, int pin, int ipl, int irqmode, 634 int (*func)(void *), void *arg) 635 { 636 struct sunxi_gpio_softc * const sc = vsc; 637 bool mpsafe = (irqmode & GPIO_INTR_MPSAFE) != 0; 638 int type = irqmode & GPIO_INTR_MODE_MASK; 639 const struct sunxi_gpio_pins *pin_def; 640 u_int mode; 641 642 switch (type) { 643 case GPIO_INTR_POS_EDGE: 644 mode = SUNXI_GPIO_INT_MODE_POS_EDGE; 645 break; 646 case GPIO_INTR_NEG_EDGE: 647 mode = SUNXI_GPIO_INT_MODE_NEG_EDGE; 648 break; 649 case GPIO_INTR_DOUBLE_EDGE: 650 mode = SUNXI_GPIO_INT_MODE_DOUBLE_EDGE; 651 break; 652 case GPIO_INTR_HIGH_LEVEL: 653 mode = SUNXI_GPIO_INT_MODE_HIGH_LEVEL; 654 break; 655 case GPIO_INTR_LOW_LEVEL: 656 mode = SUNXI_GPIO_INT_MODE_LOW_LEVEL; 657 break; 658 default: 659 aprint_error_dev(sc->sc_dev, "%s: unsupported irq type 0x%x\n", 660 __func__, type); 661 return NULL; 662 } 663 664 if (pin < 0 || pin >= sc->sc_padconf->npins) 665 return NULL; 666 pin_def = &sc->sc_padconf->pins[pin]; 667 668 return sunxi_intr_enable(sc, pin_def, mode, mpsafe, func, arg); 669 } 670 671 static void 672 sunxi_gpio_intr_disestablish(void *vsc, void *ih) 673 { 674 struct sunxi_gpio_softc * const sc = vsc; 675 struct sunxi_gpio_eint * const eint = ih; 676 677 sunxi_intr_disable(sc, eint); 678 } 679 680 static bool 681 sunxi_gpio_intrstr(void *vsc, int pin, int irqmode, char *buf, size_t buflen) 682 { 683 struct sunxi_gpio_softc * const sc = vsc; 684 const struct sunxi_gpio_pins *pin_def; 685 686 if (pin < 0 || pin >= sc->sc_padconf->npins) 687 return NULL; 688 pin_def = &sc->sc_padconf->pins[pin]; 689 690 snprintf(buf, buflen, "GPIO %s", pin_def->name); 691 692 return true; 693 } 694 695 static const char * 696 sunxi_pinctrl_parse_function(int phandle) 697 { 698 const char *function; 699 700 function = fdtbus_pinctrl_parse_function(phandle); 701 if (function != NULL) 702 return function; 703 704 return fdtbus_get_string(phandle, "allwinner,function"); 705 } 706 707 static const char * 708 sunxi_pinctrl_parse_pins(int phandle, int *pins_len) 709 { 710 const char *pins; 711 int len; 712 713 pins = fdtbus_pinctrl_parse_pins(phandle, pins_len); 714 if (pins != NULL) 715 return pins; 716 717 len = OF_getproplen(phandle, "allwinner,pins"); 718 if (len > 0) { 719 *pins_len = len; 720 return fdtbus_get_prop(phandle, "allwinner,pins", pins_len); 721 } 722 723 return NULL; 724 } 725 726 static int 727 sunxi_pinctrl_parse_bias(int phandle) 728 { 729 u_int pull; 730 int bias; 731 732 bias = fdtbus_pinctrl_parse_bias(phandle, NULL); 733 if (bias != -1) 734 return bias; 735 736 if (of_getprop_uint32(phandle, "allwinner,pull", &pull) == 0) { 737 switch (pull) { 738 case 0: 739 bias = 0; 740 break; 741 case 1: 742 bias = GPIO_PIN_PULLUP; 743 break; 744 case 2: 745 bias = GPIO_PIN_PULLDOWN; 746 break; 747 } 748 } 749 750 return bias; 751 } 752 753 static int 754 sunxi_pinctrl_parse_drive_strength(int phandle) 755 { 756 int val; 757 758 val = fdtbus_pinctrl_parse_drive_strength(phandle); 759 if (val != -1) 760 return val; 761 762 if (of_getprop_uint32(phandle, "allwinner,drive", &val) == 0) 763 return (val + 1) * 10; 764 765 return -1; 766 } 767 768 static void 769 sunxi_pinctrl_enable_regulator(struct sunxi_gpio_softc *sc, 770 const struct sunxi_gpio_pins *pin_def) 771 { 772 char supply_prop[16]; 773 uint32_t val; 774 u_int uvol; 775 int error; 776 777 const char c = tolower(pin_def->name[1]); 778 if (c < 'a' || c > 'z') 779 return; 780 const int index = c - 'a'; 781 782 if (sc->sc_pin_supply[index] != NULL) { 783 /* Already enabled */ 784 return; 785 } 786 787 snprintf(supply_prop, sizeof(supply_prop), "vcc-p%c-supply", c); 788 sc->sc_pin_supply[index] = fdtbus_regulator_acquire(sc->sc_phandle, supply_prop); 789 if (sc->sc_pin_supply[index] == NULL) 790 return; 791 792 aprint_debug_dev(sc->sc_dev, "enable \"%s\"\n", supply_prop); 793 error = fdtbus_regulator_enable(sc->sc_pin_supply[index]); 794 if (error != 0) 795 aprint_error_dev(sc->sc_dev, "failed to enable %s: %d\n", supply_prop, error); 796 797 if (sc->sc_padconf->has_io_bias_config) { 798 error = fdtbus_regulator_get_voltage(sc->sc_pin_supply[index], &uvol); 799 if (error != 0) { 800 aprint_error_dev(sc->sc_dev, "failed to get %s voltage: %d\n", 801 supply_prop, error); 802 uvol = 0; 803 } 804 if (uvol != 0) { 805 if (uvol <= 1800000) 806 val = 0x0; /* 1.8V */ 807 else if (uvol <= 2500000) 808 val = 0x6; /* 2.5V */ 809 else if (uvol <= 2800000) 810 val = 0x9; /* 2.8V */ 811 else if (uvol <= 3000000) 812 val = 0xa; /* 3.0V */ 813 else 814 val = 0xd; /* 3.3V */ 815 816 aprint_debug_dev(sc->sc_dev, "set io bias config for port %d to 0x%x\n", 817 pin_def->port, val); 818 val = GPIO_READ(sc, SUNXI_GPIO_GRP_CONFIG(pin_def->port)); 819 val &= ~SUNXI_GPIO_GRP_IO_BIAS_CONFIGMASK; 820 val |= __SHIFTIN(val, SUNXI_GPIO_GRP_IO_BIAS_CONFIGMASK); 821 GPIO_WRITE(sc, SUNXI_GPIO_GRP_CONFIG(pin_def->port), val); 822 } 823 } 824 } 825 826 static int 827 sunxi_pinctrl_set_config(device_t dev, const void *data, size_t len) 828 { 829 struct sunxi_gpio_softc * const sc = device_private(dev); 830 const struct sunxi_gpio_pins *pin_def; 831 int pins_len; 832 833 if (len != 4) 834 return -1; 835 836 const int phandle = fdtbus_get_phandle_from_native(be32dec(data)); 837 838 /* 839 * Required: pins, function 840 * Optional: bias, drive strength 841 */ 842 843 const char *function = sunxi_pinctrl_parse_function(phandle); 844 if (function == NULL) 845 return -1; 846 const char *pins = sunxi_pinctrl_parse_pins(phandle, &pins_len); 847 if (pins == NULL) 848 return -1; 849 850 const int bias = sunxi_pinctrl_parse_bias(phandle); 851 const int drive_strength = sunxi_pinctrl_parse_drive_strength(phandle); 852 853 mutex_enter(&sc->sc_lock); 854 855 for (; pins_len > 0; 856 pins_len -= strlen(pins) + 1, pins += strlen(pins) + 1) { 857 pin_def = sunxi_gpio_lookup_byname(sc, pins); 858 if (pin_def == NULL) { 859 aprint_error_dev(dev, "unknown pin name '%s'\n", pins); 860 continue; 861 } 862 if (sunxi_gpio_setfunc(sc, pin_def, function) != 0) 863 continue; 864 865 if (bias != -1) 866 sunxi_gpio_setpull(sc, pin_def, bias); 867 868 if (drive_strength != -1) 869 sunxi_gpio_setdrv(sc, pin_def, drive_strength); 870 871 sunxi_pinctrl_enable_regulator(sc, pin_def); 872 } 873 874 mutex_exit(&sc->sc_lock); 875 876 return 0; 877 } 878 879 static struct fdtbus_pinctrl_controller_func sunxi_pinctrl_funcs = { 880 .set_config = sunxi_pinctrl_set_config, 881 }; 882 883 static int 884 sunxi_gpio_pin_read(void *priv, int pin) 885 { 886 struct sunxi_gpio_softc * const sc = priv; 887 const struct sunxi_gpio_pins *pin_def = &sc->sc_padconf->pins[pin]; 888 uint32_t data; 889 int val; 890 891 KASSERT(pin < sc->sc_padconf->npins); 892 893 const bus_size_t data_reg = SUNXI_GPIO_DATA(pin_def->port); 894 const uint32_t data_mask = __BIT(pin_def->pin); 895 896 /* No lock required for reads */ 897 data = GPIO_READ(sc, data_reg); 898 val = __SHIFTOUT(data, data_mask); 899 900 return val; 901 } 902 903 static void 904 sunxi_gpio_pin_write(void *priv, int pin, int val) 905 { 906 struct sunxi_gpio_softc * const sc = priv; 907 const struct sunxi_gpio_pins *pin_def = &sc->sc_padconf->pins[pin]; 908 uint32_t data; 909 910 KASSERT(pin < sc->sc_padconf->npins); 911 912 const bus_size_t data_reg = SUNXI_GPIO_DATA(pin_def->port); 913 const uint32_t data_mask = __BIT(pin_def->pin); 914 915 mutex_enter(&sc->sc_lock); 916 data = GPIO_READ(sc, data_reg); 917 if (val) 918 data |= data_mask; 919 else 920 data &= ~data_mask; 921 GPIO_WRITE(sc, data_reg, data); 922 mutex_exit(&sc->sc_lock); 923 } 924 925 static void 926 sunxi_gpio_pin_ctl(void *priv, int pin, int flags) 927 { 928 struct sunxi_gpio_softc * const sc = priv; 929 const struct sunxi_gpio_pins *pin_def = &sc->sc_padconf->pins[pin]; 930 931 KASSERT(pin < sc->sc_padconf->npins); 932 933 mutex_enter(&sc->sc_lock); 934 sunxi_gpio_ctl(sc, pin_def, flags); 935 sunxi_gpio_setpull(sc, pin_def, flags); 936 mutex_exit(&sc->sc_lock); 937 } 938 939 static void 940 sunxi_gpio_attach_ports(struct sunxi_gpio_softc *sc) 941 { 942 const struct sunxi_gpio_pins *pin_def; 943 struct gpio_chipset_tag *gp = &sc->sc_gp; 944 struct gpiobus_attach_args gba; 945 u_int pin; 946 947 gp->gp_cookie = sc; 948 gp->gp_pin_read = sunxi_gpio_pin_read; 949 gp->gp_pin_write = sunxi_gpio_pin_write; 950 gp->gp_pin_ctl = sunxi_gpio_pin_ctl; 951 gp->gp_intr_establish = sunxi_gpio_intr_establish; 952 gp->gp_intr_disestablish = sunxi_gpio_intr_disestablish; 953 gp->gp_intr_str = sunxi_gpio_intrstr; 954 955 const u_int npins = sc->sc_padconf->npins; 956 sc->sc_pins = kmem_zalloc(sizeof(*sc->sc_pins) * npins, KM_SLEEP); 957 958 for (pin = 0; pin < sc->sc_padconf->npins; pin++) { 959 pin_def = &sc->sc_padconf->pins[pin]; 960 sc->sc_pins[pin].pin_num = pin; 961 sc->sc_pins[pin].pin_caps = GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | 962 GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN; 963 if (pin_def->functions[pin_def->eint_func] != NULL && 964 strcmp(pin_def->functions[pin_def->eint_func], "irq") == 0) { 965 sc->sc_pins[pin].pin_intrcaps = 966 GPIO_INTR_POS_EDGE | GPIO_INTR_NEG_EDGE | 967 GPIO_INTR_HIGH_LEVEL | GPIO_INTR_LOW_LEVEL | 968 GPIO_INTR_DOUBLE_EDGE | GPIO_INTR_MPSAFE; 969 } 970 sc->sc_pins[pin].pin_state = sunxi_gpio_pin_read(sc, pin); 971 strlcpy(sc->sc_pins[pin].pin_defname, pin_def->name, 972 sizeof(sc->sc_pins[pin].pin_defname)); 973 } 974 975 memset(&gba, 0, sizeof(gba)); 976 gba.gba_gc = gp; 977 gba.gba_pins = sc->sc_pins; 978 gba.gba_npins = npins; 979 sc->sc_gpiodev = config_found(sc->sc_dev, &gba, NULL, CFARGS_NONE); 980 } 981 982 static int 983 sunxi_gpio_match(device_t parent, cfdata_t cf, void *aux) 984 { 985 struct fdt_attach_args * const faa = aux; 986 987 return of_compatible_match(faa->faa_phandle, compat_data); 988 } 989 990 static void 991 sunxi_gpio_attach(device_t parent, device_t self, void *aux) 992 { 993 struct sunxi_gpio_softc * const sc = device_private(self); 994 struct fdt_attach_args * const faa = aux; 995 const int phandle = faa->faa_phandle; 996 char intrstr[128]; 997 struct fdtbus_reset *rst; 998 struct clk *clk; 999 bus_addr_t addr; 1000 bus_size_t size; 1001 int child; 1002 1003 if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { 1004 aprint_error(": couldn't get registers\n"); 1005 return; 1006 } 1007 1008 if ((clk = fdtbus_clock_get_index(phandle, 0)) != NULL) 1009 if (clk_enable(clk) != 0) { 1010 aprint_error(": couldn't enable clock\n"); 1011 return; 1012 } 1013 1014 if ((rst = fdtbus_reset_get_index(phandle, 0)) != NULL) 1015 if (fdtbus_reset_deassert(rst) != 0) { 1016 aprint_error(": couldn't de-assert reset\n"); 1017 return; 1018 } 1019 1020 sc->sc_dev = self; 1021 sc->sc_phandle = phandle; 1022 sc->sc_bst = faa->faa_bst; 1023 if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) { 1024 aprint_error(": couldn't map registers\n"); 1025 return; 1026 } 1027 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_VM); 1028 sc->sc_padconf = of_compatible_lookup(phandle, compat_data)->data; 1029 1030 aprint_naive("\n"); 1031 aprint_normal(": PIO\n"); 1032 1033 fdtbus_register_gpio_controller(self, phandle, &sunxi_gpio_funcs); 1034 1035 for (child = OF_child(phandle); child; child = OF_peer(child)) { 1036 bool is_valid = 1037 (of_hasprop(child, "function") && of_hasprop(child, "pins")) || 1038 (of_hasprop(child, "allwinner,function") && of_hasprop(child, "allwinner,pins")); 1039 if (!is_valid) 1040 continue; 1041 fdtbus_register_pinctrl_config(self, child, &sunxi_pinctrl_funcs); 1042 } 1043 1044 sunxi_gpio_attach_ports(sc); 1045 1046 /* Disable all external interrupts */ 1047 for (int i = 0; i < sc->sc_padconf->npins; i++) { 1048 const struct sunxi_gpio_pins *pin_def = &sc->sc_padconf->pins[i]; 1049 if (pin_def->eint_func == 0) 1050 continue; 1051 GPIO_WRITE(sc, SUNXI_GPIO_INT_CTL(pin_def->eint_bank), __BIT(pin_def->eint_num)); 1052 GPIO_WRITE(sc, SUNXI_GPIO_INT_STATUS(pin_def->eint_bank), __BIT(pin_def->eint_num)); 1053 1054 if (sc->sc_eint_bank_max < pin_def->eint_bank) 1055 sc->sc_eint_bank_max = pin_def->eint_bank; 1056 } 1057 KASSERT(sc->sc_eint_bank_max < SUNXI_GPIO_MAX_EINT_BANK); 1058 1059 if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) { 1060 aprint_error_dev(self, "failed to decode interrupt\n"); 1061 return; 1062 } 1063 sc->sc_ih = fdtbus_intr_establish_xname(phandle, 0, IPL_VM, 1064 FDT_INTR_MPSAFE, sunxi_gpio_intr, sc, device_xname(self)); 1065 if (sc->sc_ih == NULL) { 1066 aprint_error_dev(self, "failed to establish interrupt on %s\n", 1067 intrstr); 1068 return; 1069 } 1070 aprint_normal_dev(self, "interrupting on %s\n", intrstr); 1071 fdtbus_register_interrupt_controller(self, phandle, 1072 &sunxi_gpio_intrfuncs); 1073 } 1074