aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/regulator
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/regulator')
-rw-r--r--drivers/regulator/twl-regulator.c189
1 files changed, 97 insertions, 92 deletions
diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c
index 8cc46e99ccca..8e1b68a20ef0 100644
--- a/drivers/regulator/twl-regulator.c
+++ b/drivers/regulator/twl-regulator.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * twl4030-regulator.c -- support regulators in twl4030 family chips 2 * twl-regulator.c -- support regulators in twl4030/twl6030 family chips
3 * 3 *
4 * Copyright (C) 2008 David Brownell 4 * Copyright (C) 2008 David Brownell
5 * 5 *
@@ -19,7 +19,7 @@
19 19
20 20
21/* 21/*
22 * The TWL4030/TW5030/TPS659x0 family chips include power management, a 22 * The TWL4030/TW5030/TPS659x0/TWL6030 family chips include power management, a
23 * USB OTG transceiver, an RTC, ADC, PWM, and lots more. Some versions 23 * USB OTG transceiver, an RTC, ADC, PWM, and lots more. Some versions
24 * include an audio codec, battery charger, and more voltage regulators. 24 * include an audio codec, battery charger, and more voltage regulators.
25 * These chips are often used in OMAP-based systems. 25 * These chips are often used in OMAP-based systems.
@@ -33,7 +33,7 @@ struct twlreg_info {
33 /* start of regulator's PM_RECEIVER control register bank */ 33 /* start of regulator's PM_RECEIVER control register bank */
34 u8 base; 34 u8 base;
35 35
36 /* twl4030 resource ID, for resource control state machine */ 36 /* twl resource ID, for resource control state machine */
37 u8 id; 37 u8 id;
38 38
39 /* voltage in mV = table[VSEL]; table_len must be a power-of-two */ 39 /* voltage in mV = table[VSEL]; table_len must be a power-of-two */
@@ -59,20 +59,20 @@ struct twlreg_info {
59 59
60 60
61static inline int 61static inline int
62twl4030reg_read(struct twlreg_info *info, unsigned offset) 62twlreg_read(struct twlreg_info *info, unsigned offset)
63{ 63{
64 u8 value; 64 u8 value;
65 int status; 65 int status;
66 66
67 status = twl_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, 67 status = twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER,
68 &value, info->base + offset); 68 &value, info->base + offset);
69 return (status < 0) ? status : value; 69 return (status < 0) ? status : value;
70} 70}
71 71
72static inline int 72static inline int
73twl4030reg_write(struct twlreg_info *info, unsigned offset, u8 value) 73twlreg_write(struct twlreg_info *info, unsigned offset, u8 value)
74{ 74{
75 return twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 75 return twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER,
76 value, info->base + offset); 76 value, info->base + offset);
77} 77}
78 78
@@ -80,9 +80,9 @@ twl4030reg_write(struct twlreg_info *info, unsigned offset, u8 value)
80 80
81/* generic power resource operations, which work on all regulators */ 81/* generic power resource operations, which work on all regulators */
82 82
83static int twl4030reg_grp(struct regulator_dev *rdev) 83static int twlreg_grp(struct regulator_dev *rdev)
84{ 84{
85 return twl4030reg_read(rdev_get_drvdata(rdev), VREG_GRP); 85 return twlreg_read(rdev_get_drvdata(rdev), VREG_GRP);
86} 86}
87 87
88/* 88/*
@@ -94,9 +94,9 @@ static int twl4030reg_grp(struct regulator_dev *rdev)
94#define P2_GRP BIT(6) /* secondary processor, modem, etc */ 94#define P2_GRP BIT(6) /* secondary processor, modem, etc */
95#define P1_GRP BIT(5) /* CPU/Linux */ 95#define P1_GRP BIT(5) /* CPU/Linux */
96 96
97static int twl4030reg_is_enabled(struct regulator_dev *rdev) 97static int twlreg_is_enabled(struct regulator_dev *rdev)
98{ 98{
99 int state = twl4030reg_grp(rdev); 99 int state = twlreg_grp(rdev);
100 100
101 if (state < 0) 101 if (state < 0)
102 return state; 102 return state;
@@ -104,35 +104,35 @@ static int twl4030reg_is_enabled(struct regulator_dev *rdev)
104 return (state & P1_GRP) != 0; 104 return (state & P1_GRP) != 0;
105} 105}
106 106
107static int twl4030reg_enable(struct regulator_dev *rdev) 107static int twlreg_enable(struct regulator_dev *rdev)
108{ 108{
109 struct twlreg_info *info = rdev_get_drvdata(rdev); 109 struct twlreg_info *info = rdev_get_drvdata(rdev);
110 int grp; 110 int grp;
111 111
112 grp = twl4030reg_read(info, VREG_GRP); 112 grp = twlreg_read(info, VREG_GRP);
113 if (grp < 0) 113 if (grp < 0)
114 return grp; 114 return grp;
115 115
116 grp |= P1_GRP; 116 grp |= P1_GRP;
117 return twl4030reg_write(info, VREG_GRP, grp); 117 return twlreg_write(info, VREG_GRP, grp);
118} 118}
119 119
120static int twl4030reg_disable(struct regulator_dev *rdev) 120static int twlreg_disable(struct regulator_dev *rdev)
121{ 121{
122 struct twlreg_info *info = rdev_get_drvdata(rdev); 122 struct twlreg_info *info = rdev_get_drvdata(rdev);
123 int grp; 123 int grp;
124 124
125 grp = twl4030reg_read(info, VREG_GRP); 125 grp = twlreg_read(info, VREG_GRP);
126 if (grp < 0) 126 if (grp < 0)
127 return grp; 127 return grp;
128 128
129 grp &= ~P1_GRP; 129 grp &= ~P1_GRP;
130 return twl4030reg_write(info, VREG_GRP, grp); 130 return twlreg_write(info, VREG_GRP, grp);
131} 131}
132 132
133static int twl4030reg_get_status(struct regulator_dev *rdev) 133static int twlreg_get_status(struct regulator_dev *rdev)
134{ 134{
135 int state = twl4030reg_grp(rdev); 135 int state = twlreg_grp(rdev);
136 136
137 if (state < 0) 137 if (state < 0)
138 return state; 138 return state;
@@ -146,7 +146,7 @@ static int twl4030reg_get_status(struct regulator_dev *rdev)
146 : REGULATOR_STATUS_STANDBY; 146 : REGULATOR_STATUS_STANDBY;
147} 147}
148 148
149static int twl4030reg_set_mode(struct regulator_dev *rdev, unsigned mode) 149static int twlreg_set_mode(struct regulator_dev *rdev, unsigned mode)
150{ 150{
151 struct twlreg_info *info = rdev_get_drvdata(rdev); 151 struct twlreg_info *info = rdev_get_drvdata(rdev);
152 unsigned message; 152 unsigned message;
@@ -165,18 +165,18 @@ static int twl4030reg_set_mode(struct regulator_dev *rdev, unsigned mode)
165 } 165 }
166 166
167 /* Ensure the resource is associated with some group */ 167 /* Ensure the resource is associated with some group */
168 status = twl4030reg_grp(rdev); 168 status = twlreg_grp(rdev);
169 if (status < 0) 169 if (status < 0)
170 return status; 170 return status;
171 if (!(status & (P3_GRP | P2_GRP | P1_GRP))) 171 if (!(status & (P3_GRP | P2_GRP | P1_GRP)))
172 return -EACCES; 172 return -EACCES;
173 173
174 status = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 174 status = twl_i2c_write_u8(TWL_MODULE_PM_MASTER,
175 message >> 8, 0x15 /* PB_WORD_MSB */ ); 175 message >> 8, 0x15 /* PB_WORD_MSB */ );
176 if (status >= 0) 176 if (status >= 0)
177 return status; 177 return status;
178 178
179 return twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 179 return twl_i2c_write_u8(TWL_MODULE_PM_MASTER,
180 message, 0x16 /* PB_WORD_LSB */ ); 180 message, 0x16 /* PB_WORD_LSB */ );
181} 181}
182 182
@@ -262,7 +262,7 @@ static const u16 VDAC_VSEL_table[] = {
262}; 262};
263 263
264 264
265static int twl4030ldo_list_voltage(struct regulator_dev *rdev, unsigned index) 265static int twlldo_list_voltage(struct regulator_dev *rdev, unsigned index)
266{ 266{
267 struct twlreg_info *info = rdev_get_drvdata(rdev); 267 struct twlreg_info *info = rdev_get_drvdata(rdev);
268 int mV = info->table[index]; 268 int mV = info->table[index];
@@ -271,7 +271,7 @@ static int twl4030ldo_list_voltage(struct regulator_dev *rdev, unsigned index)
271} 271}
272 272
273static int 273static int
274twl4030ldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) 274twlldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV)
275{ 275{
276 struct twlreg_info *info = rdev_get_drvdata(rdev); 276 struct twlreg_info *info = rdev_get_drvdata(rdev);
277 int vsel; 277 int vsel;
@@ -288,16 +288,16 @@ twl4030ldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV)
288 288
289 /* use the first in-range value */ 289 /* use the first in-range value */
290 if (min_uV <= uV && uV <= max_uV) 290 if (min_uV <= uV && uV <= max_uV)
291 return twl4030reg_write(info, VREG_DEDICATED, vsel); 291 return twlreg_write(info, VREG_DEDICATED, vsel);
292 } 292 }
293 293
294 return -EDOM; 294 return -EDOM;
295} 295}
296 296
297static int twl4030ldo_get_voltage(struct regulator_dev *rdev) 297static int twlldo_get_voltage(struct regulator_dev *rdev)
298{ 298{
299 struct twlreg_info *info = rdev_get_drvdata(rdev); 299 struct twlreg_info *info = rdev_get_drvdata(rdev);
300 int vsel = twl4030reg_read(info, VREG_DEDICATED); 300 int vsel = twlreg_read(info, VREG_DEDICATED);
301 301
302 if (vsel < 0) 302 if (vsel < 0)
303 return vsel; 303 return vsel;
@@ -306,19 +306,19 @@ static int twl4030ldo_get_voltage(struct regulator_dev *rdev)
306 return LDO_MV(info->table[vsel]) * 1000; 306 return LDO_MV(info->table[vsel]) * 1000;
307} 307}
308 308
309static struct regulator_ops twl4030ldo_ops = { 309static struct regulator_ops twlldo_ops = {
310 .list_voltage = twl4030ldo_list_voltage, 310 .list_voltage = twlldo_list_voltage,
311 311
312 .set_voltage = twl4030ldo_set_voltage, 312 .set_voltage = twlldo_set_voltage,
313 .get_voltage = twl4030ldo_get_voltage, 313 .get_voltage = twlldo_get_voltage,
314 314
315 .enable = twl4030reg_enable, 315 .enable = twlreg_enable,
316 .disable = twl4030reg_disable, 316 .disable = twlreg_disable,
317 .is_enabled = twl4030reg_is_enabled, 317 .is_enabled = twlreg_is_enabled,
318 318
319 .set_mode = twl4030reg_set_mode, 319 .set_mode = twlreg_set_mode,
320 320
321 .get_status = twl4030reg_get_status, 321 .get_status = twlreg_get_status,
322}; 322};
323 323
324/*----------------------------------------------------------------------*/ 324/*----------------------------------------------------------------------*/
@@ -326,60 +326,65 @@ static struct regulator_ops twl4030ldo_ops = {
326/* 326/*
327 * Fixed voltage LDOs don't have a VSEL field to update. 327 * Fixed voltage LDOs don't have a VSEL field to update.
328 */ 328 */
329static int twl4030fixed_list_voltage(struct regulator_dev *rdev, unsigned index) 329static int twlfixed_list_voltage(struct regulator_dev *rdev, unsigned index)
330{ 330{
331 struct twlreg_info *info = rdev_get_drvdata(rdev); 331 struct twlreg_info *info = rdev_get_drvdata(rdev);
332 332
333 return info->min_mV * 1000; 333 return info->min_mV * 1000;
334} 334}
335 335
336static int twl4030fixed_get_voltage(struct regulator_dev *rdev) 336static int twlfixed_get_voltage(struct regulator_dev *rdev)
337{ 337{
338 struct twlreg_info *info = rdev_get_drvdata(rdev); 338 struct twlreg_info *info = rdev_get_drvdata(rdev);
339 339
340 return info->min_mV * 1000; 340 return info->min_mV * 1000;
341} 341}
342 342
343static struct regulator_ops twl4030fixed_ops = { 343static struct regulator_ops twlfixed_ops = {
344 .list_voltage = twl4030fixed_list_voltage, 344 .list_voltage = twlfixed_list_voltage,
345 345
346 .get_voltage = twl4030fixed_get_voltage, 346 .get_voltage = twlfixed_get_voltage,
347 347
348 .enable = twl4030reg_enable, 348 .enable = twlreg_enable,
349 .disable = twl4030reg_disable, 349 .disable = twlreg_disable,
350 .is_enabled = twl4030reg_is_enabled, 350 .is_enabled = twlreg_is_enabled,
351 351
352 .set_mode = twl4030reg_set_mode, 352 .set_mode = twlreg_set_mode,
353 353
354 .get_status = twl4030reg_get_status, 354 .get_status = twlreg_get_status,
355}; 355};
356 356
357/*----------------------------------------------------------------------*/ 357/*----------------------------------------------------------------------*/
358 358
359#define TWL_ADJUSTABLE_LDO(label, offset, num) { \ 359#define TWL4030_ADJUSTABLE_LDO(label, offset, num) \
360 TWL_ADJUSTABLE_LDO(label, offset, num, TWL4030)
361#define TWL4030_FIXED_LDO(label, offset, mVolts, num) \
362 TWL_FIXED_LDO(label, offset, mVolts, num, TWL4030)
363
364#define TWL_ADJUSTABLE_LDO(label, offset, num, family) { \
360 .base = offset, \ 365 .base = offset, \
361 .id = num, \ 366 .id = num, \
362 .table_len = ARRAY_SIZE(label##_VSEL_table), \ 367 .table_len = ARRAY_SIZE(label##_VSEL_table), \
363 .table = label##_VSEL_table, \ 368 .table = label##_VSEL_table, \
364 .desc = { \ 369 .desc = { \
365 .name = #label, \ 370 .name = #label, \
366 .id = TWL4030_REG_##label, \ 371 .id = family##_REG_##label, \
367 .n_voltages = ARRAY_SIZE(label##_VSEL_table), \ 372 .n_voltages = ARRAY_SIZE(label##_VSEL_table), \
368 .ops = &twl4030ldo_ops, \ 373 .ops = &twlldo_ops, \
369 .type = REGULATOR_VOLTAGE, \ 374 .type = REGULATOR_VOLTAGE, \
370 .owner = THIS_MODULE, \ 375 .owner = THIS_MODULE, \
371 }, \ 376 }, \
372 } 377 }
373 378
374#define TWL_FIXED_LDO(label, offset, mVolts, num) { \ 379#define TWL_FIXED_LDO(label, offset, mVolts, num, family) { \
375 .base = offset, \ 380 .base = offset, \
376 .id = num, \ 381 .id = num, \
377 .min_mV = mVolts, \ 382 .min_mV = mVolts, \
378 .desc = { \ 383 .desc = { \
379 .name = #label, \ 384 .name = #label, \
380 .id = TWL4030_REG_##label, \ 385 .id = family##_REG_##label, \
381 .n_voltages = 1, \ 386 .n_voltages = 1, \
382 .ops = &twl4030fixed_ops, \ 387 .ops = &twlfixed_ops, \
383 .type = REGULATOR_VOLTAGE, \ 388 .type = REGULATOR_VOLTAGE, \
384 .owner = THIS_MODULE, \ 389 .owner = THIS_MODULE, \
385 }, \ 390 }, \
@@ -389,35 +394,35 @@ static struct regulator_ops twl4030fixed_ops = {
389 * We list regulators here if systems need some level of 394 * We list regulators here if systems need some level of
390 * software control over them after boot. 395 * software control over them after boot.
391 */ 396 */
392static struct twlreg_info twl4030_regs[] = { 397static struct twlreg_info twl_regs[] = {
393 TWL_ADJUSTABLE_LDO(VAUX1, 0x17, 1), 398 TWL4030_ADJUSTABLE_LDO(VAUX1, 0x17, 1),
394 TWL_ADJUSTABLE_LDO(VAUX2_4030, 0x1b, 2), 399 TWL4030_ADJUSTABLE_LDO(VAUX2_4030, 0x1b, 2),
395 TWL_ADJUSTABLE_LDO(VAUX2, 0x1b, 2), 400 TWL4030_ADJUSTABLE_LDO(VAUX2, 0x1b, 2),
396 TWL_ADJUSTABLE_LDO(VAUX3, 0x1f, 3), 401 TWL4030_ADJUSTABLE_LDO(VAUX3, 0x1f, 3),
397 TWL_ADJUSTABLE_LDO(VAUX4, 0x23, 4), 402 TWL4030_ADJUSTABLE_LDO(VAUX4, 0x23, 4),
398 TWL_ADJUSTABLE_LDO(VMMC1, 0x27, 5), 403 TWL4030_ADJUSTABLE_LDO(VMMC1, 0x27, 5),
399 TWL_ADJUSTABLE_LDO(VMMC2, 0x2b, 6), 404 TWL4030_ADJUSTABLE_LDO(VMMC2, 0x2b, 6),
400 /* 405 /*
401 TWL_ADJUSTABLE_LDO(VPLL1, 0x2f, 7), 406 TWL4030_ADJUSTABLE_LDO(VPLL1, 0x2f, 7),
402 */ 407 */
403 TWL_ADJUSTABLE_LDO(VPLL2, 0x33, 8), 408 TWL4030_ADJUSTABLE_LDO(VPLL2, 0x33, 8),
404 TWL_ADJUSTABLE_LDO(VSIM, 0x37, 9), 409 TWL4030_ADJUSTABLE_LDO(VSIM, 0x37, 9),
405 TWL_ADJUSTABLE_LDO(VDAC, 0x3b, 10), 410 TWL4030_ADJUSTABLE_LDO(VDAC, 0x3b, 10),
406 /* 411 /*
407 TWL_ADJUSTABLE_LDO(VINTANA1, 0x3f, 11), 412 TWL4030_ADJUSTABLE_LDO(VINTANA1, 0x3f, 11),
408 TWL_ADJUSTABLE_LDO(VINTANA2, 0x43, 12), 413 TWL4030_ADJUSTABLE_LDO(VINTANA2, 0x43, 12),
409 TWL_ADJUSTABLE_LDO(VINTDIG, 0x47, 13), 414 TWL4030_ADJUSTABLE_LDO(VINTDIG, 0x47, 13),
410 TWL_SMPS(VIO, 0x4b, 14), 415 TWL4030_SMPS(VIO, 0x4b, 14),
411 TWL_SMPS(VDD1, 0x55, 15), 416 TWL4030_SMPS(VDD1, 0x55, 15),
412 TWL_SMPS(VDD2, 0x63, 16), 417 TWL4030_SMPS(VDD2, 0x63, 16),
413 */ 418 */
414 TWL_FIXED_LDO(VUSB1V5, 0x71, 1500, 17), 419 TWL4030_FIXED_LDO(VUSB1V5, 0x71, 1500, 17),
415 TWL_FIXED_LDO(VUSB1V8, 0x74, 1800, 18), 420 TWL4030_FIXED_LDO(VUSB1V8, 0x74, 1800, 18),
416 TWL_FIXED_LDO(VUSB3V1, 0x77, 3100, 19), 421 TWL4030_FIXED_LDO(VUSB3V1, 0x77, 3100, 19),
417 /* VUSBCP is managed *only* by the USB subchip */ 422 /* VUSBCP is managed *only* by the USB subchip */
418}; 423};
419 424
420static int twl4030reg_probe(struct platform_device *pdev) 425static int twlreg_probe(struct platform_device *pdev)
421{ 426{
422 int i; 427 int i;
423 struct twlreg_info *info; 428 struct twlreg_info *info;
@@ -425,10 +430,10 @@ static int twl4030reg_probe(struct platform_device *pdev)
425 struct regulation_constraints *c; 430 struct regulation_constraints *c;
426 struct regulator_dev *rdev; 431 struct regulator_dev *rdev;
427 432
428 for (i = 0, info = NULL; i < ARRAY_SIZE(twl4030_regs); i++) { 433 for (i = 0, info = NULL; i < ARRAY_SIZE(twl_regs); i++) {
429 if (twl4030_regs[i].desc.id != pdev->id) 434 if (twl_regs[i].desc.id != pdev->id)
430 continue; 435 continue;
431 info = twl4030_regs + i; 436 info = twl_regs + i;
432 break; 437 break;
433 } 438 }
434 if (!info) 439 if (!info)
@@ -466,35 +471,35 @@ static int twl4030reg_probe(struct platform_device *pdev)
466 return 0; 471 return 0;
467} 472}
468 473
469static int __devexit twl4030reg_remove(struct platform_device *pdev) 474static int __devexit twlreg_remove(struct platform_device *pdev)
470{ 475{
471 regulator_unregister(platform_get_drvdata(pdev)); 476 regulator_unregister(platform_get_drvdata(pdev));
472 return 0; 477 return 0;
473} 478}
474 479
475MODULE_ALIAS("platform:twl4030_reg"); 480MODULE_ALIAS("platform:twl_reg");
476 481
477static struct platform_driver twl4030reg_driver = { 482static struct platform_driver twlreg_driver = {
478 .probe = twl4030reg_probe, 483 .probe = twlreg_probe,
479 .remove = __devexit_p(twl4030reg_remove), 484 .remove = __devexit_p(twlreg_remove),
480 /* NOTE: short name, to work around driver model truncation of 485 /* NOTE: short name, to work around driver model truncation of
481 * "twl4030_regulator.12" (and friends) to "twl4030_regulator.1". 486 * "twl_regulator.12" (and friends) to "twl_regulator.1".
482 */ 487 */
483 .driver.name = "twl4030_reg", 488 .driver.name = "twl_reg",
484 .driver.owner = THIS_MODULE, 489 .driver.owner = THIS_MODULE,
485}; 490};
486 491
487static int __init twl4030reg_init(void) 492static int __init twlreg_init(void)
488{ 493{
489 return platform_driver_register(&twl4030reg_driver); 494 return platform_driver_register(&twlreg_driver);
490} 495}
491subsys_initcall(twl4030reg_init); 496subsys_initcall(twlreg_init);
492 497
493static void __exit twl4030reg_exit(void) 498static void __exit twlreg_exit(void)
494{ 499{
495 platform_driver_unregister(&twl4030reg_driver); 500 platform_driver_unregister(&twlreg_driver);
496} 501}
497module_exit(twl4030reg_exit) 502module_exit(twlreg_exit)
498 503
499MODULE_DESCRIPTION("TWL4030 regulator driver"); 504MODULE_DESCRIPTION("TWL regulator driver");
500MODULE_LICENSE("GPL"); 505MODULE_LICENSE("GPL");