diff options
author | Emeric Vigier <emeric.vigier@stericsson.com> | 2013-03-21 11:58:59 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2013-03-22 07:03:16 -0400 |
commit | bd28a15733df2f3e66e6abc073cdf300df0f01e6 (patch) | |
tree | 73b1d5da94f354c30f4f14283716be57c24efb87 /drivers/regulator/ab8500.c | |
parent | d79df329d0bd425c00856915b7b12f54dd100154 (diff) |
regulator: ab8500: Add set_mode/get_mode support
Signed-off-by: Ludovic Barré <ludovic.barre@stericsson.com>
Signed-off-by: Emeric Vigier <emeric.vigier@stericsson.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
Reviewed-by: Bengt JONSSON <bengt.g.jonsson@stericsson.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'drivers/regulator/ab8500.c')
-rw-r--r-- | drivers/regulator/ab8500.c | 112 |
1 files changed, 94 insertions, 18 deletions
diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c index 4d9d556a47cc..283d9a51114b 100644 --- a/drivers/regulator/ab8500.c +++ b/drivers/regulator/ab8500.c | |||
@@ -30,10 +30,13 @@ | |||
30 | * @dev: device pointer | 30 | * @dev: device pointer |
31 | * @desc: regulator description | 31 | * @desc: regulator description |
32 | * @regulator_dev: regulator device | 32 | * @regulator_dev: regulator device |
33 | * @is_enabled: status of regulator (on/off) | ||
33 | * @update_bank: bank to control on/off | 34 | * @update_bank: bank to control on/off |
34 | * @update_reg: register to control on/off | 35 | * @update_reg: register to control on/off |
35 | * @update_mask: mask to enable/disable regulator | 36 | * @update_mask: mask to enable/disable and set mode of regulator |
36 | * @update_val_enable: bits to enable the regulator in normal (high power) mode | 37 | * @update_val: bits holding the regulator current mode |
38 | * @update_val_idle: bits to enable the regulator in idle (low power) mode | ||
39 | * @update_val_normal: bits to enable the regulator in normal (high power) mode | ||
37 | * @voltage_bank: bank to control regulator voltage | 40 | * @voltage_bank: bank to control regulator voltage |
38 | * @voltage_reg: register to control regulator voltage | 41 | * @voltage_reg: register to control regulator voltage |
39 | * @voltage_mask: mask to control regulator voltage | 42 | * @voltage_mask: mask to control regulator voltage |
@@ -44,10 +47,13 @@ struct ab8500_regulator_info { | |||
44 | struct device *dev; | 47 | struct device *dev; |
45 | struct regulator_desc desc; | 48 | struct regulator_desc desc; |
46 | struct regulator_dev *regulator; | 49 | struct regulator_dev *regulator; |
50 | bool is_enabled; | ||
47 | u8 update_bank; | 51 | u8 update_bank; |
48 | u8 update_reg; | 52 | u8 update_reg; |
49 | u8 update_mask; | 53 | u8 update_mask; |
50 | u8 update_val_enable; | 54 | u8 update_val; |
55 | u8 update_val_idle; | ||
56 | u8 update_val_normal; | ||
51 | u8 voltage_bank; | 57 | u8 voltage_bank; |
52 | u8 voltage_reg; | 58 | u8 voltage_reg; |
53 | u8 voltage_mask; | 59 | u8 voltage_mask; |
@@ -108,15 +114,17 @@ static int ab8500_regulator_enable(struct regulator_dev *rdev) | |||
108 | 114 | ||
109 | ret = abx500_mask_and_set_register_interruptible(info->dev, | 115 | ret = abx500_mask_and_set_register_interruptible(info->dev, |
110 | info->update_bank, info->update_reg, | 116 | info->update_bank, info->update_reg, |
111 | info->update_mask, info->update_val_enable); | 117 | info->update_mask, info->update_val); |
112 | if (ret < 0) | 118 | if (ret < 0) |
113 | dev_err(rdev_get_dev(rdev), | 119 | dev_err(rdev_get_dev(rdev), |
114 | "couldn't set enable bits for regulator\n"); | 120 | "couldn't set enable bits for regulator\n"); |
115 | 121 | ||
122 | info->is_enabled = true; | ||
123 | |||
116 | dev_vdbg(rdev_get_dev(rdev), | 124 | dev_vdbg(rdev_get_dev(rdev), |
117 | "%s-enable (bank, reg, mask, value): 0x%x, 0x%x, 0x%x, 0x%x\n", | 125 | "%s-enable (bank, reg, mask, value): 0x%x, 0x%x, 0x%x, 0x%x\n", |
118 | info->desc.name, info->update_bank, info->update_reg, | 126 | info->desc.name, info->update_bank, info->update_reg, |
119 | info->update_mask, info->update_val_enable); | 127 | info->update_mask, info->update_val); |
120 | 128 | ||
121 | return ret; | 129 | return ret; |
122 | } | 130 | } |
@@ -138,6 +146,8 @@ static int ab8500_regulator_disable(struct regulator_dev *rdev) | |||
138 | dev_err(rdev_get_dev(rdev), | 146 | dev_err(rdev_get_dev(rdev), |
139 | "couldn't set disable bits for regulator\n"); | 147 | "couldn't set disable bits for regulator\n"); |
140 | 148 | ||
149 | info->is_enabled = false; | ||
150 | |||
141 | dev_vdbg(rdev_get_dev(rdev), | 151 | dev_vdbg(rdev_get_dev(rdev), |
142 | "%s-disable (bank, reg, mask, value): 0x%x, 0x%x, 0x%x, 0x%x\n", | 152 | "%s-disable (bank, reg, mask, value): 0x%x, 0x%x, 0x%x, 0x%x\n", |
143 | info->desc.name, info->update_bank, info->update_reg, | 153 | info->desc.name, info->update_bank, info->update_reg, |
@@ -146,6 +156,61 @@ static int ab8500_regulator_disable(struct regulator_dev *rdev) | |||
146 | return ret; | 156 | return ret; |
147 | } | 157 | } |
148 | 158 | ||
159 | static int ab8500_regulator_set_mode(struct regulator_dev *rdev, | ||
160 | unsigned int mode) | ||
161 | { | ||
162 | int ret = 0; | ||
163 | |||
164 | struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); | ||
165 | |||
166 | if (info == NULL) { | ||
167 | dev_err(rdev_get_dev(rdev), "regulator info null pointer\n"); | ||
168 | return -EINVAL; | ||
169 | } | ||
170 | |||
171 | switch (mode) { | ||
172 | case REGULATOR_MODE_NORMAL: | ||
173 | info->update_val = info->update_val_normal; | ||
174 | break; | ||
175 | case REGULATOR_MODE_IDLE: | ||
176 | info->update_val = info->update_val_idle; | ||
177 | break; | ||
178 | default: | ||
179 | return -EINVAL; | ||
180 | } | ||
181 | |||
182 | if (info->is_enabled) { | ||
183 | ret = abx500_mask_and_set_register_interruptible(info->dev, | ||
184 | info->update_bank, info->update_reg, | ||
185 | info->update_mask, info->update_val); | ||
186 | if (ret < 0) | ||
187 | dev_err(rdev_get_dev(rdev), | ||
188 | "couldn't set regulator mode\n"); | ||
189 | } | ||
190 | |||
191 | return ret; | ||
192 | } | ||
193 | |||
194 | static unsigned int ab8500_regulator_get_mode(struct regulator_dev *rdev) | ||
195 | { | ||
196 | struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); | ||
197 | int ret; | ||
198 | |||
199 | if (info == NULL) { | ||
200 | dev_err(rdev_get_dev(rdev), "regulator info null pointer\n"); | ||
201 | return -EINVAL; | ||
202 | } | ||
203 | |||
204 | if (info->update_val == info->update_val_normal) | ||
205 | ret = REGULATOR_MODE_NORMAL; | ||
206 | else if (info->update_val == info->update_val_idle) | ||
207 | ret = REGULATOR_MODE_IDLE; | ||
208 | else | ||
209 | ret = -EINVAL; | ||
210 | |||
211 | return ret; | ||
212 | } | ||
213 | |||
149 | static int ab8500_regulator_is_enabled(struct regulator_dev *rdev) | 214 | static int ab8500_regulator_is_enabled(struct regulator_dev *rdev) |
150 | { | 215 | { |
151 | int ret; | 216 | int ret; |
@@ -172,9 +237,11 @@ static int ab8500_regulator_is_enabled(struct regulator_dev *rdev) | |||
172 | info->update_mask, regval); | 237 | info->update_mask, regval); |
173 | 238 | ||
174 | if (regval & info->update_mask) | 239 | if (regval & info->update_mask) |
175 | return true; | 240 | info->is_enabled = true; |
176 | else | 241 | else |
177 | return false; | 242 | info->is_enabled = false; |
243 | |||
244 | return info->is_enabled; | ||
178 | } | 245 | } |
179 | 246 | ||
180 | static int ab8500_regulator_get_voltage_sel(struct regulator_dev *rdev) | 247 | static int ab8500_regulator_get_voltage_sel(struct regulator_dev *rdev) |
@@ -249,6 +316,8 @@ static int ab8500_regulator_set_voltage_time_sel(struct regulator_dev *rdev, | |||
249 | static struct regulator_ops ab8500_regulator_ops = { | 316 | static struct regulator_ops ab8500_regulator_ops = { |
250 | .enable = ab8500_regulator_enable, | 317 | .enable = ab8500_regulator_enable, |
251 | .disable = ab8500_regulator_disable, | 318 | .disable = ab8500_regulator_disable, |
319 | .set_mode = ab8500_regulator_set_mode, | ||
320 | .get_mode = ab8500_regulator_get_mode, | ||
252 | .is_enabled = ab8500_regulator_is_enabled, | 321 | .is_enabled = ab8500_regulator_is_enabled, |
253 | .get_voltage_sel = ab8500_regulator_get_voltage_sel, | 322 | .get_voltage_sel = ab8500_regulator_get_voltage_sel, |
254 | .set_voltage_sel = ab8500_regulator_set_voltage_sel, | 323 | .set_voltage_sel = ab8500_regulator_set_voltage_sel, |
@@ -284,7 +353,9 @@ static struct ab8500_regulator_info | |||
284 | .update_bank = 0x04, | 353 | .update_bank = 0x04, |
285 | .update_reg = 0x09, | 354 | .update_reg = 0x09, |
286 | .update_mask = 0x03, | 355 | .update_mask = 0x03, |
287 | .update_val_enable = 0x01, | 356 | .update_val = 0x01, |
357 | .update_val_idle = 0x03, | ||
358 | .update_val_normal = 0x01, | ||
288 | .voltage_bank = 0x04, | 359 | .voltage_bank = 0x04, |
289 | .voltage_reg = 0x1f, | 360 | .voltage_reg = 0x1f, |
290 | .voltage_mask = 0x0f, | 361 | .voltage_mask = 0x0f, |
@@ -302,7 +373,9 @@ static struct ab8500_regulator_info | |||
302 | .update_bank = 0x04, | 373 | .update_bank = 0x04, |
303 | .update_reg = 0x09, | 374 | .update_reg = 0x09, |
304 | .update_mask = 0x0c, | 375 | .update_mask = 0x0c, |
305 | .update_val_enable = 0x04, | 376 | .update_val = 0x04, |
377 | .update_val_idle = 0x0c, | ||
378 | .update_val_normal = 0x04, | ||
306 | .voltage_bank = 0x04, | 379 | .voltage_bank = 0x04, |
307 | .voltage_reg = 0x20, | 380 | .voltage_reg = 0x20, |
308 | .voltage_mask = 0x0f, | 381 | .voltage_mask = 0x0f, |
@@ -320,7 +393,9 @@ static struct ab8500_regulator_info | |||
320 | .update_bank = 0x04, | 393 | .update_bank = 0x04, |
321 | .update_reg = 0x0a, | 394 | .update_reg = 0x0a, |
322 | .update_mask = 0x03, | 395 | .update_mask = 0x03, |
323 | .update_val_enable = 0x01, | 396 | .update_val = 0x01, |
397 | .update_val_idle = 0x03, | ||
398 | .update_val_normal = 0x01, | ||
324 | .voltage_bank = 0x04, | 399 | .voltage_bank = 0x04, |
325 | .voltage_reg = 0x21, | 400 | .voltage_reg = 0x21, |
326 | .voltage_mask = 0x07, | 401 | .voltage_mask = 0x07, |
@@ -338,7 +413,9 @@ static struct ab8500_regulator_info | |||
338 | .update_bank = 0x03, | 413 | .update_bank = 0x03, |
339 | .update_reg = 0x80, | 414 | .update_reg = 0x80, |
340 | .update_mask = 0x44, | 415 | .update_mask = 0x44, |
341 | .update_val_enable = 0x04, | 416 | .update_val = 0x04, |
417 | .update_val_idle = 0x44, | ||
418 | .update_val_normal = 0x04, | ||
342 | .voltage_bank = 0x03, | 419 | .voltage_bank = 0x03, |
343 | .voltage_reg = 0x80, | 420 | .voltage_reg = 0x80, |
344 | .voltage_mask = 0x38, | 421 | .voltage_mask = 0x38, |
@@ -365,7 +442,7 @@ static struct ab8500_regulator_info | |||
365 | .update_bank = 0x03, | 442 | .update_bank = 0x03, |
366 | .update_reg = 0x80, | 443 | .update_reg = 0x80, |
367 | .update_mask = 0x82, | 444 | .update_mask = 0x82, |
368 | .update_val_enable = 0x02, | 445 | .update_val = 0x02, |
369 | }, | 446 | }, |
370 | [AB8500_LDO_USB] = { | 447 | [AB8500_LDO_USB] = { |
371 | .desc = { | 448 | .desc = { |
@@ -380,7 +457,6 @@ static struct ab8500_regulator_info | |||
380 | .update_bank = 0x03, | 457 | .update_bank = 0x03, |
381 | .update_reg = 0x82, | 458 | .update_reg = 0x82, |
382 | .update_mask = 0x03, | 459 | .update_mask = 0x03, |
383 | .update_val_enable = 0x01, | ||
384 | }, | 460 | }, |
385 | [AB8500_LDO_AUDIO] = { | 461 | [AB8500_LDO_AUDIO] = { |
386 | .desc = { | 462 | .desc = { |
@@ -395,7 +471,7 @@ static struct ab8500_regulator_info | |||
395 | .update_bank = 0x03, | 471 | .update_bank = 0x03, |
396 | .update_reg = 0x83, | 472 | .update_reg = 0x83, |
397 | .update_mask = 0x02, | 473 | .update_mask = 0x02, |
398 | .update_val_enable = 0x02, | 474 | .update_val = 0x02, |
399 | }, | 475 | }, |
400 | [AB8500_LDO_ANAMIC1] = { | 476 | [AB8500_LDO_ANAMIC1] = { |
401 | .desc = { | 477 | .desc = { |
@@ -410,7 +486,7 @@ static struct ab8500_regulator_info | |||
410 | .update_bank = 0x03, | 486 | .update_bank = 0x03, |
411 | .update_reg = 0x83, | 487 | .update_reg = 0x83, |
412 | .update_mask = 0x08, | 488 | .update_mask = 0x08, |
413 | .update_val_enable = 0x08, | 489 | .update_val = 0x08, |
414 | }, | 490 | }, |
415 | [AB8500_LDO_ANAMIC2] = { | 491 | [AB8500_LDO_ANAMIC2] = { |
416 | .desc = { | 492 | .desc = { |
@@ -425,7 +501,7 @@ static struct ab8500_regulator_info | |||
425 | .update_bank = 0x03, | 501 | .update_bank = 0x03, |
426 | .update_reg = 0x83, | 502 | .update_reg = 0x83, |
427 | .update_mask = 0x10, | 503 | .update_mask = 0x10, |
428 | .update_val_enable = 0x10, | 504 | .update_val = 0x10, |
429 | }, | 505 | }, |
430 | [AB8500_LDO_DMIC] = { | 506 | [AB8500_LDO_DMIC] = { |
431 | .desc = { | 507 | .desc = { |
@@ -440,7 +516,7 @@ static struct ab8500_regulator_info | |||
440 | .update_bank = 0x03, | 516 | .update_bank = 0x03, |
441 | .update_reg = 0x83, | 517 | .update_reg = 0x83, |
442 | .update_mask = 0x04, | 518 | .update_mask = 0x04, |
443 | .update_val_enable = 0x04, | 519 | .update_val = 0x04, |
444 | }, | 520 | }, |
445 | [AB8500_LDO_ANA] = { | 521 | [AB8500_LDO_ANA] = { |
446 | .desc = { | 522 | .desc = { |
@@ -455,7 +531,7 @@ static struct ab8500_regulator_info | |||
455 | .update_bank = 0x04, | 531 | .update_bank = 0x04, |
456 | .update_reg = 0x06, | 532 | .update_reg = 0x06, |
457 | .update_mask = 0x0c, | 533 | .update_mask = 0x0c, |
458 | .update_val_enable = 0x04, | 534 | .update_val = 0x04, |
459 | }, | 535 | }, |
460 | 536 | ||
461 | 537 | ||