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$");
32 * X-Power AXP209/AXP211 PMU for Allwinner SoCs
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/eventhandler.h>
38 #include <sys/kernel.h>
39 #include <sys/module.h>
40 #include <sys/clock.h>
45 #include <sys/reboot.h>
46 #include <sys/resource.h>
48 #include <sys/sysctl.h>
50 #include <dev/iicbus/iiconf.h>
52 #include <dev/gpio/gpiobusvar.h>
54 #include <dev/ofw/ofw_bus.h>
55 #include <dev/ofw/ofw_bus_subr.h>
57 #include <dev/extres/regulator/regulator.h>
59 #include <arm/allwinner/axp209reg.h>
62 #include "regdev_if.h"
64 MALLOC_DEFINE(M_AXP2XX_REG, "Axp2XX regulator", "Axp2XX power regulator");
66 struct axp2xx_regdef {
73 uint8_t voltage_shift;
80 static struct axp2xx_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 static struct axp2xx_regdef axp221_regdefs[] = {
134 .id = AXP221_REG_ID_DLDO1,
136 .enable_reg = AXP221_POWERCTL_2,
137 .enable_mask = AXP221_POWERCTL2_DLDO1,
138 .voltage_reg = AXP221_REG_DLDO1_VOLTAGE,
139 .voltage_mask = 0x1f,
146 .id = AXP221_REG_ID_DLDO2,
148 .enable_reg = AXP221_POWERCTL_2,
149 .enable_mask = AXP221_POWERCTL2_DLDO2,
150 .voltage_reg = AXP221_REG_DLDO2_VOLTAGE,
151 .voltage_mask = 0x1f,
158 .id = AXP221_REG_ID_DLDO3,
160 .enable_reg = AXP221_POWERCTL_2,
161 .enable_mask = AXP221_POWERCTL2_DLDO3,
162 .voltage_reg = AXP221_REG_DLDO3_VOLTAGE,
163 .voltage_mask = 0x1f,
170 .id = AXP221_REG_ID_DLDO4,
172 .enable_reg = AXP221_POWERCTL_2,
173 .enable_mask = AXP221_POWERCTL2_DLDO4,
174 .voltage_reg = AXP221_REG_DLDO4_VOLTAGE,
175 .voltage_mask = 0x1f,
182 .id = AXP221_REG_ID_ELDO1,
184 .enable_reg = AXP221_POWERCTL_2,
185 .enable_mask = AXP221_POWERCTL2_ELDO1,
186 .voltage_reg = AXP221_REG_ELDO1_VOLTAGE,
187 .voltage_mask = 0x1f,
194 .id = AXP221_REG_ID_ELDO2,
196 .enable_reg = AXP221_POWERCTL_2,
197 .enable_mask = AXP221_POWERCTL2_ELDO2,
198 .voltage_reg = AXP221_REG_ELDO2_VOLTAGE,
199 .voltage_mask = 0x1f,
206 .id = AXP221_REG_ID_ELDO3,
208 .enable_reg = AXP221_POWERCTL_2,
209 .enable_mask = AXP221_POWERCTL2_ELDO3,
210 .voltage_reg = AXP221_REG_ELDO3_VOLTAGE,
211 .voltage_mask = 0x1f,
218 .id = AXP221_REG_ID_DC5LDO,
220 .enable_reg = AXP221_POWERCTL_1,
221 .enable_mask = AXP221_POWERCTL1_DC5LDO,
222 .voltage_reg = AXP221_REG_DC5LDO_VOLTAGE,
230 .id = AXP221_REG_ID_DCDC1,
232 .enable_reg = AXP221_POWERCTL_1,
233 .enable_mask = AXP221_POWERCTL1_DCDC1,
234 .voltage_reg = AXP221_REG_DCDC1_VOLTAGE,
235 .voltage_mask = 0x1f,
242 .id = AXP221_REG_ID_DCDC2,
244 .enable_reg = AXP221_POWERCTL_1,
245 .enable_mask = AXP221_POWERCTL1_DCDC2,
246 .voltage_reg = AXP221_REG_DCDC2_VOLTAGE,
247 .voltage_mask = 0x3f,
254 .id = AXP221_REG_ID_DCDC3,
256 .enable_reg = AXP221_POWERCTL_1,
257 .enable_mask = AXP221_POWERCTL1_DCDC3,
258 .voltage_reg = AXP221_REG_DCDC3_VOLTAGE,
259 .voltage_mask = 0x3f,
266 .id = AXP221_REG_ID_DCDC4,
268 .enable_reg = AXP221_POWERCTL_1,
269 .enable_mask = AXP221_POWERCTL1_DCDC4,
270 .voltage_reg = AXP221_REG_DCDC4_VOLTAGE,
271 .voltage_mask = 0x3f,
278 .id = AXP221_REG_ID_DCDC5,
280 .enable_reg = AXP221_POWERCTL_1,
281 .enable_mask = AXP221_POWERCTL1_DCDC5,
282 .voltage_reg = AXP221_REG_DCDC5_VOLTAGE,
283 .voltage_mask = 0x1f,
290 .id = AXP221_REG_ID_ALDO1,
292 .enable_reg = AXP221_POWERCTL_1,
293 .enable_mask = AXP221_POWERCTL1_ALDO1,
294 .voltage_reg = AXP221_REG_ALDO1_VOLTAGE,
295 .voltage_mask = 0x1f,
302 .id = AXP221_REG_ID_ALDO2,
304 .enable_reg = AXP221_POWERCTL_1,
305 .enable_mask = AXP221_POWERCTL1_ALDO2,
306 .voltage_reg = AXP221_REG_ALDO2_VOLTAGE,
307 .voltage_mask = 0x1f,
314 .id = AXP221_REG_ID_ALDO3,
316 .enable_reg = AXP221_POWERCTL_3,
317 .enable_mask = AXP221_POWERCTL3_ALDO3,
318 .voltage_reg = AXP221_REG_ALDO3_VOLTAGE,
319 .voltage_mask = 0x1f,
326 .id = AXP221_REG_ID_DC1SW,
328 .enable_reg = AXP221_POWERCTL_2,
329 .enable_mask = AXP221_POWERCTL2_DC1SW,
333 struct axp2xx_reg_sc {
334 struct regnode *regnode;
336 struct axp2xx_regdef *def;
338 struct regnode_std_param *param;
346 uint8_t status_shift;
349 /* GPIO3 is different, don't expose it for now */
350 static const struct axp2xx_pins axp209_pins[] = {
353 .ctrl_reg = AXP2XX_GPIO0_CTRL,
354 .status_reg = AXP2XX_GPIO_STATUS,
360 .ctrl_reg = AXP2XX_GPIO1_CTRL,
361 .status_reg = AXP2XX_GPIO_STATUS,
367 .ctrl_reg = AXP209_GPIO2_CTRL,
368 .status_reg = AXP2XX_GPIO_STATUS,
374 static const struct axp2xx_pins axp221_pins[] = {
377 .ctrl_reg = AXP2XX_GPIO0_CTRL,
378 .status_reg = AXP2XX_GPIO_STATUS,
384 .ctrl_reg = AXP2XX_GPIO0_CTRL,
385 .status_reg = AXP2XX_GPIO_STATUS,
391 struct axp2xx_sensors {
400 uint8_t h_value_mask;
401 uint8_t h_value_shift;
402 uint8_t l_value_mask;
403 uint8_t l_value_shift;
408 static const struct axp2xx_sensors axp209_sensors[] = {
412 .desc = "AC Voltage (microvolt)",
414 .enable_reg = AXP2XX_ADC_ENABLE1,
415 .enable_mask = AXP209_ADC1_ACVOLT,
416 .value_reg = AXP209_ACIN_VOLTAGE,
418 .h_value_mask = 0xff,
422 .value_step = AXP209_VOLT_STEP,
425 .id = AXP209_ACCURRENT,
427 .desc = "AC Current (microAmpere)",
429 .enable_reg = AXP2XX_ADC_ENABLE1,
430 .enable_mask = AXP209_ADC1_ACCURRENT,
431 .value_reg = AXP209_ACIN_CURRENT,
433 .h_value_mask = 0xff,
437 .value_step = AXP209_ACCURRENT_STEP,
440 .id = AXP209_VBUSVOLT,
442 .desc = "VBUS Voltage (microVolt)",
444 .enable_reg = AXP2XX_ADC_ENABLE1,
445 .enable_mask = AXP209_ADC1_VBUSVOLT,
446 .value_reg = AXP209_VBUS_VOLTAGE,
448 .h_value_mask = 0xff,
452 .value_step = AXP209_VOLT_STEP,
455 .id = AXP209_VBUSCURRENT,
456 .name = "vbuscurrent",
457 .desc = "VBUS Current (microAmpere)",
459 .enable_reg = AXP2XX_ADC_ENABLE1,
460 .enable_mask = AXP209_ADC1_VBUSCURRENT,
461 .value_reg = AXP209_VBUS_CURRENT,
463 .h_value_mask = 0xff,
467 .value_step = AXP209_VBUSCURRENT_STEP,
470 .id = AXP2XX_BATVOLT,
472 .desc = "Battery Voltage (microVolt)",
474 .enable_reg = AXP2XX_ADC_ENABLE1,
475 .enable_mask = AXP2XX_ADC1_BATVOLT,
476 .value_reg = AXP2XX_BAT_VOLTAGE,
478 .h_value_mask = 0xff,
482 .value_step = AXP2XX_BATVOLT_STEP,
485 .id = AXP2XX_BATCHARGECURRENT,
486 .name = "batchargecurrent",
487 .desc = "Battery Charging Current (microAmpere)",
489 .enable_reg = AXP2XX_ADC_ENABLE1,
490 .enable_mask = AXP2XX_ADC1_BATCURRENT,
491 .value_reg = AXP2XX_BAT_CHARGE_CURRENT,
493 .h_value_mask = 0xff,
495 .l_value_mask = 0x1f,
497 .value_step = AXP2XX_BATCURRENT_STEP,
500 .id = AXP2XX_BATDISCHARGECURRENT,
501 .name = "batdischargecurrent",
502 .desc = "Battery Discharging Current (microAmpere)",
504 .enable_reg = AXP2XX_ADC_ENABLE1,
505 .enable_mask = AXP2XX_ADC1_BATCURRENT,
506 .value_reg = AXP2XX_BAT_DISCHARGE_CURRENT,
508 .h_value_mask = 0xff,
510 .l_value_mask = 0x1f,
512 .value_step = AXP2XX_BATCURRENT_STEP,
517 .desc = "Internal Temperature",
519 .enable_reg = AXP209_ADC_ENABLE2,
520 .enable_mask = AXP209_ADC2_TEMP,
521 .value_reg = AXP209_TEMPMON,
523 .h_value_mask = 0xff,
528 .value_convert = -(AXP209_TEMPMON_MIN - AXP209_0C_TO_K),
532 static const struct axp2xx_sensors axp221_sensors[] = {
534 .id = AXP2XX_BATVOLT,
536 .desc = "Battery Voltage (microVolt)",
538 .enable_reg = AXP2XX_ADC_ENABLE1,
539 .enable_mask = AXP2XX_ADC1_BATVOLT,
540 .value_reg = AXP2XX_BAT_VOLTAGE,
542 .h_value_mask = 0xff,
546 .value_step = AXP2XX_BATVOLT_STEP,
549 .id = AXP2XX_BATCHARGECURRENT,
550 .name = "batchargecurrent",
551 .desc = "Battery Charging Current (microAmpere)",
553 .enable_reg = AXP2XX_ADC_ENABLE1,
554 .enable_mask = AXP2XX_ADC1_BATCURRENT,
555 .value_reg = AXP2XX_BAT_CHARGE_CURRENT,
557 .h_value_mask = 0xff,
559 .l_value_mask = 0x1f,
561 .value_step = AXP2XX_BATCURRENT_STEP,
564 .id = AXP2XX_BATDISCHARGECURRENT,
565 .name = "batdischargecurrent",
566 .desc = "Battery Discharging Current (microAmpere)",
568 .enable_reg = AXP2XX_ADC_ENABLE1,
569 .enable_mask = AXP2XX_ADC1_BATCURRENT,
570 .value_reg = AXP2XX_BAT_DISCHARGE_CURRENT,
572 .h_value_mask = 0xff,
574 .l_value_mask = 0x1f,
576 .value_step = AXP2XX_BATCURRENT_STEP,
581 .desc = "Internal Temperature",
583 .enable_reg = AXP2XX_ADC_ENABLE1,
584 .enable_mask = AXP221_ADC1_TEMP,
585 .value_reg = AXP221_TEMPMON,
587 .h_value_mask = 0xff,
592 .value_convert = -(AXP221_TEMPMON_MIN - AXP209_0C_TO_K),
601 struct axp2xx_softc {
603 struct resource * res[1];
605 struct intr_config_hook intr_hook;
612 const struct axp2xx_pins *pins;
615 const struct axp2xx_sensors *sensors;
619 struct axp2xx_reg_sc **regs;
621 struct axp2xx_regdef *regdefs;
624 static struct ofw_compat_data compat_data[] = {
625 { "x-powers,axp209", AXP209 },
626 { "x-powers,axp221", AXP221 },
630 static struct resource_spec axp_res_spec[] = {
631 { SYS_RES_IRQ, 0, RF_ACTIVE },
635 #define AXP_LOCK(sc) mtx_lock(&(sc)->mtx)
636 #define AXP_UNLOCK(sc) mtx_unlock(&(sc)->mtx)
639 axp2xx_read(device_t dev, uint8_t reg, uint8_t *data, uint8_t size)
642 return (iicdev_readfrom(dev, reg, data, size, IIC_INTRWAIT));
646 axp2xx_write(device_t dev, uint8_t reg, uint8_t data)
649 return (iicdev_writeto(dev, reg, &data, sizeof(data), IIC_INTRWAIT));
653 axp2xx_regnode_init(struct regnode *regnode)
659 axp2xx_regnode_enable(struct regnode *regnode, bool enable, int *udelay)
661 struct axp2xx_reg_sc *sc;
664 sc = regnode_get_softc(regnode);
666 axp2xx_read(sc->base_dev, sc->def->enable_reg, &val, 1);
668 val |= sc->def->enable_mask;
670 val &= ~sc->def->enable_mask;
671 axp2xx_write(sc->base_dev, sc->def->enable_reg, val);
679 axp2xx_regnode_reg_to_voltage(struct axp2xx_reg_sc *sc, uint8_t val, int *uv)
681 if (val < sc->def->voltage_nstep)
682 *uv = sc->def->voltage_min + val * sc->def->voltage_step;
684 *uv = sc->def->voltage_min +
685 (sc->def->voltage_nstep * sc->def->voltage_step);
690 axp2xx_regnode_voltage_to_reg(struct axp2xx_reg_sc *sc, int min_uvolt,
691 int max_uvolt, uint8_t *val)
697 uvolt = sc->def->voltage_min * 1000;
699 for (nstep = 0; nstep < sc->def->voltage_nstep && uvolt < min_uvolt;
702 uvolt += (sc->def->voltage_step * 1000);
704 if (uvolt > max_uvolt)
712 axp2xx_regnode_set_voltage(struct regnode *regnode, int min_uvolt,
713 int max_uvolt, int *udelay)
715 struct axp2xx_reg_sc *sc;
718 sc = regnode_get_softc(regnode);
720 if (!sc->def->voltage_step)
723 if (axp2xx_regnode_voltage_to_reg(sc, min_uvolt, max_uvolt, &val) != 0)
726 axp2xx_write(sc->base_dev, sc->def->voltage_reg, val);
734 axp2xx_regnode_get_voltage(struct regnode *regnode, int *uvolt)
736 struct axp2xx_reg_sc *sc;
739 sc = regnode_get_softc(regnode);
741 if (!sc->def->voltage_step)
744 axp2xx_read(sc->base_dev, sc->def->voltage_reg, &val, 1);
745 axp2xx_regnode_reg_to_voltage(sc, val & sc->def->voltage_mask, uvolt);
750 static regnode_method_t axp2xx_regnode_methods[] = {
751 /* Regulator interface */
752 REGNODEMETHOD(regnode_init, axp2xx_regnode_init),
753 REGNODEMETHOD(regnode_enable, axp2xx_regnode_enable),
754 REGNODEMETHOD(regnode_set_voltage, axp2xx_regnode_set_voltage),
755 REGNODEMETHOD(regnode_get_voltage, axp2xx_regnode_get_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);