From cd5759db61c9d0d2b2f2b340fc2fc91667cd4763 Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Fri, 27 Apr 2012 00:19:43 +0530 Subject: regulator: add sysfs for rail enable/disable Added support for enable/disable rails from user space. bug 966960 Change-Id: Iae660699c60f537296f90508a78bd40959c46535 Signed-off-by: Laxman Dewangan Reviewed-on: http://git-master/r/99186 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Hunk Lin Tested-by: Hunk Lin GVS: Gerrit_Virtual_Submit --- drivers/regulator/core.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 1b7d64118e4d..cbe36b93639b 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -91,6 +91,8 @@ struct regulator { static int _regulator_is_enabled(struct regulator_dev *rdev); static int _regulator_disable(struct regulator_dev *rdev); +static int _regulator_enable(struct regulator_dev *rdev); +static int _regulator_get_enable_time(struct regulator_dev *rdev); static int _regulator_get_voltage(struct regulator_dev *rdev); static int _regulator_get_current_limit(struct regulator_dev *rdev); static unsigned int _regulator_get_mode(struct regulator_dev *rdev); @@ -358,7 +360,65 @@ static ssize_t regulator_state_show(struct device *dev, return ret; } -static DEVICE_ATTR(state, 0444, regulator_state_show, NULL); + +static ssize_t regulator_state_set(struct device *dev, + struct device_attribute *attr, const char *buf, size_t count) +{ + struct regulator_dev *rdev = dev_get_drvdata(dev); + int ret; + bool enabled; + + if ((*buf == 'E') || (*buf == 'e')) + enabled = true; + else if ((*buf == 'D') || (*buf == 'd')) + enabled = false; + else + return -EINVAL; + + if ((_regulator_is_enabled(rdev) && enabled) || + (!_regulator_is_enabled(rdev) && !enabled)) + return count; + + mutex_lock(&rdev->mutex); + if (enabled) { + int delay = 0; + if (!rdev->desc->ops->enable) { + ret = -EINVAL; + goto end; + } + ret = _regulator_get_enable_time(rdev); + if (ret >= 0) + delay = ret; + ret = rdev->desc->ops->enable(rdev); + if (ret < 0) { + rdev_warn(rdev, "enable() failed: %d\n", ret); + goto end; + } + if (delay >= 1000) { + mdelay(delay / 1000); + udelay(delay % 1000); + } else if (delay) { + udelay(delay); + } + } else { + if (!rdev->desc->ops->disable) { + ret = -EINVAL; + goto end; + } + ret = rdev->desc->ops->disable(rdev); + if (ret < 0) { + rdev_warn(rdev, "disable() failed: %d\n", ret); + goto end; + } + } + +end: + mutex_unlock(&rdev->mutex); + if (ret < 0) + return ret; + return count; +} +static DEVICE_ATTR(state, 0644, regulator_state_show, regulator_state_set); static ssize_t regulator_status_show(struct device *dev, struct device_attribute *attr, char *buf) -- cgit v1.2.3