Home | History | Annotate | Line # | Download | only in i2c
tps65217pmic.c revision 1.15
      1 /*	$NetBSD: tps65217pmic.c,v 1.15 2019/12/23 21:24:59 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.15 2019/12/23 21:24:59 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 	{ "ti,tps65217",			0 },
    303 	{ NULL }
    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_phandle = ia->ia_cookie;
    339 	sc->sc_tag = ia->ia_tag;
    340 
    341 	dict = device_properties(self);
    342 	if (prop_dictionary_get_int32(dict, "isel", &isel)) {
    343 		prop_dictionary_get_int32(dict, "fdim", &fdim);
    344 		prop_dictionary_get_int32(dict, "brightness", &brightness);
    345 	} else
    346 		isel = -1;
    347 
    348 	tps65217pmic_version(sc);
    349 
    350 	aprint_normal(": TPS65217");
    351 	switch (sc->sc_version) {
    352 	case TPS65217PMIC_CHIPID_VER_A:
    353 		aprint_normal("A");
    354 		break;
    355 	case TPS65217PMIC_CHIPID_VER_B:
    356 		aprint_normal("B");
    357 		break;
    358 	case TPS65217PMIC_CHIPID_VER_C:
    359 		aprint_normal("C");
    360 		break;
    361 	case TPS65217PMIC_CHIPID_VER_D:
    362 		aprint_normal("D");
    363 		break;
    364 	default:
    365 		/* unknown version */
    366 		break;
    367 	}
    368 
    369 	aprint_normal(" Power Management Multi-Channel IC (rev 1.%d)\n",
    370 	    sc->sc_revision);
    371 
    372 	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
    373 
    374 	sc->sc_smpsw.smpsw_name = device_xname(self);
    375 	sc->sc_smpsw.smpsw_type = PSWITCH_TYPE_ACADAPTER;
    376 	sysmon_pswitch_register(&sc->sc_smpsw);
    377 
    378 	tps65217pmic_reg_refresh(sc);
    379 
    380 	tps65217pmic_print_ppath(sc);
    381 	tps65217pmic_print_ldos(sc);
    382 
    383 	tps65217pmic_power_monitor_init(sc);
    384 
    385 	if (isel != -1)
    386 		tps65217pmic_wled_init(sc, isel, fdim, brightness);
    387 
    388 	tps65217pmic_envsys_register(sc);
    389 
    390 #ifdef FDT
    391 	tps65217pmic_regulator_attach(sc);
    392 #endif
    393 }
    394 
    395 static void
    396 tps65217pmic_power_monitor_init(struct tps65217pmic_softc *sc)
    397 {
    398 	uint8_t intr, intrmask, status, ppath;
    399 
    400 	intrmask = TPS65217PMIC_INT_USBM | TPS65217PMIC_INT_ACM |
    401 	    TPS65217PMIC_INT_PBM;
    402 
    403 	if (tps65217pmic_i2c_lock(sc) != 0) {
    404 		aprint_error_dev(sc->sc_dev,
    405 		    "failed to initialize power monitor\n");
    406 		return;
    407 	}
    408 
    409 	status = tps65217pmic_reg_read(sc, TPS65217PMIC_STATUS);
    410 	ppath = tps65217pmic_reg_read(sc, TPS65217PMIC_PPATH);
    411 	/* acknowledge and disregard whatever interrupt was generated earlier */
    412 	intr = tps65217pmic_reg_read(sc, TPS65217PMIC_INT);
    413 
    414 	tps65217pmic_i2c_unlock(sc);
    415 
    416 	sc->sc_usbstatus = status & TPS65217PMIC_STATUS_USBPWR;
    417 	sc->sc_acstatus = status & TPS65217PMIC_STATUS_ACPWR;
    418 	sc->sc_usbenabled = ppath & TPS65217PMIC_PPATH_USB_EN;
    419 	sc->sc_acenabled = ppath & TPS65217PMIC_PPATH_AC_EN;
    420 
    421 	if (intr & intrmask)
    422 		aprint_normal_dev(sc->sc_dev,
    423 		    "WARNING: hardware interrupt enabled but not supported");
    424 
    425 	/* set up callout to poll for power source changes */
    426 	callout_init(&sc->sc_powerpollco, 0);
    427 	callout_setfunc(&sc->sc_powerpollco, tps65217pmic_power_monitor, sc);
    428 
    429 	callout_schedule(&sc->sc_powerpollco, hz);
    430 }
    431 
    432 static void
    433 tps65217pmic_power_monitor_task(void *aux)
    434 {
    435 	struct tps65217pmic_softc *sc;
    436 	uint8_t status;
    437 	bool usbstatus, acstatus;
    438 
    439 	sc = aux;
    440 
    441 	mutex_enter(&sc->sc_lock);
    442 
    443 	if (tps65217pmic_i2c_lock(sc) != 0) {
    444 		device_printf(sc->sc_dev,
    445 		    "WARNING: unable to perform power monitor task.\n");
    446 		return;
    447 	}
    448 	status = tps65217pmic_reg_read(sc, TPS65217PMIC_STATUS);
    449 	tps65217pmic_i2c_unlock(sc);
    450 
    451 	usbstatus = status & TPS65217PMIC_STATUS_USBPWR;
    452 	acstatus = status & TPS65217PMIC_STATUS_ACPWR;
    453 
    454 	if (usbstatus != sc->sc_usbstatus) {
    455 		sc->sc_usbstatus = usbstatus;
    456 		pmf_event_inject(NULL, PMFE_POWER_CHANGED);
    457 		if (usbstatus)
    458 			aprint_normal_dev(sc->sc_dev,
    459 			    "USB power source connected\n");
    460 		else
    461 			aprint_normal_dev(sc->sc_dev,
    462 			    "USB power source disconnected\n");
    463 	}
    464 
    465 	if (acstatus != sc->sc_acstatus) {
    466 		sc->sc_acstatus = acstatus;
    467 		pmf_event_inject(NULL, PMFE_POWER_CHANGED);
    468 		if (acstatus) {
    469 			sysmon_pswitch_event(&sc->sc_smpsw,
    470 			    PSWITCH_EVENT_PRESSED);
    471 		} else {
    472 			sysmon_pswitch_event(&sc->sc_smpsw,
    473 			    PSWITCH_EVENT_RELEASED);
    474 		}
    475 	}
    476 
    477 	mutex_exit(&sc->sc_lock);
    478 
    479 	callout_schedule(&sc->sc_powerpollco, hz);
    480 }
    481 
    482 static void
    483 tps65217pmic_power_monitor(void *aux)
    484 {
    485 	sysmon_task_queue_sched(0, tps65217pmic_power_monitor_task, aux);
    486 }
    487 
    488 static void
    489 tps65217pmic_wled_init(struct tps65217pmic_softc *sc, int isel, int fdim,
    490 		       int brightness)
    491 {
    492 	uint8_t val = 0;
    493 
    494 	switch (isel) {
    495 	case 1:
    496 	case 2:
    497 		val |= ((isel - 1) << TPS65217PMIC_WLEDCTRL1_ISEL);
    498 		break;
    499 	default:
    500 		aprint_error_dev(sc->sc_dev,
    501 		    "WLED ISET selection is 1 or 2: isel %d\n", isel);
    502 		return;
    503 	}
    504 	switch (fdim) {
    505 	case 100:
    506 		val |= TPS65217PMIC_WLEDCTRL1_FDIM_100Hz;
    507 		break;
    508 	case 200:
    509 		val |= TPS65217PMIC_WLEDCTRL1_FDIM_200Hz;
    510 		break;
    511 	case 500:
    512 		val |= TPS65217PMIC_WLEDCTRL1_FDIM_500Hz;
    513 		break;
    514 	case 1000:
    515 		val |= TPS65217PMIC_WLEDCTRL1_FDIM_1000Hz;
    516 		break;
    517 	default:
    518 		aprint_error_dev(sc->sc_dev,
    519 		    "WLED PWM dimming frequency is 100, 200, 500 or 1000:"
    520 		    " fdim %d\n", fdim);
    521 		return;
    522 	}
    523 	if (brightness > 100 ||
    524 	    brightness < 0) {
    525 		aprint_error_dev(sc->sc_dev,
    526 		    "invalid brightness: between 0 and 100: %d\n", brightness);
    527 		return;
    528 	}
    529 
    530 	if (tps65217pmic_i2c_lock(sc) != 0) {
    531 		device_printf(sc->sc_dev,
    532 		    "WARNING: unable to configure LED\n");
    533 		return;
    534 	}
    535 
    536 	tps65217pmic_reg_write(sc, TPS65217PMIC_WLEDCTRL1, val);
    537 	tps65217pmic_reg_write(sc, TPS65217PMIC_WLEDCTRL2,
    538 	    (brightness - 1) & TPS65217PMIC_WLEDCTRL2_DUTY);
    539 	val |= TPS65217PMIC_WLEDCTRL1_ISINK_EN;
    540 	tps65217pmic_reg_write(sc, TPS65217PMIC_WLEDCTRL1, val);
    541 
    542 	tps65217pmic_i2c_unlock(sc);
    543 }
    544 
    545 static void
    546 tps65217pmic_reg_refresh(struct tps65217pmic_softc *sc)
    547 {
    548 	int i;
    549 	struct tps_reg_param *c_reg;
    550 
    551 	if (tps65217pmic_i2c_lock(sc) != 0) {
    552 		device_printf(sc->sc_dev,
    553 		    "WARNING: unable to refresh regulators\n");
    554 		return;
    555 	}
    556 
    557 	for (i = 0; i < NTPS_REG; i++) {
    558 		c_reg = &tps_regulators[i];
    559 		tps65217pmic_regulator_read_config(sc, c_reg);
    560 	}
    561 
    562 	tps65217pmic_i2c_unlock(sc);
    563 }
    564 
    565 /* Get version and revision of the chip. */
    566 static void
    567 tps65217pmic_version(struct tps65217pmic_softc *sc)
    568 {
    569 	uint8_t chipid;
    570 
    571 	if (tps65217pmic_i2c_lock(sc) != 0) {
    572 		device_printf(sc->sc_dev,
    573 		    "WARNING: unable to get chip ID\n");
    574 		return;
    575 	}
    576 
    577 	chipid = tps65217pmic_reg_read(sc, TPS65217PMIC_CHIPID);
    578 
    579 	tps65217pmic_i2c_unlock(sc);
    580 
    581 	sc->sc_version = chipid & TPS65217PMIC_CHIPID_VER_MASK;
    582 	sc->sc_revision = chipid & TPS65217PMIC_CHIPID_REV_MASK;
    583 }
    584 
    585 static uint16_t
    586 tps65217pmic_ppath_max_ac_current(uint8_t ppath)
    587 {
    588 	switch ((ppath & TPS65217PMIC_PPATH_IAC) >>
    589 	    TPS65217PMIC_PPATH_IAC_RSHFIT) {
    590 	case TPS65217PMIC_PPATH_IAC_100MA:
    591 		return 100;
    592 	case TPS65217PMIC_PPATH_IAC_500MA:
    593 		return 500;
    594 	case TPS65217PMIC_PPATH_IAC_1300MA:
    595 		return 1300;
    596 	case TPS65217PMIC_PPATH_IAC_2500MA:
    597 		return 2500;
    598 	}
    599 	return 0;
    600 }
    601 
    602 static uint16_t
    603 tps65217pmic_ppath_max_usb_current(uint8_t ppath)
    604 {
    605 	switch (ppath & TPS65217PMIC_PPATH_IUSB) {
    606 	case TPS65217PMIC_PPATH_IUSB_100MA:
    607 		return 100;
    608 	case TPS65217PMIC_PPATH_IUSB_500MA:
    609 		return 500;
    610 	case TPS65217PMIC_PPATH_IUSB_1300MA:
    611 		return 1300;
    612 	case TPS65217PMIC_PPATH_IUSB_1800MA:
    613 		return 1800;
    614 	}
    615 	return 0;
    616 }
    617 
    618 /* Read regulator state and save it to tps_reg_param. */
    619 static void
    620 tps65217pmic_regulator_read_config(struct tps65217pmic_softc *sc, struct
    621     tps_reg_param *regulator)
    622 {
    623 	uint8_t defreg, regenable;
    624 	uint16_t voltage;
    625 
    626 	regenable = tps65217pmic_reg_read(sc, TPS65217PMIC_ENABLE);
    627 
    628 	if (regenable & (regulator->enable_bit))
    629 		regulator->is_enabled = true;
    630 	else {
    631 		regulator->is_enabled = false;
    632 		return;
    633 	}
    634 
    635 	defreg = tps65217pmic_reg_read(sc,
    636 	    regulator->defreg_num);
    637 
    638 	switch (regulator->nvoltages) {
    639 	case 16:
    640 		voltage = regulator->voltages[defreg &
    641 		    TPS65217PMIC_DEFX_VOLTAGE_16];
    642 		break;
    643 	case 32:
    644 		voltage = regulator->voltages[defreg &
    645 		    TPS65217PMIC_DEFX_VOLTAGE_32];
    646 		break;
    647 	case 64:
    648 		voltage = regulator->voltages[defreg &
    649 		    TPS65217PMIC_DEFX_VOLTAGE_64];
    650 		break;
    651 	default:
    652 		/* unsupported number of voltage settings? */
    653 		voltage = 0;
    654 		break;
    655 	}
    656 
    657 	/* Handle regulator tracking other regulator voltage. */
    658 	if (regulator->can_track)
    659 		if (defreg & TPS65217PMIC_DEFX_TRACKING) {
    660 			regulator->is_tracking = true;
    661 			voltage = 0; /* see regulator->tracked_reg */
    662 		}
    663 
    664 	/* Handle regulator configured into load switch mode. */
    665 	if (regulator->can_ls)
    666 		if (!(defreg & TPS65217PMIC_DEFX_LS)) {
    667 			regulator->is_ls = true;
    668 			voltage = 0;
    669 		}
    670 
    671 	if (regulator->can_xadj)
    672 		if (defreg & TPS65217PMIC_DEFX_XADJ) {
    673 			regulator->is_xadj = true;
    674 			voltage = 0;
    675 
    676 		}
    677 
    678 	/* TODO: add PGOOD checking */
    679 
    680 	regulator->current_voltage = voltage;
    681 }
    682 
    683 static void
    684 tps65217pmic_print_ldos(struct tps65217pmic_softc *sc)
    685 {
    686 	int i;
    687 	struct tps_reg_param *c_reg;
    688 
    689 	aprint_normal_dev(sc->sc_dev, "");
    690 
    691 	for (i = 0; i < NTPS_REG; i++) {
    692 		c_reg = &tps_regulators[i];
    693 
    694 		if (c_reg->is_enabled) {
    695 			if (c_reg->is_ls)
    696 				aprint_normal("[%s: LS] ", c_reg->name);
    697 			else if (c_reg->is_xadj)
    698 				aprint_normal("[%s: XADJ] ", c_reg->name);
    699 			else
    700 				aprint_normal("[%s: %d mV] ", c_reg->name,
    701 				    c_reg->current_voltage);
    702 		}
    703 	}
    704 	aprint_normal("\n");
    705 }
    706 
    707 static void
    708 tps65217pmic_print_ppath(struct tps65217pmic_softc *sc)
    709 {
    710 	uint8_t status, ppath;
    711 
    712 	ppath = tps65217pmic_reg_read(sc, TPS65217PMIC_PPATH);
    713 	status = tps65217pmic_reg_read(sc, TPS65217PMIC_STATUS);
    714 
    715 	aprint_normal_dev(sc->sc_dev, "power sources ");
    716 
    717 	if (ppath & TPS65217PMIC_PPATH_USB_EN) {
    718 		if (status & TPS65217PMIC_STATUS_USBPWR)
    719 			aprint_normal("[USB] ");
    720 		else
    721 			aprint_normal("USB ");
    722 		aprint_normal("max %d mA, ",
    723 		    tps65217pmic_ppath_max_usb_current(ppath));
    724 	}
    725 
    726 	if (ppath & TPS65217PMIC_PPATH_AC_EN) {
    727 		if (status & TPS65217PMIC_STATUS_ACPWR)
    728 			aprint_normal("[AC] ");
    729 		else
    730 			aprint_normal("AC ");
    731 		aprint_normal("max %d mA",
    732 		    tps65217pmic_ppath_max_ac_current(ppath));
    733 	}
    734 
    735 	aprint_normal("\n");
    736 }
    737 
    738 static int
    739 tps65217pmic_i2c_lock(struct tps65217pmic_softc *sc)
    740 {
    741 	int error;
    742 
    743 	error = iic_acquire_bus(sc->sc_tag, 0);
    744 	if (error) {
    745 		device_printf(sc->sc_dev,
    746 		    "unable to acquire i2c bus, error %d\n", error);
    747 	}
    748 	return error;
    749 }
    750 
    751 static void
    752 tps65217pmic_i2c_unlock(struct tps65217pmic_softc *sc)
    753 {
    754 	iic_release_bus(sc->sc_tag, 0);
    755 }
    756 
    757 static uint8_t
    758 tps65217pmic_reg_read(struct tps65217pmic_softc *sc, uint8_t reg)
    759 {
    760 	uint8_t wbuf[2];
    761 	uint8_t rv;
    762 
    763 	wbuf[0] = reg;
    764 
    765 	if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr, wbuf,
    766 	    1, &rv, 1, 0)) {
    767 		aprint_error_dev(sc->sc_dev, "cannot execute operation\n");
    768 		iic_release_bus(sc->sc_tag, 0);
    769 		return 0;
    770 	}
    771 
    772 	return rv;
    773 }
    774 
    775 static void
    776 tps65217pmic_reg_write(struct tps65217pmic_softc *sc,
    777     uint8_t reg, uint8_t data)
    778 {
    779 	uint8_t wbuf[2];
    780 
    781 	wbuf[0] = reg;
    782 	wbuf[1] = data;
    783 
    784 	if (iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP, sc->sc_addr, NULL, 0,
    785 	    wbuf, 2, 0)) {
    786 		aprint_error_dev(sc->sc_dev, "cannot execute I2C write\n");
    787 	}
    788 }
    789 
    790 static void
    791 tps65217pmic_reg_write_l2(struct tps65217pmic_softc *sc,
    792     uint8_t reg, uint8_t data)
    793 {
    794 	uint8_t regpw = reg ^ TPS65217PMIC_PASSWORD_XOR;
    795 
    796 	if (tps65217pmic_i2c_lock(sc))
    797 		return;
    798 
    799 	tps65217pmic_reg_write(sc, TPS65217PMIC_PASSWORD, regpw);
    800 	tps65217pmic_reg_write(sc, reg, data);
    801 	tps65217pmic_reg_write(sc, TPS65217PMIC_PASSWORD, regpw);
    802 	tps65217pmic_reg_write(sc, reg, data);
    803 
    804 	tps65217pmic_i2c_unlock(sc);
    805 }
    806 
    807 static void
    808 tps65217pmic_envsys_register(struct tps65217pmic_softc *sc)
    809 {
    810 	int i;
    811 
    812 	sc->sc_sme = sysmon_envsys_create();
    813 
    814 	/* iterate over all regulators and attach them as sensors */
    815 	for(i = 0; i <= SNUM_REGS; i++) {
    816 		/* set name */
    817 		strlcpy(sc->sc_regsensor[i].desc, tps_regulators[i].name,
    818 		    sizeof(sc->sc_regsensor[i].desc));
    819 		sc->sc_regsensor[i].units = ENVSYS_SVOLTS_DC;
    820 		sc->sc_regsensor[i].state = ENVSYS_SINVALID;
    821 
    822 		if (sysmon_envsys_sensor_attach(sc->sc_sme,
    823 		    &sc->sc_regsensor[i]))
    824 			aprint_error_dev(sc->sc_dev,
    825 			    "error attaching regulator sensor %d\n", i);
    826 	}
    827 
    828 	/* attach power source indicators */
    829 	strcpy(sc->sc_usbsensor.desc, "USB power source"); /* SNUM_USBSTATUS */
    830 	sc->sc_usbsensor.units = ENVSYS_INDICATOR;
    831 	sc->sc_usbsensor.state = ENVSYS_SINVALID;
    832 	if (sysmon_envsys_sensor_attach(sc->sc_sme, &sc->sc_usbsensor))
    833 		aprint_error_dev(sc->sc_dev,
    834 		    "error attaching USB power source sensor\n");
    835 	strcpy(sc->sc_acsensor.desc, "AC power source"); /* SNUM_ACSTATUS */
    836 	sc->sc_acsensor.units = ENVSYS_INDICATOR;
    837 	sc->sc_acsensor.state = ENVSYS_SINVALID;
    838 	if (sysmon_envsys_sensor_attach(sc->sc_sme, &sc->sc_acsensor))
    839 		aprint_error_dev(sc->sc_dev,
    840 		    "error attaching AC power source sensor\n");
    841 
    842 	/* register everything in sysmon */
    843 	sc->sc_sme->sme_name = device_xname(sc->sc_dev);
    844 	sc->sc_sme->sme_cookie = sc;
    845 	sc->sc_sme->sme_refresh = tps65217pmic_envsys_refresh;
    846 
    847 	if (sysmon_envsys_register(sc->sc_sme)) {
    848 		aprint_error_dev(sc->sc_dev, "unable to register in sysmon\n");
    849 		sysmon_envsys_destroy(sc->sc_sme);
    850 	}
    851 }
    852 
    853 static void
    854 tps65217pmic_envsys_refresh(struct sysmon_envsys *sme, envsys_data_t *edata)
    855 {
    856 	struct tps65217pmic_softc *sc = sme->sme_cookie;
    857 
    858 	mutex_enter(&sc->sc_lock);
    859 
    860 	tps65217pmic_reg_refresh(sc);
    861 
    862 	if (edata->sensor <= SNUM_REGS) {
    863 		/* TODO: handle special cases like LS, XADJ... */
    864 		edata->value_cur = tps_regulators[edata->sensor].current_voltage * 1000;
    865 		edata->state = ENVSYS_SVALID;
    866 	} else if (edata->sensor == SNUM_USBSTATUS) {
    867 		edata->value_cur = sc->sc_usbstatus && sc->sc_usbenabled;
    868 		edata->state = ENVSYS_SVALID;
    869 	} else if (edata->sensor == SNUM_ACSTATUS) {
    870 		edata->value_cur = sc->sc_acstatus && sc->sc_acenabled;
    871 		edata->state = ENVSYS_SVALID;
    872 	} else
    873 		aprint_error_dev(sc->sc_dev, "unknown sensor number\n");
    874 
    875 	mutex_exit(&sc->sc_lock);
    876 }
    877 
    878 int
    879 tps65217pmic_set_volt(device_t self, const char *name, int mvolt)
    880 {
    881 	int i;
    882 	struct tps65217pmic_softc *sc = device_private(self);
    883 	struct tps_reg_param *regulator = NULL;
    884 	uint8_t val;
    885 
    886 	for (i = 0; i < __arraycount(tps_regulators); i++) {
    887 		if (strcmp(name, tps_regulators[i].name) == 0) {
    888 			regulator = &tps_regulators[i];
    889 			break;
    890 		}
    891 	}
    892 	if (regulator == NULL)
    893 		return EINVAL;
    894 
    895 	if (regulator->voltage_min > mvolt || regulator->voltage_max < mvolt)
    896 		return EINVAL;
    897 
    898 	if (!regulator->is_enabled)
    899 		return EINVAL;
    900 
    901 	if (regulator->is_tracking)
    902 		return EINVAL;
    903 
    904 	if (regulator->is_xadj)
    905 		return EINVAL;
    906 
    907 	/* find closest voltage entry */
    908 	for (i = 0; i < regulator->nvoltages; i++) {
    909 		if (mvolt <= regulator->voltages[i]) {
    910 			break;
    911 		}
    912 	}
    913 	KASSERT(i < regulator->nvoltages);
    914 	tps65217pmic_reg_write_l2(sc, regulator->defreg_num, i);
    915 
    916 	val = tps65217pmic_reg_read(sc, TPS65217PMIC_DEFSLEW);
    917 	val |= TPS65217PMIC_DEFSLEW_GO;
    918 	tps65217pmic_reg_write_l2(sc, TPS65217PMIC_DEFSLEW, val);
    919 
    920 	while (val & TPS65217PMIC_DEFSLEW_GO) {
    921 		val = tps65217pmic_reg_read(sc, TPS65217PMIC_DEFSLEW);
    922 	}
    923 
    924 	regulator->current_voltage = regulator->voltages[i];
    925 
    926 	return 0;
    927 }
    928 
    929 #ifdef FDT
    930 static struct tps_reg_param *
    931 tps65217pmic_get_params(const char *name)
    932 {
    933 	int i;
    934 
    935 	for (i = 0; i < __arraycount(tps_regulators); i++) {
    936 		if (strcmp(name, tps_regulators[i].name) == 0)
    937 			return &tps_regulators[i];
    938 	}
    939 
    940 	return NULL;
    941 }
    942 
    943 static void
    944 tps65217pmic_regulator_attach(struct tps65217pmic_softc *sc)
    945 {
    946 	struct tps65217reg_attach_args raa;
    947 	struct tps_reg_param *param;
    948 	const char *compat_name;
    949 	int phandle, child;
    950 
    951 	phandle = of_find_firstchild_byname(sc->sc_phandle, "regulators");
    952 	if (phandle <= 0)
    953 		return;
    954 
    955 	for (child = OF_child(phandle); child; child = OF_peer(child)) {
    956 		compat_name = fdtbus_get_string(child, "regulator-compatible");
    957 		if (compat_name == NULL)
    958 			continue;
    959 		param = tps65217pmic_get_params(compat_name);
    960 		if (param == NULL)
    961 			continue;
    962 
    963 		raa.reg_param = param;
    964 		raa.reg_phandle = child;
    965 		config_found(sc->sc_dev, &raa, NULL);
    966 	}
    967 }
    968 
    969 static int
    970 tps65217reg_acquire(device_t dev)
    971 {
    972 	return 0;
    973 }
    974 
    975 static void
    976 tps65217reg_release(device_t dev)
    977 {
    978 }
    979 
    980 static int
    981 tps65217reg_enable(device_t dev, bool enable)
    982 {
    983 	struct tps65217reg_softc *sc = device_private(dev);
    984 	struct tps65217pmic_softc *pmic_sc = device_private(device_parent(dev));
    985 	struct tps_reg_param *regulator = sc->sc_param;
    986 	uint8_t val;
    987 	int error;
    988 
    989 	error = tps65217pmic_i2c_lock(pmic_sc);
    990 	if (error != 0)
    991 		return error;
    992 
    993 	val = tps65217pmic_reg_read(pmic_sc, TPS65217PMIC_ENABLE);
    994 	if (enable)
    995 		val |= regulator->enable_bit;
    996 	else
    997 		val &= ~regulator->enable_bit;
    998 	tps65217pmic_reg_write(pmic_sc, TPS65217PMIC_ENABLE, val);
    999 
   1000 	regulator->is_enabled = enable;
   1001 
   1002 	tps65217pmic_i2c_unlock(pmic_sc);
   1003 
   1004 	return 0;
   1005 }
   1006 
   1007 static int
   1008 tps65217reg_set_voltage(device_t dev, u_int min_uvol, u_int max_uvol)
   1009 {
   1010 	struct tps65217reg_softc *sc = device_private(dev);
   1011 	struct tps65217pmic_softc *pmic_sc = device_private(device_parent(dev));
   1012 	struct tps_reg_param *regulator = sc->sc_param;
   1013 	int error;
   1014 
   1015 	error = tps65217pmic_i2c_lock(pmic_sc);
   1016 	if (error != 0)
   1017 		return error;
   1018 
   1019 	error = tps65217pmic_set_volt(pmic_sc->sc_dev, regulator->name, min_uvol / 1000);
   1020 
   1021 	tps65217pmic_i2c_unlock(pmic_sc);
   1022 
   1023 	return error;
   1024 }
   1025 
   1026 static int
   1027 tps65217reg_get_voltage(device_t dev, u_int *puvol)
   1028 {
   1029 	struct tps65217reg_softc *sc = device_private(dev);
   1030 	struct tps_reg_param *regulator = sc->sc_param;
   1031 
   1032 	*puvol = (u_int)regulator->current_voltage * 1000;
   1033 
   1034 	return 0;
   1035 }
   1036 
   1037 static struct fdtbus_regulator_controller_func tps65217reg_funcs = {
   1038 	.acquire = tps65217reg_acquire,
   1039 	.release = tps65217reg_release,
   1040 	.enable = tps65217reg_enable,
   1041 	.set_voltage = tps65217reg_set_voltage,
   1042 	.get_voltage = tps65217reg_get_voltage,
   1043 };
   1044 
   1045 static int
   1046 tps65217reg_match(device_t parent, cfdata_t match, void *aux)
   1047 {
   1048 	return 1;
   1049 }
   1050 
   1051 static void
   1052 tps65217reg_attach(device_t parent, device_t self, void *aux)
   1053 {
   1054 	struct tps65217reg_softc *sc = device_private(self);
   1055 	struct tps65217reg_attach_args *raa = aux;
   1056 	const char *regname;
   1057 
   1058 	sc->sc_dev = self;
   1059 	sc->sc_phandle = raa->reg_phandle;
   1060 	sc->sc_param = raa->reg_param;
   1061 
   1062 	fdtbus_register_regulator_controller(self, sc->sc_phandle,
   1063 	    &tps65217reg_funcs);
   1064 
   1065 	regname = fdtbus_get_string(sc->sc_phandle, "regulator-name");
   1066 	if (regname == NULL)
   1067 		regname = fdtbus_get_string(sc->sc_phandle, "regulator-compatible");
   1068 
   1069 	aprint_naive("\n");
   1070 	if (regname != NULL)
   1071 		aprint_normal(": %s\n", regname);
   1072 	else
   1073 		aprint_normal("\n");
   1074 }
   1075 
   1076 CFATTACH_DECL_NEW(tps65217reg, sizeof (struct tps65217reg_softc),
   1077     tps65217reg_match, tps65217reg_attach, NULL, NULL);
   1078 
   1079 #endif
   1080