diff options
-rw-r--r-- | drivers/regulator/core.c | 113 | ||||
-rw-r--r-- | include/linux/regulator/consumer.h | 2 | ||||
-rw-r--r-- | include/linux/regulator/driver.h | 9 |
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) | |||
1251 | EXPORT_SYMBOL_GPL(regulator_is_enabled); | 1314 | EXPORT_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 | */ | ||
1324 | int regulator_count_voltages(struct regulator *regulator) | ||
1325 | { | ||
1326 | struct regulator_dev *rdev = regulator->rdev; | ||
1327 | |||
1328 | return rdev->desc->n_voltages ? : -EINVAL; | ||
1329 | } | ||
1330 | EXPORT_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 | */ | ||
1342 | int 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 | } | ||
1364 | EXPORT_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, | |||
142 | void regulator_bulk_free(int num_consumers, | 142 | void regulator_bulk_free(int num_consumers, |
143 | struct regulator_bulk_data *consumers); | 143 | struct regulator_bulk_data *consumers); |
144 | 144 | ||
145 | int regulator_count_voltages(struct regulator *regulator); | ||
146 | int regulator_list_voltage(struct regulator *regulator, unsigned selector); | ||
145 | int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV); | 147 | int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV); |
146 | int regulator_get_voltage(struct regulator *regulator); | 148 | int regulator_get_voltage(struct regulator *regulator); |
147 | int regulator_set_current_limit(struct regulator *regulator, | 149 | int 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 | */ |
67 | struct regulator_ops { | 71 | struct 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 { | |||
132 | struct regulator_desc { | 140 | struct 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; |