tps65217pmic.c revision 1.4 1 /* $NetBSD: tps65217pmic.c,v 1.4 2013/04/28 00:41:22 jakllsch 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.4 2013/04/28 00:41:22 jakllsch 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
55 struct tps65217pmic_softc {
56 device_t sc_dev;
57
58 i2c_tag_t sc_tag;
59 i2c_addr_t sc_addr;
60
61 uint8_t sc_version;
62 uint8_t sc_revision;
63
64 /* envsys(4) stuff */
65 struct sysmon_envsys *sc_sme;
66 envsys_data_t sc_sensor[NTPS_REG];
67 kmutex_t sc_lock;
68 };
69
70 /* Voltage regulators */
71 enum tps_reg_num {
72 TPS65217PMIC_LDO1,
73 TPS65217PMIC_LDO2,
74 TPS65217PMIC_LDO3LS,
75 TPS65217PMIC_LDO4LS,
76 TPS65217PMIC_DCDC1,
77 TPS65217PMIC_DCDC2,
78 TPS65217PMIC_DCDC3
79 };
80
81 struct tps_reg_param {
82 /* parameters configured statically */
83
84 const char* name;
85 uint16_t voltage_min; /* in mV */
86 uint16_t voltage_max; /* in mV */
87 const uint16_t *voltages; /* all possible voltage settings */
88 uint8_t nvoltages; /* number of voltage settings */
89
90 bool can_track; /* regulator can track U of other r. */
91 struct tps_reg_param *tracked_reg; /* ptr to tracked regulator */
92 bool can_xadj; /* voltage can be adjusted externally */
93 bool can_ls; /* can be a load switch instead of r. */
94
95 uint8_t defreg_num; /* DEF register */
96 uint8_t enable_bit; /* position in ENABLE register */
97
98 /*
99 * Run-time parameters configured during attachment and later, these
100 * probably should be split into separate struct that would be a part
101 * of softc. But since we can have only one TPS chip, that should be
102 * okay for now.
103 */
104
105 bool is_enabled; /* regulator is enabled */
106 bool is_pg; /* regulator is "power good" */
107 bool is_tracking; /* voltage is tracking other reg. */
108 bool is_ls; /* is a load switch */
109 bool is_xadj; /* voltage is adjusted externally */
110
111 uint16_t current_voltage; /* in mV */
112
113 };
114
115 static int tps65217pmic_match(device_t, cfdata_t, void *);
116 static void tps65217pmic_attach(device_t, device_t, void *);
117
118 static uint8_t tps65217pmic_reg_read(struct tps65217pmic_softc *, uint8_t);
119
120 static void tps65217pmic_refresh(struct tps65217pmic_softc *);
121
122 static uint16_t tps65217pmic_ppath_max_usb_current(uint8_t);
123 static uint16_t tps65217pmic_ppath_max_ac_current(uint8_t);
124
125 static void tps65217pmic_regulator_read_config(struct tps65217pmic_softc *,
126 struct tps_reg_param *);
127
128 static void tps65217pmic_print_ppath(struct tps65217pmic_softc *);
129 static void tps65217pmic_print_ldos(struct tps65217pmic_softc *);
130
131 static void tps65217pmic_version(struct tps65217pmic_softc *);
132
133 static void tps65217pmic_envsys_register(struct tps65217pmic_softc *);
134 static void tps65217pmic_envsys_refresh(struct sysmon_envsys *, envsys_data_t *);
135
136 CFATTACH_DECL_NEW(tps65217pmic, sizeof (struct tps65217pmic_softc),
137 tps65217pmic_match, tps65217pmic_attach, NULL, NULL);
138
139 /* Possible settings of LDO1 in mV. */
140 static const uint16_t ldo1voltages[] = { 1000, 1100, 1200, 1250, 1300, 1350,
141 1400, 1500, 1600, 1800, 2500, 2750, 2800, 3000, 3100, 3300 };
142 /* Possible settings of LDO2, DCDC1, DCDC2, DCDC3 in mV. */
143 static const uint16_t ldo2voltages[] = { 900, 925, 950, 975, 1000, 1025, 1050,
144 1075, 1100, 1125, 1150, 1175, 1200, 1225, 1250, 1275, 1300, 1325, 1350,
145 1375, 1400, 1425, 1450, 1475, 1500, 1550, 1600, 1650, 1700, 1750, 1800,
146 1850, 1900, 1950, 2000, 2050, 2100, 2150, 2200, 2250, 2300, 2350, 2400,
147 2450, 2500, 2550, 2600, 2650, 2700, 2750, 2800, 2850, 2900, 3000, 3100,
148 3200, 3300, 3300, 3300, 3300, 3300, 3300, 3300, 3300 };
149 /* Possible settings of LDO3, LDO4 in mV. */
150 static const uint16_t ldo3voltages[] = { 1500, 1550, 1600, 1650, 1700, 1750,
151 1800, 1850, 1900, 2000, 2100, 2200, 2300, 2400, 2450, 2500, 2550, 2600,
152 2650, 2700, 2750, 2800, 2850, 2900,2950, 3000, 3050, 3100, 3150, 3200,
153 3250, 3300 };
154
155 static struct tps_reg_param tps_regulators[] = {
156 {
157 .name = "LDO1",
158 .voltage_min = 1000,
159 .voltage_max = 3300,
160 .voltages = ldo1voltages,
161 .nvoltages = 16,
162 .can_track = false,
163 .tracked_reg = NULL,
164 .can_xadj = false,
165 .can_ls = false,
166 .defreg_num = TPS65217PMIC_DEFLDO1,
167 .enable_bit = TPS65217PMIC_ENABLE_LDO1
168 },
169 {
170 .name = "LDO2",
171 .voltage_min = 900,
172 .voltage_max = 3300,
173 .voltages = ldo2voltages,
174 .nvoltages = 64,
175 .can_track = true,
176 .tracked_reg = &(tps_regulators[TPS65217PMIC_DCDC3]),
177 .can_xadj = false,
178 .can_ls = false,
179 .defreg_num = TPS65217PMIC_DEFLDO2,
180 .enable_bit = TPS65217PMIC_ENABLE_LDO2
181 },
182 {
183 .name = "LDO3",
184 .voltage_min = 1500,
185 .voltage_max = 3300,
186 .voltages = ldo3voltages,
187 .nvoltages = 32,
188 .can_track = false,
189 .tracked_reg = NULL,
190 .can_xadj = false,
191 .can_ls = true,
192 .defreg_num = TPS65217PMIC_DEFLDO3,
193 .enable_bit = TPS65217PMIC_ENABLE_LDO3
194 },
195 {
196 .name = "LDO4",
197 .voltage_min = 1500,
198 .voltage_max = 3300,
199 .voltages = ldo3voltages,
200 .nvoltages = 32,
201 .can_track = false,
202 .tracked_reg = NULL,
203 .can_xadj = false,
204 .can_ls = true,
205 .defreg_num = TPS65217PMIC_DEFLDO4,
206 .enable_bit = TPS65217PMIC_ENABLE_LDO4
207 },
208 {
209 .name = "DCDC1",
210 .voltage_min = 900,
211 .voltage_max = 3300,
212 .voltages = ldo2voltages,
213 .nvoltages = 64,
214 .can_track = false,
215 .tracked_reg = NULL,
216 .can_xadj = true,
217 .can_ls = false,
218 .defreg_num = TPS65217PMIC_DEFDCDC1,
219 .enable_bit = TPS65217PMIC_ENABLE_DCDC1
220 },
221 {
222 .name = "DCDC2",
223 .voltage_min = 900,
224 .voltage_max = 3300,
225 .voltages = ldo2voltages,
226 .nvoltages = 64,
227 .can_track = false,
228 .tracked_reg = NULL,
229 .can_xadj = true,
230 .can_ls = false,
231 .defreg_num = TPS65217PMIC_DEFDCDC2,
232 .enable_bit = TPS65217PMIC_ENABLE_DCDC2
233 },
234 {
235 .name = "DCDC3",
236 .voltage_min = 900,
237 .voltage_max = 3300,
238 .voltages = ldo2voltages,
239 .nvoltages = 64,
240 .can_track = false,
241 .tracked_reg = NULL,
242 .can_xadj = true,
243 .can_ls = false,
244 .defreg_num = TPS65217PMIC_DEFDCDC3,
245 .enable_bit = TPS65217PMIC_ENABLE_DCDC3
246 }
247 };
248
249 static bool matched = false;
250
251 static int
252 tps65217pmic_match(device_t parent, cfdata_t cf, void *aux)
253 {
254 struct i2c_attach_args *ia = aux;
255
256 if (ia->ia_addr == TPS65217PMIC_ADDR) {
257 /* we can only have one */
258 if (matched)
259 return 0;
260 else
261 matched = true;
262
263 return 1;
264 }
265 return 0;
266 }
267
268 static void
269 tps65217pmic_attach(device_t parent, device_t self, void *aux)
270 {
271 struct tps65217pmic_softc *sc = device_private(self);
272 struct i2c_attach_args *ia = aux;
273
274 sc->sc_dev = self;
275 sc->sc_addr = ia->ia_addr;
276 sc->sc_tag = ia->ia_tag;
277
278 tps65217pmic_version(sc);
279
280 aprint_normal(": TPS65217");
281 switch (sc->sc_version) {
282 case TPS65217PMIC_CHIPID_VER_A:
283 aprint_normal("A");
284 break;
285 case TPS65217PMIC_CHIPID_VER_B:
286 aprint_normal("B");
287 break;
288 case TPS65217PMIC_CHIPID_VER_C:
289 aprint_normal("C");
290 break;
291 case TPS65217PMIC_CHIPID_VER_D:
292 aprint_normal("D");
293 break;
294 default:
295 /* unknown version */
296 break;
297 }
298
299 aprint_normal(" Power Management Multi-Channel IC (rev 1.%d)\n",
300 sc->sc_revision);
301
302 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
303
304 tps65217pmic_refresh(sc);
305
306 tps65217pmic_print_ppath(sc);
307 tps65217pmic_print_ldos(sc);
308
309 tps65217pmic_envsys_register(sc);
310 }
311
312 static void
313 tps65217pmic_refresh(struct tps65217pmic_softc *sc)
314 {
315 int i;
316 struct tps_reg_param *c_reg;
317
318 for (i = 0; i < NTPS_REG; i++) {
319 c_reg = &tps_regulators[i];
320 tps65217pmic_regulator_read_config(sc, c_reg);
321 }
322 }
323
324 /* Get version and revision of the chip. */
325 static void
326 tps65217pmic_version(struct tps65217pmic_softc *sc)
327 {
328 uint8_t chipid;
329
330 chipid = tps65217pmic_reg_read(sc, TPS65217PMIC_CHIPID);
331
332 sc->sc_version = chipid & TPS65217PMIC_CHIPID_VER_MASK;
333 sc->sc_revision = chipid & TPS65217PMIC_CHIPID_REV_MASK;
334 }
335
336 static uint16_t
337 tps65217pmic_ppath_max_ac_current(uint8_t ppath)
338 {
339 switch ((ppath & TPS65217PMIC_PPATH_IAC) >>
340 TPS65217PMIC_PPATH_IAC_RSHFIT) {
341 case TPS65217PMIC_PPATH_IAC_100MA:
342 return 100;
343 case TPS65217PMIC_PPATH_IAC_500MA:
344 return 300;
345 case TPS65217PMIC_PPATH_IAC_1300MA:
346 return 1300;
347 case TPS65217PMIC_PPATH_IAC_2500MA:
348 return 2500;
349 }
350 return 0;
351 }
352
353 static uint16_t
354 tps65217pmic_ppath_max_usb_current(uint8_t ppath)
355 {
356 switch (ppath & TPS65217PMIC_PPATH_IUSB) {
357 case TPS65217PMIC_PPATH_IUSB_100MA:
358 return 100;
359 case TPS65217PMIC_PPATH_IUSB_500MA:
360 return 300;
361 case TPS65217PMIC_PPATH_IUSB_1300MA:
362 return 1300;
363 case TPS65217PMIC_PPATH_IUSB_1800MA:
364 return 1800;
365 }
366 return 0;
367 }
368
369 /* Read regulator state and save it to tps_reg_param. */
370 static void
371 tps65217pmic_regulator_read_config(struct tps65217pmic_softc *sc, struct
372 tps_reg_param *regulator)
373 {
374 uint8_t defreg, regenable;
375 uint16_t voltage;
376
377 regenable = tps65217pmic_reg_read(sc, TPS65217PMIC_ENABLE);
378
379 if (regenable & (regulator->enable_bit))
380 regulator->is_enabled = true;
381 else {
382 regulator->is_enabled = false;
383 return;
384 }
385
386 defreg = tps65217pmic_reg_read(sc,
387 regulator->defreg_num);
388
389 switch (regulator->nvoltages) {
390 case 16:
391 voltage = regulator->voltages[defreg &
392 TPS65217PMIC_DEFX_VOLTAGE_16];
393 break;
394 case 32:
395 voltage = regulator->voltages[defreg &
396 TPS65217PMIC_DEFX_VOLTAGE_32];
397 break;
398 case 64:
399 voltage = regulator->voltages[defreg &
400 TPS65217PMIC_DEFX_VOLTAGE_64];
401 break;
402 default:
403 /* unsupported number of voltage settings? */
404 voltage = 0;
405 break;
406 }
407
408 /* Handle regulator tracking other regulator voltage. */
409 if (regulator->can_track)
410 if (defreg & TPS65217PMIC_DEFX_TRACKING) {
411 regulator->is_tracking = true;
412 voltage = 0; /* see regulator->tracked_reg */
413 }
414
415 /* Handle regulator configured into load switch mode. */
416 if (regulator->can_ls)
417 if (!(defreg & TPS65217PMIC_DEFX_LS)) {
418 regulator->is_ls = true;
419 voltage = 0;
420 }
421
422 if (regulator->can_xadj)
423 if (defreg & TPS65217PMIC_DEFX_XADJ) {
424 regulator->is_xadj = true;
425 voltage = 0;
426
427 }
428
429 /* TODO: add PGOOD checking */
430
431 regulator->current_voltage = voltage;
432 }
433
434 static void
435 tps65217pmic_print_ldos(struct tps65217pmic_softc *sc)
436 {
437 int i;
438 struct tps_reg_param *c_reg;
439
440 aprint_normal_dev(sc->sc_dev, "");
441
442 for (i = 0; i < NTPS_REG; i++) {
443 c_reg = &tps_regulators[i];
444
445 if (c_reg->is_enabled) {
446 if (c_reg->is_ls)
447 aprint_normal("[%s: LS] ", c_reg->name);
448 else if (c_reg->is_xadj)
449 aprint_normal("[%s: XADJ] ", c_reg->name);
450 else
451 aprint_normal("[%s: %d mV] ", c_reg->name,
452 c_reg->current_voltage);
453 }
454 }
455 aprint_normal("\n");
456 }
457
458 static void
459 tps65217pmic_print_ppath(struct tps65217pmic_softc *sc)
460 {
461 uint8_t status, ppath, regenable;
462
463 ppath = tps65217pmic_reg_read(sc, TPS65217PMIC_PPATH);
464 status = tps65217pmic_reg_read(sc, TPS65217PMIC_STATUS);
465 regenable = tps65217pmic_reg_read(sc, TPS65217PMIC_ENABLE);
466
467 aprint_normal_dev(sc->sc_dev, "power sources ");
468
469 if (ppath & TPS65217PMIC_PPATH_USB_EN) {
470 if (status & TPS65217PMIC_STATUS_USBPWR)
471 aprint_normal("[USB] ");
472 else
473 aprint_normal("USB ");
474 aprint_normal("max %d mA, ",
475 tps65217pmic_ppath_max_usb_current(ppath));
476 }
477
478 if (ppath & TPS65217PMIC_PPATH_AC_EN) {
479 if (status & TPS65217PMIC_STATUS_ACPWR)
480 aprint_normal("[AC] ");
481 else
482 aprint_normal("AC ");
483 aprint_normal("max %d mA",
484 tps65217pmic_ppath_max_ac_current(ppath));
485 }
486
487 aprint_normal("\n");
488 }
489
490 static uint8_t
491 tps65217pmic_reg_read(struct tps65217pmic_softc *sc, uint8_t reg)
492 {
493 uint8_t wbuf[2];
494 uint8_t rv;
495
496 if (iic_acquire_bus(sc->sc_tag, I2C_F_POLL) != 0) {
497 aprint_error_dev(sc->sc_dev, "cannot acquire bus for read\n");
498 return 0;
499 }
500
501 wbuf[0] = reg;
502
503 if (iic_exec(sc->sc_tag, I2C_OP_READ_WITH_STOP, sc->sc_addr, wbuf,
504 1, &rv, 1, I2C_F_POLL)) {
505 aprint_error_dev(sc->sc_dev, "cannot execute operation\n");
506 iic_release_bus(sc->sc_tag, I2C_F_POLL);
507 return 0;
508 }
509 iic_release_bus(sc->sc_tag, I2C_F_POLL);
510
511 return rv;
512 }
513
514 static void
515 tps65217pmic_envsys_register(struct tps65217pmic_softc *sc)
516 {
517 int i;
518
519 sc->sc_sme = sysmon_envsys_create();
520
521 /* iterate over all regulators and register them as sensors */
522 for(i = 0; i < NTPS_REG; i++) {
523 /* set name */
524 strlcpy(sc->sc_sensor[i].desc, tps_regulators[i].name,
525 sizeof(sc->sc_sensor[i].desc));
526 sc->sc_sensor[i].units = ENVSYS_SVOLTS_DC;
527 sc->sc_sensor[i].state = ENVSYS_SINVALID;
528
529 if (sysmon_envsys_sensor_attach(sc->sc_sme, &sc->sc_sensor[i]))
530 aprint_error_dev(sc->sc_dev,
531 "error attaching sensor %d\n", i);
532 }
533
534 sc->sc_sme->sme_name = device_xname(sc->sc_dev);
535 sc->sc_sme->sme_cookie = sc;
536 sc->sc_sme->sme_refresh = tps65217pmic_envsys_refresh;
537
538 if (sysmon_envsys_register(sc->sc_sme)) {
539 aprint_error_dev(sc->sc_dev, "unable to register in sysmon\n");
540 sysmon_envsys_destroy(sc->sc_sme);
541 }
542 }
543
544 static void
545 tps65217pmic_envsys_refresh(struct sysmon_envsys *sme, envsys_data_t *edata)
546 {
547 struct tps65217pmic_softc *sc = sme->sme_cookie;
548
549 mutex_enter(&sc->sc_lock);
550
551 tps65217pmic_refresh(sc);
552
553 /* TODO: handle special cases like LS, XADJ... */
554 edata->value_cur = tps_regulators[edata->sensor].current_voltage * 1000;
555 edata->state = ENVSYS_SVALID;
556
557 mutex_exit(&sc->sc_lock);
558 }
559
560