Prepare for merging the s2mpa01 regulator driver into s2mps11 by: 1. Adding common id for buck regulators. 2. Splitting shared ramp delay settings to match S2MPA01. 3. Adding a configuration of registers for setting ramp delay for each buck regulator. The functionality of the driver should not change as this patch only prepares for supporting S2MPA01 device. Signed-off-by: Krzysztof Kozlowski <k.kozlowski@xxxxxxxxxxx> --- drivers/regulator/s2mps11.c | 210 ++++++++++++++++++++++++++++++-------------- 1 file changed, 144 insertions(+), 66 deletions(-) diff --git a/drivers/regulator/s2mps11.c b/drivers/regulator/s2mps11.c index 02e2fb2fca66..fa12d75b784f 100644 --- a/drivers/regulator/s2mps11.c +++ b/drivers/regulator/s2mps11.c @@ -32,13 +32,32 @@ #include <linux/mfd/samsung/s2mps11.h> #include <linux/mfd/samsung/s2mps14.h> +/* + * Enum used as a common id of buck regulators on S2MPA01 and S2MPS11. + */ +enum s2mpx_bucks { + S2MPX_BUCK1, + S2MPX_BUCK2, + S2MPX_BUCK3, + S2MPX_BUCK4, + S2MPX_BUCK5, + S2MPX_BUCK6, + S2MPX_BUCK7, + S2MPX_BUCK8, + S2MPX_BUCK9, + S2MPX_BUCK10, +}; + struct s2mps11_info { + enum sec_device_type dev_type; unsigned int rdev_num; int ramp_delay2; - int ramp_delay34; + int ramp_delay3; + int ramp_delay4; int ramp_delay5; int ramp_delay16; - int ramp_delay7810; + int ramp_delay7; + int ramp_delay810; int ramp_delay9; /* * One bit for each S2MPS14 regulator whether the suspend mode @@ -49,6 +68,47 @@ struct s2mps11_info { int *ext_control_gpio; }; +/* + * Description of ramp delay register for one buck regulator + * on S2MPA01 and S2MPS11. + */ +struct s2mpx_ramp_reg { + unsigned int ramp_shift; + unsigned int ramp_reg; + unsigned int enable_shift; + bool enable_supported; +}; + +#define s2mps11_ramp_reg(r_shift) { \ + .ramp_shift = S2MPS11_ ## r_shift ## _RAMP_SHIFT, \ + .ramp_reg = S2MPS11_REG_RAMP_BUCK, \ + .enable_shift = 0, \ + .enable_supported = false, \ +} +#define s2mps11_buck2346_ramp_reg(r_shift, r_reg, e_shift) { \ + .ramp_shift = S2MPS11_ ## r_shift ## _RAMP_SHIFT, \ + .ramp_reg = S2MPS11_REG_ ## r_reg, \ + .enable_shift = S2MPS11_ ## e_shift ## _RAMP_EN_SHIFT,\ + .enable_supported = true, \ +} + +static const struct s2mpx_ramp_reg s2mps11_ramp_regs[] = { + [S2MPX_BUCK1] = s2mps11_ramp_reg(BUCK16), + [S2MPX_BUCK2] = s2mps11_buck2346_ramp_reg(BUCK2, RAMP, BUCK2), + [S2MPX_BUCK3] = s2mps11_buck2346_ramp_reg(BUCK34, RAMP, BUCK3), + [S2MPX_BUCK4] = s2mps11_buck2346_ramp_reg(BUCK34, RAMP, BUCK4), + [S2MPX_BUCK5] = s2mps11_ramp_reg(BUCK5), + [S2MPX_BUCK6] = s2mps11_buck2346_ramp_reg(BUCK16, RAMP_BUCK, BUCK6), + [S2MPX_BUCK7] = s2mps11_ramp_reg(BUCK7810), + [S2MPX_BUCK8] = s2mps11_ramp_reg(BUCK7810), + [S2MPX_BUCK9] = s2mps11_ramp_reg(BUCK9), + [S2MPX_BUCK10] = s2mps11_ramp_reg(BUCK7810), +}; + +static const struct s2mpx_ramp_reg * const s2mpx_ramp_regs[] = { + [S2MPS11X] = s2mps11_ramp_regs, +}; + static int get_ramp_delay(int ramp_delay) { unsigned char cnt = 0; @@ -68,6 +128,23 @@ static int get_ramp_delay(int ramp_delay) return cnt; } +/* + * Maps a buck regulator id to enum s2mpx_bucks. + * Valid only for buck regulators on on S2MPS11. + * + * Returns a value of enum s2mpx_bucks or -EINVAL. + */ +static int get_s2mpx_buck_id(enum sec_device_type dev_type, + int rdev_id) +{ + switch (dev_type) { + case S2MPS11X: + return rdev_id - S2MPS11_BUCK1; + default: + return -EINVAL; + } +} + static int s2mps11_regulator_set_voltage_time_sel(struct regulator_dev *rdev, unsigned int old_selector, unsigned int new_selector) @@ -75,29 +152,40 @@ static int s2mps11_regulator_set_voltage_time_sel(struct regulator_dev *rdev, struct s2mps11_info *s2mps11 = rdev_get_drvdata(rdev); unsigned int ramp_delay = 0; int old_volt, new_volt; + int buck_id = get_s2mpx_buck_id(s2mps11->dev_type, rdev_get_id(rdev)); - switch (rdev_get_id(rdev)) { - case S2MPS11_BUCK2: + switch (buck_id) { + case S2MPX_BUCK2: ramp_delay = s2mps11->ramp_delay2; break; - case S2MPS11_BUCK3: - case S2MPS11_BUCK4: - ramp_delay = s2mps11->ramp_delay34; + case S2MPX_BUCK3: + ramp_delay = s2mps11->ramp_delay3; break; - case S2MPS11_BUCK5: + case S2MPX_BUCK4: + ramp_delay = s2mps11->ramp_delay4; + break; + case S2MPX_BUCK5: ramp_delay = s2mps11->ramp_delay5; break; - case S2MPS11_BUCK6: - case S2MPS11_BUCK1: + case S2MPX_BUCK6: + case S2MPX_BUCK1: ramp_delay = s2mps11->ramp_delay16; break; - case S2MPS11_BUCK7: - case S2MPS11_BUCK8: - case S2MPS11_BUCK10: - ramp_delay = s2mps11->ramp_delay7810; + case S2MPX_BUCK7: + ramp_delay = s2mps11->ramp_delay7; break; - case S2MPS11_BUCK9: + case S2MPX_BUCK8: + case S2MPX_BUCK10: + ramp_delay = s2mps11->ramp_delay810; + break; + case S2MPX_BUCK9: ramp_delay = s2mps11->ramp_delay9; + break; + default: + dev_err(rdev_get_dev(rdev), + "Wrong regulator id %d for set_voltage_time_sel\n", + rdev_get_id(rdev)); + return -EINVAL; } if (ramp_delay == 0) @@ -112,66 +200,55 @@ static int s2mps11_regulator_set_voltage_time_sel(struct regulator_dev *rdev, static int s2mps11_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay) { struct s2mps11_info *s2mps11 = rdev_get_drvdata(rdev); - unsigned int ramp_val, ramp_shift, ramp_reg = S2MPS11_REG_RAMP_BUCK; - unsigned int ramp_enable = 1, enable_shift = 0; + const struct s2mpx_ramp_reg *ramp_reg; + unsigned int ramp_val; + unsigned int ramp_enable = 1; + int buck_id; int ret; - switch (rdev_get_id(rdev)) { - case S2MPS11_BUCK1: + buck_id = get_s2mpx_buck_id(s2mps11->dev_type, rdev_get_id(rdev)); + + switch (buck_id) { + case S2MPX_BUCK1: if (ramp_delay > s2mps11->ramp_delay16) s2mps11->ramp_delay16 = ramp_delay; else ramp_delay = s2mps11->ramp_delay16; - - ramp_shift = S2MPS11_BUCK16_RAMP_SHIFT; break; - case S2MPS11_BUCK2: - enable_shift = S2MPS11_BUCK2_RAMP_EN_SHIFT; + case S2MPX_BUCK2: if (!ramp_delay) { ramp_enable = 0; break; } s2mps11->ramp_delay2 = ramp_delay; - ramp_shift = S2MPS11_BUCK2_RAMP_SHIFT; - ramp_reg = S2MPS11_REG_RAMP; break; - case S2MPS11_BUCK3: - enable_shift = S2MPS11_BUCK3_RAMP_EN_SHIFT; + case S2MPX_BUCK3: if (!ramp_delay) { ramp_enable = 0; break; } - if (ramp_delay > s2mps11->ramp_delay34) - s2mps11->ramp_delay34 = ramp_delay; + if (ramp_delay > s2mps11->ramp_delay3) + s2mps11->ramp_delay3 = ramp_delay; else - ramp_delay = s2mps11->ramp_delay34; - - ramp_shift = S2MPS11_BUCK34_RAMP_SHIFT; - ramp_reg = S2MPS11_REG_RAMP; + ramp_delay = s2mps11->ramp_delay3; break; case S2MPS11_BUCK4: - enable_shift = S2MPS11_BUCK4_RAMP_EN_SHIFT; if (!ramp_delay) { ramp_enable = 0; break; } - if (ramp_delay > s2mps11->ramp_delay34) - s2mps11->ramp_delay34 = ramp_delay; + if (ramp_delay > s2mps11->ramp_delay4) + s2mps11->ramp_delay4 = ramp_delay; else - ramp_delay = s2mps11->ramp_delay34; - - ramp_shift = S2MPS11_BUCK34_RAMP_SHIFT; - ramp_reg = S2MPS11_REG_RAMP; + ramp_delay = s2mps11->ramp_delay4; break; case S2MPS11_BUCK5: s2mps11->ramp_delay5 = ramp_delay; - ramp_shift = S2MPS11_BUCK5_RAMP_SHIFT; break; case S2MPS11_BUCK6: - enable_shift = S2MPS11_BUCK6_RAMP_EN_SHIFT; if (!ramp_delay) { ramp_enable = 0; break; @@ -181,36 +258,37 @@ static int s2mps11_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay) s2mps11->ramp_delay16 = ramp_delay; else ramp_delay = s2mps11->ramp_delay16; - - ramp_shift = S2MPS11_BUCK16_RAMP_SHIFT; break; case S2MPS11_BUCK7: + if (ramp_delay > s2mps11->ramp_delay7) + s2mps11->ramp_delay7 = ramp_delay; + else + ramp_delay = s2mps11->ramp_delay7; + break; case S2MPS11_BUCK8: case S2MPS11_BUCK10: - if (ramp_delay > s2mps11->ramp_delay7810) - s2mps11->ramp_delay7810 = ramp_delay; + if (ramp_delay > s2mps11->ramp_delay810) + s2mps11->ramp_delay810 = ramp_delay; else - ramp_delay = s2mps11->ramp_delay7810; - - ramp_shift = S2MPS11_BUCK7810_RAMP_SHIFT; + ramp_delay = s2mps11->ramp_delay810; break; case S2MPS11_BUCK9: s2mps11->ramp_delay9 = ramp_delay; - ramp_shift = S2MPS11_BUCK9_RAMP_SHIFT; break; default: return 0; } + ramp_reg = &s2mpx_ramp_regs[s2mps11->dev_type][buck_id]; + if (!ramp_enable) goto ramp_disable; /* Ramp delay can be enabled/disabled only for buck[2346] */ - if ((rdev_get_id(rdev) >= S2MPS11_BUCK2 && - rdev_get_id(rdev) <= S2MPS11_BUCK4) || - rdev_get_id(rdev) == S2MPS11_BUCK6) { + if (ramp_reg->enable_supported) { ret = regmap_update_bits(rdev->regmap, S2MPS11_REG_RAMP, - 1 << enable_shift, 1 << enable_shift); + 1 << ramp_reg->enable_shift, + 1 << ramp_reg->enable_shift); if (ret) { dev_err(&rdev->dev, "failed to enable ramp rate\n"); return ret; @@ -219,12 +297,13 @@ static int s2mps11_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay) ramp_val = get_ramp_delay(ramp_delay); - return regmap_update_bits(rdev->regmap, ramp_reg, 0x3 << ramp_shift, - ramp_val << ramp_shift); + return regmap_update_bits(rdev->regmap, ramp_reg->ramp_reg, + 0x3 << ramp_reg->ramp_shift, + ramp_val << ramp_reg->ramp_shift); ramp_disable: return regmap_update_bits(rdev->regmap, S2MPS11_REG_RAMP, - 1 << enable_shift, 0); + 1 << ramp_reg->enable_shift, 0); } static struct regulator_ops s2mps11_ldo_ops = { @@ -250,7 +329,7 @@ static struct regulator_ops s2mps11_buck_ops = { .set_ramp_delay = s2mps11_set_ramp_delay, }; -#define regulator_desc_s2mps11_ldo1(num) { \ +#define regulator_desc_s2mps11_ldo1(num) { \ .name = "LDO"#num, \ .id = S2MPS11_LDO##num, \ .ops = &s2mps11_ldo_ops, \ @@ -605,8 +684,7 @@ static void s2mps14_pmic_dt_parse_ext_control_gpio(struct platform_device *pdev, } static int s2mps11_pmic_dt_parse(struct platform_device *pdev, - struct of_regulator_match *rdata, struct s2mps11_info *s2mps11, - enum sec_device_type dev_type) + struct of_regulator_match *rdata, struct s2mps11_info *s2mps11) { struct device_node *reg_np; @@ -617,7 +695,7 @@ static int s2mps11_pmic_dt_parse(struct platform_device *pdev, } of_regulator_match(&pdev->dev, reg_np, rdata, s2mps11->rdev_num); - if (dev_type == S2MPS14X) + if (s2mps11->dev_type == S2MPS14X) s2mps14_pmic_dt_parse_ext_control_gpio(pdev, rdata, s2mps11); of_node_put(reg_np); @@ -634,15 +712,14 @@ static int s2mps11_pmic_probe(struct platform_device *pdev) struct s2mps11_info *s2mps11; int i, ret = 0; const struct regulator_desc *regulators; - enum sec_device_type dev_type; s2mps11 = devm_kzalloc(&pdev->dev, sizeof(struct s2mps11_info), GFP_KERNEL); if (!s2mps11) return -ENOMEM; - dev_type = platform_get_device_id(pdev)->driver_data; - switch (dev_type) { + s2mps11->dev_type = platform_get_device_id(pdev)->driver_data; + switch (s2mps11->dev_type) { case S2MPS11X: s2mps11->rdev_num = ARRAY_SIZE(s2mps11_regulators); regulators = s2mps11_regulators; @@ -652,7 +729,8 @@ static int s2mps11_pmic_probe(struct platform_device *pdev) regulators = s2mps14_regulators; break; default: - dev_err(&pdev->dev, "Invalid device type: %u\n", dev_type); + dev_err(&pdev->dev, "Invalid device type: %u\n", + s2mps11->dev_type); return -EINVAL; }; @@ -686,7 +764,7 @@ static int s2mps11_pmic_probe(struct platform_device *pdev) for (i = 0; i < s2mps11->rdev_num; i++) rdata[i].name = regulators[i].name; - ret = s2mps11_pmic_dt_parse(pdev, rdata, s2mps11, dev_type); + ret = s2mps11_pmic_dt_parse(pdev, rdata, s2mps11); if (ret) goto out; -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html