aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/regulator/pcf50633-regulator.c
diff options
context:
space:
mode:
authorLars-Peter Clausen <lars@metafoo.de>2009-08-03 20:03:52 -0400
committerLiam Girdwood <lrg@slimlogic.co.uk>2009-09-22 08:32:41 -0400
commita6576cff1801e2f1a9f328f02bd4cbcab7b03f91 (patch)
tree8757d59b00c962e19dd486a10a617e12d354036a /drivers/regulator/pcf50633-regulator.c
parent9a2372fa7a403ba327873d0208a619d781a8a150 (diff)
Regulator: Implement list_voltage for pcf50633 regulator driver.
This patch implements list_voltage for the pcf50644 regulator driver. As the voltages are linearly scaled the code to convert register values to voltages can be reused and most of the code can be shared with get_voltage. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> Signed-off-by: Liam Girdwood <lrg@slimlogic.co.uk>
Diffstat (limited to 'drivers/regulator/pcf50633-regulator.c')
-rw-r--r--drivers/regulator/pcf50633-regulator.c96
1 files changed, 64 insertions, 32 deletions
diff --git a/drivers/regulator/pcf50633-regulator.c b/drivers/regulator/pcf50633-regulator.c
index 70ba77557650..0803ffe6236d 100644
--- a/drivers/regulator/pcf50633-regulator.c
+++ b/drivers/regulator/pcf50633-regulator.c
@@ -24,11 +24,12 @@
24#include <linux/mfd/pcf50633/core.h> 24#include <linux/mfd/pcf50633/core.h>
25#include <linux/mfd/pcf50633/pmic.h> 25#include <linux/mfd/pcf50633/pmic.h>
26 26
27#define PCF50633_REGULATOR(_name, _id) \ 27#define PCF50633_REGULATOR(_name, _id, _n) \
28 { \ 28 { \
29 .name = _name, \ 29 .name = _name, \
30 .id = _id, \ 30 .id = _id, \
31 .ops = &pcf50633_regulator_ops, \ 31 .ops = &pcf50633_regulator_ops, \
32 .n_voltages = _n, \
32 .type = REGULATOR_VOLTAGE, \ 33 .type = REGULATOR_VOLTAGE, \
33 .owner = THIS_MODULE, \ 34 .owner = THIS_MODULE, \
34 } 35 }
@@ -149,11 +150,42 @@ static int pcf50633_regulator_set_voltage(struct regulator_dev *rdev,
149 return pcf50633_reg_write(pcf, regnr, volt_bits); 150 return pcf50633_reg_write(pcf, regnr, volt_bits);
150} 151}
151 152
153static int pcf50633_regulator_voltage_value(enum pcf50633_regulator_id id,
154 u8 bits)
155{
156 int millivolts;
157
158 switch (id) {
159 case PCF50633_REGULATOR_AUTO:
160 millivolts = auto_voltage_value(bits);
161 break;
162 case PCF50633_REGULATOR_DOWN1:
163 millivolts = down_voltage_value(bits);
164 break;
165 case PCF50633_REGULATOR_DOWN2:
166 millivolts = down_voltage_value(bits);
167 break;
168 case PCF50633_REGULATOR_LDO1:
169 case PCF50633_REGULATOR_LDO2:
170 case PCF50633_REGULATOR_LDO3:
171 case PCF50633_REGULATOR_LDO4:
172 case PCF50633_REGULATOR_LDO5:
173 case PCF50633_REGULATOR_LDO6:
174 case PCF50633_REGULATOR_HCLDO:
175 millivolts = ldo_voltage_value(bits);
176 break;
177 default:
178 return -EINVAL;
179 }
180
181 return millivolts * 1000;
182}
183
152static int pcf50633_regulator_get_voltage(struct regulator_dev *rdev) 184static int pcf50633_regulator_get_voltage(struct regulator_dev *rdev)
153{ 185{
154 struct pcf50633 *pcf; 186 struct pcf50633 *pcf;
155 int regulator_id, millivolts, volt_bits; 187 int regulator_id;
156 u8 regnr; 188 u8 volt_bits, regnr;
157 189
158 pcf = rdev_get_drvdata(rdev); 190 pcf = rdev_get_drvdata(rdev);
159 191
@@ -164,33 +196,32 @@ static int pcf50633_regulator_get_voltage(struct regulator_dev *rdev)
164 regnr = pcf50633_regulator_registers[regulator_id]; 196 regnr = pcf50633_regulator_registers[regulator_id];
165 197
166 volt_bits = pcf50633_reg_read(pcf, regnr); 198 volt_bits = pcf50633_reg_read(pcf, regnr);
167 if (volt_bits < 0) 199
168 return -1; 200 return pcf50633_regulator_voltage_value(regulator_id, volt_bits);
201}
202
203static int pcf50633_regulator_list_voltage(struct regulator_dev *rdev,
204 unsigned int index)
205{
206 struct pcf50633 *pcf;
207 int regulator_id;
208
209 pcf = rdev_get_drvdata(rdev);
210
211 regulator_id = rdev_get_id(rdev);
169 212
170 switch (regulator_id) { 213 switch (regulator_id) {
171 case PCF50633_REGULATOR_AUTO: 214 case PCF50633_REGULATOR_AUTO:
172 millivolts = auto_voltage_value(volt_bits); 215 index += 0x2f;
173 break;
174 case PCF50633_REGULATOR_DOWN1:
175 millivolts = down_voltage_value(volt_bits);
176 break;
177 case PCF50633_REGULATOR_DOWN2:
178 millivolts = down_voltage_value(volt_bits);
179 break; 216 break;
180 case PCF50633_REGULATOR_LDO1:
181 case PCF50633_REGULATOR_LDO2:
182 case PCF50633_REGULATOR_LDO3:
183 case PCF50633_REGULATOR_LDO4:
184 case PCF50633_REGULATOR_LDO5:
185 case PCF50633_REGULATOR_LDO6:
186 case PCF50633_REGULATOR_HCLDO: 217 case PCF50633_REGULATOR_HCLDO:
187 millivolts = ldo_voltage_value(volt_bits); 218 index += 0x01;
188 break; 219 break;
189 default: 220 default:
190 return -EINVAL; 221 break;
191 } 222 }
192 223
193 return millivolts * 1000; 224 return pcf50633_regulator_voltage_value(regulator_id, index);
194} 225}
195 226
196static int pcf50633_regulator_enable(struct regulator_dev *rdev) 227static int pcf50633_regulator_enable(struct regulator_dev *rdev)
@@ -246,6 +277,7 @@ static int pcf50633_regulator_is_enabled(struct regulator_dev *rdev)
246static struct regulator_ops pcf50633_regulator_ops = { 277static struct regulator_ops pcf50633_regulator_ops = {
247 .set_voltage = pcf50633_regulator_set_voltage, 278 .set_voltage = pcf50633_regulator_set_voltage,
248 .get_voltage = pcf50633_regulator_get_voltage, 279 .get_voltage = pcf50633_regulator_get_voltage,
280 .list_voltage = pcf50633_regulator_list_voltage,
249 .enable = pcf50633_regulator_enable, 281 .enable = pcf50633_regulator_enable,
250 .disable = pcf50633_regulator_disable, 282 .disable = pcf50633_regulator_disable,
251 .is_enabled = pcf50633_regulator_is_enabled, 283 .is_enabled = pcf50633_regulator_is_enabled,
@@ -253,27 +285,27 @@ static struct regulator_ops pcf50633_regulator_ops = {
253 285
254static struct regulator_desc regulators[] = { 286static struct regulator_desc regulators[] = {
255 [PCF50633_REGULATOR_AUTO] = 287 [PCF50633_REGULATOR_AUTO] =
256 PCF50633_REGULATOR("auto", PCF50633_REGULATOR_AUTO), 288 PCF50633_REGULATOR("auto", PCF50633_REGULATOR_AUTO, 80),
257 [PCF50633_REGULATOR_DOWN1] = 289 [PCF50633_REGULATOR_DOWN1] =
258 PCF50633_REGULATOR("down1", PCF50633_REGULATOR_DOWN1), 290 PCF50633_REGULATOR("down1", PCF50633_REGULATOR_DOWN1, 95),
259 [PCF50633_REGULATOR_DOWN2] = 291 [PCF50633_REGULATOR_DOWN2] =
260 PCF50633_REGULATOR("down2", PCF50633_REGULATOR_DOWN2), 292 PCF50633_REGULATOR("down2", PCF50633_REGULATOR_DOWN2, 95),
261 [PCF50633_REGULATOR_LDO1] = 293 [PCF50633_REGULATOR_LDO1] =
262 PCF50633_REGULATOR("ldo1", PCF50633_REGULATOR_LDO1), 294 PCF50633_REGULATOR("ldo1", PCF50633_REGULATOR_LDO1, 27),
263 [PCF50633_REGULATOR_LDO2] = 295 [PCF50633_REGULATOR_LDO2] =
264 PCF50633_REGULATOR("ldo2", PCF50633_REGULATOR_LDO2), 296 PCF50633_REGULATOR("ldo2", PCF50633_REGULATOR_LDO2, 27),
265 [PCF50633_REGULATOR_LDO3] = 297 [PCF50633_REGULATOR_LDO3] =
266 PCF50633_REGULATOR("ldo3", PCF50633_REGULATOR_LDO3), 298 PCF50633_REGULATOR("ldo3", PCF50633_REGULATOR_LDO3, 27),
267 [PCF50633_REGULATOR_LDO4] = 299 [PCF50633_REGULATOR_LDO4] =
268 PCF50633_REGULATOR("ldo4", PCF50633_REGULATOR_LDO4), 300 PCF50633_REGULATOR("ldo4", PCF50633_REGULATOR_LDO4, 27),
269 [PCF50633_REGULATOR_LDO5] = 301 [PCF50633_REGULATOR_LDO5] =
270 PCF50633_REGULATOR("ldo5", PCF50633_REGULATOR_LDO5), 302 PCF50633_REGULATOR("ldo5", PCF50633_REGULATOR_LDO5, 27),
271 [PCF50633_REGULATOR_LDO6] = 303 [PCF50633_REGULATOR_LDO6] =
272 PCF50633_REGULATOR("ldo6", PCF50633_REGULATOR_LDO6), 304 PCF50633_REGULATOR("ldo6", PCF50633_REGULATOR_LDO6, 27),
273 [PCF50633_REGULATOR_HCLDO] = 305 [PCF50633_REGULATOR_HCLDO] =
274 PCF50633_REGULATOR("hcldo", PCF50633_REGULATOR_HCLDO), 306 PCF50633_REGULATOR("hcldo", PCF50633_REGULATOR_HCLDO, 26),
275 [PCF50633_REGULATOR_MEMLDO] = 307 [PCF50633_REGULATOR_MEMLDO] =
276 PCF50633_REGULATOR("memldo", PCF50633_REGULATOR_MEMLDO), 308 PCF50633_REGULATOR("memldo", PCF50633_REGULATOR_MEMLDO, 0),
277}; 309};
278 310
279static int __devinit pcf50633_regulator_probe(struct platform_device *pdev) 311static int __devinit pcf50633_regulator_probe(struct platform_device *pdev)