regulator: core: Add set/get_current_limit helpers for regmap users
By setting curr_table, n_current_limits, csel_reg and csel_mask, the regmap users can use regulator_set_current_limit_regmap and regulator_get_current_limit_regmap for set/get_current_limit callbacks. Signed-off-by: Axel Lin <axel.lin@ingics.com> Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
35d838ff98
commit
a32e0c773b
|
@ -780,3 +780,89 @@ int regulator_set_active_discharge_regmap(struct regulator_dev *rdev,
|
||||||
rdev->desc->active_discharge_mask, val);
|
rdev->desc->active_discharge_mask, val);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(regulator_set_active_discharge_regmap);
|
EXPORT_SYMBOL_GPL(regulator_set_active_discharge_regmap);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* regulator_set_current_limit_regmap - set_current_limit for regmap users
|
||||||
|
*
|
||||||
|
* @rdev: regulator to operate on
|
||||||
|
* @min_uA: Lower bound for current limit
|
||||||
|
* @max_uA: Upper bound for current limit
|
||||||
|
*
|
||||||
|
* Regulators that use regmap for their register I/O can set curr_table,
|
||||||
|
* csel_reg and csel_mask fields in their descriptor and then use this
|
||||||
|
* as their set_current_limit operation, saving some code.
|
||||||
|
*/
|
||||||
|
int regulator_set_current_limit_regmap(struct regulator_dev *rdev,
|
||||||
|
int min_uA, int max_uA)
|
||||||
|
{
|
||||||
|
unsigned int n_currents = rdev->desc->n_current_limits;
|
||||||
|
int i, sel = -1;
|
||||||
|
|
||||||
|
if (n_currents == 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (rdev->desc->curr_table) {
|
||||||
|
const unsigned int *curr_table = rdev->desc->curr_table;
|
||||||
|
bool ascend = curr_table[n_currents - 1] > curr_table[0];
|
||||||
|
|
||||||
|
/* search for closest to maximum */
|
||||||
|
if (ascend) {
|
||||||
|
for (i = n_currents - 1; i >= 0; i--) {
|
||||||
|
if (min_uA <= curr_table[i] &&
|
||||||
|
curr_table[i] <= max_uA) {
|
||||||
|
sel = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (i = 0; i < n_currents; i++) {
|
||||||
|
if (min_uA <= curr_table[i] &&
|
||||||
|
curr_table[i] <= max_uA) {
|
||||||
|
sel = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sel < 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
sel <<= ffs(rdev->desc->csel_mask) - 1;
|
||||||
|
|
||||||
|
return regmap_update_bits(rdev->regmap, rdev->desc->csel_reg,
|
||||||
|
rdev->desc->csel_mask, sel);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(regulator_set_current_limit_regmap);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* regulator_get_current_limit_regmap - get_current_limit for regmap users
|
||||||
|
*
|
||||||
|
* @rdev: regulator to operate on
|
||||||
|
*
|
||||||
|
* Regulators that use regmap for their register I/O can set the
|
||||||
|
* csel_reg and csel_mask fields in their descriptor and then use this
|
||||||
|
* as their get_current_limit operation, saving some code.
|
||||||
|
*/
|
||||||
|
int regulator_get_current_limit_regmap(struct regulator_dev *rdev)
|
||||||
|
{
|
||||||
|
unsigned int val;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = regmap_read(rdev->regmap, rdev->desc->csel_reg, &val);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
val &= rdev->desc->csel_mask;
|
||||||
|
val >>= ffs(rdev->desc->csel_mask) - 1;
|
||||||
|
|
||||||
|
if (rdev->desc->curr_table) {
|
||||||
|
if (val >= rdev->desc->n_current_limits)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
return rdev->desc->curr_table[val];
|
||||||
|
}
|
||||||
|
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(regulator_get_current_limit_regmap);
|
||||||
|
|
|
@ -264,6 +264,7 @@ enum regulator_type {
|
||||||
* @continuous_voltage_range: Indicates if the regulator can set any
|
* @continuous_voltage_range: Indicates if the regulator can set any
|
||||||
* voltage within constrains range.
|
* voltage within constrains range.
|
||||||
* @n_voltages: Number of selectors available for ops.list_voltage().
|
* @n_voltages: Number of selectors available for ops.list_voltage().
|
||||||
|
* @n_current_limits: Number of selectors available for current limits
|
||||||
*
|
*
|
||||||
* @min_uV: Voltage given by the lowest selector (if linear mapping)
|
* @min_uV: Voltage given by the lowest selector (if linear mapping)
|
||||||
* @uV_step: Voltage increase with each selector (if linear mapping)
|
* @uV_step: Voltage increase with each selector (if linear mapping)
|
||||||
|
@ -278,6 +279,7 @@ enum regulator_type {
|
||||||
* @n_linear_ranges: Number of entries in the @linear_ranges (and in
|
* @n_linear_ranges: Number of entries in the @linear_ranges (and in
|
||||||
* linear_range_selectors if used) table(s).
|
* linear_range_selectors if used) table(s).
|
||||||
* @volt_table: Voltage mapping table (if table based mapping)
|
* @volt_table: Voltage mapping table (if table based mapping)
|
||||||
|
* @curr_table: Current limit mapping table (if table based mapping)
|
||||||
*
|
*
|
||||||
* @vsel_range_reg: Register for range selector when using pickable ranges
|
* @vsel_range_reg: Register for range selector when using pickable ranges
|
||||||
* and regulator_regmap_X_voltage_X_pickable functions.
|
* and regulator_regmap_X_voltage_X_pickable functions.
|
||||||
|
@ -333,6 +335,7 @@ struct regulator_desc {
|
||||||
int id;
|
int id;
|
||||||
unsigned int continuous_voltage_range:1;
|
unsigned int continuous_voltage_range:1;
|
||||||
unsigned n_voltages;
|
unsigned n_voltages;
|
||||||
|
unsigned int n_current_limits;
|
||||||
const struct regulator_ops *ops;
|
const struct regulator_ops *ops;
|
||||||
int irq;
|
int irq;
|
||||||
enum regulator_type type;
|
enum regulator_type type;
|
||||||
|
@ -351,6 +354,7 @@ struct regulator_desc {
|
||||||
int n_linear_ranges;
|
int n_linear_ranges;
|
||||||
|
|
||||||
const unsigned int *volt_table;
|
const unsigned int *volt_table;
|
||||||
|
const unsigned int *curr_table;
|
||||||
|
|
||||||
unsigned int vsel_range_reg;
|
unsigned int vsel_range_reg;
|
||||||
unsigned int vsel_range_mask;
|
unsigned int vsel_range_mask;
|
||||||
|
@ -534,6 +538,9 @@ int regulator_set_pull_down_regmap(struct regulator_dev *rdev);
|
||||||
|
|
||||||
int regulator_set_active_discharge_regmap(struct regulator_dev *rdev,
|
int regulator_set_active_discharge_regmap(struct regulator_dev *rdev,
|
||||||
bool enable);
|
bool enable);
|
||||||
|
int regulator_set_current_limit_regmap(struct regulator_dev *rdev,
|
||||||
|
int min_uA, int max_uA);
|
||||||
|
int regulator_get_current_limit_regmap(struct regulator_dev *rdev);
|
||||||
void *regulator_get_init_drvdata(struct regulator_init_data *reg_init_data);
|
void *regulator_get_init_drvdata(struct regulator_init_data *reg_init_data);
|
||||||
|
|
||||||
void regulator_lock(struct regulator_dev *rdev);
|
void regulator_lock(struct regulator_dev *rdev);
|
||||||
|
|
Loading…
Reference in New Issue