diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index bca1e5989243..02d2e15b2262 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1838,6 +1838,50 @@ int regulator_is_supported_voltage(struct regulator *regulator, } EXPORT_SYMBOL_GPL(regulator_is_supported_voltage); +/** + * regulator_get_voltage_sel_regmap - standard get_voltage_sel for regmap users + * + * @rdev: regulator to operate on + * + * Regulators that use regmap for their register I/O can set the + * vsel_reg and vsel_mask fields in their descriptor and then use this + * as their get_voltage_vsel operation, saving some code. + */ +int regulator_get_voltage_sel_regmap(struct regulator_dev *rdev) +{ + unsigned int val; + int ret; + + ret = regmap_read(rdev->regmap, rdev->desc->vsel_reg, &val); + if (ret != 0) + return ret; + + val &= rdev->desc->vsel_mask; + val >>= ffs(rdev->desc->vsel_mask) - 1; + + return val; +} +EXPORT_SYMBOL_GPL(regulator_get_voltage_sel_regmap); + +/** + * regulator_set_voltage_sel_regmap - standard set_voltage_sel for regmap users + * + * @rdev: regulator to operate on + * @sel: Selector to set + * + * Regulators that use regmap for their register I/O can set the + * vsel_reg and vsel_mask fields in their descriptor and then use this + * as their set_voltage_vsel operation, saving some code. + */ +int regulator_set_voltage_sel_regmap(struct regulator_dev *rdev, unsigned sel) +{ + sel <<= ffs(rdev->desc->vsel_mask) - 1; + + return regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg, + rdev->desc->vsel_mask, sel); +} +EXPORT_SYMBOL_GPL(regulator_set_voltage_sel_regmap); + static int _regulator_do_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) { diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h index 2e753731217b..d1c238970a6e 100644 --- a/include/linux/regulator/driver.h +++ b/include/linux/regulator/driver.h @@ -164,6 +164,9 @@ enum regulator_type { * @irq: Interrupt number for the regulator. * @type: Indicates if the regulator is a voltage or current regulator. * @owner: Module providing the regulator, used for refcounting. + + * @vsel_reg: Register for selector when using regulator_regmap_X_voltage_ + * @vsel_mask: Mask for register bitfield used for selector */ struct regulator_desc { const char *name; @@ -174,6 +177,9 @@ struct regulator_desc { int irq; enum regulator_type type; struct module *owner; + + unsigned int vsel_reg; + unsigned int vsel_mask; }; /** @@ -250,6 +256,9 @@ int rdev_get_id(struct regulator_dev *rdev); int regulator_mode_to_status(unsigned int); +int regulator_get_voltage_sel_regmap(struct regulator_dev *rdev); +int regulator_set_voltage_sel_regmap(struct regulator_dev *rdev, unsigned sel); + void *regulator_get_init_drvdata(struct regulator_init_data *reg_init_data); #endif