aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/regulator/core.c37
1 files changed, 35 insertions, 2 deletions
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 23c5f7c80bff..a0579f069002 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -1637,6 +1637,32 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev,
1637 selector); 1637 selector);
1638 else 1638 else
1639 selector = -1; 1639 selector = -1;
1640 } else if (rdev->desc->ops->set_voltage_sel) {
1641 int best_val = INT_MAX;
1642 int i;
1643
1644 selector = 0;
1645
1646 /* Find the smallest voltage that falls within the specified
1647 * range.
1648 */
1649 for (i = 0; i < rdev->desc->n_voltages; i++) {
1650 ret = rdev->desc->ops->list_voltage(rdev, i);
1651 if (ret < 0)
1652 continue;
1653
1654 if (ret < best_val && ret >= min_uV && ret <= max_uV) {
1655 best_val = ret;
1656 selector = i;
1657 }
1658 }
1659
1660 if (best_val != INT_MAX) {
1661 ret = rdev->desc->ops->set_voltage_sel(rdev, selector);
1662 selector = best_val;
1663 } else {
1664 ret = -EINVAL;
1665 }
1640 } else { 1666 } else {
1641 ret = -EINVAL; 1667 ret = -EINVAL;
1642 } 1668 }
@@ -1672,7 +1698,8 @@ int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV)
1672 mutex_lock(&rdev->mutex); 1698 mutex_lock(&rdev->mutex);
1673 1699
1674 /* sanity check */ 1700 /* sanity check */
1675 if (!rdev->desc->ops->set_voltage) { 1701 if (!rdev->desc->ops->set_voltage &&
1702 !rdev->desc->ops->set_voltage_sel) {
1676 ret = -EINVAL; 1703 ret = -EINVAL;
1677 goto out; 1704 goto out;
1678 } 1705 }
@@ -2256,7 +2283,7 @@ static int add_regulator_attributes(struct regulator_dev *rdev)
2256 return status; 2283 return status;
2257 2284
2258 /* constraints need specific supporting methods */ 2285 /* constraints need specific supporting methods */
2259 if (ops->set_voltage) { 2286 if (ops->set_voltage || ops->set_voltage_sel) {
2260 status = device_create_file(dev, &dev_attr_min_microvolts); 2287 status = device_create_file(dev, &dev_attr_min_microvolts);
2261 if (status < 0) 2288 if (status < 0)
2262 return status; 2289 return status;
@@ -2354,12 +2381,18 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
2354 /* Only one of each should be implemented */ 2381 /* Only one of each should be implemented */
2355 WARN_ON(regulator_desc->ops->get_voltage && 2382 WARN_ON(regulator_desc->ops->get_voltage &&
2356 regulator_desc->ops->get_voltage_sel); 2383 regulator_desc->ops->get_voltage_sel);
2384 WARN_ON(regulator_desc->ops->set_voltage &&
2385 regulator_desc->ops->set_voltage_sel);
2357 2386
2358 /* If we're using selectors we must implement list_voltage. */ 2387 /* If we're using selectors we must implement list_voltage. */
2359 if (regulator_desc->ops->get_voltage_sel && 2388 if (regulator_desc->ops->get_voltage_sel &&
2360 !regulator_desc->ops->list_voltage) { 2389 !regulator_desc->ops->list_voltage) {
2361 return ERR_PTR(-EINVAL); 2390 return ERR_PTR(-EINVAL);
2362 } 2391 }
2392 if (regulator_desc->ops->set_voltage_sel &&
2393 !regulator_desc->ops->list_voltage) {
2394 return ERR_PTR(-EINVAL);
2395 }
2363 2396
2364 rdev = kzalloc(sizeof(struct regulator_dev), GFP_KERNEL); 2397 rdev = kzalloc(sizeof(struct regulator_dev), GFP_KERNEL);
2365 if (rdev == NULL) 2398 if (rdev == NULL)