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