1 /* $NetBSD: sunxi_gpio.c,v 1.20 2018/04/03 16:01:25 bouyer 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.20 2018/04/03 16:01:25 bouyer 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_PORT(port) (0x24 * (port)) 54 #define SUNXI_GPIO_CFG(port, pin) (SUNXI_GPIO_PORT(port) + 0x00 + (0x4 * ((pin) / 8))) 55 #define SUNXI_GPIO_CFG_PINMASK(pin) (0x7 << (((pin) % 8) * 4)) 56 #define SUNXI_GPIO_DATA(port) (SUNXI_GPIO_PORT(port) + 0x10) 57 #define SUNXI_GPIO_DRV(port, pin) (SUNXI_GPIO_PORT(port) + 0x14 + (0x4 * ((pin) / 16))) 58 #define SUNXI_GPIO_DRV_PINMASK(pin) (0x3 << (((pin) % 16) * 2)) 59 #define SUNXI_GPIO_PULL(port, pin) (SUNXI_GPIO_PORT(port) + 0x1c + (0x4 * ((pin) / 16))) 60 #define SUNXI_GPIO_PULL_DISABLE 0 61 #define SUNXI_GPIO_PULL_UP 1 62 #define SUNXI_GPIO_PULL_DOWN 2 63 #define SUNXI_GPIO_PULL_PINMASK(pin) (0x3 << (((pin) % 16) * 2)) 64 #define SUNXI_GPIO_INT_CFG(bank, eint) (0x200 + (0x20 * (bank)) + (0x4 * ((eint) / 8))) 65 #define SUNXI_GPIO_INT_MODEMASK(eint) (0xf << (((eint) % 8) * 4)) 66 #define SUNXI_GPIO_INT_MODE_POS_EDGE 0x0 67 #define SUNXI_GPIO_INT_MODE_NEG_EDGE 0x1 68 #define SUNXI_GPIO_INT_MODE_HIGH_LEVEL 0x2 69 #define SUNXI_GPIO_INT_MODE_LOW_LEVEL 0x3 70 #define SUNXI_GPIO_INT_MODE_DOUBLE_EDGE 0x4 71 #define SUNXI_GPIO_INT_CTL(bank) (0x210 + 0x20 * (bank)) 72 #define SUNXI_GPIO_INT_STATUS(bank) (0x214 + 0x20 * (bank)) 73 74 static const struct of_compat_data compat_data[] = { 75 #ifdef SOC_SUN4I_A10 76 { "allwinner,sun4i-a10-pinctrl", (uintptr_t)&sun4i_a10_padconf }, 77 #endif 78 #ifdef SOC_SUN5I_A13 79 { "allwinner,sun5i-a13-pinctrl", (uintptr_t)&sun5i_a13_padconf }, 80 { "nextthing,gr8-pinctrl", (uintptr_t)&sun5i_a13_padconf }, 81 #endif 82 #ifdef SOC_SUN6I_A31 83 { "allwinner,sun6i-a31-pinctrl", (uintptr_t)&sun6i_a31_padconf }, 84 { "allwinner,sun6i-a31-r-pinctrl", (uintptr_t)&sun6i_a31_r_padconf }, 85 #endif 86 #ifdef SOC_SUN7I_A20 87 { "allwinner,sun7i-a20-pinctrl", (uintptr_t)&sun7i_a20_padconf }, 88 #endif 89 #ifdef SOC_SUN8I_A83T 90 { "allwinner,sun8i-a83t-pinctrl", (uintptr_t)&sun8i_a83t_padconf }, 91 { "allwinner,sun8i-a83t-r-pinctrl", (uintptr_t)&sun8i_a83t_r_padconf }, 92 #endif 93 #ifdef SOC_SUN8I_H3 94 { "allwinner,sun8i-h3-pinctrl", (uintptr_t)&sun8i_h3_padconf }, 95 { "allwinner,sun8i-h3-r-pinctrl", (uintptr_t)&sun8i_h3_r_padconf }, 96 #endif 97 #ifdef SOC_SUN9I_A80 98 { "allwinner,sun9i-a80-pinctrl", (uintptr_t)&sun9i_a80_padconf }, 99 { "allwinner,sun9i-a80-r-pinctrl", (uintptr_t)&sun9i_a80_r_padconf }, 100 #endif 101 #ifdef SOC_SUN50I_A64 102 { "allwinner,sun50i-a64-pinctrl", (uintptr_t)&sun50i_a64_padconf }, 103 { "allwinner,sun50i-a64-r-pinctrl", (uintptr_t)&sun50i_a64_r_padconf }, 104 #endif 105 #ifdef SOC_SUN50I_H5 106 { "allwinner,sun50i-h5-pinctrl", (uintptr_t)&sun8i_h3_padconf }, 107 { "allwinner,sun50i-h5-r-pinctrl", (uintptr_t)&sun8i_h3_r_padconf }, 108 #endif 109 #ifdef SOC_SUN50I_H6 110 { "allwinner,sun50i-h6-pinctrl", (uintptr_t)&sun50i_h6_padconf }, 111 { "allwinner,sun50i-h6-r-pinctrl", (uintptr_t)&sun50i_h6_r_padconf }, 112 #endif 113 { NULL } 114 }; 115 116 struct sunxi_gpio_eint { 117 int (*eint_func)(void *); 118 void *eint_arg; 119 int eint_flags; 120 int eint_bank; 121 int eint_num; 122 }; 123 124 struct sunxi_gpio_softc { 125 device_t sc_dev; 126 bus_space_tag_t sc_bst; 127 bus_space_handle_t sc_bsh; 128 const struct sunxi_gpio_padconf *sc_padconf; 129 kmutex_t sc_lock; 130 131 struct gpio_chipset_tag sc_gp; 132 gpio_pin_t *sc_pins; 133 device_t sc_gpiodev; 134 135 u_int sc_eint_bank_max; 136 137 void *sc_ih; 138 struct sunxi_gpio_eint sc_eint[SUNXI_GPIO_MAX_EINT_BANK][SUNXI_GPIO_MAX_EINT]; 139 }; 140 141 struct sunxi_gpio_pin { 142 struct sunxi_gpio_softc *pin_sc; 143 const struct sunxi_gpio_pins *pin_def; 144 int pin_flags; 145 bool pin_actlo; 146 }; 147 148 #define GPIO_READ(sc, reg) \ 149 bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg)) 150 #define GPIO_WRITE(sc, reg, val) \ 151 bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val)) 152 153 static int sunxi_gpio_match(device_t, cfdata_t, void *); 154 static void sunxi_gpio_attach(device_t, device_t, void *); 155 156 CFATTACH_DECL_NEW(sunxi_gpio, sizeof(struct sunxi_gpio_softc), 157 sunxi_gpio_match, sunxi_gpio_attach, NULL, NULL); 158 159 static const struct sunxi_gpio_pins * 160 sunxi_gpio_lookup(struct sunxi_gpio_softc *sc, uint8_t port, uint8_t pin) 161 { 162 const struct sunxi_gpio_pins *pin_def; 163 u_int n; 164 165 for (n = 0; n < sc->sc_padconf->npins; n++) { 166 pin_def = &sc->sc_padconf->pins[n]; 167 if (pin_def->port == port && pin_def->pin == pin) 168 return pin_def; 169 } 170 171 return NULL; 172 } 173 174 static const struct sunxi_gpio_pins * 175 sunxi_gpio_lookup_byname(struct sunxi_gpio_softc *sc, const char *name) 176 { 177 const struct sunxi_gpio_pins *pin_def; 178 u_int n; 179 180 for (n = 0; n < sc->sc_padconf->npins; n++) { 181 pin_def = &sc->sc_padconf->pins[n]; 182 if (strcmp(pin_def->name, name) == 0) 183 return pin_def; 184 } 185 186 return NULL; 187 } 188 189 static int 190 sunxi_gpio_setfunc(struct sunxi_gpio_softc *sc, 191 const struct sunxi_gpio_pins *pin_def, const char *func) 192 { 193 uint32_t cfg; 194 u_int n; 195 196 KASSERT(mutex_owned(&sc->sc_lock)); 197 198 const bus_size_t cfg_reg = SUNXI_GPIO_CFG(pin_def->port, pin_def->pin); 199 const uint32_t cfg_mask = SUNXI_GPIO_CFG_PINMASK(pin_def->pin); 200 201 for (n = 0; n < SUNXI_GPIO_MAXFUNC; n++) { 202 if (pin_def->functions[n] == NULL) 203 continue; 204 if (strcmp(pin_def->functions[n], func) == 0) { 205 cfg = GPIO_READ(sc, cfg_reg); 206 cfg &= ~cfg_mask; 207 cfg |= __SHIFTIN(n, cfg_mask); 208 #ifdef SUNXI_GPIO_DEBUG 209 device_printf(sc->sc_dev, "P%c%02d cfg %08x -> %08x\n", 210 pin_def->port + 'A', pin_def->pin, GPIO_READ(sc, cfg_reg), cfg); 211 #endif 212 GPIO_WRITE(sc, cfg_reg, cfg); 213 return 0; 214 } 215 } 216 217 /* Function not found */ 218 device_printf(sc->sc_dev, "function '%s' not supported on P%c%02d\n", 219 func, pin_def->port + 'A', pin_def->pin); 220 221 return ENXIO; 222 } 223 224 static int 225 sunxi_gpio_setpull(struct sunxi_gpio_softc *sc, 226 const struct sunxi_gpio_pins *pin_def, int flags) 227 { 228 uint32_t pull; 229 230 KASSERT(mutex_owned(&sc->sc_lock)); 231 232 const bus_size_t pull_reg = SUNXI_GPIO_PULL(pin_def->port, pin_def->pin); 233 const uint32_t pull_mask = SUNXI_GPIO_PULL_PINMASK(pin_def->pin); 234 235 pull = GPIO_READ(sc, pull_reg); 236 pull &= ~pull_mask; 237 if (flags & GPIO_PIN_PULLUP) 238 pull |= __SHIFTIN(SUNXI_GPIO_PULL_UP, pull_mask); 239 else if (flags & GPIO_PIN_PULLDOWN) 240 pull |= __SHIFTIN(SUNXI_GPIO_PULL_DOWN, pull_mask); 241 else 242 pull |= __SHIFTIN(SUNXI_GPIO_PULL_DISABLE, pull_mask); 243 #ifdef SUNXI_GPIO_DEBUG 244 device_printf(sc->sc_dev, "P%c%02d pull %08x -> %08x\n", 245 pin_def->port + 'A', pin_def->pin, GPIO_READ(sc, pull_reg), pull); 246 #endif 247 GPIO_WRITE(sc, pull_reg, pull); 248 249 return 0; 250 } 251 252 static int 253 sunxi_gpio_setdrv(struct sunxi_gpio_softc *sc, 254 const struct sunxi_gpio_pins *pin_def, int drive_strength) 255 { 256 uint32_t drv; 257 258 KASSERT(mutex_owned(&sc->sc_lock)); 259 260 if (drive_strength < 10 || drive_strength > 40) 261 return EINVAL; 262 263 const bus_size_t drv_reg = SUNXI_GPIO_DRV(pin_def->port, pin_def->pin); 264 const uint32_t drv_mask = SUNXI_GPIO_DRV_PINMASK(pin_def->pin); 265 266 drv = GPIO_READ(sc, drv_reg); 267 drv &= ~drv_mask; 268 drv |= __SHIFTIN((drive_strength / 10) - 1, drv_mask); 269 #ifdef SUNXI_GPIO_DEBUG 270 device_printf(sc->sc_dev, "P%c%02d drv %08x -> %08x\n", 271 pin_def->port + 'A', pin_def->pin, GPIO_READ(sc, drv_reg), drv); 272 #endif 273 GPIO_WRITE(sc, drv_reg, drv); 274 275 return 0; 276 } 277 278 static int 279 sunxi_gpio_ctl(struct sunxi_gpio_softc *sc, const struct sunxi_gpio_pins *pin_def, 280 int flags) 281 { 282 KASSERT(mutex_owned(&sc->sc_lock)); 283 284 if (flags & GPIO_PIN_INPUT) 285 return sunxi_gpio_setfunc(sc, pin_def, "gpio_in"); 286 if (flags & GPIO_PIN_OUTPUT) 287 return sunxi_gpio_setfunc(sc, pin_def, "gpio_out"); 288 289 return EINVAL; 290 } 291 292 static void * 293 sunxi_gpio_acquire(device_t dev, const void *data, size_t len, int flags) 294 { 295 struct sunxi_gpio_softc * const sc = device_private(dev); 296 const struct sunxi_gpio_pins *pin_def; 297 struct sunxi_gpio_pin *gpin; 298 const u_int *gpio = data; 299 int error; 300 301 if (len != 16) 302 return NULL; 303 304 const uint8_t port = be32toh(gpio[1]) & 0xff; 305 const uint8_t pin = be32toh(gpio[2]) & 0xff; 306 const bool actlo = be32toh(gpio[3]) & 1; 307 308 pin_def = sunxi_gpio_lookup(sc, port, pin); 309 if (pin_def == NULL) 310 return NULL; 311 312 mutex_enter(&sc->sc_lock); 313 error = sunxi_gpio_ctl(sc, pin_def, flags); 314 mutex_exit(&sc->sc_lock); 315 316 if (error != 0) 317 return NULL; 318 319 gpin = kmem_zalloc(sizeof(*gpin), KM_SLEEP); 320 gpin->pin_sc = sc; 321 gpin->pin_def = pin_def; 322 gpin->pin_flags = flags; 323 gpin->pin_actlo = actlo; 324 325 return gpin; 326 } 327 328 static void 329 sunxi_gpio_release(device_t dev, void *priv) 330 { 331 struct sunxi_gpio_pin *pin = priv; 332 333 sunxi_gpio_ctl(pin->pin_sc, pin->pin_def, GPIO_PIN_INPUT); 334 335 kmem_free(pin, sizeof(*pin)); 336 } 337 338 static int 339 sunxi_gpio_read(device_t dev, void *priv, bool raw) 340 { 341 struct sunxi_gpio_softc * const sc = device_private(dev); 342 struct sunxi_gpio_pin *pin = priv; 343 const struct sunxi_gpio_pins *pin_def = pin->pin_def; 344 uint32_t data; 345 int val; 346 347 KASSERT(sc == pin->pin_sc); 348 349 const bus_size_t data_reg = SUNXI_GPIO_DATA(pin_def->port); 350 const uint32_t data_mask = __BIT(pin_def->pin); 351 352 /* No lock required for reads */ 353 data = GPIO_READ(sc, data_reg); 354 val = __SHIFTOUT(data, data_mask); 355 if (!raw && pin->pin_actlo) 356 val = !val; 357 358 #ifdef SUNXI_GPIO_DEBUG 359 device_printf(dev, "P%c%02d rd %08x (%d %d)\n", 360 pin_def->port + 'A', pin_def->pin, data, 361 __SHIFTOUT(val, data_mask), val); 362 #endif 363 364 return val; 365 } 366 367 static void 368 sunxi_gpio_write(device_t dev, void *priv, int val, bool raw) 369 { 370 struct sunxi_gpio_softc * const sc = device_private(dev); 371 struct sunxi_gpio_pin *pin = priv; 372 const struct sunxi_gpio_pins *pin_def = pin->pin_def; 373 uint32_t data; 374 375 KASSERT(sc == pin->pin_sc); 376 377 const bus_size_t data_reg = SUNXI_GPIO_DATA(pin_def->port); 378 const uint32_t data_mask = __BIT(pin_def->pin); 379 380 if (!raw && pin->pin_actlo) 381 val = !val; 382 383 mutex_enter(&sc->sc_lock); 384 data = GPIO_READ(sc, data_reg); 385 data &= ~data_mask; 386 data |= __SHIFTIN(val, data_mask); 387 #ifdef SUNXI_GPIO_DEBUG 388 device_printf(dev, "P%c%02d wr %08x -> %08x\n", 389 pin_def->port + 'A', pin_def->pin, GPIO_READ(sc, data_reg), data); 390 #endif 391 GPIO_WRITE(sc, data_reg, data); 392 mutex_exit(&sc->sc_lock); 393 } 394 395 static struct fdtbus_gpio_controller_func sunxi_gpio_funcs = { 396 .acquire = sunxi_gpio_acquire, 397 .release = sunxi_gpio_release, 398 .read = sunxi_gpio_read, 399 .write = sunxi_gpio_write, 400 }; 401 402 static int 403 sunxi_gpio_intr(void *priv) 404 { 405 struct sunxi_gpio_softc * const sc = priv; 406 struct sunxi_gpio_eint *eint; 407 uint32_t status, bit; 408 u_int bank; 409 int ret = 0; 410 411 for (bank = 0; bank <= sc->sc_eint_bank_max; bank++) { 412 status = GPIO_READ(sc, SUNXI_GPIO_INT_STATUS(bank)); 413 if (status == 0) 414 continue; 415 GPIO_WRITE(sc, SUNXI_GPIO_INT_STATUS(bank), status); 416 417 while ((bit = ffs32(status)) != 0) { 418 status &= ~__BIT(bit - 1); 419 eint = &sc->sc_eint[bank][bit - 1]; 420 if (eint->eint_func == NULL) 421 continue; 422 const bool mpsafe = (eint->eint_flags & FDT_INTR_MPSAFE) != 0; 423 if (!mpsafe) 424 KERNEL_LOCK(1, curlwp); 425 ret |= eint->eint_func(eint->eint_arg); 426 if (!mpsafe) 427 KERNEL_UNLOCK_ONE(curlwp); 428 } 429 } 430 431 return ret; 432 } 433 434 static void * 435 sunxi_gpio_establish(device_t dev, u_int *specifier, int ipl, int flags, 436 int (*func)(void *), void *arg) 437 { 438 struct sunxi_gpio_softc * const sc = device_private(dev); 439 const struct sunxi_gpio_pins *pin_def; 440 struct sunxi_gpio_eint *eint; 441 uint32_t val; 442 u_int mode; 443 444 if (ipl != IPL_VM) { 445 aprint_error_dev(dev, "%s: wrong IPL %d (expected %d)\n", 446 __func__, ipl, IPL_VM); 447 return NULL; 448 } 449 450 /* 1st cell is the bank */ 451 /* 2nd cell is the pin */ 452 /* 3rd cell is flags */ 453 const u_int port = be32toh(specifier[0]); 454 const u_int pin = be32toh(specifier[1]); 455 const u_int type = be32toh(specifier[2]) & 0xf; 456 457 switch (type) { 458 case 0x1: 459 mode = SUNXI_GPIO_INT_MODE_POS_EDGE; 460 break; 461 case 0x2: 462 mode = SUNXI_GPIO_INT_MODE_NEG_EDGE; 463 break; 464 case 0x3: 465 mode = SUNXI_GPIO_INT_MODE_DOUBLE_EDGE; 466 break; 467 case 0x4: 468 mode = SUNXI_GPIO_INT_MODE_HIGH_LEVEL; 469 break; 470 case 0x8: 471 mode = SUNXI_GPIO_INT_MODE_LOW_LEVEL; 472 break; 473 default: 474 aprint_error_dev(dev, "%s: unsupported irq type 0x%x\n", 475 __func__, type); 476 return NULL; 477 } 478 479 pin_def = sunxi_gpio_lookup(sc, port, pin); 480 if (pin_def == NULL) 481 return NULL; 482 if (pin_def->functions[pin_def->eint_func] == NULL || 483 strcmp(pin_def->functions[pin_def->eint_func], "irq") != 0) 484 return NULL; 485 486 KASSERT(pin_def->eint_num < SUNXI_GPIO_MAX_EINT); 487 488 mutex_enter(&sc->sc_lock); 489 490 eint = &sc->sc_eint[pin_def->eint_bank][pin_def->eint_num]; 491 if (eint->eint_func != NULL) { 492 mutex_exit(&sc->sc_lock); 493 return NULL; /* in use */ 494 } 495 496 /* Set function */ 497 if (sunxi_gpio_setfunc(sc, pin_def, "irq") != 0) { 498 mutex_exit(&sc->sc_lock); 499 return NULL; 500 } 501 502 eint->eint_func = func; 503 eint->eint_arg = arg; 504 eint->eint_flags = flags; 505 eint->eint_bank = pin_def->eint_bank; 506 eint->eint_num = pin_def->eint_num; 507 508 /* Configure eint mode */ 509 val = GPIO_READ(sc, SUNXI_GPIO_INT_CFG(eint->eint_bank, eint->eint_num)); 510 val &= ~SUNXI_GPIO_INT_MODEMASK(eint->eint_num); 511 val |= __SHIFTIN(mode, SUNXI_GPIO_INT_MODEMASK(eint->eint_num)); 512 GPIO_WRITE(sc, SUNXI_GPIO_INT_CFG(eint->eint_bank, eint->eint_num), val); 513 514 /* Enable eint */ 515 val = GPIO_READ(sc, SUNXI_GPIO_INT_CTL(eint->eint_bank)); 516 val |= __BIT(eint->eint_num); 517 GPIO_WRITE(sc, SUNXI_GPIO_INT_CTL(eint->eint_bank), val); 518 519 mutex_exit(&sc->sc_lock); 520 521 return eint; 522 } 523 524 static void 525 sunxi_gpio_disestablish(device_t dev, void *ih) 526 { 527 struct sunxi_gpio_softc * const sc = device_private(dev); 528 struct sunxi_gpio_eint * const eint = ih; 529 uint32_t val; 530 531 KASSERT(eint->eint_func != NULL); 532 533 mutex_enter(&sc->sc_lock); 534 535 /* Disable eint */ 536 val = GPIO_READ(sc, SUNXI_GPIO_INT_CTL(eint->eint_bank)); 537 val &= ~__BIT(eint->eint_num); 538 GPIO_WRITE(sc, SUNXI_GPIO_INT_CTL(eint->eint_bank), val); 539 GPIO_WRITE(sc, SUNXI_GPIO_INT_STATUS(eint->eint_bank), __BIT(eint->eint_num)); 540 541 eint->eint_func = NULL; 542 eint->eint_arg = NULL; 543 eint->eint_flags = 0; 544 545 mutex_exit(&sc->sc_lock); 546 } 547 548 static bool 549 sunxi_gpio_intrstr(device_t dev, u_int *specifier, char *buf, size_t buflen) 550 { 551 struct sunxi_gpio_softc * const sc = device_private(dev); 552 const struct sunxi_gpio_pins *pin_def; 553 554 /* 1st cell is the bank */ 555 /* 2nd cell is the pin */ 556 /* 3rd cell is flags */ 557 if (!specifier) 558 return false; 559 const u_int port = be32toh(specifier[0]); 560 const u_int pin = be32toh(specifier[1]); 561 562 pin_def = sunxi_gpio_lookup(sc, port, pin); 563 if (pin_def == NULL) 564 return false; 565 566 snprintf(buf, buflen, "GPIO %s", pin_def->name); 567 568 return true; 569 } 570 571 static struct fdtbus_interrupt_controller_func sunxi_gpio_intrfuncs = { 572 .establish = sunxi_gpio_establish, 573 .disestablish = sunxi_gpio_disestablish, 574 .intrstr = sunxi_gpio_intrstr, 575 }; 576 577 static const char * 578 sunxi_pinctrl_parse_function(int phandle) 579 { 580 const char *function; 581 582 function = fdtbus_get_string(phandle, "function"); 583 if (function != NULL) 584 return function; 585 586 return fdtbus_get_string(phandle, "allwinner,function"); 587 } 588 589 static const char * 590 sunxi_pinctrl_parse_pins(int phandle, int *pins_len) 591 { 592 int len; 593 594 len = OF_getproplen(phandle, "pins"); 595 if (len > 0) { 596 *pins_len = len; 597 return fdtbus_get_string(phandle, "pins"); 598 } 599 600 len = OF_getproplen(phandle, "allwinner,pins"); 601 if (len > 0) { 602 *pins_len = len; 603 return fdtbus_get_string(phandle, "allwinner,pins"); 604 } 605 606 return NULL; 607 } 608 609 static int 610 sunxi_pinctrl_parse_bias(int phandle) 611 { 612 u_int pull; 613 int bias = -1; 614 615 if (of_hasprop(phandle, "bias-disable")) 616 bias = 0; 617 else if (of_hasprop(phandle, "bias-pull-up")) 618 bias = GPIO_PIN_PULLUP; 619 else if (of_hasprop(phandle, "bias-pull-down")) 620 bias = GPIO_PIN_PULLDOWN; 621 else if (of_getprop_uint32(phandle, "allwinner,pull", &pull) == 0) { 622 switch (pull) { 623 case 0: 624 bias = 0; 625 break; 626 case 1: 627 bias = GPIO_PIN_PULLUP; 628 break; 629 case 2: 630 bias = GPIO_PIN_PULLDOWN; 631 break; 632 } 633 } 634 635 return bias; 636 } 637 638 static int 639 sunxi_pinctrl_parse_drive_strength(int phandle) 640 { 641 int val; 642 643 if (of_getprop_uint32(phandle, "drive-strength", &val) == 0) 644 return val; 645 646 if (of_getprop_uint32(phandle, "allwinner,drive", &val) == 0) 647 return (val + 1) * 10; 648 649 return -1; 650 } 651 652 static int 653 sunxi_pinctrl_set_config(device_t dev, const void *data, size_t len) 654 { 655 struct sunxi_gpio_softc * const sc = device_private(dev); 656 const struct sunxi_gpio_pins *pin_def; 657 int pins_len; 658 659 if (len != 4) 660 return -1; 661 662 const int phandle = fdtbus_get_phandle_from_native(be32dec(data)); 663 664 /* 665 * Required: pins, function 666 * Optional: bias, drive strength 667 */ 668 669 const char *function = sunxi_pinctrl_parse_function(phandle); 670 if (function == NULL) 671 return -1; 672 const char *pins = sunxi_pinctrl_parse_pins(phandle, &pins_len); 673 if (pins == NULL) 674 return -1; 675 676 const int bias = sunxi_pinctrl_parse_bias(phandle); 677 const int drive_strength = sunxi_pinctrl_parse_drive_strength(phandle); 678 679 mutex_enter(&sc->sc_lock); 680 681 for (; pins_len > 0; 682 pins_len -= strlen(pins) + 1, pins += strlen(pins) + 1) { 683 pin_def = sunxi_gpio_lookup_byname(sc, pins); 684 if (pin_def == NULL) { 685 aprint_error_dev(dev, "unknown pin name '%s'\n", pins); 686 continue; 687 } 688 if (sunxi_gpio_setfunc(sc, pin_def, function) != 0) 689 continue; 690 691 if (bias != -1) 692 sunxi_gpio_setpull(sc, pin_def, bias); 693 694 if (drive_strength != -1) 695 sunxi_gpio_setdrv(sc, pin_def, drive_strength); 696 } 697 698 mutex_exit(&sc->sc_lock); 699 700 return 0; 701 } 702 703 static struct fdtbus_pinctrl_controller_func sunxi_pinctrl_funcs = { 704 .set_config = sunxi_pinctrl_set_config, 705 }; 706 707 static int 708 sunxi_gpio_pin_read(void *priv, int pin) 709 { 710 struct sunxi_gpio_softc * const sc = priv; 711 const struct sunxi_gpio_pins *pin_def = &sc->sc_padconf->pins[pin]; 712 uint32_t data; 713 int val; 714 715 KASSERT(pin < sc->sc_padconf->npins); 716 717 const bus_size_t data_reg = SUNXI_GPIO_DATA(pin_def->port); 718 const uint32_t data_mask = __BIT(pin_def->pin); 719 720 /* No lock required for reads */ 721 data = GPIO_READ(sc, data_reg); 722 val = __SHIFTOUT(data, data_mask); 723 724 return val; 725 } 726 727 static void 728 sunxi_gpio_pin_write(void *priv, int pin, int val) 729 { 730 struct sunxi_gpio_softc * const sc = priv; 731 const struct sunxi_gpio_pins *pin_def = &sc->sc_padconf->pins[pin]; 732 uint32_t data; 733 734 KASSERT(pin < sc->sc_padconf->npins); 735 736 const bus_size_t data_reg = SUNXI_GPIO_DATA(pin_def->port); 737 const uint32_t data_mask = __BIT(pin_def->pin); 738 739 mutex_enter(&sc->sc_lock); 740 data = GPIO_READ(sc, data_reg); 741 if (val) 742 data |= data_mask; 743 else 744 data &= ~data_mask; 745 GPIO_WRITE(sc, data_reg, data); 746 mutex_exit(&sc->sc_lock); 747 } 748 749 static void 750 sunxi_gpio_pin_ctl(void *priv, int pin, int flags) 751 { 752 struct sunxi_gpio_softc * const sc = priv; 753 const struct sunxi_gpio_pins *pin_def = &sc->sc_padconf->pins[pin]; 754 755 KASSERT(pin < sc->sc_padconf->npins); 756 757 mutex_enter(&sc->sc_lock); 758 sunxi_gpio_ctl(sc, pin_def, flags); 759 sunxi_gpio_setpull(sc, pin_def, flags); 760 mutex_exit(&sc->sc_lock); 761 } 762 763 static void 764 sunxi_gpio_attach_ports(struct sunxi_gpio_softc *sc) 765 { 766 const struct sunxi_gpio_pins *pin_def; 767 struct gpio_chipset_tag *gp = &sc->sc_gp; 768 struct gpiobus_attach_args gba; 769 u_int pin; 770 771 gp->gp_cookie = sc; 772 gp->gp_pin_read = sunxi_gpio_pin_read; 773 gp->gp_pin_write = sunxi_gpio_pin_write; 774 gp->gp_pin_ctl = sunxi_gpio_pin_ctl; 775 776 const u_int npins = sc->sc_padconf->npins; 777 sc->sc_pins = kmem_zalloc(sizeof(*sc->sc_pins) * npins, KM_SLEEP); 778 779 for (pin = 0; pin < sc->sc_padconf->npins; pin++) { 780 pin_def = &sc->sc_padconf->pins[pin]; 781 sc->sc_pins[pin].pin_num = pin; 782 sc->sc_pins[pin].pin_caps = GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | 783 GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN; 784 sc->sc_pins[pin].pin_state = sunxi_gpio_pin_read(sc, pin); 785 strlcpy(sc->sc_pins[pin].pin_defname, pin_def->name, 786 sizeof(sc->sc_pins[pin].pin_defname)); 787 } 788 789 memset(&gba, 0, sizeof(gba)); 790 gba.gba_gc = gp; 791 gba.gba_pins = sc->sc_pins; 792 gba.gba_npins = npins; 793 sc->sc_gpiodev = config_found_ia(sc->sc_dev, "gpiobus", &gba, NULL); 794 } 795 796 static int 797 sunxi_gpio_match(device_t parent, cfdata_t cf, void *aux) 798 { 799 struct fdt_attach_args * const faa = aux; 800 801 return of_match_compat_data(faa->faa_phandle, compat_data); 802 } 803 804 static void 805 sunxi_gpio_attach(device_t parent, device_t self, void *aux) 806 { 807 struct sunxi_gpio_softc * const sc = device_private(self); 808 struct fdt_attach_args * const faa = aux; 809 const int phandle = faa->faa_phandle; 810 char intrstr[128]; 811 struct fdtbus_reset *rst; 812 struct clk *clk; 813 bus_addr_t addr; 814 bus_size_t size; 815 int child; 816 817 if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { 818 aprint_error(": couldn't get registers\n"); 819 return; 820 } 821 822 if ((clk = fdtbus_clock_get_index(phandle, 0)) != NULL) 823 if (clk_enable(clk) != 0) { 824 aprint_error(": couldn't enable clock\n"); 825 return; 826 } 827 828 if ((rst = fdtbus_reset_get_index(phandle, 0)) != NULL) 829 if (fdtbus_reset_deassert(rst) != 0) { 830 aprint_error(": couldn't de-assert reset\n"); 831 return; 832 } 833 834 sc->sc_dev = self; 835 sc->sc_bst = faa->faa_bst; 836 if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) { 837 aprint_error(": couldn't map registers\n"); 838 return; 839 } 840 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_VM); 841 sc->sc_padconf = (void *)of_search_compatible(phandle, compat_data)->data; 842 843 aprint_naive("\n"); 844 aprint_normal(": PIO\n"); 845 846 fdtbus_register_gpio_controller(self, phandle, &sunxi_gpio_funcs); 847 848 for (child = OF_child(phandle); child; child = OF_peer(child)) { 849 if (!of_hasprop(child, "function") || !of_hasprop(child, "pins")) 850 continue; 851 fdtbus_register_pinctrl_config(self, child, &sunxi_pinctrl_funcs); 852 } 853 854 fdtbus_pinctrl_configure(); 855 856 sunxi_gpio_attach_ports(sc); 857 858 /* Disable all external interrupts */ 859 for (int i = 0; i < sc->sc_padconf->npins; i++) { 860 const struct sunxi_gpio_pins *pin_def = &sc->sc_padconf->pins[i]; 861 if (pin_def->eint_func == 0) 862 continue; 863 GPIO_WRITE(sc, SUNXI_GPIO_INT_CTL(pin_def->eint_bank), __BIT(pin_def->eint_num)); 864 GPIO_WRITE(sc, SUNXI_GPIO_INT_STATUS(pin_def->eint_bank), __BIT(pin_def->eint_num)); 865 866 if (sc->sc_eint_bank_max < pin_def->eint_bank) 867 sc->sc_eint_bank_max = pin_def->eint_bank; 868 } 869 KASSERT(sc->sc_eint_bank_max < SUNXI_GPIO_MAX_EINT_BANK); 870 871 if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) { 872 aprint_error_dev(self, "failed to decode interrupt\n"); 873 return; 874 } 875 sc->sc_ih = fdtbus_intr_establish(phandle, 0, IPL_VM, FDT_INTR_MPSAFE, 876 sunxi_gpio_intr, sc); 877 if (sc->sc_ih == NULL) { 878 aprint_error_dev(self, "failed to establish interrupt on %s\n", 879 intrstr); 880 return; 881 } 882 aprint_normal_dev(self, "interrupting on %s\n", intrstr); 883 fdtbus_register_interrupt_controller(self, phandle, 884 &sunxi_gpio_intrfuncs); 885 } 886