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