aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/regulator/palmas-regulator.c
diff options
context:
space:
mode:
authorMark Brown <broonie@sirena.org.uk>2013-04-27 21:13:45 -0400
committerMark Brown <broonie@sirena.org.uk>2013-04-27 21:13:45 -0400
commitae5f5203e5ea2a50e90bdd3a6f2a2a2d0b2d56d5 (patch)
tree5a94af168769f0c100df2b08c07f7599b7e7bfa6 /drivers/regulator/palmas-regulator.c
parent75f01f949902db68b7937dfbae71b0b46a398161 (diff)
parent0ea34b578647e60ad4e06c9ba29829dc07c5264a (diff)
Merge remote-tracking branch 'regulator/topic/palmas' into v3.9-rc8
Diffstat (limited to 'drivers/regulator/palmas-regulator.c')
-rw-r--r--drivers/regulator/palmas-regulator.c365
1 files changed, 305 insertions, 60 deletions
diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c
index 39cf14606784..92ceed0fc65e 100644
--- a/drivers/regulator/palmas-regulator.c
+++ b/drivers/regulator/palmas-regulator.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Driver for Regulator part of Palmas PMIC Chips 2 * Driver for Regulator part of Palmas PMIC Chips
3 * 3 *
4 * Copyright 2011-2012 Texas Instruments Inc. 4 * Copyright 2011-2013 Texas Instruments Inc.
5 * 5 *
6 * Author: Graeme Gregory <gg@slimlogic.co.uk> 6 * Author: Graeme Gregory <gg@slimlogic.co.uk>
7 * Author: Ian Lartey <ian@slimlogic.co.uk> 7 * Author: Ian Lartey <ian@slimlogic.co.uk>
@@ -29,6 +29,7 @@
29 29
30struct regs_info { 30struct regs_info {
31 char *name; 31 char *name;
32 char *sname;
32 u8 vsel_addr; 33 u8 vsel_addr;
33 u8 ctrl_addr; 34 u8 ctrl_addr;
34 u8 tstep_addr; 35 u8 tstep_addr;
@@ -37,115 +38,159 @@ struct regs_info {
37static const struct regs_info palmas_regs_info[] = { 38static const struct regs_info palmas_regs_info[] = {
38 { 39 {
39 .name = "SMPS12", 40 .name = "SMPS12",
41 .sname = "smps1-in",
40 .vsel_addr = PALMAS_SMPS12_VOLTAGE, 42 .vsel_addr = PALMAS_SMPS12_VOLTAGE,
41 .ctrl_addr = PALMAS_SMPS12_CTRL, 43 .ctrl_addr = PALMAS_SMPS12_CTRL,
42 .tstep_addr = PALMAS_SMPS12_TSTEP, 44 .tstep_addr = PALMAS_SMPS12_TSTEP,
43 }, 45 },
44 { 46 {
45 .name = "SMPS123", 47 .name = "SMPS123",
48 .sname = "smps1-in",
46 .vsel_addr = PALMAS_SMPS12_VOLTAGE, 49 .vsel_addr = PALMAS_SMPS12_VOLTAGE,
47 .ctrl_addr = PALMAS_SMPS12_CTRL, 50 .ctrl_addr = PALMAS_SMPS12_CTRL,
48 .tstep_addr = PALMAS_SMPS12_TSTEP, 51 .tstep_addr = PALMAS_SMPS12_TSTEP,
49 }, 52 },
50 { 53 {
51 .name = "SMPS3", 54 .name = "SMPS3",
55 .sname = "smps3-in",
52 .vsel_addr = PALMAS_SMPS3_VOLTAGE, 56 .vsel_addr = PALMAS_SMPS3_VOLTAGE,
53 .ctrl_addr = PALMAS_SMPS3_CTRL, 57 .ctrl_addr = PALMAS_SMPS3_CTRL,
54 }, 58 },
55 { 59 {
56 .name = "SMPS45", 60 .name = "SMPS45",
61 .sname = "smps4-in",
57 .vsel_addr = PALMAS_SMPS45_VOLTAGE, 62 .vsel_addr = PALMAS_SMPS45_VOLTAGE,
58 .ctrl_addr = PALMAS_SMPS45_CTRL, 63 .ctrl_addr = PALMAS_SMPS45_CTRL,
59 .tstep_addr = PALMAS_SMPS45_TSTEP, 64 .tstep_addr = PALMAS_SMPS45_TSTEP,
60 }, 65 },
61 { 66 {
62 .name = "SMPS457", 67 .name = "SMPS457",
68 .sname = "smps4-in",
63 .vsel_addr = PALMAS_SMPS45_VOLTAGE, 69 .vsel_addr = PALMAS_SMPS45_VOLTAGE,
64 .ctrl_addr = PALMAS_SMPS45_CTRL, 70 .ctrl_addr = PALMAS_SMPS45_CTRL,
65 .tstep_addr = PALMAS_SMPS45_TSTEP, 71 .tstep_addr = PALMAS_SMPS45_TSTEP,
66 }, 72 },
67 { 73 {
68 .name = "SMPS6", 74 .name = "SMPS6",
75 .sname = "smps6-in",
69 .vsel_addr = PALMAS_SMPS6_VOLTAGE, 76 .vsel_addr = PALMAS_SMPS6_VOLTAGE,
70 .ctrl_addr = PALMAS_SMPS6_CTRL, 77 .ctrl_addr = PALMAS_SMPS6_CTRL,
71 .tstep_addr = PALMAS_SMPS6_TSTEP, 78 .tstep_addr = PALMAS_SMPS6_TSTEP,
72 }, 79 },
73 { 80 {
74 .name = "SMPS7", 81 .name = "SMPS7",
82 .sname = "smps7-in",
75 .vsel_addr = PALMAS_SMPS7_VOLTAGE, 83 .vsel_addr = PALMAS_SMPS7_VOLTAGE,
76 .ctrl_addr = PALMAS_SMPS7_CTRL, 84 .ctrl_addr = PALMAS_SMPS7_CTRL,
77 }, 85 },
78 { 86 {
79 .name = "SMPS8", 87 .name = "SMPS8",
88 .sname = "smps8-in",
80 .vsel_addr = PALMAS_SMPS8_VOLTAGE, 89 .vsel_addr = PALMAS_SMPS8_VOLTAGE,
81 .ctrl_addr = PALMAS_SMPS8_CTRL, 90 .ctrl_addr = PALMAS_SMPS8_CTRL,
82 .tstep_addr = PALMAS_SMPS8_TSTEP, 91 .tstep_addr = PALMAS_SMPS8_TSTEP,
83 }, 92 },
84 { 93 {
85 .name = "SMPS9", 94 .name = "SMPS9",
95 .sname = "smps9-in",
86 .vsel_addr = PALMAS_SMPS9_VOLTAGE, 96 .vsel_addr = PALMAS_SMPS9_VOLTAGE,
87 .ctrl_addr = PALMAS_SMPS9_CTRL, 97 .ctrl_addr = PALMAS_SMPS9_CTRL,
88 }, 98 },
89 { 99 {
90 .name = "SMPS10", 100 .name = "SMPS10",
101 .sname = "smps10-in",
102 .ctrl_addr = PALMAS_SMPS10_CTRL,
91 }, 103 },
92 { 104 {
93 .name = "LDO1", 105 .name = "LDO1",
106 .sname = "ldo1-in",
94 .vsel_addr = PALMAS_LDO1_VOLTAGE, 107 .vsel_addr = PALMAS_LDO1_VOLTAGE,
95 .ctrl_addr = PALMAS_LDO1_CTRL, 108 .ctrl_addr = PALMAS_LDO1_CTRL,
96 }, 109 },
97 { 110 {
98 .name = "LDO2", 111 .name = "LDO2",
112 .sname = "ldo2-in",
99 .vsel_addr = PALMAS_LDO2_VOLTAGE, 113 .vsel_addr = PALMAS_LDO2_VOLTAGE,
100 .ctrl_addr = PALMAS_LDO2_CTRL, 114 .ctrl_addr = PALMAS_LDO2_CTRL,
101 }, 115 },
102 { 116 {
103 .name = "LDO3", 117 .name = "LDO3",
118 .sname = "ldo3-in",
104 .vsel_addr = PALMAS_LDO3_VOLTAGE, 119 .vsel_addr = PALMAS_LDO3_VOLTAGE,
105 .ctrl_addr = PALMAS_LDO3_CTRL, 120 .ctrl_addr = PALMAS_LDO3_CTRL,
106 }, 121 },
107 { 122 {
108 .name = "LDO4", 123 .name = "LDO4",
124 .sname = "ldo4-in",
109 .vsel_addr = PALMAS_LDO4_VOLTAGE, 125 .vsel_addr = PALMAS_LDO4_VOLTAGE,
110 .ctrl_addr = PALMAS_LDO4_CTRL, 126 .ctrl_addr = PALMAS_LDO4_CTRL,
111 }, 127 },
112 { 128 {
113 .name = "LDO5", 129 .name = "LDO5",
130 .sname = "ldo5-in",
114 .vsel_addr = PALMAS_LDO5_VOLTAGE, 131 .vsel_addr = PALMAS_LDO5_VOLTAGE,
115 .ctrl_addr = PALMAS_LDO5_CTRL, 132 .ctrl_addr = PALMAS_LDO5_CTRL,
116 }, 133 },
117 { 134 {
118 .name = "LDO6", 135 .name = "LDO6",
136 .sname = "ldo6-in",
119 .vsel_addr = PALMAS_LDO6_VOLTAGE, 137 .vsel_addr = PALMAS_LDO6_VOLTAGE,
120 .ctrl_addr = PALMAS_LDO6_CTRL, 138 .ctrl_addr = PALMAS_LDO6_CTRL,
121 }, 139 },
122 { 140 {
123 .name = "LDO7", 141 .name = "LDO7",
142 .sname = "ldo7-in",
124 .vsel_addr = PALMAS_LDO7_VOLTAGE, 143 .vsel_addr = PALMAS_LDO7_VOLTAGE,
125 .ctrl_addr = PALMAS_LDO7_CTRL, 144 .ctrl_addr = PALMAS_LDO7_CTRL,
126 }, 145 },
127 { 146 {
128 .name = "LDO8", 147 .name = "LDO8",
148 .sname = "ldo8-in",
129 .vsel_addr = PALMAS_LDO8_VOLTAGE, 149 .vsel_addr = PALMAS_LDO8_VOLTAGE,
130 .ctrl_addr = PALMAS_LDO8_CTRL, 150 .ctrl_addr = PALMAS_LDO8_CTRL,
131 }, 151 },
132 { 152 {
133 .name = "LDO9", 153 .name = "LDO9",
154 .sname = "ldo9-in",
134 .vsel_addr = PALMAS_LDO9_VOLTAGE, 155 .vsel_addr = PALMAS_LDO9_VOLTAGE,
135 .ctrl_addr = PALMAS_LDO9_CTRL, 156 .ctrl_addr = PALMAS_LDO9_CTRL,
136 }, 157 },
137 { 158 {
138 .name = "LDOLN", 159 .name = "LDOLN",
160 .sname = "ldoln-in",
139 .vsel_addr = PALMAS_LDOLN_VOLTAGE, 161 .vsel_addr = PALMAS_LDOLN_VOLTAGE,
140 .ctrl_addr = PALMAS_LDOLN_CTRL, 162 .ctrl_addr = PALMAS_LDOLN_CTRL,
141 }, 163 },
142 { 164 {
143 .name = "LDOUSB", 165 .name = "LDOUSB",
166 .sname = "ldousb-in",
144 .vsel_addr = PALMAS_LDOUSB_VOLTAGE, 167 .vsel_addr = PALMAS_LDOUSB_VOLTAGE,
145 .ctrl_addr = PALMAS_LDOUSB_CTRL, 168 .ctrl_addr = PALMAS_LDOUSB_CTRL,
146 }, 169 },
170 {
171 .name = "REGEN1",
172 .ctrl_addr = PALMAS_REGEN1_CTRL,
173 },
174 {
175 .name = "REGEN2",
176 .ctrl_addr = PALMAS_REGEN2_CTRL,
177 },
178 {
179 .name = "REGEN3",
180 .ctrl_addr = PALMAS_REGEN3_CTRL,
181 },
182 {
183 .name = "SYSEN1",
184 .ctrl_addr = PALMAS_SYSEN1_CTRL,
185 },
186 {
187 .name = "SYSEN2",
188 .ctrl_addr = PALMAS_SYSEN2_CTRL,
189 },
147}; 190};
148 191
192static unsigned int palmas_smps_ramp_delay[4] = {0, 10000, 5000, 2500};
193
149#define SMPS_CTRL_MODE_OFF 0x00 194#define SMPS_CTRL_MODE_OFF 0x00
150#define SMPS_CTRL_MODE_ON 0x01 195#define SMPS_CTRL_MODE_ON 0x01
151#define SMPS_CTRL_MODE_ECO 0x02 196#define SMPS_CTRL_MODE_ECO 0x02
@@ -231,7 +276,10 @@ static int palmas_enable_smps(struct regulator_dev *dev)
231 palmas_smps_read(pmic->palmas, palmas_regs_info[id].ctrl_addr, &reg); 276 palmas_smps_read(pmic->palmas, palmas_regs_info[id].ctrl_addr, &reg);
232 277
233 reg &= ~PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK; 278 reg &= ~PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK;
234 reg |= SMPS_CTRL_MODE_ON; 279 if (pmic->current_reg_mode[id])
280 reg |= pmic->current_reg_mode[id];
281 else
282 reg |= SMPS_CTRL_MODE_ON;
235 283
236 palmas_smps_write(pmic->palmas, palmas_regs_info[id].ctrl_addr, reg); 284 palmas_smps_write(pmic->palmas, palmas_regs_info[id].ctrl_addr, reg);
237 285
@@ -253,16 +301,19 @@ static int palmas_disable_smps(struct regulator_dev *dev)
253 return 0; 301 return 0;
254} 302}
255 303
256
257static int palmas_set_mode_smps(struct regulator_dev *dev, unsigned int mode) 304static int palmas_set_mode_smps(struct regulator_dev *dev, unsigned int mode)
258{ 305{
259 struct palmas_pmic *pmic = rdev_get_drvdata(dev); 306 struct palmas_pmic *pmic = rdev_get_drvdata(dev);
260 int id = rdev_get_id(dev); 307 int id = rdev_get_id(dev);
261 unsigned int reg; 308 unsigned int reg;
309 bool rail_enable = true;
262 310
263 palmas_smps_read(pmic->palmas, palmas_regs_info[id].ctrl_addr, &reg); 311 palmas_smps_read(pmic->palmas, palmas_regs_info[id].ctrl_addr, &reg);
264 reg &= ~PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK; 312 reg &= ~PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK;
265 313
314 if (reg == SMPS_CTRL_MODE_OFF)
315 rail_enable = false;
316
266 switch (mode) { 317 switch (mode) {
267 case REGULATOR_MODE_NORMAL: 318 case REGULATOR_MODE_NORMAL:
268 reg |= SMPS_CTRL_MODE_ON; 319 reg |= SMPS_CTRL_MODE_ON;
@@ -276,8 +327,11 @@ static int palmas_set_mode_smps(struct regulator_dev *dev, unsigned int mode)
276 default: 327 default:
277 return -EINVAL; 328 return -EINVAL;
278 } 329 }
279 palmas_smps_write(pmic->palmas, palmas_regs_info[id].ctrl_addr, reg);
280 330
331 pmic->current_reg_mode[id] = reg & PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK;
332 if (rail_enable)
333 palmas_smps_write(pmic->palmas,
334 palmas_regs_info[id].ctrl_addr, reg);
281 return 0; 335 return 0;
282} 336}
283 337
@@ -287,9 +341,7 @@ static unsigned int palmas_get_mode_smps(struct regulator_dev *dev)
287 int id = rdev_get_id(dev); 341 int id = rdev_get_id(dev);
288 unsigned int reg; 342 unsigned int reg;
289 343
290 palmas_smps_read(pmic->palmas, palmas_regs_info[id].ctrl_addr, &reg); 344 reg = pmic->current_reg_mode[id] & PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK;
291 reg &= PALMAS_SMPS12_CTRL_STATUS_MASK;
292 reg >>= PALMAS_SMPS12_CTRL_STATUS_SHIFT;
293 345
294 switch (reg) { 346 switch (reg) {
295 case SMPS_CTRL_MODE_ON: 347 case SMPS_CTRL_MODE_ON:
@@ -356,6 +408,63 @@ static int palmas_map_voltage_smps(struct regulator_dev *rdev,
356 return ret; 408 return ret;
357} 409}
358 410
411static int palma_smps_set_voltage_smps_time_sel(struct regulator_dev *rdev,
412 unsigned int old_selector, unsigned int new_selector)
413{
414 struct palmas_pmic *pmic = rdev_get_drvdata(rdev);
415 int id = rdev_get_id(rdev);
416 int old_uv, new_uv;
417 unsigned int ramp_delay = pmic->ramp_delay[id];
418
419 if (!ramp_delay)
420 return 0;
421
422 old_uv = palmas_list_voltage_smps(rdev, old_selector);
423 if (old_uv < 0)
424 return old_uv;
425
426 new_uv = palmas_list_voltage_smps(rdev, new_selector);
427 if (new_uv < 0)
428 return new_uv;
429
430 return DIV_ROUND_UP(abs(old_uv - new_uv), ramp_delay);
431}
432
433static int palmas_smps_set_ramp_delay(struct regulator_dev *rdev,
434 int ramp_delay)
435{
436 struct palmas_pmic *pmic = rdev_get_drvdata(rdev);
437 int id = rdev_get_id(rdev);
438 unsigned int reg = 0;
439 unsigned int addr = palmas_regs_info[id].tstep_addr;
440 int ret;
441
442 /* SMPS3 and SMPS7 do not have tstep_addr setting */
443 switch (id) {
444 case PALMAS_REG_SMPS3:
445 case PALMAS_REG_SMPS7:
446 return 0;
447 }
448
449 if (ramp_delay <= 0)
450 reg = 0;
451 else if (ramp_delay <= 2500)
452 reg = 3;
453 else if (ramp_delay <= 5000)
454 reg = 2;
455 else
456 reg = 1;
457
458 ret = palmas_smps_write(pmic->palmas, addr, reg);
459 if (ret < 0) {
460 dev_err(pmic->palmas->dev, "TSTEP write failed: %d\n", ret);
461 return ret;
462 }
463
464 pmic->ramp_delay[id] = palmas_smps_ramp_delay[reg];
465 return ret;
466}
467
359static struct regulator_ops palmas_ops_smps = { 468static struct regulator_ops palmas_ops_smps = {
360 .is_enabled = palmas_is_enabled_smps, 469 .is_enabled = palmas_is_enabled_smps,
361 .enable = palmas_enable_smps, 470 .enable = palmas_enable_smps,
@@ -366,6 +475,8 @@ static struct regulator_ops palmas_ops_smps = {
366 .set_voltage_sel = regulator_set_voltage_sel_regmap, 475 .set_voltage_sel = regulator_set_voltage_sel_regmap,
367 .list_voltage = palmas_list_voltage_smps, 476 .list_voltage = palmas_list_voltage_smps,
368 .map_voltage = palmas_map_voltage_smps, 477 .map_voltage = palmas_map_voltage_smps,
478 .set_voltage_time_sel = palma_smps_set_voltage_smps_time_sel,
479 .set_ramp_delay = palmas_smps_set_ramp_delay,
369}; 480};
370 481
371static struct regulator_ops palmas_ops_smps10 = { 482static struct regulator_ops palmas_ops_smps10 = {
@@ -401,6 +512,12 @@ static struct regulator_ops palmas_ops_ldo = {
401 .map_voltage = regulator_map_voltage_linear, 512 .map_voltage = regulator_map_voltage_linear,
402}; 513};
403 514
515static struct regulator_ops palmas_ops_extreg = {
516 .is_enabled = regulator_is_enabled_regmap,
517 .enable = regulator_enable_regmap,
518 .disable = regulator_disable_regmap,
519};
520
404/* 521/*
405 * setup the hardware based sleep configuration of the SMPS/LDO regulators 522 * setup the hardware based sleep configuration of the SMPS/LDO regulators
406 * from the platform data. This is different to the software based control 523 * from the platform data. This is different to the software based control
@@ -422,40 +539,32 @@ static int palmas_smps_init(struct palmas *palmas, int id,
422 539
423 switch (id) { 540 switch (id) {
424 case PALMAS_REG_SMPS10: 541 case PALMAS_REG_SMPS10:
425 if (reg_init->mode_sleep) { 542 reg &= ~PALMAS_SMPS10_CTRL_MODE_SLEEP_MASK;
426 reg &= ~PALMAS_SMPS10_CTRL_MODE_SLEEP_MASK; 543 if (reg_init->mode_sleep)
427 reg |= reg_init->mode_sleep << 544 reg |= reg_init->mode_sleep <<
428 PALMAS_SMPS10_CTRL_MODE_SLEEP_SHIFT; 545 PALMAS_SMPS10_CTRL_MODE_SLEEP_SHIFT;
429 }
430 break; 546 break;
431 default: 547 default:
432 if (reg_init->warm_reset) 548 if (reg_init->warm_reset)
433 reg |= PALMAS_SMPS12_CTRL_WR_S; 549 reg |= PALMAS_SMPS12_CTRL_WR_S;
550 else
551 reg &= ~PALMAS_SMPS12_CTRL_WR_S;
434 552
435 if (reg_init->roof_floor) 553 if (reg_init->roof_floor)
436 reg |= PALMAS_SMPS12_CTRL_ROOF_FLOOR_EN; 554 reg |= PALMAS_SMPS12_CTRL_ROOF_FLOOR_EN;
555 else
556 reg &= ~PALMAS_SMPS12_CTRL_ROOF_FLOOR_EN;
437 557
438 if (reg_init->mode_sleep) { 558 reg &= ~PALMAS_SMPS12_CTRL_MODE_SLEEP_MASK;
439 reg &= ~PALMAS_SMPS12_CTRL_MODE_SLEEP_MASK; 559 if (reg_init->mode_sleep)
440 reg |= reg_init->mode_sleep << 560 reg |= reg_init->mode_sleep <<
441 PALMAS_SMPS12_CTRL_MODE_SLEEP_SHIFT; 561 PALMAS_SMPS12_CTRL_MODE_SLEEP_SHIFT;
442 }
443 } 562 }
444 563
445 ret = palmas_smps_write(palmas, addr, reg); 564 ret = palmas_smps_write(palmas, addr, reg);
446 if (ret) 565 if (ret)
447 return ret; 566 return ret;
448 567
449 if (palmas_regs_info[id].tstep_addr && reg_init->tstep) {
450 addr = palmas_regs_info[id].tstep_addr;
451
452 reg = reg_init->tstep & PALMAS_SMPS12_TSTEP_TSTEP_MASK;
453
454 ret = palmas_smps_write(palmas, addr, reg);
455 if (ret)
456 return ret;
457 }
458
459 if (palmas_regs_info[id].vsel_addr && reg_init->vsel) { 568 if (palmas_regs_info[id].vsel_addr && reg_init->vsel) {
460 addr = palmas_regs_info[id].vsel_addr; 569 addr = palmas_regs_info[id].vsel_addr;
461 570
@@ -485,9 +594,13 @@ static int palmas_ldo_init(struct palmas *palmas, int id,
485 594
486 if (reg_init->warm_reset) 595 if (reg_init->warm_reset)
487 reg |= PALMAS_LDO1_CTRL_WR_S; 596 reg |= PALMAS_LDO1_CTRL_WR_S;
597 else
598 reg &= ~PALMAS_LDO1_CTRL_WR_S;
488 599
489 if (reg_init->mode_sleep) 600 if (reg_init->mode_sleep)
490 reg |= PALMAS_LDO1_CTRL_MODE_SLEEP; 601 reg |= PALMAS_LDO1_CTRL_MODE_SLEEP;
602 else
603 reg &= ~PALMAS_LDO1_CTRL_MODE_SLEEP;
491 604
492 ret = palmas_ldo_write(palmas, addr, reg); 605 ret = palmas_ldo_write(palmas, addr, reg);
493 if (ret) 606 if (ret)
@@ -496,6 +609,68 @@ static int palmas_ldo_init(struct palmas *palmas, int id,
496 return 0; 609 return 0;
497} 610}
498 611
612static int palmas_extreg_init(struct palmas *palmas, int id,
613 struct palmas_reg_init *reg_init)
614{
615 unsigned int addr;
616 int ret;
617 unsigned int val = 0;
618
619 addr = palmas_regs_info[id].ctrl_addr;
620
621 if (reg_init->mode_sleep)
622 val = PALMAS_REGEN1_CTRL_MODE_SLEEP;
623
624 ret = palmas_update_bits(palmas, PALMAS_RESOURCE_BASE,
625 addr, PALMAS_REGEN1_CTRL_MODE_SLEEP, val);
626 if (ret < 0) {
627 dev_err(palmas->dev, "Resource reg 0x%02x update failed %d\n",
628 addr, ret);
629 return ret;
630 }
631 return 0;
632}
633
634static void palmas_enable_ldo8_track(struct palmas *palmas)
635{
636 unsigned int reg;
637 unsigned int addr;
638 int ret;
639
640 addr = palmas_regs_info[PALMAS_REG_LDO8].ctrl_addr;
641
642 ret = palmas_ldo_read(palmas, addr, &reg);
643 if (ret) {
644 dev_err(palmas->dev, "Error in reading ldo8 control reg\n");
645 return;
646 }
647
648 reg |= PALMAS_LDO8_CTRL_LDO_TRACKING_EN;
649 ret = palmas_ldo_write(palmas, addr, reg);
650 if (ret < 0) {
651 dev_err(palmas->dev, "Error in enabling tracking mode\n");
652 return;
653 }
654 /*
655 * When SMPS45 is set to off and LDO8 tracking is enabled, the LDO8
656 * output is defined by the LDO8_VOLTAGE.VSEL register divided by two,
657 * and can be set from 0.45 to 1.65 V.
658 */
659 addr = palmas_regs_info[PALMAS_REG_LDO8].vsel_addr;
660 ret = palmas_ldo_read(palmas, addr, &reg);
661 if (ret) {
662 dev_err(palmas->dev, "Error in reading ldo8 voltage reg\n");
663 return;
664 }
665
666 reg = (reg << 1) & PALMAS_LDO8_VOLTAGE_VSEL_MASK;
667 ret = palmas_ldo_write(palmas, addr, reg);
668 if (ret < 0)
669 dev_err(palmas->dev, "Error in setting ldo8 voltage reg\n");
670
671 return;
672}
673
499static struct of_regulator_match palmas_matches[] = { 674static struct of_regulator_match palmas_matches[] = {
500 { .name = "smps12", }, 675 { .name = "smps12", },
501 { .name = "smps123", }, 676 { .name = "smps123", },
@@ -518,6 +693,11 @@ static struct of_regulator_match palmas_matches[] = {
518 { .name = "ldo9", }, 693 { .name = "ldo9", },
519 { .name = "ldoln", }, 694 { .name = "ldoln", },
520 { .name = "ldousb", }, 695 { .name = "ldousb", },
696 { .name = "regen1", },
697 { .name = "regen2", },
698 { .name = "regen3", },
699 { .name = "sysen1", },
700 { .name = "sysen2", },
521}; 701};
522 702
523static void palmas_dt_to_pdata(struct device *dev, 703static void palmas_dt_to_pdata(struct device *dev,
@@ -553,39 +733,36 @@ static void palmas_dt_to_pdata(struct device *dev,
553 pdata->reg_init[idx] = devm_kzalloc(dev, 733 pdata->reg_init[idx] = devm_kzalloc(dev,
554 sizeof(struct palmas_reg_init), GFP_KERNEL); 734 sizeof(struct palmas_reg_init), GFP_KERNEL);
555 735
556 ret = of_property_read_u32(palmas_matches[idx].of_node, 736 pdata->reg_init[idx]->warm_reset =
557 "ti,warm_reset", &prop); 737 of_property_read_bool(palmas_matches[idx].of_node,
558 if (!ret) 738 "ti,warm-reset");
559 pdata->reg_init[idx]->warm_reset = prop;
560 739
561 ret = of_property_read_u32(palmas_matches[idx].of_node, 740 pdata->reg_init[idx]->roof_floor =
562 "ti,roof_floor", &prop); 741 of_property_read_bool(palmas_matches[idx].of_node,
563 if (!ret) 742 "ti,roof-floor");
564 pdata->reg_init[idx]->roof_floor = prop;
565 743
566 ret = of_property_read_u32(palmas_matches[idx].of_node, 744 ret = of_property_read_u32(palmas_matches[idx].of_node,
567 "ti,mode_sleep", &prop); 745 "ti,mode-sleep", &prop);
568 if (!ret) 746 if (!ret)
569 pdata->reg_init[idx]->mode_sleep = prop; 747 pdata->reg_init[idx]->mode_sleep = prop;
570 748
571 ret = of_property_read_u32(palmas_matches[idx].of_node, 749 ret = of_property_read_bool(palmas_matches[idx].of_node,
572 "ti,tstep", &prop); 750 "ti,smps-range");
573 if (!ret) 751 if (ret)
574 pdata->reg_init[idx]->tstep = prop; 752 pdata->reg_init[idx]->vsel =
753 PALMAS_SMPS12_VOLTAGE_RANGE;
575 754
576 ret = of_property_read_u32(palmas_matches[idx].of_node, 755 if (idx == PALMAS_REG_LDO8)
577 "ti,vsel", &prop); 756 pdata->enable_ldo8_tracking = of_property_read_bool(
578 if (!ret) 757 palmas_matches[idx].of_node,
579 pdata->reg_init[idx]->vsel = prop; 758 "ti,enable-ldo8-tracking");
580 } 759 }
581 760
582 ret = of_property_read_u32(node, "ti,ldo6_vibrator", &prop); 761 pdata->ldo6_vibrator = of_property_read_bool(node, "ti,ldo6-vibrator");
583 if (!ret)
584 pdata->ldo6_vibrator = prop;
585} 762}
586 763
587 764
588static int palmas_probe(struct platform_device *pdev) 765static int palmas_regulators_probe(struct platform_device *pdev)
589{ 766{
590 struct palmas *palmas = dev_get_drvdata(pdev->dev.parent); 767 struct palmas *palmas = dev_get_drvdata(pdev->dev.parent);
591 struct palmas_pmic_platform_data *pdata = pdev->dev.platform_data; 768 struct palmas_pmic_platform_data *pdata = pdev->dev.platform_data;
@@ -630,6 +807,7 @@ static int palmas_probe(struct platform_device *pdev)
630 config.driver_data = pmic; 807 config.driver_data = pmic;
631 808
632 for (id = 0; id < PALMAS_REG_LDO1; id++) { 809 for (id = 0; id < PALMAS_REG_LDO1; id++) {
810 bool ramp_delay_support = false;
633 811
634 /* 812 /*
635 * Miss out regulators which are not available due 813 * Miss out regulators which are not available due
@@ -640,19 +818,42 @@ static int palmas_probe(struct platform_device *pdev)
640 case PALMAS_REG_SMPS3: 818 case PALMAS_REG_SMPS3:
641 if (pmic->smps123) 819 if (pmic->smps123)
642 continue; 820 continue;
821 if (id == PALMAS_REG_SMPS12)
822 ramp_delay_support = true;
643 break; 823 break;
644 case PALMAS_REG_SMPS123: 824 case PALMAS_REG_SMPS123:
645 if (!pmic->smps123) 825 if (!pmic->smps123)
646 continue; 826 continue;
827 ramp_delay_support = true;
647 break; 828 break;
648 case PALMAS_REG_SMPS45: 829 case PALMAS_REG_SMPS45:
649 case PALMAS_REG_SMPS7: 830 case PALMAS_REG_SMPS7:
650 if (pmic->smps457) 831 if (pmic->smps457)
651 continue; 832 continue;
833 if (id == PALMAS_REG_SMPS45)
834 ramp_delay_support = true;
652 break; 835 break;
653 case PALMAS_REG_SMPS457: 836 case PALMAS_REG_SMPS457:
654 if (!pmic->smps457) 837 if (!pmic->smps457)
655 continue; 838 continue;
839 ramp_delay_support = true;
840 break;
841 }
842
843 if ((id == PALMAS_REG_SMPS6) && (id == PALMAS_REG_SMPS8))
844 ramp_delay_support = true;
845
846 if (ramp_delay_support) {
847 addr = palmas_regs_info[id].tstep_addr;
848 ret = palmas_smps_read(pmic->palmas, addr, &reg);
849 if (ret < 0) {
850 dev_err(&pdev->dev,
851 "reading TSTEP reg failed: %d\n", ret);
852 goto err_unregister_regulator;
853 }
854 pmic->desc[id].ramp_delay =
855 palmas_smps_ramp_delay[reg & 0x3];
856 pmic->ramp_delay[id] = pmic->desc[id].ramp_delay;
656 } 857 }
657 858
658 /* Initialise sleep/init values from platform data */ 859 /* Initialise sleep/init values from platform data */
@@ -686,7 +887,8 @@ static int palmas_probe(struct platform_device *pdev)
686 /* 887 /*
687 * Read and store the RANGE bit for later use 888 * Read and store the RANGE bit for later use
688 * This must be done before regulator is probed, 889 * This must be done before regulator is probed,
689 * otherwise we error in probe with unsupportable ranges. 890 * otherwise we error in probe with unsupportable
891 * ranges. Read the current smps mode for later use.
690 */ 892 */
691 addr = palmas_regs_info[id].vsel_addr; 893 addr = palmas_regs_info[id].vsel_addr;
692 894
@@ -703,6 +905,14 @@ static int palmas_probe(struct platform_device *pdev)
703 palmas_regs_info[id].vsel_addr); 905 palmas_regs_info[id].vsel_addr);
704 pmic->desc[id].vsel_mask = 906 pmic->desc[id].vsel_mask =
705 PALMAS_SMPS12_VOLTAGE_VSEL_MASK; 907 PALMAS_SMPS12_VOLTAGE_VSEL_MASK;
908
909 /* Read the smps mode for later use. */
910 addr = palmas_regs_info[id].ctrl_addr;
911 ret = palmas_smps_read(pmic->palmas, addr, &reg);
912 if (ret)
913 goto err_unregister_regulator;
914 pmic->current_reg_mode[id] = reg &
915 PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK;
706 } 916 }
707 917
708 pmic->desc[id].type = REGULATOR_VOLTAGE; 918 pmic->desc[id].type = REGULATOR_VOLTAGE;
@@ -713,6 +923,7 @@ static int palmas_probe(struct platform_device *pdev)
713 else 923 else
714 config.init_data = NULL; 924 config.init_data = NULL;
715 925
926 pmic->desc[id].supply_name = palmas_regs_info[id].sname;
716 config.of_node = palmas_matches[id].of_node; 927 config.of_node = palmas_matches[id].of_node;
717 928
718 rdev = regulator_register(&pmic->desc[id], &config); 929 rdev = regulator_register(&pmic->desc[id], &config);
@@ -738,27 +949,49 @@ static int palmas_probe(struct platform_device *pdev)
738 /* Register the regulators */ 949 /* Register the regulators */
739 pmic->desc[id].name = palmas_regs_info[id].name; 950 pmic->desc[id].name = palmas_regs_info[id].name;
740 pmic->desc[id].id = id; 951 pmic->desc[id].id = id;
741 pmic->desc[id].n_voltages = PALMAS_LDO_NUM_VOLTAGES;
742
743 pmic->desc[id].ops = &palmas_ops_ldo;
744
745 pmic->desc[id].type = REGULATOR_VOLTAGE; 952 pmic->desc[id].type = REGULATOR_VOLTAGE;
746 pmic->desc[id].owner = THIS_MODULE; 953 pmic->desc[id].owner = THIS_MODULE;
747 pmic->desc[id].min_uV = 900000; 954
748 pmic->desc[id].uV_step = 50000; 955 if (id < PALMAS_REG_REGEN1) {
749 pmic->desc[id].linear_min_sel = 1; 956 pmic->desc[id].n_voltages = PALMAS_LDO_NUM_VOLTAGES;
750 pmic->desc[id].vsel_reg = PALMAS_BASE_TO_REG(PALMAS_LDO_BASE, 957 pmic->desc[id].ops = &palmas_ops_ldo;
958 pmic->desc[id].min_uV = 900000;
959 pmic->desc[id].uV_step = 50000;
960 pmic->desc[id].linear_min_sel = 1;
961 pmic->desc[id].vsel_reg =
962 PALMAS_BASE_TO_REG(PALMAS_LDO_BASE,
751 palmas_regs_info[id].vsel_addr); 963 palmas_regs_info[id].vsel_addr);
752 pmic->desc[id].vsel_mask = PALMAS_LDO1_VOLTAGE_VSEL_MASK; 964 pmic->desc[id].vsel_mask =
753 pmic->desc[id].enable_reg = PALMAS_BASE_TO_REG(PALMAS_LDO_BASE, 965 PALMAS_LDO1_VOLTAGE_VSEL_MASK;
966 pmic->desc[id].enable_reg =
967 PALMAS_BASE_TO_REG(PALMAS_LDO_BASE,
968 palmas_regs_info[id].ctrl_addr);
969 pmic->desc[id].enable_mask =
970 PALMAS_LDO1_CTRL_MODE_ACTIVE;
971
972 /* Check if LDO8 is in tracking mode or not */
973 if (pdata && (id == PALMAS_REG_LDO8) &&
974 pdata->enable_ldo8_tracking) {
975 palmas_enable_ldo8_track(palmas);
976 pmic->desc[id].min_uV = 450000;
977 pmic->desc[id].uV_step = 25000;
978 }
979 } else {
980 pmic->desc[id].n_voltages = 1;
981 pmic->desc[id].ops = &palmas_ops_extreg;
982 pmic->desc[id].enable_reg =
983 PALMAS_BASE_TO_REG(PALMAS_RESOURCE_BASE,
754 palmas_regs_info[id].ctrl_addr); 984 palmas_regs_info[id].ctrl_addr);
755 pmic->desc[id].enable_mask = PALMAS_LDO1_CTRL_MODE_ACTIVE; 985 pmic->desc[id].enable_mask =
986 PALMAS_REGEN1_CTRL_MODE_ACTIVE;
987 }
756 988
757 if (pdata) 989 if (pdata)
758 config.init_data = pdata->reg_data[id]; 990 config.init_data = pdata->reg_data[id];
759 else 991 else
760 config.init_data = NULL; 992 config.init_data = NULL;
761 993
994 pmic->desc[id].supply_name = palmas_regs_info[id].sname;
762 config.of_node = palmas_matches[id].of_node; 995 config.of_node = palmas_matches[id].of_node;
763 996
764 rdev = regulator_register(&pmic->desc[id], &config); 997 rdev = regulator_register(&pmic->desc[id], &config);
@@ -777,7 +1010,12 @@ static int palmas_probe(struct platform_device *pdev)
777 if (pdata) { 1010 if (pdata) {
778 reg_init = pdata->reg_init[id]; 1011 reg_init = pdata->reg_init[id];
779 if (reg_init) { 1012 if (reg_init) {
780 ret = palmas_ldo_init(palmas, id, reg_init); 1013 if (id < PALMAS_REG_REGEN1)
1014 ret = palmas_ldo_init(palmas,
1015 id, reg_init);
1016 else
1017 ret = palmas_extreg_init(palmas,
1018 id, reg_init);
781 if (ret) { 1019 if (ret) {
782 regulator_unregister(pmic->rdev[id]); 1020 regulator_unregister(pmic->rdev[id]);
783 goto err_unregister_regulator; 1021 goto err_unregister_regulator;
@@ -786,6 +1024,7 @@ static int palmas_probe(struct platform_device *pdev)
786 } 1024 }
787 } 1025 }
788 1026
1027
789 return 0; 1028 return 0;
790 1029
791err_unregister_regulator: 1030err_unregister_regulator:
@@ -794,7 +1033,7 @@ err_unregister_regulator:
794 return ret; 1033 return ret;
795} 1034}
796 1035
797static int palmas_remove(struct platform_device *pdev) 1036static int palmas_regulators_remove(struct platform_device *pdev)
798{ 1037{
799 struct palmas_pmic *pmic = platform_get_drvdata(pdev); 1038 struct palmas_pmic *pmic = platform_get_drvdata(pdev);
800 int id; 1039 int id;
@@ -806,6 +1045,12 @@ static int palmas_remove(struct platform_device *pdev)
806 1045
807static struct of_device_id of_palmas_match_tbl[] = { 1046static struct of_device_id of_palmas_match_tbl[] = {
808 { .compatible = "ti,palmas-pmic", }, 1047 { .compatible = "ti,palmas-pmic", },
1048 { .compatible = "ti,twl6035-pmic", },
1049 { .compatible = "ti,twl6036-pmic", },
1050 { .compatible = "ti,twl6037-pmic", },
1051 { .compatible = "ti,tps65913-pmic", },
1052 { .compatible = "ti,tps65914-pmic", },
1053 { .compatible = "ti,tps80036-pmic", },
809 { /* end */ } 1054 { /* end */ }
810}; 1055};
811 1056
@@ -815,8 +1060,8 @@ static struct platform_driver palmas_driver = {
815 .of_match_table = of_palmas_match_tbl, 1060 .of_match_table = of_palmas_match_tbl,
816 .owner = THIS_MODULE, 1061 .owner = THIS_MODULE,
817 }, 1062 },
818 .probe = palmas_probe, 1063 .probe = palmas_regulators_probe,
819 .remove = palmas_remove, 1064 .remove = palmas_regulators_remove,
820}; 1065};
821 1066
822static int __init palmas_init(void) 1067static int __init palmas_init(void)