1 /*- 2 * Copyright (c) 2016 Daniel Wyatt <Daniel.Wyatt@gmail.com> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD$ 27 * 28 */ 29 30 /* 31 * Nuvoton GPIO driver. 32 * 33 */ 34 35 #include <sys/cdefs.h> 36 37 #include <sys/param.h> 38 #include <sys/kernel.h> 39 #include <sys/systm.h> 40 #include <sys/bus.h> 41 #include <sys/eventhandler.h> 42 #include <sys/lock.h> 43 44 #include <sys/module.h> 45 #include <sys/gpio.h> 46 47 #include <machine/bus.h> 48 49 #include <dev/gpio/gpiobusvar.h> 50 #include <dev/superio/superio.h> 51 52 #include "gpio_if.h" 53 54 /* Logical Device Numbers. */ 55 #define NCT_LDN_GPIO 0x07 56 #define NCT_LDN_GPIO_MODE 0x0f 57 58 /* Logical Device 7 */ 59 #define NCT_LD7_GPIO0_IOR 0xe0 60 #define NCT_LD7_GPIO0_DAT 0xe1 61 #define NCT_LD7_GPIO0_INV 0xe2 62 #define NCT_LD7_GPIO0_DST 0xe3 63 #define NCT_LD7_GPIO1_IOR 0xe4 64 #define NCT_LD7_GPIO1_DAT 0xe5 65 #define NCT_LD7_GPIO1_INV 0xe6 66 #define NCT_LD7_GPIO1_DST 0xe7 67 68 /* Logical Device F */ 69 #define NCT_LDF_GPIO0_OUTCFG 0xe0 70 #define NCT_LDF_GPIO1_OUTCFG 0xe1 71 72 /* Direct I/O port access. */ 73 #define NCT_IO_GSR 0 74 #define NCT_IO_IOR 1 75 #define NCT_IO_DAT 2 76 #define NCT_IO_INV 3 77 78 #define NCT_MAX_PIN 15 79 #define NCT_IS_VALID_PIN(_p) ((_p) >= 0 && (_p) <= NCT_MAX_PIN) 80 81 #define NCT_PIN_BIT(_p) (1 << ((_p) & 7)) 82 83 #define NCT_GPIO_CAPS (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | \ 84 GPIO_PIN_OPENDRAIN | GPIO_PIN_PUSHPULL | \ 85 GPIO_PIN_INVIN | GPIO_PIN_INVOUT) 86 87 /* 88 * Note that the values are important. 89 * They match actual register offsets. 90 */ 91 typedef enum { 92 REG_IOR = 0, 93 REG_DAT = 1, 94 REG_INV = 2, 95 } reg_t; 96 97 struct nct_softc { 98 device_t dev; 99 device_t dev_f; 100 device_t busdev; 101 struct mtx mtx; 102 struct resource *iores; 103 int iorid; 104 int curgrp; 105 struct { 106 /* direction, 1: pin is input */ 107 uint8_t ior[2]; 108 /* output value */ 109 uint8_t out[2]; 110 /* whether out is valid */ 111 uint8_t out_known[2]; 112 /* inversion, 1: pin is inverted */ 113 uint8_t inv[2]; 114 } cache; 115 struct gpio_pin pins[NCT_MAX_PIN + 1]; 116 }; 117 118 #define GPIO_LOCK_INIT(_sc) mtx_init(&(_sc)->mtx, \ 119 device_get_nameunit(dev), NULL, MTX_DEF) 120 #define GPIO_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->mtx) 121 #define GPIO_LOCK(_sc) mtx_lock(&(_sc)->mtx) 122 #define GPIO_UNLOCK(_sc) mtx_unlock(&(_sc)->mtx) 123 #define GPIO_ASSERT_LOCKED(_sc) mtx_assert(&(_sc)->mtx, MA_OWNED) 124 #define GPIO_ASSERT_UNLOCKED(_sc) mtx_assert(&(_sc)->mtx, MA_NOTOWNED) 125 126 struct nuvoton_vendor_device_id { 127 uint16_t chip_id; 128 const char * descr; 129 } nct_devs[] = { 130 { 131 .chip_id = 0x1061, 132 .descr = "Nuvoton NCT5104D", 133 }, 134 { 135 .chip_id = 0xc452, 136 .descr = "Nuvoton NCT5104D (PC-Engines APU)", 137 }, 138 { 139 .chip_id = 0xc453, 140 .descr = "Nuvoton NCT5104D (PC-Engines APU3)", 141 }, 142 }; 143 144 static void 145 nct_io_set_group(struct nct_softc *sc, int group) 146 { 147 148 GPIO_ASSERT_LOCKED(sc); 149 if (group != sc->curgrp) { 150 bus_write_1(sc->iores, NCT_IO_GSR, group); 151 sc->curgrp = group; 152 } 153 } 154 155 static uint8_t 156 nct_io_read(struct nct_softc *sc, int group, uint8_t reg) 157 { 158 nct_io_set_group(sc, group); 159 return (bus_read_1(sc->iores, reg)); 160 } 161 162 static void 163 nct_io_write(struct nct_softc *sc, int group, uint8_t reg, uint8_t val) 164 { 165 nct_io_set_group(sc, group); 166 return (bus_write_1(sc->iores, reg, val)); 167 } 168 169 static uint8_t 170 nct_get_ioreg(struct nct_softc *sc, reg_t reg, int group) 171 { 172 uint8_t ioreg; 173 174 if (sc->iores != NULL) 175 ioreg = NCT_IO_IOR + reg; 176 else if (group == 0) 177 ioreg = NCT_LD7_GPIO0_IOR + reg; 178 else 179 ioreg = NCT_LD7_GPIO1_IOR + reg; 180 return (ioreg); 181 } 182 183 static uint8_t 184 nct_read_reg(struct nct_softc *sc, reg_t reg, int group) 185 { 186 uint8_t ioreg; 187 uint8_t val; 188 189 ioreg = nct_get_ioreg(sc, reg, group); 190 if (sc->iores != NULL) 191 val = nct_io_read(sc, group, ioreg); 192 else 193 val = superio_read(sc->dev, ioreg); 194 195 return (val); 196 } 197 198 #define GET_BIT(v, b) (((v) >> (b)) & 1) 199 static bool 200 nct_get_pin_reg(struct nct_softc *sc, reg_t reg, uint32_t pin_num) 201 { 202 uint8_t bit; 203 uint8_t group; 204 uint8_t val; 205 206 KASSERT(NCT_IS_VALID_PIN(pin_num), ("%s: invalid pin number %d", 207 __func__, pin_num)); 208 209 group = pin_num >> 3; 210 bit = pin_num & 7; 211 val = nct_read_reg(sc, reg, group); 212 return (GET_BIT(val, bit)); 213 } 214 215 static int 216 nct_get_pin_cache(struct nct_softc *sc, uint32_t pin_num, uint8_t *cache) 217 { 218 uint8_t bit; 219 uint8_t group; 220 uint8_t val; 221 222 KASSERT(NCT_IS_VALID_PIN(pin_num), ("%s: invalid pin number %d", 223 __func__, pin_num)); 224 225 group = pin_num >> 3; 226 bit = pin_num & 7; 227 val = cache[group]; 228 return (GET_BIT(val, bit)); 229 } 230 231 static void 232 nct_write_reg(struct nct_softc *sc, reg_t reg, int group, uint8_t val) 233 { 234 uint8_t ioreg; 235 236 ioreg = nct_get_ioreg(sc, reg, group); 237 if (sc->iores != NULL) 238 nct_io_write(sc, group, ioreg, val); 239 else 240 superio_write(sc->dev, ioreg, val); 241 } 242 243 static void 244 nct_set_pin_reg(struct nct_softc *sc, reg_t reg, uint32_t pin_num, bool val) 245 { 246 uint8_t *cache; 247 uint8_t bit; 248 uint8_t bitval; 249 uint8_t group; 250 uint8_t mask; 251 252 KASSERT(NCT_IS_VALID_PIN(pin_num), 253 ("%s: invalid pin number %d", __func__, pin_num)); 254 KASSERT(reg == REG_IOR || reg == REG_INV, 255 ("%s: unsupported register %d", __func__, reg)); 256 257 group = pin_num >> 3; 258 bit = pin_num & 7; 259 mask = (uint8_t)1 << bit; 260 bitval = (uint8_t)val << bit; 261 262 if (reg == REG_IOR) 263 cache = &sc->cache.ior[group]; 264 else 265 cache = &sc->cache.inv[group]; 266 if ((*cache & mask) == bitval) 267 return; 268 *cache &= ~mask; 269 *cache |= bitval; 270 nct_write_reg(sc, reg, group, *cache); 271 } 272 273 /* 274 * Set a pin to input (val is true) or output (val is false) mode. 275 */ 276 static void 277 nct_set_pin_input(struct nct_softc *sc, uint32_t pin_num, bool val) 278 { 279 nct_set_pin_reg(sc, REG_IOR, pin_num, val); 280 } 281 282 /* 283 * Check whether a pin is configured as an input. 284 */ 285 static bool 286 nct_pin_is_input(struct nct_softc *sc, uint32_t pin_num) 287 { 288 return (nct_get_pin_cache(sc, pin_num, sc->cache.ior)); 289 } 290 291 /* 292 * Set a pin to inverted (val is true) or normal (val is false) mode. 293 */ 294 static void 295 nct_set_pin_inverted(struct nct_softc *sc, uint32_t pin_num, bool val) 296 { 297 nct_set_pin_reg(sc, REG_INV, pin_num, val); 298 } 299 300 static bool 301 nct_pin_is_inverted(struct nct_softc *sc, uint32_t pin_num) 302 { 303 return (nct_get_pin_cache(sc, pin_num, sc->cache.inv)); 304 } 305 306 /* 307 * Write a value to an output pin. 308 * NB: the hardware remembers last output value across switching from 309 * output mode to input mode and back. 310 * Writes to a pin in input mode are not allowed here as they cannot 311 * have any effect and would corrupt the output value cache. 312 */ 313 static void 314 nct_write_pin(struct nct_softc *sc, uint32_t pin_num, bool val) 315 { 316 uint8_t bit; 317 uint8_t group; 318 319 KASSERT(!nct_pin_is_input(sc, pin_num), ("attempt to write input pin")); 320 group = pin_num >> 3; 321 bit = pin_num & 7; 322 if (GET_BIT(sc->cache.out_known[group], bit) && 323 GET_BIT(sc->cache.out[group], bit) == val) { 324 /* The pin is already in requested state. */ 325 return; 326 } 327 sc->cache.out_known[group] |= 1 << bit; 328 if (val) 329 sc->cache.out[group] |= 1 << bit; 330 else 331 sc->cache.out[group] &= ~(1 << bit); 332 nct_write_reg(sc, REG_DAT, group, sc->cache.out[group]); 333 } 334 335 /* 336 * NB: state of an input pin cannot be cached, of course. 337 * For an output we can either take the value from the cache if it's valid 338 * or read the state from the hadrware and cache it. 339 */ 340 static bool 341 nct_read_pin(struct nct_softc *sc, uint32_t pin_num) 342 { 343 uint8_t bit; 344 uint8_t group; 345 bool val; 346 347 if (nct_pin_is_input(sc, pin_num)) 348 return (nct_get_pin_reg(sc, REG_DAT, pin_num)); 349 350 group = pin_num >> 3; 351 bit = pin_num & 7; 352 if (GET_BIT(sc->cache.out_known[group], bit)) 353 return (GET_BIT(sc->cache.out[group], bit)); 354 355 val = nct_get_pin_reg(sc, REG_DAT, pin_num); 356 sc->cache.out_known[group] |= 1 << bit; 357 if (val) 358 sc->cache.out[group] |= 1 << bit; 359 else 360 sc->cache.out[group] &= ~(1 << bit); 361 return (val); 362 } 363 364 static uint8_t 365 nct_outcfg_addr(uint32_t pin_num) 366 { 367 KASSERT(NCT_IS_VALID_PIN(pin_num), ("%s: invalid pin number %d", 368 __func__, pin_num)); 369 if ((pin_num >> 3) == 0) 370 return (NCT_LDF_GPIO0_OUTCFG); 371 else 372 return (NCT_LDF_GPIO1_OUTCFG); 373 } 374 375 /* 376 * NB: PP/OD can be configured only via configuration registers. 377 * Also, the registers are in a different logical device. 378 * So, this is a special case. No caching too. 379 */ 380 static void 381 nct_set_pin_opendrain(struct nct_softc *sc, uint32_t pin_num) 382 { 383 uint8_t reg; 384 uint8_t outcfg; 385 386 reg = nct_outcfg_addr(pin_num); 387 outcfg = superio_read(sc->dev_f, reg); 388 outcfg |= NCT_PIN_BIT(pin_num); 389 superio_write(sc->dev_f, reg, outcfg); 390 } 391 392 static void 393 nct_set_pin_pushpull(struct nct_softc *sc, uint32_t pin_num) 394 { 395 uint8_t reg; 396 uint8_t outcfg; 397 398 reg = nct_outcfg_addr(pin_num); 399 outcfg = superio_read(sc->dev_f, reg); 400 outcfg &= ~NCT_PIN_BIT(pin_num); 401 superio_write(sc->dev_f, reg, outcfg); 402 } 403 404 static bool 405 nct_pin_is_opendrain(struct nct_softc *sc, uint32_t pin_num) 406 { 407 uint8_t reg; 408 uint8_t outcfg; 409 410 reg = nct_outcfg_addr(pin_num); 411 outcfg = superio_read(sc->dev_f, reg); 412 return (outcfg & NCT_PIN_BIT(pin_num)); 413 } 414 415 static int 416 nct_probe(device_t dev) 417 { 418 int j; 419 uint16_t chipid; 420 421 if (superio_vendor(dev) != SUPERIO_VENDOR_NUVOTON) 422 return (ENXIO); 423 if (superio_get_type(dev) != SUPERIO_DEV_GPIO) 424 return (ENXIO); 425 426 /* 427 * There are several GPIO devices, we attach only to one of them 428 * and use the rest without attaching. 429 */ 430 if (superio_get_ldn(dev) != NCT_LDN_GPIO) 431 return (ENXIO); 432 433 chipid = superio_devid(dev); 434 for (j = 0; j < nitems(nct_devs); j++) { 435 if (chipid == nct_devs[j].chip_id) { 436 device_set_desc(dev, "Nuvoton GPIO controller"); 437 return (BUS_PROBE_DEFAULT); 438 } 439 } 440 return (ENXIO); 441 } 442 443 static int 444 nct_attach(device_t dev) 445 { 446 struct nct_softc *sc; 447 device_t dev_8; 448 uint16_t iobase; 449 int err; 450 int i; 451 452 sc = device_get_softc(dev); 453 sc->dev = dev; 454 sc->dev_f = superio_find_dev(device_get_parent(dev), SUPERIO_DEV_GPIO, 455 NCT_LDN_GPIO_MODE); 456 if (sc->dev_f == NULL) { 457 device_printf(dev, "failed to find LDN F\n"); 458 return (ENXIO); 459 } 460 461 /* 462 * As strange as it may seem, I/O port base is configured in the 463 * Logical Device 8 which is primarily used for WDT, but also plays 464 * a role in GPIO configuration. 465 */ 466 iobase = 0; 467 dev_8 = superio_find_dev(device_get_parent(dev), SUPERIO_DEV_WDT, 8); 468 if (dev_8 != NULL) 469 iobase = superio_get_iobase(dev_8); 470 if (iobase != 0 && iobase != 0xffff) { 471 sc->curgrp = -1; 472 sc->iorid = 0; 473 err = bus_set_resource(dev, SYS_RES_IOPORT, sc->iorid, 474 iobase, 7); 475 if (err == 0) { 476 sc->iores = bus_alloc_resource_any(dev, SYS_RES_IOPORT, 477 &sc->iorid, RF_ACTIVE); 478 if (sc->iores == NULL) { 479 device_printf(dev, "can't map i/o space, " 480 "iobase=0x%04x\n", iobase); 481 } 482 } else { 483 device_printf(dev, 484 "failed to set io port resource at 0x%x\n", iobase); 485 } 486 } 487 488 /* Enable gpio0 and gpio1. */ 489 superio_dev_enable(dev, 0x03); 490 491 GPIO_LOCK_INIT(sc); 492 GPIO_LOCK(sc); 493 494 sc->cache.inv[0] = nct_read_reg(sc, REG_INV, 0); 495 sc->cache.inv[1] = nct_read_reg(sc, REG_INV, 1); 496 sc->cache.ior[0] = nct_read_reg(sc, REG_IOR, 0); 497 sc->cache.ior[1] = nct_read_reg(sc, REG_IOR, 1); 498 499 /* 500 * Caching input values is meaningless as an input can be changed at any 501 * time by an external agent. But outputs are controlled by this 502 * driver, so it can cache their state. Also, the hardware remembers 503 * the output state of a pin when the pin is switched to input mode and 504 * then back to output mode. So, the cache stays valid. 505 * The only problem is with pins that are in input mode at the attach 506 * time. For them the output state is not known until it is set by the 507 * driver for the first time. 508 * 'out' and 'out_known' bits form a tri-state output cache: 509 * |-----+-----------+---------| 510 * | out | out_known | cache | 511 * |-----+-----------+---------| 512 * | X | 0 | invalid | 513 * | 0 | 1 | 0 | 514 * | 1 | 1 | 1 | 515 * |-----+-----------+---------| 516 */ 517 sc->cache.out[0] = nct_read_reg(sc, REG_DAT, 0); 518 sc->cache.out[1] = nct_read_reg(sc, REG_DAT, 1); 519 sc->cache.out_known[0] = ~sc->cache.ior[0]; 520 sc->cache.out_known[1] = ~sc->cache.ior[1]; 521 522 for (i = 0; i <= NCT_MAX_PIN; i++) { 523 struct gpio_pin *pin; 524 525 pin = &sc->pins[i]; 526 pin->gp_pin = i; 527 pin->gp_caps = NCT_GPIO_CAPS; 528 pin->gp_flags = 0; 529 530 snprintf(pin->gp_name, GPIOMAXNAME, "GPIO%02o", i); 531 pin->gp_name[GPIOMAXNAME - 1] = '\0'; 532 533 if (nct_pin_is_input(sc, i)) 534 pin->gp_flags |= GPIO_PIN_INPUT; 535 else 536 pin->gp_flags |= GPIO_PIN_OUTPUT; 537 538 if (nct_pin_is_opendrain(sc, i)) 539 pin->gp_flags |= GPIO_PIN_OPENDRAIN; 540 else 541 pin->gp_flags |= GPIO_PIN_PUSHPULL; 542 543 if (nct_pin_is_inverted(sc, i)) 544 pin->gp_flags |= (GPIO_PIN_INVIN | GPIO_PIN_INVOUT); 545 } 546 GPIO_UNLOCK(sc); 547 548 sc->busdev = gpiobus_attach_bus(dev); 549 if (sc->busdev == NULL) { 550 GPIO_LOCK_DESTROY(sc); 551 return (ENXIO); 552 } 553 554 return (0); 555 } 556 557 static int 558 nct_detach(device_t dev) 559 { 560 struct nct_softc *sc; 561 562 sc = device_get_softc(dev); 563 gpiobus_detach_bus(dev); 564 565 if (sc->iores != NULL) 566 bus_release_resource(dev, SYS_RES_IOPORT, sc->iorid, sc->iores); 567 GPIO_ASSERT_UNLOCKED(sc); 568 GPIO_LOCK_DESTROY(sc); 569 570 return (0); 571 } 572 573 static device_t 574 nct_gpio_get_bus(device_t dev) 575 { 576 struct nct_softc *sc; 577 578 sc = device_get_softc(dev); 579 580 return (sc->busdev); 581 } 582 583 static int 584 nct_gpio_pin_max(device_t dev, int *npins) 585 { 586 *npins = NCT_MAX_PIN; 587 588 return (0); 589 } 590 591 static int 592 nct_gpio_pin_set(device_t dev, uint32_t pin_num, uint32_t pin_value) 593 { 594 struct nct_softc *sc; 595 596 if (!NCT_IS_VALID_PIN(pin_num)) 597 return (EINVAL); 598 599 sc = device_get_softc(dev); 600 GPIO_LOCK(sc); 601 if ((sc->pins[pin_num].gp_flags & GPIO_PIN_OUTPUT) == 0) { 602 GPIO_UNLOCK(sc); 603 return (EINVAL); 604 } 605 nct_write_pin(sc, pin_num, pin_value); 606 GPIO_UNLOCK(sc); 607 608 return (0); 609 } 610 611 static int 612 nct_gpio_pin_get(device_t dev, uint32_t pin_num, uint32_t *pin_value) 613 { 614 struct nct_softc *sc; 615 616 if (!NCT_IS_VALID_PIN(pin_num)) 617 return (EINVAL); 618 619 sc = device_get_softc(dev); 620 GPIO_ASSERT_UNLOCKED(sc); 621 GPIO_LOCK(sc); 622 *pin_value = nct_read_pin(sc, pin_num); 623 GPIO_UNLOCK(sc); 624 625 return (0); 626 } 627 628 static int 629 nct_gpio_pin_toggle(device_t dev, uint32_t pin_num) 630 { 631 struct nct_softc *sc; 632 633 if (!NCT_IS_VALID_PIN(pin_num)) 634 return (EINVAL); 635 636 sc = device_get_softc(dev); 637 GPIO_ASSERT_UNLOCKED(sc); 638 GPIO_LOCK(sc); 639 if ((sc->pins[pin_num].gp_flags & GPIO_PIN_OUTPUT) == 0) { 640 GPIO_UNLOCK(sc); 641 return (EINVAL); 642 } 643 if (nct_read_pin(sc, pin_num)) 644 nct_write_pin(sc, pin_num, 0); 645 else 646 nct_write_pin(sc, pin_num, 1); 647 648 GPIO_UNLOCK(sc); 649 650 return (0); 651 } 652 653 static int 654 nct_gpio_pin_getcaps(device_t dev, uint32_t pin_num, uint32_t *caps) 655 { 656 struct nct_softc *sc; 657 658 if (!NCT_IS_VALID_PIN(pin_num)) 659 return (EINVAL); 660 661 sc = device_get_softc(dev); 662 GPIO_ASSERT_UNLOCKED(sc); 663 GPIO_LOCK(sc); 664 *caps = sc->pins[pin_num].gp_caps; 665 GPIO_UNLOCK(sc); 666 667 return (0); 668 } 669 670 static int 671 nct_gpio_pin_getflags(device_t dev, uint32_t pin_num, uint32_t *flags) 672 { 673 struct nct_softc *sc; 674 675 if (!NCT_IS_VALID_PIN(pin_num)) 676 return (EINVAL); 677 678 sc = device_get_softc(dev); 679 GPIO_ASSERT_UNLOCKED(sc); 680 GPIO_LOCK(sc); 681 *flags = sc->pins[pin_num].gp_flags; 682 GPIO_UNLOCK(sc); 683 684 return (0); 685 } 686 687 static int 688 nct_gpio_pin_getname(device_t dev, uint32_t pin_num, char *name) 689 { 690 struct nct_softc *sc; 691 692 if (!NCT_IS_VALID_PIN(pin_num)) 693 return (EINVAL); 694 695 sc = device_get_softc(dev); 696 GPIO_ASSERT_UNLOCKED(sc); 697 GPIO_LOCK(sc); 698 memcpy(name, sc->pins[pin_num].gp_name, GPIOMAXNAME); 699 GPIO_UNLOCK(sc); 700 701 return (0); 702 } 703 704 static int 705 nct_gpio_pin_setflags(device_t dev, uint32_t pin_num, uint32_t flags) 706 { 707 struct nct_softc *sc; 708 struct gpio_pin *pin; 709 710 if (!NCT_IS_VALID_PIN(pin_num)) 711 return (EINVAL); 712 713 sc = device_get_softc(dev); 714 pin = &sc->pins[pin_num]; 715 if ((flags & pin->gp_caps) != flags) 716 return (EINVAL); 717 718 if ((flags & (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) == 719 (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) { 720 return (EINVAL); 721 } 722 if ((flags & (GPIO_PIN_OPENDRAIN | GPIO_PIN_PUSHPULL)) == 723 (GPIO_PIN_OPENDRAIN | GPIO_PIN_PUSHPULL)) { 724 return (EINVAL); 725 } 726 if ((flags & (GPIO_PIN_INVIN | GPIO_PIN_INVOUT)) == 727 (GPIO_PIN_INVIN | GPIO_PIN_INVOUT)) { 728 return (EINVAL); 729 } 730 731 GPIO_ASSERT_UNLOCKED(sc); 732 GPIO_LOCK(sc); 733 if ((flags & (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT)) != 0) { 734 nct_set_pin_input(sc, pin_num, (flags & GPIO_PIN_INPUT) != 0); 735 pin->gp_flags &= ~(GPIO_PIN_INPUT | GPIO_PIN_OUTPUT); 736 pin->gp_flags |= flags & (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT); 737 } 738 if ((flags & (GPIO_PIN_INVIN | GPIO_PIN_INVOUT)) != 0) { 739 nct_set_pin_inverted(sc, pin_num, 740 (flags & GPIO_PIN_INVIN) != 0); 741 pin->gp_flags &= ~(GPIO_PIN_INVIN | GPIO_PIN_INVOUT); 742 pin->gp_flags |= flags & (GPIO_PIN_INVIN | GPIO_PIN_INVOUT); 743 } 744 if ((flags & (GPIO_PIN_OPENDRAIN | GPIO_PIN_PUSHPULL)) != 0) { 745 if (flags & GPIO_PIN_OPENDRAIN) 746 nct_set_pin_opendrain(sc, pin_num); 747 else 748 nct_set_pin_pushpull(sc, pin_num); 749 pin->gp_flags &= ~(GPIO_PIN_OPENDRAIN | GPIO_PIN_PUSHPULL); 750 pin->gp_flags |= 751 flags & (GPIO_PIN_OPENDRAIN | GPIO_PIN_PUSHPULL); 752 } 753 GPIO_UNLOCK(sc); 754 755 return (0); 756 } 757 758 static device_method_t nct_methods[] = { 759 /* Device interface */ 760 DEVMETHOD(device_probe, nct_probe), 761 DEVMETHOD(device_attach, nct_attach), 762 DEVMETHOD(device_detach, nct_detach), 763 764 /* GPIO */ 765 DEVMETHOD(gpio_get_bus, nct_gpio_get_bus), 766 DEVMETHOD(gpio_pin_max, nct_gpio_pin_max), 767 DEVMETHOD(gpio_pin_get, nct_gpio_pin_get), 768 DEVMETHOD(gpio_pin_set, nct_gpio_pin_set), 769 DEVMETHOD(gpio_pin_toggle, nct_gpio_pin_toggle), 770 DEVMETHOD(gpio_pin_getname, nct_gpio_pin_getname), 771 DEVMETHOD(gpio_pin_getcaps, nct_gpio_pin_getcaps), 772 DEVMETHOD(gpio_pin_getflags, nct_gpio_pin_getflags), 773 DEVMETHOD(gpio_pin_setflags, nct_gpio_pin_setflags), 774 775 DEVMETHOD_END 776 }; 777 778 static driver_t nct_driver = { 779 "gpio", 780 nct_methods, 781 sizeof(struct nct_softc) 782 }; 783 784 DRIVER_MODULE(nctgpio, superio, nct_driver, NULL, NULL); 785 MODULE_DEPEND(nctgpio, gpiobus, 1, 1, 1); 786 MODULE_DEPEND(nctgpio, superio, 1, 1, 1); 787 MODULE_VERSION(nctgpio, 1); 788 789