Home | History | Annotate | Line # | Download | only in i2c
      1 /*	$NetBSD: tps65217pmic.c,v 1.21 2025/09/17 13:49:13 thorpej 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.21 2025/09/17 13:49:13 thorpej 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 static int tps65217pmic_match(device_t, cfdata_t, void *);
    152 static void tps65217pmic_attach(device_t, device_t, void *);
    153 
    154 static int tps65217pmic_i2c_lock(struct tps65217pmic_softc *);
    155 static void tps65217pmic_i2c_unlock(struct tps65217pmic_softc *);
    156 
    157 static uint8_t tps65217pmic_reg_read(struct tps65217pmic_softc *, uint8_t);
    158 static void tps65217pmic_reg_write(struct tps65217pmic_softc *, uint8_t,
    159     uint8_t);
    160 
    161 static void tps65217pmic_reg_refresh(struct tps65217pmic_softc *);
    162 
    163 static uint16_t tps65217pmic_ppath_max_usb_current(uint8_t);
    164 static uint16_t tps65217pmic_ppath_max_ac_current(uint8_t);
    165 
    166 static void tps65217pmic_regulator_read_config(struct tps65217pmic_softc *,
    167     struct tps_reg_param *);
    168 
    169 static void tps65217pmic_print_ppath(struct tps65217pmic_softc *);
    170 static void tps65217pmic_print_ldos(struct tps65217pmic_softc *);
    171 
    172 static void tps65217pmic_version(struct tps65217pmic_softc *);
    173 
    174 static void tps65217pmic_envsys_register(struct tps65217pmic_softc *);
    175 static void tps65217pmic_envsys_refresh(struct sysmon_envsys *, envsys_data_t *);
    176 
    177 static void tps65217pmic_power_monitor_init(struct tps65217pmic_softc *);
    178 static void tps65217pmic_power_monitor(void *);
    179 
    180 static void tps65217pmic_wled_init(struct tps65217pmic_softc *, int, int, int);
    181 
    182 CFATTACH_DECL_NEW(tps65217pmic, sizeof (struct tps65217pmic_softc),
    183     tps65217pmic_match, tps65217pmic_attach, NULL, NULL);
    184 
    185 #ifdef FDT
    186 static void tps65217pmic_regulator_attach(struct tps65217pmic_softc *);
    187 #endif
    188 
    189 /* Possible settings of LDO1 in mV. */
    190 static const uint16_t ldo1voltages[] = { 1000, 1100, 1200, 1250, 1300, 1350,
    191     1400, 1500, 1600, 1800, 2500, 2750, 2800, 3000, 3100, 3300 };
    192 /* Possible settings of LDO2, DCDC1, DCDC2, DCDC3 in mV. */
    193 static const uint16_t ldo2voltages[] = { 900, 925, 950, 975, 1000, 1025, 1050,
    194     1075, 1100, 1125, 1150, 1175, 1200, 1225, 1250, 1275, 1300, 1325, 1350,
    195     1375, 1400, 1425, 1450, 1475, 1500, 1550, 1600, 1650, 1700, 1750, 1800,
    196     1850, 1900, 1950, 2000, 2050, 2100, 2150, 2200, 2250, 2300, 2350, 2400,
    197     2450, 2500, 2550, 2600, 2650, 2700, 2750, 2800, 2850, 2900, 3000, 3100,
    198     3200, 3300, 3300, 3300, 3300, 3300, 3300, 3300, 3300 };
    199 /* Possible settings of LDO3, LDO4 in mV. */
    200 static const uint16_t ldo3voltages[] = { 1500, 1550, 1600, 1650, 1700, 1750,
    201     1800, 1850, 1900, 2000, 2100, 2200, 2300, 2400, 2450, 2500, 2550, 2600,
    202     2650, 2700, 2750, 2800, 2850, 2900,2950, 3000, 3050, 3100, 3150, 3200,
    203     3250, 3300 };
    204 
    205 static struct tps_reg_param tps_regulators[] = {
    206 	{
    207 		.name = "ldo1",
    208 		.voltage_min = 1000,
    209 		.voltage_max = 3300,
    210 		.voltages = ldo1voltages,
    211 		.nvoltages = 16,
    212 		.can_track = false,
    213 		.tracked_reg = NULL,
    214 		.can_xadj =  false,
    215 		.can_ls = false,
    216 		.defreg_num = TPS65217PMIC_DEFLDO1,
    217 		.enable_bit = TPS65217PMIC_ENABLE_LDO1
    218 	},
    219 	{
    220 		.name = "ldo2",
    221 		.voltage_min = 900,
    222 		.voltage_max = 3300,
    223 		.voltages = ldo2voltages,
    224 		.nvoltages = 64,
    225 		.can_track = true,
    226 		.tracked_reg = &(tps_regulators[TPS65217PMIC_DCDC3]),
    227 		.can_xadj = false,
    228 		.can_ls = false,
    229 		.defreg_num = TPS65217PMIC_DEFLDO2,
    230 		.enable_bit = TPS65217PMIC_ENABLE_LDO2
    231 	},
    232 	{
    233 		.name = "ldo3",
    234 		.voltage_min = 1500,
    235 		.voltage_max = 3300,
    236 		.voltages = ldo3voltages,
    237 		.nvoltages = 32,
    238 		.can_track = false,
    239 		.tracked_reg = NULL,
    240 		.can_xadj = false,
    241 		.can_ls = true,
    242 		.defreg_num = TPS65217PMIC_DEFLDO3,
    243 		.enable_bit = TPS65217PMIC_ENABLE_LDO3
    244 	},
    245 	{
    246 		.name = "ldo4",
    247 		.voltage_min = 1500,
    248 		.voltage_max = 3300,
    249 		.voltages = ldo3voltages,
    250 		.nvoltages = 32,
    251 		.can_track = false,
    252 		.tracked_reg = NULL,
    253 		.can_xadj = false,
    254 		.can_ls = true,
    255 		.defreg_num = TPS65217PMIC_DEFLDO4,
    256 		.enable_bit = TPS65217PMIC_ENABLE_LDO4
    257 	},
    258 	{
    259 		.name = "dcdc1",
    260 		.voltage_min = 900,
    261 		.voltage_max = 3300,
    262 		.voltages = ldo2voltages,
    263 		.nvoltages = 64,
    264 		.can_track = false,
    265 		.tracked_reg = NULL,
    266 		.can_xadj = true,
    267 		.can_ls = false,
    268 		.defreg_num = TPS65217PMIC_DEFDCDC1,
    269 		.enable_bit = TPS65217PMIC_ENABLE_DCDC1
    270 	},
    271 	{
    272 		.name = "dcdc2",
    273 		.voltage_min = 900,
    274 		.voltage_max = 3300,
    275 		.voltages = ldo2voltages,
    276 		.nvoltages = 64,
    277 		.can_track = false,
    278 		.tracked_reg = NULL,
    279 		.can_xadj = true,
    280 		.can_ls = false,
    281 		.defreg_num = TPS65217PMIC_DEFDCDC2,
    282 		.enable_bit = TPS65217PMIC_ENABLE_DCDC2
    283 	},
    284 	{
    285 		.name = "dcdc3",
    286 		.voltage_min = 900,
    287 		.voltage_max = 3300,
    288 		.voltages = ldo2voltages,
    289 		.nvoltages = 64,
    290 		.can_track = false,
    291 		.tracked_reg = NULL,
    292 		.can_xadj = true,
    293 		.can_ls = false,
    294 		.defreg_num = TPS65217PMIC_DEFDCDC3,
    295 		.enable_bit = TPS65217PMIC_ENABLE_DCDC3
    296 	}
    297 };
    298 
    299 static bool matched = false;
    300 
    301 static const struct device_compatible_entry compat_data[] = {
    302 	{ .compat = "ti,tps65217" },
    303 	DEVICE_COMPAT_EOL
    304 };
    305 
    306 static int
    307 tps65217pmic_match(device_t parent, cfdata_t cf, void *aux)
    308 {
    309 	struct i2c_attach_args *ia = aux;
    310 	int match_result;
    311 
    312 	if (iic_use_direct_match(ia, cf, compat_data, &match_result))
    313 		return match_result;
    314 
    315 	if (ia->ia_addr == TPS65217PMIC_ADDR) {
    316 		/* we can only have one */
    317 		if (matched)
    318 			return 0;
    319 
    320 		return I2C_MATCH_ADDRESS_ONLY;
    321 	}
    322 	return 0;
    323 }
    324 
    325 static void
    326 tps65217pmic_attach(device_t parent, device_t self, void *aux)
    327 {
    328 	struct tps65217pmic_softc *sc = device_private(self);
    329 	struct i2c_attach_args *ia = aux;
    330 	prop_dictionary_t dict;
    331 	int isel, fdim, brightness;
    332 
    333 	/* XXXJRT But what if you have multiple i2c busses? */
    334 	matched = true;
    335 
    336 	sc->sc_dev = self;
    337 	sc->sc_addr = ia->ia_addr;
    338 	sc->sc_tag = ia->ia_tag;
    339 
    340 #ifdef FDT
    341 	if (devhandle_type(device_handle(self)) == DEVHANDLE_TYPE_OF) {
    342 		sc->sc_phandle = devhandle_to_of(device_handle(self));
    343 	}
    344 #endif
    345 
    346 	dict = device_properties(self);
    347 	if (prop_dictionary_get_int32(dict, "isel", &isel)) {
    348 		prop_dictionary_get_int32(dict, "fdim", &fdim);
    349 		prop_dictionary_get_int32(dict, "brightness", &brightness);
    350 	} else
    351 		isel = -1;
    352 
    353 	tps65217pmic_version(sc);
    354 
    355 	aprint_normal(": TPS65217");
    356 	switch (sc->sc_version) {
    357 	case TPS65217PMIC_CHIPID_VER_A:
    358 		aprint_normal("A");
    359 		break;
    360 	case TPS65217PMIC_CHIPID_VER_B:
    361 		aprint_normal("B");
    362 		break;
    363 	case TPS65217PMIC_CHIPID_VER_C:
    364 		aprint_normal("C");
    365 		break;
    366 	case TPS65217PMIC_CHIPID_VER_D:
    367 		aprint_normal("D");
    368 		break;
    369 	default:
    370 		/* unknown version */
    371 		break;
    372 	}
    373 
    374 	aprint_normal(" Power Management Multi-Channel IC (rev 1.%d)\n",
    375 	    sc->sc_revision);
    376 
    377 	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
    378 
    379 	sc->sc_smpsw.smpsw_name = device_xname(self);
    380 	sc->sc_smpsw.smpsw_type = PSWITCH_TYPE_ACADAPTER;
    381 	sysmon_pswitch_register(&sc->sc_smpsw);
    382 
    383 	tps65217pmic_reg_refresh(sc);
    384 
    385 	tps65217pmic_print_ppath(sc);
    386 	tps65217pmic_print_ldos(sc);
    387 
    388 	tps65217pmic_power_monitor_init(sc);
    389 
    390 	if (isel != -1)
    391 		tps65217pmic_wled_init(sc, isel, fdim, brightness);
    392 
    393 	tps65217pmic_envsys_register(sc);
    394 
    395 #ifdef FDT
    396 	tps65217pmic_regulator_attach(sc);
    397 #endif
    398 }
    399 
    400 static void
    401 tps65217pmic_power_monitor_init(struct tps65217pmic_softc *sc)
    402 {
    403 	uint8_t intr, intrmask, status, ppath;
    404 
    405 	intrmask = TPS65217PMIC_INT_USBM | TPS65217PMIC_INT_ACM |
    406 	    TPS65217PMIC_INT_PBM;
    407 
    408 	if (tps65217pmic_i2c_lock(sc) != 0) {
    409 		aprint_error_dev(sc->sc_dev,
    410 		    "failed to initialize power monitor\n");
    411 		return;
    412 	}
    413 
    414 	status = tps65217pmic_reg_read(sc, TPS65217PMIC_STATUS);
    415 	ppath = tps65217pmic_reg_read(sc, TPS65217PMIC_PPATH);
    416 	/* acknowledge and disregard whatever interrupt was generated earlier */
    417 	intr = tps65217pmic_reg_read(sc, TPS65217PMIC_INT);
    418 
    419 	tps65217pmic_i2c_unlock(sc);
    420 
    421 	sc->sc_usbstatus = status & TPS65217PMIC_STATUS_USBPWR;
    422 	sc->sc_acstatus = status & TPS65217PMIC_STATUS_ACPWR;
    423 	sc->sc_usbenabled = ppath & TPS65217PMIC_PPATH_USB_EN;
    424 	sc->sc_acenabled = ppath & TPS65217PMIC_PPATH_AC_EN;
    425 
    426 	if (intr & intrmask)
    427 		aprint_normal_dev(sc->sc_dev,
    428 		    "WARNING: hardware interrupt enabled but not supported");
    429 
    430 	/* set up callout to poll for power source changes */
    431 	callout_init(&sc->sc_powerpollco, 0);
    432 	callout_setfunc(&sc->sc_powerpollco, tps65217pmic_power_monitor, sc);
    433 
    434 	callout_schedule(&sc->sc_powerpollco, hz);
    435 }
    436 
    437 static void
    438 tps65217pmic_power_monitor_task(void *aux)
    439 {
    440 	struct tps65217pmic_softc *sc;
    441 	uint8_t status;
    442 	bool usbstatus, acstatus;
    443 
    444 	sc = aux;
    445 
    446 	mutex_enter(&sc->sc_lock);
    447 
    448 	if (tps65217pmic_i2c_lock(sc) != 0) {
    449 		device_printf(sc->sc_dev,
    450 		    "WARNING: unable to perform power monitor task.\n");
    451 		return;
    452 	}
    453 	status = tps65217pmic_reg_read(sc, TPS65217PMIC_STATUS);
    454 	tps65217pmic_i2c_unlock(sc);
    455 
    456 	usbstatus = status & TPS65217PMIC_STATUS_USBPWR;
    457 	acstatus = status & TPS65217PMIC_STATUS_ACPWR;
    458 
    459 	if (usbstatus != sc->sc_usbstatus) {
    460 		sc->sc_usbstatus = usbstatus;
    461 		pmf_event_inject(NULL, PMFE_POWER_CHANGED);
    462 		if (usbstatus)
    463 			aprint_normal_dev(sc->sc_dev,
    464 			    "USB power source connected\n");
    465 		else
    466 			aprint_normal_dev(sc->sc_dev,
    467 			    "USB power source disconnected\n");
    468 	}
    469 
    470 	if (acstatus != sc->sc_acstatus) {
    471 		sc->sc_acstatus = acstatus;
    472 		pmf_event_inject(NULL, PMFE_POWER_CHANGED);
    473 		if (acstatus) {
    474 			sysmon_pswitch_event(&sc->sc_smpsw,
    475 			    PSWITCH_EVENT_PRESSED);
    476 		} else {
    477 			sysmon_pswitch_event(&sc->sc_smpsw,
    478 			    PSWITCH_EVENT_RELEASED);
    479 		}
    480 	}
    481 
    482 	mutex_exit(&sc->sc_lock);
    483 
    484 	callout_schedule(&sc->sc_powerpollco, hz);
    485 }
    486 
    487 static void
    488 tps65217pmic_power_monitor(void *aux)
    489 {
    490 	sysmon_task_queue_sched(0, tps65217pmic_power_monitor_task, aux);
    491 }
    492 
    493 static void
    494 tps65217pmic_wled_init(struct tps65217pmic_softc *sc, int isel, int fdim,
    495 		       int brightness)
    496 {
    497 	uint8_t val = 0;
    498 
    499 	switch (isel) {
    500 	case 1:
    501 	case 2:
    502 		val |= ((isel - 1) << TPS65217PMIC_WLEDCTRL1_ISEL);
    503 		break;
    504 	default:
    505 		aprint_error_dev(sc->sc_dev,
    506 		    "WLED ISET selection is 1 or 2: isel %d\n", isel);
    507 		return;
    508 	}
    509 	switch (fdim) {
    510 	case 100:
    511 		val |= TPS65217PMIC_WLEDCTRL1_FDIM_100Hz;
    512 		break;
    513 	case 200:
    514 		val |= TPS65217PMIC_WLEDCTRL1_FDIM_200Hz;
    515 		break;
    516 	case 500:
    517 		val |= TPS65217PMIC_WLEDCTRL1_FDIM_500Hz;
    518 		break;
    519 	case 1000:
    520 		val |= TPS65217PMIC_WLEDCTRL1_FDIM_1000Hz;
    521 		break;
    522 	default:
    523 		aprint_error_dev(sc->sc_dev,
    524 		    "WLED PWM dimming frequency is 100, 200, 500 or 1000:"
    525 		    " fdim %d\n", fdim);
    526 		return;
    527 	}
    528 	if (brightness > 100 ||
    529 	    brightness < 0) {
    530 		aprint_error_dev(sc->sc_dev,
    531 		    "invalid brightness: between 0 and 100: %d\n", brightness);
    532 		return;
    533 	}
    534 
    535 	if (tps65217pmic_i2c_lock(sc) != 0) {
    536 		device_printf(sc->sc_dev,
    537 		    "WARNING: unable to configure LED\n");
    538 		return;
    539 	}
    540 
    541 	tps65217pmic_reg_write(sc, TPS65217PMIC_WLEDCTRL1, val);
    542 	tps65217pmic_reg_write(sc, TPS65217PMIC_WLEDCTRL2,
    543 	    (brightness - 1) & TPS65217PMIC_WLEDCTRL2_DUTY);
    544 	val |= TPS65217PMIC_WLEDCTRL1_ISINK_EN;
    545 	tps65217pmic_reg_write(sc, TPS65217PMIC_WLEDCTRL1, val);
    546 
    547 	tps65217pmic_i2c_unlock(sc);
    548 }
    549 
    550 static void
    551 tps65217pmic_reg_refresh(struct tps65217pmic_softc *sc)
    552 {
    553 	int i;
    554 	struct tps_reg_param *c_reg;
    555 
    556 	if (tps65217pmic_i2c_lock(sc) != 0) {
    557 		device_printf(sc->sc_dev,
    558 		    "WARNING: unable to refresh regulators\n");
    559 		return;
    560 	}
    561 
    562 	for (i = 0; i < NTPS_REG; i++) {
    563 		c_reg = &tps_regulators[i];
    564 		tps65217pmic_regulator_read_config(sc, c_reg);
    565 	}
    566 
    567 	tps65217pmic_i2c_unlock(sc);
    568 }
    569 
    570 /* Get version and revision of the chip. */
    571 static void
    572 tps65217pmic_version(struct tps65217pmic_softc *sc)
    573 {
    574 	uint8_t chipid;
    575 
    576 	if (tps65217pmic_i2c_lock(sc) != 0) {
    577 		device_printf(sc->sc_dev,
    578 		    "WARNING: unable to get chip ID\n");
    579 		return;
    580 	}
    581 
    582 	chipid = tps65217pmic_reg_read(sc, TPS65217PMIC_CHIPID);
    583 
    584 	tps65217pmic_i2c_unlock(sc);
    585 
    586 	sc->sc_version = chipid & TPS65217PMIC_CHIPID_VER_MASK;
    587 	sc->sc_revision = chipid & TPS65217PMIC_CHIPID_REV_MASK;
    588 }
    589 
    590 static uint16_t
    591 tps65217pmic_ppath_max_ac_current(uint8_t ppath)
    592 {
    593 	switch ((ppath & TPS65217PMIC_PPATH_IAC) >>
    594 	    TPS65217PMIC_PPATH_IAC_RSHFIT) {
    595 	case TPS65217PMIC_PPATH_IAC_100MA:
    596 		return 100;
    597 	case TPS65217PMIC_PPATH_IAC_500MA:
    598 		return 500;
    599 	case TPS65217PMIC_PPATH_IAC_1300MA:
    600 		return 1300;
    601 	case TPS65217PMIC_PPATH_IAC_2500MA:
    602 		return 2500;
    603 	}
    604 	return 0;
    605 }
    606 
    607 static uint16_t
    608 tps65217pmic_ppath_max_usb_current(uint8_t ppath)
    609 {
    610 	switch (ppath & TPS65217PMIC_PPATH_IUSB) {
    611 	case TPS65217PMIC_PPATH_IUSB_100MA:
    612 		return 100;
    613 	case TPS65217PMIC_PPATH_IUSB_500MA:
    614 		return 500;
    615 	case TPS65217PMIC_PPATH_IUSB_1300MA:
    616 		return 1300;
    617 	case TPS65217PMIC_PPATH_IUSB_1800MA:
    618 		return 1800;
    619 	}
    620 	return 0;
    621 }
    622 
    623 /* Read regulator state and save it to tps_reg_param. */
    624 static void
    625 tps65217pmic_regulator_read_config(struct tps65217pmic_softc *sc, struct
    626     tps_reg_param *regulator)
    627 {
    628 	uint8_t defreg, regenable;
    629 	uint16_t voltage;
    630 
    631 	regenable = tps65217pmic_reg_read(sc, TPS65217PMIC_ENABLE);
    632 
    633 	if (regenable & (regulator->enable_bit))
    634 		regulator->is_enabled = true;
    635 	else {
    636 		regulator->is_enabled = false;
    637 		return;
    638 	}
    639 
    640 	defreg = tps65217pmic_reg_read(sc,
    641 	    regulator->defreg_num);
    642 
    643 	switch (regulator->nvoltages) {
    644 	case 16:
    645 		voltage = regulator->voltages[defreg &
    646 		    TPS65217PMIC_DEFX_VOLTAGE_16];
    647 		break;
    648 	case 32:
    649 		voltage = regulator->voltages[defreg &
    650 		    TPS65217PMIC_DEFX_VOLTAGE_32];
    651 		break;
    652 	case 64:
    653 		voltage = regulator->voltages[defreg &
    654 		    TPS65217PMIC_DEFX_VOLTAGE_64];
    655 		break;
    656 	default:
    657 		/* unsupported number of voltage settings? */
    658 		voltage = 0;
    659 		break;
    660 	}
    661 
    662 	/* Handle regulator tracking other regulator voltage. */
    663 	if (regulator->can_track)
    664 		if (defreg & TPS65217PMIC_DEFX_TRACKING) {
    665 			regulator->is_tracking = true;
    666 			voltage = 0; /* see regulator->tracked_reg */
    667 		}
    668 
    669 	/* Handle regulator configured into load switch mode. */
    670 	if (regulator->can_ls)
    671 		if (!(defreg & TPS65217PMIC_DEFX_LS)) {
    672 			regulator->is_ls = true;
    673 			voltage = 0;
    674 		}
    675 
    676 	if (regulator->can_xadj)
    677 		if (defreg & TPS65217PMIC_DEFX_XADJ) {
    678 			regulator->is_xadj = true;
    679 			voltage = 0;
    680 
    681 		}
    682 
    683 	/* TODO: add PGOOD checking */
    684 
    685 	regulator->current_voltage = voltage;
    686 }
    687 
    688 static void
    689 tps65217pmic_print_ldos(struct tps65217pmic_softc *sc)
    690 {
    691 	int i;
    692 	struct tps_reg_param *c_reg;
    693 
    694 	aprint_normal_dev(sc->sc_dev, "");
    695 
    696 	for (i = 0; i < NTPS_REG; i++) {
    697 		c_reg = &tps_regulators[i];
    698 
    699 		if (c_reg->is_enabled) {
    700 			if (c_reg->is_ls)
    701 				aprint_normal("[%s: LS] ", c_reg->name);
    702 			else if (c_reg->is_xadj)
    703 				aprint_normal("[%s: XADJ] ", c_reg->name);
    704 			else
    705 				aprint_normal("[%s: %d mV] ", c_reg->name,
    706 				    c_reg->current_voltage);
    707 		}
    708 	}
    709 	aprint_normal("\n");
    710 }
    711 
    712 static void
    713 tps65217pmic_print_ppath(struct tps65217pmic_softc *sc)
    714 {
    715 	uint8_t status, ppath;
    716 
    717 	ppath = tps65217pmic_reg_read(sc, TPS65217PMIC_PPATH);
    718 	status = tps65217pmic_reg_read(sc, TPS65217PMIC_STATUS);
    719 
    720 	aprint_normal_dev(sc->sc_dev, "power sources ");
    721 
    722 	if (ppath & TPS65217PMIC_PPATH_USB_EN) {
    723 		if (status & TPS65217PMIC_STATUS_USBPWR)
    724 			aprint_normal("[USB] ");
    725 		else
    726 			aprint_normal("USB ");
    727 		aprint_normal("max %d mA, ",
    728 		    tps65217pmic_ppath_max_usb_current(ppath));
    729 	}
    730 
    731 	if (ppath & TPS65217PMIC_PPATH_AC_EN) {
    732 		if (status & TPS65217PMIC_STATUS_ACPWR)
    733 			aprint_normal("[AC] ");
    734 		else
    735 			aprint_normal("AC ");
    736 		aprint_normal("max %d mA",
    737 		    tps65217pmic_ppath_max_ac_current(ppath));
    738 	}
    739 
    740 	aprint_normal("\n");
    741 }
    742 
    743 static int
    744 tps65217pmic_i2c_lock(struct tps65217pmic_softc *sc)
    745 {
    746 	int error;
    747 
    748 	error = iic_acquire_bus(sc->sc_tag, 0);
    749 	if (error) {
    750 		device_printf(sc->sc_dev,
    751 		    "unable to acquire i2c bus, error %d\n", error);
    752 	}
    753 	return error;
    754 }
    755 
    756 static void
    757 tps65217pmic_i2c_unlock(struct tps65217pmic_softc *sc)
    758 {
    759 	iic_release_bus(sc->sc_tag, 0);
    760 }
    761 
    762 static uint8_t
    763 tps65217pmic_reg_read(struct tps65217pmic_softc *sc, uint8_t reg)
    764 {
    765 	uint8_t wbuf[2];
    766 	uint8_t rv;
    767 
    768 	wbuf[0] = reg;
    769 
    770 	if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr, wbuf,
    771 	    1, &rv, 1, 0)) {
    772 		aprint_error_dev(sc->sc_dev, "cannot execute operation\n");
    773 		iic_release_bus(sc->sc_tag, 0);
    774 		return 0;
    775 	}
    776 
    777 	return rv;
    778 }
    779 
    780 static void
    781 tps65217pmic_reg_write(struct tps65217pmic_softc *sc,
    782     uint8_t reg, uint8_t data)
    783 {
    784 	uint8_t wbuf[2];
    785 
    786 	wbuf[0] = reg;
    787 	wbuf[1] = data;
    788 
    789 	if (iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP, sc->sc_addr, NULL, 0,
    790 	    wbuf, 2, 0)) {
    791 		aprint_error_dev(sc->sc_dev, "cannot execute I2C write\n");
    792 	}
    793 }
    794 
    795 static void
    796 tps65217pmic_reg_write_l2(struct tps65217pmic_softc *sc,
    797     uint8_t reg, uint8_t data)
    798 {
    799 	uint8_t regpw = reg ^ TPS65217PMIC_PASSWORD_XOR;
    800 
    801 	if (tps65217pmic_i2c_lock(sc))
    802 		return;
    803 
    804 	tps65217pmic_reg_write(sc, TPS65217PMIC_PASSWORD, regpw);
    805 	tps65217pmic_reg_write(sc, reg, data);
    806 	tps65217pmic_reg_write(sc, TPS65217PMIC_PASSWORD, regpw);
    807 	tps65217pmic_reg_write(sc, reg, data);
    808 
    809 	tps65217pmic_i2c_unlock(sc);
    810 }
    811 
    812 static void
    813 tps65217pmic_envsys_register(struct tps65217pmic_softc *sc)
    814 {
    815 	int i;
    816 
    817 	sc->sc_sme = sysmon_envsys_create();
    818 
    819 	/* iterate over all regulators and attach them as sensors */
    820 	for(i = 0; i <= SNUM_REGS; i++) {
    821 		/* set name */
    822 		strlcpy(sc->sc_regsensor[i].desc, tps_regulators[i].name,
    823 		    sizeof(sc->sc_regsensor[i].desc));
    824 		sc->sc_regsensor[i].units = ENVSYS_SVOLTS_DC;
    825 		sc->sc_regsensor[i].state = ENVSYS_SINVALID;
    826 
    827 		if (sysmon_envsys_sensor_attach(sc->sc_sme,
    828 		    &sc->sc_regsensor[i]))
    829 			aprint_error_dev(sc->sc_dev,
    830 			    "error attaching regulator sensor %d\n", i);
    831 	}
    832 
    833 	/* attach power source indicators */
    834 	strcpy(sc->sc_usbsensor.desc, "USB power source"); /* SNUM_USBSTATUS */
    835 	sc->sc_usbsensor.units = ENVSYS_INDICATOR;
    836 	sc->sc_usbsensor.state = ENVSYS_SINVALID;
    837 	if (sysmon_envsys_sensor_attach(sc->sc_sme, &sc->sc_usbsensor))
    838 		aprint_error_dev(sc->sc_dev,
    839 		    "error attaching USB power source sensor\n");
    840 	strcpy(sc->sc_acsensor.desc, "AC power source"); /* SNUM_ACSTATUS */
    841 	sc->sc_acsensor.units = ENVSYS_INDICATOR;
    842 	sc->sc_acsensor.state = ENVSYS_SINVALID;
    843 	if (sysmon_envsys_sensor_attach(sc->sc_sme, &sc->sc_acsensor))
    844 		aprint_error_dev(sc->sc_dev,
    845 		    "error attaching AC power source sensor\n");
    846 
    847 	/* register everything in sysmon */
    848 	sc->sc_sme->sme_name = device_xname(sc->sc_dev);
    849 	sc->sc_sme->sme_cookie = sc;
    850 	sc->sc_sme->sme_refresh = tps65217pmic_envsys_refresh;
    851 
    852 	if (sysmon_envsys_register(sc->sc_sme)) {
    853 		aprint_error_dev(sc->sc_dev, "unable to register in sysmon\n");
    854 		sysmon_envsys_destroy(sc->sc_sme);
    855 	}
    856 }
    857 
    858 static void
    859 tps65217pmic_envsys_refresh(struct sysmon_envsys *sme, envsys_data_t *edata)
    860 {
    861 	struct tps65217pmic_softc *sc = sme->sme_cookie;
    862 
    863 	mutex_enter(&sc->sc_lock);
    864 
    865 	tps65217pmic_reg_refresh(sc);
    866 
    867 	if (edata->sensor <= SNUM_REGS) {
    868 		/* TODO: handle special cases like LS, XADJ... */
    869 		edata->value_cur = tps_regulators[edata->sensor].current_voltage * 1000;
    870 		edata->state = ENVSYS_SVALID;
    871 	} else if (edata->sensor == SNUM_USBSTATUS) {
    872 		edata->value_cur = sc->sc_usbstatus && sc->sc_usbenabled;
    873 		edata->state = ENVSYS_SVALID;
    874 	} else if (edata->sensor == SNUM_ACSTATUS) {
    875 		edata->value_cur = sc->sc_acstatus && sc->sc_acenabled;
    876 		edata->state = ENVSYS_SVALID;
    877 	} else
    878 		aprint_error_dev(sc->sc_dev, "unknown sensor number\n");
    879 
    880 	mutex_exit(&sc->sc_lock);
    881 }
    882 
    883 int
    884 tps65217pmic_set_volt(device_t self, const char *name, int mvolt)
    885 {
    886 	int i;
    887 	struct tps65217pmic_softc *sc = device_private(self);
    888 	struct tps_reg_param *regulator = NULL;
    889 	uint8_t val;
    890 
    891 	for (i = 0; i < __arraycount(tps_regulators); i++) {
    892 		if (strcmp(name, tps_regulators[i].name) == 0) {
    893 			regulator = &tps_regulators[i];
    894 			break;
    895 		}
    896 	}
    897 	if (regulator == NULL)
    898 		return EINVAL;
    899 
    900 	if (regulator->voltage_min > mvolt || regulator->voltage_max < mvolt)
    901 		return EINVAL;
    902 
    903 	if (!regulator->is_enabled)
    904 		return EINVAL;
    905 
    906 	if (regulator->is_tracking)
    907 		return EINVAL;
    908 
    909 	if (regulator->is_xadj)
    910 		return EINVAL;
    911 
    912 	/* find closest voltage entry */
    913 	for (i = 0; i < regulator->nvoltages; i++) {
    914 		if (mvolt <= regulator->voltages[i]) {
    915 			break;
    916 		}
    917 	}
    918 	KASSERT(i < regulator->nvoltages);
    919 	tps65217pmic_reg_write_l2(sc, regulator->defreg_num, i);
    920 
    921 	val = tps65217pmic_reg_read(sc, TPS65217PMIC_DEFSLEW);
    922 	val |= TPS65217PMIC_DEFSLEW_GO;
    923 	tps65217pmic_reg_write_l2(sc, TPS65217PMIC_DEFSLEW, val);
    924 
    925 	while (val & TPS65217PMIC_DEFSLEW_GO) {
    926 		val = tps65217pmic_reg_read(sc, TPS65217PMIC_DEFSLEW);
    927 	}
    928 
    929 	regulator->current_voltage = regulator->voltages[i];
    930 
    931 	return 0;
    932 }
    933 
    934 #ifdef FDT
    935 static struct tps_reg_param *
    936 tps65217pmic_get_params(const char *name)
    937 {
    938 	int i;
    939 
    940 	for (i = 0; i < __arraycount(tps_regulators); i++) {
    941 		if (strcmp(name, tps_regulators[i].name) == 0)
    942 			return &tps_regulators[i];
    943 	}
    944 
    945 	return NULL;
    946 }
    947 
    948 static void
    949 tps65217pmic_regulator_attach(struct tps65217pmic_softc *sc)
    950 {
    951 	struct tps65217reg_attach_args raa;
    952 	struct tps_reg_param *param;
    953 	const char *compat_name;
    954 	int phandle, child;
    955 
    956 	phandle = of_find_firstchild_byname(sc->sc_phandle, "regulators");
    957 	if (phandle <= 0)
    958 		return;
    959 
    960 	for (child = OF_child(phandle); child; child = OF_peer(child)) {
    961 		compat_name = fdtbus_get_string(child, "regulator-compatible");
    962 		if (compat_name == NULL)
    963 			continue;
    964 		param = tps65217pmic_get_params(compat_name);
    965 		if (param == NULL)
    966 			continue;
    967 
    968 		raa.reg_param = param;
    969 		raa.reg_phandle = child;
    970 		config_found(sc->sc_dev, &raa, NULL, CFARGS_NONE);
    971 	}
    972 }
    973 
    974 static int
    975 tps65217reg_acquire(device_t dev)
    976 {
    977 	return 0;
    978 }
    979 
    980 static void
    981 tps65217reg_release(device_t dev)
    982 {
    983 }
    984 
    985 static int
    986 tps65217reg_enable(device_t dev, bool enable)
    987 {
    988 	struct tps65217reg_softc *sc = device_private(dev);
    989 	struct tps65217pmic_softc *pmic_sc = device_private(device_parent(dev));
    990 	struct tps_reg_param *regulator = sc->sc_param;
    991 	uint8_t val;
    992 	int error;
    993 
    994 	error = tps65217pmic_i2c_lock(pmic_sc);
    995 	if (error != 0)
    996 		return error;
    997 
    998 	val = tps65217pmic_reg_read(pmic_sc, TPS65217PMIC_ENABLE);
    999 	if (enable)
   1000 		val |= regulator->enable_bit;
   1001 	else
   1002 		val &= ~regulator->enable_bit;
   1003 	tps65217pmic_reg_write(pmic_sc, TPS65217PMIC_ENABLE, val);
   1004 
   1005 	regulator->is_enabled = enable;
   1006 
   1007 	tps65217pmic_i2c_unlock(pmic_sc);
   1008 
   1009 	return 0;
   1010 }
   1011 
   1012 static int
   1013 tps65217reg_set_voltage(device_t dev, u_int min_uvol, u_int max_uvol)
   1014 {
   1015 	struct tps65217reg_softc *sc = device_private(dev);
   1016 	struct tps65217pmic_softc *pmic_sc = device_private(device_parent(dev));
   1017 	struct tps_reg_param *regulator = sc->sc_param;
   1018 	int error;
   1019 
   1020 	error = tps65217pmic_i2c_lock(pmic_sc);
   1021 	if (error != 0)
   1022 		return error;
   1023 
   1024 	error = tps65217pmic_set_volt(pmic_sc->sc_dev, regulator->name, min_uvol / 1000);
   1025 
   1026 	tps65217pmic_i2c_unlock(pmic_sc);
   1027 
   1028 	return error;
   1029 }
   1030 
   1031 static int
   1032 tps65217reg_get_voltage(device_t dev, u_int *puvol)
   1033 {
   1034 	struct tps65217reg_softc *sc = device_private(dev);
   1035 	struct tps_reg_param *regulator = sc->sc_param;
   1036 
   1037 	*puvol = (u_int)regulator->current_voltage * 1000;
   1038 
   1039 	return 0;
   1040 }
   1041 
   1042 static struct fdtbus_regulator_controller_func tps65217reg_funcs = {
   1043 	.acquire = tps65217reg_acquire,
   1044 	.release = tps65217reg_release,
   1045 	.enable = tps65217reg_enable,
   1046 	.set_voltage = tps65217reg_set_voltage,
   1047 	.get_voltage = tps65217reg_get_voltage,
   1048 };
   1049 
   1050 static int
   1051 tps65217reg_match(device_t parent, cfdata_t match, void *aux)
   1052 {
   1053 	return 1;
   1054 }
   1055 
   1056 static void
   1057 tps65217reg_attach(device_t parent, device_t self, void *aux)
   1058 {
   1059 	struct tps65217reg_softc *sc = device_private(self);
   1060 	struct tps65217reg_attach_args *raa = aux;
   1061 	const char *regname;
   1062 
   1063 	sc->sc_dev = self;
   1064 	sc->sc_phandle = raa->reg_phandle;
   1065 	sc->sc_param = raa->reg_param;
   1066 
   1067 	fdtbus_register_regulator_controller(self, sc->sc_phandle,
   1068 	    &tps65217reg_funcs);
   1069 
   1070 	regname = fdtbus_get_string(sc->sc_phandle, "regulator-name");
   1071 	if (regname == NULL)
   1072 		regname = fdtbus_get_string(sc->sc_phandle, "regulator-compatible");
   1073 
   1074 	aprint_naive("\n");
   1075 	if (regname != NULL)
   1076 		aprint_normal(": %s\n", regname);
   1077 	else
   1078 		aprint_normal("\n");
   1079 }
   1080 
   1081 CFATTACH_DECL_NEW(tps65217reg, sizeof (struct tps65217reg_softc),
   1082     tps65217reg_match, tps65217reg_attach, NULL, NULL);
   1083 
   1084 #endif
   1085