1 /*- 2 * Copyright (c) 2014 The NetBSD Foundation, Inc. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to The NetBSD Foundation 6 * by Reinoud Zandijk 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 * POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 #include "opt_exynos.h" 31 #include "opt_arm_debug.h" 32 #include "gpio.h" 33 34 #include <sys/cdefs.h> 35 __KERNEL_RCSID(1, "$NetBSD: exynos_gpio.c,v 1.6 2014/05/21 12:18:24 reinoud Exp $"); 36 37 #include <sys/param.h> 38 #include <sys/bus.h> 39 #include <sys/device.h> 40 #include <sys/intr.h> 41 #include <sys/systm.h> 42 #include <sys/kmem.h> 43 44 #include <arm/samsung/exynos_reg.h> 45 #include <arm/samsung/exynos_io.h> 46 #include <arm/samsung/exynos_intr.h> 47 48 #include <sys/gpio.h> 49 #include <dev/gpio/gpiovar.h> 50 51 static int exynos_gpio_match(device_t, cfdata_t, void *); 52 static void exynos_gpio_attach(device_t, device_t, void *); 53 54 static int exynos_gpio_pin_read(void *, int); 55 static void exynos_gpio_pin_write(void *, int, int); 56 static void exynos_gpio_pin_ctl(void *, int, int); 57 58 struct exynos_gpio_pin_cfg { 59 uint32_t cfg; 60 uint32_t pud; 61 uint32_t drv; 62 uint32_t conpwd; 63 uint32_t pudpwd; 64 }; 65 66 struct exynos_gpio_pin_group { 67 const char grp_name[6]; 68 const bus_addr_t grp_core_offset; 69 const uint8_t grp_bits; 70 71 uint8_t grp_pin_mask; 72 uint8_t grp_pin_inuse_mask; 73 bus_space_handle_t grp_bsh; 74 struct exynos_gpio_pin_cfg grp_cfg; 75 struct gpio_chipset_tag grp_gc_tag; 76 }; 77 78 79 #define GPIO_REG(v,s,o) (EXYNOS##v##_GPIO_##s##_OFFSET + (o)) 80 #define GPIO_GRP(v, s, o, n, b) \ 81 { \ 82 .grp_name = #n, \ 83 .grp_core_offset = GPIO_REG(v,s,o), \ 84 .grp_bits = b,\ 85 } 86 87 #ifdef EXYNOS4 88 /* 89 * Exynos 4412 contains 304 multi-functional input/output port pins and 164 90 * memory port pins. There are 37 general port groups and two memory port 91 * groups. They are: 92 * 93 * GPA0, GPA1: 14 in/out ports-3xUART with flow control, UART without flow 94 * control, and/or 2xI2C 95 * 96 * GPB: 8 in/out ports-2xSPI and/or 2xI2C and/ or IEM 97 * 98 * GPC0, GPC1: 10 in/out ports-2xI2S, and/or 2xPCM, and/or AC97, SPDIF, I2C, 99 * and/or SPI 100 * 101 * GPD0, GPD1: 8 in/out ports-PWM, 2xI2C, and/ or LCD I/F, MIPI 102 * 103 * GPM0, GPM1, GPM2, GPM3, GPM4: 35 in/out ports-CAM I/F, and/ or TS I/F, 104 * HSI, and/ or Trace I/F 105 * 106 * GPF0, GPF1, GPF2, GPF3: 30 in/out ports-LCD I/F 107 * 108 * GPJ0, GPJ1: 13 in/out ports-CAM I/F 109 * 110 * GPK0, GPK1, GPK2, GPK3: 28 in/out ports-4xMMC (4-bit MMC), and/or 2xMMC 111 * (8-bit MMC)), and/or GPS debugging I/F 112 * 113 * GPL0, GPL1: 11 in/out ports-GPS I/F 114 * 115 * GPL2: 8 in/out ports-GPS debugging I/F or Key pad I/F 116 * 117 * GPX0, GPX1, GPX2, GPX3: 32 in/out ports-External wake-up, and/or Key pad 118 * I/F 119 * 120 * GPZ: 7 in/out ports-low Power I2S and/or PCM 121 * 122 * GPY0, GPY1, GPY2: 16 in/out ports-Control signals of EBI (SROM, NF, One 123 * NAND) 124 * 125 * GPY3, GPY4, GPY5, GPY6: 32 in/out memory ports-EBI (For more information 126 * about EBI configuration, refer to Chapter 5, and 6) 127 * 128 * MP1_0-MP1_9: 78 DRAM1 ports. NOTE: GPIO registers does not control these 129 * ports. 130 * 131 * MP2_0-MP2_9: 78 DRAM2 ports. NOTE: GPIO registers does not control these 132 * ports. 133 * 134 * ETC0, ETC1, ETC6: 18 in/out ETC ports-JTAG, SLIMBUS, RESET, CLOCK 135 * 136 * ETC7, ETC8 : 4 clock port for C2C 137 * 138 */ 139 140 static struct exynos_gpio_pin_group exynos4_pin_groups[] = { 141 GPIO_GRP(4, LEFT, 0x0000, GPA0, 8), 142 GPIO_GRP(4, LEFT, 0x0020, GPA1, 6), 143 GPIO_GRP(4, LEFT, 0x0040, GPB, 8), 144 GPIO_GRP(4, LEFT, 0x0060, GPC0, 5), 145 GPIO_GRP(4, LEFT, 0x0080, GPC1, 5), 146 GPIO_GRP(4, LEFT, 0x00A0, GPD0, 4), 147 GPIO_GRP(4, LEFT, 0x00C0, GPD1, 4), 148 GPIO_GRP(4, LEFT, 0x0180, GPF0, 8), 149 GPIO_GRP(4, LEFT, 0x01A0, GPF1, 8), 150 GPIO_GRP(4, LEFT, 0x01C0, GPF2, 8), 151 GPIO_GRP(4, LEFT, 0x01E0, GPF3, 8), 152 GPIO_GRP(4, LEFT, 0x0240, GPJ0, 8), 153 GPIO_GRP(4, LEFT, 0x0260, GPJ1, 5), 154 /* EXTINT skipped */ 155 156 GPIO_GRP(4, RIGHT, 0x0040, GPK0, 8), 157 GPIO_GRP(4, RIGHT, 0x0060, GPK1, 8), 158 GPIO_GRP(4, RIGHT, 0x0080, GPK2, 7), 159 GPIO_GRP(4, RIGHT, 0x00A0, GPK3, 7), 160 GPIO_GRP(4, RIGHT, 0x00C0, GPL0, 7), 161 GPIO_GRP(4, RIGHT, 0x00E0, GPL1, 2), 162 GPIO_GRP(4, RIGHT, 0x0100, GPL2, 8), 163 GPIO_GRP(4, RIGHT, 0x0120, GPY0, 6), 164 GPIO_GRP(4, RIGHT, 0x0140, GPY1, 4), 165 GPIO_GRP(4, RIGHT, 0x0160, GPY2, 6), 166 GPIO_GRP(4, RIGHT, 0x0180, GPY3, 8), 167 GPIO_GRP(4, RIGHT, 0x01A0, GPY4, 8), 168 GPIO_GRP(4, RIGHT, 0x01C0, GPY5, 8), 169 GPIO_GRP(4, RIGHT, 0x01E0, GPY6, 8), 170 GPIO_GRP(4, RIGHT, 0x0200, ETC0, 6), 171 GPIO_GRP(4, RIGHT, 0x0220, ETC6, 7), 172 GPIO_GRP(4, RIGHT, 0x0260, GPM0, 8), 173 GPIO_GRP(4, RIGHT, 0x0280, GPM1, 7), 174 GPIO_GRP(4, RIGHT, 0x02A0, GPM2, 5), 175 GPIO_GRP(4, RIGHT, 0x02C0, GPM3, 8), 176 GPIO_GRP(4, RIGHT, 0x02E0, GPM4, 8), 177 /* EXTINT skipped */ 178 GPIO_GRP(4, RIGHT, 0x0C00, GPX0, 8), 179 GPIO_GRP(4, RIGHT, 0x0C20, GPX1, 8), 180 GPIO_GRP(4, RIGHT, 0x0C40, GPX2, 8), 181 GPIO_GRP(4, RIGHT, 0x0C60, GPX3, 8), 182 /* EXTINT skipped */ 183 184 GPIO_GRP(4, I2S0, 0x0000, GPZ, 8), 185 /* EXTINT skipped */ 186 187 GPIO_GRP(4, C2C, 0x0000, GPV0, 8), 188 GPIO_GRP(4, C2C, 0x0020, GPV1, 8), 189 GPIO_GRP(4, C2C, 0x0040, ETC7, 2), 190 GPIO_GRP(4, C2C, 0x0060, GPV2, 8), 191 GPIO_GRP(4, C2C, 0x0080, GPV3, 8), 192 GPIO_GRP(4, C2C, 0x00A0, ETC8, 2), 193 GPIO_GRP(4, C2C, 0x00C0, GPV4, 2), 194 /* EXTINT skipped */ 195 }; 196 #endif 197 198 199 #ifdef EXYNOS5 200 static struct exynos_gpio_pin_group exynos5_pin_groups[] = { 201 }; 202 #endif 203 204 205 struct exynos_gpio_softc { 206 device_t sc_dev; 207 bus_space_tag_t sc_bst; 208 bus_space_handle_t sc_bsh; 209 }; 210 211 212 /* force these structures in DATA segment */ 213 static struct exynos_gpio_pin_group *exynos_pin_groups = NULL; 214 static int exynos_n_pin_groups = 0; 215 216 static struct exynos_gpio_softc exynos_gpio_sc = {}; 217 218 219 CFATTACH_DECL_NEW(exynos_gpio, sizeof(struct exynos_gpio_softc), 220 exynos_gpio_match, exynos_gpio_attach, NULL, NULL); 221 222 223 static int 224 exynos_gpio_match(device_t parent, cfdata_t cf, void *aux) 225 { 226 struct exyo_attach_args * const exyoaa = aux; 227 struct exyo_locators *loc = &exyoaa->exyo_loc; 228 229 /* no locators expected */ 230 KASSERT(loc->loc_offset == 0); 231 KASSERT(loc->loc_size == 0); 232 KASSERT(loc->loc_port == EXYOCF_PORT_DEFAULT); 233 234 /* there can only be one */ 235 if (exynos_gpio_sc.sc_dev != NULL) 236 return 0; 237 return 1; 238 } 239 240 241 #if NGPIO > 0 242 static void 243 exynos_gpio_config_pins(device_t self) 244 { 245 struct exynos_gpio_softc * const sc = &exynos_gpio_sc; 246 struct exynos_gpio_pin_group *grp; 247 struct gpiobus_attach_args gba; 248 gpio_pin_t *pin, *pins; 249 size_t pin_count = 0; 250 int i, bit, mask, pincaps, data; 251 252 if (exynos_n_pin_groups == 0) 253 return; 254 255 /* find out how many pins we can offer */ 256 pin_count = 0; 257 for (i = 0; i < exynos_n_pin_groups; i++) { 258 grp = &exynos_pin_groups[i]; 259 mask = grp->grp_pin_mask & ~grp->grp_pin_inuse_mask; 260 pin_count += popcount32(mask); 261 } 262 263 /* if no pins available, don't proceed */ 264 if (pin_count == 0) 265 return; 266 267 /* allocate pin data */ 268 pins = kmem_zalloc(sizeof(gpio_pin_t) * pin_count, KM_SLEEP); 269 KASSERT(pins); 270 271 pincaps = GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | 272 GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN; 273 274 /* add all pins */ 275 pin = pins; 276 for (i = 0; i < exynos_n_pin_groups; i++) { 277 grp = &exynos_pin_groups[i]; 278 mask = grp->grp_pin_mask & ~grp->grp_pin_inuse_mask; 279 if (mask == 0) 280 continue; 281 gba.gba_gc = &grp->grp_gc_tag; 282 gba.gba_pins = pin; 283 data = bus_space_read_1(sc->sc_bst, grp->grp_bsh, 284 EXYNOS_GPIO_DAT); 285 for (bit = 0; mask != 0; mask >>= 1, data >>= 1, bit++) { 286 if (mask & 1) { 287 pin->pin_num = bit + (i << 3); 288 pin->pin_caps = pincaps; 289 pin->pin_flags = pincaps; 290 pin->pin_state = (data & 1) != 0; 291 pin++; 292 } 293 } 294 gba.gba_npins = pin - gba.gba_pins; 295 config_found_ia(self, "gpiobus", &gba, gpiobus_print); 296 } 297 } 298 #endif 299 300 301 static void 302 exynos_gpio_attach(device_t parent, device_t self, void *aux) 303 { 304 struct exynos_gpio_softc * const sc = &exynos_gpio_sc; 305 struct exyo_attach_args * const exyoaa = aux; 306 struct exynos_gpio_pin_group *grp; 307 prop_dictionary_t dict = device_properties(self); 308 uint32_t nc; 309 char scrap[16]; 310 int i; 311 312 /* construct softc */ 313 sc->sc_dev = self; 314 315 /* we use the core bushandle here */ 316 sc->sc_bst = exyoaa->exyo_core_bst; 317 sc->sc_bsh = exyoaa->exyo_core_bsh; 318 319 exynos_gpio_bootstrap(); 320 if (exynos_n_pin_groups == 0) { 321 printf(": disabled, no pins defined\n"); 322 return; 323 } 324 325 KASSERT(exynos_pin_groups); 326 KASSERT(exynos_n_pin_groups); 327 328 aprint_naive("\n"); 329 aprint_normal("\n"); 330 331 /* go trough all pin groups */ 332 for (i = 0; i < exynos_n_pin_groups; i++) { 333 grp = &exynos_pin_groups[i]; 334 snprintf(scrap, sizeof(scrap), "nc-%s", grp->grp_name); 335 if (prop_dictionary_get_uint32(dict, scrap, &nc)) { 336 KASSERT((~grp->grp_pin_mask & nc) == 0); 337 /* switch off the pins we have signalled NC */ 338 grp->grp_pin_mask &= ~nc; 339 #if 0 340 printf("%s: %-4s inuse_mask %02x, pin_mask %02x\n", 341 __func__, grp->grp_name, 342 grp->grp_pin_inuse_mask, grp->grp_pin_mask); 343 #endif 344 } 345 } 346 347 #if NGPIO > 0 348 config_defer(self, exynos_gpio_config_pins); 349 #endif 350 } 351 352 353 /* pin access functions */ 354 static u_int 355 exynos_gpio_get_pin_func(const struct exynos_gpio_pin_cfg *cfg, int pin) 356 { 357 const u_int shift = (pin & 7) << 2; 358 359 return (cfg->cfg >> shift) & 0x0f; 360 } 361 362 363 static void 364 exynos_gpio_set_pin_func(struct exynos_gpio_pin_cfg *cfg, 365 int pin, int func) 366 { 367 const u_int shift = (pin & 7) << 2; 368 369 cfg->cfg &= ~(0x0f << shift); 370 cfg->cfg |= func << shift; 371 } 372 373 374 static void 375 exynos_gpio_set_pin_pull(struct exynos_gpio_pin_cfg *cfg, int pin, int pull) 376 { 377 const u_int shift = (pin & 7) << 1; 378 379 cfg->pud &= ~(0x3 << shift); 380 cfg->pud |= pull << shift; 381 } 382 383 384 static int 385 exynos_gpio_pin_read(void *cookie, int pin) 386 { 387 struct exynos_gpio_pin_group * const grp = cookie; 388 389 KASSERT(pin < grp->grp_bits); 390 return (bus_space_read_1(exynos_gpio_sc.sc_bst, grp->grp_bsh, 391 EXYNOS_GPIO_DAT) >> pin) & 1; 392 } 393 394 395 static void 396 exynos_gpio_pin_write(void *cookie, int pin, int value) 397 { 398 struct exynos_gpio_pin_group * const grp = cookie; 399 int val; 400 401 KASSERT(pin < grp->grp_bits); 402 val = bus_space_read_1(exynos_gpio_sc.sc_bst, grp->grp_bsh, 403 EXYNOS_GPIO_DAT); 404 val &= ~__BIT(pin); 405 if (value) 406 val |= __BIT(pin); 407 bus_space_write_1(exynos_gpio_sc.sc_bst, grp->grp_bsh, 408 EXYNOS_GPIO_DAT, val); 409 } 410 411 412 static void 413 exynos_gpio_update_cfg_regs(struct exynos_gpio_pin_group *grp, 414 const struct exynos_gpio_pin_cfg *ncfg) 415 { 416 bus_space_tag_t bst = &exynos_bs_tag; 417 418 if (grp->grp_cfg.cfg != ncfg->cfg) { 419 bus_space_write_4(bst, grp->grp_bsh, 420 EXYNOS_GPIO_CON, ncfg->cfg); 421 grp->grp_cfg.cfg = ncfg->cfg; 422 } 423 if (grp->grp_cfg.pud != ncfg->pud) { 424 bus_space_write_4(bst, grp->grp_bsh, 425 EXYNOS_GPIO_PUD, ncfg->pud); 426 grp->grp_cfg.pud = ncfg->pud; 427 } 428 429 /* the following attributes are not yet setable */ 430 #if 0 431 if (grp->grp_cfg.drv != ncfg->drv) { 432 bus_space_write_4(bst, grp->grp_bsh, 433 EXYNOS_GPIO_DRV, ncfg->drv); 434 grp->grp_cfg.drv = ncfg->drv; 435 } 436 if (grp->grp_cfg.conpwd != ncfg->conpwd) { 437 bus_space_write_4(bst, grp->grp_bsh, 438 EXYNOS_GPIO_CONPWD, ncfg->conpwd); 439 grp->grp_cfg.conpwd = ncfg->conpwd; 440 } 441 if (grp->grp_cfg.pudpwd != ncfg->pudpwd) { 442 bus_space_write_4(bst, grp->grp_bsh, 443 EXYNOS_GPIO_PUDPWD, ncfg->pudpwd); 444 grp->grp_cfg.pudpwd = ncfg->pudpwd; 445 } 446 #endif 447 } 448 449 450 static void 451 exynos_gpio_pin_ctl(void *cookie, int pin, int flags) 452 { 453 struct exynos_gpio_pin_group * const grp = cookie; 454 struct exynos_gpio_pin_cfg ncfg = grp->grp_cfg; 455 int pull; 456 457 /* honour pullup requests */ 458 pull = EXYNOS_GPIO_PIN_FLOAT; 459 if (flags & GPIO_PIN_PULLUP) 460 pull = EXYNOS_GPIO_PIN_PULL_UP; 461 if (flags & GPIO_PIN_PULLDOWN) 462 pull = EXYNOS_GPIO_PIN_PULL_DOWN; 463 exynos_gpio_set_pin_pull(&ncfg, pin, pull); 464 465 /* honour i/o */ 466 if (flags & GPIO_PIN_INPUT) 467 exynos_gpio_set_pin_func(&ncfg, pin, EXYNOS_GPIO_FUNC_INPUT); 468 if (flags & GPIO_PIN_OUTPUT) 469 exynos_gpio_set_pin_func(&ncfg, pin, EXYNOS_GPIO_FUNC_OUTPUT); 470 471 /* update any config registers that changed */ 472 exynos_gpio_update_cfg_regs(grp, &ncfg); 473 } 474 475 476 bool 477 exynos_gpio_pinset_available(const struct exynos_gpio_pinset *req) 478 { 479 struct exynos_gpio_pin_group *grp; 480 int i, n, inuse; 481 482 KASSERT(req); 483 if (exynos_n_pin_groups == 0) 484 return false; 485 486 /* we need a pinset group */ 487 if (strlen(req->pinset_group) == 0) 488 return false; 489 490 /* determine which group is requested */ 491 grp = NULL; 492 for (i = 0; i < exynos_n_pin_groups; i++) { 493 grp = &exynos_pin_groups[i]; 494 if (strcmp(req->pinset_group, grp->grp_name) == 0) 495 break; 496 } 497 /* found? */ 498 if (i == exynos_n_pin_groups) 499 return false; 500 KASSERT(grp); 501 502 /* fail unconnected pins */ 503 if (req->pinset_mask & ~grp->grp_pin_mask) 504 return false; 505 506 /* if none in use, they are available */ 507 if (req->pinset_mask & ~grp->grp_pin_inuse_mask) 508 return true; 509 510 /* OK, so some are in use; now see if the request is compatible */ 511 inuse = req->pinset_mask & grp->grp_pin_inuse_mask; 512 for (i = 0; inuse; i++, inuse >>= 1) { 513 /* try to be smart by skipping zero's */ 514 n = ffs(inuse) -1; 515 i += n; 516 inuse >>= n; 517 /* this pin is in use, check its usage */ 518 if (exynos_gpio_get_pin_func(&grp->grp_cfg, i) != req->pinset_func) 519 return false; 520 } 521 522 /* seems to be OK */ 523 return true; 524 } 525 526 527 void 528 exynos_gpio_pinset_acquire(const struct exynos_gpio_pinset *req) 529 { 530 struct exynos_gpio_pin_group *grp; 531 struct exynos_gpio_pin_cfg ncfg; 532 int i, n, todo; 533 534 KASSERT(req); 535 KASSERT(exynos_gpio_pinset_available(req)); 536 537 /* determine which group is requested */ 538 grp = NULL; 539 for (i = 0; i < exynos_n_pin_groups; i++) { 540 grp = &exynos_pin_groups[i]; 541 if (strcmp(req->pinset_group, grp->grp_name) == 0) 542 break; 543 } 544 KASSERT(grp); 545 546 /* check if all the pins have the right function */ 547 if ((req->pinset_mask & ~grp->grp_pin_inuse_mask) == 0) 548 return; 549 550 /* copy current config for update routine */ 551 ncfg = grp->grp_cfg; 552 553 /* update the function of each pin that is not in use */ 554 todo = req->pinset_mask & grp->grp_pin_inuse_mask; 555 for (i = 0; todo; i++, todo >>= 1) { 556 /* try to be smart by skipping zero's */ 557 n = ffs(todo) -1; 558 i += n; 559 todo >>= n; 560 /* change the function of this pin */ 561 exynos_gpio_set_pin_func(&ncfg, i, req->pinset_func); 562 } 563 564 /* update config registers */ 565 exynos_gpio_update_cfg_regs(grp, &ncfg); 566 567 /* mark pins in use */ 568 grp->grp_pin_inuse_mask |= req->pinset_mask; 569 } 570 571 572 /* get a pindata structure from a pinset structure */ 573 void 574 exynos_gpio_pinset_to_pindata(const struct exynos_gpio_pinset *req, int pinnr, 575 struct exynos_gpio_pindata *pd) 576 { 577 struct exynos_gpio_pin_group *grp; 578 int i; 579 580 KASSERT(req); 581 KASSERT(pd); 582 KASSERT(req->pinset_mask & __BIT(pinnr)); 583 584 /* determine which group is requested */ 585 grp = NULL; 586 for (i = 0; i < exynos_n_pin_groups; i++) { 587 grp = &exynos_pin_groups[i]; 588 if (strcmp(req->pinset_group, grp->grp_name) == 0) 589 break; 590 } 591 KASSERT(grp); 592 593 pd->pd_gc = &grp->grp_gc_tag; 594 pd->pd_pin = pinnr; 595 } 596 597 598 /* XXXRPZ This release doesn't grock multiple usages! */ 599 void 600 exynos_gpio_pinset_release(const struct exynos_gpio_pinset *req) 601 { 602 struct exynos_gpio_pin_group *grp; 603 int i; 604 605 KASSERT(!exynos_gpio_pinset_available(req)); 606 607 /* determine which group is requested */ 608 grp = NULL; 609 for (i = 0; i < exynos_n_pin_groups; i++) { 610 grp = &exynos_pin_groups[i]; 611 if (strcmp(req->pinset_group, grp->grp_name) == 0) 612 break; 613 } 614 KASSERT(grp); 615 616 /* bluntly mark as not being in use */ 617 grp->grp_pin_inuse_mask &= ~req->pinset_mask; 618 } 619 620 621 /* 622 * name convention : 623 * pin = <func><groupname><pinnr>[<pud>] 624 * func = '<' | '>' 625 * pinnr = '['['0'-'7']']' 626 * pud = 'F' | 'U' | 'D' 627 * 628 * example "<GPC1[0]", ">GPB[0]" 629 */ 630 631 bool 632 exynos_gpio_pin_reserve(const char *name, struct exynos_gpio_pindata *pd) 633 { 634 struct exynos_gpio_softc * const sc = &exynos_gpio_sc; 635 struct exynos_gpio_pin_group *grp; 636 struct exynos_gpio_pin_cfg ncfg; 637 prop_dictionary_t dict = device_properties(sc->sc_dev); 638 const char *pin_data; 639 char grp_name[15], *pos; 640 int func, pud, pinnr; 641 int pi, i; 642 643 if (exynos_n_pin_groups == 0) 644 return false; 645 646 /* do we have a named pin description? */ 647 if (!prop_dictionary_get_cstring_nocopy(dict, name, &pin_data)) 648 return false; 649 650 KASSERT(strlen(pin_data) < 10); 651 if (!(pin_data[0] == '>' || pin_data[0] == '<')) { 652 printf("%s: malformed pin data in '%s', missing direction\n", 653 __func__, pin_data); 654 return false; 655 } 656 657 func = (pin_data[0] == '<') ? 658 EXYNOS_GPIO_FUNC_INPUT : EXYNOS_GPIO_FUNC_OUTPUT; 659 660 /* find groupname */ 661 pi = 1; pos = grp_name; 662 while (pin_data[pi] && pin_data[pi] != '[') { 663 *pos++ = pin_data[pi++]; 664 } 665 if (pin_data[pi] != '[') { 666 printf("%s: malformed pin data in '%s', missing '['\n", 667 __func__, pin_data); 668 return false; 669 } 670 *pos++ = (char) 0; 671 672 /* skip '[' */ 673 pi++; 674 if (!(pin_data[pi] >= '0' && pin_data[pi] <= '7')) { 675 printf("%s: malformed pin data in '%s', bad pin number\n", 676 __func__, pin_data); 677 return false; 678 } 679 pinnr = pin_data[pi] - '0'; 680 681 /* skip digit */ 682 pi++; 683 if ((pin_data[pi] != ']')) { 684 printf("%s: malformed pin data in '%s', missing end ']'\n", 685 __func__, pin_data); 686 return false; 687 } 688 689 /* skip ']' */ 690 pi++; 691 pud = EXYNOS_GPIO_PIN_FLOAT; 692 switch (tolower(pin_data[pi])) { 693 case (char) 0: 694 break; 695 case 'f': 696 pud = EXYNOS_GPIO_PIN_FLOAT; 697 break; 698 case 'u': 699 pud = EXYNOS_GPIO_PIN_PULL_UP; 700 break; 701 case 'd': 702 pud = EXYNOS_GPIO_PIN_PULL_DOWN; 703 break; 704 default: 705 printf("%s: malformed pin data in '%s', expecting " 706 "optional pull up/down or float argument\n", 707 __func__, pin_data); 708 return false; 709 } 710 711 /* determine which group is requested */ 712 grp = NULL; 713 for (i = 0; i < exynos_n_pin_groups; i++) { 714 grp = &exynos_pin_groups[i]; 715 if (strcmp(grp_name, grp->grp_name) == 0) 716 break; 717 } 718 719 /* found? */ 720 if (i >= exynos_n_pin_groups) { 721 printf("%s: malformed pin data in '%s', " 722 "no such pin group name\n", 723 __func__, grp_name); 724 return false; 725 } 726 KASSERT(grp); 727 728 /* in range? */ 729 if (pinnr >= grp->grp_bits) 730 return false; 731 732 /* marked as connected? */ 733 if ((grp->grp_pin_mask & __BIT(pinnr)) == 0) 734 return false; 735 736 /* it better not be used!! this is not taken lightly */ 737 KASSERT((grp->grp_pin_inuse_mask & __BIT(pinnr)) == 0); 738 739 /* update our pin configuration */ 740 ncfg = grp->grp_cfg; 741 exynos_gpio_set_pin_func(&ncfg, pinnr, func); 742 exynos_gpio_set_pin_pull(&ncfg, pinnr, pud); 743 exynos_gpio_update_cfg_regs(grp, &ncfg); 744 745 grp->grp_pin_inuse_mask |= __BIT(pinnr); 746 grp->grp_pin_mask &= ~__BIT(pinnr); 747 748 pd->pd_gc = &grp->grp_gc_tag; 749 pd->pd_pin = pinnr; 750 751 return true; 752 } 753 754 755 /* bootstrapping */ 756 void 757 exynos_gpio_bootstrap(void) 758 { 759 bus_space_tag_t bst = &exynos_bs_tag; 760 struct exynos_gpio_pin_group *grp; 761 struct gpio_chipset_tag *gc_tag; 762 int i; 763 764 /* determine what we're running on */ 765 #ifdef EXYNOS4 766 if (IS_EXYNOS4_P()) { 767 exynos_pin_groups = exynos4_pin_groups; 768 exynos_n_pin_groups = __arraycount(exynos4_pin_groups); 769 } 770 #endif 771 #ifdef EXYNOS5 772 if (IS_EXYNOS5_P()) { 773 exynos_pin_groups = exynos5_pin_groups; 774 exynos_n_pin_groups = __arraycount(exynos5_pin_groups); 775 } 776 #endif 777 778 if (exynos_n_pin_groups == 0) 779 return; 780 781 /* init groups */ 782 for (i = 0; i < exynos_n_pin_groups; i++) { 783 grp = &exynos_pin_groups[i]; 784 gc_tag = &grp->grp_gc_tag; 785 786 bus_space_subregion(&exynos_bs_tag, exynos_core_bsh, 787 grp->grp_core_offset, EXYNOS_GPIO_GRP_SIZE, 788 &grp->grp_bsh); 789 KASSERT(&grp->grp_bsh); 790 791 grp->grp_pin_mask = __BIT(grp->grp_bits) - 1; 792 grp->grp_pin_inuse_mask = 0; 793 794 gc_tag->gp_cookie = grp; 795 gc_tag->gp_pin_read = exynos_gpio_pin_read; 796 gc_tag->gp_pin_write = exynos_gpio_pin_write; 797 gc_tag->gp_pin_ctl = exynos_gpio_pin_ctl; 798 799 /* read in our initial settings */ 800 grp->grp_cfg.cfg = bus_space_read_4(bst, grp->grp_bsh, 801 EXYNOS_GPIO_CON); 802 grp->grp_cfg.pud = bus_space_read_4(bst, grp->grp_bsh, 803 EXYNOS_GPIO_PUD); 804 grp->grp_cfg.drv = bus_space_read_4(bst, grp->grp_bsh, 805 EXYNOS_GPIO_DRV); 806 grp->grp_cfg.conpwd = bus_space_read_4(bst, grp->grp_bsh, 807 EXYNOS_GPIO_CONPWD); 808 grp->grp_cfg.pudpwd = bus_space_read_4(bst, grp->grp_bsh, 809 EXYNOS_GPIO_PUDPWD); 810 811 /* 812 * Normally we would count the busy pins. 813 * 814 * We can't check inuse here since uboot has used pins for its 815 * own use and left them configured forbidding us to use pins 816 * for our own sake. 817 */ 818 #if 0 819 for (int j = 0, int mask = 1; 820 (mask & grp->grp_pin_mask) != 0; 821 j++, mask <<= 1) { 822 int func = exynos_gpio_get_pin_func(&grp->grp_cfg, j); 823 if (func > EXYNOS_GPIO_FUNC_INPUT) { 824 printf("%s: %s[%d] func %d\n", __func__, 825 grp->grp_name, j, func); 826 } 827 } 828 #endif 829 } 830 #if 0 831 printf("\n"); 832 printf("default NC pin list generated: \n"); 833 /* enable this for default NC pins list generation */ 834 for (i = 0; i < exynos_n_pin_groups; i++) { 835 grp = &exynos_pin_groups[i]; 836 printf("prop_dictionary_set_uint32(dict, \"nc-%s\", " 837 "0x%02x - 0b00000000);\n", 838 grp->grp_name, grp->grp_pin_mask); 839 } 840 #endif 841 } 842 843