aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/regulator
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-03-07 18:56:04 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2010-03-07 18:56:04 -0500
commit6dc3eb5c1f96641cda7056aa34393e317076d6cf (patch)
tree9a615b884d7ff5375382b5a3f020f518f618c589 /drivers/regulator
parent8fe900b8c7aa6a307e552ff776e0c04c28dcf9c8 (diff)
parent2c08583c6a6b4c5f5dea4cb0931eca82af7db6fe (diff)
Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6
* 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6: (66 commits) mfd: Fix ucb1x00 build failure for collie_defconfig mfd: Fix lpc_sch related depends/selects, fix build error gpio: Fix sch_gpio warning gpio: add Intel SCH GPIO controller driver i2c: convert i2c-isch to platform_device mfd: Use completion interrupt for WM831x AUXADC mfd: Use completion interrupt for WM835x AUXADC mfd: Introduce remove_script function for twl4030 mfd/mmc: SDHI Kconfig update mfd: sh_mobile_sdhi MMC_CAP_MMC_HIGHSPEED support gpiolib: Force wm831x GPIOs into GPIO mode when requested mfd: Add WM831x revision B support gpiolib: Correct debugfs display of WM831x GPIO inversion gpiolib: Actually set output state in wm831x_gpio_direction_output() tmio_mmc: Balance cell enable()/disable() calls tmio_mmc: Remove const from platform data V3 tmio_mmc: Use 100ms mmc_detect_change() delay tmio_mmc: Add MMC_CAP_MMC_HIGHSPEED support V2 tmio_mmc: Keep card-detect interrupts enabled mfd: Add twl6030 base addr for ID0, ID1, ID2 ...
Diffstat (limited to 'drivers/regulator')
-rw-r--r--drivers/regulator/88pm8607.c318
-rw-r--r--drivers/regulator/Kconfig8
-rw-r--r--drivers/regulator/Makefile1
-rw-r--r--drivers/regulator/max8925-regulator.c306
-rw-r--r--drivers/regulator/wm8350-regulator.c2
5 files changed, 405 insertions, 230 deletions
diff --git a/drivers/regulator/88pm8607.c b/drivers/regulator/88pm8607.c
index 04719551381b..5fb83e2ced25 100644
--- a/drivers/regulator/88pm8607.c
+++ b/drivers/regulator/88pm8607.c
@@ -11,15 +11,17 @@
11#include <linux/kernel.h> 11#include <linux/kernel.h>
12#include <linux/init.h> 12#include <linux/init.h>
13#include <linux/err.h> 13#include <linux/err.h>
14#include <linux/i2c.h>
14#include <linux/platform_device.h> 15#include <linux/platform_device.h>
15#include <linux/regulator/driver.h> 16#include <linux/regulator/driver.h>
16#include <linux/regulator/machine.h> 17#include <linux/regulator/machine.h>
17#include <linux/mfd/88pm8607.h> 18#include <linux/mfd/88pm860x.h>
18 19
19struct pm8607_regulator_info { 20struct pm8607_regulator_info {
20 struct regulator_desc desc; 21 struct regulator_desc desc;
21 struct pm8607_chip *chip; 22 struct pm860x_chip *chip;
22 struct regulator_dev *regulator; 23 struct regulator_dev *regulator;
24 struct i2c_client *i2c;
23 25
24 int min_uV; 26 int min_uV;
25 int max_uV; 27 int max_uV;
@@ -46,7 +48,6 @@ static inline int check_range(struct pm8607_regulator_info *info,
46static int pm8607_list_voltage(struct regulator_dev *rdev, unsigned index) 48static int pm8607_list_voltage(struct regulator_dev *rdev, unsigned index)
47{ 49{
48 struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); 50 struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
49 uint8_t chip_id = info->chip->chip_id;
50 int ret = -EINVAL; 51 int ret = -EINVAL;
51 52
52 switch (info->desc.id) { 53 switch (info->desc.id) {
@@ -88,79 +89,29 @@ static int pm8607_list_voltage(struct regulator_dev *rdev, unsigned index)
88 case PM8607_ID_LDO2: 89 case PM8607_ID_LDO2:
89 case PM8607_ID_LDO3: 90 case PM8607_ID_LDO3:
90 case PM8607_ID_LDO9: 91 case PM8607_ID_LDO9:
91 switch (chip_id) { 92 ret = (index < 3) ? (index * 50000 + 1800000) :
92 case PM8607_CHIP_A0: 93 ((index < 7) ? (index * 50000 + 2550000) :
93 case PM8607_CHIP_A1: 94 3300000);
94 ret = (index < 3) ? (index * 50000 + 1800000) :
95 ((index < 8) ? (index * 50000 + 2550000) :
96 -EINVAL);
97 break;
98 case PM8607_CHIP_B0:
99 ret = (index < 3) ? (index * 50000 + 1800000) :
100 ((index < 7) ? (index * 50000 + 2550000) :
101 3300000);
102 break;
103 }
104 break; 95 break;
105 case PM8607_ID_LDO4: 96 case PM8607_ID_LDO4:
106 switch (chip_id) { 97 ret = (index < 3) ? (index * 50000 + 1800000) :
107 case PM8607_CHIP_A0: 98 ((index < 6) ? (index * 50000 + 2550000) :
108 case PM8607_CHIP_A1: 99 ((index == 6) ? 2900000 : 3300000));
109 ret = (index < 3) ? (index * 50000 + 1800000) :
110 ((index < 8) ? (index * 50000 + 2550000) :
111 -EINVAL);
112 break;
113 case PM8607_CHIP_B0:
114 ret = (index < 3) ? (index * 50000 + 1800000) :
115 ((index < 6) ? (index * 50000 + 2550000) :
116 ((index == 6) ? 2900000 : 3300000));
117 break;
118 }
119 break; 100 break;
120 case PM8607_ID_LDO6: 101 case PM8607_ID_LDO6:
121 switch (chip_id) { 102 ret = (index < 2) ? (index * 50000 + 1800000) :
122 case PM8607_CHIP_A0: 103 ((index < 7) ? (index * 50000 + 2500000) :
123 case PM8607_CHIP_A1: 104 3300000);
124 ret = (index < 3) ? (index * 50000 + 1800000) :
125 ((index < 8) ? (index * 50000 + 2450000) :
126 -EINVAL);
127 break;
128 case PM8607_CHIP_B0:
129 ret = (index < 2) ? (index * 50000 + 1800000) :
130 ((index < 7) ? (index * 50000 + 2500000) :
131 3300000);
132 break;
133 }
134 break; 105 break;
135 case PM8607_ID_LDO10: 106 case PM8607_ID_LDO10:
136 switch (chip_id) { 107 ret = (index < 3) ? (index * 50000 + 1800000) :
137 case PM8607_CHIP_A0: 108 ((index < 7) ? (index * 50000 + 2550000) :
138 case PM8607_CHIP_A1: 109 ((index == 7) ? 3300000 : 1200000));
139 ret = (index < 3) ? (index * 50000 + 1800000) :
140 ((index < 8) ? (index * 50000 + 2550000) :
141 1200000);
142 break;
143 case PM8607_CHIP_B0:
144 ret = (index < 3) ? (index * 50000 + 1800000) :
145 ((index < 7) ? (index * 50000 + 2550000) :
146 ((index == 7) ? 3300000 : 1200000));
147 break;
148 }
149 break; 110 break;
150 case PM8607_ID_LDO14: 111 case PM8607_ID_LDO14:
151 switch (chip_id) { 112 ret = (index < 2) ? (index * 50000 + 1800000) :
152 case PM8607_CHIP_A0: 113 ((index < 7) ? (index * 50000 + 2600000) :
153 case PM8607_CHIP_A1: 114 3300000);
154 ret = (index < 3) ? (index * 50000 + 1800000) :
155 ((index < 8) ? (index * 50000 + 2550000) :
156 -EINVAL);
157 break;
158 case PM8607_CHIP_B0:
159 ret = (index < 2) ? (index * 50000 + 1800000) :
160 ((index < 7) ? (index * 50000 + 2600000) :
161 3300000);
162 break;
163 }
164 break; 115 break;
165 } 116 }
166 return ret; 117 return ret;
@@ -169,7 +120,6 @@ static int pm8607_list_voltage(struct regulator_dev *rdev, unsigned index)
169static int choose_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) 120static int choose_voltage(struct regulator_dev *rdev, int min_uV, int max_uV)
170{ 121{
171 struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); 122 struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
172 uint8_t chip_id = info->chip->chip_id;
173 int val = -ENOENT; 123 int val = -ENOENT;
174 int ret; 124 int ret;
175 125
@@ -254,161 +204,77 @@ static int choose_voltage(struct regulator_dev *rdev, int min_uV, int max_uV)
254 case PM8607_ID_LDO2: 204 case PM8607_ID_LDO2:
255 case PM8607_ID_LDO3: 205 case PM8607_ID_LDO3:
256 case PM8607_ID_LDO9: 206 case PM8607_ID_LDO9:
257 switch (chip_id) { 207 if (min_uV < 2700000) { /* 1800mV ~ 1900mV / 50mV */
258 case PM8607_CHIP_A0: 208 if (min_uV <= 1800000)
259 case PM8607_CHIP_A1: 209 val = 0;
260 if (min_uV < 2700000) /* 1800mV ~ 1900mV / 50mV */ 210 else if (min_uV <= 1900000)
261 if (min_uV <= 1800000) 211 val = (min_uV - 1750001) / 50000;
262 val = 0; 212 else
263 else if (min_uV <= 1900000) 213 val = 3; /* 2700mV */
264 val = (min_uV - 1750001) / 50000; 214 } else { /* 2700mV ~ 2850mV / 50mV */
265 else 215 if (min_uV <= 2850000) {
266 val = 3; /* 2700mV */ 216 val = (min_uV - 2650001) / 50000;
267 else { /* 2700mV ~ 2900mV / 50mV */ 217 val += 3;
268 if (min_uV <= 2900000) { 218 } else if (min_uV <= 3300000)
269 val = (min_uV - 2650001) / 50000; 219 val = 7;
270 val += 3; 220 else
271 } else 221 val = -EINVAL;
272 val = -EINVAL;
273 }
274 break;
275 case PM8607_CHIP_B0:
276 if (min_uV < 2700000) { /* 1800mV ~ 1900mV / 50mV */
277 if (min_uV <= 1800000)
278 val = 0;
279 else if (min_uV <= 1900000)
280 val = (min_uV - 1750001) / 50000;
281 else
282 val = 3; /* 2700mV */
283 } else { /* 2700mV ~ 2850mV / 50mV */
284 if (min_uV <= 2850000) {
285 val = (min_uV - 2650001) / 50000;
286 val += 3;
287 } else if (min_uV <= 3300000)
288 val = 7;
289 else
290 val = -EINVAL;
291 }
292 break;
293 } 222 }
294 break; 223 break;
295 case PM8607_ID_LDO4: 224 case PM8607_ID_LDO4:
296 switch (chip_id) { 225 if (min_uV < 2700000) { /* 1800mV ~ 1900mV / 50mV */
297 case PM8607_CHIP_A0: 226 if (min_uV <= 1800000)
298 case PM8607_CHIP_A1: 227 val = 0;
299 if (min_uV < 2700000) /* 1800mV ~ 1900mV / 50mV */ 228 else if (min_uV <= 1900000)
300 if (min_uV <= 1800000) 229 val = (min_uV - 1750001) / 50000;
301 val = 0; 230 else
302 else if (min_uV <= 1900000) 231 val = 3; /* 2700mV */
303 val = (min_uV - 1750001) / 50000; 232 } else { /* 2700mV ~ 2800mV / 50mV */
304 else 233 if (min_uV <= 2850000) {
305 val = 3; /* 2700mV */ 234 val = (min_uV - 2650001) / 50000;
306 else { /* 2700mV ~ 2900mV / 50mV */ 235 val += 3;
307 if (min_uV <= 2900000) { 236 } else if (min_uV <= 2900000)
308 val = (min_uV - 2650001) / 50000; 237 val = 6;
309 val += 3; 238 else if (min_uV <= 3300000)
310 } else 239 val = 7;
311 val = -EINVAL; 240 else
312 } 241 val = -EINVAL;
313 break;
314 case PM8607_CHIP_B0:
315 if (min_uV < 2700000) { /* 1800mV ~ 1900mV / 50mV */
316 if (min_uV <= 1800000)
317 val = 0;
318 else if (min_uV <= 1900000)
319 val = (min_uV - 1750001) / 50000;
320 else
321 val = 3; /* 2700mV */
322 } else { /* 2700mV ~ 2800mV / 50mV */
323 if (min_uV <= 2850000) {
324 val = (min_uV - 2650001) / 50000;
325 val += 3;
326 } else if (min_uV <= 2900000)
327 val = 6;
328 else if (min_uV <= 3300000)
329 val = 7;
330 else
331 val = -EINVAL;
332 }
333 break;
334 } 242 }
335 break; 243 break;
336 case PM8607_ID_LDO6: 244 case PM8607_ID_LDO6:
337 switch (chip_id) { 245 if (min_uV < 2600000) { /* 1800mV ~ 1850mV / 50mV */
338 case PM8607_CHIP_A0: 246 if (min_uV <= 1800000)
339 case PM8607_CHIP_A1: 247 val = 0;
340 if (min_uV < 2600000) { /* 1800mV ~ 1900mV / 50mV */ 248 else if (min_uV <= 1850000)
341 if (min_uV <= 1800000) 249 val = (min_uV - 1750001) / 50000;
342 val = 0; 250 else
343 else if (min_uV <= 1900000) 251 val = 2; /* 2600mV */
344 val = (min_uV - 1750001) / 50000; 252 } else { /* 2600mV ~ 2800mV / 50mV */
345 else 253 if (min_uV <= 2800000) {
346 val = 3; /* 2600mV */ 254 val = (min_uV - 2550001) / 50000;
347 } else { /* 2600mV ~ 2800mV / 50mV */ 255 val += 2;
348 if (min_uV <= 2800000) { 256 } else if (min_uV <= 3300000)
349 val = (min_uV - 2550001) / 50000; 257 val = 7;
350 val += 3; 258 else
351 } else 259 val = -EINVAL;
352 val = -EINVAL;
353 }
354 break;
355 case PM8607_CHIP_B0:
356 if (min_uV < 2600000) { /* 1800mV ~ 1850mV / 50mV */
357 if (min_uV <= 1800000)
358 val = 0;
359 else if (min_uV <= 1850000)
360 val = (min_uV - 1750001) / 50000;
361 else
362 val = 2; /* 2600mV */
363 } else { /* 2600mV ~ 2800mV / 50mV */
364 if (min_uV <= 2800000) {
365 val = (min_uV - 2550001) / 50000;
366 val += 2;
367 } else if (min_uV <= 3300000)
368 val = 7;
369 else
370 val = -EINVAL;
371 }
372 break;
373 } 260 }
374 break; 261 break;
375 case PM8607_ID_LDO14: 262 case PM8607_ID_LDO14:
376 switch (chip_id) { 263 if (min_uV < 2700000) { /* 1800mV ~ 1850mV / 50mV */
377 case PM8607_CHIP_A0: 264 if (min_uV <= 1800000)
378 case PM8607_CHIP_A1: 265 val = 0;
379 if (min_uV < 2700000) { /* 1800mV ~ 1900mV / 50mV */ 266 else if (min_uV <= 1850000)
380 if (min_uV <= 1800000) 267 val = (min_uV - 1750001) / 50000;
381 val = 0; 268 else
382 else if (min_uV <= 1900000) 269 val = 2; /* 2700mV */
383 val = (min_uV - 1750001) / 50000; 270 } else { /* 2700mV ~ 2900mV / 50mV */
384 else 271 if (min_uV <= 2900000) {
385 val = 3; /* 2700mV */ 272 val = (min_uV - 2650001) / 50000;
386 } else { /* 2700mV ~ 2900mV / 50mV */ 273 val += 2;
387 if (min_uV <= 2900000) { 274 } else if (min_uV <= 3300000)
388 val = (min_uV - 2650001) / 50000; 275 val = 7;
389 val += 3; 276 else
390 } else 277 val = -EINVAL;
391 val = -EINVAL;
392 }
393 break;
394 case PM8607_CHIP_B0:
395 if (min_uV < 2700000) { /* 1800mV ~ 1850mV / 50mV */
396 if (min_uV <= 1800000)
397 val = 0;
398 else if (min_uV <= 1850000)
399 val = (min_uV - 1750001) / 50000;
400 else
401 val = 2; /* 2700mV */
402 } else { /* 2700mV ~ 2900mV / 50mV */
403 if (min_uV <= 2900000) {
404 val = (min_uV - 2650001) / 50000;
405 val += 2;
406 } else if (min_uV <= 3300000)
407 val = 7;
408 else
409 val = -EINVAL;
410 }
411 break;
412 } 278 }
413 break; 279 break;
414 } 280 }
@@ -428,7 +294,6 @@ static int pm8607_set_voltage(struct regulator_dev *rdev,
428 int min_uV, int max_uV) 294 int min_uV, int max_uV)
429{ 295{
430 struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); 296 struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
431 struct pm8607_chip *chip = info->chip;
432 uint8_t val, mask; 297 uint8_t val, mask;
433 int ret; 298 int ret;
434 299
@@ -443,13 +308,13 @@ static int pm8607_set_voltage(struct regulator_dev *rdev,
443 val = (uint8_t)(ret << info->vol_shift); 308 val = (uint8_t)(ret << info->vol_shift);
444 mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; 309 mask = ((1 << info->vol_nbits) - 1) << info->vol_shift;
445 310
446 ret = pm8607_set_bits(chip, info->vol_reg, mask, val); 311 ret = pm860x_set_bits(info->i2c, info->vol_reg, mask, val);
447 if (ret) 312 if (ret)
448 return ret; 313 return ret;
449 switch (info->desc.id) { 314 switch (info->desc.id) {
450 case PM8607_ID_BUCK1: 315 case PM8607_ID_BUCK1:
451 case PM8607_ID_BUCK3: 316 case PM8607_ID_BUCK3:
452 ret = pm8607_set_bits(chip, info->update_reg, 317 ret = pm860x_set_bits(info->i2c, info->update_reg,
453 1 << info->update_bit, 318 1 << info->update_bit,
454 1 << info->update_bit); 319 1 << info->update_bit);
455 break; 320 break;
@@ -460,11 +325,10 @@ static int pm8607_set_voltage(struct regulator_dev *rdev,
460static int pm8607_get_voltage(struct regulator_dev *rdev) 325static int pm8607_get_voltage(struct regulator_dev *rdev)
461{ 326{
462 struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); 327 struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
463 struct pm8607_chip *chip = info->chip;
464 uint8_t val, mask; 328 uint8_t val, mask;
465 int ret; 329 int ret;
466 330
467 ret = pm8607_reg_read(chip, info->vol_reg); 331 ret = pm860x_reg_read(info->i2c, info->vol_reg);
468 if (ret < 0) 332 if (ret < 0)
469 return ret; 333 return ret;
470 334
@@ -477,9 +341,8 @@ static int pm8607_get_voltage(struct regulator_dev *rdev)
477static int pm8607_enable(struct regulator_dev *rdev) 341static int pm8607_enable(struct regulator_dev *rdev)
478{ 342{
479 struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); 343 struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
480 struct pm8607_chip *chip = info->chip;
481 344
482 return pm8607_set_bits(chip, info->enable_reg, 345 return pm860x_set_bits(info->i2c, info->enable_reg,
483 1 << info->enable_bit, 346 1 << info->enable_bit,
484 1 << info->enable_bit); 347 1 << info->enable_bit);
485} 348}
@@ -487,19 +350,17 @@ static int pm8607_enable(struct regulator_dev *rdev)
487static int pm8607_disable(struct regulator_dev *rdev) 350static int pm8607_disable(struct regulator_dev *rdev)
488{ 351{
489 struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); 352 struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
490 struct pm8607_chip *chip = info->chip;
491 353
492 return pm8607_set_bits(chip, info->enable_reg, 354 return pm860x_set_bits(info->i2c, info->enable_reg,
493 1 << info->enable_bit, 0); 355 1 << info->enable_bit, 0);
494} 356}
495 357
496static int pm8607_is_enabled(struct regulator_dev *rdev) 358static int pm8607_is_enabled(struct regulator_dev *rdev)
497{ 359{
498 struct pm8607_regulator_info *info = rdev_get_drvdata(rdev); 360 struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
499 struct pm8607_chip *chip = info->chip;
500 int ret; 361 int ret;
501 362
502 ret = pm8607_reg_read(chip, info->enable_reg); 363 ret = pm860x_reg_read(info->i2c, info->enable_reg);
503 if (ret < 0) 364 if (ret < 0)
504 return ret; 365 return ret;
505 366
@@ -589,8 +450,8 @@ static inline struct pm8607_regulator_info *find_regulator_info(int id)
589 450
590static int __devinit pm8607_regulator_probe(struct platform_device *pdev) 451static int __devinit pm8607_regulator_probe(struct platform_device *pdev)
591{ 452{
592 struct pm8607_chip *chip = dev_get_drvdata(pdev->dev.parent); 453 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
593 struct pm8607_platform_data *pdata = chip->dev->platform_data; 454 struct pm860x_platform_data *pdata = chip->dev->platform_data;
594 struct pm8607_regulator_info *info = NULL; 455 struct pm8607_regulator_info *info = NULL;
595 456
596 info = find_regulator_info(pdev->id); 457 info = find_regulator_info(pdev->id);
@@ -599,6 +460,7 @@ static int __devinit pm8607_regulator_probe(struct platform_device *pdev)
599 return -EINVAL; 460 return -EINVAL;
600 } 461 }
601 462
463 info->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion;
602 info->chip = chip; 464 info->chip = chip;
603 465
604 info->regulator = regulator_register(&info->desc, &pdev->dev, 466 info->regulator = regulator_register(&info->desc, &pdev->dev,
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 834b48441829..04f2e085116a 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -94,6 +94,12 @@ config REGULATOR_MAX8660
94 This driver controls a Maxim 8660/8661 voltage output 94 This driver controls a Maxim 8660/8661 voltage output
95 regulator via I2C bus. 95 regulator via I2C bus.
96 96
97config REGULATOR_MAX8925
98 tristate "Maxim MAX8925 Power Management IC"
99 depends on MFD_MAX8925
100 help
101 Say y here to support the voltage regulaltor of Maxim MAX8925 PMIC.
102
97config REGULATOR_TWL4030 103config REGULATOR_TWL4030
98 bool "TI TWL4030/TWL5030/TWL6030/TPS695x0 PMIC" 104 bool "TI TWL4030/TWL5030/TWL6030/TPS695x0 PMIC"
99 depends on TWL4030_CORE 105 depends on TWL4030_CORE
@@ -191,7 +197,7 @@ config REGULATOR_TPS6507X
191 197
192config REGULATOR_88PM8607 198config REGULATOR_88PM8607
193 bool "Marvell 88PM8607 Power regulators" 199 bool "Marvell 88PM8607 Power regulators"
194 depends on MFD_88PM8607=y 200 depends on MFD_88PM860X=y
195 help 201 help
196 This driver supports 88PM8607 voltage regulator chips. 202 This driver supports 88PM8607 voltage regulator chips.
197 203
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index e845b66ad59c..4e7feece22d5 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_REGULATOR_MAX1586) += max1586.o
15obj-$(CONFIG_REGULATOR_TWL4030) += twl-regulator.o 15obj-$(CONFIG_REGULATOR_TWL4030) += twl-regulator.o
16obj-$(CONFIG_REGULATOR_MAX8649) += max8649.o 16obj-$(CONFIG_REGULATOR_MAX8649) += max8649.o
17obj-$(CONFIG_REGULATOR_MAX8660) += max8660.o 17obj-$(CONFIG_REGULATOR_MAX8660) += max8660.o
18obj-$(CONFIG_REGULATOR_MAX8925) += max8925-regulator.o
18obj-$(CONFIG_REGULATOR_WM831X) += wm831x-dcdc.o 19obj-$(CONFIG_REGULATOR_WM831X) += wm831x-dcdc.o
19obj-$(CONFIG_REGULATOR_WM831X) += wm831x-isink.o 20obj-$(CONFIG_REGULATOR_WM831X) += wm831x-isink.o
20obj-$(CONFIG_REGULATOR_WM831X) += wm831x-ldo.o 21obj-$(CONFIG_REGULATOR_WM831X) += wm831x-ldo.o
diff --git a/drivers/regulator/max8925-regulator.c b/drivers/regulator/max8925-regulator.c
new file mode 100644
index 000000000000..67873f08ed40
--- /dev/null
+++ b/drivers/regulator/max8925-regulator.c
@@ -0,0 +1,306 @@
1/*
2 * Regulators driver for Maxim max8925
3 *
4 * Copyright (C) 2009 Marvell International Ltd.
5 * Haojian Zhuang <haojian.zhuang@marvell.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#include <linux/kernel.h>
12#include <linux/init.h>
13#include <linux/err.h>
14#include <linux/i2c.h>
15#include <linux/platform_device.h>
16#include <linux/regulator/driver.h>
17#include <linux/regulator/machine.h>
18#include <linux/mfd/max8925.h>
19
20#define SD1_DVM_VMIN 850000
21#define SD1_DVM_VMAX 1000000
22#define SD1_DVM_STEP 50000
23#define SD1_DVM_SHIFT 5 /* SDCTL1 bit5 */
24#define SD1_DVM_EN 6 /* SDV1 bit 6 */
25
26struct max8925_regulator_info {
27 struct regulator_desc desc;
28 struct regulator_dev *regulator;
29 struct i2c_client *i2c;
30 struct max8925_chip *chip;
31
32 int min_uV;
33 int max_uV;
34 int step_uV;
35 int vol_reg;
36 int vol_shift;
37 int vol_nbits;
38 int enable_bit;
39 int enable_reg;
40};
41
42static inline int check_range(struct max8925_regulator_info *info,
43 int min_uV, int max_uV)
44{
45 if (min_uV < info->min_uV || min_uV > info->max_uV)
46 return -EINVAL;
47
48 return 0;
49}
50
51static int max8925_list_voltage(struct regulator_dev *rdev, unsigned index)
52{
53 struct max8925_regulator_info *info = rdev_get_drvdata(rdev);
54 return info->min_uV + index * info->step_uV;
55}
56
57static int max8925_set_voltage(struct regulator_dev *rdev,
58 int min_uV, int max_uV)
59{
60 struct max8925_regulator_info *info = rdev_get_drvdata(rdev);
61 unsigned char data, mask;
62
63 if (check_range(info, min_uV, max_uV)) {
64 dev_err(info->chip->dev, "invalid voltage range (%d, %d) uV\n",
65 min_uV, max_uV);
66 return -EINVAL;
67 }
68 data = (min_uV - info->min_uV + info->step_uV - 1) / info->step_uV;
69 data <<= info->vol_shift;
70 mask = ((1 << info->vol_nbits) - 1) << info->vol_shift;
71
72 return max8925_set_bits(info->i2c, info->vol_reg, mask, data);
73}
74
75static int max8925_get_voltage(struct regulator_dev *rdev)
76{
77 struct max8925_regulator_info *info = rdev_get_drvdata(rdev);
78 unsigned char data, mask;
79 int ret;
80
81 ret = max8925_reg_read(info->i2c, info->vol_reg);
82 if (ret < 0)
83 return ret;
84 mask = ((1 << info->vol_nbits) - 1) << info->vol_shift;
85 data = (ret & mask) >> info->vol_shift;
86
87 return max8925_list_voltage(rdev, data);
88}
89
90static int max8925_enable(struct regulator_dev *rdev)
91{
92 struct max8925_regulator_info *info = rdev_get_drvdata(rdev);
93
94 return max8925_set_bits(info->i2c, info->enable_reg,
95 1 << info->enable_bit,
96 1 << info->enable_bit);
97}
98
99static int max8925_disable(struct regulator_dev *rdev)
100{
101 struct max8925_regulator_info *info = rdev_get_drvdata(rdev);
102
103 return max8925_set_bits(info->i2c, info->enable_reg,
104 1 << info->enable_bit, 0);
105}
106
107static int max8925_is_enabled(struct regulator_dev *rdev)
108{
109 struct max8925_regulator_info *info = rdev_get_drvdata(rdev);
110 int ret;
111
112 ret = max8925_reg_read(info->i2c, info->vol_reg);
113 if (ret < 0)
114 return ret;
115
116 return ret & (1 << info->enable_bit);
117}
118
119static int max8925_set_dvm_voltage(struct regulator_dev *rdev, int uV)
120{
121 struct max8925_regulator_info *info = rdev_get_drvdata(rdev);
122 unsigned char data, mask;
123
124 if (uV < SD1_DVM_VMIN || uV > SD1_DVM_VMAX)
125 return -EINVAL;
126
127 data = (uV - SD1_DVM_VMIN + SD1_DVM_STEP - 1) / SD1_DVM_STEP;
128 data <<= SD1_DVM_SHIFT;
129 mask = 3 << SD1_DVM_SHIFT;
130
131 return max8925_set_bits(info->i2c, info->enable_reg, mask, data);
132}
133
134static int max8925_set_dvm_enable(struct regulator_dev *rdev)
135{
136 struct max8925_regulator_info *info = rdev_get_drvdata(rdev);
137
138 return max8925_set_bits(info->i2c, info->vol_reg, 1 << SD1_DVM_EN,
139 1 << SD1_DVM_EN);
140}
141
142static int max8925_set_dvm_disable(struct regulator_dev *rdev)
143{
144 struct max8925_regulator_info *info = rdev_get_drvdata(rdev);
145
146 return max8925_set_bits(info->i2c, info->vol_reg, 1 << SD1_DVM_EN, 0);
147}
148
149static struct regulator_ops max8925_regulator_sdv_ops = {
150 .set_voltage = max8925_set_voltage,
151 .get_voltage = max8925_get_voltage,
152 .enable = max8925_enable,
153 .disable = max8925_disable,
154 .is_enabled = max8925_is_enabled,
155 .set_suspend_voltage = max8925_set_dvm_voltage,
156 .set_suspend_enable = max8925_set_dvm_enable,
157 .set_suspend_disable = max8925_set_dvm_disable,
158};
159
160static struct regulator_ops max8925_regulator_ldo_ops = {
161 .set_voltage = max8925_set_voltage,
162 .get_voltage = max8925_get_voltage,
163 .enable = max8925_enable,
164 .disable = max8925_disable,
165 .is_enabled = max8925_is_enabled,
166};
167
168#define MAX8925_SDV(_id, min, max, step) \
169{ \
170 .desc = { \
171 .name = "SDV" #_id, \
172 .ops = &max8925_regulator_sdv_ops, \
173 .type = REGULATOR_VOLTAGE, \
174 .id = MAX8925_ID_SD##_id, \
175 .owner = THIS_MODULE, \
176 }, \
177 .min_uV = min * 1000, \
178 .max_uV = max * 1000, \
179 .step_uV = step * 1000, \
180 .vol_reg = MAX8925_SDV##_id, \
181 .vol_shift = 0, \
182 .vol_nbits = 6, \
183 .enable_reg = MAX8925_SDCTL##_id, \
184 .enable_bit = 0, \
185}
186
187#define MAX8925_LDO(_id, min, max, step) \
188{ \
189 .desc = { \
190 .name = "LDO" #_id, \
191 .ops = &max8925_regulator_ldo_ops, \
192 .type = REGULATOR_VOLTAGE, \
193 .id = MAX8925_ID_LDO##_id, \
194 .owner = THIS_MODULE, \
195 }, \
196 .min_uV = min * 1000, \
197 .max_uV = max * 1000, \
198 .step_uV = step * 1000, \
199 .vol_reg = MAX8925_LDOVOUT##_id, \
200 .vol_shift = 0, \
201 .vol_nbits = 6, \
202 .enable_reg = MAX8925_LDOCTL##_id, \
203 .enable_bit = 0, \
204}
205
206static struct max8925_regulator_info max8925_regulator_info[] = {
207 MAX8925_SDV(1, 637.5, 1425, 12.5),
208 MAX8925_SDV(2, 650, 2225, 25),
209 MAX8925_SDV(3, 750, 3900, 50),
210
211 MAX8925_LDO(1, 750, 3900, 50),
212 MAX8925_LDO(2, 650, 2250, 25),
213 MAX8925_LDO(3, 650, 2250, 25),
214 MAX8925_LDO(4, 750, 3900, 50),
215 MAX8925_LDO(5, 750, 3900, 50),
216 MAX8925_LDO(6, 750, 3900, 50),
217 MAX8925_LDO(7, 750, 3900, 50),
218 MAX8925_LDO(8, 750, 3900, 50),
219 MAX8925_LDO(9, 750, 3900, 50),
220 MAX8925_LDO(10, 750, 3900, 50),
221 MAX8925_LDO(11, 750, 3900, 50),
222 MAX8925_LDO(12, 750, 3900, 50),
223 MAX8925_LDO(13, 750, 3900, 50),
224 MAX8925_LDO(14, 750, 3900, 50),
225 MAX8925_LDO(15, 750, 3900, 50),
226 MAX8925_LDO(16, 750, 3900, 50),
227 MAX8925_LDO(17, 650, 2250, 25),
228 MAX8925_LDO(18, 650, 2250, 25),
229 MAX8925_LDO(19, 750, 3900, 50),
230 MAX8925_LDO(20, 750, 3900, 50),
231};
232
233static inline struct max8925_regulator_info *find_regulator_info(int id)
234{
235 struct max8925_regulator_info *ri;
236 int i;
237
238 for (i = 0; i < ARRAY_SIZE(max8925_regulator_info); i++) {
239 ri = &max8925_regulator_info[i];
240 if (ri->desc.id == id)
241 return ri;
242 }
243 return NULL;
244}
245
246static int __devinit max8925_regulator_probe(struct platform_device *pdev)
247{
248 struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent);
249 struct max8925_platform_data *pdata = chip->dev->platform_data;
250 struct max8925_regulator_info *ri = NULL;
251 struct regulator_dev *rdev;
252
253 ri = find_regulator_info(pdev->id);
254 if (ri == NULL) {
255 dev_err(&pdev->dev, "invalid regulator ID specified\n");
256 return -EINVAL;
257 }
258 ri->i2c = chip->i2c;
259 ri->chip = chip;
260
261 rdev = regulator_register(&ri->desc, &pdev->dev,
262 pdata->regulator[pdev->id], ri);
263 if (IS_ERR(rdev)) {
264 dev_err(&pdev->dev, "failed to register regulator %s\n",
265 ri->desc.name);
266 return PTR_ERR(rdev);
267 }
268
269 platform_set_drvdata(pdev, rdev);
270 return 0;
271}
272
273static int __devexit max8925_regulator_remove(struct platform_device *pdev)
274{
275 struct regulator_dev *rdev = platform_get_drvdata(pdev);
276
277 regulator_unregister(rdev);
278 return 0;
279}
280
281static struct platform_driver max8925_regulator_driver = {
282 .driver = {
283 .name = "max8925-regulator",
284 .owner = THIS_MODULE,
285 },
286 .probe = max8925_regulator_probe,
287 .remove = __devexit_p(max8925_regulator_remove),
288};
289
290static int __init max8925_regulator_init(void)
291{
292 return platform_driver_register(&max8925_regulator_driver);
293}
294subsys_initcall(max8925_regulator_init);
295
296static void __exit max8925_regulator_exit(void)
297{
298 platform_driver_unregister(&max8925_regulator_driver);
299}
300module_exit(max8925_regulator_exit);
301
302MODULE_LICENSE("GPL");
303MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
304MODULE_DESCRIPTION("Regulator Driver for Maxim 8925 PMIC");
305MODULE_ALIAS("platform:max8925-regulator");
306
diff --git a/drivers/regulator/wm8350-regulator.c b/drivers/regulator/wm8350-regulator.c
index 94227dd6ba7b..723cd1fb4867 100644
--- a/drivers/regulator/wm8350-regulator.c
+++ b/drivers/regulator/wm8350-regulator.c
@@ -1453,7 +1453,7 @@ static int wm8350_regulator_remove(struct platform_device *pdev)
1453 struct regulator_dev *rdev = platform_get_drvdata(pdev); 1453 struct regulator_dev *rdev = platform_get_drvdata(pdev);
1454 struct wm8350 *wm8350 = rdev_get_drvdata(rdev); 1454 struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
1455 1455
1456 wm8350_free_irq(wm8350, wm8350_reg[pdev->id].irq); 1456 wm8350_free_irq(wm8350, wm8350_reg[pdev->id].irq, rdev);
1457 1457
1458 regulator_unregister(rdev); 1458 regulator_unregister(rdev);
1459 1459