summaryrefslogtreecommitdiff
path: root/drivers/regulator
diff options
context:
space:
mode:
authorHeiko Stübner <heiko@sntech.de>2012-08-08 02:50:19 +0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2012-08-08 15:16:06 +0400
commiteb0c5686b3c6332892b3eb5d8bb9eb04f943cb25 (patch)
tree982bd81ae8d81791df1ebddb38b441e1d2473c65 /drivers/regulator
parentcfa9cfbc083c7fc882286dcfba59c7e5a1a15545 (diff)
downloadlinux-eb0c5686b3c6332892b3eb5d8bb9eb04f943cb25.tar.xz
regulator: gpio-regulator: Split setting of voltages and currents
Originally gpio-regulator used the first item of its state list that matched the given voltage or current range. Commit 4dbd8f63f0 (regulator: gpio-regulator: Set the smallest voltage/current in the specified range) changed this, to make the selection independent of the ordering of the state list. But selecting the minimal value is only true for voltage regulators. For current regulators the maximum in the given range should be selected instead. Therefore split the previous common selection function into specific functions for voltage and current regulators. Signed-off-by: Heiko Stuebner <heiko@sntech.de> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'drivers/regulator')
-rw-r--r--drivers/regulator/gpio-regulator.c38
1 files changed, 26 insertions, 12 deletions
diff --git a/drivers/regulator/gpio-regulator.c b/drivers/regulator/gpio-regulator.c
index 34b67bee9323..8b5944f2d7d1 100644
--- a/drivers/regulator/gpio-regulator.c
+++ b/drivers/regulator/gpio-regulator.c
@@ -57,16 +57,17 @@ static int gpio_regulator_get_value(struct regulator_dev *dev)
return -EINVAL;
}
-static int gpio_regulator_set_value(struct regulator_dev *dev,
- int min, int max, unsigned *selector)
+static int gpio_regulator_set_voltage(struct regulator_dev *dev,
+ int min_uV, int max_uV,
+ unsigned *selector)
{
struct gpio_regulator_data *data = rdev_get_drvdata(dev);
int ptr, target = 0, state, best_val = INT_MAX;
for (ptr = 0; ptr < data->nr_states; ptr++)
if (data->states[ptr].value < best_val &&
- data->states[ptr].value >= min &&
- data->states[ptr].value <= max) {
+ data->states[ptr].value >= min_uV &&
+ data->states[ptr].value <= max_uV) {
target = data->states[ptr].gpios;
best_val = data->states[ptr].value;
if (selector)
@@ -85,13 +86,6 @@ static int gpio_regulator_set_value(struct regulator_dev *dev,
return 0;
}
-static int gpio_regulator_set_voltage(struct regulator_dev *dev,
- int min_uV, int max_uV,
- unsigned *selector)
-{
- return gpio_regulator_set_value(dev, min_uV, max_uV, selector);
-}
-
static int gpio_regulator_list_voltage(struct regulator_dev *dev,
unsigned selector)
{
@@ -106,7 +100,27 @@ static int gpio_regulator_list_voltage(struct regulator_dev *dev,
static int gpio_regulator_set_current_limit(struct regulator_dev *dev,
int min_uA, int max_uA)
{
- return gpio_regulator_set_value(dev, min_uA, max_uA, NULL);
+ struct gpio_regulator_data *data = rdev_get_drvdata(dev);
+ int ptr, target = 0, state, best_val = 0;
+
+ for (ptr = 0; ptr < data->nr_states; ptr++)
+ if (data->states[ptr].value > best_val &&
+ data->states[ptr].value >= min_uA &&
+ data->states[ptr].value <= max_uA) {
+ target = data->states[ptr].gpios;
+ best_val = data->states[ptr].value;
+ }
+
+ if (best_val == 0)
+ return -EINVAL;
+
+ for (ptr = 0; ptr < data->nr_gpios; ptr++) {
+ state = (target & (1 << ptr)) >> ptr;
+ gpio_set_value(data->gpios[ptr].gpio, state);
+ }
+ data->state = target;
+
+ return 0;
}
static struct regulator_ops gpio_regulator_voltage_ops = {