2 * Copyright (c) 2015-2016 Emmanuel Vadot <manu@freebsd.org>
3 * Copyright (c) 2016 Jared McNeill <jmcneill@invisible.ca>
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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.
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
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
31 * X-Power AXP209 PMU for Allwinner SoCs
33 #include <sys/param.h>
34 #include <sys/systm.h>
35 #include <sys/eventhandler.h>
36 #include <sys/kernel.h>
37 #include <sys/module.h>
38 #include <sys/clock.h>
43 #include <sys/reboot.h>
44 #include <sys/resource.h>
46 #include <sys/sysctl.h>
48 #include <dev/iicbus/iicbus.h>
49 #include <dev/iicbus/iiconf.h>
51 #include <dev/gpio/gpiobusvar.h>
53 #include <dev/ofw/ofw_bus.h>
54 #include <dev/ofw/ofw_bus_subr.h>
56 #include <dev/extres/regulator/regulator.h>
58 #include <arm/allwinner/axp209reg.h>
60 #include "iicbus_if.h"
62 #include "regdev_if.h"
64 MALLOC_DEFINE(M_AXP209_REG, "Axp209 regulator", "Axp209 power regulator");
66 struct axp209_regdef {
73 uint8_t voltage_shift;
80 static struct axp209_regdef axp209_regdefs[] = {
82 .id = AXP209_REG_ID_DCDC2,
84 .enable_reg = AXP209_POWERCTL,
85 .enable_mask = AXP209_POWERCTL_DCDC2,
86 .voltage_reg = AXP209_REG_DCDC2_VOLTAGE,
94 .id = AXP209_REG_ID_DCDC3,
96 .enable_reg = AXP209_POWERCTL,
97 .enable_mask = AXP209_POWERCTL_DCDC3,
98 .voltage_reg = AXP209_REG_DCDC3_VOLTAGE,
103 .voltage_nstep = 128,
106 .id = AXP209_REG_ID_LDO2,
108 .enable_reg = AXP209_POWERCTL,
109 .enable_mask = AXP209_POWERCTL_LDO2,
110 .voltage_reg = AXP209_REG_LDO24_VOLTAGE,
111 .voltage_mask = 0xf0,
119 .id = AXP209_REG_ID_LDO3,
121 .enable_reg = AXP209_POWERCTL,
122 .enable_mask = AXP209_POWERCTL_LDO3,
123 .voltage_reg = AXP209_REG_LDO3_VOLTAGE,
124 .voltage_mask = 0x7f,
128 .voltage_nstep = 128,
132 struct axp209_reg_sc {
133 struct regnode *regnode;
135 struct axp209_regdef *def;
137 struct regnode_std_param *param;
140 struct axp209_softc {
143 struct resource * res[1];
145 struct intr_config_hook intr_hook;
150 struct axp209_reg_sc **regs;
154 /* GPIO3 is different, don't expose it for now */
155 static const struct {
159 { "GPIO0", AXP209_GPIO0_CTRL },
160 { "GPIO1", AXP209_GPIO1_CTRL },
161 { "GPIO2", AXP209_GPIO2_CTRL },
164 static struct resource_spec axp_res_spec[] = {
165 { SYS_RES_IRQ, 0, RF_ACTIVE },
169 #define AXP_LOCK(sc) mtx_lock(&(sc)->mtx)
170 #define AXP_UNLOCK(sc) mtx_unlock(&(sc)->mtx)
173 axp209_read(device_t dev, uint8_t reg, uint8_t *data, uint8_t size)
175 struct axp209_softc *sc = device_get_softc(dev);
176 struct iic_msg msg[2];
178 msg[0].slave = sc->addr;
179 msg[0].flags = IIC_M_WR;
183 msg[1].slave = sc->addr;
184 msg[1].flags = IIC_M_RD;
188 return (iicbus_transfer(dev, msg, 2));
192 axp209_write(device_t dev, uint8_t reg, uint8_t data)
195 struct axp209_softc *sc = device_get_softc(dev);
201 msg.slave = sc->addr;
202 msg.flags = IIC_M_WR;
206 return (iicbus_transfer(dev, &msg, 1));
210 axp209_regnode_init(struct regnode *regnode)
216 axp209_regnode_enable(struct regnode *regnode, bool enable, int *udelay)
218 struct axp209_reg_sc *sc;
221 sc = regnode_get_softc(regnode);
223 axp209_read(sc->base_dev, sc->def->enable_reg, &val, 1);
225 val |= sc->def->enable_mask;
227 val &= ~sc->def->enable_mask;
228 axp209_write(sc->base_dev, sc->def->enable_reg, val);
236 axp209_regnode_reg_to_voltage(struct axp209_reg_sc *sc, uint8_t val, int *uv)
238 if (val < sc->def->voltage_nstep)
239 *uv = sc->def->voltage_min + val * sc->def->voltage_step;
241 *uv = sc->def->voltage_min +
242 (sc->def->voltage_nstep * sc->def->voltage_step);
247 axp209_regnode_voltage_to_reg(struct axp209_reg_sc *sc, int min_uvolt,
248 int max_uvolt, uint8_t *val)
254 uvolt = sc->def->voltage_min * 1000;
256 for (nstep = 0; nstep < sc->def->voltage_nstep && uvolt < min_uvolt;
259 uvolt += (sc->def->voltage_step * 1000);
261 if (uvolt > max_uvolt)
269 axp209_regnode_set_voltage(struct regnode *regnode, int min_uvolt,
270 int max_uvolt, int *udelay)
272 struct axp209_reg_sc *sc;
275 sc = regnode_get_softc(regnode);
277 if (!sc->def->voltage_step)
280 if (axp209_regnode_voltage_to_reg(sc, min_uvolt, max_uvolt, &val) != 0)
283 axp209_write(sc->base_dev, sc->def->voltage_reg, val);
291 axp209_regnode_get_voltage(struct regnode *regnode, int *uvolt)
293 struct axp209_reg_sc *sc;
296 sc = regnode_get_softc(regnode);
298 if (!sc->def->voltage_step)
301 axp209_read(sc->base_dev, sc->def->voltage_reg, &val, 1);
302 axp209_regnode_reg_to_voltage(sc, val & sc->def->voltage_mask, uvolt);
307 static regnode_method_t axp209_regnode_methods[] = {
308 /* Regulator interface */
309 REGNODEMETHOD(regnode_init, axp209_regnode_init),
310 REGNODEMETHOD(regnode_enable, axp209_regnode_enable),
311 REGNODEMETHOD(regnode_set_voltage, axp209_regnode_set_voltage),
312 REGNODEMETHOD(regnode_get_voltage, axp209_regnode_get_voltage),
315 DEFINE_CLASS_1(axp209_regnode, axp209_regnode_class, axp209_regnode_methods,
316 sizeof(struct axp209_reg_sc), regnode_class);
319 axp209_sysctl(SYSCTL_HANDLER_ARGS)
322 enum axp209_sensor sensor = arg2;
328 error = axp209_read(dev, AXP209_TEMPMON, data, 2);
332 /* Temperature is between -144.7C and 264.8C, step +0.1C */
333 val = (AXP209_SENSOR_H(data[0]) | AXP209_SENSOR_L(data[1])) -
334 AXP209_TEMPMON_MIN + AXP209_0C_TO_K;
337 error = axp209_read(dev, AXP209_ACIN_VOLTAGE, data, 2);
341 val = (AXP209_SENSOR_H(data[0]) | AXP209_SENSOR_L(data[1])) *
344 case AXP209_ACCURRENT:
345 error = axp209_read(dev, AXP209_ACIN_CURRENT, data, 2);
349 val = (AXP209_SENSOR_H(data[0]) | AXP209_SENSOR_L(data[1])) *
350 AXP209_ACCURRENT_STEP;
352 case AXP209_VBUSVOLT:
353 error = axp209_read(dev, AXP209_VBUS_VOLTAGE, data, 2);
357 val = (AXP209_SENSOR_H(data[0]) | AXP209_SENSOR_L(data[1])) *
360 case AXP209_VBUSCURRENT:
361 error = axp209_read(dev, AXP209_VBUS_CURRENT, data, 2);
365 val = (AXP209_SENSOR_H(data[0]) | AXP209_SENSOR_L(data[1])) *
366 AXP209_VBUSCURRENT_STEP;
369 error = axp209_read(dev, AXP209_BAT_VOLTAGE, data, 2);
373 val = (AXP209_SENSOR_H(data[0]) | AXP209_SENSOR_L(data[1])) *
376 case AXP209_BATCHARGECURRENT:
377 error = axp209_read(dev, AXP209_BAT_CHARGE_CURRENT, data, 2);
381 val = (AXP209_SENSOR_H(data[0]) | AXP209_SENSOR_L(data[1])) *
382 AXP209_BATCURRENT_STEP;
384 case AXP209_BATDISCHARGECURRENT:
385 error = axp209_read(dev, AXP209_BAT_DISCHARGE_CURRENT, data, 2);
389 val = (AXP209_SENSOR_BAT_H(data[0]) |
390 AXP209_SENSOR_BAT_L(data[1])) * AXP209_BATCURRENT_STEP;
396 return sysctl_handle_opaque(oidp, &val, sizeof(val), req);
400 axp209_shutdown(void *devp, int howto)
404 if (!(howto & RB_POWEROFF))
406 dev = (device_t)devp;
409 device_printf(dev, "Shutdown AXP209\n");
411 axp209_write(dev, AXP209_SHUTBAT, AXP209_SHUTBAT_SHUTDOWN);
417 struct axp209_softc *sc;
422 axp209_read(sc->dev, AXP209_IRQ1_STATUS, ®, 1);
424 if (reg & AXP209_IRQ1_AC_OVERVOLT)
425 devctl_notify("PMU", "AC", "overvoltage", NULL);
426 if (reg & AXP209_IRQ1_VBUS_OVERVOLT)
427 devctl_notify("PMU", "USB", "overvoltage", NULL);
428 if (reg & AXP209_IRQ1_VBUS_LOW)
429 devctl_notify("PMU", "USB", "undervoltage", NULL);
430 if (reg & AXP209_IRQ1_AC_CONN)
431 devctl_notify("PMU", "AC", "plugged", NULL);
432 if (reg & AXP209_IRQ1_AC_DISCONN)
433 devctl_notify("PMU", "AC", "unplugged", NULL);
434 if (reg & AXP209_IRQ1_VBUS_CONN)
435 devctl_notify("PMU", "USB", "plugged", NULL);
436 if (reg & AXP209_IRQ1_VBUS_DISCONN)
437 devctl_notify("PMU", "USB", "unplugged", NULL);
438 axp209_write(sc->dev, AXP209_IRQ1_STATUS, AXP209_IRQ_ACK);
441 axp209_read(sc->dev, AXP209_IRQ2_STATUS, ®, 1);
443 if (reg & AXP209_IRQ2_BATT_CHARGED)
444 devctl_notify("PMU", "Battery", "charged", NULL);
445 if (reg & AXP209_IRQ2_BATT_CHARGING)
446 devctl_notify("PMU", "Battery", "charging", NULL);
447 if (reg & AXP209_IRQ2_BATT_CONN)
448 devctl_notify("PMU", "Battery", "connected", NULL);
449 if (reg & AXP209_IRQ2_BATT_DISCONN)
450 devctl_notify("PMU", "Battery", "disconnected", NULL);
451 if (reg & AXP209_IRQ2_BATT_TEMP_LOW)
452 devctl_notify("PMU", "Battery", "low temp", NULL);
453 if (reg & AXP209_IRQ2_BATT_TEMP_OVER)
454 devctl_notify("PMU", "Battery", "high temp", NULL);
455 axp209_write(sc->dev, AXP209_IRQ2_STATUS, AXP209_IRQ_ACK);
458 axp209_read(sc->dev, AXP209_IRQ3_STATUS, ®, 1);
460 if (reg & AXP209_IRQ3_PEK_SHORT)
461 shutdown_nice(RB_POWEROFF);
462 axp209_write(sc->dev, AXP209_IRQ3_STATUS, AXP209_IRQ_ACK);
465 axp209_read(sc->dev, AXP209_IRQ4_STATUS, ®, 1);
467 axp209_write(sc->dev, AXP209_IRQ4_STATUS, AXP209_IRQ_ACK);
470 axp209_read(sc->dev, AXP209_IRQ5_STATUS, ®, 1);
472 axp209_write(sc->dev, AXP209_IRQ5_STATUS, AXP209_IRQ_ACK);
477 axp209_gpio_get_bus(device_t dev)
479 struct axp209_softc *sc;
481 sc = device_get_softc(dev);
483 return (sc->gpiodev);
487 axp209_gpio_pin_max(device_t dev, int *maxpin)
489 *maxpin = nitems(axp209_pins) - 1;
495 axp209_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
497 if (pin >= nitems(axp209_pins))
500 snprintf(name, GPIOMAXNAME, "%s", axp209_pins[pin].name);
506 axp209_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
508 if (pin >= nitems(axp209_pins))
511 *caps = GPIO_PIN_INPUT | GPIO_PIN_OUTPUT;
517 axp209_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
519 struct axp209_softc *sc;
523 if (pin >= nitems(axp209_pins))
526 sc = device_get_softc(dev);
529 error = axp209_read(dev, axp209_pins[pin].ctrl_reg, &data, 1);
531 func = data & AXP209_GPIO_FUNC_MASK;
532 if (func == AXP209_GPIO_FUNC_INPUT)
533 *flags = GPIO_PIN_INPUT;
534 else if (func == AXP209_GPIO_FUNC_DRVLO ||
535 func == AXP209_GPIO_FUNC_DRVHI)
536 *flags = GPIO_PIN_OUTPUT;
546 axp209_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
548 struct axp209_softc *sc;
552 if (pin >= nitems(axp209_pins))
555 sc = device_get_softc(dev);
558 error = axp209_read(dev, axp209_pins[pin].ctrl_reg, &data, 1);
560 data &= ~AXP209_GPIO_FUNC_MASK;
561 if ((flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) != 0) {
562 if ((flags & GPIO_PIN_OUTPUT) == 0)
563 data |= AXP209_GPIO_FUNC_INPUT;
565 error = axp209_write(dev, axp209_pins[pin].ctrl_reg, data);
573 axp209_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val)
575 struct axp209_softc *sc;
579 if (pin >= nitems(axp209_pins))
582 sc = device_get_softc(dev);
585 error = axp209_read(dev, axp209_pins[pin].ctrl_reg, &data, 1);
587 func = data & AXP209_GPIO_FUNC_MASK;
589 case AXP209_GPIO_FUNC_DRVLO:
592 case AXP209_GPIO_FUNC_DRVHI:
595 case AXP209_GPIO_FUNC_INPUT:
596 error = axp209_read(dev, AXP209_GPIO_STATUS, &data, 1);
598 *val = (data & AXP209_GPIO_DATA(pin)) ? 1 : 0;
611 axp209_gpio_pin_set(device_t dev, uint32_t pin, unsigned int val)
613 struct axp209_softc *sc;
617 if (pin >= nitems(axp209_pins))
620 sc = device_get_softc(dev);
623 error = axp209_read(dev, axp209_pins[pin].ctrl_reg, &data, 1);
625 func = data & AXP209_GPIO_FUNC_MASK;
627 case AXP209_GPIO_FUNC_DRVLO:
628 case AXP209_GPIO_FUNC_DRVHI:
629 /* GPIO2 can't be set to 1 */
630 if (pin == 2 && val == 1) {
634 data &= ~AXP209_GPIO_FUNC_MASK;
643 error = axp209_write(dev, axp209_pins[pin].ctrl_reg, data);
651 axp209_gpio_pin_toggle(device_t dev, uint32_t pin)
653 struct axp209_softc *sc;
657 if (pin >= nitems(axp209_pins))
660 sc = device_get_softc(dev);
663 error = axp209_read(dev, axp209_pins[pin].ctrl_reg, &data, 1);
665 func = data & AXP209_GPIO_FUNC_MASK;
667 case AXP209_GPIO_FUNC_DRVLO:
668 /* Pin 2 can't be set to 1*/
673 data &= ~AXP209_GPIO_FUNC_MASK;
674 data |= AXP209_GPIO_FUNC_DRVHI;
676 case AXP209_GPIO_FUNC_DRVHI:
677 data &= ~AXP209_GPIO_FUNC_MASK;
678 data |= AXP209_GPIO_FUNC_DRVLO;
686 error = axp209_write(dev, axp209_pins[pin].ctrl_reg, data);
693 axp209_gpio_map_gpios(device_t bus, phandle_t dev, phandle_t gparent,
694 int gcells, pcell_t *gpios, uint32_t *pin, uint32_t *flags)
696 if (gpios[0] >= nitems(axp209_pins))
706 axp209_get_node(device_t dev, device_t bus)
708 return (ofw_bus_get_node(dev));
711 static struct axp209_reg_sc *
712 axp209_reg_attach(device_t dev, phandle_t node,
713 struct axp209_regdef *def)
715 struct axp209_reg_sc *reg_sc;
716 struct regnode_init_def initdef;
717 struct regnode *regnode;
719 memset(&initdef, 0, sizeof(initdef));
720 if (regulator_parse_ofw_stdparam(dev, node, &initdef) != 0) {
721 device_printf(dev, "cannot create regulator\n");
724 if (initdef.std_param.min_uvolt == 0)
725 initdef.std_param.min_uvolt = def->voltage_min * 1000;
726 if (initdef.std_param.max_uvolt == 0)
727 initdef.std_param.max_uvolt = def->voltage_max * 1000;
728 initdef.id = def->id;
729 initdef.ofw_node = node;
730 regnode = regnode_create(dev, &axp209_regnode_class, &initdef);
731 if (regnode == NULL) {
732 device_printf(dev, "cannot create regulator\n");
736 reg_sc = regnode_get_softc(regnode);
737 reg_sc->regnode = regnode;
738 reg_sc->base_dev = dev;
740 reg_sc->xref = OF_xref_from_node(node);
741 reg_sc->param = regnode_get_stdparam(regnode);
743 regnode_register(regnode);
749 axp209_regdev_map(device_t dev, phandle_t xref, int ncells, pcell_t *cells,
752 struct axp209_softc *sc;
755 sc = device_get_softc(dev);
756 for (i = 0; i < sc->nregs; i++) {
757 if (sc->regs[i] == NULL)
759 if (sc->regs[i]->xref == xref) {
760 *num = sc->regs[i]->def->id;
769 axp209_start(void *pdev)
772 struct axp209_softc *sc;
773 const char *pwr_name[] = {"Battery", "AC", "USB", "AC and USB"};
779 sc = device_get_softc(dev);
780 sc->addr = iicbus_get_addr(dev);
785 * Read the Power State register.
786 * Shift the AC presence into bit 0.
787 * Shift the Battery presence into bit 1.
789 axp209_read(dev, AXP209_PSR, &data, 1);
790 pwr_src = ((data & AXP209_PSR_ACIN) >> AXP209_PSR_ACIN_SHIFT) |
791 ((data & AXP209_PSR_VBUS) >> (AXP209_PSR_VBUS_SHIFT - 1));
793 device_printf(dev, "AXP209 Powered by %s\n",
797 /* Only enable interrupts that we are interested in */
798 axp209_write(dev, AXP209_IRQ1_ENABLE,
799 AXP209_IRQ1_AC_OVERVOLT |
800 AXP209_IRQ1_AC_DISCONN |
801 AXP209_IRQ1_AC_CONN |
802 AXP209_IRQ1_VBUS_OVERVOLT |
803 AXP209_IRQ1_VBUS_DISCONN |
804 AXP209_IRQ1_VBUS_CONN);
805 axp209_write(dev, AXP209_IRQ2_ENABLE,
806 AXP209_IRQ2_BATT_CONN |
807 AXP209_IRQ2_BATT_DISCONN |
808 AXP209_IRQ2_BATT_CHARGE_ACCT_ON |
809 AXP209_IRQ2_BATT_CHARGE_ACCT_OFF |
810 AXP209_IRQ2_BATT_CHARGING |
811 AXP209_IRQ2_BATT_CHARGED |
812 AXP209_IRQ2_BATT_TEMP_OVER |
813 AXP209_IRQ2_BATT_TEMP_LOW);
814 axp209_write(dev, AXP209_IRQ3_ENABLE,
815 AXP209_IRQ3_PEK_SHORT | AXP209_IRQ3_PEK_LONG);
816 axp209_write(dev, AXP209_IRQ4_ENABLE, AXP209_IRQ4_APS_LOW_2);
817 axp209_write(dev, AXP209_IRQ5_ENABLE, 0x0);
819 EVENTHANDLER_REGISTER(shutdown_final, axp209_shutdown, dev,
822 /* Enable ADC sensors */
823 if (axp209_write(dev, AXP209_ADC_ENABLE1,
824 AXP209_ADC1_BATVOLT | AXP209_ADC1_BATCURRENT |
825 AXP209_ADC1_ACVOLT | AXP209_ADC1_ACCURRENT |
826 AXP209_ADC1_VBUSVOLT | AXP209_ADC1_VBUSCURRENT) != -1) {
827 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
828 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
830 CTLTYPE_INT | CTLFLAG_RD,
831 dev, AXP209_ACVOLT, axp209_sysctl, "I",
832 "AC Voltage (microVolt)");
833 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
834 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
835 OID_AUTO, "accurrent",
836 CTLTYPE_INT | CTLFLAG_RD,
837 dev, AXP209_ACCURRENT, axp209_sysctl, "I",
838 "AC Current (microAmpere)");
839 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
840 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
841 OID_AUTO, "vbusvolt",
842 CTLTYPE_INT | CTLFLAG_RD,
843 dev, AXP209_VBUSVOLT, axp209_sysctl, "I",
844 "VBUS Voltage (microVolt)");
845 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
846 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
847 OID_AUTO, "vbuscurrent",
848 CTLTYPE_INT | CTLFLAG_RD,
849 dev, AXP209_VBUSCURRENT, axp209_sysctl, "I",
850 "VBUS Current (microAmpere)");
851 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
852 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
854 CTLTYPE_INT | CTLFLAG_RD,
855 dev, AXP209_BATVOLT, axp209_sysctl, "I",
856 "Battery Voltage (microVolt)");
857 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
858 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
859 OID_AUTO, "batchargecurrent",
860 CTLTYPE_INT | CTLFLAG_RD,
861 dev, AXP209_BATCHARGECURRENT, axp209_sysctl, "I",
862 "Battery Charging Current (microAmpere)");
863 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
864 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
865 OID_AUTO, "batdischargecurrent",
866 CTLTYPE_INT | CTLFLAG_RD,
867 dev, AXP209_BATDISCHARGECURRENT, axp209_sysctl, "I",
868 "Battery Discharging Current (microAmpere)");
870 device_printf(dev, "Couldn't enable ADC sensors\n");
873 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
874 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
876 CTLTYPE_INT | CTLFLAG_RD,
877 dev, AXP209_TEMP, axp209_sysctl, "IK", "Internal temperature");
879 if ((bus_setup_intr(dev, sc->res[0], INTR_TYPE_MISC | INTR_MPSAFE,
880 NULL, axp_intr, sc, &sc->intrcookie)))
881 device_printf(dev, "unable to register interrupt handler\n");
883 config_intrhook_disestablish(&sc->intr_hook);
887 axp209_probe(device_t dev)
890 if (!ofw_bus_status_okay(dev))
893 if (!ofw_bus_is_compatible(dev, "x-powers,axp209"))
896 device_set_desc(dev, "X-Powers AXP209 Power Management Unit");
898 return (BUS_PROBE_DEFAULT);
902 axp209_attach(device_t dev)
904 struct axp209_softc *sc;
905 struct axp209_reg_sc *reg;
906 phandle_t rnode, child;
909 sc = device_get_softc(dev);
910 mtx_init(&sc->mtx, device_get_nameunit(dev), NULL, MTX_DEF);
912 if (bus_alloc_resources(dev, axp_res_spec, sc->res) != 0) {
913 device_printf(dev, "can't allocate device resources\n");
917 sc->intr_hook.ich_func = axp209_start;
918 sc->intr_hook.ich_arg = dev;
920 if (config_intrhook_establish(&sc->intr_hook) != 0)
923 sc->nregs = nitems(axp209_regdefs);
924 sc->regs = malloc(sizeof(struct axp209_reg_sc *) * sc->nregs,
925 M_AXP209_REG, M_WAITOK | M_ZERO);
927 /* Attach known regulators that exist in the DT */
928 rnode = ofw_bus_find_child(ofw_bus_get_node(dev), "regulators");
930 for (i = 0; i < sc->nregs; i++) {
931 child = ofw_bus_find_child(rnode,
932 axp209_regdefs[i].name);
935 reg = axp209_reg_attach(dev, child, &axp209_regdefs[i]);
938 "cannot attach regulator %s\n",
939 axp209_regdefs[i].name);
946 sc->gpiodev = gpiobus_attach_bus(dev);
951 static device_method_t axp209_methods[] = {
952 DEVMETHOD(device_probe, axp209_probe),
953 DEVMETHOD(device_attach, axp209_attach),
956 DEVMETHOD(gpio_get_bus, axp209_gpio_get_bus),
957 DEVMETHOD(gpio_pin_max, axp209_gpio_pin_max),
958 DEVMETHOD(gpio_pin_getname, axp209_gpio_pin_getname),
959 DEVMETHOD(gpio_pin_getcaps, axp209_gpio_pin_getcaps),
960 DEVMETHOD(gpio_pin_getflags, axp209_gpio_pin_getflags),
961 DEVMETHOD(gpio_pin_setflags, axp209_gpio_pin_setflags),
962 DEVMETHOD(gpio_pin_get, axp209_gpio_pin_get),
963 DEVMETHOD(gpio_pin_set, axp209_gpio_pin_set),
964 DEVMETHOD(gpio_pin_toggle, axp209_gpio_pin_toggle),
965 DEVMETHOD(gpio_map_gpios, axp209_gpio_map_gpios),
967 /* Regdev interface */
968 DEVMETHOD(regdev_map, axp209_regdev_map),
970 /* OFW bus interface */
971 DEVMETHOD(ofw_bus_get_node, axp209_get_node),
976 static driver_t axp209_driver = {
979 sizeof(struct axp209_softc),
982 static devclass_t axp209_devclass;
983 extern devclass_t ofwgpiobus_devclass, gpioc_devclass;
984 extern driver_t ofw_gpiobus_driver, gpioc_driver;
986 EARLY_DRIVER_MODULE(axp209, iicbus, axp209_driver, axp209_devclass,
987 0, 0, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_LATE);
988 EARLY_DRIVER_MODULE(ofw_gpiobus, axp209_pmu, ofw_gpiobus_driver,
989 ofwgpiobus_devclass, 0, 0, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_LATE);
990 DRIVER_MODULE(gpioc, axp209_pmu, gpioc_driver, gpioc_devclass,
992 MODULE_VERSION(axp209, 1);
993 MODULE_DEPEND(axp209, iicbus, 1, 1, 1);