aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/regulator/core.c113
-rw-r--r--include/linux/regulator/consumer.h2
-rw-r--r--include/linux/regulator/driver.h9
3 files changed, 124 insertions, 0 deletions
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 75abcd85e51b..da357a07c98e 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -692,6 +692,69 @@ static int set_machine_constraints(struct regulator_dev *rdev,
692 else 692 else
693 name = "regulator"; 693 name = "regulator";
694 694
695 /* constrain machine-level voltage specs to fit
696 * the actual range supported by this regulator.
697 */
698 if (ops->list_voltage && rdev->desc->n_voltages) {
699 int count = rdev->desc->n_voltages;
700 int i;
701 int min_uV = INT_MAX;
702 int max_uV = INT_MIN;
703 int cmin = constraints->min_uV;
704 int cmax = constraints->max_uV;
705
706 /* it's safe to autoconfigure fixed-voltage supplies */
707 if (count == 1 && !cmin) {
708 cmin = INT_MIN;
709 cmax = INT_MAX;
710 }
711
712 /* else require explicit machine-level constraints */
713 else if (cmin <= 0 || cmax <= 0 || cmax < cmin) {
714 pr_err("%s: %s '%s' voltage constraints\n",
715 __func__, "invalid", name);
716 ret = -EINVAL;
717 goto out;
718 }
719
720 /* initial: [cmin..cmax] valid, [min_uV..max_uV] not */
721 for (i = 0; i < count; i++) {
722 int value;
723
724 value = ops->list_voltage(rdev, i);
725 if (value <= 0)
726 continue;
727
728 /* maybe adjust [min_uV..max_uV] */
729 if (value >= cmin && value < min_uV)
730 min_uV = value;
731 if (value <= cmax && value > max_uV)
732 max_uV = value;
733 }
734
735 /* final: [min_uV..max_uV] valid iff constraints valid */
736 if (max_uV < min_uV) {
737 pr_err("%s: %s '%s' voltage constraints\n",
738 __func__, "unsupportable", name);
739 ret = -EINVAL;
740 goto out;
741 }
742
743 /* use regulator's subset of machine constraints */
744 if (constraints->min_uV < min_uV) {
745 pr_debug("%s: override '%s' %s, %d -> %d\n",
746 __func__, name, "min_uV",
747 constraints->min_uV, min_uV);
748 constraints->min_uV = min_uV;
749 }
750 if (constraints->max_uV > max_uV) {
751 pr_debug("%s: override '%s' %s, %d -> %d\n",
752 __func__, name, "max_uV",
753 constraints->max_uV, max_uV);
754 constraints->max_uV = max_uV;
755 }
756 }
757
695 rdev->constraints = constraints; 758 rdev->constraints = constraints;
696 759
697 /* do we need to apply the constraint voltage */ 760 /* do we need to apply the constraint voltage */
@@ -1251,6 +1314,56 @@ int regulator_is_enabled(struct regulator *regulator)
1251EXPORT_SYMBOL_GPL(regulator_is_enabled); 1314EXPORT_SYMBOL_GPL(regulator_is_enabled);
1252 1315
1253/** 1316/**
1317 * regulator_count_voltages - count regulator_list_voltage() selectors
1318 * @regulator: regulator source
1319 *
1320 * Returns number of selectors, or negative errno. Selectors are
1321 * numbered starting at zero, and typically correspond to bitfields
1322 * in hardware registers.
1323 */
1324int regulator_count_voltages(struct regulator *regulator)
1325{
1326 struct regulator_dev *rdev = regulator->rdev;
1327
1328 return rdev->desc->n_voltages ? : -EINVAL;
1329}
1330EXPORT_SYMBOL_GPL(regulator_count_voltages);
1331
1332/**
1333 * regulator_list_voltage - enumerate supported voltages
1334 * @regulator: regulator source
1335 * @selector: identify voltage to list
1336 * Context: can sleep
1337 *
1338 * Returns a voltage that can be passed to @regulator_set_voltage(),
1339 * zero if this selector code can't be used on this sytem, or a
1340 * negative errno.
1341 */
1342int regulator_list_voltage(struct regulator *regulator, unsigned selector)
1343{
1344 struct regulator_dev *rdev = regulator->rdev;
1345 struct regulator_ops *ops = rdev->desc->ops;
1346 int ret;
1347
1348 if (!ops->list_voltage || selector >= rdev->desc->n_voltages)
1349 return -EINVAL;
1350
1351 mutex_lock(&rdev->mutex);
1352 ret = ops->list_voltage(rdev, selector);
1353 mutex_unlock(&rdev->mutex);
1354
1355 if (ret > 0) {
1356 if (ret < rdev->constraints->min_uV)
1357 ret = 0;
1358 else if (ret > rdev->constraints->max_uV)
1359 ret = 0;
1360 }
1361
1362 return ret;
1363}
1364EXPORT_SYMBOL_GPL(regulator_list_voltage);
1365
1366/**
1254 * regulator_set_voltage - set regulator output voltage 1367 * regulator_set_voltage - set regulator output voltage
1255 * @regulator: regulator source 1368 * @regulator: regulator source
1256 * @min_uV: Minimum required voltage in uV 1369 * @min_uV: Minimum required voltage in uV
diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h
index df6c4bcf38f8..277f4b964df5 100644
--- a/include/linux/regulator/consumer.h
+++ b/include/linux/regulator/consumer.h
@@ -142,6 +142,8 @@ int regulator_bulk_disable(int num_consumers,
142void regulator_bulk_free(int num_consumers, 142void regulator_bulk_free(int num_consumers,
143 struct regulator_bulk_data *consumers); 143 struct regulator_bulk_data *consumers);
144 144
145int regulator_count_voltages(struct regulator *regulator);
146int regulator_list_voltage(struct regulator *regulator, unsigned selector);
145int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV); 147int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV);
146int regulator_get_voltage(struct regulator *regulator); 148int regulator_get_voltage(struct regulator *regulator);
147int regulator_set_current_limit(struct regulator *regulator, 149int regulator_set_current_limit(struct regulator *regulator,
diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h
index 0cf37bc85c41..2255468d456f 100644
--- a/include/linux/regulator/driver.h
+++ b/include/linux/regulator/driver.h
@@ -45,6 +45,10 @@ enum regulator_status {
45 * @set_voltage: Set the voltage for the regulator within the range specified. 45 * @set_voltage: Set the voltage for the regulator within the range specified.
46 * The driver should select the voltage closest to min_uV. 46 * The driver should select the voltage closest to min_uV.
47 * @get_voltage: Return the currently configured voltage for the regulator. 47 * @get_voltage: Return the currently configured voltage for the regulator.
48 * @list_voltage: Return one of the supported voltages, in microvolts; zero
49 * if the selector indicates a voltage that is unusable on this system;
50 * or negative errno. Selectors range from zero to one less than
51 * regulator_desc.n_voltages. Voltages may be reported in any order.
48 * 52 *
49 * @set_current_limit: Configure a limit for a current-limited regulator. 53 * @set_current_limit: Configure a limit for a current-limited regulator.
50 * @get_current_limit: Get the limit for a current-limited regulator. 54 * @get_current_limit: Get the limit for a current-limited regulator.
@@ -66,6 +70,9 @@ enum regulator_status {
66 */ 70 */
67struct regulator_ops { 71struct regulator_ops {
68 72
73 /* enumerate supported voltages */
74 int (*list_voltage) (struct regulator_dev *, unsigned selector);
75
69 /* get/set regulator voltage */ 76 /* get/set regulator voltage */
70 int (*set_voltage) (struct regulator_dev *, int min_uV, int max_uV); 77 int (*set_voltage) (struct regulator_dev *, int min_uV, int max_uV);
71 int (*get_voltage) (struct regulator_dev *); 78 int (*get_voltage) (struct regulator_dev *);
@@ -124,6 +131,7 @@ enum regulator_type {
124 * 131 *
125 * @name: Identifying name for the regulator. 132 * @name: Identifying name for the regulator.
126 * @id: Numerical identifier for the regulator. 133 * @id: Numerical identifier for the regulator.
134 * @n_voltages: Number of selectors available for ops.list_voltage().
127 * @ops: Regulator operations table. 135 * @ops: Regulator operations table.
128 * @irq: Interrupt number for the regulator. 136 * @irq: Interrupt number for the regulator.
129 * @type: Indicates if the regulator is a voltage or current regulator. 137 * @type: Indicates if the regulator is a voltage or current regulator.
@@ -132,6 +140,7 @@ enum regulator_type {
132struct regulator_desc { 140struct regulator_desc {
133 const char *name; 141 const char *name;
134 int id; 142 int id;
143 unsigned n_voltages;
135 struct regulator_ops *ops; 144 struct regulator_ops *ops;
136 int irq; 145 int irq;
137 enum regulator_type type; 146 enum regulator_type type;