diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-03-07 18:56:04 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-03-07 18:56:04 -0500 |
commit | 6dc3eb5c1f96641cda7056aa34393e317076d6cf (patch) | |
tree | 9a615b884d7ff5375382b5a3f020f518f618c589 /drivers/regulator | |
parent | 8fe900b8c7aa6a307e552ff776e0c04c28dcf9c8 (diff) | |
parent | 2c08583c6a6b4c5f5dea4cb0931eca82af7db6fe (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.c | 318 | ||||
-rw-r--r-- | drivers/regulator/Kconfig | 8 | ||||
-rw-r--r-- | drivers/regulator/Makefile | 1 | ||||
-rw-r--r-- | drivers/regulator/max8925-regulator.c | 306 | ||||
-rw-r--r-- | drivers/regulator/wm8350-regulator.c | 2 |
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 | ||
19 | struct pm8607_regulator_info { | 20 | struct 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, | |||
46 | static int pm8607_list_voltage(struct regulator_dev *rdev, unsigned index) | 48 | static 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) | |||
169 | static int choose_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) | 120 | static 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, | |||
460 | static int pm8607_get_voltage(struct regulator_dev *rdev) | 325 | static 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) | |||
477 | static int pm8607_enable(struct regulator_dev *rdev) | 341 | static 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) | |||
487 | static int pm8607_disable(struct regulator_dev *rdev) | 350 | static 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 | ||
496 | static int pm8607_is_enabled(struct regulator_dev *rdev) | 358 | static 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 | ||
590 | static int __devinit pm8607_regulator_probe(struct platform_device *pdev) | 451 | static 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 | ||
97 | config 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 | |||
97 | config REGULATOR_TWL4030 | 103 | config 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 | ||
192 | config REGULATOR_88PM8607 | 198 | config 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 | |||
15 | obj-$(CONFIG_REGULATOR_TWL4030) += twl-regulator.o | 15 | obj-$(CONFIG_REGULATOR_TWL4030) += twl-regulator.o |
16 | obj-$(CONFIG_REGULATOR_MAX8649) += max8649.o | 16 | obj-$(CONFIG_REGULATOR_MAX8649) += max8649.o |
17 | obj-$(CONFIG_REGULATOR_MAX8660) += max8660.o | 17 | obj-$(CONFIG_REGULATOR_MAX8660) += max8660.o |
18 | obj-$(CONFIG_REGULATOR_MAX8925) += max8925-regulator.o | ||
18 | obj-$(CONFIG_REGULATOR_WM831X) += wm831x-dcdc.o | 19 | obj-$(CONFIG_REGULATOR_WM831X) += wm831x-dcdc.o |
19 | obj-$(CONFIG_REGULATOR_WM831X) += wm831x-isink.o | 20 | obj-$(CONFIG_REGULATOR_WM831X) += wm831x-isink.o |
20 | obj-$(CONFIG_REGULATOR_WM831X) += wm831x-ldo.o | 21 | obj-$(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 | |||
26 | struct 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 | |||
42 | static 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 | |||
51 | static 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 | |||
57 | static 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 | |||
75 | static 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 | |||
90 | static 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 | |||
99 | static 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 | |||
107 | static 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 | |||
119 | static 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 | |||
134 | static 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 | |||
142 | static 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 | |||
149 | static 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 | |||
160 | static 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 | |||
206 | static 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 | |||
233 | static 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 | |||
246 | static 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 | |||
273 | static 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 | |||
281 | static 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 | |||
290 | static int __init max8925_regulator_init(void) | ||
291 | { | ||
292 | return platform_driver_register(&max8925_regulator_driver); | ||
293 | } | ||
294 | subsys_initcall(max8925_regulator_init); | ||
295 | |||
296 | static void __exit max8925_regulator_exit(void) | ||
297 | { | ||
298 | platform_driver_unregister(&max8925_regulator_driver); | ||
299 | } | ||
300 | module_exit(max8925_regulator_exit); | ||
301 | |||
302 | MODULE_LICENSE("GPL"); | ||
303 | MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>"); | ||
304 | MODULE_DESCRIPTION("Regulator Driver for Maxim 8925 PMIC"); | ||
305 | MODULE_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 | ||