aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Brown <broonie@linaro.org>2013-07-19 14:08:29 -0400
committerMark Brown <broonie@linaro.org>2013-07-19 14:08:29 -0400
commite54e6aa245c8a3d349b133bea4f5ad3d491465c9 (patch)
tree02ba23b2dbadd110e02c5a9ae10f7a9010dc76da
parent82b736df4da2c6fdf2c0018938685cf36d112ecd (diff)
parent6c918d220925eeeca75b67e896eabffd061cd128 (diff)
Merge remote-tracking branch 'regulator/topic/linear-range' into HEAD
-rw-r--r--drivers/regulator/core.c95
-rw-r--r--drivers/regulator/wm831x-ldo.c104
-rw-r--r--drivers/regulator/wm8350-regulator.c55
-rw-r--r--drivers/regulator/wm8400-regulator.c50
-rw-r--r--include/linux/regulator/driver.h25
5 files changed, 177 insertions, 152 deletions
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 288c75abc190..42ae134797e0 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -2079,6 +2079,43 @@ int regulator_list_voltage_linear(struct regulator_dev *rdev,
2079EXPORT_SYMBOL_GPL(regulator_list_voltage_linear); 2079EXPORT_SYMBOL_GPL(regulator_list_voltage_linear);
2080 2080
2081/** 2081/**
2082 * regulator_list_voltage_linear_range - List voltages for linear ranges
2083 *
2084 * @rdev: Regulator device
2085 * @selector: Selector to convert into a voltage
2086 *
2087 * Regulators with a series of simple linear mappings between voltages
2088 * and selectors can set linear_ranges in the regulator descriptor and
2089 * then use this function as their list_voltage() operation,
2090 */
2091int regulator_list_voltage_linear_range(struct regulator_dev *rdev,
2092 unsigned int selector)
2093{
2094 const struct regulator_linear_range *range;
2095 int i;
2096
2097 if (!rdev->desc->n_linear_ranges) {
2098 BUG_ON(!rdev->desc->n_linear_ranges);
2099 return -EINVAL;
2100 }
2101
2102 for (i = 0; i < rdev->desc->n_linear_ranges; i++) {
2103 range = &rdev->desc->linear_ranges[i];
2104
2105 if (!(selector >= range->min_sel &&
2106 selector <= range->max_sel))
2107 continue;
2108
2109 selector -= range->min_sel;
2110
2111 return range->min_uV + (range->uV_step * selector);
2112 }
2113
2114 return -EINVAL;
2115}
2116EXPORT_SYMBOL_GPL(regulator_list_voltage_linear_range);
2117
2118/**
2082 * regulator_list_voltage_table - List voltages with table based mapping 2119 * regulator_list_voltage_table - List voltages with table based mapping
2083 * 2120 *
2084 * @rdev: Regulator device 2121 * @rdev: Regulator device
@@ -2368,6 +2405,64 @@ int regulator_map_voltage_linear(struct regulator_dev *rdev,
2368} 2405}
2369EXPORT_SYMBOL_GPL(regulator_map_voltage_linear); 2406EXPORT_SYMBOL_GPL(regulator_map_voltage_linear);
2370 2407
2408/**
2409 * regulator_map_voltage_linear - map_voltage() for multiple linear ranges
2410 *
2411 * @rdev: Regulator to operate on
2412 * @min_uV: Lower bound for voltage
2413 * @max_uV: Upper bound for voltage
2414 *
2415 * Drivers providing linear_ranges in their descriptor can use this as
2416 * their map_voltage() callback.
2417 */
2418int regulator_map_voltage_linear_range(struct regulator_dev *rdev,
2419 int min_uV, int max_uV)
2420{
2421 const struct regulator_linear_range *range;
2422 int ret = -EINVAL;
2423 int voltage, i;
2424
2425 if (!rdev->desc->n_linear_ranges) {
2426 BUG_ON(!rdev->desc->n_linear_ranges);
2427 return -EINVAL;
2428 }
2429
2430 for (i = 0; i < rdev->desc->n_linear_ranges; i++) {
2431 range = &rdev->desc->linear_ranges[i];
2432
2433 if (!(min_uV <= range->max_uV && max_uV >= range->min_uV))
2434 continue;
2435
2436 if (min_uV <= range->min_uV)
2437 min_uV = range->min_uV;
2438
2439 /* range->uV_step == 0 means fixed voltage range */
2440 if (range->uV_step == 0) {
2441 ret = 0;
2442 } else {
2443 ret = DIV_ROUND_UP(min_uV - range->min_uV,
2444 range->uV_step);
2445 if (ret < 0)
2446 return ret;
2447 }
2448
2449 ret += range->min_sel;
2450
2451 break;
2452 }
2453
2454 if (i == rdev->desc->n_linear_ranges)
2455 return -EINVAL;
2456
2457 /* Map back into a voltage to verify we're still in bounds */
2458 voltage = rdev->desc->ops->list_voltage(rdev, ret);
2459 if (voltage < min_uV || voltage > max_uV)
2460 return -EINVAL;
2461
2462 return ret;
2463}
2464EXPORT_SYMBOL_GPL(regulator_map_voltage_linear_range);
2465
2371static int _regulator_do_set_voltage(struct regulator_dev *rdev, 2466static int _regulator_do_set_voltage(struct regulator_dev *rdev,
2372 int min_uV, int max_uV) 2467 int min_uV, int max_uV)
2373{ 2468{
diff --git a/drivers/regulator/wm831x-ldo.c b/drivers/regulator/wm831x-ldo.c
index 9ff883f80878..76792c7d86f3 100644
--- a/drivers/regulator/wm831x-ldo.c
+++ b/drivers/regulator/wm831x-ldo.c
@@ -62,41 +62,12 @@ static irqreturn_t wm831x_ldo_uv_irq(int irq, void *data)
62 * General purpose LDOs 62 * General purpose LDOs
63 */ 63 */
64 64
65#define WM831X_GP_LDO_SELECTOR_LOW 0xe 65static const struct regulator_linear_range wm831x_gp_ldo_ranges[] = {
66#define WM831X_GP_LDO_MAX_SELECTOR 0x1f 66 { .min_uV = 900000, .max_uV = 1650000, .min_sel = 0, .max_sel = 14,
67 67 .uV_step = 50000 },
68static int wm831x_gp_ldo_list_voltage(struct regulator_dev *rdev, 68 { .min_uV = 1700000, .max_uV = 3300000, .min_sel = 15, .max_sel = 31,
69 unsigned int selector) 69 .uV_step = 100000 },
70{ 70};
71 /* 0.9-1.6V in 50mV steps */
72 if (selector <= WM831X_GP_LDO_SELECTOR_LOW)
73 return 900000 + (selector * 50000);
74 /* 1.7-3.3V in 100mV steps */
75 if (selector <= WM831X_GP_LDO_MAX_SELECTOR)
76 return 1600000 + ((selector - WM831X_GP_LDO_SELECTOR_LOW)
77 * 100000);
78 return -EINVAL;
79}
80
81static int wm831x_gp_ldo_map_voltage(struct regulator_dev *rdev,
82 int min_uV, int max_uV)
83{
84 int volt, vsel;
85
86 if (min_uV < 900000)
87 vsel = 0;
88 else if (min_uV < 1700000)
89 vsel = ((min_uV - 900000) / 50000);
90 else
91 vsel = ((min_uV - 1700000) / 100000)
92 + WM831X_GP_LDO_SELECTOR_LOW + 1;
93
94 volt = wm831x_gp_ldo_list_voltage(rdev, vsel);
95 if (volt < min_uV || volt > max_uV)
96 return -EINVAL;
97
98 return vsel;
99}
100 71
101static int wm831x_gp_ldo_set_suspend_voltage(struct regulator_dev *rdev, 72static int wm831x_gp_ldo_set_suspend_voltage(struct regulator_dev *rdev,
102 int uV) 73 int uV)
@@ -105,7 +76,7 @@ static int wm831x_gp_ldo_set_suspend_voltage(struct regulator_dev *rdev,
105 struct wm831x *wm831x = ldo->wm831x; 76 struct wm831x *wm831x = ldo->wm831x;
106 int sel, reg = ldo->base + WM831X_LDO_SLEEP_CONTROL; 77 int sel, reg = ldo->base + WM831X_LDO_SLEEP_CONTROL;
107 78
108 sel = wm831x_gp_ldo_map_voltage(rdev, uV, uV); 79 sel = regulator_map_voltage_linear_range(rdev, uV, uV);
109 if (sel < 0) 80 if (sel < 0)
110 return sel; 81 return sel;
111 82
@@ -230,8 +201,8 @@ static unsigned int wm831x_gp_ldo_get_optimum_mode(struct regulator_dev *rdev,
230 201
231 202
232static struct regulator_ops wm831x_gp_ldo_ops = { 203static struct regulator_ops wm831x_gp_ldo_ops = {
233 .list_voltage = wm831x_gp_ldo_list_voltage, 204 .list_voltage = regulator_list_voltage_linear_range,
234 .map_voltage = wm831x_gp_ldo_map_voltage, 205 .map_voltage = regulator_map_voltage_linear_range,
235 .get_voltage_sel = regulator_get_voltage_sel_regmap, 206 .get_voltage_sel = regulator_get_voltage_sel_regmap,
236 .set_voltage_sel = regulator_set_voltage_sel_regmap, 207 .set_voltage_sel = regulator_set_voltage_sel_regmap,
237 .set_suspend_voltage = wm831x_gp_ldo_set_suspend_voltage, 208 .set_suspend_voltage = wm831x_gp_ldo_set_suspend_voltage,
@@ -290,7 +261,7 @@ static int wm831x_gp_ldo_probe(struct platform_device *pdev)
290 261
291 ldo->desc.id = id; 262 ldo->desc.id = id;
292 ldo->desc.type = REGULATOR_VOLTAGE; 263 ldo->desc.type = REGULATOR_VOLTAGE;
293 ldo->desc.n_voltages = WM831X_GP_LDO_MAX_SELECTOR + 1; 264 ldo->desc.n_voltages = 32;
294 ldo->desc.ops = &wm831x_gp_ldo_ops; 265 ldo->desc.ops = &wm831x_gp_ldo_ops;
295 ldo->desc.owner = THIS_MODULE; 266 ldo->desc.owner = THIS_MODULE;
296 ldo->desc.vsel_reg = ldo->base + WM831X_LDO_ON_CONTROL; 267 ldo->desc.vsel_reg = ldo->base + WM831X_LDO_ON_CONTROL;
@@ -299,6 +270,8 @@ static int wm831x_gp_ldo_probe(struct platform_device *pdev)
299 ldo->desc.enable_mask = 1 << id; 270 ldo->desc.enable_mask = 1 << id;
300 ldo->desc.bypass_reg = ldo->base; 271 ldo->desc.bypass_reg = ldo->base;
301 ldo->desc.bypass_mask = WM831X_LDO1_SWI; 272 ldo->desc.bypass_mask = WM831X_LDO1_SWI;
273 ldo->desc.linear_ranges = wm831x_gp_ldo_ranges;
274 ldo->desc.n_linear_ranges = ARRAY_SIZE(wm831x_gp_ldo_ranges);
302 275
303 config.dev = pdev->dev.parent; 276 config.dev = pdev->dev.parent;
304 if (pdata) 277 if (pdata)
@@ -358,43 +331,12 @@ static struct platform_driver wm831x_gp_ldo_driver = {
358 * Analogue LDOs 331 * Analogue LDOs
359 */ 332 */
360 333
361 334static const struct regulator_linear_range wm831x_aldo_ranges[] = {
362#define WM831X_ALDO_SELECTOR_LOW 0xc 335 { .min_uV = 1000000, .max_uV = 1650000, .min_sel = 0, .max_sel = 12,
363#define WM831X_ALDO_MAX_SELECTOR 0x1f 336 .uV_step = 50000 },
364 337 { .min_uV = 1700000, .max_uV = 3500000, .min_sel = 13, .max_sel = 31,
365static int wm831x_aldo_list_voltage(struct regulator_dev *rdev, 338 .uV_step = 100000 },
366 unsigned int selector) 339};
367{
368 /* 1-1.6V in 50mV steps */
369 if (selector <= WM831X_ALDO_SELECTOR_LOW)
370 return 1000000 + (selector * 50000);
371 /* 1.7-3.5V in 100mV steps */
372 if (selector <= WM831X_ALDO_MAX_SELECTOR)
373 return 1600000 + ((selector - WM831X_ALDO_SELECTOR_LOW)
374 * 100000);
375 return -EINVAL;
376}
377
378static int wm831x_aldo_map_voltage(struct regulator_dev *rdev,
379 int min_uV, int max_uV)
380{
381 int volt, vsel;
382
383 if (min_uV < 1000000)
384 vsel = 0;
385 else if (min_uV < 1700000)
386 vsel = ((min_uV - 1000000) / 50000);
387 else
388 vsel = ((min_uV - 1700000) / 100000)
389 + WM831X_ALDO_SELECTOR_LOW + 1;
390
391 volt = wm831x_aldo_list_voltage(rdev, vsel);
392 if (volt < min_uV || volt > max_uV)
393 return -EINVAL;
394
395 return vsel;
396
397}
398 340
399static int wm831x_aldo_set_suspend_voltage(struct regulator_dev *rdev, 341static int wm831x_aldo_set_suspend_voltage(struct regulator_dev *rdev,
400 int uV) 342 int uV)
@@ -403,7 +345,7 @@ static int wm831x_aldo_set_suspend_voltage(struct regulator_dev *rdev,
403 struct wm831x *wm831x = ldo->wm831x; 345 struct wm831x *wm831x = ldo->wm831x;
404 int sel, reg = ldo->base + WM831X_LDO_SLEEP_CONTROL; 346 int sel, reg = ldo->base + WM831X_LDO_SLEEP_CONTROL;
405 347
406 sel = wm831x_aldo_map_voltage(rdev, uV, uV); 348 sel = regulator_map_voltage_linear_range(rdev, uV, uV);
407 if (sel < 0) 349 if (sel < 0)
408 return sel; 350 return sel;
409 351
@@ -486,8 +428,8 @@ static int wm831x_aldo_get_status(struct regulator_dev *rdev)
486} 428}
487 429
488static struct regulator_ops wm831x_aldo_ops = { 430static struct regulator_ops wm831x_aldo_ops = {
489 .list_voltage = wm831x_aldo_list_voltage, 431 .list_voltage = regulator_list_voltage_linear_range,
490 .map_voltage = wm831x_aldo_map_voltage, 432 .map_voltage = regulator_map_voltage_linear_range,
491 .get_voltage_sel = regulator_get_voltage_sel_regmap, 433 .get_voltage_sel = regulator_get_voltage_sel_regmap,
492 .set_voltage_sel = regulator_set_voltage_sel_regmap, 434 .set_voltage_sel = regulator_set_voltage_sel_regmap,
493 .set_suspend_voltage = wm831x_aldo_set_suspend_voltage, 435 .set_suspend_voltage = wm831x_aldo_set_suspend_voltage,
@@ -545,7 +487,9 @@ static int wm831x_aldo_probe(struct platform_device *pdev)
545 487
546 ldo->desc.id = id; 488 ldo->desc.id = id;
547 ldo->desc.type = REGULATOR_VOLTAGE; 489 ldo->desc.type = REGULATOR_VOLTAGE;
548 ldo->desc.n_voltages = WM831X_ALDO_MAX_SELECTOR + 1; 490 ldo->desc.n_voltages = 32;
491 ldo->desc.linear_ranges = wm831x_aldo_ranges;
492 ldo->desc.n_linear_ranges = ARRAY_SIZE(wm831x_aldo_ranges);
549 ldo->desc.ops = &wm831x_aldo_ops; 493 ldo->desc.ops = &wm831x_aldo_ops;
550 ldo->desc.owner = THIS_MODULE; 494 ldo->desc.owner = THIS_MODULE;
551 ldo->desc.vsel_reg = ldo->base + WM831X_LDO_ON_CONTROL; 495 ldo->desc.vsel_reg = ldo->base + WM831X_LDO_ON_CONTROL;
diff --git a/drivers/regulator/wm8350-regulator.c b/drivers/regulator/wm8350-regulator.c
index 7f0fa22ef2aa..5453dd0105ed 100644
--- a/drivers/regulator/wm8350-regulator.c
+++ b/drivers/regulator/wm8350-regulator.c
@@ -542,41 +542,12 @@ static int wm8350_dcdc_set_suspend_mode(struct regulator_dev *rdev,
542 return 0; 542 return 0;
543} 543}
544 544
545static int wm8350_ldo_list_voltage(struct regulator_dev *rdev, 545static const struct regulator_linear_range wm8350_ldo_ranges[] = {
546 unsigned selector) 546 { .min_uV = 900000, .max_uV = 1750000, .min_sel = 0, .max_sel = 15,
547{ 547 .uV_step = 50000 },
548 if (selector > WM8350_LDO1_VSEL_MASK) 548 { .min_uV = 1800000, .max_uV = 3300000, .min_sel = 16, .max_sel = 31,
549 return -EINVAL; 549 .uV_step = 100000 },
550 550};
551 if (selector < 16)
552 return (selector * 50000) + 900000;
553 else
554 return ((selector - 16) * 100000) + 1800000;
555}
556
557static int wm8350_ldo_map_voltage(struct regulator_dev *rdev, int min_uV,
558 int max_uV)
559{
560 int volt, sel;
561 int min_mV = min_uV / 1000;
562 int max_mV = max_uV / 1000;
563
564 if (min_mV < 900 || min_mV > 3300)
565 return -EINVAL;
566 if (max_mV < 900 || max_mV > 3300)
567 return -EINVAL;
568
569 if (min_mV < 1800) /* step size is 50mV < 1800mV */
570 sel = DIV_ROUND_UP(min_uV - 900, 50);
571 else /* step size is 100mV > 1800mV */
572 sel = DIV_ROUND_UP(min_uV - 1800, 100) + 16;
573
574 volt = wm8350_ldo_list_voltage(rdev, sel);
575 if (volt < min_uV || volt > max_uV)
576 return -EINVAL;
577
578 return sel;
579}
580 551
581static int wm8350_ldo_set_suspend_voltage(struct regulator_dev *rdev, int uV) 552static int wm8350_ldo_set_suspend_voltage(struct regulator_dev *rdev, int uV)
582{ 553{
@@ -603,7 +574,7 @@ static int wm8350_ldo_set_suspend_voltage(struct regulator_dev *rdev, int uV)
603 return -EINVAL; 574 return -EINVAL;
604 } 575 }
605 576
606 sel = wm8350_ldo_map_voltage(rdev, uV, uV); 577 sel = regulator_map_voltage_linear_range(rdev, uV, uV);
607 if (sel < 0) 578 if (sel < 0)
608 return -EINVAL; 579 return -EINVAL;
609 580
@@ -998,10 +969,10 @@ static struct regulator_ops wm8350_dcdc2_5_ops = {
998}; 969};
999 970
1000static struct regulator_ops wm8350_ldo_ops = { 971static struct regulator_ops wm8350_ldo_ops = {
1001 .map_voltage = wm8350_ldo_map_voltage, 972 .map_voltage = regulator_map_voltage_linear_range,
1002 .set_voltage_sel = regulator_set_voltage_sel_regmap, 973 .set_voltage_sel = regulator_set_voltage_sel_regmap,
1003 .get_voltage_sel = regulator_get_voltage_sel_regmap, 974 .get_voltage_sel = regulator_get_voltage_sel_regmap,
1004 .list_voltage = wm8350_ldo_list_voltage, 975 .list_voltage = regulator_list_voltage_linear_range,
1005 .enable = regulator_enable_regmap, 976 .enable = regulator_enable_regmap,
1006 .disable = regulator_disable_regmap, 977 .disable = regulator_disable_regmap,
1007 .is_enabled = regulator_is_enabled_regmap, 978 .is_enabled = regulator_is_enabled_regmap,
@@ -1108,6 +1079,8 @@ static const struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = {
1108 .irq = WM8350_IRQ_UV_LDO1, 1079 .irq = WM8350_IRQ_UV_LDO1,
1109 .type = REGULATOR_VOLTAGE, 1080 .type = REGULATOR_VOLTAGE,
1110 .n_voltages = WM8350_LDO1_VSEL_MASK + 1, 1081 .n_voltages = WM8350_LDO1_VSEL_MASK + 1,
1082 .linear_ranges = wm8350_ldo_ranges,
1083 .n_linear_ranges = ARRAY_SIZE(wm8350_ldo_ranges),
1111 .vsel_reg = WM8350_LDO1_CONTROL, 1084 .vsel_reg = WM8350_LDO1_CONTROL,
1112 .vsel_mask = WM8350_LDO1_VSEL_MASK, 1085 .vsel_mask = WM8350_LDO1_VSEL_MASK,
1113 .enable_reg = WM8350_DCDC_LDO_REQUESTED, 1086 .enable_reg = WM8350_DCDC_LDO_REQUESTED,
@@ -1121,6 +1094,8 @@ static const struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = {
1121 .irq = WM8350_IRQ_UV_LDO2, 1094 .irq = WM8350_IRQ_UV_LDO2,
1122 .type = REGULATOR_VOLTAGE, 1095 .type = REGULATOR_VOLTAGE,
1123 .n_voltages = WM8350_LDO2_VSEL_MASK + 1, 1096 .n_voltages = WM8350_LDO2_VSEL_MASK + 1,
1097 .linear_ranges = wm8350_ldo_ranges,
1098 .n_linear_ranges = ARRAY_SIZE(wm8350_ldo_ranges),
1124 .vsel_reg = WM8350_LDO2_CONTROL, 1099 .vsel_reg = WM8350_LDO2_CONTROL,
1125 .vsel_mask = WM8350_LDO2_VSEL_MASK, 1100 .vsel_mask = WM8350_LDO2_VSEL_MASK,
1126 .enable_reg = WM8350_DCDC_LDO_REQUESTED, 1101 .enable_reg = WM8350_DCDC_LDO_REQUESTED,
@@ -1134,6 +1109,8 @@ static const struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = {
1134 .irq = WM8350_IRQ_UV_LDO3, 1109 .irq = WM8350_IRQ_UV_LDO3,
1135 .type = REGULATOR_VOLTAGE, 1110 .type = REGULATOR_VOLTAGE,
1136 .n_voltages = WM8350_LDO3_VSEL_MASK + 1, 1111 .n_voltages = WM8350_LDO3_VSEL_MASK + 1,
1112 .linear_ranges = wm8350_ldo_ranges,
1113 .n_linear_ranges = ARRAY_SIZE(wm8350_ldo_ranges),
1137 .vsel_reg = WM8350_LDO3_CONTROL, 1114 .vsel_reg = WM8350_LDO3_CONTROL,
1138 .vsel_mask = WM8350_LDO3_VSEL_MASK, 1115 .vsel_mask = WM8350_LDO3_VSEL_MASK,
1139 .enable_reg = WM8350_DCDC_LDO_REQUESTED, 1116 .enable_reg = WM8350_DCDC_LDO_REQUESTED,
@@ -1147,6 +1124,8 @@ static const struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = {
1147 .irq = WM8350_IRQ_UV_LDO4, 1124 .irq = WM8350_IRQ_UV_LDO4,
1148 .type = REGULATOR_VOLTAGE, 1125 .type = REGULATOR_VOLTAGE,
1149 .n_voltages = WM8350_LDO4_VSEL_MASK + 1, 1126 .n_voltages = WM8350_LDO4_VSEL_MASK + 1,
1127 .linear_ranges = wm8350_ldo_ranges,
1128 .n_linear_ranges = ARRAY_SIZE(wm8350_ldo_ranges),
1150 .vsel_reg = WM8350_LDO4_CONTROL, 1129 .vsel_reg = WM8350_LDO4_CONTROL,
1151 .vsel_mask = WM8350_LDO4_VSEL_MASK, 1130 .vsel_mask = WM8350_LDO4_VSEL_MASK,
1152 .enable_reg = WM8350_DCDC_LDO_REQUESTED, 1131 .enable_reg = WM8350_DCDC_LDO_REQUESTED,
diff --git a/drivers/regulator/wm8400-regulator.c b/drivers/regulator/wm8400-regulator.c
index a09f03ee5506..2ac7e1aceb05 100644
--- a/drivers/regulator/wm8400-regulator.c
+++ b/drivers/regulator/wm8400-regulator.c
@@ -19,47 +19,21 @@
19#include <linux/regulator/driver.h> 19#include <linux/regulator/driver.h>
20#include <linux/mfd/wm8400-private.h> 20#include <linux/mfd/wm8400-private.h>
21 21
22static int wm8400_ldo_list_voltage(struct regulator_dev *dev, 22static const struct regulator_linear_range wm8400_ldo_ranges[] = {
23 unsigned selector) 23 { .min_uV = 900000, .max_uV = 1600000, .min_sel = 0, .max_sel = 14,
24{ 24 .uV_step = 50000 },
25 if (selector > WM8400_LDO1_VSEL_MASK) 25 { .min_uV = 1700000, .max_uV = 3300000, .min_sel = 15, .max_sel = 31,
26 return -EINVAL; 26 .uV_step = 100000 },
27 27};
28 if (selector < 15)
29 return 900000 + (selector * 50000);
30 else
31 return 1700000 + ((selector - 15) * 100000);
32}
33
34static int wm8400_ldo_map_voltage(struct regulator_dev *dev,
35 int min_uV, int max_uV)
36{
37 u16 val;
38 int volt;
39
40 if (min_uV < 900000 || min_uV > 3300000)
41 return -EINVAL;
42
43 if (min_uV < 1700000) /* Steps of 50mV from 900mV; */
44 val = DIV_ROUND_UP(min_uV - 900000, 50000);
45 else /* Steps of 100mV from 1700mV */
46 val = DIV_ROUND_UP(min_uV - 1700000, 100000) + 15;
47
48 volt = wm8400_ldo_list_voltage(dev, val);
49 if (volt < min_uV || volt > max_uV)
50 return -EINVAL;
51
52 return val;
53}
54 28
55static struct regulator_ops wm8400_ldo_ops = { 29static struct regulator_ops wm8400_ldo_ops = {
56 .is_enabled = regulator_is_enabled_regmap, 30 .is_enabled = regulator_is_enabled_regmap,
57 .enable = regulator_enable_regmap, 31 .enable = regulator_enable_regmap,
58 .disable = regulator_disable_regmap, 32 .disable = regulator_disable_regmap,
59 .list_voltage = wm8400_ldo_list_voltage, 33 .list_voltage = regulator_list_voltage_linear_range,
60 .get_voltage_sel = regulator_get_voltage_sel_regmap, 34 .get_voltage_sel = regulator_get_voltage_sel_regmap,
61 .set_voltage_sel = regulator_set_voltage_sel_regmap, 35 .set_voltage_sel = regulator_set_voltage_sel_regmap,
62 .map_voltage = wm8400_ldo_map_voltage, 36 .map_voltage = regulator_map_voltage_linear_range,
63}; 37};
64 38
65static unsigned int wm8400_dcdc_get_mode(struct regulator_dev *dev) 39static unsigned int wm8400_dcdc_get_mode(struct regulator_dev *dev)
@@ -155,6 +129,8 @@ static struct regulator_desc regulators[] = {
155 .enable_reg = WM8400_LDO1_CONTROL, 129 .enable_reg = WM8400_LDO1_CONTROL,
156 .enable_mask = WM8400_LDO1_ENA, 130 .enable_mask = WM8400_LDO1_ENA,
157 .n_voltages = WM8400_LDO1_VSEL_MASK + 1, 131 .n_voltages = WM8400_LDO1_VSEL_MASK + 1,
132 .linear_ranges = wm8400_ldo_ranges,
133 .n_linear_ranges = ARRAY_SIZE(wm8400_ldo_ranges),
158 .vsel_reg = WM8400_LDO1_CONTROL, 134 .vsel_reg = WM8400_LDO1_CONTROL,
159 .vsel_mask = WM8400_LDO1_VSEL_MASK, 135 .vsel_mask = WM8400_LDO1_VSEL_MASK,
160 .type = REGULATOR_VOLTAGE, 136 .type = REGULATOR_VOLTAGE,
@@ -167,6 +143,8 @@ static struct regulator_desc regulators[] = {
167 .enable_reg = WM8400_LDO2_CONTROL, 143 .enable_reg = WM8400_LDO2_CONTROL,
168 .enable_mask = WM8400_LDO2_ENA, 144 .enable_mask = WM8400_LDO2_ENA,
169 .n_voltages = WM8400_LDO2_VSEL_MASK + 1, 145 .n_voltages = WM8400_LDO2_VSEL_MASK + 1,
146 .linear_ranges = wm8400_ldo_ranges,
147 .n_linear_ranges = ARRAY_SIZE(wm8400_ldo_ranges),
170 .type = REGULATOR_VOLTAGE, 148 .type = REGULATOR_VOLTAGE,
171 .vsel_reg = WM8400_LDO2_CONTROL, 149 .vsel_reg = WM8400_LDO2_CONTROL,
172 .vsel_mask = WM8400_LDO2_VSEL_MASK, 150 .vsel_mask = WM8400_LDO2_VSEL_MASK,
@@ -179,6 +157,8 @@ static struct regulator_desc regulators[] = {
179 .enable_reg = WM8400_LDO3_CONTROL, 157 .enable_reg = WM8400_LDO3_CONTROL,
180 .enable_mask = WM8400_LDO3_ENA, 158 .enable_mask = WM8400_LDO3_ENA,
181 .n_voltages = WM8400_LDO3_VSEL_MASK + 1, 159 .n_voltages = WM8400_LDO3_VSEL_MASK + 1,
160 .linear_ranges = wm8400_ldo_ranges,
161 .n_linear_ranges = ARRAY_SIZE(wm8400_ldo_ranges),
182 .vsel_reg = WM8400_LDO3_CONTROL, 162 .vsel_reg = WM8400_LDO3_CONTROL,
183 .vsel_mask = WM8400_LDO3_VSEL_MASK, 163 .vsel_mask = WM8400_LDO3_VSEL_MASK,
184 .type = REGULATOR_VOLTAGE, 164 .type = REGULATOR_VOLTAGE,
@@ -191,6 +171,8 @@ static struct regulator_desc regulators[] = {
191 .enable_reg = WM8400_LDO4_CONTROL, 171 .enable_reg = WM8400_LDO4_CONTROL,
192 .enable_mask = WM8400_LDO4_ENA, 172 .enable_mask = WM8400_LDO4_ENA,
193 .n_voltages = WM8400_LDO4_VSEL_MASK + 1, 173 .n_voltages = WM8400_LDO4_VSEL_MASK + 1,
174 .linear_ranges = wm8400_ldo_ranges,
175 .n_linear_ranges = ARRAY_SIZE(wm8400_ldo_ranges),
194 .vsel_reg = WM8400_LDO4_CONTROL, 176 .vsel_reg = WM8400_LDO4_CONTROL,
195 .vsel_mask = WM8400_LDO4_VSEL_MASK, 177 .vsel_mask = WM8400_LDO4_VSEL_MASK,
196 .type = REGULATOR_VOLTAGE, 178 .type = REGULATOR_VOLTAGE,
diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h
index 6700cc94bdd1..67e13aa5a478 100644
--- a/include/linux/regulator/driver.h
+++ b/include/linux/regulator/driver.h
@@ -40,6 +40,24 @@ enum regulator_status {
40}; 40};
41 41
42/** 42/**
43 * Specify a range of voltages for regulator_map_linar_range() and
44 * regulator_list_linear_range().
45 *
46 * @min_uV: Lowest voltage in range
47 * @max_uV: Highest voltage in range
48 * @min_sel: Lowest selector for range
49 * @max_sel: Highest selector for range
50 * @uV_step: Step size
51 */
52struct regulator_linear_range {
53 unsigned int min_uV;
54 unsigned int max_uV;
55 unsigned int min_sel;
56 unsigned int max_sel;
57 unsigned int uV_step;
58};
59
60/**
43 * struct regulator_ops - regulator operations. 61 * struct regulator_ops - regulator operations.
44 * 62 *
45 * @enable: Configure the regulator as enabled. 63 * @enable: Configure the regulator as enabled.
@@ -223,6 +241,9 @@ struct regulator_desc {
223 unsigned int linear_min_sel; 241 unsigned int linear_min_sel;
224 unsigned int ramp_delay; 242 unsigned int ramp_delay;
225 243
244 const struct regulator_linear_range *linear_ranges;
245 int n_linear_ranges;
246
226 const unsigned int *volt_table; 247 const unsigned int *volt_table;
227 248
228 unsigned int vsel_reg; 249 unsigned int vsel_reg;
@@ -326,10 +347,14 @@ int regulator_mode_to_status(unsigned int);
326 347
327int regulator_list_voltage_linear(struct regulator_dev *rdev, 348int regulator_list_voltage_linear(struct regulator_dev *rdev,
328 unsigned int selector); 349 unsigned int selector);
350int regulator_list_voltage_linear_range(struct regulator_dev *rdev,
351 unsigned int selector);
329int regulator_list_voltage_table(struct regulator_dev *rdev, 352int regulator_list_voltage_table(struct regulator_dev *rdev,
330 unsigned int selector); 353 unsigned int selector);
331int regulator_map_voltage_linear(struct regulator_dev *rdev, 354int regulator_map_voltage_linear(struct regulator_dev *rdev,
332 int min_uV, int max_uV); 355 int min_uV, int max_uV);
356int regulator_map_voltage_linear_range(struct regulator_dev *rdev,
357 int min_uV, int max_uV);
333int regulator_map_voltage_iterate(struct regulator_dev *rdev, 358int regulator_map_voltage_iterate(struct regulator_dev *rdev,
334 int min_uV, int max_uV); 359 int min_uV, int max_uV);
335int regulator_map_voltage_ascend(struct regulator_dev *rdev, 360int regulator_map_voltage_ascend(struct regulator_dev *rdev,