Home | History | Annotate | Line # | Download | only in i2c
tps65217pmic.c revision 1.14
      1 /*	$NetBSD: tps65217pmic.c,v 1.14 2019/11/03 22:55:34 jmcneill Exp $ */
      2 
      3 /*-
      4  * Copyright (c) 2013 The NetBSD Foundation, Inc.
      5  * All rights reserved.
      6  *
      7  * This code is derived from software contributed to The NetBSD Foundation
      8  * by Radoslaw Kujawa.
      9  *
     10  * Redistribution and use in source and binary forms, with or without
     11  * modification, are permitted provided that the following conditions
     12  * are met:
     13  * 1. Redistributions of source code must retain the above copyright
     14  *    notice, this list of conditions and the following disclaimer.
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29  * POSSIBILITY OF SUCH DAMAGE.
     30  */
     31 
     32 /*
     33  * Texas Instruments TPS65217 Power Management IC driver.
     34  * TODO: battery, sequencer, pgood
     35  */
     36 
     37 #include "opt_fdt.h"
     38 
     39 #include <sys/cdefs.h>
     40 __KERNEL_RCSID(0, "$NetBSD: tps65217pmic.c,v 1.14 2019/11/03 22:55:34 jmcneill Exp $");
     41 
     42 #include <sys/param.h>
     43 #include <sys/systm.h>
     44 #include <sys/device.h>
     45 #include <sys/kernel.h>
     46 #include <sys/mutex.h>
     47 
     48 #include <sys/bus.h>
     49 #include <dev/i2c/i2cvar.h>
     50 
     51 #include <dev/sysmon/sysmonvar.h>
     52 #include <dev/sysmon/sysmon_taskq.h>
     53 
     54 #include <dev/i2c/tps65217pmicreg.h>
     55 #include <dev/i2c/tps65217pmicvar.h>
     56 
     57 #ifdef FDT
     58 #include <dev/fdt/fdtvar.h>
     59 #endif
     60 
     61 #define NTPS_REG	7
     62 #define SNUM_REGS	NTPS_REG-1
     63 #define SNUM_USBSTATUS	NTPS_REG
     64 #define SNUM_ACSTATUS	NTPS_REG+1
     65 
     66 struct tps_reg_param;
     67 
     68 struct tps65217pmic_softc {
     69 	device_t		sc_dev;
     70 
     71 	i2c_tag_t		sc_tag;
     72 	i2c_addr_t		sc_addr;
     73 	int			sc_phandle;
     74 
     75 	uint8_t			sc_version;
     76 	uint8_t			sc_revision;
     77 
     78 	kmutex_t		sc_lock;
     79 
     80 	bool			sc_acstatus;
     81 	bool			sc_usbstatus;
     82 	bool			sc_acenabled;
     83 	bool			sc_usbenabled;
     84 
     85 	callout_t		sc_powerpollco;
     86 
     87 	/* sysmon(4) stuff */
     88 	struct sysmon_envsys	*sc_sme;
     89 	envsys_data_t		sc_regsensor[NTPS_REG];
     90 	envsys_data_t		sc_acsensor;
     91 	envsys_data_t		sc_usbsensor;
     92 
     93 	struct sysmon_pswitch	sc_smpsw;
     94 };
     95 
     96 struct tps65217reg_softc {
     97 	device_t		sc_dev;
     98 	int			sc_phandle;
     99 	struct tps_reg_param	*sc_param;
    100 };
    101 
    102 struct tps65217reg_attach_args {
    103 	struct tps_reg_param	*reg_param;
    104 	int			reg_phandle;
    105 };
    106 
    107 /* Voltage regulators */
    108 enum tps_reg_num {
    109 	TPS65217PMIC_LDO1,
    110 	TPS65217PMIC_LDO2,
    111 	TPS65217PMIC_LDO3LS,
    112 	TPS65217PMIC_LDO4LS,
    113 	TPS65217PMIC_DCDC1,
    114 	TPS65217PMIC_DCDC2,
    115 	TPS65217PMIC_DCDC3
    116 };
    117 
    118 struct tps_reg_param {
    119 	/* parameters configured statically */
    120 
    121 	const char* name;
    122 	uint16_t voltage_min;		/* in mV */
    123 	uint16_t voltage_max;		/* in mV */
    124 	const uint16_t *voltages;	/* all possible voltage settings */
    125 	uint8_t nvoltages;		/* number of voltage settings */
    126 
    127 	bool can_track;			/* regulator can track U of other r. */
    128 	struct tps_reg_param *tracked_reg; /* ptr to tracked regulator */
    129 	bool can_xadj;			/* voltage can be adjusted externally */
    130 	bool can_ls;			/* can be a load switch instead of r. */
    131 
    132 	uint8_t defreg_num;		/* DEF register */
    133 	uint8_t enable_bit;		/* position in ENABLE register */
    134 
    135 	/*
    136 	 * Run-time parameters configured during attachment and later, these
    137 	 * probably should be split into separate struct that would be a part
    138 	 * of softc. But since we can have only one TPS chip, that should be
    139 	 * okay for now.
    140 	 */
    141 
    142 	bool is_enabled;		/* regulator is enabled */
    143 	bool is_pg;			/* regulator is "power good" */
    144 	bool is_tracking;		/* voltage is tracking other reg. */
    145 	bool is_ls;			/* is a load switch */
    146 	bool is_xadj;			/* voltage is adjusted externally */
    147 
    148 	uint16_t current_voltage;	/* in mV */
    149 
    150 };
    151 
    152 static int tps65217pmic_match(device_t, cfdata_t, void *);
    153 static void tps65217pmic_attach(device_t, device_t, void *);
    154 
    155 static uint8_t tps65217pmic_reg_read(struct tps65217pmic_softc *, uint8_t);
    156 static void tps65217pmic_reg_write(struct tps65217pmic_softc *, uint8_t,
    157     uint8_t);
    158 
    159 static void tps65217pmic_reg_refresh(struct tps65217pmic_softc *);
    160 
    161 static uint16_t tps65217pmic_ppath_max_usb_current(uint8_t);
    162 static uint16_t tps65217pmic_ppath_max_ac_current(uint8_t);
    163 
    164 static void tps65217pmic_regulator_read_config(struct tps65217pmic_softc *,
    165     struct tps_reg_param *);
    166 
    167 static void tps65217pmic_print_ppath(struct tps65217pmic_softc *);
    168 static void tps65217pmic_print_ldos(struct tps65217pmic_softc *);
    169 
    170 static void tps65217pmic_version(struct tps65217pmic_softc *);
    171 
    172 static void tps65217pmic_envsys_register(struct tps65217pmic_softc *);
    173 static void tps65217pmic_envsys_refresh(struct sysmon_envsys *, envsys_data_t *);
    174 
    175 static void tps65217pmic_power_monitor_init(struct tps65217pmic_softc *);
    176 static void tps65217pmic_power_monitor(void *);
    177 
    178 static void tps65217pmic_wled_init(struct tps65217pmic_softc *, int, int, int);
    179 
    180 CFATTACH_DECL_NEW(tps65217pmic, sizeof (struct tps65217pmic_softc),
    181     tps65217pmic_match, tps65217pmic_attach, NULL, NULL);
    182 
    183 #ifdef FDT
    184 static void tps65217pmic_regulator_attach(struct tps65217pmic_softc *);
    185 #endif
    186 
    187 /* Possible settings of LDO1 in mV. */
    188 static const uint16_t ldo1voltages[] = { 1000, 1100, 1200, 1250, 1300, 1350,
    189     1400, 1500, 1600, 1800, 2500, 2750, 2800, 3000, 3100, 3300 };
    190 /* Possible settings of LDO2, DCDC1, DCDC2, DCDC3 in mV. */
    191 static const uint16_t ldo2voltages[] = { 900, 925, 950, 975, 1000, 1025, 1050,
    192     1075, 1100, 1125, 1150, 1175, 1200, 1225, 1250, 1275, 1300, 1325, 1350,
    193     1375, 1400, 1425, 1450, 1475, 1500, 1550, 1600, 1650, 1700, 1750, 1800,
    194     1850, 1900, 1950, 2000, 2050, 2100, 2150, 2200, 2250, 2300, 2350, 2400,
    195     2450, 2500, 2550, 2600, 2650, 2700, 2750, 2800, 2850, 2900, 3000, 3100,
    196     3200, 3300, 3300, 3300, 3300, 3300, 3300, 3300, 3300 };
    197 /* Possible settings of LDO3, LDO4 in mV. */
    198 static const uint16_t ldo3voltages[] = { 1500, 1550, 1600, 1650, 1700, 1750,
    199     1800, 1850, 1900, 2000, 2100, 2200, 2300, 2400, 2450, 2500, 2550, 2600,
    200     2650, 2700, 2750, 2800, 2850, 2900,2950, 3000, 3050, 3100, 3150, 3200,
    201     3250, 3300 };
    202 
    203 static struct tps_reg_param tps_regulators[] = {
    204 	{
    205 		.name = "ldo1",
    206 		.voltage_min = 1000,
    207 		.voltage_max = 3300,
    208 		.voltages = ldo1voltages,
    209 		.nvoltages = 16,
    210 		.can_track = false,
    211 		.tracked_reg = NULL,
    212 		.can_xadj =  false,
    213 		.can_ls = false,
    214 		.defreg_num = TPS65217PMIC_DEFLDO1,
    215 		.enable_bit = TPS65217PMIC_ENABLE_LDO1
    216 	},
    217 	{
    218 		.name = "ldo2",
    219 		.voltage_min = 900,
    220 		.voltage_max = 3300,
    221 		.voltages = ldo2voltages,
    222 		.nvoltages = 64,
    223 		.can_track = true,
    224 		.tracked_reg = &(tps_regulators[TPS65217PMIC_DCDC3]),
    225 		.can_xadj = false,
    226 		.can_ls = false,
    227 		.defreg_num = TPS65217PMIC_DEFLDO2,
    228 		.enable_bit = TPS65217PMIC_ENABLE_LDO2
    229 	},
    230 	{
    231 		.name = "ldo3",
    232 		.voltage_min = 1500,
    233 		.voltage_max = 3300,
    234 		.voltages = ldo3voltages,
    235 		.nvoltages = 32,
    236 		.can_track = false,
    237 		.tracked_reg = NULL,
    238 		.can_xadj = false,
    239 		.can_ls = true,
    240 		.defreg_num = TPS65217PMIC_DEFLDO3,
    241 		.enable_bit = TPS65217PMIC_ENABLE_LDO3
    242 	},
    243 	{
    244 		.name = "ldo4",
    245 		.voltage_min = 1500,
    246 		.voltage_max = 3300,
    247 		.voltages = ldo3voltages,
    248 		.nvoltages = 32,
    249 		.can_track = false,
    250 		.tracked_reg = NULL,
    251 		.can_xadj = false,
    252 		.can_ls = true,
    253 		.defreg_num = TPS65217PMIC_DEFLDO4,
    254 		.enable_bit = TPS65217PMIC_ENABLE_LDO4
    255 	},
    256 	{
    257 		.name = "dcdc1",
    258 		.voltage_min = 900,
    259 		.voltage_max = 3300,
    260 		.voltages = ldo2voltages,
    261 		.nvoltages = 64,
    262 		.can_track = false,
    263 		.tracked_reg = NULL,
    264 		.can_xadj = true,
    265 		.can_ls = false,
    266 		.defreg_num = TPS65217PMIC_DEFDCDC1,
    267 		.enable_bit = TPS65217PMIC_ENABLE_DCDC1
    268 	},
    269 	{
    270 		.name = "dcdc2",
    271 		.voltage_min = 900,
    272 		.voltage_max = 3300,
    273 		.voltages = ldo2voltages,
    274 		.nvoltages = 64,
    275 		.can_track = false,
    276 		.tracked_reg = NULL,
    277 		.can_xadj = true,
    278 		.can_ls = false,
    279 		.defreg_num = TPS65217PMIC_DEFDCDC2,
    280 		.enable_bit = TPS65217PMIC_ENABLE_DCDC2
    281 	},
    282 	{
    283 		.name = "dcdc3",
    284 		.voltage_min = 900,
    285 		.voltage_max = 3300,
    286 		.voltages = ldo2voltages,
    287 		.nvoltages = 64,
    288 		.can_track = false,
    289 		.tracked_reg = NULL,
    290 		.can_xadj = true,
    291 		.can_ls = false,
    292 		.defreg_num = TPS65217PMIC_DEFDCDC3,
    293 		.enable_bit = TPS65217PMIC_ENABLE_DCDC3
    294 	}
    295 };
    296 
    297 static bool matched = false;
    298 
    299 static const struct device_compatible_entry compat_data[] = {
    300 	{ "ti,tps65217",			0 },
    301 	{ NULL }
    302 };
    303 
    304 static int
    305 tps65217pmic_match(device_t parent, cfdata_t cf, void *aux)
    306 {
    307 	struct i2c_attach_args *ia = aux;
    308 	int match_result;
    309 
    310 	if (iic_use_direct_match(ia, cf, compat_data, &match_result))
    311 		return match_result;
    312 
    313 	if (ia->ia_addr == TPS65217PMIC_ADDR) {
    314 		/* we can only have one */
    315 		if (matched)
    316 			return 0;
    317 
    318 		return I2C_MATCH_ADDRESS_ONLY;
    319 	}
    320 	return 0;
    321 }
    322 
    323 static void
    324 tps65217pmic_attach(device_t parent, device_t self, void *aux)
    325 {
    326 	struct tps65217pmic_softc *sc = device_private(self);
    327 	struct i2c_attach_args *ia = aux;
    328 	prop_dictionary_t dict;
    329 	int isel, fdim, brightness;
    330 
    331 	/* XXXJRT But what if you have multiple i2c busses? */
    332 	matched = true;
    333 
    334 	sc->sc_dev = self;
    335 	sc->sc_addr = ia->ia_addr;
    336 	sc->sc_phandle = ia->ia_cookie;
    337 	sc->sc_tag = ia->ia_tag;
    338 
    339 	dict = device_properties(self);
    340 	if (prop_dictionary_get_int32(dict, "isel", &isel)) {
    341 		prop_dictionary_get_int32(dict, "fdim", &fdim);
    342 		prop_dictionary_get_int32(dict, "brightness", &brightness);
    343 	} else
    344 		isel = -1;
    345 
    346 	tps65217pmic_version(sc);
    347 
    348 	aprint_normal(": TPS65217");
    349 	switch (sc->sc_version) {
    350 	case TPS65217PMIC_CHIPID_VER_A:
    351 		aprint_normal("A");
    352 		break;
    353 	case TPS65217PMIC_CHIPID_VER_B:
    354 		aprint_normal("B");
    355 		break;
    356 	case TPS65217PMIC_CHIPID_VER_C:
    357 		aprint_normal("C");
    358 		break;
    359 	case TPS65217PMIC_CHIPID_VER_D:
    360 		aprint_normal("D");
    361 		break;
    362 	default:
    363 		/* unknown version */
    364 		break;
    365 	}
    366 
    367 	aprint_normal(" Power Management Multi-Channel IC (rev 1.%d)\n",
    368 	    sc->sc_revision);
    369 
    370 	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
    371 
    372 	sc->sc_smpsw.smpsw_name = device_xname(self);
    373 	sc->sc_smpsw.smpsw_type = PSWITCH_TYPE_ACADAPTER;
    374 	sysmon_pswitch_register(&sc->sc_smpsw);
    375 
    376 	tps65217pmic_reg_refresh(sc);
    377 
    378 	tps65217pmic_print_ppath(sc);
    379 	tps65217pmic_print_ldos(sc);
    380 
    381 	tps65217pmic_power_monitor_init(sc);
    382 
    383 	if (isel != -1)
    384 		tps65217pmic_wled_init(sc, isel, fdim, brightness);
    385 
    386 	tps65217pmic_envsys_register(sc);
    387 
    388 #ifdef FDT
    389 	tps65217pmic_regulator_attach(sc);
    390 #endif
    391 }
    392 
    393 static void
    394 tps65217pmic_power_monitor_init(struct tps65217pmic_softc *sc)
    395 {
    396 	uint8_t intr, intrmask, status, ppath;
    397 
    398 	intrmask = TPS65217PMIC_INT_USBM | TPS65217PMIC_INT_ACM |
    399 	    TPS65217PMIC_INT_PBM;
    400 
    401 	status = tps65217pmic_reg_read(sc, TPS65217PMIC_STATUS);
    402 	ppath = tps65217pmic_reg_read(sc, TPS65217PMIC_PPATH);
    403 	/* acknowledge and disregard whatever interrupt was generated earlier */
    404 	intr = tps65217pmic_reg_read(sc, TPS65217PMIC_INT);
    405 
    406 	sc->sc_usbstatus = status & TPS65217PMIC_STATUS_USBPWR;
    407 	sc->sc_acstatus = status & TPS65217PMIC_STATUS_ACPWR;
    408 	sc->sc_usbenabled = ppath & TPS65217PMIC_PPATH_USB_EN;
    409 	sc->sc_acenabled = ppath & TPS65217PMIC_PPATH_AC_EN;
    410 
    411 	if (intr & intrmask)
    412 		aprint_normal_dev(sc->sc_dev,
    413 		    "WARNING: hardware interrupt enabled but not supported");
    414 
    415 	/* set up callout to poll for power source changes */
    416 	callout_init(&sc->sc_powerpollco, 0);
    417 	callout_setfunc(&sc->sc_powerpollco, tps65217pmic_power_monitor, sc);
    418 
    419 	callout_schedule(&sc->sc_powerpollco, hz);
    420 }
    421 
    422 static void
    423 tps65217pmic_power_monitor_task(void *aux)
    424 {
    425 	struct tps65217pmic_softc *sc;
    426 	uint8_t status;
    427 	bool usbstatus, acstatus;
    428 
    429 	sc = aux;
    430 
    431 	mutex_enter(&sc->sc_lock);
    432 
    433 	status = tps65217pmic_reg_read(sc, TPS65217PMIC_STATUS);
    434 	usbstatus = status & TPS65217PMIC_STATUS_USBPWR;
    435 	acstatus = status & TPS65217PMIC_STATUS_ACPWR;
    436 
    437 	if (usbstatus != sc->sc_usbstatus) {
    438 		sc->sc_usbstatus = usbstatus;
    439 		pmf_event_inject(NULL, PMFE_POWER_CHANGED);
    440 		if (usbstatus)
    441 			aprint_normal_dev(sc->sc_dev,
    442 			    "USB power source connected\n");
    443 		else
    444 			aprint_normal_dev(sc->sc_dev,
    445 			    "USB power source disconnected\n");
    446 	}
    447 
    448 	if (acstatus != sc->sc_acstatus) {
    449 		sc->sc_acstatus = acstatus;
    450 		pmf_event_inject(NULL, PMFE_POWER_CHANGED);
    451 		if (acstatus) {
    452 			sysmon_pswitch_event(&sc->sc_smpsw,
    453 			    PSWITCH_EVENT_PRESSED);
    454 		} else {
    455 			sysmon_pswitch_event(&sc->sc_smpsw,
    456 			    PSWITCH_EVENT_RELEASED);
    457 		}
    458 	}
    459 
    460 	mutex_exit(&sc->sc_lock);
    461 
    462 	callout_schedule(&sc->sc_powerpollco, hz);
    463 }
    464 
    465 static void
    466 tps65217pmic_power_monitor(void *aux)
    467 {
    468 	sysmon_task_queue_sched(0, tps65217pmic_power_monitor_task, aux);
    469 }
    470 
    471 static void
    472 tps65217pmic_wled_init(struct tps65217pmic_softc *sc, int isel, int fdim,
    473 		       int brightness)
    474 {
    475 	uint8_t val = 0;
    476 
    477 	switch (isel) {
    478 	case 1:
    479 	case 2:
    480 		val |= ((isel - 1) << TPS65217PMIC_WLEDCTRL1_ISEL);
    481 		break;
    482 	default:
    483 		aprint_error_dev(sc->sc_dev,
    484 		    "WLED ISET selection is 1 or 2: isel %d\n", isel);
    485 		return;
    486 	}
    487 	switch (fdim) {
    488 	case 100:
    489 		val |= TPS65217PMIC_WLEDCTRL1_FDIM_100Hz;
    490 		break;
    491 	case 200:
    492 		val |= TPS65217PMIC_WLEDCTRL1_FDIM_200Hz;
    493 		break;
    494 	case 500:
    495 		val |= TPS65217PMIC_WLEDCTRL1_FDIM_500Hz;
    496 		break;
    497 	case 1000:
    498 		val |= TPS65217PMIC_WLEDCTRL1_FDIM_1000Hz;
    499 		break;
    500 	default:
    501 		aprint_error_dev(sc->sc_dev,
    502 		    "WLED PWM dimming frequency is 100, 200, 500 or 1000:"
    503 		    " fdim %d\n", fdim);
    504 		return;
    505 	}
    506 	if (brightness > 100 ||
    507 	    brightness < 0) {
    508 		aprint_error_dev(sc->sc_dev,
    509 		    "invalid brightness: between 0 and 100: %d\n", brightness);
    510 		return;
    511 	}
    512 
    513 	tps65217pmic_reg_write(sc, TPS65217PMIC_WLEDCTRL1, val);
    514 	tps65217pmic_reg_write(sc, TPS65217PMIC_WLEDCTRL2,
    515 	    (brightness - 1) & TPS65217PMIC_WLEDCTRL2_DUTY);
    516 	val |= TPS65217PMIC_WLEDCTRL1_ISINK_EN;
    517 	tps65217pmic_reg_write(sc, TPS65217PMIC_WLEDCTRL1, val);
    518 }
    519 
    520 static void
    521 tps65217pmic_reg_refresh(struct tps65217pmic_softc *sc)
    522 {
    523 	int i;
    524 	struct tps_reg_param *c_reg;
    525 
    526 	for (i = 0; i < NTPS_REG; i++) {
    527 		c_reg = &tps_regulators[i];
    528 		tps65217pmic_regulator_read_config(sc, c_reg);
    529 	}
    530 }
    531 
    532 /* Get version and revision of the chip. */
    533 static void
    534 tps65217pmic_version(struct tps65217pmic_softc *sc)
    535 {
    536 	uint8_t chipid;
    537 
    538 	chipid = tps65217pmic_reg_read(sc, TPS65217PMIC_CHIPID);
    539 
    540 	sc->sc_version = chipid & TPS65217PMIC_CHIPID_VER_MASK;
    541 	sc->sc_revision = chipid & TPS65217PMIC_CHIPID_REV_MASK;
    542 }
    543 
    544 static uint16_t
    545 tps65217pmic_ppath_max_ac_current(uint8_t ppath)
    546 {
    547 	switch ((ppath & TPS65217PMIC_PPATH_IAC) >>
    548 	    TPS65217PMIC_PPATH_IAC_RSHFIT) {
    549 	case TPS65217PMIC_PPATH_IAC_100MA:
    550 		return 100;
    551 	case TPS65217PMIC_PPATH_IAC_500MA:
    552 		return 500;
    553 	case TPS65217PMIC_PPATH_IAC_1300MA:
    554 		return 1300;
    555 	case TPS65217PMIC_PPATH_IAC_2500MA:
    556 		return 2500;
    557 	}
    558 	return 0;
    559 }
    560 
    561 static uint16_t
    562 tps65217pmic_ppath_max_usb_current(uint8_t ppath)
    563 {
    564 	switch (ppath & TPS65217PMIC_PPATH_IUSB) {
    565 	case TPS65217PMIC_PPATH_IUSB_100MA:
    566 		return 100;
    567 	case TPS65217PMIC_PPATH_IUSB_500MA:
    568 		return 500;
    569 	case TPS65217PMIC_PPATH_IUSB_1300MA:
    570 		return 1300;
    571 	case TPS65217PMIC_PPATH_IUSB_1800MA:
    572 		return 1800;
    573 	}
    574 	return 0;
    575 }
    576 
    577 /* Read regulator state and save it to tps_reg_param. */
    578 static void
    579 tps65217pmic_regulator_read_config(struct tps65217pmic_softc *sc, struct
    580     tps_reg_param *regulator)
    581 {
    582 	uint8_t defreg, regenable;
    583 	uint16_t voltage;
    584 
    585 	regenable = tps65217pmic_reg_read(sc, TPS65217PMIC_ENABLE);
    586 
    587 	if (regenable & (regulator->enable_bit))
    588 		regulator->is_enabled = true;
    589 	else {
    590 		regulator->is_enabled = false;
    591 		return;
    592 	}
    593 
    594 	defreg = tps65217pmic_reg_read(sc,
    595 	    regulator->defreg_num);
    596 
    597 	switch (regulator->nvoltages) {
    598 	case 16:
    599 		voltage = regulator->voltages[defreg &
    600 		    TPS65217PMIC_DEFX_VOLTAGE_16];
    601 		break;
    602 	case 32:
    603 		voltage = regulator->voltages[defreg &
    604 		    TPS65217PMIC_DEFX_VOLTAGE_32];
    605 		break;
    606 	case 64:
    607 		voltage = regulator->voltages[defreg &
    608 		    TPS65217PMIC_DEFX_VOLTAGE_64];
    609 		break;
    610 	default:
    611 		/* unsupported number of voltage settings? */
    612 		voltage = 0;
    613 		break;
    614 	}
    615 
    616 	/* Handle regulator tracking other regulator voltage. */
    617 	if (regulator->can_track)
    618 		if (defreg & TPS65217PMIC_DEFX_TRACKING) {
    619 			regulator->is_tracking = true;
    620 			voltage = 0; /* see regulator->tracked_reg */
    621 		}
    622 
    623 	/* Handle regulator configured into load switch mode. */
    624 	if (regulator->can_ls)
    625 		if (!(defreg & TPS65217PMIC_DEFX_LS)) {
    626 			regulator->is_ls = true;
    627 			voltage = 0;
    628 		}
    629 
    630 	if (regulator->can_xadj)
    631 		if (defreg & TPS65217PMIC_DEFX_XADJ) {
    632 			regulator->is_xadj = true;
    633 			voltage = 0;
    634 
    635 		}
    636 
    637 	/* TODO: add PGOOD checking */
    638 
    639 	regulator->current_voltage = voltage;
    640 }
    641 
    642 static void
    643 tps65217pmic_print_ldos(struct tps65217pmic_softc *sc)
    644 {
    645 	int i;
    646 	struct tps_reg_param *c_reg;
    647 
    648 	aprint_normal_dev(sc->sc_dev, "");
    649 
    650 	for (i = 0; i < NTPS_REG; i++) {
    651 		c_reg = &tps_regulators[i];
    652 
    653 		if (c_reg->is_enabled) {
    654 			if (c_reg->is_ls)
    655 				aprint_normal("[%s: LS] ", c_reg->name);
    656 			else if (c_reg->is_xadj)
    657 				aprint_normal("[%s: XADJ] ", c_reg->name);
    658 			else
    659 				aprint_normal("[%s: %d mV] ", c_reg->name,
    660 				    c_reg->current_voltage);
    661 		}
    662 	}
    663 	aprint_normal("\n");
    664 }
    665 
    666 static void
    667 tps65217pmic_print_ppath(struct tps65217pmic_softc *sc)
    668 {
    669 	uint8_t status, ppath;
    670 
    671 	ppath = tps65217pmic_reg_read(sc, TPS65217PMIC_PPATH);
    672 	status = tps65217pmic_reg_read(sc, TPS65217PMIC_STATUS);
    673 
    674 	aprint_normal_dev(sc->sc_dev, "power sources ");
    675 
    676 	if (ppath & TPS65217PMIC_PPATH_USB_EN) {
    677 		if (status & TPS65217PMIC_STATUS_USBPWR)
    678 			aprint_normal("[USB] ");
    679 		else
    680 			aprint_normal("USB ");
    681 		aprint_normal("max %d mA, ",
    682 		    tps65217pmic_ppath_max_usb_current(ppath));
    683 	}
    684 
    685 	if (ppath & TPS65217PMIC_PPATH_AC_EN) {
    686 		if (status & TPS65217PMIC_STATUS_ACPWR)
    687 			aprint_normal("[AC] ");
    688 		else
    689 			aprint_normal("AC ");
    690 		aprint_normal("max %d mA",
    691 		    tps65217pmic_ppath_max_ac_current(ppath));
    692 	}
    693 
    694 	aprint_normal("\n");
    695 }
    696 
    697 static uint8_t
    698 tps65217pmic_reg_read(struct tps65217pmic_softc *sc, uint8_t reg)
    699 {
    700 	uint8_t wbuf[2];
    701 	uint8_t rv;
    702 
    703 	if (iic_acquire_bus(sc->sc_tag, I2C_F_POLL) != 0) {
    704 		aprint_error_dev(sc->sc_dev, "cannot acquire bus for read\n");
    705 		return 0;
    706 	}
    707 
    708 	wbuf[0] = reg;
    709 
    710 	if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr, wbuf,
    711 	    1, &rv, 1, I2C_F_POLL)) {
    712 		aprint_error_dev(sc->sc_dev, "cannot execute operation\n");
    713 		iic_release_bus(sc->sc_tag, I2C_F_POLL);
    714 		return 0;
    715 	}
    716 	iic_release_bus(sc->sc_tag, I2C_F_POLL);
    717 
    718 	return rv;
    719 }
    720 
    721 static void
    722 tps65217pmic_reg_write_unlocked(struct tps65217pmic_softc *sc,
    723     uint8_t reg, uint8_t data)
    724 {
    725 	uint8_t wbuf[2];
    726 
    727 	wbuf[0] = reg;
    728 	wbuf[1] = data;
    729 
    730 	if (iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP, sc->sc_addr, NULL, 0,
    731 	    wbuf, 2, I2C_F_POLL)) {
    732 		aprint_error_dev(sc->sc_dev, "cannot execute I2C write\n");
    733 	}
    734 }
    735 
    736 static void __unused
    737 tps65217pmic_reg_write(struct tps65217pmic_softc *sc, uint8_t reg, uint8_t data)
    738 {
    739 
    740 	if (iic_acquire_bus(sc->sc_tag, I2C_F_POLL) != 0) {
    741 		aprint_error_dev(sc->sc_dev, "cannot acquire bus for write\n");
    742 		return;
    743 	}
    744 
    745 	tps65217pmic_reg_write_unlocked(sc, reg, data);
    746 
    747 	iic_release_bus(sc->sc_tag, I2C_F_POLL);
    748 }
    749 
    750 static void
    751 tps65217pmic_reg_write_l2(struct tps65217pmic_softc *sc,
    752     uint8_t reg, uint8_t data)
    753 {
    754 	uint8_t regpw = reg ^ TPS65217PMIC_PASSWORD_XOR;
    755 	if (iic_acquire_bus(sc->sc_tag, I2C_F_POLL) != 0) {
    756 		aprint_error_dev(sc->sc_dev, "cannot acquire bus for write\n");
    757 		return;
    758 	}
    759 
    760 	tps65217pmic_reg_write_unlocked(sc, TPS65217PMIC_PASSWORD, regpw);
    761 	tps65217pmic_reg_write_unlocked(sc, reg, data);
    762 	tps65217pmic_reg_write_unlocked(sc, TPS65217PMIC_PASSWORD, regpw);
    763 	tps65217pmic_reg_write_unlocked(sc, reg, data);
    764 	iic_release_bus(sc->sc_tag, I2C_F_POLL);
    765 }
    766 
    767 static void
    768 tps65217pmic_envsys_register(struct tps65217pmic_softc *sc)
    769 {
    770 	int i;
    771 
    772 	sc->sc_sme = sysmon_envsys_create();
    773 
    774 	/* iterate over all regulators and attach them as sensors */
    775 	for(i = 0; i <= SNUM_REGS; i++) {
    776 		/* set name */
    777 		strlcpy(sc->sc_regsensor[i].desc, tps_regulators[i].name,
    778 		    sizeof(sc->sc_regsensor[i].desc));
    779 		sc->sc_regsensor[i].units = ENVSYS_SVOLTS_DC;
    780 		sc->sc_regsensor[i].state = ENVSYS_SINVALID;
    781 
    782 		if (sysmon_envsys_sensor_attach(sc->sc_sme,
    783 		    &sc->sc_regsensor[i]))
    784 			aprint_error_dev(sc->sc_dev,
    785 			    "error attaching regulator sensor %d\n", i);
    786 	}
    787 
    788 	/* attach power source indicators */
    789 	strcpy(sc->sc_usbsensor.desc, "USB power source"); /* SNUM_USBSTATUS */
    790 	sc->sc_usbsensor.units = ENVSYS_INDICATOR;
    791 	sc->sc_usbsensor.state = ENVSYS_SINVALID;
    792 	if (sysmon_envsys_sensor_attach(sc->sc_sme, &sc->sc_usbsensor))
    793 		aprint_error_dev(sc->sc_dev,
    794 		    "error attaching USB power source sensor\n");
    795 	strcpy(sc->sc_acsensor.desc, "AC power source"); /* SNUM_ACSTATUS */
    796 	sc->sc_acsensor.units = ENVSYS_INDICATOR;
    797 	sc->sc_acsensor.state = ENVSYS_SINVALID;
    798 	if (sysmon_envsys_sensor_attach(sc->sc_sme, &sc->sc_acsensor))
    799 		aprint_error_dev(sc->sc_dev,
    800 		    "error attaching AC power source sensor\n");
    801 
    802 	/* register everything in sysmon */
    803 	sc->sc_sme->sme_name = device_xname(sc->sc_dev);
    804 	sc->sc_sme->sme_cookie = sc;
    805 	sc->sc_sme->sme_refresh = tps65217pmic_envsys_refresh;
    806 
    807 	if (sysmon_envsys_register(sc->sc_sme)) {
    808 		aprint_error_dev(sc->sc_dev, "unable to register in sysmon\n");
    809 		sysmon_envsys_destroy(sc->sc_sme);
    810 	}
    811 }
    812 
    813 static void
    814 tps65217pmic_envsys_refresh(struct sysmon_envsys *sme, envsys_data_t *edata)
    815 {
    816 	struct tps65217pmic_softc *sc = sme->sme_cookie;
    817 
    818 	mutex_enter(&sc->sc_lock);
    819 
    820 	tps65217pmic_reg_refresh(sc);
    821 
    822 	if (edata->sensor <= SNUM_REGS) {
    823 		/* TODO: handle special cases like LS, XADJ... */
    824 		edata->value_cur = tps_regulators[edata->sensor].current_voltage * 1000;
    825 		edata->state = ENVSYS_SVALID;
    826 	} else if (edata->sensor == SNUM_USBSTATUS) {
    827 		edata->value_cur = sc->sc_usbstatus && sc->sc_usbenabled;
    828 		edata->state = ENVSYS_SVALID;
    829 	} else if (edata->sensor == SNUM_ACSTATUS) {
    830 		edata->value_cur = sc->sc_acstatus && sc->sc_acenabled;
    831 		edata->state = ENVSYS_SVALID;
    832 	} else
    833 		aprint_error_dev(sc->sc_dev, "unknown sensor number\n");
    834 
    835 	mutex_exit(&sc->sc_lock);
    836 }
    837 
    838 int
    839 tps65217pmic_set_volt(device_t self, const char *name, int mvolt)
    840 {
    841 	int i;
    842 	struct tps65217pmic_softc *sc = device_private(self);
    843 	struct tps_reg_param *regulator = NULL;
    844 	uint8_t val;
    845 
    846 	for (i = 0; i < __arraycount(tps_regulators); i++) {
    847 		if (strcmp(name, tps_regulators[i].name) == 0) {
    848 			regulator = &tps_regulators[i];
    849 			break;
    850 		}
    851 	}
    852 	if (regulator == NULL)
    853 		return EINVAL;
    854 
    855 	if (regulator->voltage_min > mvolt || regulator->voltage_max < mvolt)
    856 		return EINVAL;
    857 
    858 	if (!regulator->is_enabled)
    859 		return EINVAL;
    860 
    861 	if (regulator->is_tracking)
    862 		return EINVAL;
    863 
    864 	if (regulator->is_xadj)
    865 		return EINVAL;
    866 
    867 	/* find closest voltage entry */
    868 	for (i = 0; i < regulator->nvoltages; i++) {
    869 		if (mvolt <= regulator->voltages[i]) {
    870 			break;
    871 		}
    872 	}
    873 	KASSERT(i < regulator->nvoltages);
    874 	tps65217pmic_reg_write_l2(sc, regulator->defreg_num, i);
    875 
    876 	val = tps65217pmic_reg_read(sc, TPS65217PMIC_DEFSLEW);
    877 	val |= TPS65217PMIC_DEFSLEW_GO;
    878 	tps65217pmic_reg_write_l2(sc, TPS65217PMIC_DEFSLEW, val);
    879 
    880 	while (val & TPS65217PMIC_DEFSLEW_GO) {
    881 		val = tps65217pmic_reg_read(sc, TPS65217PMIC_DEFSLEW);
    882 	}
    883 
    884 	regulator->current_voltage = regulator->voltages[i];
    885 
    886 	return 0;
    887 }
    888 
    889 #ifdef FDT
    890 static struct tps_reg_param *
    891 tps65217pmic_get_params(const char *name)
    892 {
    893 	int i;
    894 
    895 	for (i = 0; i < __arraycount(tps_regulators); i++) {
    896 		if (strcmp(name, tps_regulators[i].name) == 0)
    897 			return &tps_regulators[i];
    898 	}
    899 
    900 	return NULL;
    901 }
    902 
    903 static void
    904 tps65217pmic_regulator_attach(struct tps65217pmic_softc *sc)
    905 {
    906 	struct tps65217reg_attach_args raa;
    907 	struct tps_reg_param *param;
    908 	const char *compat_name;
    909 	int phandle, child;
    910 
    911 	phandle = of_find_firstchild_byname(sc->sc_phandle, "regulators");
    912 	if (phandle <= 0)
    913 		return;
    914 
    915 	for (child = OF_child(phandle); child; child = OF_peer(child)) {
    916 		compat_name = fdtbus_get_string(child, "regulator-compatible");
    917 		if (compat_name == NULL)
    918 			continue;
    919 		param = tps65217pmic_get_params(compat_name);
    920 		if (param == NULL)
    921 			continue;
    922 
    923 		raa.reg_param = param;
    924 		raa.reg_phandle = child;
    925 		config_found(sc->sc_dev, &raa, NULL);
    926 	}
    927 }
    928 
    929 static int
    930 tps65217reg_acquire(device_t dev)
    931 {
    932 	return 0;
    933 }
    934 
    935 static void
    936 tps65217reg_release(device_t dev)
    937 {
    938 }
    939 
    940 static int
    941 tps65217reg_enable(device_t dev, bool enable)
    942 {
    943 	struct tps65217reg_softc *sc = device_private(dev);
    944 	struct tps65217pmic_softc *pmic_sc = device_private(device_parent(dev));
    945 	struct tps_reg_param *regulator = sc->sc_param;
    946 	uint8_t val;
    947 	int error;
    948 
    949 	error = iic_acquire_bus(pmic_sc->sc_tag, I2C_F_POLL);
    950 	if (error != 0)
    951 		return error;
    952 
    953 	val = tps65217pmic_reg_read(pmic_sc, TPS65217PMIC_ENABLE);
    954 	if (enable)
    955 		val |= regulator->enable_bit;
    956 	else
    957 		val &= ~regulator->enable_bit;
    958 	tps65217pmic_reg_write(pmic_sc, TPS65217PMIC_ENABLE, val);
    959 
    960 	regulator->is_enabled = enable;
    961 
    962 	iic_release_bus(pmic_sc->sc_tag, I2C_F_POLL);
    963 
    964 	return 0;
    965 }
    966 
    967 static int
    968 tps65217reg_set_voltage(device_t dev, u_int min_uvol, u_int max_uvol)
    969 {
    970 	struct tps65217reg_softc *sc = device_private(dev);
    971 	struct tps65217pmic_softc *pmic_sc = device_private(device_parent(dev));
    972 	struct tps_reg_param *regulator = sc->sc_param;
    973 	int error;
    974 
    975 	error = iic_acquire_bus(pmic_sc->sc_tag, I2C_F_POLL);
    976 	if (error != 0)
    977 		return error;
    978 
    979 	error = tps65217pmic_set_volt(pmic_sc->sc_dev, regulator->name, min_uvol / 1000);
    980 
    981 	iic_release_bus(pmic_sc->sc_tag, I2C_F_POLL);
    982 
    983 	return error;
    984 }
    985 
    986 static int
    987 tps65217reg_get_voltage(device_t dev, u_int *puvol)
    988 {
    989 	struct tps65217reg_softc *sc = device_private(dev);
    990 	struct tps_reg_param *regulator = sc->sc_param;
    991 
    992 	*puvol = (u_int)regulator->current_voltage * 1000;
    993 
    994 	return 0;
    995 }
    996 
    997 static struct fdtbus_regulator_controller_func tps65217reg_funcs = {
    998 	.acquire = tps65217reg_acquire,
    999 	.release = tps65217reg_release,
   1000 	.enable = tps65217reg_enable,
   1001 	.set_voltage = tps65217reg_set_voltage,
   1002 	.get_voltage = tps65217reg_get_voltage,
   1003 };
   1004 
   1005 static int
   1006 tps65217reg_match(device_t parent, cfdata_t match, void *aux)
   1007 {
   1008 	return 1;
   1009 }
   1010 
   1011 static void
   1012 tps65217reg_attach(device_t parent, device_t self, void *aux)
   1013 {
   1014 	struct tps65217reg_softc *sc = device_private(self);
   1015 	struct tps65217reg_attach_args *raa = aux;
   1016 	const char *regname;
   1017 
   1018 	sc->sc_dev = self;
   1019 	sc->sc_phandle = raa->reg_phandle;
   1020 	sc->sc_param = raa->reg_param;
   1021 
   1022 	fdtbus_register_regulator_controller(self, sc->sc_phandle,
   1023 	    &tps65217reg_funcs);
   1024 
   1025 	regname = fdtbus_get_string(sc->sc_phandle, "regulator-name");
   1026 	if (regname == NULL)
   1027 		regname = fdtbus_get_string(sc->sc_phandle, "regulator-compatible");
   1028 
   1029 	aprint_naive("\n");
   1030 	if (regname != NULL)
   1031 		aprint_normal(": %s\n", regname);
   1032 	else
   1033 		aprint_normal("\n");
   1034 }
   1035 
   1036 CFATTACH_DECL_NEW(tps65217reg, sizeof (struct tps65217reg_softc),
   1037     tps65217reg_match, tps65217reg_attach, NULL, NULL);
   1038 
   1039 #endif
   1040