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