diff options
author | Axel Lin <axel.lin@ingics.com> | 2012-11-20 02:36:46 -0500 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2012-11-21 04:50:52 -0500 |
commit | 369cf602f364a60c72b8258c21eca8793939328f (patch) | |
tree | 73e3c2fea5a99ac844e82e70ad214bb084db1fa1 | |
parent | 26cbd3073394b966654294c8cb9cb2fec870c567 (diff) |
regulator: da9055: Properly handle voltage range that doesn't start with 0 offset
This patch implements map_voltage and list_voltage callbacks to properly handle
the case voltage range that doesn't start with 0 offset.
Now we adjust the selector in map_voltage() before calling set_voltage_sel().
And return 0 in list_voltage() for invalid selectors.
With above change, we can remove da9055_regulator_set_voltage_bits function.
One tricky part is that we need adding voffset to n_voltages.
Although for the cases "selector < voffset" are invalid, we need add voffset to
n_voltage so regulator_list_voltage() won't fail while checking the boundary for
selector before calling list_voltage callback.
Signed-off-by: Axel Lin <axel.lin@ingics.com>
Tested-by: Ashish Jangam <ashish.jangam@kpitcummins.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
-rw-r--r-- | drivers/regulator/da9055-regulator.c | 80 |
1 files changed, 50 insertions, 30 deletions
diff --git a/drivers/regulator/da9055-regulator.c b/drivers/regulator/da9055-regulator.c index 79c56655b9b3..121564bb5415 100644 --- a/drivers/regulator/da9055-regulator.c +++ b/drivers/regulator/da9055-regulator.c | |||
@@ -204,6 +204,41 @@ static int da9055_buck_set_current_limit(struct regulator_dev *rdev, int min_uA, | |||
204 | info->mode.mask, val << info->mode.shift); | 204 | info->mode.mask, val << info->mode.shift); |
205 | } | 205 | } |
206 | 206 | ||
207 | static int da9055_list_voltage(struct regulator_dev *rdev, unsigned selector) | ||
208 | { | ||
209 | struct da9055_regulator *regulator = rdev_get_drvdata(rdev); | ||
210 | struct da9055_regulator_info *info = regulator->info; | ||
211 | |||
212 | if (selector >= rdev->desc->n_voltages) | ||
213 | return -EINVAL; | ||
214 | |||
215 | if (selector < info->volt.v_offset) | ||
216 | return 0; | ||
217 | |||
218 | selector -= info->volt.v_offset; | ||
219 | return rdev->desc->min_uV + (rdev->desc->uV_step * selector); | ||
220 | } | ||
221 | |||
222 | static int da9055_map_voltage(struct regulator_dev *rdev, int min_uV, | ||
223 | int max_uV) | ||
224 | { | ||
225 | struct da9055_regulator *regulator = rdev_get_drvdata(rdev); | ||
226 | struct da9055_regulator_info *info = regulator->info; | ||
227 | int sel, voltage; | ||
228 | |||
229 | if (min_uV < rdev->desc->min_uV) | ||
230 | min_uV = rdev->desc->min_uV; | ||
231 | |||
232 | sel = DIV_ROUND_UP(min_uV - rdev->desc->min_uV, rdev->desc->uV_step); | ||
233 | sel += info->volt.v_offset; | ||
234 | |||
235 | voltage = da9055_list_voltage(rdev, sel); | ||
236 | if (voltage < min_uV || voltage > max_uV) | ||
237 | return -EINVAL; | ||
238 | |||
239 | return sel; | ||
240 | } | ||
241 | |||
207 | static int da9055_regulator_get_voltage_sel(struct regulator_dev *rdev) | 242 | static int da9055_regulator_get_voltage_sel(struct regulator_dev *rdev) |
208 | { | 243 | { |
209 | struct da9055_regulator *regulator = rdev_get_drvdata(rdev); | 244 | struct da9055_regulator *regulator = rdev_get_drvdata(rdev); |
@@ -238,22 +273,6 @@ static int da9055_regulator_get_voltage_sel(struct regulator_dev *rdev) | |||
238 | return sel; | 273 | return sel; |
239 | } | 274 | } |
240 | 275 | ||
241 | static int da9055_regulator_set_voltage_bits(struct regulator_dev *rdev, | ||
242 | unsigned int reg, | ||
243 | unsigned int selector) | ||
244 | { | ||
245 | struct da9055_regulator *regulator = rdev_get_drvdata(rdev); | ||
246 | struct da9055_regulator_info *info = regulator->info; | ||
247 | |||
248 | /* Takes care of voltage range that does not start with 0 offset. */ | ||
249 | selector += info->volt.v_offset; | ||
250 | |||
251 | /* Set the voltage */ | ||
252 | return da9055_reg_update(regulator->da9055, reg, info->volt.v_mask, | ||
253 | selector); | ||
254 | |||
255 | } | ||
256 | |||
257 | static int da9055_regulator_set_voltage_sel(struct regulator_dev *rdev, | 276 | static int da9055_regulator_set_voltage_sel(struct regulator_dev *rdev, |
258 | unsigned int selector) | 277 | unsigned int selector) |
259 | { | 278 | { |
@@ -273,8 +292,8 @@ static int da9055_regulator_set_voltage_sel(struct regulator_dev *rdev, | |||
273 | return ret; | 292 | return ret; |
274 | 293 | ||
275 | /* Set the voltage */ | 294 | /* Set the voltage */ |
276 | return da9055_regulator_set_voltage_bits(rdev, info->volt.reg_a, | 295 | return da9055_reg_update(regulator->da9055, info->volt.reg_a, |
277 | selector); | 296 | info->volt.v_mask, selector); |
278 | } | 297 | } |
279 | 298 | ||
280 | /* | 299 | /* |
@@ -290,11 +309,11 @@ static int da9055_regulator_set_voltage_sel(struct regulator_dev *rdev, | |||
290 | 309 | ||
291 | /* Set the voltage */ | 310 | /* Set the voltage */ |
292 | if (ret == DA9055_REGUALTOR_SET_A) | 311 | if (ret == DA9055_REGUALTOR_SET_A) |
293 | return da9055_regulator_set_voltage_bits(rdev, info->volt.reg_a, | 312 | return da9055_reg_update(regulator->da9055, info->volt.reg_a, |
294 | selector); | 313 | info->volt.v_mask, selector); |
295 | else | 314 | else |
296 | return da9055_regulator_set_voltage_bits(rdev, info->volt.reg_b, | 315 | return da9055_reg_update(regulator->da9055, info->volt.reg_b, |
297 | selector); | 316 | info->volt.v_mask, selector); |
298 | } | 317 | } |
299 | 318 | ||
300 | static int da9055_regulator_set_suspend_voltage(struct regulator_dev *rdev, | 319 | static int da9055_regulator_set_suspend_voltage(struct regulator_dev *rdev, |
@@ -312,11 +331,12 @@ static int da9055_regulator_set_suspend_voltage(struct regulator_dev *rdev, | |||
312 | return ret; | 331 | return ret; |
313 | } | 332 | } |
314 | 333 | ||
315 | ret = regulator_map_voltage_linear(rdev, uV, uV); | 334 | ret = da9055_map_voltage(rdev, uV, uV); |
316 | if (ret < 0) | 335 | if (ret < 0) |
317 | return ret; | 336 | return ret; |
318 | 337 | ||
319 | return da9055_regulator_set_voltage_bits(rdev, info->volt.reg_b, ret); | 338 | return da9055_reg_update(regulator->da9055, info->volt.reg_b, |
339 | info->volt.v_mask, ret); | ||
320 | } | 340 | } |
321 | 341 | ||
322 | static int da9055_suspend_enable(struct regulator_dev *rdev) | 342 | static int da9055_suspend_enable(struct regulator_dev *rdev) |
@@ -354,8 +374,8 @@ static struct regulator_ops da9055_buck_ops = { | |||
354 | 374 | ||
355 | .get_voltage_sel = da9055_regulator_get_voltage_sel, | 375 | .get_voltage_sel = da9055_regulator_get_voltage_sel, |
356 | .set_voltage_sel = da9055_regulator_set_voltage_sel, | 376 | .set_voltage_sel = da9055_regulator_set_voltage_sel, |
357 | .list_voltage = regulator_list_voltage_linear, | 377 | .list_voltage = da9055_list_voltage, |
358 | .map_voltage = regulator_map_voltage_linear, | 378 | .map_voltage = da9055_map_voltage, |
359 | .is_enabled = regulator_is_enabled_regmap, | 379 | .is_enabled = regulator_is_enabled_regmap, |
360 | .enable = regulator_enable_regmap, | 380 | .enable = regulator_enable_regmap, |
361 | .disable = regulator_disable_regmap, | 381 | .disable = regulator_disable_regmap, |
@@ -372,8 +392,8 @@ static struct regulator_ops da9055_ldo_ops = { | |||
372 | 392 | ||
373 | .get_voltage_sel = da9055_regulator_get_voltage_sel, | 393 | .get_voltage_sel = da9055_regulator_get_voltage_sel, |
374 | .set_voltage_sel = da9055_regulator_set_voltage_sel, | 394 | .set_voltage_sel = da9055_regulator_set_voltage_sel, |
375 | .list_voltage = regulator_list_voltage_linear, | 395 | .list_voltage = da9055_list_voltage, |
376 | .map_voltage = regulator_map_voltage_linear, | 396 | .map_voltage = da9055_map_voltage, |
377 | .is_enabled = regulator_is_enabled_regmap, | 397 | .is_enabled = regulator_is_enabled_regmap, |
378 | .enable = regulator_enable_regmap, | 398 | .enable = regulator_enable_regmap, |
379 | .disable = regulator_disable_regmap, | 399 | .disable = regulator_disable_regmap, |
@@ -392,7 +412,7 @@ static struct regulator_ops da9055_ldo_ops = { | |||
392 | .ops = &da9055_ldo_ops,\ | 412 | .ops = &da9055_ldo_ops,\ |
393 | .type = REGULATOR_VOLTAGE,\ | 413 | .type = REGULATOR_VOLTAGE,\ |
394 | .id = DA9055_ID_##_id,\ | 414 | .id = DA9055_ID_##_id,\ |
395 | .n_voltages = (max - min) / step + 1, \ | 415 | .n_voltages = (max - min) / step + 1 + (voffset), \ |
396 | .enable_reg = DA9055_REG_BCORE_CONT + DA9055_ID_##_id, \ | 416 | .enable_reg = DA9055_REG_BCORE_CONT + DA9055_ID_##_id, \ |
397 | .enable_mask = 1, \ | 417 | .enable_mask = 1, \ |
398 | .min_uV = (min) * 1000,\ | 418 | .min_uV = (min) * 1000,\ |
@@ -421,7 +441,7 @@ static struct regulator_ops da9055_ldo_ops = { | |||
421 | .ops = &da9055_buck_ops,\ | 441 | .ops = &da9055_buck_ops,\ |
422 | .type = REGULATOR_VOLTAGE,\ | 442 | .type = REGULATOR_VOLTAGE,\ |
423 | .id = DA9055_ID_##_id,\ | 443 | .id = DA9055_ID_##_id,\ |
424 | .n_voltages = (max - min) / step + 1, \ | 444 | .n_voltages = (max - min) / step + 1 + (voffset), \ |
425 | .enable_reg = DA9055_REG_BCORE_CONT + DA9055_ID_##_id, \ | 445 | .enable_reg = DA9055_REG_BCORE_CONT + DA9055_ID_##_id, \ |
426 | .enable_mask = 1,\ | 446 | .enable_mask = 1,\ |
427 | .min_uV = (min) * 1000,\ | 447 | .min_uV = (min) * 1000,\ |