aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/regulator/tps65912-regulator.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/regulator/tps65912-regulator.c')
-rw-r--r--drivers/regulator/tps65912-regulator.c340
1 files changed, 64 insertions, 276 deletions
diff --git a/drivers/regulator/tps65912-regulator.c b/drivers/regulator/tps65912-regulator.c
index da00d88f94b7..b36799b1f530 100644
--- a/drivers/regulator/tps65912-regulator.c
+++ b/drivers/regulator/tps65912-regulator.c
@@ -114,10 +114,7 @@ struct tps65912_reg {
114 struct mutex io_lock; 114 struct mutex io_lock;
115 int mode; 115 int mode;
116 int (*get_ctrl_reg)(int); 116 int (*get_ctrl_reg)(int);
117 int dcdc1_range; 117 int dcdc_range[TPS65912_NUM_DCDC];
118 int dcdc2_range;
119 int dcdc3_range;
120 int dcdc4_range;
121 int pwm_mode_reg; 118 int pwm_mode_reg;
122 int eco_reg; 119 int eco_reg;
123}; 120};
@@ -125,46 +122,31 @@ struct tps65912_reg {
125static int tps65912_get_range(struct tps65912_reg *pmic, int id) 122static int tps65912_get_range(struct tps65912_reg *pmic, int id)
126{ 123{
127 struct tps65912 *mfd = pmic->mfd; 124 struct tps65912 *mfd = pmic->mfd;
128 125 int range;
129 if (id > TPS65912_REG_DCDC4)
130 return 0;
131 126
132 switch (id) { 127 switch (id) {
133 case TPS65912_REG_DCDC1: 128 case TPS65912_REG_DCDC1:
134 pmic->dcdc1_range = tps65912_reg_read(mfd, 129 range = tps65912_reg_read(mfd, TPS65912_DCDC1_LIMIT);
135 TPS65912_DCDC1_LIMIT); 130 break;
136 if (pmic->dcdc1_range < 0)
137 return pmic->dcdc1_range;
138 pmic->dcdc1_range = (pmic->dcdc1_range &
139 DCDC_LIMIT_RANGE_MASK) >> DCDC_LIMIT_RANGE_SHIFT;
140 return pmic->dcdc1_range;
141 case TPS65912_REG_DCDC2: 131 case TPS65912_REG_DCDC2:
142 pmic->dcdc2_range = tps65912_reg_read(mfd, 132 range = tps65912_reg_read(mfd, TPS65912_DCDC2_LIMIT);
143 TPS65912_DCDC2_LIMIT); 133 break;
144 if (pmic->dcdc2_range < 0)
145 return pmic->dcdc2_range;
146 pmic->dcdc2_range = (pmic->dcdc2_range &
147 DCDC_LIMIT_RANGE_MASK) >> DCDC_LIMIT_RANGE_SHIFT;
148 return pmic->dcdc2_range;
149 case TPS65912_REG_DCDC3: 134 case TPS65912_REG_DCDC3:
150 pmic->dcdc3_range = tps65912_reg_read(mfd, 135 range = tps65912_reg_read(mfd, TPS65912_DCDC3_LIMIT);
151 TPS65912_DCDC3_LIMIT); 136 break;
152 if (pmic->dcdc3_range < 0)
153 return pmic->dcdc3_range;
154 pmic->dcdc3_range = (pmic->dcdc3_range &
155 DCDC_LIMIT_RANGE_MASK) >> DCDC_LIMIT_RANGE_SHIFT;
156 return pmic->dcdc3_range;
157 case TPS65912_REG_DCDC4: 137 case TPS65912_REG_DCDC4:
158 pmic->dcdc4_range = tps65912_reg_read(mfd, 138 range = tps65912_reg_read(mfd, TPS65912_DCDC4_LIMIT);
159 TPS65912_DCDC4_LIMIT); 139 break;
160 if (pmic->dcdc4_range < 0)
161 return pmic->dcdc4_range;
162 pmic->dcdc4_range = (pmic->dcdc4_range &
163 DCDC_LIMIT_RANGE_MASK) >> DCDC_LIMIT_RANGE_SHIFT;
164 return pmic->dcdc4_range;
165 default: 140 default:
166 return 0; 141 return 0;
167 } 142 }
143
144 if (range >= 0)
145 range = (range & DCDC_LIMIT_RANGE_MASK)
146 >> DCDC_LIMIT_RANGE_SHIFT;
147
148 pmic->dcdc_range[id] = range;
149 return range;
168} 150}
169 151
170static unsigned long tps65912_vsel_to_uv_range0(u8 vsel) 152static unsigned long tps65912_vsel_to_uv_range0(u8 vsel)
@@ -219,146 +201,30 @@ static unsigned long tps65912_vsel_to_uv_ldo(u8 vsel)
219 201
220static int tps65912_get_ctrl_register(int id) 202static int tps65912_get_ctrl_register(int id)
221{ 203{
222 switch (id) { 204 if (id >= TPS65912_REG_DCDC1 && id <= TPS65912_REG_LDO4)
223 case TPS65912_REG_DCDC1: 205 return id * 3 + TPS65912_DCDC1_AVS;
224 return TPS65912_DCDC1_AVS; 206 else if (id >= TPS65912_REG_LDO5 && id <= TPS65912_REG_LDO10)
225 case TPS65912_REG_DCDC2: 207 return id - TPS65912_REG_LDO5 + TPS65912_LDO5;
226 return TPS65912_DCDC2_AVS; 208 else
227 case TPS65912_REG_DCDC3:
228 return TPS65912_DCDC3_AVS;
229 case TPS65912_REG_DCDC4:
230 return TPS65912_DCDC4_AVS;
231 case TPS65912_REG_LDO1:
232 return TPS65912_LDO1_AVS;
233 case TPS65912_REG_LDO2:
234 return TPS65912_LDO2_AVS;
235 case TPS65912_REG_LDO3:
236 return TPS65912_LDO3_AVS;
237 case TPS65912_REG_LDO4:
238 return TPS65912_LDO4_AVS;
239 case TPS65912_REG_LDO5:
240 return TPS65912_LDO5;
241 case TPS65912_REG_LDO6:
242 return TPS65912_LDO6;
243 case TPS65912_REG_LDO7:
244 return TPS65912_LDO7;
245 case TPS65912_REG_LDO8:
246 return TPS65912_LDO8;
247 case TPS65912_REG_LDO9:
248 return TPS65912_LDO9;
249 case TPS65912_REG_LDO10:
250 return TPS65912_LDO10;
251 default:
252 return -EINVAL; 209 return -EINVAL;
253 }
254} 210}
255 211
256static int tps65912_get_dcdc_sel_register(struct tps65912_reg *pmic, int id) 212static int tps65912_get_sel_register(struct tps65912_reg *pmic, int id)
257{ 213{
258 struct tps65912 *mfd = pmic->mfd; 214 struct tps65912 *mfd = pmic->mfd;
259 int opvsel = 0, sr = 0; 215 int opvsel;
260 u8 reg = 0; 216 u8 reg = 0;
261 217
262 if (id < TPS65912_REG_DCDC1 || id > TPS65912_REG_DCDC4) 218 if (id >= TPS65912_REG_DCDC1 && id <= TPS65912_REG_LDO4) {
263 return -EINVAL; 219 opvsel = tps65912_reg_read(mfd, id * 3 + TPS65912_DCDC1_OP);
264 220 if (opvsel & OP_SELREG_MASK)
265 switch (id) { 221 reg = id * 3 + TPS65912_DCDC1_AVS;
266 case TPS65912_REG_DCDC1:
267 opvsel = tps65912_reg_read(mfd, TPS65912_DCDC1_OP);
268 sr = ((opvsel & OP_SELREG_MASK) >> OP_SELREG_SHIFT);
269 if (sr)
270 reg = TPS65912_DCDC1_AVS;
271 else
272 reg = TPS65912_DCDC1_OP;
273 break;
274 case TPS65912_REG_DCDC2:
275 opvsel = tps65912_reg_read(mfd, TPS65912_DCDC2_OP);
276 sr = (opvsel & OP_SELREG_MASK) >> OP_SELREG_SHIFT;
277 if (sr)
278 reg = TPS65912_DCDC2_AVS;
279 else
280 reg = TPS65912_DCDC2_OP;
281 break;
282 case TPS65912_REG_DCDC3:
283 opvsel = tps65912_reg_read(mfd, TPS65912_DCDC3_OP);
284 sr = (opvsel & OP_SELREG_MASK) >> OP_SELREG_SHIFT;
285 if (sr)
286 reg = TPS65912_DCDC3_AVS;
287 else
288 reg = TPS65912_DCDC3_OP;
289 break;
290 case TPS65912_REG_DCDC4:
291 opvsel = tps65912_reg_read(mfd, TPS65912_DCDC4_OP);
292 sr = (opvsel & OP_SELREG_MASK) >> OP_SELREG_SHIFT;
293 if (sr)
294 reg = TPS65912_DCDC4_AVS;
295 else 222 else
296 reg = TPS65912_DCDC4_OP; 223 reg = id * 3 + TPS65912_DCDC1_OP;
297 break; 224 } else if (id >= TPS65912_REG_LDO5 && id <= TPS65912_REG_LDO10) {
298 } 225 reg = id - TPS65912_REG_LDO5 + TPS65912_LDO5;
299 return reg; 226 } else {
300}
301
302static int tps65912_get_ldo_sel_register(struct tps65912_reg *pmic, int id)
303{
304 struct tps65912 *mfd = pmic->mfd;
305 int opvsel = 0, sr = 0;
306 u8 reg = 0;
307
308 if (id < TPS65912_REG_LDO1 || id > TPS65912_REG_LDO10)
309 return -EINVAL; 227 return -EINVAL;
310
311 switch (id) {
312 case TPS65912_REG_LDO1:
313 opvsel = tps65912_reg_read(mfd, TPS65912_LDO1_OP);
314 sr = (opvsel & OP_SELREG_MASK) >> OP_SELREG_SHIFT;
315 if (sr)
316 reg = TPS65912_LDO1_AVS;
317 else
318 reg = TPS65912_LDO1_OP;
319 break;
320 case TPS65912_REG_LDO2:
321 opvsel = tps65912_reg_read(mfd, TPS65912_LDO2_OP);
322 sr = (opvsel & OP_SELREG_MASK) >> OP_SELREG_SHIFT;
323 if (sr)
324 reg = TPS65912_LDO2_AVS;
325 else
326 reg = TPS65912_LDO2_OP;
327 break;
328 case TPS65912_REG_LDO3:
329 opvsel = tps65912_reg_read(mfd, TPS65912_LDO3_OP);
330 sr = (opvsel & OP_SELREG_MASK) >> OP_SELREG_SHIFT;
331 if (sr)
332 reg = TPS65912_LDO3_AVS;
333 else
334 reg = TPS65912_LDO3_OP;
335 break;
336 case TPS65912_REG_LDO4:
337 opvsel = tps65912_reg_read(mfd, TPS65912_LDO4_OP);
338 sr = (opvsel & OP_SELREG_MASK) >> OP_SELREG_SHIFT;
339 if (sr)
340 reg = TPS65912_LDO4_AVS;
341 else
342 reg = TPS65912_LDO4_OP;
343 break;
344 case TPS65912_REG_LDO5:
345 reg = TPS65912_LDO5;
346 break;
347 case TPS65912_REG_LDO6:
348 reg = TPS65912_LDO6;
349 break;
350 case TPS65912_REG_LDO7:
351 reg = TPS65912_LDO7;
352 break;
353 case TPS65912_REG_LDO8:
354 reg = TPS65912_LDO8;
355 break;
356 case TPS65912_REG_LDO9:
357 reg = TPS65912_LDO9;
358 break;
359 case TPS65912_REG_LDO10:
360 reg = TPS65912_LDO10;
361 break;
362 } 228 }
363 229
364 return reg; 230 return reg;
@@ -506,151 +372,83 @@ static unsigned int tps65912_get_mode(struct regulator_dev *dev)
506 return mode; 372 return mode;
507} 373}
508 374
509static int tps65912_get_voltage_dcdc(struct regulator_dev *dev) 375static int tps65912_list_voltage_dcdc(struct regulator_dev *dev,
376 unsigned selector)
510{ 377{
511 struct tps65912_reg *pmic = rdev_get_drvdata(dev); 378 struct tps65912_reg *pmic = rdev_get_drvdata(dev);
512 struct tps65912 *mfd = pmic->mfd; 379 int range, voltage = 0, id = rdev_get_id(dev);
513 int id = rdev_get_id(dev), voltage = 0, range;
514 int opvsel = 0, avsel = 0, sr, vsel;
515 380
516 switch (id) { 381 if (id > TPS65912_REG_DCDC4)
517 case TPS65912_REG_DCDC1:
518 opvsel = tps65912_reg_read(mfd, TPS65912_DCDC1_OP);
519 avsel = tps65912_reg_read(mfd, TPS65912_DCDC1_AVS);
520 range = pmic->dcdc1_range;
521 break;
522 case TPS65912_REG_DCDC2:
523 opvsel = tps65912_reg_read(mfd, TPS65912_DCDC2_OP);
524 avsel = tps65912_reg_read(mfd, TPS65912_DCDC2_AVS);
525 range = pmic->dcdc2_range;
526 break;
527 case TPS65912_REG_DCDC3:
528 opvsel = tps65912_reg_read(mfd, TPS65912_DCDC3_OP);
529 avsel = tps65912_reg_read(mfd, TPS65912_DCDC3_AVS);
530 range = pmic->dcdc3_range;
531 break;
532 case TPS65912_REG_DCDC4:
533 opvsel = tps65912_reg_read(mfd, TPS65912_DCDC4_OP);
534 avsel = tps65912_reg_read(mfd, TPS65912_DCDC4_AVS);
535 range = pmic->dcdc4_range;
536 break;
537 default:
538 return -EINVAL; 382 return -EINVAL;
539 }
540 383
541 sr = (opvsel & OP_SELREG_MASK) >> OP_SELREG_SHIFT; 384 range = pmic->dcdc_range[id];
542 if (sr)
543 vsel = avsel;
544 else
545 vsel = opvsel;
546 vsel &= 0x3F;
547 385
548 switch (range) { 386 switch (range) {
549 case 0: 387 case 0:
550 /* 0.5 - 1.2875V in 12.5mV steps */ 388 /* 0.5 - 1.2875V in 12.5mV steps */
551 voltage = tps65912_vsel_to_uv_range0(vsel); 389 voltage = tps65912_vsel_to_uv_range0(selector);
552 break; 390 break;
553 case 1: 391 case 1:
554 /* 0.7 - 1.4875V in 12.5mV steps */ 392 /* 0.7 - 1.4875V in 12.5mV steps */
555 voltage = tps65912_vsel_to_uv_range1(vsel); 393 voltage = tps65912_vsel_to_uv_range1(selector);
556 break; 394 break;
557 case 2: 395 case 2:
558 /* 0.5 - 2.075V in 25mV steps */ 396 /* 0.5 - 2.075V in 25mV steps */
559 voltage = tps65912_vsel_to_uv_range2(vsel); 397 voltage = tps65912_vsel_to_uv_range2(selector);
560 break; 398 break;
561 case 3: 399 case 3:
562 /* 0.5 - 3.8V in 50mV steps */ 400 /* 0.5 - 3.8V in 50mV steps */
563 voltage = tps65912_vsel_to_uv_range3(vsel); 401 voltage = tps65912_vsel_to_uv_range3(selector);
564 break; 402 break;
565 } 403 }
566 return voltage; 404 return voltage;
567} 405}
568 406
569static int tps65912_set_voltage_dcdc(struct regulator_dev *dev, 407static int tps65912_get_voltage_dcdc(struct regulator_dev *dev)
570 unsigned selector)
571{ 408{
572 struct tps65912_reg *pmic = rdev_get_drvdata(dev); 409 struct tps65912_reg *pmic = rdev_get_drvdata(dev);
573 struct tps65912 *mfd = pmic->mfd; 410 struct tps65912 *mfd = pmic->mfd;
574 int id = rdev_get_id(dev); 411 int id = rdev_get_id(dev);
575 int value; 412 int reg, vsel;
576 u8 reg;
577
578 reg = tps65912_get_dcdc_sel_register(pmic, id);
579 value = tps65912_reg_read(mfd, reg);
580 value &= 0xC0;
581 return tps65912_reg_write(mfd, reg, selector | value);
582}
583 413
584static int tps65912_get_voltage_ldo(struct regulator_dev *dev) 414 reg = tps65912_get_sel_register(pmic, id);
585{ 415 if (reg < 0)
586 struct tps65912_reg *pmic = rdev_get_drvdata(dev); 416 return reg;
587 struct tps65912 *mfd = pmic->mfd;
588 int id = rdev_get_id(dev);
589 int vsel = 0;
590 u8 reg;
591 417
592 reg = tps65912_get_ldo_sel_register(pmic, id);
593 vsel = tps65912_reg_read(mfd, reg); 418 vsel = tps65912_reg_read(mfd, reg);
594 vsel &= 0x3F; 419 vsel &= 0x3F;
595 420
596 return tps65912_vsel_to_uv_ldo(vsel); 421 return tps65912_list_voltage_dcdc(dev, vsel);
597} 422}
598 423
599static int tps65912_set_voltage_ldo(struct regulator_dev *dev, 424static int tps65912_set_voltage_sel(struct regulator_dev *dev,
600 unsigned selector) 425 unsigned selector)
601{ 426{
602 struct tps65912_reg *pmic = rdev_get_drvdata(dev); 427 struct tps65912_reg *pmic = rdev_get_drvdata(dev);
603 struct tps65912 *mfd = pmic->mfd; 428 struct tps65912 *mfd = pmic->mfd;
604 int id = rdev_get_id(dev), reg, value; 429 int id = rdev_get_id(dev);
430 int value;
431 u8 reg;
605 432
606 reg = tps65912_get_ldo_sel_register(pmic, id); 433 reg = tps65912_get_sel_register(pmic, id);
607 value = tps65912_reg_read(mfd, reg); 434 value = tps65912_reg_read(mfd, reg);
608 value &= 0xC0; 435 value &= 0xC0;
609 return tps65912_reg_write(mfd, reg, selector | value); 436 return tps65912_reg_write(mfd, reg, selector | value);
610} 437}
611 438
612static int tps65912_list_voltage_dcdc(struct regulator_dev *dev, 439static int tps65912_get_voltage_ldo(struct regulator_dev *dev)
613 unsigned selector)
614{ 440{
615 struct tps65912_reg *pmic = rdev_get_drvdata(dev); 441 struct tps65912_reg *pmic = rdev_get_drvdata(dev);
616 int range, voltage = 0, id = rdev_get_id(dev); 442 struct tps65912 *mfd = pmic->mfd;
443 int id = rdev_get_id(dev);
444 int vsel = 0;
445 u8 reg;
617 446
618 switch (id) { 447 reg = tps65912_get_sel_register(pmic, id);
619 case TPS65912_REG_DCDC1: 448 vsel = tps65912_reg_read(mfd, reg);
620 range = pmic->dcdc1_range; 449 vsel &= 0x3F;
621 break;
622 case TPS65912_REG_DCDC2:
623 range = pmic->dcdc2_range;
624 break;
625 case TPS65912_REG_DCDC3:
626 range = pmic->dcdc3_range;
627 break;
628 case TPS65912_REG_DCDC4:
629 range = pmic->dcdc4_range;
630 break;
631 default:
632 return -EINVAL;
633 }
634 450
635 switch (range) { 451 return tps65912_vsel_to_uv_ldo(vsel);
636 case 0:
637 /* 0.5 - 1.2875V in 12.5mV steps */
638 voltage = tps65912_vsel_to_uv_range0(selector);
639 break;
640 case 1:
641 /* 0.7 - 1.4875V in 12.5mV steps */
642 voltage = tps65912_vsel_to_uv_range1(selector);
643 break;
644 case 2:
645 /* 0.5 - 2.075V in 25mV steps */
646 voltage = tps65912_vsel_to_uv_range2(selector);
647 break;
648 case 3:
649 /* 0.5 - 3.8V in 50mV steps */
650 voltage = tps65912_vsel_to_uv_range3(selector);
651 break;
652 }
653 return voltage;
654} 452}
655 453
656static int tps65912_list_voltage_ldo(struct regulator_dev *dev, 454static int tps65912_list_voltage_ldo(struct regulator_dev *dev,
@@ -672,7 +470,7 @@ static struct regulator_ops tps65912_ops_dcdc = {
672 .set_mode = tps65912_set_mode, 470 .set_mode = tps65912_set_mode,
673 .get_mode = tps65912_get_mode, 471 .get_mode = tps65912_get_mode,
674 .get_voltage = tps65912_get_voltage_dcdc, 472 .get_voltage = tps65912_get_voltage_dcdc,
675 .set_voltage_sel = tps65912_set_voltage_dcdc, 473 .set_voltage_sel = tps65912_set_voltage_sel,
676 .list_voltage = tps65912_list_voltage_dcdc, 474 .list_voltage = tps65912_list_voltage_dcdc,
677}; 475};
678 476
@@ -682,7 +480,7 @@ static struct regulator_ops tps65912_ops_ldo = {
682 .enable = tps65912_reg_enable, 480 .enable = tps65912_reg_enable,
683 .disable = tps65912_reg_disable, 481 .disable = tps65912_reg_disable,
684 .get_voltage = tps65912_get_voltage_ldo, 482 .get_voltage = tps65912_get_voltage_ldo,
685 .set_voltage_sel = tps65912_set_voltage_ldo, 483 .set_voltage_sel = tps65912_set_voltage_sel,
686 .list_voltage = tps65912_list_voltage_ldo, 484 .list_voltage = tps65912_list_voltage_ldo,
687}; 485};
688 486
@@ -770,22 +568,12 @@ static struct platform_driver tps65912_driver = {
770 .remove = __devexit_p(tps65912_remove), 568 .remove = __devexit_p(tps65912_remove),
771}; 569};
772 570
773/**
774 * tps65912_init
775 *
776 * Module init function
777 */
778static int __init tps65912_init(void) 571static int __init tps65912_init(void)
779{ 572{
780 return platform_driver_register(&tps65912_driver); 573 return platform_driver_register(&tps65912_driver);
781} 574}
782subsys_initcall(tps65912_init); 575subsys_initcall(tps65912_init);
783 576
784/**
785 * tps65912_cleanup
786 *
787 * Module exit function
788 */
789static void __exit tps65912_cleanup(void) 577static void __exit tps65912_cleanup(void)
790{ 578{
791 platform_driver_unregister(&tps65912_driver); 579 platform_driver_unregister(&tps65912_driver);