Home | History | Annotate | Line # | Download | only in i2c
axppmic.c revision 1.2
      1 /* $NetBSD: axppmic.c,v 1.2 2018/05/05 00:39:59 jmcneill Exp $ */
      2 
      3 /*-
      4  * Copyright (c) 2014-2018 Jared McNeill <jmcneill (at) invisible.ca>
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     17  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     18  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     19  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     20  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     26  * POSSIBILITY OF SUCH DAMAGE.
     27  */
     28 
     29 #include <sys/cdefs.h>
     30 __KERNEL_RCSID(0, "$NetBSD: axppmic.c,v 1.2 2018/05/05 00:39:59 jmcneill Exp $");
     31 
     32 #include <sys/param.h>
     33 #include <sys/systm.h>
     34 #include <sys/kernel.h>
     35 #include <sys/device.h>
     36 #include <sys/conf.h>
     37 #include <sys/bus.h>
     38 #include <sys/kmem.h>
     39 
     40 #include <dev/i2c/i2cvar.h>
     41 
     42 #include <dev/sysmon/sysmonvar.h>
     43 #include <dev/sysmon/sysmon_taskq.h>
     44 
     45 #include <dev/fdt/fdtvar.h>
     46 
     47 #define	AXP_POWER_MODE_REG	0x01
     48 #define	 AXP_POWER_MODE_BATT_VALID	__BIT(4)
     49 #define	 AXP_POWER_MODE_BATT_PRESENT	__BIT(5)
     50 #define	 AXP_POWER_MODE_BATT_CHARGING	__BIT(6)
     51 
     52 #define AXP_POWER_DISABLE_REG	0x32
     53 #define	 AXP_POWER_DISABLE_CTRL	__BIT(7)
     54 
     55 #define AXP_IRQ_ENABLE_REG(n)	(0x40 + (n) - 1)
     56 #define	 AXP_IRQ2_POKSIRQ	__BIT(1)
     57 #define AXP_IRQ_STATUS_REG(n)	(0x48 + (n) - 1)
     58 
     59 #define	AXP_FUEL_GAUGE_CTRL_REG	0xb8
     60 #define	 AXP_FUEL_GAUGE_CTRL_EN	__BIT(7)
     61 #define	AXP_BATT_CAP_REG	0xb9
     62 #define	 AXP_BATT_CAP_VALID	__BIT(7)
     63 #define	 AXP_BATT_CAP_PERCENT	__BITS(6,0)
     64 
     65 #define	AXP_BATT_CAP_WARN_REG	0xe6
     66 #define	 AXP_BATT_CAP_WARN_LV1	__BITS(7,4)
     67 #define	 AXP_BATT_CAP_WARN_LV2	__BITS(3,0)
     68 
     69 struct axppmic_ctrl {
     70 	device_t	c_dev;
     71 
     72 	const char *	c_name;
     73 	u_int		c_min;
     74 	u_int		c_max;
     75 	u_int		c_step1;
     76 	u_int		c_step1cnt;
     77 	u_int		c_step2;
     78 	u_int		c_step2cnt;
     79 
     80 	uint8_t		c_enable_reg;
     81 	uint8_t		c_enable_mask;
     82 
     83 	uint8_t		c_voltage_reg;
     84 	uint8_t		c_voltage_mask;
     85 };
     86 
     87 #define AXP_CTRL(name, min, max, step, ereg, emask, vreg, vmask)	\
     88 	{ .c_name = (name), .c_min = (min), .c_max = (max),		\
     89 	  .c_step1 = (step), .c_step1cnt = (((max) - (min)) / (step)) + 1, \
     90 	  .c_step2 = 0, .c_step2cnt = 0,				\
     91 	  .c_enable_reg = (ereg), .c_enable_mask = (emask),		\
     92 	  .c_voltage_reg = (vreg), .c_voltage_mask = (vmask) }
     93 
     94 #define AXP_CTRL2(name, min, max, step1, step1cnt, step2, step2cnt, ereg, emask, vreg, vmask) \
     95 	{ .c_name = (name), .c_min = (min), .c_max = (max),		\
     96 	  .c_step1 = (step1), .c_step1cnt = (step1cnt),			\
     97 	  .c_step2 = (step2), .c_step2cnt = (step2cnt),			\
     98 	  .c_enable_reg = (ereg), .c_enable_mask = (emask),		\
     99 	  .c_voltage_reg = (vreg), .c_voltage_mask = (vmask) }
    100 
    101 static const struct axppmic_ctrl axp803_ctrls[] = {
    102 	AXP_CTRL("dldo1", 700, 3300, 100,
    103 		0x12, __BIT(3), 0x15, __BITS(4,0)),
    104 	AXP_CTRL2("dldo2", 700, 4200, 100, 28, 200, 4,
    105 		0x12, __BIT(4), 0x16, __BITS(4,0)),
    106 	AXP_CTRL("dldo3", 700, 3300, 100,
    107 	 	0x12, __BIT(5), 0x17, __BITS(4,0)),
    108 	AXP_CTRL("dldo4", 700, 3300, 100,
    109 		0x12, __BIT(6), 0x18, __BITS(4,0)),
    110 	AXP_CTRL("eldo1", 700, 1900, 50,
    111 		0x12, __BIT(0), 0x19, __BITS(4,0)),
    112 	AXP_CTRL("eldo2", 700, 1900, 50,
    113 		0x12, __BIT(1), 0x1a, __BITS(4,0)),
    114 	AXP_CTRL("eldo3", 700, 1900, 50,
    115 		0x12, __BIT(2), 0x1b, __BITS(4,0)),
    116 	AXP_CTRL("fldo1", 700, 1450, 50,
    117 		0x13, __BIT(2), 0x1c, __BITS(3,0)),
    118 	AXP_CTRL("fldo2", 700, 1450, 50,
    119 		0x13, __BIT(3), 0x1d, __BITS(3,0)),
    120 	AXP_CTRL("dcdc1", 1600, 3400, 100,
    121 		0x10, __BIT(0), 0x20, __BITS(4,0)),
    122 	AXP_CTRL2("dcdc2", 500, 1300, 10, 71, 20, 5,
    123 		0x10, __BIT(1), 0x21, __BITS(6,0)),
    124 	AXP_CTRL2("dcdc3", 500, 1300, 10, 71, 20, 5,
    125 		0x10, __BIT(2), 0x22, __BITS(6,0)),
    126 	AXP_CTRL2("dcdc4", 500, 1300, 10, 71, 20, 5,
    127 		0x10, __BIT(3), 0x23, __BITS(6,0)),
    128 	AXP_CTRL2("dcdc5", 800, 1840, 10, 33, 20, 36,
    129 		0x10, __BIT(4), 0x24, __BITS(6,0)),
    130 	AXP_CTRL2("dcdc6", 600, 1520, 10, 51, 20, 21,
    131 		0x10, __BIT(5), 0x25, __BITS(6,0)),
    132 	AXP_CTRL("aldo1", 700, 3300, 100,
    133 		0x13, __BIT(5), 0x28, __BITS(4,0)),
    134 	AXP_CTRL("aldo2", 700, 3300, 100,
    135 		0x13, __BIT(6), 0x29, __BITS(4,0)),
    136 	AXP_CTRL("aldo3", 700, 3300, 100,
    137 		0x13, __BIT(7), 0x2a, __BITS(4,0)),
    138 };
    139 
    140 static const struct axppmic_ctrl axp805_ctrls[] = {
    141 	AXP_CTRL2("dcdca", 600, 1520, 10, 51, 20, 21,
    142 		0x10, __BIT(0), 0x12, __BITS(6,0)),
    143 	AXP_CTRL("dcdcb", 1000, 2550, 50,
    144 		0x10, __BIT(1), 0x13, __BITS(4,0)),
    145 	AXP_CTRL2("dcdcc", 600, 1520, 10, 51, 20, 21,
    146 		0x10, __BIT(2), 0x14, __BITS(6,0)),
    147 	AXP_CTRL2("dcdcd", 600, 3300, 20, 46, 100, 18,
    148 		0x10, __BIT(3), 0x15, __BITS(5,0)),
    149 	AXP_CTRL("dcdce", 1100, 3400, 100,
    150 		0x10, __BIT(4), 0x16, __BITS(4,0)),
    151 	AXP_CTRL("aldo1", 700, 3300, 100,
    152 		0x10, __BIT(5), 0x17, __BITS(4,0)),
    153 	AXP_CTRL("aldo2", 700, 3400, 100,
    154 		0x10, __BIT(6), 0x18, __BITS(4,0)),
    155 	AXP_CTRL("aldo3", 700, 3300, 100,
    156 		0x10, __BIT(7), 0x19, __BITS(4,0)),
    157 	AXP_CTRL("bldo1", 700, 1900, 100,
    158 		0x11, __BIT(0), 0x20, __BITS(3,0)),
    159 	AXP_CTRL("bldo2", 700, 1900, 100,
    160 		0x11, __BIT(1), 0x21, __BITS(3,0)),
    161 	AXP_CTRL("bldo3", 700, 1900, 100,
    162 		0x11, __BIT(2), 0x22, __BITS(3,0)),
    163 	AXP_CTRL("bldo4", 700, 1900, 100,
    164 		0x11, __BIT(3), 0x23, __BITS(3,0)),
    165 	AXP_CTRL("cldo1", 700, 3300, 100,
    166 		0x11, __BIT(4), 0x24, __BITS(4,0)),
    167 	AXP_CTRL2("cldo2", 700, 4200, 100, 28, 200, 4,
    168 		0x11, __BIT(5), 0x25, __BITS(4,0)),
    169 	AXP_CTRL("cldo3", 700, 3300, 100,
    170 		0x11, __BIT(6), 0x26, __BITS(4,0)),
    171 };
    172 
    173 struct axppmic_config {
    174 	const char *name;
    175 	const struct axppmic_ctrl *controls;
    176 	u_int ncontrols;
    177 	u_int irq_regs;
    178 	bool has_battery;
    179 	bool has_fuel_gauge;
    180 };
    181 
    182 enum axppmic_sensor {
    183 	AXP_SENSOR_BATT_PRESENT,
    184 	AXP_SENSOR_BATT_CHARGING,
    185 	AXP_SENSOR_BATT_CHARGE_STATE,
    186 	AXP_SENSOR_BATT_CAPACITY,
    187 	AXP_NSENSORS
    188 };
    189 
    190 struct axppmic_softc {
    191 	device_t	sc_dev;
    192 	i2c_tag_t	sc_i2c;
    193 	i2c_addr_t	sc_addr;
    194 	int		sc_phandle;
    195 
    196 	bool		sc_has_battery;
    197 	bool		sc_has_fuel_gauge;
    198 
    199 	struct sysmon_pswitch sc_smpsw;
    200 
    201 	struct sysmon_envsys *sc_sme;
    202 	envsys_data_t	sc_sensor[AXP_NSENSORS];
    203 };
    204 
    205 struct axpreg_softc {
    206 	device_t	sc_dev;
    207 	i2c_tag_t	sc_i2c;
    208 	i2c_addr_t	sc_addr;
    209 	const struct axppmic_ctrl *sc_ctrl;
    210 };
    211 
    212 struct axpreg_attach_args {
    213 	const struct axppmic_ctrl *reg_ctrl;
    214 	int		reg_phandle;
    215 	i2c_tag_t	reg_i2c;
    216 	i2c_addr_t	reg_addr;
    217 };
    218 
    219 static const struct axppmic_config axp803_config = {
    220 	.name = "AXP803",
    221 	.controls = axp803_ctrls,
    222 	.ncontrols = __arraycount(axp803_ctrls),
    223 	.irq_regs = 6,
    224 	.has_battery = true,
    225 	.has_fuel_gauge = true,
    226 };
    227 
    228 static const struct axppmic_config axp805_config = {
    229 	.name = "AXP805/806",
    230 	.controls = axp805_ctrls,
    231 	.ncontrols = __arraycount(axp805_ctrls),
    232 	.irq_regs = 2,
    233 };
    234 
    235 static const struct of_compat_data compat_data[] = {
    236 	{ "x-powers,axp803",	(uintptr_t)&axp803_config },
    237 	{ "x-powers,axp805",	(uintptr_t)&axp805_config },
    238 	{ "x-powers,axp806",	(uintptr_t)&axp805_config },
    239 	{ NULL }
    240 };
    241 
    242 static int
    243 axppmic_read(i2c_tag_t tag, i2c_addr_t addr, uint8_t reg, uint8_t *val, int flags)
    244 {
    245 	return iic_smbus_read_byte(tag, addr, reg, val, flags);
    246 }
    247 
    248 static int
    249 axppmic_write(i2c_tag_t tag, i2c_addr_t addr, uint8_t reg, uint8_t val, int flags)
    250 {
    251 	return iic_smbus_write_byte(tag, addr, reg, val, flags);
    252 }
    253 
    254 static int
    255 axppmic_set_voltage(i2c_tag_t tag, i2c_addr_t addr, const struct axppmic_ctrl *c, u_int min, u_int max)
    256 {
    257 	const int flags = (cold ? I2C_F_POLL : 0);
    258 	u_int vol, reg_val;
    259 	int nstep, error;
    260 	uint8_t val;
    261 
    262 	if (!c->c_voltage_mask)
    263 		return EINVAL;
    264 
    265 	if (min < c->c_min || min > c->c_max)
    266 		return EINVAL;
    267 
    268 	reg_val = 0;
    269 	nstep = 1;
    270 	vol = c->c_min;
    271 
    272 	for (nstep = 0; nstep < c->c_step1cnt && vol < min; nstep++) {
    273 		++reg_val;
    274 		vol += c->c_step1;
    275 	}
    276 	for (nstep = 0; nstep < c->c_step2cnt && vol < min; nstep++) {
    277 		++reg_val;
    278 		vol += c->c_step2;
    279 	}
    280 
    281 	if (vol > max)
    282 		return EINVAL;
    283 
    284 	iic_acquire_bus(tag, flags);
    285 	if ((error = axppmic_read(tag, addr, c->c_voltage_reg, &val, flags)) == 0) {
    286 		val &= ~c->c_voltage_mask;
    287 		val |= __SHIFTIN(reg_val, c->c_voltage_mask);
    288 		error = axppmic_write(tag, addr, c->c_voltage_reg, val, flags);
    289 	}
    290 	iic_release_bus(tag, flags);
    291 
    292 	return error;
    293 }
    294 
    295 static int
    296 axppmic_get_voltage(i2c_tag_t tag, i2c_addr_t addr, const struct axppmic_ctrl *c, u_int *pvol)
    297 {
    298 	const int flags = (cold ? I2C_F_POLL : 0);
    299 	int reg_val, error;
    300 	uint8_t val;
    301 
    302 	if (!c->c_voltage_mask)
    303 		return EINVAL;
    304 
    305 	iic_acquire_bus(tag, flags);
    306 	error = axppmic_read(tag, addr, c->c_voltage_reg, &val, flags);
    307 	iic_release_bus(tag, flags);
    308 	if (error)
    309 		return error;
    310 
    311 	reg_val = __SHIFTOUT(val, c->c_voltage_mask);
    312 	if (reg_val < c->c_step1cnt) {
    313 		*pvol = c->c_min + reg_val * c->c_step1;
    314 	} else {
    315 		*pvol = c->c_min + (c->c_step1cnt * c->c_step1) +
    316 		    ((reg_val - c->c_step1cnt) * c->c_step2);
    317 	}
    318 
    319 	return 0;
    320 }
    321 
    322 static void
    323 axppmic_power_poweroff(device_t dev)
    324 {
    325 	struct axppmic_softc *sc = device_private(dev);
    326 
    327 	delay(1000000);
    328 
    329 	iic_acquire_bus(sc->sc_i2c, I2C_F_POLL);
    330 	axppmic_write(sc->sc_i2c, sc->sc_addr, AXP_POWER_DISABLE_REG, AXP_POWER_DISABLE_CTRL, I2C_F_POLL);
    331 	iic_release_bus(sc->sc_i2c, I2C_F_POLL);
    332 }
    333 
    334 static struct fdtbus_power_controller_func axppmic_power_funcs = {
    335 	.poweroff = axppmic_power_poweroff,
    336 };
    337 
    338 static void
    339 axppmic_task_shut(void *priv)
    340 {
    341 	struct axppmic_softc *sc = priv;
    342 
    343 	sysmon_pswitch_event(&sc->sc_smpsw, PSWITCH_EVENT_PRESSED);
    344 }
    345 
    346 static int
    347 axppmic_intr(void *priv)
    348 {
    349 	struct axppmic_softc *sc = priv;
    350 	const int flags = I2C_F_POLL;
    351 	uint8_t stat;
    352 
    353 	iic_acquire_bus(sc->sc_i2c, flags);
    354 	if (axppmic_read(sc->sc_i2c, sc->sc_addr, AXP_IRQ_STATUS_REG(2), &stat, flags) == 0) {
    355 		if (stat & AXP_IRQ2_POKSIRQ)
    356 			sysmon_task_queue_sched(0, axppmic_task_shut, sc);
    357 
    358 		axppmic_write(sc->sc_i2c, sc->sc_addr, AXP_IRQ_STATUS_REG(2), stat, flags);
    359 	}
    360 	iic_release_bus(sc->sc_i2c, flags);
    361 
    362 	return 1;
    363 }
    364 
    365 static void
    366 axppmic_sensor_refresh(struct sysmon_envsys *sme, envsys_data_t *e)
    367 {
    368 	struct axppmic_softc *sc = sme->sme_cookie;
    369 	const int flags = I2C_F_POLL;
    370 	uint8_t val, warn_val;
    371 
    372 	e->state = ENVSYS_SINVALID;
    373 
    374 	iic_acquire_bus(sc->sc_i2c, flags);
    375 	switch (e->private) {
    376 	case AXP_SENSOR_BATT_PRESENT:
    377 		if (axppmic_read(sc->sc_i2c, sc->sc_addr, AXP_POWER_MODE_REG, &val, flags) == 0) {
    378 			if (val & AXP_POWER_MODE_BATT_VALID) {
    379 				e->state = ENVSYS_SVALID;
    380 				e->value_cur = !!(val & AXP_POWER_MODE_BATT_PRESENT);
    381 				break;
    382 			}
    383 		}
    384 		break;
    385 	case AXP_SENSOR_BATT_CHARGING:
    386 		if (axppmic_read(sc->sc_i2c, sc->sc_addr, AXP_POWER_MODE_REG, &val, flags) == 0) {
    387 			e->state = ENVSYS_SVALID;
    388 			e->value_cur = !!(val & AXP_POWER_MODE_BATT_CHARGING);
    389 		}
    390 		break;
    391 	case AXP_SENSOR_BATT_CHARGE_STATE:
    392 		if (axppmic_read(sc->sc_i2c, sc->sc_addr, AXP_POWER_MODE_REG, &val, flags) == 0 &&
    393 		    (val & AXP_POWER_MODE_BATT_VALID) != 0 &&
    394 		    (val & AXP_POWER_MODE_BATT_PRESENT) != 0 &&
    395 		    axppmic_read(sc->sc_i2c, sc->sc_addr, AXP_BATT_CAP_REG, &val, flags) == 0 &&
    396 		    (val & AXP_BATT_CAP_VALID) != 0 &&
    397 		    axppmic_read(sc->sc_i2c, sc->sc_addr, AXP_BATT_CAP_WARN_REG, &warn_val, flags) == 0) {
    398 			const u_int warn_thres = __SHIFTOUT(warn_val, AXP_BATT_CAP_WARN_LV1) + 5;
    399 			const u_int shut_thres = __SHIFTOUT(warn_val, AXP_BATT_CAP_WARN_LV2);
    400 
    401 			const u_int batt_val = __SHIFTOUT(val, AXP_BATT_CAP_PERCENT);
    402 			if (batt_val <= shut_thres) {
    403 				e->state = ENVSYS_SCRITICAL;
    404 				e->value_cur = ENVSYS_BATTERY_CAPACITY_CRITICAL;
    405 			} else if (batt_val <= warn_thres) {
    406 				e->state = ENVSYS_SWARNUNDER;
    407 				e->value_cur = ENVSYS_BATTERY_CAPACITY_WARNING;
    408 			} else {
    409 				e->state = ENVSYS_SVALID;
    410 				e->value_cur = ENVSYS_BATTERY_CAPACITY_NORMAL;
    411 			}
    412 		}
    413 		break;
    414 	case AXP_SENSOR_BATT_CAPACITY:
    415 		if (axppmic_read(sc->sc_i2c, sc->sc_addr, AXP_POWER_MODE_REG, &val, flags) == 0 &&
    416 		    (val & AXP_POWER_MODE_BATT_VALID) != 0 &&
    417 		    (val & AXP_POWER_MODE_BATT_PRESENT) != 0 &&
    418 		    axppmic_read(sc->sc_i2c, sc->sc_addr, AXP_BATT_CAP_REG, &val, flags) == 0 &&
    419 		    (val & AXP_BATT_CAP_VALID) != 0) {
    420 			e->state = ENVSYS_SVALID;
    421 			e->value_cur = __SHIFTOUT(val, AXP_BATT_CAP_PERCENT);
    422 		}
    423 		break;
    424 	}
    425 	iic_release_bus(sc->sc_i2c, flags);
    426 }
    427 
    428 static void
    429 axppmic_attach_battery(struct axppmic_softc *sc)
    430 {
    431 	envsys_data_t *e;
    432 
    433 	e = &sc->sc_sensor[AXP_SENSOR_BATT_PRESENT];
    434 	e->private = AXP_SENSOR_BATT_PRESENT;
    435 	e->units = ENVSYS_INDICATOR;
    436 	e->state = ENVSYS_SINVALID;
    437 	strlcpy(e->desc, "battery present", sizeof(e->desc));
    438 	sysmon_envsys_sensor_attach(sc->sc_sme, e);
    439 
    440 	e = &sc->sc_sensor[AXP_SENSOR_BATT_CHARGING];
    441 	e->private = AXP_SENSOR_BATT_CHARGING;
    442 	e->units = ENVSYS_BATTERY_CHARGE;
    443 	e->state = ENVSYS_SINVALID;
    444 	strlcpy(e->desc, "charging", sizeof(e->desc));
    445 	sysmon_envsys_sensor_attach(sc->sc_sme, e);
    446 
    447 	e = &sc->sc_sensor[AXP_SENSOR_BATT_CHARGE_STATE];
    448 	e->private = AXP_SENSOR_BATT_CHARGE_STATE;
    449 	e->units = ENVSYS_BATTERY_CAPACITY;
    450 	e->flags = ENVSYS_FMONSTCHANGED;
    451 	e->state = ENVSYS_SVALID;
    452 	e->value_cur = ENVSYS_BATTERY_CAPACITY_NORMAL;
    453 	strlcpy(e->desc, "charge state", sizeof(e->desc));
    454 	sysmon_envsys_sensor_attach(sc->sc_sme, e);
    455 
    456 	if (sc->sc_has_fuel_gauge) {
    457 		e = &sc->sc_sensor[AXP_SENSOR_BATT_CAPACITY];
    458 		e->private = AXP_SENSOR_BATT_CAPACITY;
    459 		e->units = ENVSYS_INTEGER;
    460 		e->state = ENVSYS_SINVALID;
    461 		e->flags = ENVSYS_FPERCENT;
    462 		strlcpy(e->desc, "battery percent", sizeof(e->desc));
    463 		sysmon_envsys_sensor_attach(sc->sc_sme, e);
    464 	}
    465 }
    466 
    467 static void
    468 axppmic_attach_sensors(struct axppmic_softc *sc)
    469 {
    470 	if (sc->sc_has_battery) {
    471 		sc->sc_sme = sysmon_envsys_create();
    472 		sc->sc_sme->sme_name = device_xname(sc->sc_dev);
    473 		sc->sc_sme->sme_cookie = sc;
    474 		sc->sc_sme->sme_refresh = axppmic_sensor_refresh;
    475 		sc->sc_sme->sme_class = SME_CLASS_BATTERY;
    476 		sc->sc_sme->sme_flags = SME_POLL_ONLY | SME_INIT_REFRESH;
    477 
    478 		axppmic_attach_battery(sc);
    479 
    480 		sysmon_envsys_register(sc->sc_sme);
    481 	}
    482 }
    483 
    484 
    485 static int
    486 axppmic_match(device_t parent, cfdata_t match, void *aux)
    487 {
    488 	struct i2c_attach_args *ia = aux;
    489 
    490 	if (ia->ia_name != NULL) {
    491 		if (ia->ia_cookie)
    492 			return of_match_compat_data(ia->ia_cookie, compat_data);
    493 		else
    494 			return 0;
    495 	}
    496 
    497 	return 1;
    498 }
    499 
    500 static void
    501 axppmic_attach(device_t parent, device_t self, void *aux)
    502 {
    503 	struct axppmic_softc *sc = device_private(self);
    504 	const struct axppmic_config *c;
    505 	struct axpreg_attach_args aaa;
    506 	struct i2c_attach_args *ia = aux;
    507 	int phandle, child, i;
    508 	uint32_t irq_mask;
    509 	void *ih;
    510 
    511 	c = (void *)of_search_compatible(ia->ia_cookie, compat_data)->data;
    512 
    513 	sc->sc_dev = self;
    514 	sc->sc_i2c = ia->ia_tag;
    515 	sc->sc_addr = ia->ia_addr;
    516 	sc->sc_phandle = ia->ia_cookie;
    517 	sc->sc_has_battery = c->has_battery;
    518 	sc->sc_has_fuel_gauge = c->has_fuel_gauge;
    519 
    520 	aprint_naive("\n");
    521 	aprint_normal(": %s\n", c->name);
    522 
    523 	sc->sc_smpsw.smpsw_name = device_xname(self);
    524 	sc->sc_smpsw.smpsw_type = PSWITCH_TYPE_POWER;
    525 	sysmon_pswitch_register(&sc->sc_smpsw);
    526 
    527 	iic_acquire_bus(sc->sc_i2c, I2C_F_POLL);
    528 	for (i = 1; i <= c->irq_regs; i++) {
    529 		irq_mask = 0;
    530 		if (i == 2)
    531 			irq_mask |= AXP_IRQ2_POKSIRQ;
    532 		axppmic_write(sc->sc_i2c, sc->sc_addr, AXP_IRQ_ENABLE_REG(i), irq_mask, I2C_F_POLL);
    533 	}
    534 	iic_release_bus(sc->sc_i2c, I2C_F_POLL);
    535 
    536 	ih = fdtbus_intr_establish(sc->sc_phandle, 0, IPL_VM, FDT_INTR_MPSAFE,
    537 	    axppmic_intr, sc);
    538 	if (ih == NULL) {
    539 		aprint_error_dev(self, "WARNING: couldn't establish interrupt handler\n");
    540 	}
    541 
    542 	fdtbus_register_power_controller(sc->sc_dev, sc->sc_phandle,
    543 	    &axppmic_power_funcs);
    544 
    545 	phandle = of_find_firstchild_byname(sc->sc_phandle, "regulators");
    546 	if (phandle > 0) {
    547 		aaa.reg_i2c = sc->sc_i2c;
    548 		aaa.reg_addr = sc->sc_addr;
    549 		for (i = 0; i < c->ncontrols; i++) {
    550 			const struct axppmic_ctrl *ctrl = &c->controls[i];
    551 			child = of_find_firstchild_byname(phandle, ctrl->c_name);
    552 			if (child <= 0)
    553 				continue;
    554 			aaa.reg_ctrl = ctrl;
    555 			aaa.reg_phandle = child;
    556 			config_found(sc->sc_dev, &aaa, NULL);
    557 		}
    558 	}
    559 
    560 	if (c->has_battery)
    561 		axppmic_attach_sensors(sc);
    562 }
    563 
    564 static int
    565 axpreg_acquire(device_t dev)
    566 {
    567 	return 0;
    568 }
    569 
    570 static void
    571 axpreg_release(device_t dev)
    572 {
    573 }
    574 
    575 static int
    576 axpreg_enable(device_t dev, bool enable)
    577 {
    578 	struct axpreg_softc *sc = device_private(dev);
    579 	const struct axppmic_ctrl *c = sc->sc_ctrl;
    580 	const int flags = (cold ? I2C_F_POLL : 0);
    581 	uint8_t val;
    582 	int error;
    583 
    584 	if (!c->c_enable_mask)
    585 		return EINVAL;
    586 
    587 	iic_acquire_bus(sc->sc_i2c, flags);
    588 	if ((error = axppmic_read(sc->sc_i2c, sc->sc_addr, c->c_enable_reg, &val, flags)) == 0) {
    589 		if (enable)
    590 			val |= c->c_enable_mask;
    591 		else
    592 			val &= ~c->c_enable_mask;
    593 		error = axppmic_write(sc->sc_i2c, sc->sc_addr, c->c_enable_reg, val, flags);
    594 	}
    595 	iic_release_bus(sc->sc_i2c, flags);
    596 
    597 	return error;
    598 }
    599 
    600 static int
    601 axpreg_set_voltage(device_t dev, u_int min_uvol, u_int max_uvol)
    602 {
    603 	struct axpreg_softc *sc = device_private(dev);
    604 	const struct axppmic_ctrl *c = sc->sc_ctrl;
    605 
    606 	return axppmic_set_voltage(sc->sc_i2c, sc->sc_addr, c,
    607 	    min_uvol / 1000, max_uvol / 1000);
    608 }
    609 
    610 static int
    611 axpreg_get_voltage(device_t dev, u_int *puvol)
    612 {
    613 	struct axpreg_softc *sc = device_private(dev);
    614 	const struct axppmic_ctrl *c = sc->sc_ctrl;
    615 	int error;
    616 	u_int vol;
    617 
    618 	error = axppmic_get_voltage(sc->sc_i2c, sc->sc_addr, c, &vol);
    619 	if (error)
    620 		return error;
    621 
    622 	*puvol = vol * 1000;
    623 	return 0;
    624 }
    625 
    626 static struct fdtbus_regulator_controller_func axpreg_funcs = {
    627 	.acquire = axpreg_acquire,
    628 	.release = axpreg_release,
    629 	.enable = axpreg_enable,
    630 	.set_voltage = axpreg_set_voltage,
    631 	.get_voltage = axpreg_get_voltage,
    632 };
    633 
    634 static int
    635 axpreg_match(device_t parent, cfdata_t match, void *aux)
    636 {
    637 	return 1;
    638 }
    639 
    640 static void
    641 axpreg_attach(device_t parent, device_t self, void *aux)
    642 {
    643 	struct axpreg_softc *sc = device_private(self);
    644 	struct axpreg_attach_args *aaa = aux;
    645 	const int phandle = aaa->reg_phandle;
    646 	const char *name;
    647 
    648 	sc->sc_dev = self;
    649 	sc->sc_i2c = aaa->reg_i2c;
    650 	sc->sc_addr = aaa->reg_addr;
    651 	sc->sc_ctrl = aaa->reg_ctrl;
    652 
    653 	fdtbus_register_regulator_controller(self, phandle,
    654 	    &axpreg_funcs);
    655 
    656 	aprint_naive("\n");
    657 	name = fdtbus_get_string(phandle, "regulator-name");
    658 	if (name)
    659 		aprint_normal(": %s\n", name);
    660 	else
    661 		aprint_normal("\n");
    662 }
    663 
    664 CFATTACH_DECL_NEW(axppmic, sizeof(struct axppmic_softc),
    665     axppmic_match, axppmic_attach, NULL, NULL);
    666 
    667 CFATTACH_DECL_NEW(axpreg, sizeof(struct axpreg_softc),
    668     axpreg_match, axpreg_attach, NULL, NULL);
    669