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