xref: /netbsd-src/sys/dev/i2c/tps65217pmic.c (revision c7fb772b85b2b5d4cfb282f868f454b4701534fd)
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 
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
tps65217pmic_match(device_t parent,cfdata_t cf,void * aux)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
tps65217pmic_attach(device_t parent,device_t self,void * aux)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
tps65217pmic_power_monitor_init(struct tps65217pmic_softc * sc)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
tps65217pmic_power_monitor_task(void * aux)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
tps65217pmic_power_monitor(void * aux)483 tps65217pmic_power_monitor(void *aux)
484 {
485 	sysmon_task_queue_sched(0, tps65217pmic_power_monitor_task, aux);
486 }
487 
488 static void
tps65217pmic_wled_init(struct tps65217pmic_softc * sc,int isel,int fdim,int brightness)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
tps65217pmic_reg_refresh(struct tps65217pmic_softc * sc)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
tps65217pmic_version(struct tps65217pmic_softc * sc)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
tps65217pmic_ppath_max_ac_current(uint8_t ppath)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
tps65217pmic_ppath_max_usb_current(uint8_t ppath)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
tps65217pmic_regulator_read_config(struct tps65217pmic_softc * sc,struct tps_reg_param * regulator)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
tps65217pmic_print_ldos(struct tps65217pmic_softc * sc)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
tps65217pmic_print_ppath(struct tps65217pmic_softc * sc)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
tps65217pmic_i2c_lock(struct tps65217pmic_softc * sc)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
tps65217pmic_i2c_unlock(struct tps65217pmic_softc * sc)752 tps65217pmic_i2c_unlock(struct tps65217pmic_softc *sc)
753 {
754 	iic_release_bus(sc->sc_tag, 0);
755 }
756 
757 static uint8_t
tps65217pmic_reg_read(struct tps65217pmic_softc * sc,uint8_t reg)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
tps65217pmic_reg_write(struct tps65217pmic_softc * sc,uint8_t reg,uint8_t data)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
tps65217pmic_reg_write_l2(struct tps65217pmic_softc * sc,uint8_t reg,uint8_t data)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
tps65217pmic_envsys_register(struct tps65217pmic_softc * sc)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
tps65217pmic_envsys_refresh(struct sysmon_envsys * sme,envsys_data_t * edata)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
tps65217pmic_set_volt(device_t self,const char * name,int mvolt)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 *
tps65217pmic_get_params(const char * name)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
tps65217pmic_regulator_attach(struct tps65217pmic_softc * sc)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, CFARGS_NONE);
966 	}
967 }
968 
969 static int
tps65217reg_acquire(device_t dev)970 tps65217reg_acquire(device_t dev)
971 {
972 	return 0;
973 }
974 
975 static void
tps65217reg_release(device_t dev)976 tps65217reg_release(device_t dev)
977 {
978 }
979 
980 static int
tps65217reg_enable(device_t dev,bool enable)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
tps65217reg_set_voltage(device_t dev,u_int min_uvol,u_int max_uvol)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
tps65217reg_get_voltage(device_t dev,u_int * puvol)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
tps65217reg_match(device_t parent,cfdata_t match,void * aux)1046 tps65217reg_match(device_t parent, cfdata_t match, void *aux)
1047 {
1048 	return 1;
1049 }
1050 
1051 static void
tps65217reg_attach(device_t parent,device_t self,void * aux)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