regulator: core: support for voltage change from user-space
[linux-2.6.git] / drivers / regulator / core.c
index dd4e44b..48bd838 100644 (file)
@@ -307,6 +307,50 @@ static ssize_t device_requested_uA_show(struct device *dev,
        return sprintf(buf, "%d\n", regulator->uA_load);
 }
 
+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)
 {
@@ -319,7 +363,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)
@@ -3001,7 +3045,6 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
                struct regulator_dev *r;
 
                r = regulator_dev_lookup(dev, supply);
-
                if (!r) {
                        dev_err(dev, "Failed to find supply %s\n", supply);
                        ret = -EPROBE_DEFER;