1/*	$NetBSD: tps65217pmic.c,v 1.20 2021/08/07 16:19:11 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.20 2021/08/07 16:19:11 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
66struct tps_reg_param;
67
68struct 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
96struct tps65217reg_softc {
97	device_t		sc_dev;
98	int			sc_phandle;
99	struct tps_reg_param	*sc_param;
100};
101
102struct tps65217reg_attach_args {
103	struct tps_reg_param	*reg_param;
104	int			reg_phandle;
105};
106
107/* Voltage regulators */
108enum 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
118struct 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
151static int tps65217pmic_match(device_t, cfdata_t, void *);
152static void tps65217pmic_attach(device_t, device_t, void *);
153
154static int tps65217pmic_i2c_lock(struct tps65217pmic_softc *);
155static void tps65217pmic_i2c_unlock(struct tps65217pmic_softc *);
156
157static uint8_t tps65217pmic_reg_read(struct tps65217pmic_softc *, uint8_t);
158static void tps65217pmic_reg_write(struct tps65217pmic_softc *, uint8_t,
159    uint8_t);
160
161static void tps65217pmic_reg_refresh(struct tps65217pmic_softc *);
162
163static uint16_t tps65217pmic_ppath_max_usb_current(uint8_t);
164static uint16_t tps65217pmic_ppath_max_ac_current(uint8_t);
165
166static void tps65217pmic_regulator_read_config(struct tps65217pmic_softc *,
167    struct tps_reg_param *);
168
169static void tps65217pmic_print_ppath(struct tps65217pmic_softc *);
170static void tps65217pmic_print_ldos(struct tps65217pmic_softc *);
171
172static void tps65217pmic_version(struct tps65217pmic_softc *);
173
174static void tps65217pmic_envsys_register(struct tps65217pmic_softc *);
175static void tps65217pmic_envsys_refresh(struct sysmon_envsys *, envsys_data_t *);
176
177static void tps65217pmic_power_monitor_init(struct tps65217pmic_softc *);
178static void tps65217pmic_power_monitor(void *);
179
180static void tps65217pmic_wled_init(struct tps65217pmic_softc *, int, int, int);
181
182CFATTACH_DECL_NEW(tps65217pmic, sizeof (struct tps65217pmic_softc),
183    tps65217pmic_match, tps65217pmic_attach, NULL, NULL);
184
185#ifdef FDT
186static void tps65217pmic_regulator_attach(struct tps65217pmic_softc *);
187#endif
188
189/* Possible settings of LDO1 in mV. */
190static 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. */
193static 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. */
200static 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
205static 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
299static bool matched = false;
300
301static const struct device_compatible_entry compat_data[] = {
302	{ .compat = "ti,tps65217" },
303	DEVICE_COMPAT_EOL
304};
305
306static int
307tps65217pmic_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
325static void
326tps65217pmic_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
395static void
396tps65217pmic_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
432static void
433tps65217pmic_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
482static void
483tps65217pmic_power_monitor(void *aux)
484{
485	sysmon_task_queue_sched(0, tps65217pmic_power_monitor_task, aux);
486}
487
488static void
489tps65217pmic_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
545static void
546tps65217pmic_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. */
566static void
567tps65217pmic_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
585static uint16_t
586tps65217pmic_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
602static uint16_t
603tps65217pmic_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. */
619static void
620tps65217pmic_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
683static void
684tps65217pmic_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
707static void
708tps65217pmic_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
738static int
739tps65217pmic_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
751static void
752tps65217pmic_i2c_unlock(struct tps65217pmic_softc *sc)
753{
754	iic_release_bus(sc->sc_tag, 0);
755}
756
757static uint8_t
758tps65217pmic_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
775static void
776tps65217pmic_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
790static void
791tps65217pmic_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
807static void
808tps65217pmic_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
853static void
854tps65217pmic_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
878int
879tps65217pmic_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
930static struct tps_reg_param *
931tps65217pmic_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
943static void
944tps65217pmic_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, CFARGS_NONE);
966	}
967}
968
969static int
970tps65217reg_acquire(device_t dev)
971{
972	return 0;
973}
974
975static void
976tps65217reg_release(device_t dev)
977{
978}
979
980static int
981tps65217reg_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
1007static int
1008tps65217reg_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
1026static int
1027tps65217reg_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
1037static 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
1045static int
1046tps65217reg_match(device_t parent, cfdata_t match, void *aux)
1047{
1048	return 1;
1049}
1050
1051static void
1052tps65217reg_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
1076CFATTACH_DECL_NEW(tps65217reg, sizeof (struct tps65217reg_softc),
1077    tps65217reg_match, tps65217reg_attach, NULL, NULL);
1078
1079#endif
1080