tps65217pmic.c revision 1.9.4.2 1 /* $NetBSD: tps65217pmic.c,v 1.9.4.2 2014/05/22 11:40:21 yamt 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 <sys/cdefs.h>
38 __KERNEL_RCSID(0, "$NetBSD: tps65217pmic.c,v 1.9.4.2 2014/05/22 11:40:21 yamt Exp $");
39
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/device.h>
43 #include <sys/kernel.h>
44 #include <sys/mutex.h>
45
46 #include <sys/bus.h>
47 #include <dev/i2c/i2cvar.h>
48
49 #include <dev/sysmon/sysmonvar.h>
50
51 #include <dev/i2c/tps65217pmicreg.h>
52
53 #define NTPS_REG 7
54 #define SNUM_REGS NTPS_REG-1
55 #define SNUM_USBSTATUS NTPS_REG
56 #define SNUM_ACSTATUS NTPS_REG+1
57
58 struct tps65217pmic_softc {
59 device_t sc_dev;
60
61 i2c_tag_t sc_tag;
62 i2c_addr_t sc_addr;
63
64 uint8_t sc_version;
65 uint8_t sc_revision;
66
67 kmutex_t sc_lock;
68
69 bool sc_acstatus;
70 bool sc_usbstatus;
71 bool sc_acenabled;
72 bool sc_usbenabled;
73
74 callout_t sc_powerpollco;
75
76 /* sysmon(4) stuff */
77 struct sysmon_envsys *sc_sme;
78 envsys_data_t sc_regsensor[NTPS_REG];
79 envsys_data_t sc_acsensor;
80 envsys_data_t sc_usbsensor;
81
82 struct sysmon_pswitch sc_smpsw;
83 };
84
85 /* Voltage regulators */
86 enum tps_reg_num {
87 TPS65217PMIC_LDO1,
88 TPS65217PMIC_LDO2,
89 TPS65217PMIC_LDO3LS,
90 TPS65217PMIC_LDO4LS,
91 TPS65217PMIC_DCDC1,
92 TPS65217PMIC_DCDC2,
93 TPS65217PMIC_DCDC3
94 };
95
96 struct tps_reg_param {
97 /* parameters configured statically */
98
99 const char* name;
100 uint16_t voltage_min; /* in mV */
101 uint16_t voltage_max; /* in mV */
102 const uint16_t *voltages; /* all possible voltage settings */
103 uint8_t nvoltages; /* number of voltage settings */
104
105 bool can_track; /* regulator can track U of other r. */
106 struct tps_reg_param *tracked_reg; /* ptr to tracked regulator */
107 bool can_xadj; /* voltage can be adjusted externally */
108 bool can_ls; /* can be a load switch instead of r. */
109
110 uint8_t defreg_num; /* DEF register */
111 uint8_t enable_bit; /* position in ENABLE register */
112
113 /*
114 * Run-time parameters configured during attachment and later, these
115 * probably should be split into separate struct that would be a part
116 * of softc. But since we can have only one TPS chip, that should be
117 * okay for now.
118 */
119
120 bool is_enabled; /* regulator is enabled */
121 bool is_pg; /* regulator is "power good" */
122 bool is_tracking; /* voltage is tracking other reg. */
123 bool is_ls; /* is a load switch */
124 bool is_xadj; /* voltage is adjusted externally */
125
126 uint16_t current_voltage; /* in mV */
127
128 };
129
130 static int tps65217pmic_match(device_t, cfdata_t, void *);
131 static void tps65217pmic_attach(device_t, device_t, void *);
132
133 static uint8_t tps65217pmic_reg_read(struct tps65217pmic_softc *, uint8_t);
134 static void tps65217pmic_reg_write(struct tps65217pmic_softc *, uint8_t,
135 uint8_t);
136
137 static void tps65217pmic_reg_refresh(struct tps65217pmic_softc *);
138
139 static uint16_t tps65217pmic_ppath_max_usb_current(uint8_t);
140 static uint16_t tps65217pmic_ppath_max_ac_current(uint8_t);
141
142 static void tps65217pmic_regulator_read_config(struct tps65217pmic_softc *,
143 struct tps_reg_param *);
144
145 static void tps65217pmic_print_ppath(struct tps65217pmic_softc *);
146 static void tps65217pmic_print_ldos(struct tps65217pmic_softc *);
147
148 static void tps65217pmic_version(struct tps65217pmic_softc *);
149
150 static void tps65217pmic_envsys_register(struct tps65217pmic_softc *);
151 static void tps65217pmic_envsys_refresh(struct sysmon_envsys *, envsys_data_t *);
152
153 static void tps65217pmic_power_monitor_init(struct tps65217pmic_softc *);
154 static void tps65217pmic_power_monitor(void *);
155
156 CFATTACH_DECL_NEW(tps65217pmic, sizeof (struct tps65217pmic_softc),
157 tps65217pmic_match, tps65217pmic_attach, NULL, NULL);
158
159 /* Possible settings of LDO1 in mV. */
160 static const uint16_t ldo1voltages[] = { 1000, 1100, 1200, 1250, 1300, 1350,
161 1400, 1500, 1600, 1800, 2500, 2750, 2800, 3000, 3100, 3300 };
162 /* Possible settings of LDO2, DCDC1, DCDC2, DCDC3 in mV. */
163 static const uint16_t ldo2voltages[] = { 900, 925, 950, 975, 1000, 1025, 1050,
164 1075, 1100, 1125, 1150, 1175, 1200, 1225, 1250, 1275, 1300, 1325, 1350,
165 1375, 1400, 1425, 1450, 1475, 1500, 1550, 1600, 1650, 1700, 1750, 1800,
166 1850, 1900, 1950, 2000, 2050, 2100, 2150, 2200, 2250, 2300, 2350, 2400,
167 2450, 2500, 2550, 2600, 2650, 2700, 2750, 2800, 2850, 2900, 3000, 3100,
168 3200, 3300, 3300, 3300, 3300, 3300, 3300, 3300, 3300 };
169 /* Possible settings of LDO3, LDO4 in mV. */
170 static const uint16_t ldo3voltages[] = { 1500, 1550, 1600, 1650, 1700, 1750,
171 1800, 1850, 1900, 2000, 2100, 2200, 2300, 2400, 2450, 2500, 2550, 2600,
172 2650, 2700, 2750, 2800, 2850, 2900,2950, 3000, 3050, 3100, 3150, 3200,
173 3250, 3300 };
174
175 static struct tps_reg_param tps_regulators[] = {
176 {
177 .name = "LDO1",
178 .voltage_min = 1000,
179 .voltage_max = 3300,
180 .voltages = ldo1voltages,
181 .nvoltages = 16,
182 .can_track = false,
183 .tracked_reg = NULL,
184 .can_xadj = false,
185 .can_ls = false,
186 .defreg_num = TPS65217PMIC_DEFLDO1,
187 .enable_bit = TPS65217PMIC_ENABLE_LDO1
188 },
189 {
190 .name = "LDO2",
191 .voltage_min = 900,
192 .voltage_max = 3300,
193 .voltages = ldo2voltages,
194 .nvoltages = 64,
195 .can_track = true,
196 .tracked_reg = &(tps_regulators[TPS65217PMIC_DCDC3]),
197 .can_xadj = false,
198 .can_ls = false,
199 .defreg_num = TPS65217PMIC_DEFLDO2,
200 .enable_bit = TPS65217PMIC_ENABLE_LDO2
201 },
202 {
203 .name = "LDO3",
204 .voltage_min = 1500,
205 .voltage_max = 3300,
206 .voltages = ldo3voltages,
207 .nvoltages = 32,
208 .can_track = false,
209 .tracked_reg = NULL,
210 .can_xadj = false,
211 .can_ls = true,
212 .defreg_num = TPS65217PMIC_DEFLDO3,
213 .enable_bit = TPS65217PMIC_ENABLE_LDO3
214 },
215 {
216 .name = "LDO4",
217 .voltage_min = 1500,
218 .voltage_max = 3300,
219 .voltages = ldo3voltages,
220 .nvoltages = 32,
221 .can_track = false,
222 .tracked_reg = NULL,
223 .can_xadj = false,
224 .can_ls = true,
225 .defreg_num = TPS65217PMIC_DEFLDO4,
226 .enable_bit = TPS65217PMIC_ENABLE_LDO4
227 },
228 {
229 .name = "DCDC1",
230 .voltage_min = 900,
231 .voltage_max = 3300,
232 .voltages = ldo2voltages,
233 .nvoltages = 64,
234 .can_track = false,
235 .tracked_reg = NULL,
236 .can_xadj = true,
237 .can_ls = false,
238 .defreg_num = TPS65217PMIC_DEFDCDC1,
239 .enable_bit = TPS65217PMIC_ENABLE_DCDC1
240 },
241 {
242 .name = "DCDC2",
243 .voltage_min = 900,
244 .voltage_max = 3300,
245 .voltages = ldo2voltages,
246 .nvoltages = 64,
247 .can_track = false,
248 .tracked_reg = NULL,
249 .can_xadj = true,
250 .can_ls = false,
251 .defreg_num = TPS65217PMIC_DEFDCDC2,
252 .enable_bit = TPS65217PMIC_ENABLE_DCDC2
253 },
254 {
255 .name = "DCDC3",
256 .voltage_min = 900,
257 .voltage_max = 3300,
258 .voltages = ldo2voltages,
259 .nvoltages = 64,
260 .can_track = false,
261 .tracked_reg = NULL,
262 .can_xadj = true,
263 .can_ls = false,
264 .defreg_num = TPS65217PMIC_DEFDCDC3,
265 .enable_bit = TPS65217PMIC_ENABLE_DCDC3
266 }
267 };
268
269 static bool matched = false;
270
271 static int
272 tps65217pmic_match(device_t parent, cfdata_t cf, void *aux)
273 {
274 struct i2c_attach_args *ia = aux;
275
276 if (ia->ia_addr == TPS65217PMIC_ADDR) {
277 /* we can only have one */
278 if (matched)
279 return 0;
280 else
281 matched = true;
282
283 return 1;
284 }
285 return 0;
286 }
287
288 static void
289 tps65217pmic_attach(device_t parent, device_t self, void *aux)
290 {
291 struct tps65217pmic_softc *sc = device_private(self);
292 struct i2c_attach_args *ia = aux;
293
294 sc->sc_dev = self;
295 sc->sc_addr = ia->ia_addr;
296 sc->sc_tag = ia->ia_tag;
297
298 tps65217pmic_version(sc);
299
300 aprint_normal(": TPS65217");
301 switch (sc->sc_version) {
302 case TPS65217PMIC_CHIPID_VER_A:
303 aprint_normal("A");
304 break;
305 case TPS65217PMIC_CHIPID_VER_B:
306 aprint_normal("B");
307 break;
308 case TPS65217PMIC_CHIPID_VER_C:
309 aprint_normal("C");
310 break;
311 case TPS65217PMIC_CHIPID_VER_D:
312 aprint_normal("D");
313 break;
314 default:
315 /* unknown version */
316 break;
317 }
318
319 aprint_normal(" Power Management Multi-Channel IC (rev 1.%d)\n",
320 sc->sc_revision);
321
322 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
323
324 sc->sc_smpsw.smpsw_name = device_xname(self);
325 sc->sc_smpsw.smpsw_type = PSWITCH_TYPE_ACADAPTER;
326 sysmon_pswitch_register(&sc->sc_smpsw);
327
328 tps65217pmic_reg_refresh(sc);
329
330 tps65217pmic_print_ppath(sc);
331 tps65217pmic_print_ldos(sc);
332
333 tps65217pmic_power_monitor_init(sc);
334
335 tps65217pmic_envsys_register(sc);
336 }
337
338 static void
339 tps65217pmic_power_monitor_init(struct tps65217pmic_softc *sc)
340 {
341 uint8_t intr, intrmask, status, ppath;
342
343 intrmask = TPS65217PMIC_INT_USBM | TPS65217PMIC_INT_ACM |
344 TPS65217PMIC_INT_PBM;
345
346 status = tps65217pmic_reg_read(sc, TPS65217PMIC_STATUS);
347 ppath = tps65217pmic_reg_read(sc, TPS65217PMIC_PPATH);
348 /* acknowledge and disregard whatever interrupt was generated earlier */
349 intr = tps65217pmic_reg_read(sc, TPS65217PMIC_INT);
350
351 sc->sc_usbstatus = status & TPS65217PMIC_STATUS_USBPWR;
352 sc->sc_acstatus = status & TPS65217PMIC_STATUS_ACPWR;
353 sc->sc_usbenabled = ppath & TPS65217PMIC_PPATH_USB_EN;
354 sc->sc_acenabled = ppath & TPS65217PMIC_PPATH_AC_EN;
355
356 if (intr & intrmask)
357 aprint_normal_dev(sc->sc_dev,
358 "WARNING: hardware interrupt enabled but not supported");
359
360 /* set up callout to poll for power source changes */
361 callout_init(&sc->sc_powerpollco, 0);
362 callout_setfunc(&sc->sc_powerpollco, tps65217pmic_power_monitor, sc);
363
364 callout_schedule(&sc->sc_powerpollco, hz);
365 }
366
367 static void
368 tps65217pmic_power_monitor(void *aux)
369 {
370 struct tps65217pmic_softc *sc;
371 uint8_t status;
372 bool usbstatus, acstatus;
373
374 sc = aux;
375
376 mutex_enter(&sc->sc_lock);
377
378 status = tps65217pmic_reg_read(sc, TPS65217PMIC_STATUS);
379 usbstatus = status & TPS65217PMIC_STATUS_USBPWR;
380 acstatus = status & TPS65217PMIC_STATUS_ACPWR;
381
382 if (usbstatus != sc->sc_usbstatus) {
383 sc->sc_usbstatus = usbstatus;
384 pmf_event_inject(NULL, PMFE_POWER_CHANGED);
385 if (usbstatus)
386 aprint_normal_dev(sc->sc_dev,
387 "USB power source connected\n");
388 else
389 aprint_normal_dev(sc->sc_dev,
390 "USB power source disconnected\n");
391 }
392
393 if (acstatus != sc->sc_acstatus) {
394 sc->sc_acstatus = acstatus;
395 pmf_event_inject(NULL, PMFE_POWER_CHANGED);
396 if (acstatus) {
397 sysmon_pswitch_event(&sc->sc_smpsw,
398 PSWITCH_EVENT_PRESSED);
399 } else {
400 sysmon_pswitch_event(&sc->sc_smpsw,
401 PSWITCH_EVENT_RELEASED);
402 }
403 }
404
405 mutex_exit(&sc->sc_lock);
406
407 callout_schedule(&sc->sc_powerpollco, hz);
408 }
409
410 static void
411 tps65217pmic_reg_refresh(struct tps65217pmic_softc *sc)
412 {
413 int i;
414 struct tps_reg_param *c_reg;
415
416 for (i = 0; i < NTPS_REG; i++) {
417 c_reg = &tps_regulators[i];
418 tps65217pmic_regulator_read_config(sc, c_reg);
419 }
420 }
421
422 /* Get version and revision of the chip. */
423 static void
424 tps65217pmic_version(struct tps65217pmic_softc *sc)
425 {
426 uint8_t chipid;
427
428 chipid = tps65217pmic_reg_read(sc, TPS65217PMIC_CHIPID);
429
430 sc->sc_version = chipid & TPS65217PMIC_CHIPID_VER_MASK;
431 sc->sc_revision = chipid & TPS65217PMIC_CHIPID_REV_MASK;
432 }
433
434 static uint16_t
435 tps65217pmic_ppath_max_ac_current(uint8_t ppath)
436 {
437 switch ((ppath & TPS65217PMIC_PPATH_IAC) >>
438 TPS65217PMIC_PPATH_IAC_RSHFIT) {
439 case TPS65217PMIC_PPATH_IAC_100MA:
440 return 100;
441 case TPS65217PMIC_PPATH_IAC_500MA:
442 return 500;
443 case TPS65217PMIC_PPATH_IAC_1300MA:
444 return 1300;
445 case TPS65217PMIC_PPATH_IAC_2500MA:
446 return 2500;
447 }
448 return 0;
449 }
450
451 static uint16_t
452 tps65217pmic_ppath_max_usb_current(uint8_t ppath)
453 {
454 switch (ppath & TPS65217PMIC_PPATH_IUSB) {
455 case TPS65217PMIC_PPATH_IUSB_100MA:
456 return 100;
457 case TPS65217PMIC_PPATH_IUSB_500MA:
458 return 500;
459 case TPS65217PMIC_PPATH_IUSB_1300MA:
460 return 1300;
461 case TPS65217PMIC_PPATH_IUSB_1800MA:
462 return 1800;
463 }
464 return 0;
465 }
466
467 /* Read regulator state and save it to tps_reg_param. */
468 static void
469 tps65217pmic_regulator_read_config(struct tps65217pmic_softc *sc, struct
470 tps_reg_param *regulator)
471 {
472 uint8_t defreg, regenable;
473 uint16_t voltage;
474
475 regenable = tps65217pmic_reg_read(sc, TPS65217PMIC_ENABLE);
476
477 if (regenable & (regulator->enable_bit))
478 regulator->is_enabled = true;
479 else {
480 regulator->is_enabled = false;
481 return;
482 }
483
484 defreg = tps65217pmic_reg_read(sc,
485 regulator->defreg_num);
486
487 switch (regulator->nvoltages) {
488 case 16:
489 voltage = regulator->voltages[defreg &
490 TPS65217PMIC_DEFX_VOLTAGE_16];
491 break;
492 case 32:
493 voltage = regulator->voltages[defreg &
494 TPS65217PMIC_DEFX_VOLTAGE_32];
495 break;
496 case 64:
497 voltage = regulator->voltages[defreg &
498 TPS65217PMIC_DEFX_VOLTAGE_64];
499 break;
500 default:
501 /* unsupported number of voltage settings? */
502 voltage = 0;
503 break;
504 }
505
506 /* Handle regulator tracking other regulator voltage. */
507 if (regulator->can_track)
508 if (defreg & TPS65217PMIC_DEFX_TRACKING) {
509 regulator->is_tracking = true;
510 voltage = 0; /* see regulator->tracked_reg */
511 }
512
513 /* Handle regulator configured into load switch mode. */
514 if (regulator->can_ls)
515 if (!(defreg & TPS65217PMIC_DEFX_LS)) {
516 regulator->is_ls = true;
517 voltage = 0;
518 }
519
520 if (regulator->can_xadj)
521 if (defreg & TPS65217PMIC_DEFX_XADJ) {
522 regulator->is_xadj = true;
523 voltage = 0;
524
525 }
526
527 /* TODO: add PGOOD checking */
528
529 regulator->current_voltage = voltage;
530 }
531
532 static void
533 tps65217pmic_print_ldos(struct tps65217pmic_softc *sc)
534 {
535 int i;
536 struct tps_reg_param *c_reg;
537
538 aprint_normal_dev(sc->sc_dev, "");
539
540 for (i = 0; i < NTPS_REG; i++) {
541 c_reg = &tps_regulators[i];
542
543 if (c_reg->is_enabled) {
544 if (c_reg->is_ls)
545 aprint_normal("[%s: LS] ", c_reg->name);
546 else if (c_reg->is_xadj)
547 aprint_normal("[%s: XADJ] ", c_reg->name);
548 else
549 aprint_normal("[%s: %d mV] ", c_reg->name,
550 c_reg->current_voltage);
551 }
552 }
553 aprint_normal("\n");
554 }
555
556 static void
557 tps65217pmic_print_ppath(struct tps65217pmic_softc *sc)
558 {
559 uint8_t status, ppath;
560
561 ppath = tps65217pmic_reg_read(sc, TPS65217PMIC_PPATH);
562 status = tps65217pmic_reg_read(sc, TPS65217PMIC_STATUS);
563
564 aprint_normal_dev(sc->sc_dev, "power sources ");
565
566 if (ppath & TPS65217PMIC_PPATH_USB_EN) {
567 if (status & TPS65217PMIC_STATUS_USBPWR)
568 aprint_normal("[USB] ");
569 else
570 aprint_normal("USB ");
571 aprint_normal("max %d mA, ",
572 tps65217pmic_ppath_max_usb_current(ppath));
573 }
574
575 if (ppath & TPS65217PMIC_PPATH_AC_EN) {
576 if (status & TPS65217PMIC_STATUS_ACPWR)
577 aprint_normal("[AC] ");
578 else
579 aprint_normal("AC ");
580 aprint_normal("max %d mA",
581 tps65217pmic_ppath_max_ac_current(ppath));
582 }
583
584 aprint_normal("\n");
585 }
586
587 static uint8_t
588 tps65217pmic_reg_read(struct tps65217pmic_softc *sc, uint8_t reg)
589 {
590 uint8_t wbuf[2];
591 uint8_t rv;
592
593 if (iic_acquire_bus(sc->sc_tag, I2C_F_POLL) != 0) {
594 aprint_error_dev(sc->sc_dev, "cannot acquire bus for read\n");
595 return 0;
596 }
597
598 wbuf[0] = reg;
599
600 if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr, wbuf,
601 1, &rv, 1, I2C_F_POLL)) {
602 aprint_error_dev(sc->sc_dev, "cannot execute operation\n");
603 iic_release_bus(sc->sc_tag, I2C_F_POLL);
604 return 0;
605 }
606 iic_release_bus(sc->sc_tag, I2C_F_POLL);
607
608 return rv;
609 }
610
611 static void __unused
612 tps65217pmic_reg_write(struct tps65217pmic_softc *sc, uint8_t reg, uint8_t data)
613 {
614 uint8_t wbuf[2];
615
616 if (iic_acquire_bus(sc->sc_tag, I2C_F_POLL) != 0) {
617 aprint_error_dev(sc->sc_dev, "cannot acquire bus for write\n");
618 return;
619 }
620
621 wbuf[0] = reg;
622 wbuf[1] = data;
623
624 if (iic_exec(sc->sc_tag, I2C_OP_WRITE_WITH_STOP, sc->sc_addr, wbuf,
625 2, NULL, 0, I2C_F_POLL)) {
626 aprint_error_dev(sc->sc_dev, "cannot execute I2C write\n");
627 iic_release_bus(sc->sc_tag, I2C_F_POLL);
628 return;
629 }
630
631 iic_release_bus(sc->sc_tag, I2C_F_POLL);
632 }
633
634 static void
635 tps65217pmic_envsys_register(struct tps65217pmic_softc *sc)
636 {
637 int i;
638
639 sc->sc_sme = sysmon_envsys_create();
640
641 /* iterate over all regulators and attach them as sensors */
642 for(i = 0; i <= SNUM_REGS; i++) {
643 /* set name */
644 strlcpy(sc->sc_regsensor[i].desc, tps_regulators[i].name,
645 sizeof(sc->sc_regsensor[i].desc));
646 sc->sc_regsensor[i].units = ENVSYS_SVOLTS_DC;
647 sc->sc_regsensor[i].state = ENVSYS_SINVALID;
648
649 if (sysmon_envsys_sensor_attach(sc->sc_sme,
650 &sc->sc_regsensor[i]))
651 aprint_error_dev(sc->sc_dev,
652 "error attaching regulator sensor %d\n", i);
653 }
654
655 /* attach power source indicators */
656 strcpy(sc->sc_usbsensor.desc, "USB power source"); /* SNUM_USBSTATUS */
657 sc->sc_usbsensor.units = ENVSYS_INDICATOR;
658 sc->sc_usbsensor.state = ENVSYS_SINVALID;
659 if (sysmon_envsys_sensor_attach(sc->sc_sme, &sc->sc_usbsensor))
660 aprint_error_dev(sc->sc_dev,
661 "error attaching USB power source sensor\n");
662 strcpy(sc->sc_acsensor.desc, "AC power source"); /* SNUM_ACSTATUS */
663 sc->sc_acsensor.units = ENVSYS_INDICATOR;
664 sc->sc_acsensor.state = ENVSYS_SINVALID;
665 if (sysmon_envsys_sensor_attach(sc->sc_sme, &sc->sc_acsensor))
666 aprint_error_dev(sc->sc_dev,
667 "error attaching AC power source sensor\n");
668
669 /* register everything in sysmon */
670 sc->sc_sme->sme_name = device_xname(sc->sc_dev);
671 sc->sc_sme->sme_cookie = sc;
672 sc->sc_sme->sme_refresh = tps65217pmic_envsys_refresh;
673
674 if (sysmon_envsys_register(sc->sc_sme)) {
675 aprint_error_dev(sc->sc_dev, "unable to register in sysmon\n");
676 sysmon_envsys_destroy(sc->sc_sme);
677 }
678 }
679
680 static void
681 tps65217pmic_envsys_refresh(struct sysmon_envsys *sme, envsys_data_t *edata)
682 {
683 struct tps65217pmic_softc *sc = sme->sme_cookie;
684
685 mutex_enter(&sc->sc_lock);
686
687 tps65217pmic_reg_refresh(sc);
688
689 if (edata->sensor <= SNUM_REGS) {
690 /* TODO: handle special cases like LS, XADJ... */
691 edata->value_cur = tps_regulators[edata->sensor].current_voltage * 1000;
692 edata->state = ENVSYS_SVALID;
693 } else if (edata->sensor == SNUM_USBSTATUS) {
694 edata->value_cur = sc->sc_usbstatus && sc->sc_usbenabled;
695 edata->state = ENVSYS_SVALID;
696 } else if (edata->sensor == SNUM_ACSTATUS) {
697 edata->value_cur = sc->sc_acstatus && sc->sc_acenabled;
698 edata->state = ENVSYS_SVALID;
699 } else
700 aprint_error_dev(sc->sc_dev, "unknown sensor number\n");
701
702 mutex_exit(&sc->sc_lock);
703 }
704
705