summaryrefslogtreecommitdiff
path: root/drivers/regulator/core.c
diff options
context:
space:
mode:
authorLaxman Dewangan <ldewangan@nvidia.com>2012-08-17 16:37:47 +0530
committerDan Willemsen <dwillemsen@nvidia.com>2013-09-14 01:09:41 -0700
commitaaaf89699f3f06d5d81d07f83dc654b02a9707a3 (patch)
treeb78d08b4fd92657ca1702995cb455a79182981b4 /drivers/regulator/core.c
parent9be521d5f5b68f5f67b06a9146a1c01db57a8afd (diff)
regulator: core: support for voltage change from user-space
It is required for changing voltage of some of rails from user space to perform characterization of chip. Support the API to have achieve this from user space. bug 1033482 Change-Id: Ic5d2c2eda9a4521968577aed38e1fd492b2bb2c3 Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com> Reviewed-on: http://git-master/r/124352 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> Rebase-Id: R5c5c3551ea971a5665d7373f6921c3438353ca6d
Diffstat (limited to 'drivers/regulator/core.c')
-rw-r--r--drivers/regulator/core.c46
1 files changed, 45 insertions, 1 deletions
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index f2e9383b7e77..dd435904ff35 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -305,6 +305,50 @@ static int regulator_check_drms(struct regulator_dev *rdev)
return 0;
}
+static ssize_t regulator_uV_set(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct regulator_dev *rdev = dev_get_drvdata(dev);
+ int ret;
+ int min_uV;
+ int max_uV = rdev->constraints->max_uV;
+ char *p = (char *)buf;
+
+ min_uV = memparse(p, &p);
+ mutex_lock(&rdev->mutex);
+
+ /* sanity check */
+ if (!rdev->desc->ops->set_voltage &&
+ !rdev->desc->ops->set_voltage_sel) {
+ rdev_err(rdev, "The operation is not supported\n");
+ goto out;
+ }
+
+ /* constraints check */
+ ret = regulator_check_voltage(rdev, &min_uV, &max_uV);
+ if (ret < 0) {
+ rdev_err(rdev, "Voltage is out of range min:max= %d:%d\n",
+ rdev->constraints->min_uV, rdev->constraints->max_uV);
+ goto out;
+ }
+
+ /* Consumer check */
+ ret = regulator_check_consumers(rdev, &min_uV, &max_uV);
+ if (ret < 0) {
+ rdev_warn(rdev, "new voltage is out-range for some consumer\n");
+ rdev_warn(rdev, "min: max = %d:%d\n", min_uV, max_uV);
+ }
+
+ rdev_info(rdev, "Setting voltage min:max = %d:%d\n", min_uV, max_uV);
+ ret = _regulator_do_set_voltage(rdev, min_uV, max_uV);
+ if (ret < 0)
+ rdev_warn(rdev, "Can not set voltage %d:%d\n", min_uV, max_uV);
+
+out:
+ mutex_unlock(&rdev->mutex);
+ return count;
+}
+
static ssize_t regulator_uV_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -317,7 +361,7 @@ static ssize_t regulator_uV_show(struct device *dev,
return ret;
}
-static DEVICE_ATTR(microvolts, 0444, regulator_uV_show, NULL);
+static DEVICE_ATTR(microvolts, 0666, regulator_uV_show, regulator_uV_set);
static ssize_t regulator_uA_show(struct device *dev,
struct device_attribute *attr, char *buf)