tps65217pmic.c revision 1.16 1 /* $NetBSD: tps65217pmic.c,v 1.16 2021/01/17 21:42:35 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.16 2021/01/17 21:42:35 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
304 { 0 }
305 };
306
307 static int
308 tps65217pmic_match(device_t parent, cfdata_t cf, void *aux)
309 {
310 struct i2c_attach_args *ia = aux;
311 int match_result;
312
313 if (iic_use_direct_match(ia, cf, compat_data, &match_result))
314 return match_result;
315
316 if (ia->ia_addr == TPS65217PMIC_ADDR) {
317 /* we can only have one */
318 if (matched)
319 return 0;
320
321 return I2C_MATCH_ADDRESS_ONLY;
322 }
323 return 0;
324 }
325
326 static void
327 tps65217pmic_attach(device_t parent, device_t self, void *aux)
328 {
329 struct tps65217pmic_softc *sc = device_private(self);
330 struct i2c_attach_args *ia = aux;
331 prop_dictionary_t dict;
332 int isel, fdim, brightness;
333
334 /* XXXJRT But what if you have multiple i2c busses? */
335 matched = true;
336
337 sc->sc_dev = self;
338 sc->sc_addr = ia->ia_addr;
339 sc->sc_phandle = ia->ia_cookie;
340 sc->sc_tag = ia->ia_tag;
341
342 dict = device_properties(self);
343 if (prop_dictionary_get_int32(dict, "isel", &isel)) {
344 prop_dictionary_get_int32(dict, "fdim", &fdim);
345 prop_dictionary_get_int32(dict, "brightness", &brightness);
346 } else
347 isel = -1;
348
349 tps65217pmic_version(sc);
350
351 aprint_normal(": TPS65217");
352 switch (sc->sc_version) {
353 case TPS65217PMIC_CHIPID_VER_A:
354 aprint_normal("A");
355 break;
356 case TPS65217PMIC_CHIPID_VER_B:
357 aprint_normal("B");
358 break;
359 case TPS65217PMIC_CHIPID_VER_C:
360 aprint_normal("C");
361 break;
362 case TPS65217PMIC_CHIPID_VER_D:
363 aprint_normal("D");
364 break;
365 default:
366 /* unknown version */
367 break;
368 }
369
370 aprint_normal(" Power Management Multi-Channel IC (rev 1.%d)\n",
371 sc->sc_revision);
372
373 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
374
375 sc->sc_smpsw.smpsw_name = device_xname(self);
376 sc->sc_smpsw.smpsw_type = PSWITCH_TYPE_ACADAPTER;
377 sysmon_pswitch_register(&sc->sc_smpsw);
378
379 tps65217pmic_reg_refresh(sc);
380
381 tps65217pmic_print_ppath(sc);
382 tps65217pmic_print_ldos(sc);
383
384 tps65217pmic_power_monitor_init(sc);
385
386 if (isel != -1)
387 tps65217pmic_wled_init(sc, isel, fdim, brightness);
388
389 tps65217pmic_envsys_register(sc);
390
391 #ifdef FDT
392 tps65217pmic_regulator_attach(sc);
393 #endif
394 }
395
396 static void
397 tps65217pmic_power_monitor_init(struct tps65217pmic_softc *sc)
398 {
399 uint8_t intr, intrmask, status, ppath;
400
401 intrmask = TPS65217PMIC_INT_USBM | TPS65217PMIC_INT_ACM |
402 TPS65217PMIC_INT_PBM;
403
404 if (tps65217pmic_i2c_lock(sc) != 0) {
405 aprint_error_dev(sc->sc_dev,
406 "failed to initialize power monitor\n");
407 return;
408 }
409
410 status = tps65217pmic_reg_read(sc, TPS65217PMIC_STATUS);
411 ppath = tps65217pmic_reg_read(sc, TPS65217PMIC_PPATH);
412 /* acknowledge and disregard whatever interrupt was generated earlier */
413 intr = tps65217pmic_reg_read(sc, TPS65217PMIC_INT);
414
415 tps65217pmic_i2c_unlock(sc);
416
417 sc->sc_usbstatus = status & TPS65217PMIC_STATUS_USBPWR;
418 sc->sc_acstatus = status & TPS65217PMIC_STATUS_ACPWR;
419 sc->sc_usbenabled = ppath & TPS65217PMIC_PPATH_USB_EN;
420 sc->sc_acenabled = ppath & TPS65217PMIC_PPATH_AC_EN;
421
422 if (intr & intrmask)
423 aprint_normal_dev(sc->sc_dev,
424 "WARNING: hardware interrupt enabled but not supported");
425
426 /* set up callout to poll for power source changes */
427 callout_init(&sc->sc_powerpollco, 0);
428 callout_setfunc(&sc->sc_powerpollco, tps65217pmic_power_monitor, sc);
429
430 callout_schedule(&sc->sc_powerpollco, hz);
431 }
432
433 static void
434 tps65217pmic_power_monitor_task(void *aux)
435 {
436 struct tps65217pmic_softc *sc;
437 uint8_t status;
438 bool usbstatus, acstatus;
439
440 sc = aux;
441
442 mutex_enter(&sc->sc_lock);
443
444 if (tps65217pmic_i2c_lock(sc) != 0) {
445 device_printf(sc->sc_dev,
446 "WARNING: unable to perform power monitor task.\n");
447 return;
448 }
449 status = tps65217pmic_reg_read(sc, TPS65217PMIC_STATUS);
450 tps65217pmic_i2c_unlock(sc);
451
452 usbstatus = status & TPS65217PMIC_STATUS_USBPWR;
453 acstatus = status & TPS65217PMIC_STATUS_ACPWR;
454
455 if (usbstatus != sc->sc_usbstatus) {
456 sc->sc_usbstatus = usbstatus;
457 pmf_event_inject(NULL, PMFE_POWER_CHANGED);
458 if (usbstatus)
459 aprint_normal_dev(sc->sc_dev,
460 "USB power source connected\n");
461 else
462 aprint_normal_dev(sc->sc_dev,
463 "USB power source disconnected\n");
464 }
465
466 if (acstatus != sc->sc_acstatus) {
467 sc->sc_acstatus = acstatus;
468 pmf_event_inject(NULL, PMFE_POWER_CHANGED);
469 if (acstatus) {
470 sysmon_pswitch_event(&sc->sc_smpsw,
471 PSWITCH_EVENT_PRESSED);
472 } else {
473 sysmon_pswitch_event(&sc->sc_smpsw,
474 PSWITCH_EVENT_RELEASED);
475 }
476 }
477
478 mutex_exit(&sc->sc_lock);
479
480 callout_schedule(&sc->sc_powerpollco, hz);
481 }
482
483 static void
484 tps65217pmic_power_monitor(void *aux)
485 {
486 sysmon_task_queue_sched(0, tps65217pmic_power_monitor_task, aux);
487 }
488
489 static void
490 tps65217pmic_wled_init(struct tps65217pmic_softc *sc, int isel, int fdim,
491 int brightness)
492 {
493 uint8_t val = 0;
494
495 switch (isel) {
496 case 1:
497 case 2:
498 val |= ((isel - 1) << TPS65217PMIC_WLEDCTRL1_ISEL);
499 break;
500 default:
501 aprint_error_dev(sc->sc_dev,
502 "WLED ISET selection is 1 or 2: isel %d\n", isel);
503 return;
504 }
505 switch (fdim) {
506 case 100:
507 val |= TPS65217PMIC_WLEDCTRL1_FDIM_100Hz;
508 break;
509 case 200:
510 val |= TPS65217PMIC_WLEDCTRL1_FDIM_200Hz;
511 break;
512 case 500:
513 val |= TPS65217PMIC_WLEDCTRL1_FDIM_500Hz;
514 break;
515 case 1000:
516 val |= TPS65217PMIC_WLEDCTRL1_FDIM_1000Hz;
517 break;
518 default:
519 aprint_error_dev(sc->sc_dev,
520 "WLED PWM dimming frequency is 100, 200, 500 or 1000:"
521 " fdim %d\n", fdim);
522 return;
523 }
524 if (brightness > 100 ||
525 brightness < 0) {
526 aprint_error_dev(sc->sc_dev,
527 "invalid brightness: between 0 and 100: %d\n", brightness);
528 return;
529 }
530
531 if (tps65217pmic_i2c_lock(sc) != 0) {
532 device_printf(sc->sc_dev,
533 "WARNING: unable to configure LED\n");
534 return;
535 }
536
537 tps65217pmic_reg_write(sc, TPS65217PMIC_WLEDCTRL1, val);
538 tps65217pmic_reg_write(sc, TPS65217PMIC_WLEDCTRL2,
539 (brightness - 1) & TPS65217PMIC_WLEDCTRL2_DUTY);
540 val |= TPS65217PMIC_WLEDCTRL1_ISINK_EN;
541 tps65217pmic_reg_write(sc, TPS65217PMIC_WLEDCTRL1, val);
542
543 tps65217pmic_i2c_unlock(sc);
544 }
545
546 static void
547 tps65217pmic_reg_refresh(struct tps65217pmic_softc *sc)
548 {
549 int i;
550 struct tps_reg_param *c_reg;
551
552 if (tps65217pmic_i2c_lock(sc) != 0) {
553 device_printf(sc->sc_dev,
554 "WARNING: unable to refresh regulators\n");
555 return;
556 }
557
558 for (i = 0; i < NTPS_REG; i++) {
559 c_reg = &tps_regulators[i];
560 tps65217pmic_regulator_read_config(sc, c_reg);
561 }
562
563 tps65217pmic_i2c_unlock(sc);
564 }
565
566 /* Get version and revision of the chip. */
567 static void
568 tps65217pmic_version(struct tps65217pmic_softc *sc)
569 {
570 uint8_t chipid;
571
572 if (tps65217pmic_i2c_lock(sc) != 0) {
573 device_printf(sc->sc_dev,
574 "WARNING: unable to get chip ID\n");
575 return;
576 }
577
578 chipid = tps65217pmic_reg_read(sc, TPS65217PMIC_CHIPID);
579
580 tps65217pmic_i2c_unlock(sc);
581
582 sc->sc_version = chipid & TPS65217PMIC_CHIPID_VER_MASK;
583 sc->sc_revision = chipid & TPS65217PMIC_CHIPID_REV_MASK;
584 }
585
586 static uint16_t
587 tps65217pmic_ppath_max_ac_current(uint8_t ppath)
588 {
589 switch ((ppath & TPS65217PMIC_PPATH_IAC) >>
590 TPS65217PMIC_PPATH_IAC_RSHFIT) {
591 case TPS65217PMIC_PPATH_IAC_100MA:
592 return 100;
593 case TPS65217PMIC_PPATH_IAC_500MA:
594 return 500;
595 case TPS65217PMIC_PPATH_IAC_1300MA:
596 return 1300;
597 case TPS65217PMIC_PPATH_IAC_2500MA:
598 return 2500;
599 }
600 return 0;
601 }
602
603 static uint16_t
604 tps65217pmic_ppath_max_usb_current(uint8_t ppath)
605 {
606 switch (ppath & TPS65217PMIC_PPATH_IUSB) {
607 case TPS65217PMIC_PPATH_IUSB_100MA:
608 return 100;
609 case TPS65217PMIC_PPATH_IUSB_500MA:
610 return 500;
611 case TPS65217PMIC_PPATH_IUSB_1300MA:
612 return 1300;
613 case TPS65217PMIC_PPATH_IUSB_1800MA:
614 return 1800;
615 }
616 return 0;
617 }
618
619 /* Read regulator state and save it to tps_reg_param. */
620 static void
621 tps65217pmic_regulator_read_config(struct tps65217pmic_softc *sc, struct
622 tps_reg_param *regulator)
623 {
624 uint8_t defreg, regenable;
625 uint16_t voltage;
626
627 regenable = tps65217pmic_reg_read(sc, TPS65217PMIC_ENABLE);
628
629 if (regenable & (regulator->enable_bit))
630 regulator->is_enabled = true;
631 else {
632 regulator->is_enabled = false;
633 return;
634 }
635
636 defreg = tps65217pmic_reg_read(sc,
637 regulator->defreg_num);
638
639 switch (regulator->nvoltages) {
640 case 16:
641 voltage = regulator->voltages[defreg &
642 TPS65217PMIC_DEFX_VOLTAGE_16];
643 break;
644 case 32:
645 voltage = regulator->voltages[defreg &
646 TPS65217PMIC_DEFX_VOLTAGE_32];
647 break;
648 case 64:
649 voltage = regulator->voltages[defreg &
650 TPS65217PMIC_DEFX_VOLTAGE_64];
651 break;
652 default:
653 /* unsupported number of voltage settings? */
654 voltage = 0;
655 break;
656 }
657
658 /* Handle regulator tracking other regulator voltage. */
659 if (regulator->can_track)
660 if (defreg & TPS65217PMIC_DEFX_TRACKING) {
661 regulator->is_tracking = true;
662 voltage = 0; /* see regulator->tracked_reg */
663 }
664
665 /* Handle regulator configured into load switch mode. */
666 if (regulator->can_ls)
667 if (!(defreg & TPS65217PMIC_DEFX_LS)) {
668 regulator->is_ls = true;
669 voltage = 0;
670 }
671
672 if (regulator->can_xadj)
673 if (defreg & TPS65217PMIC_DEFX_XADJ) {
674 regulator->is_xadj = true;
675 voltage = 0;
676
677 }
678
679 /* TODO: add PGOOD checking */
680
681 regulator->current_voltage = voltage;
682 }
683
684 static void
685 tps65217pmic_print_ldos(struct tps65217pmic_softc *sc)
686 {
687 int i;
688 struct tps_reg_param *c_reg;
689
690 aprint_normal_dev(sc->sc_dev, "");
691
692 for (i = 0; i < NTPS_REG; i++) {
693 c_reg = &tps_regulators[i];
694
695 if (c_reg->is_enabled) {
696 if (c_reg->is_ls)
697 aprint_normal("[%s: LS] ", c_reg->name);
698 else if (c_reg->is_xadj)
699 aprint_normal("[%s: XADJ] ", c_reg->name);
700 else
701 aprint_normal("[%s: %d mV] ", c_reg->name,
702 c_reg->current_voltage);
703 }
704 }
705 aprint_normal("\n");
706 }
707
708 static void
709 tps65217pmic_print_ppath(struct tps65217pmic_softc *sc)
710 {
711 uint8_t status, ppath;
712
713 ppath = tps65217pmic_reg_read(sc, TPS65217PMIC_PPATH);
714 status = tps65217pmic_reg_read(sc, TPS65217PMIC_STATUS);
715
716 aprint_normal_dev(sc->sc_dev, "power sources ");
717
718 if (ppath & TPS65217PMIC_PPATH_USB_EN) {
719 if (status & TPS65217PMIC_STATUS_USBPWR)
720 aprint_normal("[USB] ");
721 else
722 aprint_normal("USB ");
723 aprint_normal("max %d mA, ",
724 tps65217pmic_ppath_max_usb_current(ppath));
725 }
726
727 if (ppath & TPS65217PMIC_PPATH_AC_EN) {
728 if (status & TPS65217PMIC_STATUS_ACPWR)
729 aprint_normal("[AC] ");
730 else
731 aprint_normal("AC ");
732 aprint_normal("max %d mA",
733 tps65217pmic_ppath_max_ac_current(ppath));
734 }
735
736 aprint_normal("\n");
737 }
738
739 static int
740 tps65217pmic_i2c_lock(struct tps65217pmic_softc *sc)
741 {
742 int error;
743
744 error = iic_acquire_bus(sc->sc_tag, 0);
745 if (error) {
746 device_printf(sc->sc_dev,
747 "unable to acquire i2c bus, error %d\n", error);
748 }
749 return error;
750 }
751
752 static void
753 tps65217pmic_i2c_unlock(struct tps65217pmic_softc *sc)
754 {
755 iic_release_bus(sc->sc_tag, 0);
756 }
757
758 static uint8_t
759 tps65217pmic_reg_read(struct tps65217pmic_softc *sc, uint8_t reg)
760 {
761 uint8_t wbuf[2];
762 uint8_t rv;
763
764 wbuf[0] = reg;
765
766 if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr, wbuf,
767 1, &rv, 1, 0)) {
768 aprint_error_dev(sc->sc_dev, "cannot execute operation\n");
769 iic_release_bus(sc->sc_tag, 0);
770 return 0;
771 }
772
773 return rv;
774 }
775
776 static void
777 tps65217pmic_reg_write(struct tps65217pmic_softc *sc,
778 uint8_t reg, uint8_t data)
779 {
780 uint8_t wbuf[2];
781
782 wbuf[0] = reg;
783 wbuf[1] = data;
784
785 if (iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP, sc->sc_addr, NULL, 0,
786 wbuf, 2, 0)) {
787 aprint_error_dev(sc->sc_dev, "cannot execute I2C write\n");
788 }
789 }
790
791 static void
792 tps65217pmic_reg_write_l2(struct tps65217pmic_softc *sc,
793 uint8_t reg, uint8_t data)
794 {
795 uint8_t regpw = reg ^ TPS65217PMIC_PASSWORD_XOR;
796
797 if (tps65217pmic_i2c_lock(sc))
798 return;
799
800 tps65217pmic_reg_write(sc, TPS65217PMIC_PASSWORD, regpw);
801 tps65217pmic_reg_write(sc, reg, data);
802 tps65217pmic_reg_write(sc, TPS65217PMIC_PASSWORD, regpw);
803 tps65217pmic_reg_write(sc, reg, data);
804
805 tps65217pmic_i2c_unlock(sc);
806 }
807
808 static void
809 tps65217pmic_envsys_register(struct tps65217pmic_softc *sc)
810 {
811 int i;
812
813 sc->sc_sme = sysmon_envsys_create();
814
815 /* iterate over all regulators and attach them as sensors */
816 for(i = 0; i <= SNUM_REGS; i++) {
817 /* set name */
818 strlcpy(sc->sc_regsensor[i].desc, tps_regulators[i].name,
819 sizeof(sc->sc_regsensor[i].desc));
820 sc->sc_regsensor[i].units = ENVSYS_SVOLTS_DC;
821 sc->sc_regsensor[i].state = ENVSYS_SINVALID;
822
823 if (sysmon_envsys_sensor_attach(sc->sc_sme,
824 &sc->sc_regsensor[i]))
825 aprint_error_dev(sc->sc_dev,
826 "error attaching regulator sensor %d\n", i);
827 }
828
829 /* attach power source indicators */
830 strcpy(sc->sc_usbsensor.desc, "USB power source"); /* SNUM_USBSTATUS */
831 sc->sc_usbsensor.units = ENVSYS_INDICATOR;
832 sc->sc_usbsensor.state = ENVSYS_SINVALID;
833 if (sysmon_envsys_sensor_attach(sc->sc_sme, &sc->sc_usbsensor))
834 aprint_error_dev(sc->sc_dev,
835 "error attaching USB power source sensor\n");
836 strcpy(sc->sc_acsensor.desc, "AC power source"); /* SNUM_ACSTATUS */
837 sc->sc_acsensor.units = ENVSYS_INDICATOR;
838 sc->sc_acsensor.state = ENVSYS_SINVALID;
839 if (sysmon_envsys_sensor_attach(sc->sc_sme, &sc->sc_acsensor))
840 aprint_error_dev(sc->sc_dev,
841 "error attaching AC power source sensor\n");
842
843 /* register everything in sysmon */
844 sc->sc_sme->sme_name = device_xname(sc->sc_dev);
845 sc->sc_sme->sme_cookie = sc;
846 sc->sc_sme->sme_refresh = tps65217pmic_envsys_refresh;
847
848 if (sysmon_envsys_register(sc->sc_sme)) {
849 aprint_error_dev(sc->sc_dev, "unable to register in sysmon\n");
850 sysmon_envsys_destroy(sc->sc_sme);
851 }
852 }
853
854 static void
855 tps65217pmic_envsys_refresh(struct sysmon_envsys *sme, envsys_data_t *edata)
856 {
857 struct tps65217pmic_softc *sc = sme->sme_cookie;
858
859 mutex_enter(&sc->sc_lock);
860
861 tps65217pmic_reg_refresh(sc);
862
863 if (edata->sensor <= SNUM_REGS) {
864 /* TODO: handle special cases like LS, XADJ... */
865 edata->value_cur = tps_regulators[edata->sensor].current_voltage * 1000;
866 edata->state = ENVSYS_SVALID;
867 } else if (edata->sensor == SNUM_USBSTATUS) {
868 edata->value_cur = sc->sc_usbstatus && sc->sc_usbenabled;
869 edata->state = ENVSYS_SVALID;
870 } else if (edata->sensor == SNUM_ACSTATUS) {
871 edata->value_cur = sc->sc_acstatus && sc->sc_acenabled;
872 edata->state = ENVSYS_SVALID;
873 } else
874 aprint_error_dev(sc->sc_dev, "unknown sensor number\n");
875
876 mutex_exit(&sc->sc_lock);
877 }
878
879 int
880 tps65217pmic_set_volt(device_t self, const char *name, int mvolt)
881 {
882 int i;
883 struct tps65217pmic_softc *sc = device_private(self);
884 struct tps_reg_param *regulator = NULL;
885 uint8_t val;
886
887 for (i = 0; i < __arraycount(tps_regulators); i++) {
888 if (strcmp(name, tps_regulators[i].name) == 0) {
889 regulator = &tps_regulators[i];
890 break;
891 }
892 }
893 if (regulator == NULL)
894 return EINVAL;
895
896 if (regulator->voltage_min > mvolt || regulator->voltage_max < mvolt)
897 return EINVAL;
898
899 if (!regulator->is_enabled)
900 return EINVAL;
901
902 if (regulator->is_tracking)
903 return EINVAL;
904
905 if (regulator->is_xadj)
906 return EINVAL;
907
908 /* find closest voltage entry */
909 for (i = 0; i < regulator->nvoltages; i++) {
910 if (mvolt <= regulator->voltages[i]) {
911 break;
912 }
913 }
914 KASSERT(i < regulator->nvoltages);
915 tps65217pmic_reg_write_l2(sc, regulator->defreg_num, i);
916
917 val = tps65217pmic_reg_read(sc, TPS65217PMIC_DEFSLEW);
918 val |= TPS65217PMIC_DEFSLEW_GO;
919 tps65217pmic_reg_write_l2(sc, TPS65217PMIC_DEFSLEW, val);
920
921 while (val & TPS65217PMIC_DEFSLEW_GO) {
922 val = tps65217pmic_reg_read(sc, TPS65217PMIC_DEFSLEW);
923 }
924
925 regulator->current_voltage = regulator->voltages[i];
926
927 return 0;
928 }
929
930 #ifdef FDT
931 static struct tps_reg_param *
932 tps65217pmic_get_params(const char *name)
933 {
934 int i;
935
936 for (i = 0; i < __arraycount(tps_regulators); i++) {
937 if (strcmp(name, tps_regulators[i].name) == 0)
938 return &tps_regulators[i];
939 }
940
941 return NULL;
942 }
943
944 static void
945 tps65217pmic_regulator_attach(struct tps65217pmic_softc *sc)
946 {
947 struct tps65217reg_attach_args raa;
948 struct tps_reg_param *param;
949 const char *compat_name;
950 int phandle, child;
951
952 phandle = of_find_firstchild_byname(sc->sc_phandle, "regulators");
953 if (phandle <= 0)
954 return;
955
956 for (child = OF_child(phandle); child; child = OF_peer(child)) {
957 compat_name = fdtbus_get_string(child, "regulator-compatible");
958 if (compat_name == NULL)
959 continue;
960 param = tps65217pmic_get_params(compat_name);
961 if (param == NULL)
962 continue;
963
964 raa.reg_param = param;
965 raa.reg_phandle = child;
966 config_found(sc->sc_dev, &raa, NULL);
967 }
968 }
969
970 static int
971 tps65217reg_acquire(device_t dev)
972 {
973 return 0;
974 }
975
976 static void
977 tps65217reg_release(device_t dev)
978 {
979 }
980
981 static int
982 tps65217reg_enable(device_t dev, bool enable)
983 {
984 struct tps65217reg_softc *sc = device_private(dev);
985 struct tps65217pmic_softc *pmic_sc = device_private(device_parent(dev));
986 struct tps_reg_param *regulator = sc->sc_param;
987 uint8_t val;
988 int error;
989
990 error = tps65217pmic_i2c_lock(pmic_sc);
991 if (error != 0)
992 return error;
993
994 val = tps65217pmic_reg_read(pmic_sc, TPS65217PMIC_ENABLE);
995 if (enable)
996 val |= regulator->enable_bit;
997 else
998 val &= ~regulator->enable_bit;
999 tps65217pmic_reg_write(pmic_sc, TPS65217PMIC_ENABLE, val);
1000
1001 regulator->is_enabled = enable;
1002
1003 tps65217pmic_i2c_unlock(pmic_sc);
1004
1005 return 0;
1006 }
1007
1008 static int
1009 tps65217reg_set_voltage(device_t dev, u_int min_uvol, u_int max_uvol)
1010 {
1011 struct tps65217reg_softc *sc = device_private(dev);
1012 struct tps65217pmic_softc *pmic_sc = device_private(device_parent(dev));
1013 struct tps_reg_param *regulator = sc->sc_param;
1014 int error;
1015
1016 error = tps65217pmic_i2c_lock(pmic_sc);
1017 if (error != 0)
1018 return error;
1019
1020 error = tps65217pmic_set_volt(pmic_sc->sc_dev, regulator->name, min_uvol / 1000);
1021
1022 tps65217pmic_i2c_unlock(pmic_sc);
1023
1024 return error;
1025 }
1026
1027 static int
1028 tps65217reg_get_voltage(device_t dev, u_int *puvol)
1029 {
1030 struct tps65217reg_softc *sc = device_private(dev);
1031 struct tps_reg_param *regulator = sc->sc_param;
1032
1033 *puvol = (u_int)regulator->current_voltage * 1000;
1034
1035 return 0;
1036 }
1037
1038 static struct fdtbus_regulator_controller_func tps65217reg_funcs = {
1039 .acquire = tps65217reg_acquire,
1040 .release = tps65217reg_release,
1041 .enable = tps65217reg_enable,
1042 .set_voltage = tps65217reg_set_voltage,
1043 .get_voltage = tps65217reg_get_voltage,
1044 };
1045
1046 static int
1047 tps65217reg_match(device_t parent, cfdata_t match, void *aux)
1048 {
1049 return 1;
1050 }
1051
1052 static void
1053 tps65217reg_attach(device_t parent, device_t self, void *aux)
1054 {
1055 struct tps65217reg_softc *sc = device_private(self);
1056 struct tps65217reg_attach_args *raa = aux;
1057 const char *regname;
1058
1059 sc->sc_dev = self;
1060 sc->sc_phandle = raa->reg_phandle;
1061 sc->sc_param = raa->reg_param;
1062
1063 fdtbus_register_regulator_controller(self, sc->sc_phandle,
1064 &tps65217reg_funcs);
1065
1066 regname = fdtbus_get_string(sc->sc_phandle, "regulator-name");
1067 if (regname == NULL)
1068 regname = fdtbus_get_string(sc->sc_phandle, "regulator-compatible");
1069
1070 aprint_naive("\n");
1071 if (regname != NULL)
1072 aprint_normal(": %s\n", regname);
1073 else
1074 aprint_normal("\n");
1075 }
1076
1077 CFATTACH_DECL_NEW(tps65217reg, sizeof (struct tps65217reg_softc),
1078 tps65217reg_match, tps65217reg_attach, NULL, NULL);
1079
1080 #endif
1081