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