Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 140253
b: refs/heads/master
c: 4367cfd
h: refs/heads/master
i:
  140251: 0bf902d
v: v3
  • Loading branch information
David Brownell authored and Liam Girdwood committed Mar 31, 2009
1 parent 2da82c9 commit 56b2bf2
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 33f301af0c56971e3c0f4a4eb4b92f7e80230f49
refs/heads/master: 4367cfdc7c657ad8a797f51b9ffd3c64b31910e7
113 changes: 113 additions & 0 deletions trunk/drivers/regulator/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -692,6 +692,69 @@ static int set_machine_constraints(struct regulator_dev *rdev,
else
name = "regulator";

/* constrain machine-level voltage specs to fit
* the actual range supported by this regulator.
*/
if (ops->list_voltage && rdev->desc->n_voltages) {
int count = rdev->desc->n_voltages;
int i;
int min_uV = INT_MAX;
int max_uV = INT_MIN;
int cmin = constraints->min_uV;
int cmax = constraints->max_uV;

/* it's safe to autoconfigure fixed-voltage supplies */
if (count == 1 && !cmin) {
cmin = INT_MIN;
cmax = INT_MAX;
}

/* else require explicit machine-level constraints */
else if (cmin <= 0 || cmax <= 0 || cmax < cmin) {
pr_err("%s: %s '%s' voltage constraints\n",
__func__, "invalid", name);
ret = -EINVAL;
goto out;
}

/* initial: [cmin..cmax] valid, [min_uV..max_uV] not */
for (i = 0; i < count; i++) {
int value;

value = ops->list_voltage(rdev, i);
if (value <= 0)
continue;

/* maybe adjust [min_uV..max_uV] */
if (value >= cmin && value < min_uV)
min_uV = value;
if (value <= cmax && value > max_uV)
max_uV = value;
}

/* final: [min_uV..max_uV] valid iff constraints valid */
if (max_uV < min_uV) {
pr_err("%s: %s '%s' voltage constraints\n",
__func__, "unsupportable", name);
ret = -EINVAL;
goto out;
}

/* use regulator's subset of machine constraints */
if (constraints->min_uV < min_uV) {
pr_debug("%s: override '%s' %s, %d -> %d\n",
__func__, name, "min_uV",
constraints->min_uV, min_uV);
constraints->min_uV = min_uV;
}
if (constraints->max_uV > max_uV) {
pr_debug("%s: override '%s' %s, %d -> %d\n",
__func__, name, "max_uV",
constraints->max_uV, max_uV);
constraints->max_uV = max_uV;
}
}

rdev->constraints = constraints;

/* do we need to apply the constraint voltage */
Expand Down Expand Up @@ -1250,6 +1313,56 @@ int regulator_is_enabled(struct regulator *regulator)
}
EXPORT_SYMBOL_GPL(regulator_is_enabled);

/**
* regulator_count_voltages - count regulator_list_voltage() selectors
* @regulator: regulator source
*
* Returns number of selectors, or negative errno. Selectors are
* numbered starting at zero, and typically correspond to bitfields
* in hardware registers.
*/
int regulator_count_voltages(struct regulator *regulator)
{
struct regulator_dev *rdev = regulator->rdev;

return rdev->desc->n_voltages ? : -EINVAL;
}
EXPORT_SYMBOL_GPL(regulator_count_voltages);

/**
* regulator_list_voltage - enumerate supported voltages
* @regulator: regulator source
* @selector: identify voltage to list
* Context: can sleep
*
* Returns a voltage that can be passed to @regulator_set_voltage(),
* zero if this selector code can't be used on this sytem, or a
* negative errno.
*/
int regulator_list_voltage(struct regulator *regulator, unsigned selector)
{
struct regulator_dev *rdev = regulator->rdev;
struct regulator_ops *ops = rdev->desc->ops;
int ret;

if (!ops->list_voltage || selector >= rdev->desc->n_voltages)
return -EINVAL;

mutex_lock(&rdev->mutex);
ret = ops->list_voltage(rdev, selector);
mutex_unlock(&rdev->mutex);

if (ret > 0) {
if (ret < rdev->constraints->min_uV)
ret = 0;
else if (ret > rdev->constraints->max_uV)
ret = 0;
}

return ret;
}
EXPORT_SYMBOL_GPL(regulator_list_voltage);

/**
* regulator_set_voltage - set regulator output voltage
* @regulator: regulator source
Expand Down
2 changes: 2 additions & 0 deletions trunk/include/linux/regulator/consumer.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@ int regulator_bulk_disable(int num_consumers,
void regulator_bulk_free(int num_consumers,
struct regulator_bulk_data *consumers);

int regulator_count_voltages(struct regulator *regulator);
int regulator_list_voltage(struct regulator *regulator, unsigned selector);
int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV);
int regulator_get_voltage(struct regulator *regulator);
int regulator_set_current_limit(struct regulator *regulator,
Expand Down
9 changes: 9 additions & 0 deletions trunk/include/linux/regulator/driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ enum regulator_status {
* @set_voltage: Set the voltage for the regulator within the range specified.
* The driver should select the voltage closest to min_uV.
* @get_voltage: Return the currently configured voltage for the regulator.
* @list_voltage: Return one of the supported voltages, in microvolts; zero
* if the selector indicates a voltage that is unusable on this system;
* or negative errno. Selectors range from zero to one less than
* regulator_desc.n_voltages. Voltages may be reported in any order.
*
* @set_current_limit: Configure a limit for a current-limited regulator.
* @get_current_limit: Get the limit for a current-limited regulator.
Expand All @@ -66,6 +70,9 @@ enum regulator_status {
*/
struct regulator_ops {

/* enumerate supported voltages */
int (*list_voltage) (struct regulator_dev *, unsigned selector);

/* get/set regulator voltage */
int (*set_voltage) (struct regulator_dev *, int min_uV, int max_uV);
int (*get_voltage) (struct regulator_dev *);
Expand Down Expand Up @@ -124,6 +131,7 @@ enum regulator_type {
*
* @name: Identifying name for the regulator.
* @id: Numerical identifier for the regulator.
* @n_voltages: Number of selectors available for ops.list_voltage().
* @ops: Regulator operations table.
* @irq: Interrupt number for the regulator.
* @type: Indicates if the regulator is a voltage or current regulator.
Expand All @@ -132,6 +140,7 @@ enum regulator_type {
struct regulator_desc {
const char *name;
int id;
unsigned n_voltages;
struct regulator_ops *ops;
int irq;
enum regulator_type type;
Expand Down

0 comments on commit 56b2bf2

Please sign in to comment.