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