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