From fb69114b3efc47c2489b2d0a781814c66bcaaf35 Mon Sep 17 00:00:00 2001 From: Henry Chen Date: Mon, 23 May 2016 15:30:16 +0800 Subject: regulator: mt6397: Constify struct regulator_ops Consitify the structure of regulator operations. Signed-off-by: Henry Chen Signed-off-by: Mark Brown --- drivers/regulator/mt6397-regulator.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/regulator/mt6397-regulator.c b/drivers/regulator/mt6397-regulator.c index 17a5b6c2d6a9..1c45abb94409 100644 --- a/drivers/regulator/mt6397-regulator.c +++ b/drivers/regulator/mt6397-regulator.c @@ -160,7 +160,7 @@ static int mt6397_get_status(struct regulator_dev *rdev) return (regval & info->qi) ? REGULATOR_STATUS_ON : REGULATOR_STATUS_OFF; } -static struct regulator_ops mt6397_volt_range_ops = { +static const struct regulator_ops mt6397_volt_range_ops = { .list_voltage = regulator_list_voltage_linear_range, .map_voltage = regulator_map_voltage_linear_range, .set_voltage_sel = regulator_set_voltage_sel_regmap, @@ -172,7 +172,7 @@ static struct regulator_ops mt6397_volt_range_ops = { .get_status = mt6397_get_status, }; -static struct regulator_ops mt6397_volt_table_ops = { +static const struct regulator_ops mt6397_volt_table_ops = { .list_voltage = regulator_list_voltage_table, .map_voltage = regulator_map_voltage_iterate, .set_voltage_sel = regulator_set_voltage_sel_regmap, @@ -184,7 +184,7 @@ static struct regulator_ops mt6397_volt_table_ops = { .get_status = mt6397_get_status, }; -static struct regulator_ops mt6397_volt_fixed_ops = { +static const struct regulator_ops mt6397_volt_fixed_ops = { .list_voltage = regulator_list_voltage_linear, .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, -- cgit v1.2.3 From 056925132722312d9ca7fa686138b87b24b7c04c Mon Sep 17 00:00:00 2001 From: Henry Chen Date: Mon, 23 May 2016 15:13:31 +0800 Subject: regulator: mt6397: Add buck change mode regulator interface for mt6397 BUCKs of mt6397 have auto mode and pwm mode. User can use regulator interfaces to control modes Signed-off-by: Henry Chen Signed-off-by: Mark Brown --- drivers/regulator/mt6397-regulator.c | 89 ++++++++++++++++++++++++++++++++---- 1 file changed, 80 insertions(+), 9 deletions(-) diff --git a/drivers/regulator/mt6397-regulator.c b/drivers/regulator/mt6397-regulator.c index 1c45abb94409..c6c6aa85e4e8 100644 --- a/drivers/regulator/mt6397-regulator.c +++ b/drivers/regulator/mt6397-regulator.c @@ -23,6 +23,9 @@ #include #include +#define MT6397_BUCK_MODE_AUTO 0 +#define MT6397_BUCK_MODE_FORCE_PWM 1 + /* * MT6397 regulators' information * @@ -38,10 +41,14 @@ struct mt6397_regulator_info { u32 vselon_reg; u32 vselctrl_reg; u32 vselctrl_mask; + u32 modeset_reg; + u32 modeset_mask; + u32 modeset_shift; }; #define MT6397_BUCK(match, vreg, min, max, step, volt_ranges, enreg, \ - vosel, vosel_mask, voselon, vosel_ctrl) \ + vosel, vosel_mask, voselon, vosel_ctrl, _modeset_reg, \ + _modeset_shift) \ [MT6397_ID_##vreg] = { \ .desc = { \ .name = #vreg, \ @@ -62,6 +69,9 @@ struct mt6397_regulator_info { .vselon_reg = voselon, \ .vselctrl_reg = vosel_ctrl, \ .vselctrl_mask = BIT(1), \ + .modeset_reg = _modeset_reg, \ + .modeset_mask = BIT(_modeset_shift), \ + .modeset_shift = _modeset_shift \ } #define MT6397_LDO(match, vreg, ldo_volt_table, enreg, enbit, vosel, \ @@ -145,6 +155,63 @@ static const u32 ldo_volt_table7[] = { 1300000, 1500000, 1800000, 2000000, 2500000, 2800000, 3000000, 3300000, }; +static int mt6397_regulator_set_mode(struct regulator_dev *rdev, + unsigned int mode) +{ + struct mt6397_regulator_info *info = rdev_get_drvdata(rdev); + int ret, val; + + switch (mode) { + case REGULATOR_MODE_FAST: + val = MT6397_BUCK_MODE_FORCE_PWM; + break; + case REGULATOR_MODE_NORMAL: + val = MT6397_BUCK_MODE_AUTO; + break; + default: + ret = -EINVAL; + goto err_mode; + } + + dev_dbg(&rdev->dev, "mt6397 buck set_mode %#x, %#x, %#x, %#x\n", + info->modeset_reg, info->modeset_mask, + info->modeset_shift, val); + + val <<= info->modeset_shift; + ret = regmap_update_bits(rdev->regmap, info->modeset_reg, + info->modeset_mask, val); +err_mode: + if (ret != 0) { + dev_err(&rdev->dev, + "Failed to set mt6397 buck mode: %d\n", ret); + return ret; + } + + return 0; +} + +static unsigned int mt6397_regulator_get_mode(struct regulator_dev *rdev) +{ + struct mt6397_regulator_info *info = rdev_get_drvdata(rdev); + int ret, regval; + + ret = regmap_read(rdev->regmap, info->modeset_reg, ®val); + if (ret != 0) { + dev_err(&rdev->dev, + "Failed to get mt6397 buck mode: %d\n", ret); + return ret; + } + + switch ((regval & info->modeset_mask) >> info->modeset_shift) { + case MT6397_BUCK_MODE_AUTO: + return REGULATOR_MODE_NORMAL; + case MT6397_BUCK_MODE_FORCE_PWM: + return REGULATOR_MODE_FAST; + default: + return -EINVAL; + } +} + static int mt6397_get_status(struct regulator_dev *rdev) { int ret; @@ -170,6 +237,8 @@ static const struct regulator_ops mt6397_volt_range_ops = { .disable = regulator_disable_regmap, .is_enabled = regulator_is_enabled_regmap, .get_status = mt6397_get_status, + .set_mode = mt6397_regulator_set_mode, + .get_mode = mt6397_regulator_get_mode, }; static const struct regulator_ops mt6397_volt_table_ops = { @@ -196,28 +265,30 @@ static const struct regulator_ops mt6397_volt_fixed_ops = { static struct mt6397_regulator_info mt6397_regulators[] = { MT6397_BUCK("buck_vpca15", VPCA15, 700000, 1493750, 6250, buck_volt_range1, MT6397_VCA15_CON7, MT6397_VCA15_CON9, 0x7f, - MT6397_VCA15_CON10, MT6397_VCA15_CON5), + MT6397_VCA15_CON10, MT6397_VCA15_CON5, MT6397_VCA15_CON2, 11), MT6397_BUCK("buck_vpca7", VPCA7, 700000, 1493750, 6250, buck_volt_range1, MT6397_VPCA7_CON7, MT6397_VPCA7_CON9, 0x7f, - MT6397_VPCA7_CON10, MT6397_VPCA7_CON5), + MT6397_VPCA7_CON10, MT6397_VPCA7_CON5, MT6397_VPCA7_CON2, 8), MT6397_BUCK("buck_vsramca15", VSRAMCA15, 700000, 1493750, 6250, buck_volt_range1, MT6397_VSRMCA15_CON7, MT6397_VSRMCA15_CON9, - 0x7f, MT6397_VSRMCA15_CON10, MT6397_VSRMCA15_CON5), + 0x7f, MT6397_VSRMCA15_CON10, MT6397_VSRMCA15_CON5, + MT6397_VSRMCA15_CON2, 8), MT6397_BUCK("buck_vsramca7", VSRAMCA7, 700000, 1493750, 6250, buck_volt_range1, MT6397_VSRMCA7_CON7, MT6397_VSRMCA7_CON9, - 0x7f, MT6397_VSRMCA7_CON10, MT6397_VSRMCA7_CON5), + 0x7f, MT6397_VSRMCA7_CON10, MT6397_VSRMCA7_CON5, + MT6397_VSRMCA7_CON2, 8), MT6397_BUCK("buck_vcore", VCORE, 700000, 1493750, 6250, buck_volt_range1, MT6397_VCORE_CON7, MT6397_VCORE_CON9, 0x7f, - MT6397_VCORE_CON10, MT6397_VCORE_CON5), + MT6397_VCORE_CON10, MT6397_VCORE_CON5, MT6397_VCORE_CON2, 8), MT6397_BUCK("buck_vgpu", VGPU, 700000, 1493750, 6250, buck_volt_range1, MT6397_VGPU_CON7, MT6397_VGPU_CON9, 0x7f, - MT6397_VGPU_CON10, MT6397_VGPU_CON5), + MT6397_VGPU_CON10, MT6397_VGPU_CON5, MT6397_VGPU_CON2, 8), MT6397_BUCK("buck_vdrm", VDRM, 800000, 1593750, 6250, buck_volt_range2, MT6397_VDRM_CON7, MT6397_VDRM_CON9, 0x7f, - MT6397_VDRM_CON10, MT6397_VDRM_CON5), + MT6397_VDRM_CON10, MT6397_VDRM_CON5, MT6397_VDRM_CON2, 8), MT6397_BUCK("buck_vio18", VIO18, 1500000, 2120000, 20000, buck_volt_range3, MT6397_VIO18_CON7, MT6397_VIO18_CON9, 0x1f, - MT6397_VIO18_CON10, MT6397_VIO18_CON5), + MT6397_VIO18_CON10, MT6397_VIO18_CON5, MT6397_VIO18_CON2, 8), MT6397_REG_FIXED("ldo_vtcxo", VTCXO, MT6397_ANALDO_CON0, 10, 2800000), MT6397_REG_FIXED("ldo_va28", VA28, MT6397_ANALDO_CON1, 14, 2800000), MT6397_LDO("ldo_vcama", VCAMA, ldo_volt_table1, -- cgit v1.2.3 From 830583004e615a4637eacc77866b84908414d7a0 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Fri, 3 Jun 2016 10:23:00 +0200 Subject: regulator: pwm: Drop unneeded pwm_enable() call Now that the PWM regulator driver implements the ->enable/disable() hooks we can remove the pwm_enable() call from pwm_regulator_set_voltage(). Signed-off-by: Boris Brezillon Signed-off-by: Mark Brown --- drivers/regulator/pwm-regulator.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/regulator/pwm-regulator.c b/drivers/regulator/pwm-regulator.c index fafa3488e960..ab3cc0235843 100644 --- a/drivers/regulator/pwm-regulator.c +++ b/drivers/regulator/pwm-regulator.c @@ -159,11 +159,6 @@ static int pwm_regulator_set_voltage(struct regulator_dev *rdev, return ret; } - ret = pwm_enable(drvdata->pwm); - if (ret) { - dev_err(&rdev->dev, "Failed to enable PWM: %d\n", ret); - return ret; - } drvdata->volt_uV = min_uV; /* Delay required by PWM regulator to settle to the new voltage */ -- cgit v1.2.3 From 124256548f4e7d3ff81a37a64acb439778bcdbfb Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Sun, 5 Jun 2016 19:17:38 -0300 Subject: regulator: pfuze100-regulator: Remove global variable We should better not use a global 'struct pfuze_regulator' variable, as this could cause problems if multiple regulator chips are used. Place it inside the private struct instead. Signed-off-by: Fabio Estevam Signed-off-by: Mark Brown --- drivers/regulator/pfuze100-regulator.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/drivers/regulator/pfuze100-regulator.c b/drivers/regulator/pfuze100-regulator.c index 2a44e5dd9c2a..bcdf9206f3ee 100644 --- a/drivers/regulator/pfuze100-regulator.c +++ b/drivers/regulator/pfuze100-regulator.c @@ -70,6 +70,7 @@ struct pfuze_chip { struct device *dev; struct pfuze_regulator regulator_descs[PFUZE100_MAX_REGULATOR]; struct regulator_dev *regulators[PFUZE100_MAX_REGULATOR]; + struct pfuze_regulator *pfuze_regulators; }; static const int pfuze100_swbst[] = { @@ -334,8 +335,6 @@ static struct pfuze_regulator pfuze3000_regulators[] = { PFUZE100_VGEN_REG(PFUZE3000, VLDO4, PFUZE100_VGEN6VOL, 1800000, 3300000, 100000), }; -static struct pfuze_regulator *pfuze_regulators; - #ifdef CONFIG_OF /* PFUZE100 */ static struct of_regulator_match pfuze100_matches[] = { @@ -563,21 +562,21 @@ static int pfuze100_regulator_probe(struct i2c_client *client, /* use the right regulators after identify the right device */ switch (pfuze_chip->chip_id) { case PFUZE3000: - pfuze_regulators = pfuze3000_regulators; + pfuze_chip->pfuze_regulators = pfuze3000_regulators; regulator_num = ARRAY_SIZE(pfuze3000_regulators); sw_check_start = PFUZE3000_SW2; sw_check_end = PFUZE3000_SW2; sw_hi = 1 << 3; break; case PFUZE200: - pfuze_regulators = pfuze200_regulators; + pfuze_chip->pfuze_regulators = pfuze200_regulators; regulator_num = ARRAY_SIZE(pfuze200_regulators); sw_check_start = PFUZE200_SW2; sw_check_end = PFUZE200_SW3B; break; case PFUZE100: default: - pfuze_regulators = pfuze100_regulators; + pfuze_chip->pfuze_regulators = pfuze100_regulators; regulator_num = ARRAY_SIZE(pfuze100_regulators); sw_check_start = PFUZE100_SW2; sw_check_end = PFUZE100_SW4; @@ -587,7 +586,7 @@ static int pfuze100_regulator_probe(struct i2c_client *client, (pfuze_chip->chip_id == PFUZE100) ? "100" : ((pfuze_chip->chip_id == PFUZE200) ? "200" : "3000")); - memcpy(pfuze_chip->regulator_descs, pfuze_regulators, + memcpy(pfuze_chip->regulator_descs, pfuze_chip->pfuze_regulators, sizeof(pfuze_chip->regulator_descs)); ret = pfuze_parse_regulators_dt(pfuze_chip); @@ -631,7 +630,7 @@ static int pfuze100_regulator_probe(struct i2c_client *client, devm_regulator_register(&client->dev, desc, &config); if (IS_ERR(pfuze_chip->regulators[i])) { dev_err(&client->dev, "register regulator%s failed\n", - pfuze_regulators[i].desc.name); + pfuze_chip->pfuze_regulators[i].desc.name); return PTR_ERR(pfuze_chip->regulators[i]); } } -- cgit v1.2.3 From af2c55cd4752d77699453ff5550dc316e86d6c77 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Sun, 5 Jun 2016 19:17:39 -0300 Subject: regulator: Kconfig: Mention that PFUZE3000 is also supported The CONFIG_REGULATOR_PFUZE100 option also supports PFUZE3000, so mention that in the Kconfig text. Signed-off-by: Fabio Estevam Signed-off-by: Mark Brown --- drivers/regulator/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 144cbf5b3e5a..bd87820d7e61 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -543,12 +543,12 @@ config REGULATOR_PCF50633 on PCF50633 config REGULATOR_PFUZE100 - tristate "Freescale PFUZE100/PFUZE200 regulator driver" + tristate "Freescale PFUZE100/200/3000 regulator driver" depends on I2C select REGMAP_I2C help Say y here to support the regulators found on the Freescale - PFUZE100/PFUZE200 PMIC. + PFUZE100/200/3000 PMIC. config REGULATOR_PV88060 tristate "Powerventure Semiconductor PV88060 regulator" -- cgit v1.2.3 From 7eeeab8c02c546207be971283adfca1ebf18e387 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Sun, 5 Jun 2016 19:17:40 -0300 Subject: regulator: pfuze100-regulator: Adjust MODULE_DESCRIPTION() Adjust the MODULE_DESCRIPTION() text to also include the PFUZE3000 as a supported device. Signed-off-by: Fabio Estevam Signed-off-by: Mark Brown --- drivers/regulator/pfuze100-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/pfuze100-regulator.c b/drivers/regulator/pfuze100-regulator.c index bcdf9206f3ee..cb18b5c4f2db 100644 --- a/drivers/regulator/pfuze100-regulator.c +++ b/drivers/regulator/pfuze100-regulator.c @@ -649,5 +649,5 @@ static struct i2c_driver pfuze_driver = { module_i2c_driver(pfuze_driver); MODULE_AUTHOR("Robin Gong "); -MODULE_DESCRIPTION("Regulator Driver for Freescale PFUZE100/PFUZE200 PMIC"); +MODULE_DESCRIPTION("Regulator Driver for Freescale PFUZE100/200/3000 PMIC"); MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From 43160ffd12c8d1d331362362eea3c70e04b6f9c4 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 15 Jun 2016 10:21:34 +0800 Subject: regulator: qcom_smd: Remove list_voltage callback for rpm_smps_ldo_ops_fixed Use regulator_list_voltage_linear_range in rpm_smps_ldo_ops_fixed is wrong because it is used for fixed regulator without any linear range. The rpm_smps_ldo_ops_fixed is used for pm8941_lnldo which has fixed_uV set and n_voltages = 1. In this case, regulator_list_voltage() can return rdev->desc->fixed_uV without .list_voltage implementation. Fixes: 3bfbb4d1a480 ("regulator: qcom_smd: add list_voltage callback") Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/qcom_smd-regulator.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/regulator/qcom_smd-regulator.c b/drivers/regulator/qcom_smd-regulator.c index 526bf23dcb49..6c7fe4778793 100644 --- a/drivers/regulator/qcom_smd-regulator.c +++ b/drivers/regulator/qcom_smd-regulator.c @@ -152,7 +152,6 @@ static const struct regulator_ops rpm_smps_ldo_ops_fixed = { .enable = rpm_reg_enable, .disable = rpm_reg_disable, .is_enabled = rpm_reg_is_enabled, - .list_voltage = regulator_list_voltage_linear_range, .get_voltage = rpm_reg_get_voltage, .set_voltage = rpm_reg_set_voltage, -- cgit v1.2.3 From a0f78bc89c0396d14b6102c6f72485e14c8821f3 Mon Sep 17 00:00:00 2001 From: Keerthy Date: Mon, 20 Jun 2016 14:13:31 +0530 Subject: regulator: of: setup initial suspend state Setup initial suspend state to mem, if suspend state is defined for mem state. This makes sure that the regulators are in proper mode already from boot. Signed-off-by: Tero Kristo Signed-off-by: Dave Gerlach Signed-off-by: Keerthy Signed-off-by: Mark Brown --- drivers/regulator/of_regulator.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/regulator/of_regulator.c b/drivers/regulator/of_regulator.c index cd828dbf9d52..4f613ec99500 100644 --- a/drivers/regulator/of_regulator.c +++ b/drivers/regulator/of_regulator.c @@ -163,6 +163,9 @@ static void of_get_regulation_constraints(struct device_node *np, "regulator-suspend-microvolt", &pval)) suspend_state->uV = pval; + if (i == PM_SUSPEND_MEM) + constraints->initial_state = PM_SUSPEND_MEM; + of_node_put(suspend_np); suspend_state = NULL; suspend_np = NULL; -- cgit v1.2.3 From 27bfa8893b15a3fa22a593c90a48c8bcb1f9c75b Mon Sep 17 00:00:00 2001 From: Alexandre Courbot Date: Thu, 23 Jun 2016 16:39:44 +0900 Subject: regulator: pwm: Support for enable GPIO Add an optional enable GPIO to the pwm-regulator driver. Signed-off-by: Alexandre Courbot Signed-off-by: Mark Brown --- .../bindings/regulator/pwm-regulator.txt | 7 +++++- drivers/regulator/pwm-regulator.c | 26 ++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/regulator/pwm-regulator.txt b/Documentation/devicetree/bindings/regulator/pwm-regulator.txt index ed936f0f34f2..dd6f59cf1455 100644 --- a/Documentation/devicetree/bindings/regulator/pwm-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/pwm-regulator.txt @@ -38,13 +38,18 @@ NB: To be clear, if voltage-table is provided, then the device will be used in Voltage Table Mode. If no voltage-table is provided, then the device will be used in Continuous Voltage Mode. +Optional properties: +-------------------- +- enable-gpios: GPIO to use to enable/disable the regulator + Any property defined as part of the core regulator binding can also be used. (See: ../regulator/regulator.txt) -Continuous Voltage Example: +Continuous Voltage With Enable GPIO Example: pwm_regulator { compatible = "pwm-regulator; pwms = <&pwm1 0 8448 0>; + enable-gpios = <&gpio0 23 GPIO_ACTIVE_HIGH>; regulator-min-microvolt = <1016000>; regulator-max-microvolt = <1114000>; regulator-name = "vdd_logic"; diff --git a/drivers/regulator/pwm-regulator.c b/drivers/regulator/pwm-regulator.c index ab3cc0235843..90f8b7fd0437 100644 --- a/drivers/regulator/pwm-regulator.c +++ b/drivers/regulator/pwm-regulator.c @@ -20,6 +20,7 @@ #include #include #include +#include struct pwm_regulator_data { /* Shared */ @@ -38,6 +39,9 @@ struct pwm_regulator_data { /* Continuous voltage */ int volt_uV; + + /* Enable GPIO */ + struct gpio_desc *enb_gpio; }; struct pwm_voltages { @@ -94,6 +98,9 @@ static int pwm_regulator_enable(struct regulator_dev *dev) { struct pwm_regulator_data *drvdata = rdev_get_drvdata(dev); + if (drvdata->enb_gpio) + gpiod_set_value_cansleep(drvdata->enb_gpio, 1); + return pwm_enable(drvdata->pwm); } @@ -103,6 +110,9 @@ static int pwm_regulator_disable(struct regulator_dev *dev) pwm_disable(drvdata->pwm); + if (drvdata->enb_gpio) + gpiod_set_value_cansleep(drvdata->enb_gpio, 0); + return 0; } @@ -110,6 +120,9 @@ static int pwm_regulator_is_enabled(struct regulator_dev *dev) { struct pwm_regulator_data *drvdata = rdev_get_drvdata(dev); + if (drvdata->enb_gpio && !gpiod_get_value_cansleep(drvdata->enb_gpio)) + return false; + return pwm_is_enabled(drvdata->pwm); } @@ -248,6 +261,7 @@ static int pwm_regulator_probe(struct platform_device *pdev) struct regulator_dev *regulator; struct regulator_config config = { }; struct device_node *np = pdev->dev.of_node; + enum gpiod_flags gpio_flags; int ret; if (!np) { @@ -285,6 +299,18 @@ static int pwm_regulator_probe(struct platform_device *pdev) return ret; } + if (init_data->constraints.boot_on || init_data->constraints.always_on) + gpio_flags = GPIOD_OUT_HIGH; + else + gpio_flags = GPIOD_OUT_LOW; + drvdata->enb_gpio = devm_gpiod_get_optional(&pdev->dev, "enable", + gpio_flags); + if (IS_ERR(drvdata->enb_gpio)) { + ret = PTR_ERR(drvdata->enb_gpio); + dev_err(&pdev->dev, "Failed to get enable GPIO: %d\n", ret); + return ret; + } + /* * FIXME: pwm_apply_args() should be removed when switching to the * atomic PWM API. -- cgit v1.2.3 From c2588393e6315ab68207323d37d2a73713d6bc81 Mon Sep 17 00:00:00 2001 From: Douglas Anderson Date: Wed, 6 Jul 2016 11:42:01 -0700 Subject: regulator: pwm: Fix regulator ramp delay for continuous mode The original commit adding support for continuous voltage mode didn't handle the regulator ramp delay properly. It treated the delay as a fixed delay in uS despite the property being defined as uV / uS. Let's adjust it. Luckily there appear to be no users of this ramp delay for PWM regulators (as per grepping through device trees in linuxnext). Note also that the upper bound of usleep_range probably shouldn't be a full 1 ms longer than the lower bound since I've seen plenty of hardware with a ramp rate of ~5000 uS / uV and for small jumps the total delays are in the tens of uS. 1000 is way too much. We'll try to be dynamic and use 10%. NOTE: This commit doesn't add support for regulator-enable-ramp-delay. That could be done in a future patch when someone has a user of that featre. Though this patch is shows as "fixing" a bug, there are no actual known users of continuous mode PWM regulator w/ ramp delay in mainline and so this likely won't have any effect on anyone unless they are working out-of-tree with private patches. For anyone in this state, it is highly encouraged to also pick Boris Brezillon's WIP patches to get yourself a reliable and glitch-free regulator. Fixes: 4773be185a0f ("regulator: pwm-regulator: Add support for continuous-voltage") Signed-off-by: Douglas Anderson Acked-by: Laxman Dewangan Signed-off-by: Mark Brown --- drivers/regulator/pwm-regulator.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/regulator/pwm-regulator.c b/drivers/regulator/pwm-regulator.c index 90f8b7fd0437..666bc3bb52ef 100644 --- a/drivers/regulator/pwm-regulator.c +++ b/drivers/regulator/pwm-regulator.c @@ -145,6 +145,7 @@ static int pwm_regulator_set_voltage(struct regulator_dev *rdev, unsigned int duty_pulse; u64 req_period; u32 rem; + int old_uV = pwm_regulator_get_voltage(rdev); int ret; pwm_get_args(drvdata->pwm, &pargs); @@ -174,8 +175,12 @@ static int pwm_regulator_set_voltage(struct regulator_dev *rdev, drvdata->volt_uV = min_uV; - /* Delay required by PWM regulator to settle to the new voltage */ - usleep_range(ramp_delay, ramp_delay + 1000); + if ((ramp_delay == 0) || !pwm_regulator_is_enabled(rdev)) + return 0; + + /* Ramp delay is in uV/uS. Adjust to uS and delay */ + ramp_delay = DIV_ROUND_UP(abs(min_uV - old_uV), ramp_delay); + usleep_range(ramp_delay, ramp_delay + DIV_ROUND_UP(ramp_delay, 10)); return 0; } -- cgit v1.2.3 From b7a8524cfae0b3bde80be38c171e4ecac8ba527e Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Mon, 11 Jul 2016 14:50:09 -0700 Subject: regulator: qcom_smd: Avoid overlapping linear voltage ranges The pm8x41_hfsmps ranges overlap. The first range is from 375000 to 1562500: 375000 + (95 * 12500) == 1562500 and the second range starts at 1550000. Interestingly, the second range ends at the correct value when it's set to be the appropriate start value, 1575000: 1575000 + ((158 - 96) * 25000) == 3125000 Signed-off-by: Stephen Boyd Reviewed-by: Andy Gross Signed-off-by: Mark Brown --- drivers/regulator/qcom_smd-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/regulator/qcom_smd-regulator.c b/drivers/regulator/qcom_smd-regulator.c index 6c7fe4778793..5022fa8d10c6 100644 --- a/drivers/regulator/qcom_smd-regulator.c +++ b/drivers/regulator/qcom_smd-regulator.c @@ -211,7 +211,7 @@ static const struct regulator_desc pma8084_switch = { static const struct regulator_desc pm8x41_hfsmps = { .linear_ranges = (struct regulator_linear_range[]) { REGULATOR_LINEAR_RANGE( 375000, 0, 95, 12500), - REGULATOR_LINEAR_RANGE(1550000, 96, 158, 25000), + REGULATOR_LINEAR_RANGE(1575000, 96, 158, 25000), }, .n_linear_ranges = 2, .n_voltages = 159, -- cgit v1.2.3