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