aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAxel Lin <axel.lin@ingics.com>2012-11-20 02:36:46 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2012-11-21 04:50:52 -0500
commit369cf602f364a60c72b8258c21eca8793939328f (patch)
tree73e3c2fea5a99ac844e82e70ad214bb084db1fa1
parent26cbd3073394b966654294c8cb9cb2fec870c567 (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.c80
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
207static 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
222static 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
207static int da9055_regulator_get_voltage_sel(struct regulator_dev *rdev) 242static 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
241static 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
257static int da9055_regulator_set_voltage_sel(struct regulator_dev *rdev, 276static 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
300static int da9055_regulator_set_suspend_voltage(struct regulator_dev *rdev, 319static 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
322static int da9055_suspend_enable(struct regulator_dev *rdev) 342static 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,\