]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/regulator/core.c
Merge tag 'for-3.8' of git://openrisc.net/~jonas/linux
[karo-tx-linux.git] / drivers / regulator / core.c
index e872c8be080ed427a2e546efffee50c12acdd9fe..0f65b246cc0c8d24c559cdeafd340232d1c55e0c 100644 (file)
@@ -199,8 +199,11 @@ static int regulator_check_consumers(struct regulator_dev *rdev,
                        *min_uV = regulator->min_uV;
        }
 
-       if (*min_uV > *max_uV)
+       if (*min_uV > *max_uV) {
+               dev_err(regulator->dev, "Restricting voltage, %u-%uuV\n",
+                       regulator->min_uV, regulator->max_uV);
                return -EINVAL;
+       }
 
        return 0;
 }
@@ -880,7 +883,9 @@ static int machine_constraints_voltage(struct regulator_dev *rdev,
 
                /* final: [min_uV..max_uV] valid iff constraints valid */
                if (max_uV < min_uV) {
-                       rdev_err(rdev, "unsupportable voltage constraints\n");
+                       rdev_err(rdev,
+                                "unsupportable voltage constraints %u-%uuV\n",
+                                min_uV, max_uV);
                        return -EINVAL;
                }
 
@@ -1866,6 +1871,28 @@ int regulator_is_enabled(struct regulator *regulator)
 }
 EXPORT_SYMBOL_GPL(regulator_is_enabled);
 
+/**
+ * regulator_can_change_voltage - check if regulator can change voltage
+ * @regulator: regulator source
+ *
+ * Returns positive if the regulator driver backing the source/client
+ * can change its voltage, false otherwise. Usefull for detecting fixed
+ * or dummy regulators and disabling voltage change logic in the client
+ * driver.
+ */
+int regulator_can_change_voltage(struct regulator *regulator)
+{
+       struct regulator_dev    *rdev = regulator->rdev;
+
+       if (rdev->constraints &&
+           rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE &&
+           (rdev->desc->n_voltages - rdev->desc->linear_min_sel) > 1)
+               return 1;
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(regulator_can_change_voltage);
+
 /**
  * regulator_count_voltages - count regulator_list_voltage() selectors
  * @regulator: regulator source
@@ -1897,6 +1924,10 @@ int regulator_list_voltage_linear(struct regulator_dev *rdev,
 {
        if (selector >= rdev->desc->n_voltages)
                return -EINVAL;
+       if (selector < rdev->desc->linear_min_sel)
+               return 0;
+
+       selector -= rdev->desc->linear_min_sel;
 
        return rdev->desc->min_uV + (rdev->desc->uV_step * selector);
 }
@@ -1985,6 +2016,11 @@ int regulator_is_supported_voltage(struct regulator *regulator,
                        return ret;
        }
 
+       /* Any voltage within constrains range is fine? */
+       if (rdev->desc->continuous_voltage_range)
+               return min_uV >= rdev->constraints->min_uV &&
+                               max_uV <= rdev->constraints->max_uV;
+
        ret = regulator_count_voltages(regulator);
        if (ret < 0)
                return ret;
@@ -2120,6 +2156,8 @@ int regulator_map_voltage_linear(struct regulator_dev *rdev,
        if (ret < 0)
                return ret;
 
+       ret += rdev->desc->linear_min_sel;
+
        /* Map back into a voltage to verify we're still in bounds */
        voltage = rdev->desc->ops->list_voltage(rdev, ret);
        if (voltage < min_uV || voltage > max_uV)