]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/regulator/twl4030-regulator.c
h63xx: initial omap board support.
[linux-2.6-omap-h63xx.git] / drivers / regulator / twl4030-regulator.c
1 /*
2  * twl4030-regulator.c -- support regulators in twl4030 family chips
3  *
4  * Copyright (C) 2008 David Brownell
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  */
11
12 #include <linux/module.h>
13 #include <linux/init.h>
14 #include <linux/err.h>
15 #include <linux/platform_device.h>
16 #include <linux/regulator/driver.h>
17 #include <linux/regulator/machine.h>
18 #include <linux/i2c/twl4030.h>
19
20
21 /*
22  * The TWL4030/TW5030/TPS659x0 family chips include power management, a
23  * USB OTG transceiver, an RTC, ADC, PWM, and lots more.  Some versions
24  * include an audio codec, battery charger, and more voltage regulators.
25  * These chips are often used in OMAP-based systems.
26  *
27  * This driver implements software-based resource control for various
28  * voltage regulators.  This is usually augmented with state machine
29  * based control.
30  */
31
32 struct twlreg_info {
33         /* start of regulator's PM_RECEIVER control register bank */
34         u8                      base;
35
36         /* twl4030 resource ID, for resource control state machine */
37         u8                      id;
38
39         /* voltage in mV = table[VSEL]; table_len must be a power-of-two */
40         u8                      table_len;
41         const u16               *table;
42
43         /* chip constraints on regulator behavior */
44         u16                     min_mV;
45         u16                     max_mV;
46
47         /* used by regulator core */
48         struct regulator_desc   desc;
49 };
50
51 #ifndef REGULATOR_MODE_OFF
52 #define REGULATOR_MODE_OFF 0
53 #endif
54
55
56 /* LDO control registers ... offset is from the base of its register bank.
57  * The first three registers of all power resource banks help hardware to
58  * manage the various resource groups.
59  */
60 #define VREG_GRP                0
61 #define VREG_TYPE               1
62 #define VREG_REMAP              2
63 #define VREG_DEDICATED          3       /* LDO control */
64
65
66 static inline int
67 twl4030reg_read(struct twlreg_info *info, unsigned offset)
68 {
69         u8 value;
70         int status;
71
72         status = twl4030_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER,
73                         &value, info->base + offset);
74         return (status < 0) ? status : value;
75 }
76
77 static inline int
78 twl4030reg_write(struct twlreg_info *info, unsigned offset, u8 value)
79 {
80         return twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
81                         value, info->base + offset);
82 }
83
84 /*----------------------------------------------------------------------*/
85
86 /* generic power resource operations, which work on all regulators */
87
88 static int twl4030reg_grp(struct regulator_dev *rdev)
89 {
90         return twl4030reg_read(rdev_get_drvdata(rdev), VREG_GRP);
91 }
92
93 static int twl4030reg_is_enabled(struct regulator_dev *rdev)
94 {
95         int     state = twl4030reg_grp(rdev);
96
97         if (state < 0)
98                 return state;
99
100         /* resource state == OFF (vs SLEEP or ACTIVE) */
101         return (state & 0x0f) != 0;
102 }
103
104 /*
105  * Enable/disable regulators by joining/leaving the P1 (processor) group.
106  * We assume nobody else is updating the DEV_GRP registers.
107  */
108
109 #define P3_GRP          BIT(7)          /* "peripherals" */
110 #define P2_GRP          BIT(6)          /* secondary processor, modem, etc */
111 #define P1_GRP          BIT(5)          /* CPU/Linux */
112
113 static int twl4030reg_enable(struct regulator_dev *rdev)
114 {
115         struct twlreg_info      *info = rdev_get_drvdata(rdev);
116         int                     grp;
117
118         grp = twl4030reg_read(info, VREG_GRP);
119         if (grp < 0)
120                 return grp;
121
122         grp |= P1_GRP;
123         return twl4030reg_write(info, VREG_GRP, grp);
124 }
125
126 static int twl4030reg_disable(struct regulator_dev *rdev)
127 {
128         struct twlreg_info      *info = rdev_get_drvdata(rdev);
129         int                     grp;
130
131         grp = twl4030reg_read(info, VREG_GRP);
132         if (grp < 0)
133                 return grp;
134
135         grp &= ~P1_GRP;
136         return twl4030reg_write(info, VREG_GRP, grp);
137 }
138
139 static unsigned twl4030reg_get_mode(struct regulator_dev *rdev)
140 {
141         int     state = twl4030reg_grp(rdev);
142
143         if (state < 0)
144                 return state;
145         state &= 0x0f;
146
147         /* assume state != WARM_RESET; we'd not be running...  */
148         if (!state)
149                 return REGULATOR_MODE_OFF;
150         return (state & BIT(3))
151                 ? REGULATOR_MODE_NORMAL
152                 : REGULATOR_MODE_STANDBY;
153 }
154
155 static int twl4030reg_set_mode(struct regulator_dev *rdev, unsigned mode)
156 {
157         struct twlreg_info      *info = rdev_get_drvdata(rdev);
158         unsigned                message;
159         int                     status;
160
161         /* We can only set the mode through state machine commands... */
162         switch (mode) {
163         case REGULATOR_MODE_NORMAL:
164                 message = MSG_SINGULAR(DEV_GRP_P1, info->id, RES_STATE_ACTIVE);
165                 break;
166         case REGULATOR_MODE_STANDBY:
167                 message = MSG_SINGULAR(DEV_GRP_P1, info->id, RES_STATE_SLEEP);
168                 break;
169         default:
170                 return -EINVAL;
171         }
172
173         /* Ensure the resource is associated with some group */
174         status = twl4030reg_grp(rdev);
175         if (status < 0)
176                 return status;
177         if (!(status & (P3_GRP | P2_GRP | P1_GRP)))
178                 return -EACCES;
179
180         status = twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER,
181                         message >> 8, 0x15 /* PB_WORD_MSB */ );
182         if (status >= 0)
183                 return status;
184
185         return twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER,
186                         message, 0x16 /* PB_WORD_LSB */ );
187 }
188
189 /*----------------------------------------------------------------------*/
190
191 /*
192  * Support for adjustable-voltage LDOs uses a four bit (or less) voltage
193  * select field in its control register.   We use tables indexed by VSEL
194  * to record voltages in milliVolts.  (Accuracy is about three percent.)
195  *
196  * Note that VSEL values for VAUX2 changed in twl5030 and newer silicon;
197  * currently handled by listing two slightly different VAUX2 regulators,
198  * only one of which will be configured.
199  *
200  * VSEL values documented as "TI cannot support these values" are flagged
201  * in these tables as UNSUP() values; we normally won't assign them.
202  */
203 #ifdef CONFIG_TWL4030_ALLOW_UNSUPPORTED
204 #define UNSUP_MASK      0x0000
205 #else
206 #define UNSUP_MASK      0x8000
207 #endif
208
209 #define UNSUP(x)        (UNSUP_MASK | (x))
210 #define IS_UNSUP(x)     (UNSUP_MASK & (x))
211 #define LDO_MV(x)       (~UNSUP_MASK & (x))
212
213
214 static const u16 VAUX1_VSEL_table[] = {
215         UNSUP(1500), UNSUP(1800), 2500, 2800,
216         3000, 3000, 3000, 3000,
217 };
218 static const u16 VAUX2_4030_VSEL_table[] = {
219         UNSUP(1000), UNSUP(1000), UNSUP(1200), 1300,
220         1500, 1800, UNSUP(1850), 2500,
221         UNSUP(2600), 2800, UNSUP(2850), UNSUP(3000),
222         UNSUP(3150), UNSUP(3150), UNSUP(3150), UNSUP(3150),
223 };
224 static const u16 VAUX2_VSEL_table[] = {
225         1700, 1700, 1900, 1300,
226         1500, 1800, 2000, 2500,
227         2100, 2800, 2200, 2300,
228         2400, 2400, 2400, 2400,
229 };
230 static const u16 VAUX3_VSEL_table[] = {
231         1500, 1800, 2500, 2800,
232         UNSUP(3000), UNSUP(3000), UNSUP(3000), UNSUP(3000),
233 };
234 static const u16 VAUX4_VSEL_table[] = {
235         700, 1000, 1200, UNSUP(1300),
236         1500, 1800, UNSUP(1850), 2500,
237 };
238 static const u16 VMMC1_VSEL_table[] = {
239         1850, 2850, 3000, 3150,
240 };
241 static const u16 VMMC2_VSEL_table[] = {
242         UNSUP(1000), UNSUP(1000), UNSUP(1200), UNSUP(1300),
243         UNSUP(1500), UNSUP(1800), 1850, UNSUP(2500),
244         2600, 2800, 2850, 3000,
245         3150, 3150, 3150, 3150,
246 };
247 static const u16 VPLL1_VSEL_table[] = {
248         1000, 1200, 1300, 1800,
249         UNSUP(2800), UNSUP(3000), UNSUP(3000), UNSUP(3000),
250 };
251 static const u16 VPLL2_VSEL_table[] = {
252         700, 1000, 1200, 1300,
253         UNSUP(1500), 1800, UNSUP(1850), UNSUP(2500),
254         UNSUP(2600), UNSUP(2800), UNSUP(2850), UNSUP(3000),
255         UNSUP(3150), UNSUP(3150), UNSUP(3150), UNSUP(3150),
256 };
257 static const u16 VSIM_VSEL_table[] = {
258         UNSUP(1000), UNSUP(1200), UNSUP(1300), 1800,
259         2800, 3000, 3000, 3000,
260 };
261 static const u16 VDAC_VSEL_table[] = {
262         1200, 1300, 1800, 1800,
263 };
264
265
266 static int
267 twl4030ldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV)
268 {
269         struct twlreg_info      *info = rdev_get_drvdata(rdev);
270         int                     vsel;
271
272         for (vsel = 0; vsel < info->table_len; vsel++) {
273                 int mV = info->table[vsel];
274                 int uV;
275
276                 if (IS_UNSUP(mV))
277                         continue;
278                 uV = LDO_MV(mV) * 1000;
279
280                 /* use the first in-range value */
281                 if (min_uV <= uV && uV <= max_uV)
282                         return twl4030reg_write(info, VREG_DEDICATED, vsel);
283         }
284
285         return -EDOM;
286 }
287
288 static int twl4030ldo_get_voltage(struct regulator_dev *rdev)
289 {
290         struct twlreg_info      *info = rdev_get_drvdata(rdev);
291         int                     vsel = twl4030reg_read(info, VREG_DEDICATED);
292
293         if (vsel < 0)
294                 return vsel;
295
296         vsel &= info->table_len - 1;
297         return LDO_MV(info->table[vsel]) * 1000;
298 }
299
300 static struct regulator_ops twl4030ldo_ops = {
301         .set_voltage    = twl4030ldo_set_voltage,
302         .get_voltage    = twl4030ldo_get_voltage,
303
304         .enable         = twl4030reg_enable,
305         .disable        = twl4030reg_disable,
306         .is_enabled     = twl4030reg_is_enabled,
307
308         .set_mode       = twl4030reg_set_mode,
309         .get_mode       = twl4030reg_get_mode,
310 };
311
312 /*----------------------------------------------------------------------*/
313
314 /*
315  * Fixed voltage LDOs don't have a VSEL field to update.
316  */
317 static int twl4030fixed_get_voltage(struct regulator_dev *rdev)
318 {
319         struct twlreg_info      *info = rdev_get_drvdata(rdev);
320
321         return info->min_mV * 1000;
322 }
323
324 static struct regulator_ops twl4030fixed_ops = {
325         .get_voltage    = twl4030fixed_get_voltage,
326
327         .enable         = twl4030reg_enable,
328         .disable        = twl4030reg_disable,
329         .is_enabled     = twl4030reg_is_enabled,
330
331         .set_mode       = twl4030reg_set_mode,
332         .get_mode       = twl4030reg_get_mode,
333 };
334
335 /*----------------------------------------------------------------------*/
336
337 #define TWL_ADJUSTABLE_LDO(label, offset, num) { \
338         .base = offset, \
339         .id = num, \
340         .table_len = ARRAY_SIZE(label##_VSEL_table), \
341         .table = label##_VSEL_table, \
342         .desc = { \
343                 .name = #label, \
344                 .id = TWL4030_REG_##label, \
345                 .ops = &twl4030ldo_ops, \
346                 .type = REGULATOR_VOLTAGE, \
347                 .owner = THIS_MODULE, \
348                 }, \
349         }
350
351 #define TWL_FIXED_LDO(label, offset, mVolts, num) { \
352         .base = offset, \
353         .id = num, \
354         .min_mV = mVolts, \
355         .max_mV = mVolts, \
356         .desc = { \
357                 .name = #label, \
358                 .id = TWL4030_REG_##label, \
359                 .ops = &twl4030fixed_ops, \
360                 .type = REGULATOR_VOLTAGE, \
361                 .owner = THIS_MODULE, \
362                 }, \
363         }
364
365 /*
366  * We list regulators here if systems need some level of
367  * software control over them after boot.
368  */
369 static struct twlreg_info twl4030_regs[] = {
370         TWL_ADJUSTABLE_LDO(VAUX1, 0x17, 1),
371         TWL_ADJUSTABLE_LDO(VAUX2_4030, 0x1b, 2),
372         TWL_ADJUSTABLE_LDO(VAUX2, 0x1b, 2),
373         TWL_ADJUSTABLE_LDO(VAUX3, 0x1f, 3),
374         TWL_ADJUSTABLE_LDO(VAUX4, 0x23, 4),
375         TWL_ADJUSTABLE_LDO(VMMC1, 0x27, 5),
376         TWL_ADJUSTABLE_LDO(VMMC2, 0x2b, 6),
377         /*
378         TWL_ADJUSTABLE_LDO(VPLL1, 0x2f, 7),
379         TWL_ADJUSTABLE_LDO(VPLL2, 0x33, 8),
380         */
381         TWL_ADJUSTABLE_LDO(VSIM, 0x37, 9),
382         TWL_ADJUSTABLE_LDO(VDAC, 0x3b, 10),
383         /*
384         TWL_ADJUSTABLE_LDO(VINTANA1, 0x3f, 11),
385         TWL_ADJUSTABLE_LDO(VINTANA2, 0x43, 12),
386         TWL_ADJUSTABLE_LDO(VINTDIG, 0x47, 13),
387         TWL_SMPS(VIO, 0x4b, 14),
388         TWL_SMPS(VDD1, 0x55, 15),
389         TWL_SMPS(VDD2, 0x63, 16),
390          */
391         TWL_FIXED_LDO(VUSB1V5, 0x71, 1500, 17),
392         TWL_FIXED_LDO(VUSB1V8, 0x74, 1800, 18),
393         TWL_FIXED_LDO(VUSB3V1, 0x77, 3100, 19),
394         /* VUSBCP is managed *only* by the USB subchip */
395 };
396
397 static int twl4030reg_probe(struct platform_device *pdev)
398 {
399         int                             i;
400         struct twlreg_info              *info;
401         struct regulator_init_data      *initdata;
402         struct regulation_constraints   *c;
403         struct regulator_dev            *rdev;
404         int                             min_uV, max_uV;
405
406         for (i = 0, info = NULL; i < ARRAY_SIZE(twl4030_regs); i++) {
407                 if (twl4030_regs[i].desc.id != pdev->id)
408                         continue;
409                 info = twl4030_regs + i;
410                 min_uV = info->min_mV * 1000;
411                 max_uV = info->max_mV * 1000;
412                 break;
413         }
414         if (!info)
415                 return -ENODEV;
416
417         initdata = pdev->dev.platform_data;
418         if (!initdata)
419                 return -EINVAL;
420
421         /* Constrain board-specific capabilities according to what
422          * this driver and the chip itself can actually do.
423          */
424         c = &initdata->constraints;
425         if (!c->min_uV || c->min_uV < min_uV)
426                 c->min_uV = min_uV;
427         if (!c->max_uV || c->max_uV > max_uV)
428                 c->max_uV = max_uV;
429         c->valid_modes_mask &= REGULATOR_MODE_NORMAL
430                                 | REGULATOR_MODE_STANDBY
431                                 | REGULATOR_MODE_OFF;
432         c->valid_ops_mask &= REGULATOR_CHANGE_VOLTAGE
433                                 | REGULATOR_CHANGE_MODE
434                                 | REGULATOR_CHANGE_STATUS;
435
436         rdev = regulator_register(&info->desc, &pdev->dev, info);
437         if (IS_ERR(rdev)) {
438                 dev_err(&pdev->dev, "can't register %s, %ld\n",
439                                 info->desc.name, PTR_ERR(rdev));
440                 return PTR_ERR(rdev);
441         }
442         platform_set_drvdata(pdev, rdev);
443
444         /* NOTE:  many regulators support short-circuit IRQs (presentable
445          * as REGULATOR_OVER_CURRENT notifications?) configured via:
446          *  - SC_CONFIG
447          *  - SC_DETECT1 (vintana2, vmmc1/2, vaux1/2/3/4)
448          *  - SC_DETECT2 (vusb, vdac, vio, vdd1/2, vpll2)
449          *  - IT_CONFIG
450          */
451
452         return 0;
453 }
454
455 static int __devexit twl4030reg_remove(struct platform_device *pdev)
456 {
457         regulator_unregister(platform_get_drvdata(pdev));
458         return 0;
459 }
460
461 MODULE_ALIAS("platform:twl4030_reg");
462
463 static struct platform_driver twl4030reg_driver = {
464         .probe          = twl4030reg_probe,
465         .remove         = __devexit_p(twl4030reg_remove),
466         /* NOTE: short name, to work around driver model truncation of
467          * "twl4030_regulator.12" (and friends) to "twl4030_regulator.1".
468          */
469         .driver.name    = "twl4030_reg",
470         .driver.owner   = THIS_MODULE,
471 };
472
473 static int __init twl4030reg_init(void)
474 {
475         unsigned i, j;
476
477         /* determine min/max voltage constraints, taking into account
478          * whether set_voltage() will use the "unsupported" settings
479          */
480         for (i = 0; i < ARRAY_SIZE(twl4030_regs); i++) {
481                 struct twlreg_info      *info = twl4030_regs + i;
482                 const u16               *table;
483
484                 /* fixed-voltage regulators */
485                 if (!info->table_len)
486                         continue;
487
488                 /* LDO regulators: */
489                 for (j = 0, table = info->table;
490                                 j < info->table_len;
491                                 j++, table++) {
492                         u16             mV = *table;
493
494                         if (IS_UNSUP(mV))
495                                 continue;
496                         mV = LDO_MV(mV);
497
498                         if (info->min_mV == 0 || info->min_mV > mV)
499                                 info->min_mV = mV;
500                         if (info->max_mV < mV)
501                                 info->max_mV = mV;
502                 }
503         }
504
505         return platform_driver_register(&twl4030reg_driver);
506 }
507 subsys_initcall(twl4030reg_init);
508
509 static void __exit twl4030reg_exit(void)
510 {
511         platform_driver_unregister(&twl4030reg_driver);
512 }
513 module_exit(twl4030reg_exit)
514
515 MODULE_DESCRIPTION("TWL4030 regulator driver");
516 MODULE_LICENSE("GPL");