1 /*- 2 * Copyright (c) 2016 Jared McNeill <jmcneill@invisible.ca> 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 ``AS IS'' AND ANY EXPRESS OR 15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 19 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 21 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 22 * 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 * X-Powers AXP813/818 PMU for Allwinner SoCs 31 */ 32 33 #include <sys/cdefs.h> 34 __FBSDID("$FreeBSD$"); 35 36 #include <sys/param.h> 37 #include <sys/systm.h> 38 #include <sys/eventhandler.h> 39 #include <sys/bus.h> 40 #include <sys/rman.h> 41 #include <sys/kernel.h> 42 #include <sys/reboot.h> 43 #include <sys/gpio.h> 44 #include <sys/module.h> 45 #include <machine/bus.h> 46 47 #include <dev/iicbus/iicbus.h> 48 #include <dev/iicbus/iiconf.h> 49 50 #include <dev/gpio/gpiobusvar.h> 51 52 #include <dev/ofw/ofw_bus.h> 53 #include <dev/ofw/ofw_bus_subr.h> 54 55 #include "iicbus_if.h" 56 #include "gpio_if.h" 57 58 #define AXP_ICTYPE 0x03 59 #define AXP_POWERBAT 0x32 60 #define AXP_POWERBAT_SHUTDOWN (1 << 7) 61 #define AXP_IRQEN1 0x40 62 #define AXP_IRQEN2 0x41 63 #define AXP_IRQEN3 0x42 64 #define AXP_IRQEN4 0x43 65 #define AXP_IRQEN5 0x44 66 #define AXP_IRQEN5_POKSIRQ (1 << 4) 67 #define AXP_IRQEN6 0x45 68 #define AXP_IRQSTAT5 0x4c 69 #define AXP_IRQSTAT5_POKSIRQ (1 << 4) 70 #define AXP_GPIO0_CTRL 0x90 71 #define AXP_GPIO1_CTRL 0x92 72 #define AXP_GPIO_FUNC (0x7 << 0) 73 #define AXP_GPIO_FUNC_SHIFT 0 74 #define AXP_GPIO_FUNC_DRVLO 0 75 #define AXP_GPIO_FUNC_DRVHI 1 76 #define AXP_GPIO_FUNC_INPUT 2 77 #define AXP_GPIO_SIGBIT 0x94 78 #define AXP_GPIO_PD 0x97 79 80 static const struct { 81 const char *name; 82 uint8_t ctrl_reg; 83 } axp81x_pins[] = { 84 { "GPIO0", AXP_GPIO0_CTRL }, 85 { "GPIO1", AXP_GPIO1_CTRL }, 86 }; 87 88 static struct ofw_compat_data compat_data[] = { 89 { "x-powers,axp813", 1 }, 90 { "x-powers,axp818", 1 }, 91 { NULL, 0 } 92 }; 93 94 static struct resource_spec axp81x_spec[] = { 95 { SYS_RES_IRQ, 0, RF_ACTIVE }, 96 { -1, 0 } 97 }; 98 99 struct axp81x_softc { 100 struct resource *res; 101 uint16_t addr; 102 void *ih; 103 device_t gpiodev; 104 struct mtx mtx; 105 int busy; 106 }; 107 108 #define AXP_LOCK(sc) mtx_lock(&(sc)->mtx) 109 #define AXP_UNLOCK(sc) mtx_unlock(&(sc)->mtx) 110 111 static int 112 axp81x_read(device_t dev, uint8_t reg, uint8_t *data, uint8_t size) 113 { 114 struct axp81x_softc *sc; 115 struct iic_msg msg[2]; 116 117 sc = device_get_softc(dev); 118 119 msg[0].slave = sc->addr; 120 msg[0].flags = IIC_M_WR; 121 msg[0].len = 1; 122 msg[0].buf = ® 123 124 msg[1].slave = sc->addr; 125 msg[1].flags = IIC_M_RD; 126 msg[1].len = size; 127 msg[1].buf = data; 128 129 return (iicbus_transfer(dev, msg, 2)); 130 } 131 132 static int 133 axp81x_write(device_t dev, uint8_t reg, uint8_t val) 134 { 135 struct axp81x_softc *sc; 136 struct iic_msg msg[2]; 137 138 sc = device_get_softc(dev); 139 140 msg[0].slave = sc->addr; 141 msg[0].flags = IIC_M_WR; 142 msg[0].len = 1; 143 msg[0].buf = ® 144 145 msg[1].slave = sc->addr; 146 msg[1].flags = IIC_M_WR; 147 msg[1].len = 1; 148 msg[1].buf = &val; 149 150 return (iicbus_transfer(dev, msg, 2)); 151 } 152 153 static void 154 axp81x_shutdown(void *devp, int howto) 155 { 156 device_t dev; 157 158 if ((howto & RB_POWEROFF) == 0) 159 return; 160 161 dev = devp; 162 163 if (bootverbose) 164 device_printf(dev, "Shutdown AXP81x\n"); 165 166 axp81x_write(dev, AXP_POWERBAT, AXP_POWERBAT_SHUTDOWN); 167 } 168 169 static void 170 axp81x_intr(void *arg) 171 { 172 struct axp81x_softc *sc; 173 device_t dev; 174 uint8_t val; 175 int error; 176 177 dev = arg; 178 sc = device_get_softc(dev); 179 180 error = axp81x_read(dev, AXP_IRQSTAT5, &val, 1); 181 if (error != 0) 182 return; 183 184 if (val != 0) { 185 if ((val & AXP_IRQSTAT5_POKSIRQ) != 0) { 186 if (bootverbose) 187 device_printf(dev, "Power button pressed\n"); 188 shutdown_nice(RB_POWEROFF); 189 } 190 /* Acknowledge */ 191 axp81x_write(dev, AXP_IRQSTAT5, val); 192 } 193 } 194 195 static device_t 196 axp81x_gpio_get_bus(device_t dev) 197 { 198 struct axp81x_softc *sc; 199 200 sc = device_get_softc(dev); 201 202 return (sc->gpiodev); 203 } 204 205 static int 206 axp81x_gpio_pin_max(device_t dev, int *maxpin) 207 { 208 *maxpin = nitems(axp81x_pins) - 1; 209 210 return (0); 211 } 212 213 static int 214 axp81x_gpio_pin_getname(device_t dev, uint32_t pin, char *name) 215 { 216 if (pin >= nitems(axp81x_pins)) 217 return (EINVAL); 218 219 snprintf(name, GPIOMAXNAME, "%s", axp81x_pins[pin].name); 220 221 return (0); 222 } 223 224 static int 225 axp81x_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps) 226 { 227 if (pin >= nitems(axp81x_pins)) 228 return (EINVAL); 229 230 *caps = GPIO_PIN_INPUT | GPIO_PIN_OUTPUT; 231 232 return (0); 233 } 234 235 static int 236 axp81x_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags) 237 { 238 struct axp81x_softc *sc; 239 uint8_t data, func; 240 int error; 241 242 if (pin >= nitems(axp81x_pins)) 243 return (EINVAL); 244 245 sc = device_get_softc(dev); 246 247 AXP_LOCK(sc); 248 error = axp81x_read(dev, axp81x_pins[pin].ctrl_reg, &data, 1); 249 if (error == 0) { 250 func = (data & AXP_GPIO_FUNC) >> AXP_GPIO_FUNC_SHIFT; 251 if (func == AXP_GPIO_FUNC_INPUT) 252 *flags = GPIO_PIN_INPUT; 253 else if (func == AXP_GPIO_FUNC_DRVLO || 254 func == AXP_GPIO_FUNC_DRVHI) 255 *flags = GPIO_PIN_OUTPUT; 256 else 257 *flags = 0; 258 } 259 AXP_UNLOCK(sc); 260 261 return (error); 262 } 263 264 static int 265 axp81x_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags) 266 { 267 struct axp81x_softc *sc; 268 uint8_t data; 269 int error; 270 271 if (pin >= nitems(axp81x_pins)) 272 return (EINVAL); 273 274 sc = device_get_softc(dev); 275 276 AXP_LOCK(sc); 277 error = axp81x_read(dev, axp81x_pins[pin].ctrl_reg, &data, 1); 278 if (error == 0) { 279 data &= ~AXP_GPIO_FUNC; 280 if ((flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) != 0) { 281 if ((flags & GPIO_PIN_OUTPUT) == 0) 282 data |= AXP_GPIO_FUNC_INPUT; 283 } 284 error = axp81x_write(dev, axp81x_pins[pin].ctrl_reg, data); 285 } 286 AXP_UNLOCK(sc); 287 288 return (error); 289 } 290 291 static int 292 axp81x_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val) 293 { 294 struct axp81x_softc *sc; 295 uint8_t data, func; 296 int error; 297 298 if (pin >= nitems(axp81x_pins)) 299 return (EINVAL); 300 301 sc = device_get_softc(dev); 302 303 AXP_LOCK(sc); 304 error = axp81x_read(dev, axp81x_pins[pin].ctrl_reg, &data, 1); 305 if (error == 0) { 306 func = (data & AXP_GPIO_FUNC) >> AXP_GPIO_FUNC_SHIFT; 307 switch (func) { 308 case AXP_GPIO_FUNC_DRVLO: 309 *val = 0; 310 break; 311 case AXP_GPIO_FUNC_DRVHI: 312 *val = 1; 313 break; 314 case AXP_GPIO_FUNC_INPUT: 315 error = axp81x_read(dev, AXP_GPIO_SIGBIT, &data, 1); 316 if (error == 0) 317 *val = (data & (1 << pin)) ? 1 : 0; 318 break; 319 default: 320 error = EIO; 321 break; 322 } 323 } 324 AXP_UNLOCK(sc); 325 326 return (error); 327 } 328 329 static int 330 axp81x_gpio_pin_set(device_t dev, uint32_t pin, unsigned int val) 331 { 332 struct axp81x_softc *sc; 333 uint8_t data, func; 334 int error; 335 336 if (pin >= nitems(axp81x_pins)) 337 return (EINVAL); 338 339 sc = device_get_softc(dev); 340 341 AXP_LOCK(sc); 342 error = axp81x_read(dev, axp81x_pins[pin].ctrl_reg, &data, 1); 343 if (error == 0) { 344 func = (data & AXP_GPIO_FUNC) >> AXP_GPIO_FUNC_SHIFT; 345 switch (func) { 346 case AXP_GPIO_FUNC_DRVLO: 347 case AXP_GPIO_FUNC_DRVHI: 348 data &= ~AXP_GPIO_FUNC; 349 data |= (val << AXP_GPIO_FUNC_SHIFT); 350 break; 351 default: 352 error = EIO; 353 break; 354 } 355 } 356 if (error == 0) 357 error = axp81x_write(dev, axp81x_pins[pin].ctrl_reg, data); 358 AXP_UNLOCK(sc); 359 360 return (error); 361 } 362 363 364 static int 365 axp81x_gpio_pin_toggle(device_t dev, uint32_t pin) 366 { 367 struct axp81x_softc *sc; 368 uint8_t data, func; 369 int error; 370 371 if (pin >= nitems(axp81x_pins)) 372 return (EINVAL); 373 374 sc = device_get_softc(dev); 375 376 AXP_LOCK(sc); 377 error = axp81x_read(dev, axp81x_pins[pin].ctrl_reg, &data, 1); 378 if (error == 0) { 379 func = (data & AXP_GPIO_FUNC) >> AXP_GPIO_FUNC_SHIFT; 380 switch (func) { 381 case AXP_GPIO_FUNC_DRVLO: 382 data &= ~AXP_GPIO_FUNC; 383 data |= (AXP_GPIO_FUNC_DRVHI << AXP_GPIO_FUNC_SHIFT); 384 break; 385 case AXP_GPIO_FUNC_DRVHI: 386 data &= ~AXP_GPIO_FUNC; 387 data |= (AXP_GPIO_FUNC_DRVLO << AXP_GPIO_FUNC_SHIFT); 388 break; 389 default: 390 error = EIO; 391 break; 392 } 393 } 394 if (error == 0) 395 error = axp81x_write(dev, axp81x_pins[pin].ctrl_reg, data); 396 AXP_UNLOCK(sc); 397 398 return (error); 399 } 400 401 static int 402 axp81x_gpio_map_gpios(device_t bus, phandle_t dev, phandle_t gparent, 403 int gcells, pcell_t *gpios, uint32_t *pin, uint32_t *flags) 404 { 405 if (gpios[0] >= nitems(axp81x_pins)) 406 return (EINVAL); 407 408 *pin = gpios[0]; 409 *flags = gpios[1]; 410 411 return (0); 412 } 413 414 static phandle_t 415 axp81x_get_node(device_t dev, device_t bus) 416 { 417 return (ofw_bus_get_node(dev)); 418 } 419 420 static int 421 axp81x_probe(device_t dev) 422 { 423 if (!ofw_bus_status_okay(dev)) 424 return (ENXIO); 425 426 if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) 427 return (ENXIO); 428 429 device_set_desc(dev, "X-Powers AXP81x Power Management Unit"); 430 431 return (BUS_PROBE_DEFAULT); 432 } 433 434 static int 435 axp81x_attach(device_t dev) 436 { 437 struct axp81x_softc *sc; 438 uint8_t chip_id; 439 int error; 440 441 sc = device_get_softc(dev); 442 443 sc->addr = iicbus_get_addr(dev); 444 mtx_init(&sc->mtx, device_get_nameunit(dev), NULL, MTX_DEF); 445 446 error = bus_alloc_resources(dev, axp81x_spec, &sc->res); 447 if (error != 0) { 448 device_printf(dev, "cannot allocate resources for device\n"); 449 return (error); 450 } 451 452 if (bootverbose) { 453 axp81x_read(dev, AXP_ICTYPE, &chip_id, 1); 454 device_printf(dev, "chip ID 0x%02x\n", chip_id); 455 } 456 457 /* Enable IRQ on short power key press */ 458 axp81x_write(dev, AXP_IRQEN1, 0); 459 axp81x_write(dev, AXP_IRQEN2, 0); 460 axp81x_write(dev, AXP_IRQEN3, 0); 461 axp81x_write(dev, AXP_IRQEN4, 0); 462 axp81x_write(dev, AXP_IRQEN5, AXP_IRQEN5_POKSIRQ); 463 axp81x_write(dev, AXP_IRQEN6, 0); 464 465 /* Install interrupt handler */ 466 error = bus_setup_intr(dev, sc->res, INTR_TYPE_MISC | INTR_MPSAFE, 467 NULL, axp81x_intr, dev, &sc->ih); 468 if (error != 0) { 469 device_printf(dev, "cannot setup interrupt handler\n"); 470 return (error); 471 } 472 473 EVENTHANDLER_REGISTER(shutdown_final, axp81x_shutdown, dev, 474 SHUTDOWN_PRI_LAST); 475 476 sc->gpiodev = gpiobus_attach_bus(dev); 477 478 return (0); 479 } 480 481 static device_method_t axp81x_methods[] = { 482 /* Device interface */ 483 DEVMETHOD(device_probe, axp81x_probe), 484 DEVMETHOD(device_attach, axp81x_attach), 485 486 /* GPIO interface */ 487 DEVMETHOD(gpio_get_bus, axp81x_gpio_get_bus), 488 DEVMETHOD(gpio_pin_max, axp81x_gpio_pin_max), 489 DEVMETHOD(gpio_pin_getname, axp81x_gpio_pin_getname), 490 DEVMETHOD(gpio_pin_getcaps, axp81x_gpio_pin_getcaps), 491 DEVMETHOD(gpio_pin_getflags, axp81x_gpio_pin_getflags), 492 DEVMETHOD(gpio_pin_setflags, axp81x_gpio_pin_setflags), 493 DEVMETHOD(gpio_pin_get, axp81x_gpio_pin_get), 494 DEVMETHOD(gpio_pin_set, axp81x_gpio_pin_set), 495 DEVMETHOD(gpio_pin_toggle, axp81x_gpio_pin_toggle), 496 DEVMETHOD(gpio_map_gpios, axp81x_gpio_map_gpios), 497 498 /* OFW bus interface */ 499 DEVMETHOD(ofw_bus_get_node, axp81x_get_node), 500 501 DEVMETHOD_END 502 }; 503 504 static driver_t axp81x_driver = { 505 "axp81x_pmu", 506 axp81x_methods, 507 sizeof(struct axp81x_softc), 508 }; 509 510 static devclass_t axp81x_devclass; 511 extern devclass_t ofwgpiobus_devclass, gpioc_devclass; 512 extern driver_t ofw_gpiobus_driver, gpioc_driver; 513 514 DRIVER_MODULE(axp81x, iicbus, axp81x_driver, axp81x_devclass, 0, 0); 515 DRIVER_MODULE(ofw_gpiobus, axp81x_pmu, ofw_gpiobus_driver, 516 ofwgpiobus_devclass, 0, 0); 517 DRIVER_MODULE(gpioc, axp81x_pmu, gpioc_driver, gpioc_devclass, 0, 0); 518 MODULE_VERSION(axp81x, 1); 519 MODULE_DEPEND(axp81x, iicbus, 1, 1, 1); 520