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_status(struct regnode *regnode, int *status)
713 struct axp2xx_reg_sc *sc;
716 sc = regnode_get_softc(regnode);
719 axp2xx_read(sc->base_dev, sc->def->enable_reg, &val, 1);
720 if (val & sc->def->enable_mask)
721 *status = REGULATOR_STATUS_ENABLED;
727 axp2xx_regnode_set_voltage(struct regnode *regnode, int min_uvolt,
728 int max_uvolt, int *udelay)
730 struct axp2xx_reg_sc *sc;
733 sc = regnode_get_softc(regnode);
735 if (!sc->def->voltage_step)
738 if (axp2xx_regnode_voltage_to_reg(sc, min_uvolt, max_uvolt, &val) != 0)
741 axp2xx_write(sc->base_dev, sc->def->voltage_reg, val);
749 axp2xx_regnode_get_voltage(struct regnode *regnode, int *uvolt)
751 struct axp2xx_reg_sc *sc;
754 sc = regnode_get_softc(regnode);
756 if (!sc->def->voltage_step)
759 axp2xx_read(sc->base_dev, sc->def->voltage_reg, &val, 1);
760 axp2xx_regnode_reg_to_voltage(sc, val & sc->def->voltage_mask, uvolt);
765 static regnode_method_t axp2xx_regnode_methods[] = {
766 /* Regulator interface */
767 REGNODEMETHOD(regnode_init, axp2xx_regnode_init),
768 REGNODEMETHOD(regnode_enable, axp2xx_regnode_enable),
769 REGNODEMETHOD(regnode_status, axp2xx_regnode_status),
770 REGNODEMETHOD(regnode_set_voltage, axp2xx_regnode_set_voltage),
771 REGNODEMETHOD(regnode_get_voltage, axp2xx_regnode_get_voltage),
772 REGNODEMETHOD(regnode_check_voltage, regnode_method_check_voltage),
775 DEFINE_CLASS_1(axp2xx_regnode, axp2xx_regnode_class, axp2xx_regnode_methods,
776 sizeof(struct axp2xx_reg_sc), regnode_class);
779 axp2xx_sysctl(SYSCTL_HANDLER_ARGS)
781 struct axp2xx_softc *sc;
783 enum axp2xx_sensor sensor = arg2;
785 int val, error, i, found;
787 sc = device_get_softc(dev);
789 for (found = 0, i = 0; i < sc->nsensors; i++) {
790 if (sc->sensors[i].id == sensor) {
799 error = axp2xx_read(dev, sc->sensors[i].value_reg, data, 2);
803 val = ((data[0] & sc->sensors[i].h_value_mask) <<
804 sc->sensors[i].h_value_shift);
805 val |= ((data[1] & sc->sensors[i].l_value_mask) <<
806 sc->sensors[i].l_value_shift);
807 val *= sc->sensors[i].value_step;
808 val += sc->sensors[i].value_convert;
810 return sysctl_handle_opaque(oidp, &val, sizeof(val), req);
814 axp2xx_shutdown(void *devp, int howto)
818 if (!(howto & RB_POWEROFF))
820 dev = (device_t)devp;
823 device_printf(dev, "Shutdown AXP2xx\n");
825 axp2xx_write(dev, AXP2XX_SHUTBAT, AXP2XX_SHUTBAT_SHUTDOWN);
829 axp2xx_intr(void *arg)
831 struct axp2xx_softc *sc;
836 axp2xx_read(sc->dev, AXP2XX_IRQ1_STATUS, ®, 1);
838 if (reg & AXP2XX_IRQ1_AC_OVERVOLT)
839 devctl_notify("PMU", "AC", "overvoltage", NULL);
840 if (reg & AXP2XX_IRQ1_VBUS_OVERVOLT)
841 devctl_notify("PMU", "USB", "overvoltage", NULL);
842 if (reg & AXP2XX_IRQ1_VBUS_LOW)
843 devctl_notify("PMU", "USB", "undervoltage", NULL);
844 if (reg & AXP2XX_IRQ1_AC_CONN)
845 devctl_notify("PMU", "AC", "plugged", NULL);
846 if (reg & AXP2XX_IRQ1_AC_DISCONN)
847 devctl_notify("PMU", "AC", "unplugged", NULL);
848 if (reg & AXP2XX_IRQ1_VBUS_CONN)
849 devctl_notify("PMU", "USB", "plugged", NULL);
850 if (reg & AXP2XX_IRQ1_VBUS_DISCONN)
851 devctl_notify("PMU", "USB", "unplugged", NULL);
852 axp2xx_write(sc->dev, AXP2XX_IRQ1_STATUS, AXP2XX_IRQ_ACK);
855 axp2xx_read(sc->dev, AXP2XX_IRQ2_STATUS, ®, 1);
857 if (reg & AXP2XX_IRQ2_BATT_CHARGED)
858 devctl_notify("PMU", "Battery", "charged", NULL);
859 if (reg & AXP2XX_IRQ2_BATT_CHARGING)
860 devctl_notify("PMU", "Battery", "charging", NULL);
861 if (reg & AXP2XX_IRQ2_BATT_CONN)
862 devctl_notify("PMU", "Battery", "connected", NULL);
863 if (reg & AXP2XX_IRQ2_BATT_DISCONN)
864 devctl_notify("PMU", "Battery", "disconnected", NULL);
865 if (reg & AXP2XX_IRQ2_BATT_TEMP_LOW)
866 devctl_notify("PMU", "Battery", "low temp", NULL);
867 if (reg & AXP2XX_IRQ2_BATT_TEMP_OVER)
868 devctl_notify("PMU", "Battery", "high temp", NULL);
869 axp2xx_write(sc->dev, AXP2XX_IRQ2_STATUS, AXP2XX_IRQ_ACK);
872 axp2xx_read(sc->dev, AXP2XX_IRQ3_STATUS, ®, 1);
874 if (reg & AXP2XX_IRQ3_PEK_SHORT)
875 shutdown_nice(RB_POWEROFF);
876 axp2xx_write(sc->dev, AXP2XX_IRQ3_STATUS, AXP2XX_IRQ_ACK);
879 axp2xx_read(sc->dev, AXP2XX_IRQ4_STATUS, ®, 1);
881 axp2xx_write(sc->dev, AXP2XX_IRQ4_STATUS, AXP2XX_IRQ_ACK);
884 axp2xx_read(sc->dev, AXP2XX_IRQ5_STATUS, ®, 1);
886 axp2xx_write(sc->dev, AXP2XX_IRQ5_STATUS, AXP2XX_IRQ_ACK);
891 axp2xx_gpio_get_bus(device_t dev)
893 struct axp2xx_softc *sc;
895 sc = device_get_softc(dev);
897 return (sc->gpiodev);
901 axp2xx_gpio_pin_max(device_t dev, int *maxpin)
903 struct axp2xx_softc *sc;
905 sc = device_get_softc(dev);
907 *maxpin = sc->npins - 1;
913 axp2xx_gpio_pin_getname(device_t dev, uint32_t pin, char *name)
915 struct axp2xx_softc *sc;
917 sc = device_get_softc(dev);
919 if (pin >= sc->npins)
922 snprintf(name, GPIOMAXNAME, "%s", axp209_pins[pin].name);
928 axp2xx_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
930 struct axp2xx_softc *sc;
932 sc = device_get_softc(dev);
934 if (pin >= sc->npins)
937 *caps = GPIO_PIN_INPUT | GPIO_PIN_OUTPUT;
943 axp2xx_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags)
945 struct axp2xx_softc *sc;
949 sc = device_get_softc(dev);
951 if (pin >= sc->npins)
955 error = axp2xx_read(dev, sc->pins[pin].ctrl_reg, &data, 1);
957 func = data & AXP2XX_GPIO_FUNC_MASK;
958 if (func == AXP2XX_GPIO_FUNC_INPUT)
959 *flags = GPIO_PIN_INPUT;
960 else if (func == AXP2XX_GPIO_FUNC_DRVLO ||
961 func == AXP2XX_GPIO_FUNC_DRVHI)
962 *flags = GPIO_PIN_OUTPUT;
972 axp2xx_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags)
974 struct axp2xx_softc *sc;
978 sc = device_get_softc(dev);
980 if (pin >= sc->npins)
984 error = axp2xx_read(dev, sc->pins[pin].ctrl_reg, &data, 1);
986 data &= ~AXP2XX_GPIO_FUNC_MASK;
987 if ((flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) != 0) {
988 if ((flags & GPIO_PIN_OUTPUT) == 0)
989 data |= AXP2XX_GPIO_FUNC_INPUT;
991 error = axp2xx_write(dev, sc->pins[pin].ctrl_reg, data);
999 axp2xx_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val)
1001 struct axp2xx_softc *sc;
1005 sc = device_get_softc(dev);
1007 if (pin >= sc->npins)
1011 error = axp2xx_read(dev, sc->pins[pin].ctrl_reg, &data, 1);
1013 func = data & AXP2XX_GPIO_FUNC_MASK;
1015 case AXP2XX_GPIO_FUNC_DRVLO:
1018 case AXP2XX_GPIO_FUNC_DRVHI:
1021 case AXP2XX_GPIO_FUNC_INPUT:
1022 error = axp2xx_read(dev, sc->pins[pin].status_reg,
1025 *val = (data & sc->pins[pin].status_mask);
1026 *val >>= sc->pins[pin].status_shift;
1040 axp2xx_gpio_pin_set(device_t dev, uint32_t pin, unsigned int val)
1042 struct axp2xx_softc *sc;
1046 sc = device_get_softc(dev);
1048 if (pin >= sc->npins)
1052 error = axp2xx_read(dev, sc->pins[pin].ctrl_reg, &data, 1);
1054 func = data & AXP2XX_GPIO_FUNC_MASK;
1056 case AXP2XX_GPIO_FUNC_DRVLO:
1057 case AXP2XX_GPIO_FUNC_DRVHI:
1058 /* GPIO2 can't be set to 1 */
1059 if (pin == 2 && val == 1) {
1063 data &= ~AXP2XX_GPIO_FUNC_MASK;
1072 error = axp2xx_write(dev, sc->pins[pin].ctrl_reg, data);
1080 axp2xx_gpio_pin_toggle(device_t dev, uint32_t pin)
1082 struct axp2xx_softc *sc;
1086 sc = device_get_softc(dev);
1088 if (pin >= sc->npins)
1092 error = axp2xx_read(dev, sc->pins[pin].ctrl_reg, &data, 1);
1094 func = data & AXP2XX_GPIO_FUNC_MASK;
1096 case AXP2XX_GPIO_FUNC_DRVLO:
1097 /* Pin 2 can't be set to 1*/
1102 data &= ~AXP2XX_GPIO_FUNC_MASK;
1103 data |= AXP2XX_GPIO_FUNC_DRVHI;
1105 case AXP2XX_GPIO_FUNC_DRVHI:
1106 data &= ~AXP2XX_GPIO_FUNC_MASK;
1107 data |= AXP2XX_GPIO_FUNC_DRVLO;
1115 error = axp2xx_write(dev, sc->pins[pin].ctrl_reg, data);
1122 axp2xx_gpio_map_gpios(device_t bus, phandle_t dev, phandle_t gparent,
1123 int gcells, pcell_t *gpios, uint32_t *pin, uint32_t *flags)
1125 struct axp2xx_softc *sc;
1127 sc = device_get_softc(bus);
1129 if (gpios[0] >= sc->npins)
1139 axp2xx_get_node(device_t dev, device_t bus)
1141 return (ofw_bus_get_node(dev));
1144 static struct axp2xx_reg_sc *
1145 axp2xx_reg_attach(device_t dev, phandle_t node,
1146 struct axp2xx_regdef *def)
1148 struct axp2xx_reg_sc *reg_sc;
1149 struct regnode_init_def initdef;
1150 struct regnode *regnode;
1152 memset(&initdef, 0, sizeof(initdef));
1153 if (regulator_parse_ofw_stdparam(dev, node, &initdef) != 0) {
1154 device_printf(dev, "cannot create regulator\n");
1157 if (initdef.std_param.min_uvolt == 0)
1158 initdef.std_param.min_uvolt = def->voltage_min * 1000;
1159 if (initdef.std_param.max_uvolt == 0)
1160 initdef.std_param.max_uvolt = def->voltage_max * 1000;
1161 initdef.id = def->id;
1162 initdef.ofw_node = node;
1163 regnode = regnode_create(dev, &axp2xx_regnode_class, &initdef);
1164 if (regnode == NULL) {
1165 device_printf(dev, "cannot create regulator\n");
1169 reg_sc = regnode_get_softc(regnode);
1170 reg_sc->regnode = regnode;
1171 reg_sc->base_dev = dev;
1173 reg_sc->xref = OF_xref_from_node(node);
1174 reg_sc->param = regnode_get_stdparam(regnode);
1176 regnode_register(regnode);
1182 axp2xx_regdev_map(device_t dev, phandle_t xref, int ncells, pcell_t *cells,
1185 struct axp2xx_softc *sc;
1188 sc = device_get_softc(dev);
1189 for (i = 0; i < sc->nregs; i++) {
1190 if (sc->regs[i] == NULL)
1192 if (sc->regs[i]->xref == xref) {
1193 *num = sc->regs[i]->def->id;
1202 axp2xx_start(void *pdev)
1205 struct axp2xx_softc *sc;
1206 const char *pwr_name[] = {"Battery", "AC", "USB", "AC and USB"};
1213 sc = device_get_softc(dev);
1218 * Read the Power State register.
1219 * Shift the AC presence into bit 0.
1220 * Shift the Battery presence into bit 1.
1222 axp2xx_read(dev, AXP2XX_PSR, &data, 1);
1223 pwr_src = ((data & AXP2XX_PSR_ACIN) >> AXP2XX_PSR_ACIN_SHIFT) |
1224 ((data & AXP2XX_PSR_VBUS) >> (AXP2XX_PSR_VBUS_SHIFT - 1));
1226 device_printf(dev, "Powered by %s\n",
1230 /* Only enable interrupts that we are interested in */
1231 axp2xx_write(dev, AXP2XX_IRQ1_ENABLE,
1232 AXP2XX_IRQ1_AC_OVERVOLT |
1233 AXP2XX_IRQ1_AC_DISCONN |
1234 AXP2XX_IRQ1_AC_CONN |
1235 AXP2XX_IRQ1_VBUS_OVERVOLT |
1236 AXP2XX_IRQ1_VBUS_DISCONN |
1237 AXP2XX_IRQ1_VBUS_CONN);
1238 axp2xx_write(dev, AXP2XX_IRQ2_ENABLE,
1239 AXP2XX_IRQ2_BATT_CONN |
1240 AXP2XX_IRQ2_BATT_DISCONN |
1241 AXP2XX_IRQ2_BATT_CHARGE_ACCT_ON |
1242 AXP2XX_IRQ2_BATT_CHARGE_ACCT_OFF |
1243 AXP2XX_IRQ2_BATT_CHARGING |
1244 AXP2XX_IRQ2_BATT_CHARGED |
1245 AXP2XX_IRQ2_BATT_TEMP_OVER |
1246 AXP2XX_IRQ2_BATT_TEMP_LOW);
1247 axp2xx_write(dev, AXP2XX_IRQ3_ENABLE,
1248 AXP2XX_IRQ3_PEK_SHORT | AXP2XX_IRQ3_PEK_LONG);
1249 axp2xx_write(dev, AXP2XX_IRQ4_ENABLE, AXP2XX_IRQ4_APS_LOW_2);
1250 axp2xx_write(dev, AXP2XX_IRQ5_ENABLE, 0x0);
1252 EVENTHANDLER_REGISTER(shutdown_final, axp2xx_shutdown, dev,
1255 /* Enable ADC sensors */
1256 for (i = 0; i < sc->nsensors; i++) {
1257 if (axp2xx_read(dev, sc->sensors[i].enable_reg, ®, 1) == -1) {
1258 device_printf(dev, "Cannot enable sensor '%s'\n",
1259 sc->sensors[i].name);
1262 reg |= sc->sensors[i].enable_mask;
1263 if (axp2xx_write(dev, sc->sensors[i].enable_reg, reg) == -1) {
1264 device_printf(dev, "Cannot enable sensor '%s'\n",
1265 sc->sensors[i].name);
1268 SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
1269 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
1270 OID_AUTO, sc->sensors[i].name,
1271 CTLTYPE_INT | CTLFLAG_RD,
1272 dev, sc->sensors[i].id, axp2xx_sysctl,
1273 sc->sensors[i].format,
1274 sc->sensors[i].desc);
1277 if ((bus_setup_intr(dev, sc->res[0], INTR_TYPE_MISC | INTR_MPSAFE,
1278 NULL, axp2xx_intr, sc, &sc->intrcookie)))
1279 device_printf(dev, "unable to register interrupt handler\n");
1281 config_intrhook_disestablish(&sc->intr_hook);
1285 axp2xx_probe(device_t dev)
1288 if (!ofw_bus_status_okay(dev))
1291 switch (ofw_bus_search_compatible(dev, compat_data)->ocd_data)
1294 device_set_desc(dev, "X-Powers AXP209 Power Management Unit");
1297 device_set_desc(dev, "X-Powers AXP221 Power Management Unit");
1303 return (BUS_PROBE_DEFAULT);
1307 axp2xx_attach(device_t dev)
1309 struct axp2xx_softc *sc;
1310 struct axp2xx_reg_sc *reg;
1311 struct axp2xx_regdef *regdefs;
1312 phandle_t rnode, child;
1315 sc = device_get_softc(dev);
1316 mtx_init(&sc->mtx, device_get_nameunit(dev), NULL, MTX_DEF);
1318 if (bus_alloc_resources(dev, axp_res_spec, sc->res) != 0) {
1319 device_printf(dev, "can't allocate device resources\n");
1323 sc->type = ofw_bus_search_compatible(dev, compat_data)->ocd_data;
1326 sc->pins = axp209_pins;
1327 sc->npins = nitems(axp209_pins);
1328 sc->gpiodev = gpiobus_attach_bus(dev);
1330 sc->sensors = axp209_sensors;
1331 sc->nsensors = nitems(axp209_sensors);
1333 regdefs = axp209_regdefs;
1334 sc->nregs = nitems(axp209_regdefs);
1337 sc->pins = axp221_pins;
1338 sc->npins = nitems(axp221_pins);
1339 sc->gpiodev = gpiobus_attach_bus(dev);
1341 sc->sensors = axp221_sensors;
1342 sc->nsensors = nitems(axp221_sensors);
1344 regdefs = axp221_regdefs;
1345 sc->nregs = nitems(axp221_regdefs);
1349 sc->regs = malloc(sizeof(struct axp2xx_reg_sc *) * sc->nregs,
1350 M_AXP2XX_REG, M_WAITOK | M_ZERO);
1352 sc->intr_hook.ich_func = axp2xx_start;
1353 sc->intr_hook.ich_arg = dev;
1355 if (config_intrhook_establish(&sc->intr_hook) != 0)
1358 /* Attach known regulators that exist in the DT */
1359 rnode = ofw_bus_find_child(ofw_bus_get_node(dev), "regulators");
1361 for (i = 0; i < sc->nregs; i++) {
1362 child = ofw_bus_find_child(rnode,
1366 reg = axp2xx_reg_attach(dev, child, ®defs[i]);
1369 "cannot attach regulator %s\n",
1375 device_printf(dev, "Regulator %s attached\n",
1383 static device_method_t axp2xx_methods[] = {
1384 DEVMETHOD(device_probe, axp2xx_probe),
1385 DEVMETHOD(device_attach, axp2xx_attach),
1387 /* GPIO interface */
1388 DEVMETHOD(gpio_get_bus, axp2xx_gpio_get_bus),
1389 DEVMETHOD(gpio_pin_max, axp2xx_gpio_pin_max),
1390 DEVMETHOD(gpio_pin_getname, axp2xx_gpio_pin_getname),
1391 DEVMETHOD(gpio_pin_getcaps, axp2xx_gpio_pin_getcaps),
1392 DEVMETHOD(gpio_pin_getflags, axp2xx_gpio_pin_getflags),
1393 DEVMETHOD(gpio_pin_setflags, axp2xx_gpio_pin_setflags),
1394 DEVMETHOD(gpio_pin_get, axp2xx_gpio_pin_get),
1395 DEVMETHOD(gpio_pin_set, axp2xx_gpio_pin_set),
1396 DEVMETHOD(gpio_pin_toggle, axp2xx_gpio_pin_toggle),
1397 DEVMETHOD(gpio_map_gpios, axp2xx_gpio_map_gpios),
1399 /* Regdev interface */
1400 DEVMETHOD(regdev_map, axp2xx_regdev_map),
1402 /* OFW bus interface */
1403 DEVMETHOD(ofw_bus_get_node, axp2xx_get_node),
1408 static driver_t axp2xx_driver = {
1411 sizeof(struct axp2xx_softc),
1414 static devclass_t axp2xx_devclass;
1415 extern devclass_t ofwgpiobus_devclass, gpioc_devclass;
1416 extern driver_t ofw_gpiobus_driver, gpioc_driver;
1418 EARLY_DRIVER_MODULE(axp2xx, iicbus, axp2xx_driver, axp2xx_devclass,
1419 0, 0, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_LATE);
1420 EARLY_DRIVER_MODULE(ofw_gpiobus, axp2xx_pmu, ofw_gpiobus_driver,
1421 ofwgpiobus_devclass, 0, 0, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_LATE);
1422 DRIVER_MODULE(gpioc, axp2xx_pmu, gpioc_driver, gpioc_devclass,
1424 MODULE_VERSION(axp2xx, 1);
1425 MODULE_DEPEND(axp2xx, iicbus, IICBUS_MINVER, IICBUS_PREFVER, IICBUS_MAXVER);