xref: /netbsd-src/sys/dev/i2c/tps65217pmic.c (revision 6a493d6bc668897c91594964a732d38505b70cbb)
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