Adds get/set for mode, and mapping from REGULATOR_MODE_* to select PFM/PWM/Auto operation. Signed-off-by: Adam Ward <Adam.Ward.opensource@xxxxxxxxxxx> --- drivers/regulator/da9121-regulator.c | 74 ++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/drivers/regulator/da9121-regulator.c b/drivers/regulator/da9121-regulator.c index 5d11c22..3addbd2 100644 --- a/drivers/regulator/da9121-regulator.c +++ b/drivers/regulator/da9121-regulator.c @@ -230,6 +230,72 @@ static int da9121_set_current_limit(struct regulator_dev *rdev, return ret; } +static unsigned int da9121_map_mode(unsigned int mode) +{ + switch (mode) { + case DA9121_BUCK_MODE_FORCE_PWM: + return REGULATOR_MODE_FAST; + case DA9121_BUCK_MODE_FORCE_PWM_SHEDDING: + return REGULATOR_MODE_NORMAL; + case DA9121_BUCK_MODE_AUTO: + return REGULATOR_MODE_IDLE; + case DA9121_BUCK_MODE_FORCE_PFM: + return REGULATOR_MODE_STANDBY; + default: + return -EINVAL; + } +} + +static int da9121_buck_set_mode(struct regulator_dev *rdev, unsigned int mode) +{ + struct da9121 *chip = rdev_get_drvdata(rdev); + unsigned int val; + unsigned int reg; + unsigned int msk; + + switch (mode) { + case REGULATOR_MODE_FAST: + val = DA9121_BUCK_MODE_FORCE_PWM; + break; + case REGULATOR_MODE_NORMAL: + val = DA9121_BUCK_MODE_FORCE_PWM_SHEDDING; + break; + case REGULATOR_MODE_IDLE: + val = DA9121_BUCK_MODE_AUTO; + break; + case REGULATOR_MODE_STANDBY: + val = DA9121_BUCK_MODE_FORCE_PFM; + break; + default: + return -EINVAL; + } + + if (!da9121_rdev_to_buck_reg_mask(rdev, true, ®, &msk)) + return -EINVAL; + + return regmap_update_bits(chip->regmap, reg, msk, val); +} + +static unsigned int da9121_buck_get_mode(struct regulator_dev *rdev) +{ + struct da9121 *chip = rdev_get_drvdata(rdev); + unsigned int reg; + unsigned int msk; + unsigned int val; + int ret = 0; + + if (!da9121_rdev_to_buck_reg_mask(rdev, true, ®, &msk)) + return -EINVAL; + + ret = regmap_read(chip->regmap, reg, &val); + if (ret < 0) { + dev_err(chip->dev, "Cannot read BUCK register: %d\n", ret); + return -EINVAL; + } + + return da9121_map_mode(val & msk); +} + static const struct regulator_ops da9121_buck_ops = { .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, @@ -239,6 +305,8 @@ static int da9121_set_current_limit(struct regulator_dev *rdev, .list_voltage = regulator_list_voltage_linear, .get_current_limit = da9121_get_current_limit, .set_current_limit = da9121_set_current_limit, + .set_mode = da9121_buck_set_mode, + .get_mode = da9121_buck_get_mode, }; static struct of_regulator_match da9121_matches[] = { @@ -258,6 +326,7 @@ static int da9121_set_current_limit(struct regulator_dev *rdev, .name = "da9121", .of_match = "buck1", .owner = THIS_MODULE, + .of_map_mode = da9121_map_mode, .regulators_node = of_match_ptr("regulators"), .ops = &da9121_buck_ops, .type = REGULATOR_VOLTAGE, @@ -281,6 +350,7 @@ static int da9121_set_current_limit(struct regulator_dev *rdev, .name = "DA9220/DA9132 BUCK1", .of_match = "buck1", .owner = THIS_MODULE, + .of_map_mode = da9121_map_mode, .regulators_node = of_match_ptr("regulators"), .ops = &da9121_buck_ops, .type = REGULATOR_VOLTAGE, @@ -298,6 +368,7 @@ static int da9121_set_current_limit(struct regulator_dev *rdev, .name = "DA9220/DA9132 BUCK2", .of_match = "buck2", .owner = THIS_MODULE, + .of_map_mode = da9121_map_mode, .regulators_node = of_match_ptr("regulators"), .ops = &da9121_buck_ops, .type = REGULATOR_VOLTAGE, @@ -318,6 +389,7 @@ static int da9121_set_current_limit(struct regulator_dev *rdev, .name = "DA9122/DA9131 BUCK1", .of_match = "buck1", .owner = THIS_MODULE, + .of_map_mode = da9121_map_mode, .regulators_node = of_match_ptr("regulators"), .ops = &da9121_buck_ops, .type = REGULATOR_VOLTAGE, @@ -335,6 +407,7 @@ static int da9121_set_current_limit(struct regulator_dev *rdev, .name = "DA9122/DA9131 BUCK2", .of_match = "buck2", .owner = THIS_MODULE, + .of_map_mode = da9121_map_mode, .regulators_node = of_match_ptr("regulators"), .ops = &da9121_buck_ops, .type = REGULATOR_VOLTAGE, @@ -354,6 +427,7 @@ static int da9121_set_current_limit(struct regulator_dev *rdev, .name = "DA9217 BUCK1", .of_match = "buck1", .owner = THIS_MODULE, + .of_map_mode = da9121_map_mode, .regulators_node = of_match_ptr("regulators"), .ops = &da9121_buck_ops, .type = REGULATOR_VOLTAGE, -- 1.9.1