2 * Copyright (c) 2015-2016 Emmanuel Vadot <manu@freebsd.org>
3 * Copyright (c) 2016 Jared McNeill <jmcneill@invisible.ca>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
31 * X-Power AXP209/AXP211 PMU for Allwinner SoCs
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/eventhandler.h>
37 #include <sys/kernel.h>
38 #include <sys/module.h>
39 #include <sys/clock.h>
44 #include <sys/reboot.h>
45 #include <sys/resource.h>
47 #include <sys/sysctl.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>
61 #include "regdev_if.h"
63 MALLOC_DEFINE(M_AXP2XX_REG, "Axp2XX regulator", "Axp2XX power regulator");
65 struct axp2xx_regdef {
72 uint8_t voltage_shift;
79 static struct axp2xx_regdef axp209_regdefs[] = {
81 .id = AXP209_REG_ID_DCDC2,
83 .enable_reg = AXP209_POWERCTL,
84 .enable_mask = AXP209_POWERCTL_DCDC2,
85 .voltage_reg = AXP209_REG_DCDC2_VOLTAGE,
93 .id = AXP209_REG_ID_DCDC3,
95 .enable_reg = AXP209_POWERCTL,
96 .enable_mask = AXP209_POWERCTL_DCDC3,
97 .voltage_reg = AXP209_REG_DCDC3_VOLTAGE,
102 .voltage_nstep = 128,
105 .id = AXP209_REG_ID_LDO2,
107 .enable_reg = AXP209_POWERCTL,
108 .enable_mask = AXP209_POWERCTL_LDO2,
109 .voltage_reg = AXP209_REG_LDO24_VOLTAGE,
110 .voltage_mask = 0xf0,
118 .id = AXP209_REG_ID_LDO3,
120 .enable_reg = AXP209_POWERCTL,
121 .enable_mask = AXP209_POWERCTL_LDO3,
122 .voltage_reg = AXP209_REG_LDO3_VOLTAGE,
123 .voltage_mask = 0x7f,
127 .voltage_nstep = 128,
131 static struct axp2xx_regdef axp221_regdefs[] = {
133 .id = AXP221_REG_ID_DLDO1,
135 .enable_reg = AXP221_POWERCTL_2,
136 .enable_mask = AXP221_POWERCTL2_DLDO1,
137 .voltage_reg = AXP221_REG_DLDO1_VOLTAGE,
138 .voltage_mask = 0x1f,
145 .id = AXP221_REG_ID_DLDO2,
147 .enable_reg = AXP221_POWERCTL_2,
148 .enable_mask = AXP221_POWERCTL2_DLDO2,
149 .voltage_reg = AXP221_REG_DLDO2_VOLTAGE,
150 .voltage_mask = 0x1f,
157 .id = AXP221_REG_ID_DLDO3,
159 .enable_reg = AXP221_POWERCTL_2,
160 .enable_mask = AXP221_POWERCTL2_DLDO3,
161 .voltage_reg = AXP221_REG_DLDO3_VOLTAGE,
162 .voltage_mask = 0x1f,
169 .id = AXP221_REG_ID_DLDO4,
171 .enable_reg = AXP221_POWERCTL_2,
172 .enable_mask = AXP221_POWERCTL2_DLDO4,
173 .voltage_reg = AXP221_REG_DLDO4_VOLTAGE,
174 .voltage_mask = 0x1f,
181 .id = AXP221_REG_ID_ELDO1,
183 .enable_reg = AXP221_POWERCTL_2,
184 .enable_mask = AXP221_POWERCTL2_ELDO1,
185 .voltage_reg = AXP221_REG_ELDO1_VOLTAGE,
186 .voltage_mask = 0x1f,
193 .id = AXP221_REG_ID_ELDO2,
195 .enable_reg = AXP221_POWERCTL_2,
196 .enable_mask = AXP221_POWERCTL2_ELDO2,
197 .voltage_reg = AXP221_REG_ELDO2_VOLTAGE,
198 .voltage_mask = 0x1f,
205 .id = AXP221_REG_ID_ELDO3,
207 .enable_reg = AXP221_POWERCTL_2,
208 .enable_mask = AXP221_POWERCTL2_ELDO3,
209 .voltage_reg = AXP221_REG_ELDO3_VOLTAGE,
210 .voltage_mask = 0x1f,
217 .id = AXP221_REG_ID_DC5LDO,
219 .enable_reg = AXP221_POWERCTL_1,
220 .enable_mask = AXP221_POWERCTL1_DC5LDO,
221 .voltage_reg = AXP221_REG_DC5LDO_VOLTAGE,
229 .id = AXP221_REG_ID_DCDC1,
231 .enable_reg = AXP221_POWERCTL_1,
232 .enable_mask = AXP221_POWERCTL1_DCDC1,
233 .voltage_reg = AXP221_REG_DCDC1_VOLTAGE,
234 .voltage_mask = 0x1f,
241 .id = AXP221_REG_ID_DCDC2,
243 .enable_reg = AXP221_POWERCTL_1,
244 .enable_mask = AXP221_POWERCTL1_DCDC2,
245 .voltage_reg = AXP221_REG_DCDC2_VOLTAGE,
246 .voltage_mask = 0x3f,
253 .id = AXP221_REG_ID_DCDC3,
255 .enable_reg = AXP221_POWERCTL_1,
256 .enable_mask = AXP221_POWERCTL1_DCDC3,
257 .voltage_reg = AXP221_REG_DCDC3_VOLTAGE,
258 .voltage_mask = 0x3f,
265 .id = AXP221_REG_ID_DCDC4,
267 .enable_reg = AXP221_POWERCTL_1,
268 .enable_mask = AXP221_POWERCTL1_DCDC4,
269 .voltage_reg = AXP221_REG_DCDC4_VOLTAGE,
270 .voltage_mask = 0x3f,
277 .id = AXP221_REG_ID_DCDC5,
279 .enable_reg = AXP221_POWERCTL_1,
280 .enable_mask = AXP221_POWERCTL1_DCDC5,
281 .voltage_reg = AXP221_REG_DCDC5_VOLTAGE,
282 .voltage_mask = 0x1f,
289 .id = AXP221_REG_ID_ALDO1,
291 .enable_reg = AXP221_POWERCTL_1,
292 .enable_mask = AXP221_POWERCTL1_ALDO1,
293 .voltage_reg = AXP221_REG_ALDO1_VOLTAGE,
294 .voltage_mask = 0x1f,
301 .id = AXP221_REG_ID_ALDO2,
303 .enable_reg = AXP221_POWERCTL_1,
304 .enable_mask = AXP221_POWERCTL1_ALDO2,
305 .voltage_reg = AXP221_REG_ALDO2_VOLTAGE,
306 .voltage_mask = 0x1f,
313 .id = AXP221_REG_ID_ALDO3,
315 .enable_reg = AXP221_POWERCTL_3,
316 .enable_mask = AXP221_POWERCTL3_ALDO3,
317 .voltage_reg = AXP221_REG_ALDO3_VOLTAGE,
318 .voltage_mask = 0x1f,
325 .id = AXP221_REG_ID_DC1SW,
327 .enable_reg = AXP221_POWERCTL_2,
328 .enable_mask = AXP221_POWERCTL2_DC1SW,
332 struct axp2xx_reg_sc {
333 struct regnode *regnode;
335 struct axp2xx_regdef *def;
337 struct regnode_std_param *param;
345 uint8_t status_shift;
348 /* GPIO3 is different, don't expose it for now */
349 static const struct axp2xx_pins axp209_pins[] = {
352 .ctrl_reg = AXP2XX_GPIO0_CTRL,
353 .status_reg = AXP2XX_GPIO_STATUS,
359 .ctrl_reg = AXP2XX_GPIO1_CTRL,
360 .status_reg = AXP2XX_GPIO_STATUS,
366 .ctrl_reg = AXP209_GPIO2_CTRL,
367 .status_reg = AXP2XX_GPIO_STATUS,
373 static const struct axp2xx_pins axp221_pins[] = {
376 .ctrl_reg = AXP2XX_GPIO0_CTRL,
377 .status_reg = AXP2XX_GPIO_STATUS,
383 .ctrl_reg = AXP2XX_GPIO0_CTRL,
384 .status_reg = AXP2XX_GPIO_STATUS,
390 struct axp2xx_sensors {
399 uint8_t h_value_mask;
400 uint8_t h_value_shift;
401 uint8_t l_value_mask;
402 uint8_t l_value_shift;
407 static const struct axp2xx_sensors axp209_sensors[] = {
411 .desc = "AC Voltage (microvolt)",
413 .enable_reg = AXP2XX_ADC_ENABLE1,
414 .enable_mask = AXP209_ADC1_ACVOLT,
415 .value_reg = AXP209_ACIN_VOLTAGE,
417 .h_value_mask = 0xff,
421 .value_step = AXP209_VOLT_STEP,
424 .id = AXP209_ACCURRENT,
426 .desc = "AC Current (microAmpere)",
428 .enable_reg = AXP2XX_ADC_ENABLE1,
429 .enable_mask = AXP209_ADC1_ACCURRENT,
430 .value_reg = AXP209_ACIN_CURRENT,
432 .h_value_mask = 0xff,
436 .value_step = AXP209_ACCURRENT_STEP,
439 .id = AXP209_VBUSVOLT,
441 .desc = "VBUS Voltage (microVolt)",
443 .enable_reg = AXP2XX_ADC_ENABLE1,
444 .enable_mask = AXP209_ADC1_VBUSVOLT,
445 .value_reg = AXP209_VBUS_VOLTAGE,
447 .h_value_mask = 0xff,
451 .value_step = AXP209_VOLT_STEP,
454 .id = AXP209_VBUSCURRENT,
455 .name = "vbuscurrent",
456 .desc = "VBUS Current (microAmpere)",
458 .enable_reg = AXP2XX_ADC_ENABLE1,
459 .enable_mask = AXP209_ADC1_VBUSCURRENT,
460 .value_reg = AXP209_VBUS_CURRENT,
462 .h_value_mask = 0xff,
466 .value_step = AXP209_VBUSCURRENT_STEP,
469 .id = AXP2XX_BATVOLT,
471 .desc = "Battery Voltage (microVolt)",
473 .enable_reg = AXP2XX_ADC_ENABLE1,
474 .enable_mask = AXP2XX_ADC1_BATVOLT,
475 .value_reg = AXP2XX_BAT_VOLTAGE,
477 .h_value_mask = 0xff,
481 .value_step = AXP2XX_BATVOLT_STEP,
484 .id = AXP2XX_BATCHARGECURRENT,
485 .name = "batchargecurrent",
486 .desc = "Battery Charging Current (microAmpere)",
488 .enable_reg = AXP2XX_ADC_ENABLE1,
489 .enable_mask = AXP2XX_ADC1_BATCURRENT,
490 .value_reg = AXP2XX_BAT_CHARGE_CURRENT,
492 .h_value_mask = 0xff,
494 .l_value_mask = 0x1f,
496 .value_step = AXP2XX_BATCURRENT_STEP,
499 .id = AXP2XX_BATDISCHARGECURRENT,
500 .name = "batdischargecurrent",
501 .desc = "Battery Discharging Current (microAmpere)",
503 .enable_reg = AXP2XX_ADC_ENABLE1,
504 .enable_mask = AXP2XX_ADC1_BATCURRENT,
505 .value_reg = AXP2XX_BAT_DISCHARGE_CURRENT,
507 .h_value_mask = 0xff,
509 .l_value_mask = 0x1f,
511 .value_step = AXP2XX_BATCURRENT_STEP,
516 .desc = "Internal Temperature",
518 .enable_reg = AXP209_ADC_ENABLE2,
519 .enable_mask = AXP209_ADC2_TEMP,
520 .value_reg = AXP209_TEMPMON,
522 .h_value_mask = 0xff,
527 .value_convert = -(AXP209_TEMPMON_MIN - AXP209_0C_TO_K),
531 static const struct axp2xx_sensors axp221_sensors[] = {
533 .id = AXP2XX_BATVOLT,
535 .desc = "Battery Voltage (microVolt)",
537 .enable_reg = AXP2XX_ADC_ENABLE1,
538 .enable_mask = AXP2XX_ADC1_BATVOLT,
539 .value_reg = AXP2XX_BAT_VOLTAGE,
541 .h_value_mask = 0xff,
545 .value_step = AXP2XX_BATVOLT_STEP,
548 .id = AXP2XX_BATCHARGECURRENT,
549 .name = "batchargecurrent",
550 .desc = "Battery Charging Current (microAmpere)",
552 .enable_reg = AXP2XX_ADC_ENABLE1,
553 .enable_mask = AXP2XX_ADC1_BATCURRENT,
554 .value_reg = AXP2XX_BAT_CHARGE_CURRENT,
556 .h_value_mask = 0xff,
558 .l_value_mask = 0x1f,
560 .value_step = AXP2XX_BATCURRENT_STEP,
563 .id = AXP2XX_BATDISCHARGECURRENT,
564 .name = "batdischargecurrent",
565 .desc = "Battery Discharging Current (microAmpere)",
567 .enable_reg = AXP2XX_ADC_ENABLE1,
568 .enable_mask = AXP2XX_ADC1_BATCURRENT,
569 .value_reg = AXP2XX_BAT_DISCHARGE_CURRENT,
571 .h_value_mask = 0xff,
573 .l_value_mask = 0x1f,
575 .value_step = AXP2XX_BATCURRENT_STEP,
580 .desc = "Internal Temperature",
582 .enable_reg = AXP2XX_ADC_ENABLE1,
583 .enable_mask = AXP221_ADC1_TEMP,
584 .value_reg = AXP221_TEMPMON,
586 .h_value_mask = 0xff,
591 .value_convert = -(AXP221_TEMPMON_MIN - AXP209_0C_TO_K),
600 struct axp2xx_softc {
602 struct resource * res[1];
604 struct intr_config_hook intr_hook;
611 const struct axp2xx_pins *pins;
614 const struct axp2xx_sensors *sensors;
618 struct axp2xx_reg_sc **regs;
620 struct axp2xx_regdef *regdefs;
623 static struct ofw_compat_data compat_data[] = {
624 { "x-powers,axp209", AXP209 },
625 { "x-powers,axp221", AXP221 },
629 static struct resource_spec axp_res_spec[] = {
630 { SYS_RES_IRQ, 0, RF_ACTIVE },
634 #define AXP_LOCK(sc) mtx_lock(&(sc)->mtx)
635 #define AXP_UNLOCK(sc) mtx_unlock(&(sc)->mtx)
638 axp2xx_read(device_t dev, uint8_t reg, uint8_t *data, uint8_t size)
641 return (iicdev_readfrom(dev, reg, data, size, IIC_INTRWAIT));
645 axp2xx_write(device_t dev, uint8_t reg, uint8_t data)
648 return (iicdev_writeto(dev, reg, &data, sizeof(data), IIC_INTRWAIT));
652 axp2xx_regnode_init(struct regnode *regnode)
658 axp2xx_regnode_enable(struct regnode *regnode, bool enable, int *udelay)
660 struct axp2xx_reg_sc *sc;
663 sc = regnode_get_softc(regnode);
665 axp2xx_read(sc->base_dev, sc->def->enable_reg, &val, 1);
667 val |= sc->def->enable_mask;
669 val &= ~sc->def->enable_mask;
670 axp2xx_write(sc->base_dev, sc->def->enable_reg, val);
678 axp2xx_regnode_reg_to_voltage(struct axp2xx_reg_sc *sc, uint8_t val, int *uv)
680 if (val < sc->def->voltage_nstep)
681 *uv = sc->def->voltage_min + val * sc->def->voltage_step;
683 *uv = sc->def->voltage_min +
684 (sc->def->voltage_nstep * sc->def->voltage_step);
689 axp2xx_regnode_voltage_to_reg(struct axp2xx_reg_sc *sc, int min_uvolt,
690 int max_uvolt, uint8_t *val)
696 uvolt = sc->def->voltage_min * 1000;
698 for (nstep = 0; nstep < sc->def->voltage_nstep && uvolt < min_uvolt;
701 uvolt += (sc->def->voltage_step * 1000);
703 if (uvolt > max_uvolt)
711 axp2xx_regnode_set_voltage(struct regnode *regnode, int min_uvolt,
712 int max_uvolt, int *udelay)
714 struct axp2xx_reg_sc *sc;
717 sc = regnode_get_softc(regnode);
719 if (!sc->def->voltage_step)
722 if (axp2xx_regnode_voltage_to_reg(sc, min_uvolt, max_uvolt, &val) != 0)
725 axp2xx_write(sc->base_dev, sc->def->voltage_reg, val);
733 axp2xx_regnode_get_voltage(struct regnode *regnode, int *uvolt)
735 struct axp2xx_reg_sc *sc;
738 sc = regnode_get_softc(regnode);
740 if (!sc->def->voltage_step)
743 axp2xx_read(sc->base_dev, sc->def->voltage_reg, &val, 1);
744 axp2xx_regnode_reg_to_voltage(sc, val & sc->def->voltage_mask, uvolt);
749 static regnode_method_t axp2xx_regnode_methods[] = {
750 /* Regulator interface */
751 REGNODEMETHOD(regnode_init, axp2xx_regnode_init),
752 REGNODEMETHOD(regnode_enable, axp2xx_regnode_enable),
753 REGNODEMETHOD(regnode_set_voltage, axp2xx_regnode_set_voltage),
754 REGNODEMETHOD(regnode_get_voltage, axp2xx_regnode_get_voltage),
755 REGNODEMETHOD(regnode_check_voltage, regnode_method_check_voltage),
758 DEFINE_CLASS_1(axp2xx_regnode, axp2xx_regnode_class, axp2xx_regnode_methods,
759 sizeof(struct axp2xx_reg_sc), regnode_class);
762 axp2xx_sysctl(SYSCTL_HANDLER_ARGS)
764 struct axp2xx_softc *sc;
766 enum axp2xx_sensor sensor = arg2;
768 int val, error, i, found;
770 sc = device_get_softc(dev);
772 for (found = 0, i = 0; i < sc->nsensors; i++) {
773 if (sc->sensors[i].id == sensor) {
782 error = axp2xx_read(dev, sc->sensors[i].value_reg, data, 2);
786 val = ((data[0] & sc->sensors[i].h_value_mask) <<
787 sc->sensors[i].h_value_shift);
788 val |= ((data[1] & sc->sensors[i].l_value_mask) <<
789 sc->sensors[i].l_value_shift);
790 val *= sc->sensors[i].value_step;
791 val += sc->sensors[i].value_convert;
793 return sysctl_handle_opaque(oidp, &val, sizeof(val), req);
797 axp2xx_shutdown(void *devp, int howto)
801 if (!(howto & RB_POWEROFF))
803 dev = (device_t)devp;
806 device_printf(dev, "Shutdown AXP2xx\n");
808 axp2xx_write(dev, AXP2XX_SHUTBAT, AXP2XX_SHUTBAT_SHUTDOWN);
812 axp2xx_intr(void *arg)
814 struct axp2xx_softc *sc;
819 axp2xx_read(sc->dev, AXP2XX_IRQ1_STATUS, ®, 1);
821 if (reg & AXP2XX_IRQ1_AC_OVERVOLT)
822 devctl_notify("PMU", "AC", "overvoltage", NULL);
823 if (reg & AXP2XX_IRQ1_VBUS_OVERVOLT)
824 devctl_notify("PMU", "USB", "overvoltage", NULL);
825 if (reg & AXP2XX_IRQ1_VBUS_LOW)
826 devctl_notify("PMU", "USB", "undervoltage", NULL);
827 if (reg & AXP2XX_IRQ1_AC_CONN)
828 devctl_notify("PMU", "AC", "plugged", NULL);
829 if (reg & AXP2XX_IRQ1_AC_DISCONN)
830 devctl_notify("PMU", "AC", "unplugged", NULL);
831 if (reg & AXP2XX_IRQ1_VBUS_CONN)
832 devctl_notify("PMU", "USB", "plugged", NULL);
833 if (reg & AXP2XX_IRQ1_VBUS_DISCONN)
834 devctl_notify("PMU", "USB", "unplugged", NULL);
835 axp2xx_write(sc->dev, AXP2XX_IRQ1_STATUS, AXP2XX_IRQ_ACK);
838 axp2xx_read(sc->dev, AXP2XX_IRQ2_STATUS, ®, 1);
840 if (reg & AXP2XX_IRQ2_BATT_CHARGED)
841 devctl_notify("PMU", "Battery", "charged", NULL);
842 if (reg & AXP2XX_IRQ2_BATT_CHARGING)
843 devctl_notify("PMU", "Battery", "charging", NULL);
844 if (reg & AXP2XX_IRQ2_BATT_CONN)
845 devctl_notify("PMU", "Battery", "connected", NULL);
846 if (reg & AXP2XX_IRQ2_BATT_DISCONN)
847 devctl_notify("PMU", "Battery", "disconnected", NULL);
848 if (reg & AXP2XX_IRQ2_BATT_TEMP_LOW)
849 devctl_notify("PMU", "Battery", "low temp", NULL);
850 if (reg & AXP2XX_IRQ2_BATT_TEMP_OVER)
851 devctl_notify("PMU", "Battery", "high temp", NULL);
852 axp2xx_write(sc->dev, AXP2XX_IRQ2_STATUS, AXP2XX_IRQ_ACK);
855 axp2xx_read(sc->dev, AXP2XX_IRQ3_STATUS, ®, 1);
857 if (reg & AXP2XX_IRQ3_PEK_SHORT)
858 shutdown_nice(RB_POWEROFF);
859 axp2xx_write(sc->dev, AXP2XX_IRQ3_STATUS, AXP2XX_IRQ_ACK);
862 axp2xx_read(sc->dev, AXP2XX_IRQ4_STATUS, ®, 1);
864 axp2xx_write(sc->dev, AXP2XX_IRQ4_STATUS, AXP2XX_IRQ_ACK);
867 axp2xx_read(sc->dev, AXP2XX_IRQ5_STATUS, ®, 1);
869 axp2xx_write(sc->dev, AXP2XX_IRQ5_STATUS, AXP2XX_IRQ_ACK);
874 axp2xx_gpio_get_bus(device_t dev)
876 struct axp2xx_softc *sc;
878 sc = device_get_softc(dev);
880 return (sc->gpiodev);
884 axp2xx_gpio_pin_max(device_t dev, int *maxpin)
886 struct axp2xx_softc *sc;
888 sc = device_get_softc(dev);
890 *maxpin = sc->npins - 1;
896 axp2xx_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
898 struct axp2xx_softc *sc;
900 sc = device_get_softc(dev);
902 if (pin >= sc->npins)
905 snprintf(name, GPIOMAXNAME, "%s", axp209_pins[pin].name);
911 axp2xx_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
913 struct axp2xx_softc *sc;
915 sc = device_get_softc(dev);
917 if (pin >= sc->npins)
920 *caps = GPIO_PIN_INPUT | GPIO_PIN_OUTPUT;
926 axp2xx_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
928 struct axp2xx_softc *sc;
932 sc = device_get_softc(dev);
934 if (pin >= sc->npins)
938 error = axp2xx_read(dev, sc->pins[pin].ctrl_reg, &data, 1);
940 func = data & AXP2XX_GPIO_FUNC_MASK;
941 if (func == AXP2XX_GPIO_FUNC_INPUT)
942 *flags = GPIO_PIN_INPUT;
943 else if (func == AXP2XX_GPIO_FUNC_DRVLO ||
944 func == AXP2XX_GPIO_FUNC_DRVHI)
945 *flags = GPIO_PIN_OUTPUT;
955 axp2xx_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
957 struct axp2xx_softc *sc;
961 sc = device_get_softc(dev);
963 if (pin >= sc->npins)
967 error = axp2xx_read(dev, sc->pins[pin].ctrl_reg, &data, 1);
969 data &= ~AXP2XX_GPIO_FUNC_MASK;
970 if ((flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) != 0) {
971 if ((flags & GPIO_PIN_OUTPUT) == 0)
972 data |= AXP2XX_GPIO_FUNC_INPUT;
974 error = axp2xx_write(dev, sc->pins[pin].ctrl_reg, data);
982 axp2xx_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val)
984 struct axp2xx_softc *sc;
988 sc = device_get_softc(dev);
990 if (pin >= sc->npins)
994 error = axp2xx_read(dev, sc->pins[pin].ctrl_reg, &data, 1);
996 func = data & AXP2XX_GPIO_FUNC_MASK;
998 case AXP2XX_GPIO_FUNC_DRVLO:
1001 case AXP2XX_GPIO_FUNC_DRVHI:
1004 case AXP2XX_GPIO_FUNC_INPUT:
1005 error = axp2xx_read(dev, sc->pins[pin].status_reg,
1008 *val = (data & sc->pins[pin].status_mask);
1009 *val >>= sc->pins[pin].status_shift;
1023 axp2xx_gpio_pin_set(device_t dev, uint32_t pin, unsigned int val)
1025 struct axp2xx_softc *sc;
1029 sc = device_get_softc(dev);
1031 if (pin >= sc->npins)
1035 error = axp2xx_read(dev, sc->pins[pin].ctrl_reg, &data, 1);
1037 func = data & AXP2XX_GPIO_FUNC_MASK;
1039 case AXP2XX_GPIO_FUNC_DRVLO:
1040 case AXP2XX_GPIO_FUNC_DRVHI:
1041 /* GPIO2 can't be set to 1 */
1042 if (pin == 2 && val == 1) {
1046 data &= ~AXP2XX_GPIO_FUNC_MASK;
1055 error = axp2xx_write(dev, sc->pins[pin].ctrl_reg, data);
1063 axp2xx_gpio_pin_toggle(device_t dev, uint32_t pin)
1065 struct axp2xx_softc *sc;
1069 sc = device_get_softc(dev);
1071 if (pin >= sc->npins)
1075 error = axp2xx_read(dev, sc->pins[pin].ctrl_reg, &data, 1);
1077 func = data & AXP2XX_GPIO_FUNC_MASK;
1079 case AXP2XX_GPIO_FUNC_DRVLO:
1080 /* Pin 2 can't be set to 1*/
1085 data &= ~AXP2XX_GPIO_FUNC_MASK;
1086 data |= AXP2XX_GPIO_FUNC_DRVHI;
1088 case AXP2XX_GPIO_FUNC_DRVHI:
1089 data &= ~AXP2XX_GPIO_FUNC_MASK;
1090 data |= AXP2XX_GPIO_FUNC_DRVLO;
1098 error = axp2xx_write(dev, sc->pins[pin].ctrl_reg, data);
1105 axp2xx_gpio_map_gpios(device_t bus, phandle_t dev, phandle_t gparent,
1106 int gcells, pcell_t *gpios, uint32_t *pin, uint32_t *flags)
1108 struct axp2xx_softc *sc;
1110 sc = device_get_softc(bus);
1112 if (gpios[0] >= sc->npins)
1122 axp2xx_get_node(device_t dev, device_t bus)
1124 return (ofw_bus_get_node(dev));
1127 static struct axp2xx_reg_sc *
1128 axp2xx_reg_attach(device_t dev, phandle_t node,
1129 struct axp2xx_regdef *def)
1131 struct axp2xx_reg_sc *reg_sc;
1132 struct regnode_init_def initdef;
1133 struct regnode *regnode;
1135 memset(&initdef, 0, sizeof(initdef));
1136 if (regulator_parse_ofw_stdparam(dev, node, &initdef) != 0) {
1137 device_printf(dev, "cannot create regulator\n");
1140 if (initdef.std_param.min_uvolt == 0)
1141 initdef.std_param.min_uvolt = def->voltage_min * 1000;
1142 if (initdef.std_param.max_uvolt == 0)
1143 initdef.std_param.max_uvolt = def->voltage_max * 1000;
1144 initdef.id = def->id;
1145 initdef.ofw_node = node;
1146 regnode = regnode_create(dev, &axp2xx_regnode_class, &initdef);
1147 if (regnode == NULL) {
1148 device_printf(dev, "cannot create regulator\n");
1152 reg_sc = regnode_get_softc(regnode);
1153 reg_sc->regnode = regnode;
1154 reg_sc->base_dev = dev;
1156 reg_sc->xref = OF_xref_from_node(node);
1157 reg_sc->param = regnode_get_stdparam(regnode);
1159 regnode_register(regnode);
1165 axp2xx_regdev_map(device_t dev, phandle_t xref, int ncells, pcell_t *cells,
1168 struct axp2xx_softc *sc;
1171 sc = device_get_softc(dev);
1172 for (i = 0; i < sc->nregs; i++) {
1173 if (sc->regs[i] == NULL)
1175 if (sc->regs[i]->xref == xref) {
1176 *num = sc->regs[i]->def->id;
1185 axp2xx_start(void *pdev)
1188 struct axp2xx_softc *sc;
1189 const char *pwr_name[] = {"Battery", "AC", "USB", "AC and USB"};
1196 sc = device_get_softc(dev);
1201 * Read the Power State register.
1202 * Shift the AC presence into bit 0.
1203 * Shift the Battery presence into bit 1.
1205 axp2xx_read(dev, AXP2XX_PSR, &data, 1);
1206 pwr_src = ((data & AXP2XX_PSR_ACIN) >> AXP2XX_PSR_ACIN_SHIFT) |
1207 ((data & AXP2XX_PSR_VBUS) >> (AXP2XX_PSR_VBUS_SHIFT - 1));
1209 device_printf(dev, "Powered by %s\n",
1213 /* Only enable interrupts that we are interested in */
1214 axp2xx_write(dev, AXP2XX_IRQ1_ENABLE,
1215 AXP2XX_IRQ1_AC_OVERVOLT |
1216 AXP2XX_IRQ1_AC_DISCONN |
1217 AXP2XX_IRQ1_AC_CONN |
1218 AXP2XX_IRQ1_VBUS_OVERVOLT |
1219 AXP2XX_IRQ1_VBUS_DISCONN |
1220 AXP2XX_IRQ1_VBUS_CONN);
1221 axp2xx_write(dev, AXP2XX_IRQ2_ENABLE,
1222 AXP2XX_IRQ2_BATT_CONN |
1223 AXP2XX_IRQ2_BATT_DISCONN |
1224 AXP2XX_IRQ2_BATT_CHARGE_ACCT_ON |
1225 AXP2XX_IRQ2_BATT_CHARGE_ACCT_OFF |
1226 AXP2XX_IRQ2_BATT_CHARGING |
1227 AXP2XX_IRQ2_BATT_CHARGED |
1228 AXP2XX_IRQ2_BATT_TEMP_OVER |
1229 AXP2XX_IRQ2_BATT_TEMP_LOW);
1230 axp2xx_write(dev, AXP2XX_IRQ3_ENABLE,
1231 AXP2XX_IRQ3_PEK_SHORT | AXP2XX_IRQ3_PEK_LONG);
1232 axp2xx_write(dev, AXP2XX_IRQ4_ENABLE, AXP2XX_IRQ4_APS_LOW_2);
1233 axp2xx_write(dev, AXP2XX_IRQ5_ENABLE, 0x0);
1235 EVENTHANDLER_REGISTER(shutdown_final, axp2xx_shutdown, dev,
1238 /* Enable ADC sensors */
1239 for (i = 0; i < sc->nsensors; i++) {
1240 if (axp2xx_read(dev, sc->sensors[i].enable_reg, ®, 1) == -1) {
1241 device_printf(dev, "Cannot enable sensor '%s'\n",
1242 sc->sensors[i].name);
1245 reg |= sc->sensors[i].enable_mask;
1246 if (axp2xx_write(dev, sc->sensors[i].enable_reg, reg) == -1) {
1247 device_printf(dev, "Cannot enable sensor '%s'\n",
1248 sc->sensors[i].name);
1251 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
1252 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
1253 OID_AUTO, sc->sensors[i].name,
1254 CTLTYPE_INT | CTLFLAG_RD,
1255 dev, sc->sensors[i].id, axp2xx_sysctl,
1256 sc->sensors[i].format,
1257 sc->sensors[i].desc);
1260 if ((bus_setup_intr(dev, sc->res[0], INTR_TYPE_MISC | INTR_MPSAFE,
1261 NULL, axp2xx_intr, sc, &sc->intrcookie)))
1262 device_printf(dev, "unable to register interrupt handler\n");
1264 config_intrhook_disestablish(&sc->intr_hook);
1268 axp2xx_probe(device_t dev)
1271 if (!ofw_bus_status_okay(dev))
1274 switch (ofw_bus_search_compatible(dev, compat_data)->ocd_data)
1277 device_set_desc(dev, "X-Powers AXP209 Power Management Unit");
1280 device_set_desc(dev, "X-Powers AXP221 Power Management Unit");
1286 return (BUS_PROBE_DEFAULT);
1290 axp2xx_attach(device_t dev)
1292 struct axp2xx_softc *sc;
1293 struct axp2xx_reg_sc *reg;
1294 struct axp2xx_regdef *regdefs;
1295 phandle_t rnode, child;
1298 sc = device_get_softc(dev);
1299 mtx_init(&sc->mtx, device_get_nameunit(dev), NULL, MTX_DEF);
1301 if (bus_alloc_resources(dev, axp_res_spec, sc->res) != 0) {
1302 device_printf(dev, "can't allocate device resources\n");
1306 sc->type = ofw_bus_search_compatible(dev, compat_data)->ocd_data;
1309 sc->pins = axp209_pins;
1310 sc->npins = nitems(axp209_pins);
1311 sc->gpiodev = gpiobus_attach_bus(dev);
1313 sc->sensors = axp209_sensors;
1314 sc->nsensors = nitems(axp209_sensors);
1316 regdefs = axp209_regdefs;
1317 sc->nregs = nitems(axp209_regdefs);
1320 sc->pins = axp221_pins;
1321 sc->npins = nitems(axp221_pins);
1322 sc->gpiodev = gpiobus_attach_bus(dev);
1324 sc->sensors = axp221_sensors;
1325 sc->nsensors = nitems(axp221_sensors);
1327 regdefs = axp221_regdefs;
1328 sc->nregs = nitems(axp221_regdefs);
1332 sc->regs = malloc(sizeof(struct axp2xx_reg_sc *) * sc->nregs,
1333 M_AXP2XX_REG, M_WAITOK | M_ZERO);
1335 sc->intr_hook.ich_func = axp2xx_start;
1336 sc->intr_hook.ich_arg = dev;
1338 if (config_intrhook_establish(&sc->intr_hook) != 0)
1341 /* Attach known regulators that exist in the DT */
1342 rnode = ofw_bus_find_child(ofw_bus_get_node(dev), "regulators");
1344 for (i = 0; i < sc->nregs; i++) {
1345 child = ofw_bus_find_child(rnode,
1349 reg = axp2xx_reg_attach(dev, child, ®defs[i]);
1352 "cannot attach regulator %s\n",
1358 device_printf(dev, "Regulator %s attached\n",
1366 static device_method_t axp2xx_methods[] = {
1367 DEVMETHOD(device_probe, axp2xx_probe),
1368 DEVMETHOD(device_attach, axp2xx_attach),
1370 /* GPIO interface */
1371 DEVMETHOD(gpio_get_bus, axp2xx_gpio_get_bus),
1372 DEVMETHOD(gpio_pin_max, axp2xx_gpio_pin_max),
1373 DEVMETHOD(gpio_pin_getname, axp2xx_gpio_pin_getname),
1374 DEVMETHOD(gpio_pin_getcaps, axp2xx_gpio_pin_getcaps),
1375 DEVMETHOD(gpio_pin_getflags, axp2xx_gpio_pin_getflags),
1376 DEVMETHOD(gpio_pin_setflags, axp2xx_gpio_pin_setflags),
1377 DEVMETHOD(gpio_pin_get, axp2xx_gpio_pin_get),
1378 DEVMETHOD(gpio_pin_set, axp2xx_gpio_pin_set),
1379 DEVMETHOD(gpio_pin_toggle, axp2xx_gpio_pin_toggle),
1380 DEVMETHOD(gpio_map_gpios, axp2xx_gpio_map_gpios),
1382 /* Regdev interface */
1383 DEVMETHOD(regdev_map, axp2xx_regdev_map),
1385 /* OFW bus interface */
1386 DEVMETHOD(ofw_bus_get_node, axp2xx_get_node),
1391 static driver_t axp2xx_driver = {
1394 sizeof(struct axp2xx_softc),
1397 static devclass_t axp2xx_devclass;
1398 extern devclass_t ofwgpiobus_devclass, gpioc_devclass;
1399 extern driver_t ofw_gpiobus_driver, gpioc_driver;
1401 EARLY_DRIVER_MODULE(axp2xx, iicbus, axp2xx_driver, axp2xx_devclass,
1402 0, 0, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_LATE);
1403 EARLY_DRIVER_MODULE(ofw_gpiobus, axp2xx_pmu, ofw_gpiobus_driver,
1404 ofwgpiobus_devclass, 0, 0, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_LATE);
1405 DRIVER_MODULE(gpioc, axp2xx_pmu, gpioc_driver, gpioc_devclass,
1407 MODULE_VERSION(axp2xx, 1);
1408 MODULE_DEPEND(axp2xx, iicbus, IICBUS_MINVER, IICBUS_PREFVER, IICBUS_MAXVER);