From 2ac1ea2c4a8c714d8994ce35d0f6f9fec5e8cdc5 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Tue, 7 Jun 2016 18:40:01 +0100 Subject: regulator: twl: fix use of integer as pointer The TWL6030_FIXED_LDO() macro passes the TWL_FIXED_LDO() macro an 0x0 instead of a NULL. Changing this to a NULL fixes the following warnings: drivers/regulator/twl-regulator.c:1068:1: warning: Using plain integer as NULL pointer drivers/regulator/twl-regulator.c:1069:1: warning: Using plain integer as NULL pointer drivers/regulator/twl-regulator.c:1070:1: warning: Using plain integer as NULL pointer drivers/regulator/twl-regulator.c:1071:1: warning: Using plain integer as NULL pointer drivers/regulator/twl-regulator.c:1072:1: warning: Using plain integer as NULL pointer drivers/regulator/twl-regulator.c:1073:1: warning: Using plain integer as NULL pointer Signed-off-by: Ben Dooks Signed-off-by: Mark Brown --- drivers/regulator/twl-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c index faeb5ee92c9e..210681d6b743 100644 --- a/drivers/regulator/twl-regulator.c +++ b/drivers/regulator/twl-regulator.c @@ -905,7 +905,7 @@ static struct regulator_ops twlsmps_ops = { twl4030reg_map_mode) #define TWL6030_FIXED_LDO(label, offset, mVolts, turnon_delay) \ TWL_FIXED_LDO(label, offset, mVolts, 0x0, turnon_delay, \ - 0x0, TWL6030, twl6030fixed_ops, 0x0) + 0x0, TWL6030, twl6030fixed_ops, NULL) #define TWL4030_ADJUSTABLE_LDO(label, offset, num, turnon_delay, remap_conf) \ static const struct twlreg_info TWL4030_INFO_##label = { \ -- cgit v1.2.3 From c333dfe8dba7d3e47e97e1cee3c38123e19ae73c Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Sat, 25 Jun 2016 22:52:11 -0700 Subject: regulator: qcom_spmi: Add support for S4 supply on pm8941 The S4 supply is sometimes called the boost regulator because it outputs 5V. Typically it's connected to the 5vs1 and 5vs2 switches for use in USB OTG and HDMI applications. Add support for this regulator which was mistakenly left out from the initial submission of this driver. Cc: Bjorn Andersson Fixes: e92a4047419c ("regulator: Add QCOM SPMI regulator driver") Signed-off-by: Stephen Boyd Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/regulator/qcom,spmi-regulator.txt | 4 ++-- drivers/regulator/qcom_spmi-regulator.c | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers/regulator') diff --git a/Documentation/devicetree/bindings/regulator/qcom,spmi-regulator.txt b/Documentation/devicetree/bindings/regulator/qcom,spmi-regulator.txt index 46c6f3ed1a1c..3e827bb9a56d 100644 --- a/Documentation/devicetree/bindings/regulator/qcom,spmi-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/qcom,spmi-regulator.txt @@ -113,8 +113,8 @@ pm8916: l14, l15, l16, l17, l18 pm8941: - s1, s2, s3, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, l13, l14, - l15, l16, l17, l18, l19, l20, l21, l22, l23, l24, lvs1, lvs2, lvs3, + s1, s2, s3, s4, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, l13, + l14, l15, l16, l17, l18, l19, l20, l21, l22, l23, l24, lvs1, lvs2, lvs3, mvs1, mvs2 pm8994: diff --git a/drivers/regulator/qcom_spmi-regulator.c b/drivers/regulator/qcom_spmi-regulator.c index 84cce21e98cd..fe09407b150b 100644 --- a/drivers/regulator/qcom_spmi-regulator.c +++ b/drivers/regulator/qcom_spmi-regulator.c @@ -1496,6 +1496,7 @@ static const struct spmi_regulator_data pm8941_regulators[] = { { "s1", 0x1400, "vdd_s1", }, { "s2", 0x1700, "vdd_s2", }, { "s3", 0x1a00, "vdd_s3", }, + { "s4", 0xa000, }, { "l1", 0x4000, "vdd_l1_l3", }, { "l2", 0x4100, "vdd_l2_lvs_1_2_3", }, { "l3", 0x4200, "vdd_l1_l3", }, -- cgit v1.2.3 From 93bfe79b03365f410aa91caf04263173c008ecdf Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Sat, 25 Jun 2016 22:52:12 -0700 Subject: regulator: qcom_spmi: Update mvs1/mvs2 switches on pm8941 The mvs1 and mvs2 switches are actually called 5vs1 and 5vs2 on some datasheets. Let's rename them to match the datasheets and also match the RPM based regulator driver which calls these by their 5vs names (see qcom_smd-regulator.c). There aren't any users of these regulators so far, so there aren't any concerns of DT ABI breakage here. While we're here making updates to the switches, also mandate usage of the OCP irq for these switches too. Cc: Bjorn Andersson Fixes: e92a4047419c ("regulator: Add QCOM SPMI regulator driver") Signed-off-by: Stephen Boyd Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/regulator/qcom,spmi-regulator.txt | 2 +- drivers/regulator/qcom_spmi-regulator.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/regulator') diff --git a/Documentation/devicetree/bindings/regulator/qcom,spmi-regulator.txt b/Documentation/devicetree/bindings/regulator/qcom,spmi-regulator.txt index 3e827bb9a56d..0fa3b0fac129 100644 --- a/Documentation/devicetree/bindings/regulator/qcom,spmi-regulator.txt +++ b/Documentation/devicetree/bindings/regulator/qcom,spmi-regulator.txt @@ -115,7 +115,7 @@ pm8916: pm8941: s1, s2, s3, s4, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, l13, l14, l15, l16, l17, l18, l19, l20, l21, l22, l23, l24, lvs1, lvs2, lvs3, - mvs1, mvs2 + 5vs1, 5vs2 pm8994: s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, l1, l2, l3, l4, l5, diff --git a/drivers/regulator/qcom_spmi-regulator.c b/drivers/regulator/qcom_spmi-regulator.c index fe09407b150b..43f8f20b82e9 100644 --- a/drivers/regulator/qcom_spmi-regulator.c +++ b/drivers/regulator/qcom_spmi-regulator.c @@ -1524,8 +1524,8 @@ static const struct spmi_regulator_data pm8941_regulators[] = { { "lvs1", 0x8000, "vdd_l2_lvs_1_2_3", }, { "lvs2", 0x8100, "vdd_l2_lvs_1_2_3", }, { "lvs3", 0x8200, "vdd_l2_lvs_1_2_3", }, - { "mvs1", 0x8300, "vin_5vs", }, - { "mvs2", 0x8400, "vin_5vs", }, + { "5vs1", 0x8300, "vin_5vs", "ocp-5vs1", }, + { "5vs2", 0x8400, "vin_5vs", "ocp-5vs2", }, { } }; -- cgit v1.2.3 From 919163f6362ac23138d31fc8befdd52e5d7e488d Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Sat, 25 Jun 2016 22:52:13 -0700 Subject: regulator: qcom_spmi: Add support for get_mode/set_mode on switches The voltage switches support mode switching, so add support for these ops to those types of regulators. Cc: Bjorn Andersson Fixes: e92a4047419c ("regulator: Add QCOM SPMI regulator driver") Signed-off-by: Stephen Boyd Signed-off-by: Mark Brown --- drivers/regulator/qcom_spmi-regulator.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/regulator') diff --git a/drivers/regulator/qcom_spmi-regulator.c b/drivers/regulator/qcom_spmi-regulator.c index 43f8f20b82e9..16c5f84e06a7 100644 --- a/drivers/regulator/qcom_spmi-regulator.c +++ b/drivers/regulator/qcom_spmi-regulator.c @@ -1085,6 +1085,8 @@ static struct regulator_ops spmi_vs_ops = { .set_pull_down = spmi_regulator_common_set_pull_down, .set_soft_start = spmi_regulator_common_set_soft_start, .set_over_current_protection = spmi_regulator_vs_ocp, + .set_mode = spmi_regulator_common_set_mode, + .get_mode = spmi_regulator_common_get_mode, }; static struct regulator_ops spmi_boost_ops = { -- cgit v1.2.3 From 3de56099591a4042556a2d05d4703387ad950c6f Mon Sep 17 00:00:00 2001 From: Russ Dill Date: Fri, 24 Jun 2016 13:58:07 +0530 Subject: regulator: tps65217: Enable suspend configuration The TPS65217 has a pre-defined power-up / power-down sequence which in a typical application does not need to be changed. However, it is possible to define custom sequences under I2C control. The power-up sequence is defined by strobes and delay times. Each output rail is assigned to a strobe to determine the order in which the rails are enabled. Every regulator of tps65217 PMIC has sequence registers and every regulator has a default strobe value and gets disabled when a particular power down sequence occurs. To keep a regulator on during suspend we write value 0 to strobe so that the regulator is out of all sequencers and is not impacted by any power down sequence. Hence saving the default strobe value during probe so that when we want to regulator to be enabled during suspend we write 0 to strobe and when we want it to get disabled during suspend we write the default saved strobe value. This allows platform data to specify which power rails should be on or off during RTC only suspend. This is necessary to keep DDR state while in RTC only suspend. Signed-off-by: Russ Dill [Enhanced commit log and added dynamic allocation for strobes] Signed-off-by: Keerthy Signed-off-by: Mark Brown --- drivers/regulator/tps65217-regulator.c | 69 +++++++++++++++++++++++++++++----- include/linux/mfd/tps65217.h | 1 + 2 files changed, 61 insertions(+), 9 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/tps65217-regulator.c b/drivers/regulator/tps65217-regulator.c index adbe4fc5cf07..2d12b9af3540 100644 --- a/drivers/regulator/tps65217-regulator.c +++ b/drivers/regulator/tps65217-regulator.c @@ -28,7 +28,7 @@ #include #define TPS65217_REGULATOR(_name, _id, _of_match, _ops, _n, _vr, _vm, _em, \ - _t, _lr, _nlr) \ + _t, _lr, _nlr, _sr, _sm) \ { \ .name = _name, \ .id = _id, \ @@ -45,6 +45,8 @@ .volt_table = _t, \ .linear_ranges = _lr, \ .n_linear_ranges = _nlr, \ + .bypass_reg = _sr, \ + .bypass_mask = _sm, \ } \ static const unsigned int LDO1_VSEL_table[] = { @@ -118,6 +120,35 @@ static int tps65217_pmic_set_voltage_sel(struct regulator_dev *dev, return ret; } +static int tps65217_pmic_set_suspend_enable(struct regulator_dev *dev) +{ + struct tps65217 *tps = rdev_get_drvdata(dev); + unsigned int rid = rdev_get_id(dev); + + if (rid < TPS65217_DCDC_1 || rid > TPS65217_LDO_4) + return -EINVAL; + + return tps65217_clear_bits(tps, dev->desc->bypass_reg, + dev->desc->bypass_mask, + TPS65217_PROTECT_L1); +} + +static int tps65217_pmic_set_suspend_disable(struct regulator_dev *dev) +{ + struct tps65217 *tps = rdev_get_drvdata(dev); + unsigned int rid = rdev_get_id(dev); + + if (rid < TPS65217_DCDC_1 || rid > TPS65217_LDO_4) + return -EINVAL; + + if (!tps->strobes[rid]) + return -EINVAL; + + return tps65217_set_bits(tps, dev->desc->bypass_reg, + dev->desc->bypass_mask, + tps->strobes[rid], TPS65217_PROTECT_L1); +} + /* Operations permitted on DCDCx, LDO2, LDO3 and LDO4 */ static struct regulator_ops tps65217_pmic_ops = { .is_enabled = regulator_is_enabled_regmap, @@ -127,6 +158,8 @@ static struct regulator_ops tps65217_pmic_ops = { .set_voltage_sel = tps65217_pmic_set_voltage_sel, .list_voltage = regulator_list_voltage_linear_range, .map_voltage = regulator_map_voltage_linear_range, + .set_suspend_enable = tps65217_pmic_set_suspend_enable, + .set_suspend_disable = tps65217_pmic_set_suspend_disable, }; /* Operations permitted on LDO1 */ @@ -138,41 +171,50 @@ static struct regulator_ops tps65217_pmic_ldo1_ops = { .set_voltage_sel = tps65217_pmic_set_voltage_sel, .list_voltage = regulator_list_voltage_table, .map_voltage = regulator_map_voltage_ascend, + .set_suspend_enable = tps65217_pmic_set_suspend_enable, + .set_suspend_disable = tps65217_pmic_set_suspend_disable, }; static const struct regulator_desc regulators[] = { TPS65217_REGULATOR("DCDC1", TPS65217_DCDC_1, "dcdc1", tps65217_pmic_ops, 64, TPS65217_REG_DEFDCDC1, TPS65217_DEFDCDCX_DCDC_MASK, TPS65217_ENABLE_DC1_EN, - NULL, tps65217_uv1_ranges, 2), + NULL, tps65217_uv1_ranges, 2, TPS65217_REG_SEQ1, + TPS65217_SEQ1_DC1_SEQ_MASK), TPS65217_REGULATOR("DCDC2", TPS65217_DCDC_2, "dcdc2", tps65217_pmic_ops, 64, TPS65217_REG_DEFDCDC2, TPS65217_DEFDCDCX_DCDC_MASK, TPS65217_ENABLE_DC2_EN, NULL, tps65217_uv1_ranges, - ARRAY_SIZE(tps65217_uv1_ranges)), + ARRAY_SIZE(tps65217_uv1_ranges), TPS65217_REG_SEQ1, + TPS65217_SEQ1_DC2_SEQ_MASK), TPS65217_REGULATOR("DCDC3", TPS65217_DCDC_3, "dcdc3", tps65217_pmic_ops, 64, TPS65217_REG_DEFDCDC3, TPS65217_DEFDCDCX_DCDC_MASK, TPS65217_ENABLE_DC3_EN, - NULL, tps65217_uv1_ranges, 1), + NULL, tps65217_uv1_ranges, 1, TPS65217_REG_SEQ2, + TPS65217_SEQ2_DC3_SEQ_MASK), TPS65217_REGULATOR("LDO1", TPS65217_LDO_1, "ldo1", tps65217_pmic_ldo1_ops, 16, TPS65217_REG_DEFLDO1, TPS65217_DEFLDO1_LDO1_MASK, TPS65217_ENABLE_LDO1_EN, - LDO1_VSEL_table, NULL, 0), + LDO1_VSEL_table, NULL, 0, TPS65217_REG_SEQ2, + TPS65217_SEQ2_LDO1_SEQ_MASK), TPS65217_REGULATOR("LDO2", TPS65217_LDO_2, "ldo2", tps65217_pmic_ops, 64, TPS65217_REG_DEFLDO2, TPS65217_DEFLDO2_LDO2_MASK, TPS65217_ENABLE_LDO2_EN, NULL, tps65217_uv1_ranges, - ARRAY_SIZE(tps65217_uv1_ranges)), + ARRAY_SIZE(tps65217_uv1_ranges), TPS65217_REG_SEQ3, + TPS65217_SEQ3_LDO2_SEQ_MASK), TPS65217_REGULATOR("LDO3", TPS65217_LDO_3, "ldo3", tps65217_pmic_ops, 32, TPS65217_REG_DEFLS1, TPS65217_DEFLDO3_LDO3_MASK, TPS65217_ENABLE_LS1_EN | TPS65217_DEFLDO3_LDO3_EN, NULL, tps65217_uv2_ranges, - ARRAY_SIZE(tps65217_uv2_ranges)), + ARRAY_SIZE(tps65217_uv2_ranges), TPS65217_REG_SEQ3, + TPS65217_SEQ3_LDO3_SEQ_MASK), TPS65217_REGULATOR("LDO4", TPS65217_LDO_4, "ldo4", tps65217_pmic_ops, 32, TPS65217_REG_DEFLS2, TPS65217_DEFLDO4_LDO4_MASK, TPS65217_ENABLE_LS2_EN | TPS65217_DEFLDO4_LDO4_EN, NULL, tps65217_uv2_ranges, - ARRAY_SIZE(tps65217_uv2_ranges)), + ARRAY_SIZE(tps65217_uv2_ranges), TPS65217_REG_SEQ4, + TPS65217_SEQ4_LDO4_SEQ_MASK), }; static int tps65217_regulator_probe(struct platform_device *pdev) @@ -181,13 +223,18 @@ static int tps65217_regulator_probe(struct platform_device *pdev) struct tps65217_board *pdata = dev_get_platdata(tps->dev); struct regulator_dev *rdev; struct regulator_config config = { }; - int i; + int i, ret; + unsigned int val; if (tps65217_chip_id(tps) != TPS65217) { dev_err(&pdev->dev, "Invalid tps chip version\n"); return -ENODEV; } + /* Allocate memory for strobes */ + tps->strobes = devm_kzalloc(&pdev->dev, sizeof(u8) * + TPS65217_NUM_REGULATOR, GFP_KERNEL); + platform_set_drvdata(pdev, tps); for (i = 0; i < TPS65217_NUM_REGULATOR; i++) { @@ -205,6 +252,10 @@ static int tps65217_regulator_probe(struct platform_device *pdev) pdev->name); return PTR_ERR(rdev); } + + /* Store default strobe info */ + ret = tps65217_reg_read(tps, regulators[i].bypass_reg, &val); + tps->strobes[i] = val & regulators[i].bypass_mask; } return 0; diff --git a/include/linux/mfd/tps65217.h b/include/linux/mfd/tps65217.h index ac7fba44d7e4..1c88231496d3 100644 --- a/include/linux/mfd/tps65217.h +++ b/include/linux/mfd/tps65217.h @@ -257,6 +257,7 @@ struct tps65217 { unsigned long id; struct regulator_desc desc[TPS65217_NUM_REGULATOR]; struct regmap *regmap; + u8 *strobes; }; static inline struct tps65217 *dev_to_tps65217(struct device *dev) -- cgit v1.2.3 From b9a0d359413d7f4e078d81cd59f9d851a6febb7a Mon Sep 17 00:00:00 2001 From: Tero Kristo Date: Fri, 24 Jun 2016 13:58:08 +0530 Subject: regulator: tps65218: Enable suspend configuration TPS65218 has a pre-defined power-up / power-down sequence which in a typical application does not need to be changed. However, it is possible to define custom sequences under I2C control. The power-up sequence is defined by strobes and delay times. Each output rail is assigned to a strobe to determine the order in which the rails are enabled. Every regulator has sequence registers and every regulator has a default strobe value and gets disabled when a particular power down sequence occurs. To keep a regulator on during suspend we write value 0 to strobe so that the regulator is out of all sequencers and is not impacted by any power down sequence. Hence saving the default strobe value during probe so that when we want to regulator to be enabled during suspend we write 0 to strobe and when we want it to get disabled during suspend we write the default saved strobe value. This allows platform data to specify which power rails should be on or off during RTC only suspend. This is necessary to keep DDR state while in RTC only suspend. Signed-off-by: Tero Kristo Signed-off-by: Keerthy Signed-off-by: Mark Brown --- drivers/regulator/tps65218-regulator.c | 72 ++++++++++++++++++++++++++++------ include/linux/mfd/tps65218.h | 2 + 2 files changed, 63 insertions(+), 11 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/tps65218-regulator.c b/drivers/regulator/tps65218-regulator.c index a5e5634eeb9e..8eca1eb4f219 100644 --- a/drivers/regulator/tps65218-regulator.c +++ b/drivers/regulator/tps65218-regulator.c @@ -31,7 +31,7 @@ enum tps65218_regulators { DCDC1, DCDC2, DCDC3, DCDC4, DCDC5, DCDC6, LDO1, LS3 }; #define TPS65218_REGULATOR(_name, _id, _type, _ops, _n, _vr, _vm, _er, _em, \ - _cr, _cm, _lr, _nlr, _delay, _fuv) \ + _cr, _cm, _lr, _nlr, _delay, _fuv, _sr, _sm) \ { \ .name = _name, \ .id = _id, \ @@ -49,7 +49,9 @@ enum tps65218_regulators { DCDC1, DCDC2, DCDC3, DCDC4, .linear_ranges = _lr, \ .n_linear_ranges = _nlr, \ .ramp_delay = _delay, \ - .fixed_uV = _fuv \ + .fixed_uV = _fuv, \ + .bypass_reg = _sr, \ + .bypass_mask = _sm, \ } \ #define TPS65218_INFO(_id, _nm, _min, _max) \ @@ -157,6 +159,36 @@ static int tps65218_pmic_disable(struct regulator_dev *dev) dev->desc->enable_mask, TPS65218_PROTECT_L1); } +static int tps65218_pmic_set_suspend_enable(struct regulator_dev *dev) +{ + struct tps65218 *tps = rdev_get_drvdata(dev); + unsigned int rid = rdev_get_id(dev); + + if (rid < TPS65218_DCDC_1 || rid > TPS65218_LDO_1) + return -EINVAL; + + return tps65218_clear_bits(tps, dev->desc->bypass_reg, + dev->desc->bypass_mask, + TPS65218_PROTECT_L1); +} + +static int tps65218_pmic_set_suspend_disable(struct regulator_dev *dev) +{ + struct tps65218 *tps = rdev_get_drvdata(dev); + unsigned int rid = rdev_get_id(dev); + + if (rid < TPS65218_DCDC_1 || rid > TPS65218_LDO_1) + return -EINVAL; + + if (!tps->info[rid]->strobe) + return -EINVAL; + + return tps65218_set_bits(tps, dev->desc->bypass_reg, + dev->desc->bypass_mask, + tps->info[rid]->strobe, + TPS65218_PROTECT_L1); +} + /* Operations permitted on DCDC1, DCDC2 */ static struct regulator_ops tps65218_dcdc12_ops = { .is_enabled = regulator_is_enabled_regmap, @@ -167,6 +199,8 @@ static struct regulator_ops tps65218_dcdc12_ops = { .list_voltage = regulator_list_voltage_linear_range, .map_voltage = regulator_map_voltage_linear_range, .set_voltage_time_sel = regulator_set_voltage_time_sel, + .set_suspend_enable = tps65218_pmic_set_suspend_enable, + .set_suspend_disable = tps65218_pmic_set_suspend_disable, }; /* Operations permitted on DCDC3, DCDC4 and LDO1 */ @@ -178,6 +212,8 @@ static struct regulator_ops tps65218_ldo1_dcdc34_ops = { .set_voltage_sel = tps65218_pmic_set_voltage_sel, .list_voltage = regulator_list_voltage_linear_range, .map_voltage = regulator_map_voltage_linear_range, + .set_suspend_enable = tps65218_pmic_set_suspend_enable, + .set_suspend_disable = tps65218_pmic_set_suspend_disable, }; static const int ls3_currents[] = { 100, 200, 500, 1000 }; @@ -247,6 +283,8 @@ static struct regulator_ops tps65218_dcdc56_pmic_ops = { .is_enabled = regulator_is_enabled_regmap, .enable = tps65218_pmic_enable, .disable = tps65218_pmic_disable, + .set_suspend_enable = tps65218_pmic_set_suspend_enable, + .set_suspend_disable = tps65218_pmic_set_suspend_disable, }; static const struct regulator_desc regulators[] = { @@ -254,42 +292,47 @@ static const struct regulator_desc regulators[] = { tps65218_dcdc12_ops, 64, TPS65218_REG_CONTROL_DCDC1, TPS65218_CONTROL_DCDC1_MASK, TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC1_EN, 0, 0, dcdc1_dcdc2_ranges, - 2, 4000, 0), + 2, 4000, 0, TPS65218_REG_SEQ3, + TPS65218_SEQ3_DC1_SEQ_MASK), TPS65218_REGULATOR("DCDC2", TPS65218_DCDC_2, REGULATOR_VOLTAGE, tps65218_dcdc12_ops, 64, TPS65218_REG_CONTROL_DCDC2, TPS65218_CONTROL_DCDC2_MASK, TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC2_EN, 0, 0, dcdc1_dcdc2_ranges, - 2, 4000, 0), + 2, 4000, 0, TPS65218_REG_SEQ3, + TPS65218_SEQ3_DC2_SEQ_MASK), TPS65218_REGULATOR("DCDC3", TPS65218_DCDC_3, REGULATOR_VOLTAGE, tps65218_ldo1_dcdc34_ops, 64, TPS65218_REG_CONTROL_DCDC3, TPS65218_CONTROL_DCDC3_MASK, TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC3_EN, 0, 0, ldo1_dcdc3_ranges, 2, - 0, 0), + 0, 0, TPS65218_REG_SEQ4, TPS65218_SEQ4_DC3_SEQ_MASK), TPS65218_REGULATOR("DCDC4", TPS65218_DCDC_4, REGULATOR_VOLTAGE, tps65218_ldo1_dcdc34_ops, 53, TPS65218_REG_CONTROL_DCDC4, TPS65218_CONTROL_DCDC4_MASK, TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC4_EN, 0, 0, dcdc4_ranges, 2, - 0, 0), + 0, 0, TPS65218_REG_SEQ4, TPS65218_SEQ4_DC4_SEQ_MASK), TPS65218_REGULATOR("DCDC5", TPS65218_DCDC_5, REGULATOR_VOLTAGE, tps65218_dcdc56_pmic_ops, 1, -1, -1, TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC5_EN, 0, 0, - NULL, 0, 0, 1000000), + NULL, 0, 0, 1000000, TPS65218_REG_SEQ5, + TPS65218_SEQ5_DC5_SEQ_MASK), TPS65218_REGULATOR("DCDC6", TPS65218_DCDC_6, REGULATOR_VOLTAGE, tps65218_dcdc56_pmic_ops, 1, -1, -1, TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC6_EN, 0, 0, - NULL, 0, 0, 1800000), + NULL, 0, 0, 1800000, TPS65218_REG_SEQ5, + TPS65218_SEQ5_DC6_SEQ_MASK), TPS65218_REGULATOR("LDO1", TPS65218_LDO_1, REGULATOR_VOLTAGE, tps65218_ldo1_dcdc34_ops, 64, TPS65218_REG_CONTROL_LDO1, TPS65218_CONTROL_LDO1_MASK, TPS65218_REG_ENABLE2, TPS65218_ENABLE2_LDO1_EN, 0, 0, ldo1_dcdc3_ranges, - 2, 0, 0), + 2, 0, 0, TPS65218_REG_SEQ6, + TPS65218_SEQ6_LDO1_SEQ_MASK), TPS65218_REGULATOR("LS3", TPS65218_LS_3, REGULATOR_CURRENT, tps65218_ls3_ops, 0, 0, 0, TPS65218_REG_ENABLE2, TPS65218_ENABLE2_LS3_EN, TPS65218_REG_CONFIG2, - TPS65218_CONFIG2_LS3ILIM_MASK, NULL, 0, 0, 0), + TPS65218_CONFIG2_LS3ILIM_MASK, NULL, 0, 0, 0, 0, 0), }; static int tps65218_regulator_probe(struct platform_device *pdev) @@ -300,7 +343,8 @@ static int tps65218_regulator_probe(struct platform_device *pdev) struct regulator_dev *rdev; const struct of_device_id *match; struct regulator_config config = { }; - int id; + int id, ret; + unsigned int val; match = of_match_device(tps65218_of_match, &pdev->dev); if (!match) @@ -327,6 +371,12 @@ static int tps65218_regulator_probe(struct platform_device *pdev) return PTR_ERR(rdev); } + ret = tps65218_reg_read(tps, regulators[id].bypass_reg, &val); + if (ret) + return ret; + + tps->info[id]->strobe = val & regulators[id].bypass_mask; + return 0; } diff --git a/include/linux/mfd/tps65218.h b/include/linux/mfd/tps65218.h index d58f3b5f585a..7fdf5326f34e 100644 --- a/include/linux/mfd/tps65218.h +++ b/include/linux/mfd/tps65218.h @@ -246,6 +246,7 @@ enum tps65218_irqs { * @name: Voltage regulator name * @min_uV: minimum micro volts * @max_uV: minimum micro volts + * @strobe: sequencing strobe value for the regulator * * This data is used to check the regualtor voltage limits while setting. */ @@ -254,6 +255,7 @@ struct tps_info { const char *name; int min_uV; int max_uV; + int strobe; }; /** -- cgit v1.2.3 From 3fb2ef111d6f799f3da8860c1a90ef3d9c36ea55 Mon Sep 17 00:00:00 2001 From: Tero Kristo Date: Fri, 24 Jun 2016 13:58:09 +0530 Subject: regulator: tps65218: force set power-up/down strobe to 3 for dcdc3 The reset value for this register seems broken on certain versions of tps65218 chip, so make sure the dcdc3 settings is proper. Needed for proper functionality of rtc+ddr / rtc-only modes. Signed-off-by: Tero Kristo Signed-off-by: Dave Gerlach Signed-off-by: Keerthy Signed-off-by: Mark Brown --- drivers/regulator/tps65218-regulator.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/tps65218-regulator.c b/drivers/regulator/tps65218-regulator.c index 8eca1eb4f219..d1e631d64a20 100644 --- a/drivers/regulator/tps65218-regulator.c +++ b/drivers/regulator/tps65218-regulator.c @@ -180,8 +180,12 @@ static int tps65218_pmic_set_suspend_disable(struct regulator_dev *dev) if (rid < TPS65218_DCDC_1 || rid > TPS65218_LDO_1) return -EINVAL; - if (!tps->info[rid]->strobe) - return -EINVAL; + if (!tps->info[rid]->strobe) { + if (rid == TPS65218_DCDC_3) + tps->info[rid]->strobe = 3; + else + return -EINVAL; + } return tps65218_set_bits(tps, dev->desc->bypass_reg, dev->desc->bypass_mask, -- cgit v1.2.3 From ed6d362d8dbc3494cd98cd771737ea8b1407ed61 Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Tue, 28 Jun 2016 22:53:20 -0700 Subject: regulator: rn5t618: Add RN5T567 PMIC support Extend the driver to support Ricoh RN5T567. Support the additional DCDC and slightly different voltage range of LDORTC1. Signed-off-by: Stefan Agner Reviewed-by: Marcel Ziswiler Acked-by: Mark Brown Signed-off-by: Lee Jones --- drivers/regulator/Kconfig | 5 +++-- drivers/regulator/rn5t618-regulator.c | 40 +++++++++++++++++++++++++++++++---- include/linux/mfd/rn5t618.h | 1 + 3 files changed, 40 insertions(+), 6 deletions(-) (limited to 'drivers/regulator') diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 144cbf5b3e5a..547269416950 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -636,10 +636,11 @@ config REGULATOR_RK808 outputs which can be controlled by i2c communication. config REGULATOR_RN5T618 - tristate "Ricoh RN5T618 voltage regulators" + tristate "Ricoh RN5T567/618 voltage regulators" depends on MFD_RN5T618 help - Say y here to support the regulators found on Ricoh RN5T618 PMIC. + Say y here to support the regulators found on Ricoh RN5T567 or + RN5T618 PMIC. config REGULATOR_RT5033 tristate "Richtek RT5033 Regulators" diff --git a/drivers/regulator/rn5t618-regulator.c b/drivers/regulator/rn5t618-regulator.c index b85ceb8ff911..9c930eb68cda 100644 --- a/drivers/regulator/rn5t618-regulator.c +++ b/drivers/regulator/rn5t618-regulator.c @@ -46,6 +46,23 @@ static struct regulator_ops rn5t618_reg_ops = { .vsel_mask = (vmask), \ } +static struct regulator_desc rn5t567_regulators[] = { + /* DCDC */ + REG(DCDC1, DC1CTL, BIT(0), DC1DAC, 0xff, 600000, 3500000, 12500), + REG(DCDC2, DC2CTL, BIT(0), DC2DAC, 0xff, 600000, 3500000, 12500), + REG(DCDC3, DC3CTL, BIT(0), DC3DAC, 0xff, 600000, 3500000, 12500), + REG(DCDC4, DC4CTL, BIT(0), DC4DAC, 0xff, 600000, 3500000, 12500), + /* LDO */ + REG(LDO1, LDOEN1, BIT(0), LDO1DAC, 0x7f, 900000, 3500000, 25000), + REG(LDO2, LDOEN1, BIT(1), LDO2DAC, 0x7f, 900000, 3500000, 25000), + REG(LDO3, LDOEN1, BIT(2), LDO3DAC, 0x7f, 600000, 3500000, 25000), + REG(LDO4, LDOEN1, BIT(3), LDO4DAC, 0x7f, 900000, 3500000, 25000), + REG(LDO5, LDOEN1, BIT(4), LDO5DAC, 0x7f, 900000, 3500000, 25000), + /* LDO RTC */ + REG(LDORTC1, LDOEN2, BIT(4), LDORTCDAC, 0x7f, 1200000, 3500000, 25000), + REG(LDORTC2, LDOEN2, BIT(5), LDORTC2DAC, 0x7f, 900000, 3500000, 25000), +}; + static struct regulator_desc rn5t618_regulators[] = { /* DCDC */ REG(DCDC1, DC1CTL, BIT(0), DC1DAC, 0xff, 600000, 3500000, 12500), @@ -67,18 +84,33 @@ static int rn5t618_regulator_probe(struct platform_device *pdev) struct rn5t618 *rn5t618 = dev_get_drvdata(pdev->dev.parent); struct regulator_config config = { }; struct regulator_dev *rdev; + struct regulator_desc *regulators; int i; + switch (rn5t618->variant) { + case RN5T567: + regulators = rn5t567_regulators; + break; + case RN5T618: + regulators = rn5t618_regulators; + break; + default: + return -EINVAL; + } + + config.dev = pdev->dev.parent; + config.regmap = rn5t618->regmap; + for (i = 0; i < RN5T618_REG_NUM; i++) { - config.dev = pdev->dev.parent; - config.regmap = rn5t618->regmap; + if (!regulators[i].name) + continue; rdev = devm_regulator_register(&pdev->dev, - &rn5t618_regulators[i], + ®ulators[i], &config); if (IS_ERR(rdev)) { dev_err(&pdev->dev, "failed to register %s regulator\n", - rn5t618_regulators[i].name); + regulators[i].name); return PTR_ERR(rdev); } } diff --git a/include/linux/mfd/rn5t618.h b/include/linux/mfd/rn5t618.h index 54179c2577ae..cadc6543909d 100644 --- a/include/linux/mfd/rn5t618.h +++ b/include/linux/mfd/rn5t618.h @@ -217,6 +217,7 @@ enum { RN5T618_DCDC1, RN5T618_DCDC2, RN5T618_DCDC3, + RN5T618_DCDC4, RN5T618_LDO1, RN5T618_LDO2, RN5T618_LDO3, -- cgit v1.2.3