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