1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright 2020 Michal Meloun <mmel@FreeBSD.org> 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28 #include <sys/cdefs.h> 29 __FBSDID("$FreeBSD$"); 30 31 #include <sys/param.h> 32 #include <sys/systm.h> 33 #include <sys/bus.h> 34 #include <sys/gpio.h> 35 #include <sys/kernel.h> 36 #include <sys/malloc.h> 37 #include <sys/sx.h> 38 39 #include <machine/bus.h> 40 41 #include <dev/fdt/fdt_common.h> 42 #include <dev/gpio/gpiobusvar.h> 43 44 #include "max77620.h" 45 46 MALLOC_DEFINE(M_MAX77620_GPIO, "MAX77620 gpio", "MAX77620 GPIO"); 47 48 #define NGPIO 8 49 50 #define GPIO_LOCK(_sc) sx_slock(&(_sc)->gpio_lock) 51 #define GPIO_UNLOCK(_sc) sx_unlock(&(_sc)->gpio_lock) 52 #define GPIO_ASSERT(_sc) sx_assert(&(_sc)->gpio_lock, SA_LOCKED) 53 54 enum prop_id { 55 CFG_BIAS_PULL_UP, 56 CFG_BIAS_PULL_DOWN, 57 CFG_OPEN_DRAIN, 58 CFG_PUSH_PULL, 59 60 CFG_ACTIVE_FPS_SRC, 61 CFG_ACTIVE_PWRUP_SLOT, 62 CFG_ACTIVE_PWRDOWN_SLOT, 63 CFG_SUSPEND_FPS_SRC, 64 CFG_SUSPEND_PWRUP_SLOT, 65 CFG_SUSPEND_PWRDOWN_SLOT, 66 67 PROP_ID_MAX_ID 68 }; 69 70 static const struct { 71 const char *name; 72 enum prop_id id; 73 } max77620_prop_names[] = { 74 {"bias-pull-up", CFG_BIAS_PULL_UP}, 75 {"bias-pull-down", CFG_BIAS_PULL_DOWN}, 76 {"drive-open-drain", CFG_OPEN_DRAIN}, 77 {"drive-push-pull", CFG_PUSH_PULL}, 78 {"maxim,active-fps-source", CFG_ACTIVE_FPS_SRC}, 79 {"maxim,active-fps-power-up-slot", CFG_ACTIVE_PWRUP_SLOT}, 80 {"maxim,active-fps-power-down-slot", CFG_ACTIVE_PWRDOWN_SLOT}, 81 {"maxim,suspend-fps-source", CFG_SUSPEND_FPS_SRC}, 82 {"maxim,suspend-fps-power-up-slot", CFG_SUSPEND_PWRUP_SLOT}, 83 {"maxim,suspend-fps-power-down-slot", CFG_SUSPEND_PWRDOWN_SLOT}, 84 }; 85 86 /* Configuration for one pin group. */ 87 struct max77620_pincfg { 88 bool alt_func; 89 int params[PROP_ID_MAX_ID]; 90 }; 91 92 static char *altfnc_table[] = { 93 "lpm-control-in", 94 "fps-out", 95 "32k-out1", 96 "sd0-dvs-in", 97 "sd1-dvs-in", 98 "reference-out", 99 }; 100 101 struct max77620_gpio_pin { 102 int pin_caps; 103 char pin_name[GPIOMAXNAME]; 104 uint8_t reg; 105 106 /* Runtime data */ 107 bool alt_func; /* GPIO or alternate function */ 108 }; 109 110 /* -------------------------------------------------------------------------- 111 * 112 * Pinmux functions. 113 */ 114 static int 115 max77620_pinmux_get_function(struct max77620_softc *sc, char *name, 116 struct max77620_pincfg *cfg) 117 { 118 int i; 119 120 if (strcmp("gpio", name) == 0) { 121 cfg->alt_func = false; 122 return (0); 123 } 124 for (i = 0; i < nitems(altfnc_table); i++) { 125 if (strcmp(altfnc_table[i], name) == 0) { 126 cfg->alt_func = true; 127 return (0); 128 } 129 } 130 return (-1); 131 } 132 133 static int 134 max77620_pinmux_set_fps(struct max77620_softc *sc, int pin_num, 135 struct max77620_gpio_pin *pin) 136 { 137 #if 0 138 struct max77620_fps_config *fps_config = &mpci->fps_config[pin]; 139 int addr, ret; 140 int param_val; 141 int mask, shift; 142 143 if ((pin < 1) || (pin > 3)) 144 return (0); 145 146 switch (param) { 147 case MAX77620_ACTIVE_FPS_SOURCE: 148 case MAX77620_SUSPEND_FPS_SOURCE: 149 mask = MAX77620_FPS_SRC_MASK; 150 shift = MAX77620_FPS_SRC_SHIFT; 151 param_val = fps_config->active_fps_src; 152 if (param == MAX77620_SUSPEND_FPS_SOURCE) 153 param_val = fps_config->suspend_fps_src; 154 break; 155 156 case MAX77620_ACTIVE_FPS_POWER_ON_SLOTS: 157 case MAX77620_SUSPEND_FPS_POWER_ON_SLOTS: 158 mask = MAX77620_FPS_PU_PERIOD_MASK; 159 shift = MAX77620_FPS_PU_PERIOD_SHIFT; 160 param_val = fps_config->active_power_up_slots; 161 if (param == MAX77620_SUSPEND_FPS_POWER_ON_SLOTS) 162 param_val = fps_config->suspend_power_up_slots; 163 break; 164 165 case MAX77620_ACTIVE_FPS_POWER_DOWN_SLOTS: 166 case MAX77620_SUSPEND_FPS_POWER_DOWN_SLOTS: 167 mask = MAX77620_FPS_PD_PERIOD_MASK; 168 shift = MAX77620_FPS_PD_PERIOD_SHIFT; 169 param_val = fps_config->active_power_down_slots; 170 if (param == MAX77620_SUSPEND_FPS_POWER_DOWN_SLOTS) 171 param_val = fps_config->suspend_power_down_slots; 172 break; 173 174 default: 175 dev_err(mpci->dev, "Invalid parameter %d for pin %d\n", 176 param, pin); 177 return -EINVAL; 178 } 179 180 if (param_val < 0) 181 return 0; 182 183 ret = regmap_update_bits(mpci->rmap, addr, mask, param_val << shift); 184 if (ret < 0) 185 dev_err(mpci->dev, "Reg 0x%02x update failed %d\n", addr, ret); 186 187 return ret; 188 #endif 189 return (0); 190 } 191 192 static int 193 max77620_pinmux_config_node(struct max77620_softc *sc, char *pin_name, 194 struct max77620_pincfg *cfg) 195 { 196 struct max77620_gpio_pin *pin; 197 uint8_t reg; 198 int pin_num, rv; 199 200 for (pin_num = 0; pin_num < sc->gpio_npins; pin_num++) { 201 if (strcmp(sc->gpio_pins[pin_num]->pin_name, pin_name) == 0) 202 break; 203 } 204 if (pin_num >= sc->gpio_npins) { 205 device_printf(sc->dev, "Unknown pin: %s\n", pin_name); 206 return (ENXIO); 207 } 208 pin = sc->gpio_pins[pin_num]; 209 210 rv = max77620_pinmux_set_fps(sc, pin_num, pin); 211 if (rv != 0) 212 return (rv); 213 214 rv = RD1(sc, pin->reg, ®); 215 if (rv != 0) { 216 device_printf(sc->dev, "Cannot read GIPO_CFG register\n"); 217 return (ENXIO); 218 } 219 220 if (cfg->alt_func) { 221 pin->alt_func = true; 222 sc->gpio_reg_ame |= 1 << pin_num; 223 } else { 224 pin->alt_func = false; 225 sc->gpio_reg_ame &= ~(1 << pin_num); 226 } 227 228 /* Pull up/down. */ 229 switch (cfg->params[CFG_BIAS_PULL_UP]) { 230 case 1: 231 sc->gpio_reg_pue |= 1 << pin_num; 232 break; 233 case 0: 234 sc->gpio_reg_pue &= ~(1 << pin_num); 235 break; 236 default: 237 break; 238 } 239 240 switch (cfg->params[CFG_BIAS_PULL_DOWN]) { 241 case 1: 242 sc->gpio_reg_pde |= 1 << pin_num; 243 break; 244 case 0: 245 sc->gpio_reg_pde &= ~(1 << pin_num); 246 break; 247 default: 248 break; 249 } 250 251 /* Open drain/push-pull modes. */ 252 if (cfg->params[CFG_OPEN_DRAIN] == 1) { 253 reg &= ~MAX77620_REG_GPIO_DRV(~0); 254 reg |= MAX77620_REG_GPIO_DRV(MAX77620_REG_GPIO_DRV_OPENDRAIN); 255 } 256 257 if (cfg->params[CFG_PUSH_PULL] == 1) { 258 reg &= ~MAX77620_REG_GPIO_DRV(~0); 259 reg |= MAX77620_REG_GPIO_DRV(MAX77620_REG_GPIO_DRV_PUSHPULL); 260 } 261 262 rv = WR1(sc, pin->reg, reg); 263 if (rv != 0) { 264 device_printf(sc->dev, "Cannot read GIPO_CFG register\n"); 265 return (ENXIO); 266 } 267 268 return (0); 269 } 270 271 static int 272 max77620_pinmux_read_node(struct max77620_softc *sc, phandle_t node, 273 struct max77620_pincfg *cfg, char **pins, int *lpins) 274 { 275 char *function; 276 int rv, i; 277 278 *lpins = OF_getprop_alloc(node, "pins", (void **)pins); 279 if (*lpins <= 0) 280 return (ENOENT); 281 282 /* Read function (mux) settings. */ 283 rv = OF_getprop_alloc(node, "function", (void **)&function); 284 if (rv > 0) { 285 rv = max77620_pinmux_get_function(sc, function, cfg); 286 if (rv == -1) { 287 device_printf(sc->dev, 288 "Unknown function %s\n", function); 289 OF_prop_free(function); 290 return (ENXIO); 291 } 292 } 293 294 /* Read numeric properties. */ 295 for (i = 0; i < PROP_ID_MAX_ID; i++) { 296 rv = OF_getencprop(node, max77620_prop_names[i].name, 297 &cfg->params[i], sizeof(cfg->params[i])); 298 if (rv <= 0) 299 cfg->params[i] = -1; 300 } 301 302 OF_prop_free(function); 303 return (0); 304 } 305 306 static int 307 max77620_pinmux_process_node(struct max77620_softc *sc, phandle_t node) 308 { 309 struct max77620_pincfg cfg; 310 char *pins, *pname; 311 int i, len, lpins, rv; 312 313 rv = max77620_pinmux_read_node(sc, node, &cfg, &pins, &lpins); 314 if (rv != 0) 315 return (rv); 316 317 len = 0; 318 pname = pins; 319 do { 320 i = strlen(pname) + 1; 321 rv = max77620_pinmux_config_node(sc, pname, &cfg); 322 if (rv != 0) { 323 device_printf(sc->dev, 324 "Cannot configure pin: %s: %d\n", pname, rv); 325 } 326 len += i; 327 pname += i; 328 } while (len < lpins); 329 330 if (pins != NULL) 331 OF_prop_free(pins); 332 333 return (rv); 334 } 335 336 int max77620_pinmux_configure(device_t dev, phandle_t cfgxref) 337 { 338 struct max77620_softc *sc; 339 phandle_t node, cfgnode; 340 uint8_t old_reg_pue, old_reg_pde, old_reg_ame; 341 int rv; 342 343 sc = device_get_softc(dev); 344 cfgnode = OF_node_from_xref(cfgxref); 345 346 old_reg_pue = sc->gpio_reg_pue; 347 old_reg_pde = sc->gpio_reg_pde; 348 old_reg_ame = sc->gpio_reg_ame; 349 350 for (node = OF_child(cfgnode); node != 0; node = OF_peer(node)) { 351 if (!ofw_bus_node_status_okay(node)) 352 continue; 353 rv = max77620_pinmux_process_node(sc, node); 354 if (rv != 0) 355 device_printf(dev, "Failed to process pinmux"); 356 357 } 358 359 if (old_reg_pue != sc->gpio_reg_pue) { 360 rv = WR1(sc, MAX77620_REG_PUE_GPIO, sc->gpio_reg_pue); 361 if (rv != 0) { 362 device_printf(sc->dev, 363 "Cannot update PUE_GPIO register\n"); 364 return (ENXIO); 365 } 366 } 367 368 if (old_reg_pde != sc->gpio_reg_pde) { 369 rv = WR1(sc, MAX77620_REG_PDE_GPIO, sc->gpio_reg_pde); 370 if (rv != 0) { 371 device_printf(sc->dev, 372 "Cannot update PDE_GPIO register\n"); 373 return (ENXIO); 374 } 375 } 376 377 if (old_reg_ame != sc->gpio_reg_ame) { 378 rv = WR1(sc, MAX77620_REG_AME_GPIO, sc->gpio_reg_ame); 379 if (rv != 0) { 380 device_printf(sc->dev, 381 "Cannot update PDE_GPIO register\n"); 382 return (ENXIO); 383 } 384 } 385 386 return (0); 387 } 388 389 /* -------------------------------------------------------------------------- 390 * 391 * GPIO 392 */ 393 device_t 394 max77620_gpio_get_bus(device_t dev) 395 { 396 struct max77620_softc *sc; 397 398 sc = device_get_softc(dev); 399 return (sc->gpio_busdev); 400 } 401 402 int 403 max77620_gpio_pin_max(device_t dev, int *maxpin) 404 { 405 406 *maxpin = NGPIO - 1; 407 return (0); 408 } 409 410 int 411 max77620_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps) 412 { 413 struct max77620_softc *sc; 414 415 sc = device_get_softc(dev); 416 if (pin >= sc->gpio_npins) 417 return (EINVAL); 418 GPIO_LOCK(sc); 419 *caps = sc->gpio_pins[pin]->pin_caps; 420 GPIO_UNLOCK(sc); 421 return (0); 422 } 423 424 int 425 max77620_gpio_pin_getname(device_t dev, uint32_t pin, char *name) 426 { 427 struct max77620_softc *sc; 428 429 sc = device_get_softc(dev); 430 if (pin >= sc->gpio_npins) 431 return (EINVAL); 432 GPIO_LOCK(sc); 433 memcpy(name, sc->gpio_pins[pin]->pin_name, GPIOMAXNAME); 434 GPIO_UNLOCK(sc); 435 return (0); 436 } 437 438 static int 439 max77620_gpio_get_mode(struct max77620_softc *sc, uint32_t pin_num, 440 uint32_t *out_flags) 441 { 442 struct max77620_gpio_pin *pin; 443 uint8_t reg; 444 int rv; 445 446 pin = sc->gpio_pins[pin_num]; 447 *out_flags = 0; 448 449 rv = RD1(sc, pin->reg, ®); 450 if (rv != 0) { 451 device_printf(sc->dev, "Cannot read GIPO_CFG register\n"); 452 return (ENXIO); 453 } 454 455 /* Pin function */ 456 pin->alt_func = sc->gpio_reg_ame & (1 << pin_num); 457 458 /* Pull up/down. */ 459 if (sc->gpio_reg_pue & (1 << pin_num)) 460 *out_flags |= GPIO_PIN_PULLUP; 461 if (sc->gpio_reg_pde & (1 << pin_num)) 462 *out_flags |= GPIO_PIN_PULLDOWN; 463 464 /* Open drain/push-pull modes. */ 465 if (MAX77620_REG_GPIO_DRV_GET(reg) == MAX77620_REG_GPIO_DRV_PUSHPULL) 466 *out_flags |= GPIO_PIN_PUSHPULL; 467 else 468 *out_flags |= GPIO_PIN_OPENDRAIN; 469 470 /* Input/output modes. */ 471 if (MAX77620_REG_GPIO_DRV_GET(reg) == MAX77620_REG_GPIO_DRV_PUSHPULL) 472 *out_flags |= GPIO_PIN_OUTPUT; 473 else 474 *out_flags |= GPIO_PIN_OUTPUT | GPIO_PIN_INPUT; 475 return (0); 476 } 477 478 int 479 max77620_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *out_flags) 480 { 481 struct max77620_softc *sc; 482 int rv; 483 484 sc = device_get_softc(dev); 485 if (pin >= sc->gpio_npins) 486 return (EINVAL); 487 488 GPIO_LOCK(sc); 489 #if 0 /* It colide with GPIO regulators */ 490 /* Is pin in GPIO mode ? */ 491 if (sc->gpio_pins[pin]->alt_func) { 492 GPIO_UNLOCK(sc); 493 return (ENXIO); 494 } 495 #endif 496 rv = max77620_gpio_get_mode(sc, pin, out_flags); 497 GPIO_UNLOCK(sc); 498 499 return (rv); 500 } 501 502 int 503 max77620_gpio_pin_setflags(device_t dev, uint32_t pin_num, uint32_t flags) 504 { 505 struct max77620_softc *sc; 506 struct max77620_gpio_pin *pin; 507 uint8_t reg; 508 uint8_t old_reg_pue, old_reg_pde; 509 int rv; 510 511 sc = device_get_softc(dev); 512 if (pin_num >= sc->gpio_npins) 513 return (EINVAL); 514 515 pin = sc->gpio_pins[pin_num]; 516 517 GPIO_LOCK(sc); 518 519 #if 0 /* It colide with GPIO regulators */ 520 /* Is pin in GPIO mode ? */ 521 if (pin->alt_func) { 522 GPIO_UNLOCK(sc); 523 return (ENXIO); 524 } 525 #endif 526 527 old_reg_pue = sc->gpio_reg_pue; 528 old_reg_pde = sc->gpio_reg_pde; 529 530 rv = RD1(sc, pin->reg, ®); 531 if (rv != 0) { 532 device_printf(sc->dev, "Cannot read GIPO_CFG register\n"); 533 GPIO_UNLOCK(sc); 534 return (ENXIO); 535 } 536 537 if (flags & GPIO_PIN_PULLUP) 538 sc->gpio_reg_pue |= 1 << pin_num; 539 else 540 sc->gpio_reg_pue &= ~(1 << pin_num); 541 542 if (flags & GPIO_PIN_PULLDOWN) 543 sc->gpio_reg_pde |= 1 << pin_num; 544 else 545 sc->gpio_reg_pde &= ~(1 << pin_num); 546 547 if (flags & GPIO_PIN_INPUT) { 548 reg &= ~MAX77620_REG_GPIO_DRV(~0); 549 reg |= MAX77620_REG_GPIO_DRV(MAX77620_REG_GPIO_DRV_OPENDRAIN); 550 reg &= ~MAX77620_REG_GPIO_OUTPUT_VAL(~0); 551 reg |= MAX77620_REG_GPIO_OUTPUT_VAL(1); 552 553 } else if (((flags & GPIO_PIN_OUTPUT) && 554 (flags & GPIO_PIN_OPENDRAIN) == 0) || 555 (flags & GPIO_PIN_PUSHPULL)) { 556 reg &= ~MAX77620_REG_GPIO_DRV(~0); 557 reg |= MAX77620_REG_GPIO_DRV(MAX77620_REG_GPIO_DRV_PUSHPULL); 558 } else { 559 reg &= ~MAX77620_REG_GPIO_DRV(~0); 560 reg |= MAX77620_REG_GPIO_DRV(MAX77620_REG_GPIO_DRV_OPENDRAIN); 561 } 562 563 rv = WR1(sc, pin->reg, reg); 564 if (rv != 0) { 565 device_printf(sc->dev, "Cannot read GIPO_CFG register\n"); 566 return (ENXIO); 567 } 568 if (old_reg_pue != sc->gpio_reg_pue) { 569 rv = WR1(sc, MAX77620_REG_PUE_GPIO, sc->gpio_reg_pue); 570 if (rv != 0) { 571 device_printf(sc->dev, 572 "Cannot update PUE_GPIO register\n"); 573 GPIO_UNLOCK(sc); 574 return (ENXIO); 575 } 576 } 577 578 if (old_reg_pde != sc->gpio_reg_pde) { 579 rv = WR1(sc, MAX77620_REG_PDE_GPIO, sc->gpio_reg_pde); 580 if (rv != 0) { 581 device_printf(sc->dev, 582 "Cannot update PDE_GPIO register\n"); 583 GPIO_UNLOCK(sc); 584 return (ENXIO); 585 } 586 } 587 588 GPIO_UNLOCK(sc); 589 return (0); 590 } 591 592 int 593 max77620_gpio_pin_set(device_t dev, uint32_t pin, uint32_t val) 594 { 595 struct max77620_softc *sc; 596 int rv; 597 598 sc = device_get_softc(dev); 599 if (pin >= sc->gpio_npins) 600 return (EINVAL); 601 602 GPIO_LOCK(sc); 603 rv = RM1(sc, sc->gpio_pins[pin]->reg, MAX77620_REG_GPIO_OUTPUT_VAL(~0), 604 MAX77620_REG_GPIO_OUTPUT_VAL(val)); 605 GPIO_UNLOCK(sc); 606 return (rv); 607 } 608 609 int 610 max77620_gpio_pin_get(device_t dev, uint32_t pin, uint32_t *val) 611 { 612 struct max77620_softc *sc; 613 uint8_t tmp; 614 int rv; 615 616 sc = device_get_softc(dev); 617 if (pin >= sc->gpio_npins) 618 return (EINVAL); 619 620 GPIO_LOCK(sc); 621 rv = RD1(sc, sc->gpio_pins[pin]->reg, &tmp); 622 623 if (MAX77620_REG_GPIO_DRV_GET(tmp) == MAX77620_REG_GPIO_DRV_PUSHPULL) 624 *val = MAX77620_REG_GPIO_OUTPUT_VAL_GET(tmp); 625 else 626 *val = MAX77620_REG_GPIO_INPUT_VAL_GET(tmp); 627 GPIO_UNLOCK(sc); 628 if (rv != 0) 629 return (rv); 630 631 return (0); 632 } 633 634 int 635 max77620_gpio_pin_toggle(device_t dev, uint32_t pin) 636 { 637 struct max77620_softc *sc; 638 uint8_t tmp; 639 int rv; 640 641 sc = device_get_softc(dev); 642 if (pin >= sc->gpio_npins) 643 return (EINVAL); 644 645 GPIO_LOCK(sc); 646 rv = RD1(sc, sc->gpio_pins[pin]->reg, &tmp); 647 if (rv != 0) { 648 GPIO_UNLOCK(sc); 649 return (rv); 650 } 651 tmp ^= MAX77620_REG_GPIO_OUTPUT_VAL(~0); 652 rv = RM1(sc, sc->gpio_pins[pin]->reg, MAX77620_REG_GPIO_OUTPUT_VAL(~0), 653 tmp); 654 GPIO_UNLOCK(sc); 655 return (0); 656 } 657 658 int 659 max77620_gpio_map_gpios(device_t dev, phandle_t pdev, phandle_t gparent, 660 int gcells, pcell_t *gpios, uint32_t *pin, uint32_t *flags) 661 { 662 663 if (gcells != 2) 664 return (ERANGE); 665 *pin = gpios[0]; 666 *flags= gpios[1]; 667 return (0); 668 } 669 670 int 671 max77620_gpio_attach(struct max77620_softc *sc, phandle_t node) 672 { 673 struct max77620_gpio_pin *pin; 674 int i, rv; 675 676 sx_init(&sc->gpio_lock, "MAX77620 GPIO lock"); 677 678 sc->gpio_busdev = gpiobus_attach_bus(sc->dev); 679 if (sc->gpio_busdev == NULL) 680 return (ENXIO); 681 682 rv = RD1(sc, MAX77620_REG_PUE_GPIO, &sc->gpio_reg_pue); 683 if (rv != 0) { 684 device_printf(sc->dev, "Cannot read PUE_GPIO register\n"); 685 return (ENXIO); 686 } 687 688 rv = RD1(sc, MAX77620_REG_PDE_GPIO, &sc->gpio_reg_pde); 689 if (rv != 0) { 690 device_printf(sc->dev, "Cannot read PDE_GPIO register\n"); 691 return (ENXIO); 692 } 693 694 rv = RD1(sc, MAX77620_REG_AME_GPIO, &sc->gpio_reg_ame); 695 if (rv != 0) { 696 device_printf(sc->dev, "Cannot read AME_GPIO register\n"); 697 return (ENXIO); 698 } 699 700 sc->gpio_npins = NGPIO; 701 sc->gpio_pins = malloc(sizeof(struct max77620_gpio_pin *) * 702 sc->gpio_npins, M_MAX77620_GPIO, M_WAITOK | M_ZERO); 703 for (i = 0; i < sc->gpio_npins; i++) { 704 sc->gpio_pins[i] = malloc(sizeof(struct max77620_gpio_pin), 705 M_MAX77620_GPIO, M_WAITOK | M_ZERO); 706 pin = sc->gpio_pins[i]; 707 sprintf(pin->pin_name, "gpio%d", i); 708 pin->pin_caps = GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | 709 GPIO_PIN_OPENDRAIN | GPIO_PIN_PUSHPULL | 710 GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN; 711 pin->reg = MAX77620_REG_GPIO0 + i; 712 } 713 714 return (0); 715 } 716