From 69d588392b057c0cedb1ba58d7973b77a65997ec Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Wed, 4 Jun 2014 14:53:25 -0500 Subject: regulator: core: print error value when constraints are not applied With commit 064d5cd110f94ce41ca5681dcda8b77fa63d5b95 (regulator: core: Fix the init of DT defined fixed regulators) We ensure that regulator must be capable of providing it's current voltage when constraints are used, however adding the return value in the print is a little more informative to explain the nature of the failure involved. So, instead of providing message such as: smps9: failed to get the current voltage having error value added to the message such as: smps9: failed to get the current voltage(-22) is a little more informative for debugging the error. Signed-off-by: Nishanth Menon Signed-off-by: Mark Brown --- drivers/regulator/core.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 4c1f999041dd..b4902ab64abe 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -846,7 +846,9 @@ static int machine_constraints_voltage(struct regulator_dev *rdev, rdev->constraints->min_uV == rdev->constraints->max_uV) { int current_uV = _regulator_get_voltage(rdev); if (current_uV < 0) { - rdev_err(rdev, "failed to get the current voltage\n"); + rdev_err(rdev, + "failed to get the current voltage(%d)\n", + current_uV); return current_uV; } if (current_uV < rdev->constraints->min_uV || @@ -856,8 +858,8 @@ static int machine_constraints_voltage(struct regulator_dev *rdev, rdev->constraints->max_uV); if (ret < 0) { rdev_err(rdev, - "failed to apply %duV constraint\n", - rdev->constraints->min_uV); + "failed to apply %duV constraint(%d)\n", + rdev->constraints->min_uV, ret); return ret; } } -- cgit v1.2.2 From c969faadf02076641a81197f2e8641c40d232edd Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Mon, 2 Jun 2014 15:27:21 +0900 Subject: regulator: bcm590xx: remove unnecessary OOM messages The site-specific OOM messages are unnecessary, because they duplicate the MM subsystem generic OOM message. Signed-off-by: Jingoo Han Acked-by: Matt Porter Signed-off-by: Mark Brown --- drivers/regulator/bcm590xx-regulator.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/bcm590xx-regulator.c b/drivers/regulator/bcm590xx-regulator.c index c3750c5b382b..6ac27701ff83 100644 --- a/drivers/regulator/bcm590xx-regulator.c +++ b/drivers/regulator/bcm590xx-regulator.c @@ -263,10 +263,8 @@ static struct bcm590xx_board *bcm590xx_parse_dt_reg_data( } data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); - if (!data) { - dev_err(&pdev->dev, "failed to allocate regulator board data\n"); + if (!data) return NULL; - } np = of_node_get(np); regulators = of_get_child_by_name(np, "regulators"); @@ -311,10 +309,8 @@ static int bcm590xx_probe(struct platform_device *pdev) &bcm590xx_reg_matches); pmu = devm_kzalloc(&pdev->dev, sizeof(*pmu), GFP_KERNEL); - if (!pmu) { - dev_err(&pdev->dev, "Memory allocation failed for pmu\n"); + if (!pmu) return -ENOMEM; - } pmu->mfd = bcm590xx; @@ -322,17 +318,13 @@ static int bcm590xx_probe(struct platform_device *pdev) pmu->desc = devm_kzalloc(&pdev->dev, BCM590XX_NUM_REGS * sizeof(struct regulator_desc), GFP_KERNEL); - if (!pmu->desc) { - dev_err(&pdev->dev, "Memory alloc fails for desc\n"); + if (!pmu->desc) return -ENOMEM; - } pmu->info = devm_kzalloc(&pdev->dev, BCM590XX_NUM_REGS * sizeof(struct bcm590xx_info *), GFP_KERNEL); - if (!pmu->info) { - dev_err(&pdev->dev, "Memory alloc fails for info\n"); + if (!pmu->info) return -ENOMEM; - } info = bcm590xx_regs; -- cgit v1.2.2 From 2628b10070c5a934a977f20831d97778034b39af Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 4 Jun 2014 20:44:03 +0800 Subject: regulator: tps6586x: Use regulator_list_voltage_linear for dvm/ldo4/sw2 The voltage tables for dvm/ldo4/sw2 are actually linear mapping. Thus convert dvm/ldo4/sw2 to use regulator_list_voltage_linear. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/tps6586x-regulator.c | 129 +++++++++++++++++---------------- 1 file changed, 68 insertions(+), 61 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/tps6586x-regulator.c b/drivers/regulator/tps6586x-regulator.c index 0a3bb3aecd97..ccbb9f150b4e 100644 --- a/drivers/regulator/tps6586x-regulator.c +++ b/drivers/regulator/tps6586x-regulator.c @@ -74,6 +74,16 @@ static struct regulator_ops tps6586x_rw_regulator_ops = { .disable = regulator_disable_regmap, }; +static struct regulator_ops tps6586x_rw_linear_regulator_ops = { + .list_voltage = regulator_list_voltage_linear, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + + .is_enabled = regulator_is_enabled_regmap, + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, +}; + static struct regulator_ops tps6586x_ro_regulator_ops = { .list_voltage = regulator_list_voltage_table, .map_voltage = regulator_map_voltage_ascend, @@ -91,48 +101,11 @@ static const unsigned int tps6586x_ldo0_voltages[] = { 1200000, 1500000, 1800000, 2500000, 2700000, 2850000, 3100000, 3300000, }; -static const unsigned int tps6586x_ldo4_voltages[] = { - 1700000, 1725000, 1750000, 1775000, 1800000, 1825000, 1850000, 1875000, - 1900000, 1925000, 1950000, 1975000, 2000000, 2025000, 2050000, 2075000, - 2100000, 2125000, 2150000, 2175000, 2200000, 2225000, 2250000, 2275000, - 2300000, 2325000, 2350000, 2375000, 2400000, 2425000, 2450000, 2475000, -}; - -#define tps658623_sm2_voltages tps6586x_ldo4_voltages - static const unsigned int tps6586x_ldo_voltages[] = { 1250000, 1500000, 1800000, 2500000, 2700000, 2850000, 3100000, 3300000, }; -static const unsigned int tps6586x_sm2_voltages[] = { - 3000000, 3050000, 3100000, 3150000, 3200000, 3250000, 3300000, 3350000, - 3400000, 3450000, 3500000, 3550000, 3600000, 3650000, 3700000, 3750000, - 3800000, 3850000, 3900000, 3950000, 4000000, 4050000, 4100000, 4150000, - 4200000, 4250000, 4300000, 4350000, 4400000, 4450000, 4500000, 4550000, -}; - -static int tps658640_sm2_voltages[] = { - 2150000, 2200000, 2250000, 2300000, 2350000, 2400000, 2450000, 2500000, - 2550000, 2600000, 2650000, 2700000, 2750000, 2800000, 2850000, 2900000, - 2950000, 3000000, 3050000, 3100000, 3150000, 3200000, 3250000, 3300000, - 3350000, 3400000, 3450000, 3500000, 3550000, 3600000, 3650000, 3700000, -}; - -static const unsigned int tps658643_sm2_voltages[] = { - 1025000, 1050000, 1075000, 1100000, 1125000, 1150000, 1175000, 1200000, - 1225000, 1250000, 1275000, 1300000, 1325000, 1350000, 1375000, 1400000, - 1425000, 1450000, 1475000, 1500000, 1525000, 1550000, 1575000, 1600000, - 1625000, 1650000, 1675000, 1700000, 1725000, 1750000, 1775000, 1800000, -}; - -static const unsigned int tps6586x_dvm_voltages[] = { - 725000, 750000, 775000, 800000, 825000, 850000, 875000, 900000, - 925000, 950000, 975000, 1000000, 1025000, 1050000, 1075000, 1100000, - 1125000, 1150000, 1175000, 1200000, 1225000, 1250000, 1275000, 1300000, - 1325000, 1350000, 1375000, 1400000, 1425000, 1450000, 1475000, 1500000, -}; - -static int tps658640_rtc_voltages[] = { +static const unsigned int tps658640_rtc_voltages[] = { 2500000, 2850000, 3100000, 3300000, }; @@ -159,6 +132,31 @@ static int tps658640_rtc_voltages[] = { .enable_reg[1] = TPS6586X_SUPPLY##ereg1, \ .enable_bit[1] = (ebit1), +#define TPS6586X_REGULATOR_LINEAR(_id, _ops, _pin_name, n_volt, min_uv, \ + uv_step, vreg, shift, nbits, ereg0, \ + ebit0, ereg1, ebit1, goreg, gobit) \ + .desc = { \ + .supply_name = _pin_name, \ + .name = "REG-" #_id, \ + .ops = &tps6586x_## _ops ## _regulator_ops, \ + .type = REGULATOR_VOLTAGE, \ + .id = TPS6586X_ID_##_id, \ + .n_voltages = n_volt, \ + .min_uV = min_uv, \ + .uV_step = uv_step, \ + .owner = THIS_MODULE, \ + .enable_reg = TPS6586X_SUPPLY##ereg0, \ + .enable_mask = 1 << (ebit0), \ + .vsel_reg = TPS6586X_##vreg, \ + .vsel_mask = ((1 << (nbits)) - 1) << (shift), \ + .apply_reg = (goreg), \ + .apply_bit = (gobit), \ + }, \ + .enable_reg[0] = TPS6586X_SUPPLY##ereg0, \ + .enable_bit[0] = (ebit0), \ + .enable_reg[1] = TPS6586X_SUPPLY##ereg1, \ + .enable_bit[1] = (ebit1), + #define TPS6586X_LDO(_id, _pname, vdata, vreg, shift, nbits, \ ereg0, ebit0, ereg1, ebit1) \ { \ @@ -166,6 +164,14 @@ static int tps658640_rtc_voltages[] = { ereg0, ebit0, ereg1, ebit1, 0, 0) \ } +#define TPS6586X_LDO_LINEAR(_id, _pname, n_volt, min_uv, uv_step, vreg, \ + shift, nbits, ereg0, ebit0, ereg1, ebit1) \ +{ \ + TPS6586X_REGULATOR_LINEAR(_id, rw_linear, _pname, n_volt, \ + min_uv, uv_step, vreg, shift, nbits, \ + ereg0, ebit0, ereg1, ebit1, 0, 0) \ +} + #define TPS6586X_FIXED_LDO(_id, _pname, vdata, vreg, shift, nbits, \ ereg0, ebit0, ereg1, ebit1) \ { \ @@ -173,11 +179,13 @@ static int tps658640_rtc_voltages[] = { ereg0, ebit0, ereg1, ebit1, 0, 0) \ } -#define TPS6586X_DVM(_id, _pname, vdata, vreg, shift, nbits, \ - ereg0, ebit0, ereg1, ebit1, goreg, gobit) \ +#define TPS6586X_DVM(_id, _pname, n_volt, min_uv, uv_step, vreg, shift, \ + nbits, ereg0, ebit0, ereg1, ebit1, goreg, gobit) \ { \ - TPS6586X_REGULATOR(_id, rw, _pname, vdata, vreg, shift, nbits, \ - ereg0, ebit0, ereg1, ebit1, goreg, gobit) \ + TPS6586X_REGULATOR_LINEAR(_id, rw_linear, _pname, n_volt, \ + min_uv, uv_step, vreg, shift, nbits, \ + ereg0, ebit0, ereg1, ebit1, goreg, \ + gobit) \ } #define TPS6586X_SYS_REGULATOR() \ @@ -210,24 +218,23 @@ static struct tps6586x_regulator tps6586x_regulator[] = { ENE, 7), TPS6586X_LDO(LDO_RTC, "REG-SYS", tps6586x_ldo, SUPPLYV4, 3, 3, V4, 7, V4, 7), - TPS6586X_LDO(LDO_1, "vinldo01", tps6586x_dvm, SUPPLYV1, 0, 5, ENC, 1, - END, 1), - TPS6586X_LDO(SM_2, "vin-sm2", tps6586x_sm2, SUPPLYV2, 0, 5, ENC, 7, - END, 7), - - TPS6586X_DVM(LDO_2, "vinldo23", tps6586x_dvm, LDO2BV1, 0, 5, ENA, 3, - ENB, 3, TPS6586X_VCC2, BIT(6)), - TPS6586X_DVM(LDO_4, "vinldo4", tps6586x_ldo4, LDO4V1, 0, 5, ENC, 3, - END, 3, TPS6586X_VCC1, BIT(6)), - TPS6586X_DVM(SM_0, "vin-sm0", tps6586x_dvm, SM0V1, 0, 5, ENA, 1, - ENB, 1, TPS6586X_VCC1, BIT(2)), - TPS6586X_DVM(SM_1, "vin-sm1", tps6586x_dvm, SM1V1, 0, 5, ENA, 0, - ENB, 0, TPS6586X_VCC1, BIT(0)), + TPS6586X_LDO_LINEAR(LDO_1, "vinldo01", 32, 725000, 25000, SUPPLYV1, + 0, 5, ENC, 1, END, 1), + TPS6586X_LDO_LINEAR(SM_2, "vin-sm2", 32, 3000000, 50000, SUPPLYV2, + 0, 5, ENC, 7, END, 7), + TPS6586X_DVM(LDO_2, "vinldo23", 32, 725000, 25000, LDO2BV1, 0, 5, + ENA, 3, ENB, 3, TPS6586X_VCC2, BIT(6)), + TPS6586X_DVM(LDO_4, "vinldo4", 32, 1700000, 25000, LDO4V1, 0, 5, + ENC, 3, END, 3, TPS6586X_VCC1, BIT(6)), + TPS6586X_DVM(SM_0, "vin-sm0", 32, 725000, 25000, SM0V1, 0, 5, + ENA, 1, ENB, 1, TPS6586X_VCC1, BIT(2)), + TPS6586X_DVM(SM_1, "vin-sm1", 32, 725000, 25000, SM1V1, 0, 5, + ENA, 0, ENB, 0, TPS6586X_VCC1, BIT(0)), }; static struct tps6586x_regulator tps658623_regulator[] = { - TPS6586X_LDO(SM_2, "vin-sm2", tps658623_sm2, SUPPLYV2, 0, 5, ENC, 7, - END, 7), + TPS6586X_LDO_LINEAR(SM_2, "vin-sm2", 32, 1700000, 25000, SUPPLYV2, + 0, 5, ENC, 7, END, 7), }; static struct tps6586x_regulator tps658640_regulator[] = { @@ -243,16 +250,16 @@ static struct tps6586x_regulator tps658640_regulator[] = { ENC, 6, END, 6), TPS6586X_LDO(LDO_9, "vinldo9", tps6586x_ldo0, SUPPLYV6, 3, 3, ENE, 7, ENE, 7), - TPS6586X_LDO(SM_2, "vin-sm2", tps658640_sm2, SUPPLYV2, 0, 5, - ENC, 7, END, 7), + TPS6586X_LDO_LINEAR(SM_2, "vin-sm2", 32, 2150000, 50000, SUPPLYV2, + 0, 5, ENC, 7, END, 7), TPS6586X_FIXED_LDO(LDO_RTC, "REG-SYS", tps658640_rtc, SUPPLYV4, 3, 2, V4, 7, V4, 7), }; static struct tps6586x_regulator tps658643_regulator[] = { - TPS6586X_LDO(SM_2, "vin-sm2", tps658643_sm2, SUPPLYV2, 0, 5, ENC, 7, - END, 7), + TPS6586X_LDO_LINEAR(SM_2, "vin-sm2", 32, 1025000, 25000, SUPPLYV2, + 0, 5, ENC, 7, END, 7), }; /* -- cgit v1.2.2 From 3865e11d7b28ae9cf7defb7a6717499f596f30eb Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Sun, 8 Jun 2014 15:26:28 +0400 Subject: regulator: mc13xxx: Remove unused field "hi_bit" Field "hi_bit" is not used anywhere in the driver. This patch removes this excess field. Signed-off-by: Alexander Shiyan Signed-off-by: Mark Brown --- drivers/regulator/mc13xxx.h | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/regulator/mc13xxx.h b/drivers/regulator/mc13xxx.h index 06c8903f182a..2ab9bfd93b4e 100644 --- a/drivers/regulator/mc13xxx.h +++ b/drivers/regulator/mc13xxx.h @@ -21,7 +21,6 @@ struct mc13xxx_regulator { int vsel_reg; int vsel_shift; int vsel_mask; - int hi_bit; }; struct mc13xxx_regulator_priv { -- cgit v1.2.2 From 7dd33c1d57b057c3b8eda8effa72667ec798a814 Mon Sep 17 00:00:00 2001 From: Alexander Shiyan Date: Sun, 8 Jun 2014 15:26:29 +0400 Subject: regulator: mc13xxx: Remove unnecessary locks Read-modify-write sequence is already protected by regmap, so no additional locks need. This patch remove such locks from mc13xxx regulator driver. Signed-off-by: Alexander Shiyan Signed-off-by: Mark Brown --- drivers/regulator/mc13xxx-regulator-core.c | 37 +++++++----------------------- 1 file changed, 8 insertions(+), 29 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/mc13xxx-regulator-core.c b/drivers/regulator/mc13xxx-regulator-core.c index 05b971726ffa..afba024953e1 100644 --- a/drivers/regulator/mc13xxx-regulator-core.c +++ b/drivers/regulator/mc13xxx-regulator-core.c @@ -33,17 +33,12 @@ static int mc13xxx_regulator_enable(struct regulator_dev *rdev) struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators; int id = rdev_get_id(rdev); - int ret; dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id); - mc13xxx_lock(priv->mc13xxx); - ret = mc13xxx_reg_rmw(priv->mc13xxx, mc13xxx_regulators[id].reg, - mc13xxx_regulators[id].enable_bit, - mc13xxx_regulators[id].enable_bit); - mc13xxx_unlock(priv->mc13xxx); - - return ret; + return mc13xxx_reg_rmw(priv->mc13xxx, mc13xxx_regulators[id].reg, + mc13xxx_regulators[id].enable_bit, + mc13xxx_regulators[id].enable_bit); } static int mc13xxx_regulator_disable(struct regulator_dev *rdev) @@ -51,16 +46,11 @@ static int mc13xxx_regulator_disable(struct regulator_dev *rdev) struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators; int id = rdev_get_id(rdev); - int ret; dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id); - mc13xxx_lock(priv->mc13xxx); - ret = mc13xxx_reg_rmw(priv->mc13xxx, mc13xxx_regulators[id].reg, - mc13xxx_regulators[id].enable_bit, 0); - mc13xxx_unlock(priv->mc13xxx); - - return ret; + return mc13xxx_reg_rmw(priv->mc13xxx, mc13xxx_regulators[id].reg, + mc13xxx_regulators[id].enable_bit, 0); } static int mc13xxx_regulator_is_enabled(struct regulator_dev *rdev) @@ -70,10 +60,7 @@ static int mc13xxx_regulator_is_enabled(struct regulator_dev *rdev) int ret, id = rdev_get_id(rdev); unsigned int val; - mc13xxx_lock(priv->mc13xxx); ret = mc13xxx_reg_read(priv->mc13xxx, mc13xxx_regulators[id].reg, &val); - mc13xxx_unlock(priv->mc13xxx); - if (ret) return ret; @@ -86,15 +73,10 @@ static int mc13xxx_regulator_set_voltage_sel(struct regulator_dev *rdev, struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators; int id = rdev_get_id(rdev); - int ret; - mc13xxx_lock(priv->mc13xxx); - ret = mc13xxx_reg_rmw(priv->mc13xxx, mc13xxx_regulators[id].vsel_reg, - mc13xxx_regulators[id].vsel_mask, - selector << mc13xxx_regulators[id].vsel_shift); - mc13xxx_unlock(priv->mc13xxx); - - return ret; + return mc13xxx_reg_rmw(priv->mc13xxx, mc13xxx_regulators[id].vsel_reg, + mc13xxx_regulators[id].vsel_mask, + selector << mc13xxx_regulators[id].vsel_shift); } static int mc13xxx_regulator_get_voltage(struct regulator_dev *rdev) @@ -106,11 +88,8 @@ static int mc13xxx_regulator_get_voltage(struct regulator_dev *rdev) dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id); - mc13xxx_lock(priv->mc13xxx); ret = mc13xxx_reg_read(priv->mc13xxx, mc13xxx_regulators[id].vsel_reg, &val); - mc13xxx_unlock(priv->mc13xxx); - if (ret) return ret; -- cgit v1.2.2 From ce44beb7c0b12d33ce88b396aeaea0ba4ca1bbfc Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 9 Jun 2014 18:09:52 +0300 Subject: regulator: 88pm800: remove duplicate PM800_BUCK3 define The PM800_BUCK3 define is cut and pasted twice so we can remove the second instance. Signed-off-by: Dan Carpenter Signed-off-by: Mark Brown --- drivers/regulator/88pm800.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/regulator/88pm800.c b/drivers/regulator/88pm800.c index 7a721d67e6ac..4e6c8c611905 100644 --- a/drivers/regulator/88pm800.c +++ b/drivers/regulator/88pm800.c @@ -52,7 +52,6 @@ #define PM800_BUCK1_3 (0x3F) #define PM800_BUCK2 (0x40) #define PM800_BUCK3 (0x41) -#define PM800_BUCK3 (0x41) #define PM800_BUCK4 (0x42) #define PM800_BUCK4_1 (0x43) #define PM800_BUCK4_2 (0x44) -- cgit v1.2.2 From 53ddddcad5a4fc41db3e2f16c22344d8da58cf74 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Tue, 10 Jun 2014 12:04:53 +0530 Subject: regulator: ltc3589: Staticize ltc3589_reg_defaults 'ltc3589_reg_defaults' is local to this file. Make it static. Signed-off-by: Sachin Kamat Signed-off-by: Mark Brown --- drivers/regulator/ltc3589.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/regulator/ltc3589.c b/drivers/regulator/ltc3589.c index 110a99ee1162..217d10d6f8f7 100644 --- a/drivers/regulator/ltc3589.c +++ b/drivers/regulator/ltc3589.c @@ -377,7 +377,7 @@ static bool ltc3589_volatile_reg(struct device *dev, unsigned int reg) return false; } -struct reg_default ltc3589_reg_defaults[] = { +static struct reg_default ltc3589_reg_defaults[] = { { LTC3589_SCR1, 0x00 }, { LTC3589_OVEN, 0x00 }, { LTC3589_SCR2, 0x00 }, -- cgit v1.2.2 From a5c1a416013b04b66c721af2e90c04dce604d0b2 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sun, 8 Jun 2014 22:45:42 +0800 Subject: regulator: ab8500: Remove ab8500_regulator_of_probe() Now this is a DT-only driver because non-devicetree probe path is removed, so merge ab8500_regulator_of_probe() into ab8500_regulator_probe(). Signed-off-by: Axel Lin Reviewed-by: Linus Walleij Signed-off-by: Mark Brown --- drivers/regulator/ab8500.c | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c index c625468c7f2c..88da8626a57a 100644 --- a/drivers/regulator/ab8500.c +++ b/drivers/regulator/ab8500.c @@ -3037,28 +3037,12 @@ static int ab8500_regulator_register(struct platform_device *pdev, return 0; } -static int -ab8500_regulator_of_probe(struct platform_device *pdev, - struct device_node *np) -{ - struct of_regulator_match *match = abx500_regulator.match; - int err, i; - - for (i = 0; i < abx500_regulator.info_size; i++) { - err = ab8500_regulator_register( - pdev, match[i].init_data, i, match[i].of_node); - if (err) - return err; - } - - return 0; -} - static int ab8500_regulator_probe(struct platform_device *pdev) { struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent); struct device_node *np = pdev->dev.of_node; - int err; + struct of_regulator_match *match; + int err, i; if (!ab8500) { dev_err(&pdev->dev, "null mfd parent\n"); @@ -3075,7 +3059,16 @@ static int ab8500_regulator_probe(struct platform_device *pdev) "Error parsing regulator init data: %d\n", err); return err; } - return ab8500_regulator_of_probe(pdev, np); + + match = abx500_regulator.match; + for (i = 0; i < abx500_regulator.info_size; i++) { + err = ab8500_regulator_register(pdev, match[i].init_data, i, + match[i].of_node); + if (err) + return err; + } + + return 0; } static int ab8500_regulator_remove(struct platform_device *pdev) -- cgit v1.2.2 From 03187c72db60e20354aca6802bc5cc3e42c1d6e1 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sun, 8 Jun 2014 22:47:10 +0800 Subject: regulator: ab8500: Remove ab8500_regulator_debug_init/exit() CONFIG_REGULATOR_AB8500_DEBUG is always not defined. ab8500_regulator_debug_init() is not called at all now, ab8500_regulator_debug_exit() simply return 0, thus remove them. Signed-off-by: Axel Lin Reviewed-by: Linus Walleij Signed-off-by: Mark Brown --- drivers/regulator/ab8500.c | 13 ------------- 1 file changed, 13 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c index 88da8626a57a..1fda14e12ea8 100644 --- a/drivers/regulator/ab8500.c +++ b/drivers/regulator/ab8500.c @@ -3071,21 +3071,8 @@ static int ab8500_regulator_probe(struct platform_device *pdev) return 0; } -static int ab8500_regulator_remove(struct platform_device *pdev) -{ - int err; - - /* remove regulator debug */ - err = ab8500_regulator_debug_exit(pdev); - if (err) - return err; - - return 0; -} - static struct platform_driver ab8500_regulator_driver = { .probe = ab8500_regulator_probe, - .remove = ab8500_regulator_remove, .driver = { .name = "ab8500-regulator", .owner = THIS_MODULE, -- cgit v1.2.2 From 1c113d83bb041ba544ea5054cf84ada93152b0d1 Mon Sep 17 00:00:00 2001 From: Keerthy Date: Wed, 18 Jun 2014 15:28:55 +0530 Subject: mfd: palmas: Add tps65917 support Add tps65917 PMIC support. tps65917 is a subset of palmas PMIC. Some of the register definitions and the interrupt mappings are different. Acked-by: Lee Jones Signed-off-by: Keerthy Signed-off-by: Mark Brown --- drivers/mfd/palmas.c | 179 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 172 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/mfd/palmas.c b/drivers/mfd/palmas.c index d280d789e55a..6e1786187dd8 100644 --- a/drivers/mfd/palmas.c +++ b/drivers/mfd/palmas.c @@ -92,6 +92,133 @@ static const struct regmap_config palmas_regmap_config[PALMAS_NUM_CLIENTS] = { }, }; +static const struct regmap_irq tps65917_irqs[] = { + /* INT1 IRQs */ + [TPS65917_RESERVED1] = { + .mask = TPS65917_RESERVED, + }, + [TPS65917_PWRON_IRQ] = { + .mask = TPS65917_INT1_STATUS_PWRON, + }, + [TPS65917_LONG_PRESS_KEY_IRQ] = { + .mask = TPS65917_INT1_STATUS_LONG_PRESS_KEY, + }, + [TPS65917_RESERVED2] = { + .mask = TPS65917_RESERVED, + }, + [TPS65917_PWRDOWN_IRQ] = { + .mask = TPS65917_INT1_STATUS_PWRDOWN, + }, + [TPS65917_HOTDIE_IRQ] = { + .mask = TPS65917_INT1_STATUS_HOTDIE, + }, + [TPS65917_VSYS_MON_IRQ] = { + .mask = TPS65917_INT1_STATUS_VSYS_MON, + }, + [TPS65917_RESERVED3] = { + .mask = TPS65917_RESERVED, + }, + /* INT2 IRQs*/ + [TPS65917_RESERVED4] = { + .mask = TPS65917_RESERVED, + .reg_offset = 1, + }, + [TPS65917_OTP_ERROR_IRQ] = { + .mask = TPS65917_INT2_STATUS_OTP_ERROR, + .reg_offset = 1, + }, + [TPS65917_WDT_IRQ] = { + .mask = TPS65917_INT2_STATUS_WDT, + .reg_offset = 1, + }, + [TPS65917_RESERVED5] = { + .mask = TPS65917_RESERVED, + .reg_offset = 1, + }, + [TPS65917_RESET_IN_IRQ] = { + .mask = TPS65917_INT2_STATUS_RESET_IN, + .reg_offset = 1, + }, + [TPS65917_FSD_IRQ] = { + .mask = TPS65917_INT2_STATUS_FSD, + .reg_offset = 1, + }, + [TPS65917_SHORT_IRQ] = { + .mask = TPS65917_INT2_STATUS_SHORT, + .reg_offset = 1, + }, + [TPS65917_RESERVED6] = { + .mask = TPS65917_RESERVED, + .reg_offset = 1, + }, + /* INT3 IRQs */ + [TPS65917_GPADC_AUTO_0_IRQ] = { + .mask = TPS65917_INT3_STATUS_GPADC_AUTO_0, + .reg_offset = 2, + }, + [TPS65917_GPADC_AUTO_1_IRQ] = { + .mask = TPS65917_INT3_STATUS_GPADC_AUTO_1, + .reg_offset = 2, + }, + [TPS65917_GPADC_EOC_SW_IRQ] = { + .mask = TPS65917_INT3_STATUS_GPADC_EOC_SW, + .reg_offset = 2, + }, + [TPS65917_RESREVED6] = { + .mask = TPS65917_RESERVED6, + .reg_offset = 2, + }, + [TPS65917_RESERVED7] = { + .mask = TPS65917_RESERVED, + .reg_offset = 2, + }, + [TPS65917_RESERVED8] = { + .mask = TPS65917_RESERVED, + .reg_offset = 2, + }, + [TPS65917_RESERVED9] = { + .mask = TPS65917_RESERVED, + .reg_offset = 2, + }, + [TPS65917_VBUS_IRQ] = { + .mask = TPS65917_INT3_STATUS_VBUS, + .reg_offset = 2, + }, + /* INT4 IRQs */ + [TPS65917_GPIO_0_IRQ] = { + .mask = TPS65917_INT4_STATUS_GPIO_0, + .reg_offset = 3, + }, + [TPS65917_GPIO_1_IRQ] = { + .mask = TPS65917_INT4_STATUS_GPIO_1, + .reg_offset = 3, + }, + [TPS65917_GPIO_2_IRQ] = { + .mask = TPS65917_INT4_STATUS_GPIO_2, + .reg_offset = 3, + }, + [TPS65917_GPIO_3_IRQ] = { + .mask = TPS65917_INT4_STATUS_GPIO_3, + .reg_offset = 3, + }, + [TPS65917_GPIO_4_IRQ] = { + .mask = TPS65917_INT4_STATUS_GPIO_4, + .reg_offset = 3, + }, + [TPS65917_GPIO_5_IRQ] = { + .mask = TPS65917_INT4_STATUS_GPIO_5, + .reg_offset = 3, + }, + [TPS65917_GPIO_6_IRQ] = { + .mask = TPS65917_INT4_STATUS_GPIO_6, + .reg_offset = 3, + }, + [TPS65917_RESERVED10] = { + .mask = TPS65917_RESERVED10, + .reg_offset = 3, + }, +}; + static const struct regmap_irq palmas_irqs[] = { /* INT1 IRQs */ [PALMAS_CHARG_DET_N_VBUS_OVV_IRQ] = { @@ -232,6 +359,19 @@ static struct regmap_irq_chip palmas_irq_chip = { PALMAS_INT1_MASK), }; +static struct regmap_irq_chip tps65917_irq_chip = { + .name = "tps65917", + .irqs = tps65917_irqs, + .num_irqs = ARRAY_SIZE(tps65917_irqs), + + .num_regs = 4, + .irq_reg_stride = 5, + .status_base = PALMAS_BASE_TO_REG(PALMAS_INTERRUPT_BASE, + PALMAS_INT1_STATUS), + .mask_base = PALMAS_BASE_TO_REG(PALMAS_INTERRUPT_BASE, + PALMAS_INT1_MASK), +}; + int palmas_ext_control_req_config(struct palmas *palmas, enum palmas_external_requestor_id id, int ext_ctrl, bool enable) { @@ -357,14 +497,38 @@ static void palmas_power_off(void) static unsigned int palmas_features = PALMAS_PMIC_FEATURE_SMPS10_BOOST; static unsigned int tps659038_features; +struct palmas_driver_data { + unsigned int *features; + struct regmap_irq_chip *irq_chip; +}; + +static struct palmas_driver_data palmas_data = { + .features = &palmas_features, + .irq_chip = &palmas_irq_chip, +}; + +static struct palmas_driver_data tps659038_data = { + .features = &tps659038_features, + .irq_chip = &palmas_irq_chip, +}; + +static struct palmas_driver_data tps65917_data = { + .features = &tps659038_features, + .irq_chip = &tps65917_irq_chip, +}; + static const struct of_device_id of_palmas_match_tbl[] = { { .compatible = "ti,palmas", - .data = &palmas_features, + .data = &palmas_data, }, { .compatible = "ti,tps659038", - .data = &tps659038_features, + .data = &tps659038_data, + }, + { + .compatible = "ti,tps65917", + .data = &tps65917_data, }, { }, }; @@ -375,9 +539,10 @@ static int palmas_i2c_probe(struct i2c_client *i2c, { struct palmas *palmas; struct palmas_platform_data *pdata; + struct palmas_driver_data *driver_data; struct device_node *node = i2c->dev.of_node; int ret = 0, i; - unsigned int reg, addr, *features; + unsigned int reg, addr; int slave; const struct of_device_id *match; @@ -408,8 +573,8 @@ static int palmas_i2c_probe(struct i2c_client *i2c, if (!match) return -ENODATA; - features = (unsigned int *)match->data; - palmas->features = *features; + driver_data = (struct palmas_driver_data *)match->data; + palmas->features = *driver_data->features; for (i = 0; i < PALMAS_NUM_CLIENTS; i++) { if (i == 0) @@ -463,8 +628,8 @@ static int palmas_i2c_probe(struct i2c_client *i2c, regmap_write(palmas->regmap[slave], addr, reg); ret = regmap_add_irq_chip(palmas->regmap[slave], palmas->irq, - IRQF_ONESHOT | pdata->irq_flags, 0, &palmas_irq_chip, - &palmas->irq_data); + IRQF_ONESHOT | pdata->irq_flags, 0, + driver_data->irq_chip, &palmas->irq_data); if (ret < 0) goto err_i2c; -- cgit v1.2.2 From 9f057dc1d01383e6975e515ba8e661d2aeb6bdfc Mon Sep 17 00:00:00 2001 From: Keerthy Date: Wed, 18 Jun 2014 15:28:56 +0530 Subject: regulator: palmas: Shift the reg_info structure definition to the header file Shift the reg_info structure definition to the header file. Acked-by: Lee Jones Signed-off-by: Keerthy Signed-off-by: Mark Brown --- drivers/regulator/palmas-regulator.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c index b982f0ff4e01..1cf462f90df5 100644 --- a/drivers/regulator/palmas-regulator.c +++ b/drivers/regulator/palmas-regulator.c @@ -27,15 +27,6 @@ #include #include -struct regs_info { - char *name; - char *sname; - u8 vsel_addr; - u8 ctrl_addr; - u8 tstep_addr; - int sleep_id; -}; - static const struct regulator_linear_range smps_low_ranges[] = { REGULATOR_LINEAR_RANGE(0, 0x0, 0x0, 0), REGULATOR_LINEAR_RANGE(500000, 0x1, 0x6, 0), -- cgit v1.2.2 From 7ec70c73c9e93556fd19bb6bdfbbd089d9db438b Mon Sep 17 00:00:00 2001 From: Keerthy Date: Wed, 18 Jun 2014 15:28:57 +0530 Subject: mfd: palmas: shift the palmas_sleep_requestor_info structure definition to the header file shift the palmas_sleep_requestor_info structure definition to the header file. Acked-by: Lee Jones Signed-off-by: Keerthy Signed-off-by: Mark Brown --- drivers/mfd/palmas.c | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'drivers') diff --git a/drivers/mfd/palmas.c b/drivers/mfd/palmas.c index 6e1786187dd8..c12759d1bd7c 100644 --- a/drivers/mfd/palmas.c +++ b/drivers/mfd/palmas.c @@ -25,16 +25,6 @@ #include #include -#define PALMAS_EXT_REQ (PALMAS_EXT_CONTROL_ENABLE1 | \ - PALMAS_EXT_CONTROL_ENABLE2 | \ - PALMAS_EXT_CONTROL_NSLEEP) - -struct palmas_sleep_requestor_info { - int id; - int reg_offset; - int bit_pos; -}; - #define EXTERNAL_REQUESTOR(_id, _offset, _pos) \ [PALMAS_EXTERNAL_REQSTR_ID_##_id] = { \ .id = PALMAS_EXTERNAL_REQSTR_ID_##_id, \ -- cgit v1.2.2 From cac9e916245390d7b0b770b8577af4918f74d0ee Mon Sep 17 00:00:00 2001 From: Keerthy Date: Wed, 18 Jun 2014 15:28:59 +0530 Subject: regulator: palmas: add driver data and modularize the probe add driver data and modularize the probe. Signed-off-by: Keerthy Signed-off-by: Mark Brown --- drivers/mfd/palmas.c | 44 +-- drivers/regulator/palmas-regulator.c | 658 +++++++++++++++++++++-------------- 2 files changed, 396 insertions(+), 306 deletions(-) (limited to 'drivers') diff --git a/drivers/mfd/palmas.c b/drivers/mfd/palmas.c index c12759d1bd7c..28cb048f4760 100644 --- a/drivers/mfd/palmas.c +++ b/drivers/mfd/palmas.c @@ -25,42 +25,6 @@ #include #include -#define EXTERNAL_REQUESTOR(_id, _offset, _pos) \ - [PALMAS_EXTERNAL_REQSTR_ID_##_id] = { \ - .id = PALMAS_EXTERNAL_REQSTR_ID_##_id, \ - .reg_offset = _offset, \ - .bit_pos = _pos, \ - } - -static struct palmas_sleep_requestor_info sleep_req_info[] = { - EXTERNAL_REQUESTOR(REGEN1, 0, 0), - EXTERNAL_REQUESTOR(REGEN2, 0, 1), - EXTERNAL_REQUESTOR(SYSEN1, 0, 2), - EXTERNAL_REQUESTOR(SYSEN2, 0, 3), - EXTERNAL_REQUESTOR(CLK32KG, 0, 4), - EXTERNAL_REQUESTOR(CLK32KGAUDIO, 0, 5), - EXTERNAL_REQUESTOR(REGEN3, 0, 6), - EXTERNAL_REQUESTOR(SMPS12, 1, 0), - EXTERNAL_REQUESTOR(SMPS3, 1, 1), - EXTERNAL_REQUESTOR(SMPS45, 1, 2), - EXTERNAL_REQUESTOR(SMPS6, 1, 3), - EXTERNAL_REQUESTOR(SMPS7, 1, 4), - EXTERNAL_REQUESTOR(SMPS8, 1, 5), - EXTERNAL_REQUESTOR(SMPS9, 1, 6), - EXTERNAL_REQUESTOR(SMPS10, 1, 7), - EXTERNAL_REQUESTOR(LDO1, 2, 0), - EXTERNAL_REQUESTOR(LDO2, 2, 1), - EXTERNAL_REQUESTOR(LDO3, 2, 2), - EXTERNAL_REQUESTOR(LDO4, 2, 3), - EXTERNAL_REQUESTOR(LDO5, 2, 4), - EXTERNAL_REQUESTOR(LDO6, 2, 5), - EXTERNAL_REQUESTOR(LDO7, 2, 6), - EXTERNAL_REQUESTOR(LDO8, 2, 7), - EXTERNAL_REQUESTOR(LDO9, 3, 0), - EXTERNAL_REQUESTOR(LDOLN, 3, 1), - EXTERNAL_REQUESTOR(LDOUSB, 3, 2), -}; - static const struct regmap_config palmas_regmap_config[PALMAS_NUM_CLIENTS] = { { .reg_bits = 8, @@ -365,10 +329,10 @@ static struct regmap_irq_chip tps65917_irq_chip = { int palmas_ext_control_req_config(struct palmas *palmas, enum palmas_external_requestor_id id, int ext_ctrl, bool enable) { + struct palmas_pmic_driver_data *pmic_ddata = palmas->pmic_ddata; int preq_mask_bit = 0; int reg_add = 0; - int bit_pos; - int ret; + int bit_pos, ret; if (!(ext_ctrl & PALMAS_EXT_REQ)) return 0; @@ -387,8 +351,8 @@ int palmas_ext_control_req_config(struct palmas *palmas, preq_mask_bit = 2; } - bit_pos = sleep_req_info[id].bit_pos; - reg_add += sleep_req_info[id].reg_offset; + bit_pos = pmic_ddata->sleep_req_info[id].bit_pos; + reg_add += pmic_ddata->sleep_req_info[id].reg_offset; if (enable) ret = palmas_update_bits(palmas, PALMAS_RESOURCE_BASE, reg_add, BIT(bit_pos), BIT(bit_pos)); diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c index 1cf462f90df5..aa8e5516752e 100644 --- a/drivers/regulator/palmas-regulator.c +++ b/drivers/regulator/palmas-regulator.c @@ -41,7 +41,7 @@ static const struct regulator_linear_range smps_high_ranges[] = { REGULATOR_LINEAR_RANGE(3300000, 0x7A, 0x7f, 0), }; -static const struct regs_info palmas_regs_info[] = { +static struct regs_info palmas_regs_info[] = { { .name = "SMPS12", .sname = "smps1-in", @@ -227,6 +227,42 @@ static const struct regs_info palmas_regs_info[] = { }, }; +#define EXTERNAL_REQUESTOR(_id, _offset, _pos) \ + [PALMAS_EXTERNAL_REQSTR_ID_##_id] = { \ + .id = PALMAS_EXTERNAL_REQSTR_ID_##_id, \ + .reg_offset = _offset, \ + .bit_pos = _pos, \ + } + +struct palmas_sleep_requestor_info palma_sleep_req_info[] = { + EXTERNAL_REQUESTOR(REGEN1, 0, 0), + EXTERNAL_REQUESTOR(REGEN2, 0, 1), + EXTERNAL_REQUESTOR(SYSEN1, 0, 2), + EXTERNAL_REQUESTOR(SYSEN2, 0, 3), + EXTERNAL_REQUESTOR(CLK32KG, 0, 4), + EXTERNAL_REQUESTOR(CLK32KGAUDIO, 0, 5), + EXTERNAL_REQUESTOR(REGEN3, 0, 6), + EXTERNAL_REQUESTOR(SMPS12, 1, 0), + EXTERNAL_REQUESTOR(SMPS3, 1, 1), + EXTERNAL_REQUESTOR(SMPS45, 1, 2), + EXTERNAL_REQUESTOR(SMPS6, 1, 3), + EXTERNAL_REQUESTOR(SMPS7, 1, 4), + EXTERNAL_REQUESTOR(SMPS8, 1, 5), + EXTERNAL_REQUESTOR(SMPS9, 1, 6), + EXTERNAL_REQUESTOR(SMPS10, 1, 7), + EXTERNAL_REQUESTOR(LDO1, 2, 0), + EXTERNAL_REQUESTOR(LDO2, 2, 1), + EXTERNAL_REQUESTOR(LDO3, 2, 2), + EXTERNAL_REQUESTOR(LDO4, 2, 3), + EXTERNAL_REQUESTOR(LDO5, 2, 4), + EXTERNAL_REQUESTOR(LDO6, 2, 5), + EXTERNAL_REQUESTOR(LDO7, 2, 6), + EXTERNAL_REQUESTOR(LDO8, 2, 7), + EXTERNAL_REQUESTOR(LDO9, 3, 0), + EXTERNAL_REQUESTOR(LDOLN, 3, 1), + EXTERNAL_REQUESTOR(LDOUSB, 3, 2), +}; + static unsigned int palmas_smps_ramp_delay[4] = {0, 10000, 5000, 2500}; #define SMPS_CTRL_MODE_OFF 0x00 @@ -288,11 +324,14 @@ static int palmas_ldo_write(struct palmas *palmas, unsigned int reg, static int palmas_set_mode_smps(struct regulator_dev *dev, unsigned int mode) { struct palmas_pmic *pmic = rdev_get_drvdata(dev); + struct palmas_pmic_driver_data *ddata = pmic->palmas->pmic_ddata; int id = rdev_get_id(dev); unsigned int reg; bool rail_enable = true; - palmas_smps_read(pmic->palmas, palmas_regs_info[id].ctrl_addr, ®); + palmas_smps_read(pmic->palmas, ddata->palmas_regs_info[id].ctrl_addr, + ®); + reg &= ~PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK; if (reg == SMPS_CTRL_MODE_OFF) @@ -315,7 +354,7 @@ static int palmas_set_mode_smps(struct regulator_dev *dev, unsigned int mode) pmic->current_reg_mode[id] = reg & PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK; if (rail_enable) palmas_smps_write(pmic->palmas, - palmas_regs_info[id].ctrl_addr, reg); + ddata->palmas_regs_info[id].ctrl_addr, reg); return 0; } @@ -343,9 +382,10 @@ static int palmas_smps_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay) { struct palmas_pmic *pmic = rdev_get_drvdata(rdev); + struct palmas_pmic_driver_data *ddata = pmic->palmas->pmic_ddata; int id = rdev_get_id(rdev); unsigned int reg = 0; - unsigned int addr = palmas_regs_info[id].tstep_addr; + unsigned int addr = ddata->palmas_regs_info[id].tstep_addr; int ret; /* SMPS3 and SMPS7 do not have tstep_addr setting */ @@ -414,10 +454,12 @@ static struct regulator_ops palmas_ops_smps10 = { static int palmas_is_enabled_ldo(struct regulator_dev *dev) { struct palmas_pmic *pmic = rdev_get_drvdata(dev); + struct palmas_pmic_driver_data *ddata = pmic->palmas->pmic_ddata; int id = rdev_get_id(dev); unsigned int reg; - palmas_ldo_read(pmic->palmas, palmas_regs_info[id].ctrl_addr, ®); + palmas_ldo_read(pmic->palmas, + ddata->palmas_regs_info[id].ctrl_addr, ®); reg &= PALMAS_LDO1_CTRL_STATUS; @@ -478,7 +520,9 @@ static int palmas_smps_init(struct palmas *palmas, int id, unsigned int addr; int ret; - addr = palmas_regs_info[id].ctrl_addr; + struct palmas_pmic_driver_data *ddata = palmas->pmic_ddata; + + addr = ddata->palmas_regs_info[id].ctrl_addr; ret = palmas_smps_read(palmas, addr, ®); if (ret) @@ -513,8 +557,8 @@ static int palmas_smps_init(struct palmas *palmas, int id, if (ret) return ret; - if (palmas_regs_info[id].vsel_addr && reg_init->vsel) { - addr = palmas_regs_info[id].vsel_addr; + if (ddata->palmas_regs_info[id].vsel_addr && reg_init->vsel) { + addr = ddata->palmas_regs_info[id].vsel_addr; reg = reg_init->vsel; @@ -526,7 +570,7 @@ static int palmas_smps_init(struct palmas *palmas, int id, if (reg_init->roof_floor && (id != PALMAS_REG_SMPS10_OUT1) && (id != PALMAS_REG_SMPS10_OUT2)) { /* Enable externally controlled regulator */ - addr = palmas_regs_info[id].ctrl_addr; + addr = ddata->palmas_regs_info[id].ctrl_addr; ret = palmas_smps_read(palmas, addr, ®); if (ret < 0) return ret; @@ -549,7 +593,9 @@ static int palmas_ldo_init(struct palmas *palmas, int id, unsigned int addr; int ret; - addr = palmas_regs_info[id].ctrl_addr; + struct palmas_pmic_driver_data *ddata = palmas->pmic_ddata; + + addr = ddata->palmas_regs_info[id].ctrl_addr; ret = palmas_ldo_read(palmas, addr, ®); if (ret) @@ -571,7 +617,7 @@ static int palmas_ldo_init(struct palmas *palmas, int id, if (reg_init->roof_floor) { /* Enable externally controlled regulator */ - addr = palmas_regs_info[id].ctrl_addr; + addr = ddata->palmas_regs_info[id].ctrl_addr; ret = palmas_update_bits(palmas, PALMAS_LDO_BASE, addr, PALMAS_LDO1_CTRL_MODE_ACTIVE, PALMAS_LDO1_CTRL_MODE_ACTIVE); @@ -593,7 +639,9 @@ static int palmas_extreg_init(struct palmas *palmas, int id, int ret; unsigned int val = 0; - addr = palmas_regs_info[id].ctrl_addr; + struct palmas_pmic_driver_data *ddata = palmas->pmic_ddata; + + addr = ddata->palmas_regs_info[id].ctrl_addr; if (reg_init->mode_sleep) val = PALMAS_REGEN1_CTRL_MODE_SLEEP; @@ -608,7 +656,7 @@ static int palmas_extreg_init(struct palmas *palmas, int id, if (reg_init->roof_floor) { /* Enable externally controlled regulator */ - addr = palmas_regs_info[id].ctrl_addr; + addr = ddata->palmas_regs_info[id].ctrl_addr; ret = palmas_update_bits(palmas, PALMAS_RESOURCE_BASE, addr, PALMAS_REGEN1_CTRL_MODE_ACTIVE, PALMAS_REGEN1_CTRL_MODE_ACTIVE); @@ -629,7 +677,9 @@ static void palmas_enable_ldo8_track(struct palmas *palmas) unsigned int addr; int ret; - addr = palmas_regs_info[PALMAS_REG_LDO8].ctrl_addr; + struct palmas_pmic_driver_data *ddata = palmas->pmic_ddata; + + addr = ddata->palmas_regs_info[PALMAS_REG_LDO8].ctrl_addr; ret = palmas_ldo_read(palmas, addr, ®); if (ret) { @@ -648,7 +698,7 @@ static void palmas_enable_ldo8_track(struct palmas *palmas) * output is defined by the LDO8_VOLTAGE.VSEL register divided by two, * and can be set from 0.45 to 1.65 V. */ - addr = palmas_regs_info[PALMAS_REG_LDO8].vsel_addr; + addr = ddata->palmas_regs_info[PALMAS_REG_LDO8].vsel_addr; ret = palmas_ldo_read(palmas, addr, ®); if (ret) { dev_err(palmas->dev, "Error in reading ldo8 voltage reg\n"); @@ -663,169 +713,131 @@ static void palmas_enable_ldo8_track(struct palmas *palmas) return; } -static struct of_regulator_match palmas_matches[] = { - { .name = "smps12", }, - { .name = "smps123", }, - { .name = "smps3", }, - { .name = "smps45", }, - { .name = "smps457", }, - { .name = "smps6", }, - { .name = "smps7", }, - { .name = "smps8", }, - { .name = "smps9", }, - { .name = "smps10_out2", }, - { .name = "smps10_out1", }, - { .name = "ldo1", }, - { .name = "ldo2", }, - { .name = "ldo3", }, - { .name = "ldo4", }, - { .name = "ldo5", }, - { .name = "ldo6", }, - { .name = "ldo7", }, - { .name = "ldo8", }, - { .name = "ldo9", }, - { .name = "ldoln", }, - { .name = "ldousb", }, - { .name = "regen1", }, - { .name = "regen2", }, - { .name = "regen3", }, - { .name = "sysen1", }, - { .name = "sysen2", }, -}; - -static void palmas_dt_to_pdata(struct device *dev, - struct device_node *node, - struct palmas_pmic_platform_data *pdata) +static int palmas_ldo_registration(struct palmas_pmic *pmic, + struct palmas_pmic_driver_data *ddata, + struct palmas_pmic_platform_data *pdata, + const char *pdev_name, + struct regulator_config config) { - struct device_node *regulators; - u32 prop; - int idx, ret; + int id, ret; + struct regulator_dev *rdev; + struct palmas_reg_init *reg_init; - node = of_node_get(node); - regulators = of_get_child_by_name(node, "regulators"); - if (!regulators) { - dev_info(dev, "regulator node not found\n"); - return; - } + for (id = ddata->ldo_begin; id < ddata->max_reg; id++) { + if (pdata && pdata->reg_init[id]) + reg_init = pdata->reg_init[id]; + else + reg_init = NULL; - ret = of_regulator_match(dev, regulators, palmas_matches, - PALMAS_NUM_REGS); - of_node_put(regulators); - if (ret < 0) { - dev_err(dev, "Error parsing regulator init data: %d\n", ret); - return; - } + /* Miss out regulators which are not available due + * to alternate functions. + */ - for (idx = 0; idx < PALMAS_NUM_REGS; idx++) { - if (!palmas_matches[idx].init_data || - !palmas_matches[idx].of_node) - continue; + /* Register the regulators */ + pmic->desc[id].name = ddata->palmas_regs_info[id].name; + pmic->desc[id].id = id; + pmic->desc[id].type = REGULATOR_VOLTAGE; + pmic->desc[id].owner = THIS_MODULE; - pdata->reg_data[idx] = palmas_matches[idx].init_data; + if (id < PALMAS_REG_REGEN1) { + pmic->desc[id].n_voltages = PALMAS_LDO_NUM_VOLTAGES; + if (reg_init && reg_init->roof_floor) + pmic->desc[id].ops = + &palmas_ops_ext_control_ldo; + else + pmic->desc[id].ops = &palmas_ops_ldo; + pmic->desc[id].min_uV = 900000; + pmic->desc[id].uV_step = 50000; + pmic->desc[id].linear_min_sel = 1; + pmic->desc[id].enable_time = 500; + pmic->desc[id].vsel_reg = + PALMAS_BASE_TO_REG(PALMAS_LDO_BASE, + ddata->palmas_regs_info[id].vsel_addr); + pmic->desc[id].vsel_mask = + PALMAS_LDO1_VOLTAGE_VSEL_MASK; + pmic->desc[id].enable_reg = + PALMAS_BASE_TO_REG(PALMAS_LDO_BASE, + ddata->palmas_regs_info[id].ctrl_addr); + pmic->desc[id].enable_mask = + PALMAS_LDO1_CTRL_MODE_ACTIVE; - pdata->reg_init[idx] = devm_kzalloc(dev, - sizeof(struct palmas_reg_init), GFP_KERNEL); + /* Check if LDO8 is in tracking mode or not */ + if (pdata && (id == PALMAS_REG_LDO8) && + pdata->enable_ldo8_tracking) { + palmas_enable_ldo8_track(pmic->palmas); + pmic->desc[id].min_uV = 450000; + pmic->desc[id].uV_step = 25000; + } - pdata->reg_init[idx]->warm_reset = - of_property_read_bool(palmas_matches[idx].of_node, - "ti,warm-reset"); + /* LOD6 in vibrator mode will have enable time 2000us */ + if (pdata && pdata->ldo6_vibrator && + (id == PALMAS_REG_LDO6)) + pmic->desc[id].enable_time = 2000; + } else { + pmic->desc[id].n_voltages = 1; + if (reg_init && reg_init->roof_floor) + pmic->desc[id].ops = + &palmas_ops_ext_control_extreg; + else + pmic->desc[id].ops = &palmas_ops_extreg; + pmic->desc[id].enable_reg = + PALMAS_BASE_TO_REG(PALMAS_RESOURCE_BASE, + ddata->palmas_regs_info[id].ctrl_addr); + pmic->desc[id].enable_mask = + PALMAS_REGEN1_CTRL_MODE_ACTIVE; + } - ret = of_property_read_u32(palmas_matches[idx].of_node, - "ti,roof-floor", &prop); - /* EINVAL: Property not found */ - if (ret != -EINVAL) { - int econtrol; + if (pdata) + config.init_data = pdata->reg_data[id]; + else + config.init_data = NULL; - /* use default value, when no value is specified */ - econtrol = PALMAS_EXT_CONTROL_NSLEEP; - if (!ret) { - switch (prop) { - case 1: - econtrol = PALMAS_EXT_CONTROL_ENABLE1; - break; - case 2: - econtrol = PALMAS_EXT_CONTROL_ENABLE2; - break; - case 3: - econtrol = PALMAS_EXT_CONTROL_NSLEEP; - break; - default: - WARN_ON(1); - dev_warn(dev, - "%s: Invalid roof-floor option: %u\n", - palmas_matches[idx].name, prop); - break; - } - } - pdata->reg_init[idx]->roof_floor = econtrol; - } + pmic->desc[id].supply_name = ddata->palmas_regs_info[id].sname; + config.of_node = ddata->palmas_matches[id].of_node; - ret = of_property_read_u32(palmas_matches[idx].of_node, - "ti,mode-sleep", &prop); - if (!ret) - pdata->reg_init[idx]->mode_sleep = prop; + rdev = devm_regulator_register(pmic->dev, &pmic->desc[id], + &config); + if (IS_ERR(rdev)) { + dev_err(pmic->dev, + "failed to register %s regulator\n", + pdev_name); + return PTR_ERR(rdev); + } - ret = of_property_read_bool(palmas_matches[idx].of_node, - "ti,smps-range"); - if (ret) - pdata->reg_init[idx]->vsel = - PALMAS_SMPS12_VOLTAGE_RANGE; + /* Save regulator for cleanup */ + pmic->rdev[id] = rdev; - if (idx == PALMAS_REG_LDO8) - pdata->enable_ldo8_tracking = of_property_read_bool( - palmas_matches[idx].of_node, - "ti,enable-ldo8-tracking"); + /* Initialise sleep/init values from platform data */ + if (pdata) { + reg_init = pdata->reg_init[id]; + if (reg_init) { + if (id <= ddata->ldo_end) + ret = palmas_ldo_init(pmic->palmas, id, + reg_init); + else + ret = palmas_extreg_init(pmic->palmas, + id, reg_init); + if (ret) + return ret; + } + } } - pdata->ldo6_vibrator = of_property_read_bool(node, "ti,ldo6-vibrator"); + return 0; } - -static int palmas_regulators_probe(struct platform_device *pdev) +static int palmas_smps_registration(struct palmas_pmic *pmic, + struct palmas_pmic_driver_data *ddata, + struct palmas_pmic_platform_data *pdata, + const char *pdev_name, + struct regulator_config config) { - struct palmas *palmas = dev_get_drvdata(pdev->dev.parent); - struct palmas_pmic_platform_data *pdata = dev_get_platdata(&pdev->dev); - struct device_node *node = pdev->dev.of_node; + int id, ret; + unsigned int addr, reg; struct regulator_dev *rdev; - struct regulator_config config = { }; - struct palmas_pmic *pmic; struct palmas_reg_init *reg_init; - int id = 0, ret; - unsigned int addr, reg; - - if (node && !pdata) { - pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); - - if (!pdata) - return -ENOMEM; - - palmas_dt_to_pdata(&pdev->dev, node, pdata); - } - - pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL); - if (!pmic) - return -ENOMEM; - - pmic->dev = &pdev->dev; - pmic->palmas = palmas; - palmas->pmic = pmic; - platform_set_drvdata(pdev, pmic); - - ret = palmas_smps_read(palmas, PALMAS_SMPS_CTRL, ®); - if (ret) - return ret; - - if (reg & PALMAS_SMPS_CTRL_SMPS12_SMPS123_EN) - pmic->smps123 = 1; - - if (reg & PALMAS_SMPS_CTRL_SMPS45_SMPS457_EN) - pmic->smps457 = 1; - config.regmap = palmas->regmap[REGULATOR_SLAVE]; - config.dev = &pdev->dev; - config.driver_data = pmic; - - for (id = 0; id < PALMAS_REG_LDO1; id++) { + for (id = ddata->smps_start; id <= ddata->smps_end; id++) { bool ramp_delay_support = false; /* @@ -859,7 +871,7 @@ static int palmas_regulators_probe(struct platform_device *pdev) break; case PALMAS_REG_SMPS10_OUT1: case PALMAS_REG_SMPS10_OUT2: - if (!PALMAS_PMIC_HAS(palmas, SMPS10_BOOST)) + if (!PALMAS_PMIC_HAS(pmic->palmas, SMPS10_BOOST)) continue; } @@ -867,10 +879,10 @@ static int palmas_regulators_probe(struct platform_device *pdev) ramp_delay_support = true; if (ramp_delay_support) { - addr = palmas_regs_info[id].tstep_addr; + addr = ddata->palmas_regs_info[id].tstep_addr; ret = palmas_smps_read(pmic->palmas, addr, ®); if (ret < 0) { - dev_err(&pdev->dev, + dev_err(pmic->dev, "reading TSTEP reg failed: %d\n", ret); return ret; } @@ -882,7 +894,7 @@ static int palmas_regulators_probe(struct platform_device *pdev) /* Initialise sleep/init values from platform data */ if (pdata && pdata->reg_init[id]) { reg_init = pdata->reg_init[id]; - ret = palmas_smps_init(palmas, id, reg_init); + ret = palmas_smps_init(pmic->palmas, id, reg_init); if (ret) return ret; } else { @@ -890,7 +902,7 @@ static int palmas_regulators_probe(struct platform_device *pdev) } /* Register the regulators */ - pmic->desc[id].name = palmas_regs_info[id].name; + pmic->desc[id].name = ddata->palmas_regs_info[id].name; pmic->desc[id].id = id; switch (id) { @@ -965,15 +977,15 @@ static int palmas_regulators_probe(struct platform_device *pdev) else config.init_data = NULL; - pmic->desc[id].supply_name = palmas_regs_info[id].sname; - config.of_node = palmas_matches[id].of_node; + pmic->desc[id].supply_name = ddata->palmas_regs_info[id].sname; + config.of_node = ddata->palmas_matches[id].of_node; - rdev = devm_regulator_register(&pdev->dev, &pmic->desc[id], + rdev = devm_regulator_register(pmic->dev, &pmic->desc[id], &config); if (IS_ERR(rdev)) { - dev_err(&pdev->dev, + dev_err(pmic->dev, "failed to register %s regulator\n", - pdev->name); + pdev_name); return PTR_ERR(rdev); } @@ -981,123 +993,237 @@ static int palmas_regulators_probe(struct platform_device *pdev) pmic->rdev[id] = rdev; } - /* Start this loop from the id left from previous loop */ - for (; id < PALMAS_NUM_REGS; id++) { - if (pdata && pdata->reg_init[id]) - reg_init = pdata->reg_init[id]; - else - reg_init = NULL; + return 0; +} - /* Miss out regulators which are not available due - * to alternate functions. - */ +static struct of_regulator_match palmas_matches[] = { + { .name = "smps12", }, + { .name = "smps123", }, + { .name = "smps3", }, + { .name = "smps45", }, + { .name = "smps457", }, + { .name = "smps6", }, + { .name = "smps7", }, + { .name = "smps8", }, + { .name = "smps9", }, + { .name = "smps10_out2", }, + { .name = "smps10_out1", }, + { .name = "ldo1", }, + { .name = "ldo2", }, + { .name = "ldo3", }, + { .name = "ldo4", }, + { .name = "ldo5", }, + { .name = "ldo6", }, + { .name = "ldo7", }, + { .name = "ldo8", }, + { .name = "ldo9", }, + { .name = "ldoln", }, + { .name = "ldousb", }, + { .name = "regen1", }, + { .name = "regen2", }, + { .name = "regen3", }, + { .name = "sysen1", }, + { .name = "sysen2", }, +}; - /* Register the regulators */ - pmic->desc[id].name = palmas_regs_info[id].name; - pmic->desc[id].id = id; - pmic->desc[id].type = REGULATOR_VOLTAGE; - pmic->desc[id].owner = THIS_MODULE; +struct palmas_pmic_driver_data palmas_ddata = { + .smps_start = PALMAS_REG_SMPS12, + .smps_end = PALMAS_REG_SMPS10_OUT1, + .ldo_begin = PALMAS_REG_LDO1, + .ldo_end = PALMAS_REG_LDOUSB, + .max_reg = PALMAS_NUM_REGS, + .palmas_regs_info = palmas_regs_info, + .palmas_matches = palmas_matches, + .sleep_req_info = palma_sleep_req_info, + .smps_register = palmas_smps_registration, + .ldo_register = palmas_ldo_registration, +}; - if (id < PALMAS_REG_REGEN1) { - pmic->desc[id].n_voltages = PALMAS_LDO_NUM_VOLTAGES; - if (reg_init && reg_init->roof_floor) - pmic->desc[id].ops = - &palmas_ops_ext_control_ldo; - else - pmic->desc[id].ops = &palmas_ops_ldo; - pmic->desc[id].min_uV = 900000; - pmic->desc[id].uV_step = 50000; - pmic->desc[id].linear_min_sel = 1; - pmic->desc[id].enable_time = 500; - pmic->desc[id].vsel_reg = - PALMAS_BASE_TO_REG(PALMAS_LDO_BASE, - palmas_regs_info[id].vsel_addr); - pmic->desc[id].vsel_mask = - PALMAS_LDO1_VOLTAGE_VSEL_MASK; - pmic->desc[id].enable_reg = - PALMAS_BASE_TO_REG(PALMAS_LDO_BASE, - palmas_regs_info[id].ctrl_addr); - pmic->desc[id].enable_mask = - PALMAS_LDO1_CTRL_MODE_ACTIVE; +static void palmas_dt_to_pdata(struct device *dev, + struct device_node *node, + struct palmas_pmic_platform_data *pdata, + struct palmas_pmic_driver_data *ddata) +{ + struct device_node *regulators; + u32 prop; + int idx, ret; - /* Check if LDO8 is in tracking mode or not */ - if (pdata && (id == PALMAS_REG_LDO8) && - pdata->enable_ldo8_tracking) { - palmas_enable_ldo8_track(palmas); - pmic->desc[id].min_uV = 450000; - pmic->desc[id].uV_step = 25000; - } + node = of_node_get(node); + regulators = of_get_child_by_name(node, "regulators"); + if (!regulators) { + dev_info(dev, "regulator node not found\n"); + return; + } - /* LOD6 in vibrator mode will have enable time 2000us */ - if (pdata && pdata->ldo6_vibrator && - (id == PALMAS_REG_LDO6)) - pmic->desc[id].enable_time = 2000; - } else { - pmic->desc[id].n_voltages = 1; - if (reg_init && reg_init->roof_floor) - pmic->desc[id].ops = - &palmas_ops_ext_control_extreg; - else - pmic->desc[id].ops = &palmas_ops_extreg; - pmic->desc[id].enable_reg = - PALMAS_BASE_TO_REG(PALMAS_RESOURCE_BASE, - palmas_regs_info[id].ctrl_addr); - pmic->desc[id].enable_mask = - PALMAS_REGEN1_CTRL_MODE_ACTIVE; - } + ret = of_regulator_match(dev, regulators, ddata->palmas_matches, + ddata->max_reg); + of_node_put(regulators); + if (ret < 0) { + dev_err(dev, "Error parsing regulator init data: %d\n", ret); + return; + } - if (pdata) - config.init_data = pdata->reg_data[id]; - else - config.init_data = NULL; + for (idx = 0; idx < ddata->max_reg; idx++) { + if (!ddata->palmas_matches[idx].init_data || + !ddata->palmas_matches[idx].of_node) + continue; - pmic->desc[id].supply_name = palmas_regs_info[id].sname; - config.of_node = palmas_matches[id].of_node; + pdata->reg_data[idx] = ddata->palmas_matches[idx].init_data; - rdev = devm_regulator_register(&pdev->dev, &pmic->desc[id], - &config); - if (IS_ERR(rdev)) { - dev_err(&pdev->dev, - "failed to register %s regulator\n", - pdev->name); - return PTR_ERR(rdev); - } + pdata->reg_init[idx] = devm_kzalloc(dev, + sizeof(struct palmas_reg_init), GFP_KERNEL); - /* Save regulator for cleanup */ - pmic->rdev[id] = rdev; + pdata->reg_init[idx]->warm_reset = + of_property_read_bool(ddata->palmas_matches[idx].of_node, + "ti,warm-reset"); - /* Initialise sleep/init values from platform data */ - if (pdata) { - reg_init = pdata->reg_init[id]; - if (reg_init) { - if (id < PALMAS_REG_REGEN1) - ret = palmas_ldo_init(palmas, - id, reg_init); - else - ret = palmas_extreg_init(palmas, - id, reg_init); - if (ret) - return ret; + ret = of_property_read_u32(ddata->palmas_matches[idx].of_node, + "ti,roof-floor", &prop); + /* EINVAL: Property not found */ + if (ret != -EINVAL) { + int econtrol; + + /* use default value, when no value is specified */ + econtrol = PALMAS_EXT_CONTROL_NSLEEP; + if (!ret) { + switch (prop) { + case 1: + econtrol = PALMAS_EXT_CONTROL_ENABLE1; + break; + case 2: + econtrol = PALMAS_EXT_CONTROL_ENABLE2; + break; + case 3: + econtrol = PALMAS_EXT_CONTROL_NSLEEP; + break; + default: + WARN_ON(1); + dev_warn(dev, + "%s: Invalid roof-floor option: %u\n", + palmas_matches[idx].name, prop); + break; + } } + pdata->reg_init[idx]->roof_floor = econtrol; } - } + ret = of_property_read_u32(ddata->palmas_matches[idx].of_node, + "ti,mode-sleep", &prop); + if (!ret) + pdata->reg_init[idx]->mode_sleep = prop; - return 0; + ret = of_property_read_bool(ddata->palmas_matches[idx].of_node, + "ti,smps-range"); + if (ret) + pdata->reg_init[idx]->vsel = + PALMAS_SMPS12_VOLTAGE_RANGE; + + if (idx == PALMAS_REG_LDO8) + pdata->enable_ldo8_tracking = of_property_read_bool( + ddata->palmas_matches[idx].of_node, + "ti,enable-ldo8-tracking"); + } + + pdata->ldo6_vibrator = of_property_read_bool(node, "ti,ldo6-vibrator"); } -static const struct of_device_id of_palmas_match_tbl[] = { - { .compatible = "ti,palmas-pmic", }, - { .compatible = "ti,twl6035-pmic", }, - { .compatible = "ti,twl6036-pmic", }, - { .compatible = "ti,twl6037-pmic", }, - { .compatible = "ti,tps65913-pmic", }, - { .compatible = "ti,tps65914-pmic", }, - { .compatible = "ti,tps80036-pmic", }, - { .compatible = "ti,tps659038-pmic", }, +static struct of_device_id of_palmas_match_tbl[] = { + { + .compatible = "ti,palmas-pmic", + .data = &palmas_ddata, + }, + { + .compatible = "ti,twl6035-pmic", + .data = &palmas_ddata, + }, + { + .compatible = "ti,twl6036-pmic", + .data = &palmas_ddata, + }, + { + .compatible = "ti,twl6037-pmic", + .data = &palmas_ddata, + }, + { + .compatible = "ti,tps65913-pmic", + .data = &palmas_ddata, + }, + { + .compatible = "ti,tps65914-pmic", + .data = &palmas_ddata, + }, + { + .compatible = "ti,tps80036-pmic", + .data = &palmas_ddata, + }, + { + .compatible = "ti,tps659038-pmic", + .data = &palmas_ddata, + }, { /* end */ } }; +static int palmas_regulators_probe(struct platform_device *pdev) +{ + struct palmas *palmas = dev_get_drvdata(pdev->dev.parent); + struct palmas_pmic_platform_data *pdata = dev_get_platdata(&pdev->dev); + struct device_node *node = pdev->dev.of_node; + struct palmas_pmic_driver_data *driver_data; + struct regulator_config config = { }; + struct palmas_pmic *pmic; + const char *pdev_name; + const struct of_device_id *match; + int ret = 0; + unsigned int reg; + + match = of_match_device(of_match_ptr(of_palmas_match_tbl), &pdev->dev); + + if (!match) + return -ENODATA; + + driver_data = (struct palmas_pmic_driver_data *)match->data; + pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return -ENOMEM; + + pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL); + if (!pmic) + return -ENOMEM; + + pmic->dev = &pdev->dev; + pmic->palmas = palmas; + palmas->pmic = pmic; + platform_set_drvdata(pdev, pmic); + pmic->palmas->pmic_ddata = driver_data; + + palmas_dt_to_pdata(&pdev->dev, node, pdata, driver_data); + + ret = palmas_smps_read(palmas, PALMAS_SMPS_CTRL, ®); + if (ret) + return ret; + + if (reg & PALMAS_SMPS_CTRL_SMPS12_SMPS123_EN) + pmic->smps123 = 1; + + if (reg & PALMAS_SMPS_CTRL_SMPS45_SMPS457_EN) + pmic->smps457 = 1; + + config.regmap = palmas->regmap[REGULATOR_SLAVE]; + config.dev = &pdev->dev; + config.driver_data = pmic; + pdev_name = pdev->name; + + ret = driver_data->smps_register(pmic, driver_data, pdata, pdev_name, + config); + if (ret) + return ret; + + ret = driver_data->ldo_register(pmic, driver_data, pdata, pdev_name, + config); + + return ret; +} + static struct platform_driver palmas_driver = { .driver = { .name = "palmas-pmic", -- cgit v1.2.2 From d6f83370ed978d5570b7c8c22988310cb9376202 Mon Sep 17 00:00:00 2001 From: Keerthy Date: Wed, 18 Jun 2014 15:29:00 +0530 Subject: regulator: palmas: Add tps65917 PMIC support Add tps65917 PMIC support. Signed-off-by: Keerthy Signed-off-by: Mark Brown --- drivers/regulator/palmas-regulator.c | 387 +++++++++++++++++++++++++++++++++++ 1 file changed, 387 insertions(+) (limited to 'drivers') diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c index aa8e5516752e..8fa651e998da 100644 --- a/drivers/regulator/palmas-regulator.c +++ b/drivers/regulator/palmas-regulator.c @@ -227,6 +227,94 @@ static struct regs_info palmas_regs_info[] = { }, }; +static struct regs_info tps65917_regs_info[] = { + { + .name = "SMPS1", + .sname = "smps1-in", + .vsel_addr = TPS65917_SMPS1_VOLTAGE, + .ctrl_addr = TPS65917_SMPS1_CTRL, + .sleep_id = TPS65917_EXTERNAL_REQSTR_ID_SMPS1, + }, + { + .name = "SMPS2", + .sname = "smps2-in", + .vsel_addr = TPS65917_SMPS2_VOLTAGE, + .ctrl_addr = TPS65917_SMPS2_CTRL, + .sleep_id = TPS65917_EXTERNAL_REQSTR_ID_SMPS2, + }, + { + .name = "SMPS3", + .sname = "smps3-in", + .vsel_addr = TPS65917_SMPS3_VOLTAGE, + .ctrl_addr = TPS65917_SMPS3_CTRL, + .sleep_id = TPS65917_EXTERNAL_REQSTR_ID_SMPS3, + }, + { + .name = "SMPS4", + .sname = "smps4-in", + .vsel_addr = TPS65917_SMPS4_VOLTAGE, + .ctrl_addr = TPS65917_SMPS4_CTRL, + .sleep_id = TPS65917_EXTERNAL_REQSTR_ID_SMPS4, + }, + { + .name = "SMPS5", + .sname = "smps5-in", + .vsel_addr = TPS65917_SMPS5_VOLTAGE, + .ctrl_addr = TPS65917_SMPS5_CTRL, + .sleep_id = TPS65917_EXTERNAL_REQSTR_ID_SMPS5, + }, + { + .name = "LDO1", + .sname = "ldo1-in", + .vsel_addr = TPS65917_LDO1_VOLTAGE, + .ctrl_addr = TPS65917_LDO1_CTRL, + .sleep_id = TPS65917_EXTERNAL_REQSTR_ID_LDO1, + }, + { + .name = "LDO2", + .sname = "ldo2-in", + .vsel_addr = TPS65917_LDO2_VOLTAGE, + .ctrl_addr = TPS65917_LDO2_CTRL, + .sleep_id = TPS65917_EXTERNAL_REQSTR_ID_LDO2, + }, + { + .name = "LDO3", + .sname = "ldo3-in", + .vsel_addr = TPS65917_LDO3_VOLTAGE, + .ctrl_addr = TPS65917_LDO3_CTRL, + .sleep_id = TPS65917_EXTERNAL_REQSTR_ID_LDO3, + }, + { + .name = "LDO4", + .sname = "ldo4-in", + .vsel_addr = TPS65917_LDO4_VOLTAGE, + .ctrl_addr = TPS65917_LDO4_CTRL, + .sleep_id = TPS65917_EXTERNAL_REQSTR_ID_LDO4, + }, + { + .name = "LDO5", + .sname = "ldo5-in", + .vsel_addr = TPS65917_LDO5_VOLTAGE, + .ctrl_addr = TPS65917_LDO5_CTRL, + .sleep_id = TPS65917_EXTERNAL_REQSTR_ID_LDO5, + }, + { + .name = "REGEN1", + .ctrl_addr = TPS65917_REGEN1_CTRL, + .sleep_id = TPS65917_EXTERNAL_REQSTR_ID_REGEN1, + }, + { + .name = "REGEN2", + .ctrl_addr = TPS65917_REGEN2_CTRL, + .sleep_id = TPS65917_EXTERNAL_REQSTR_ID_REGEN2, + }, + { + .name = "REGEN3", + .ctrl_addr = TPS65917_REGEN3_CTRL, + .sleep_id = TPS65917_EXTERNAL_REQSTR_ID_REGEN3, + }, +}; + #define EXTERNAL_REQUESTOR(_id, _offset, _pos) \ [PALMAS_EXTERNAL_REQSTR_ID_##_id] = { \ .id = PALMAS_EXTERNAL_REQSTR_ID_##_id, \ @@ -263,6 +351,29 @@ struct palmas_sleep_requestor_info palma_sleep_req_info[] = { EXTERNAL_REQUESTOR(LDOUSB, 3, 2), }; +#define EXTERNAL_REQUESTOR_TPS65917(_id, _offset, _pos) \ + [TPS65917_EXTERNAL_REQSTR_ID_##_id] = { \ + .id = TPS65917_EXTERNAL_REQSTR_ID_##_id, \ + .reg_offset = _offset, \ + .bit_pos = _pos, \ + } + +static struct palmas_sleep_requestor_info tps65917_sleep_req_info[] = { + EXTERNAL_REQUESTOR_TPS65917(REGEN1, 0, 0), + EXTERNAL_REQUESTOR_TPS65917(REGEN2, 0, 1), + EXTERNAL_REQUESTOR_TPS65917(REGEN3, 0, 6), + EXTERNAL_REQUESTOR_TPS65917(SMPS1, 1, 0), + EXTERNAL_REQUESTOR_TPS65917(SMPS2, 1, 1), + EXTERNAL_REQUESTOR_TPS65917(SMPS3, 1, 2), + EXTERNAL_REQUESTOR_TPS65917(SMPS4, 1, 3), + EXTERNAL_REQUESTOR_TPS65917(SMPS5, 1, 4), + EXTERNAL_REQUESTOR_TPS65917(LDO1, 2, 0), + EXTERNAL_REQUESTOR_TPS65917(LDO2, 2, 1), + EXTERNAL_REQUESTOR_TPS65917(LDO3, 2, 2), + EXTERNAL_REQUESTOR_TPS65917(LDO4, 2, 3), + EXTERNAL_REQUESTOR_TPS65917(LDO5, 2, 4), +}; + static unsigned int palmas_smps_ramp_delay[4] = {0, 10000, 5000, 2500}; #define SMPS_CTRL_MODE_OFF 0x00 @@ -451,6 +562,28 @@ static struct regulator_ops palmas_ops_smps10 = { .get_bypass = regulator_get_bypass_regmap, }; +static struct regulator_ops tps65917_ops_smps = { + .is_enabled = regulator_is_enabled_regmap, + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .set_mode = palmas_set_mode_smps, + .get_mode = palmas_get_mode_smps, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .list_voltage = regulator_list_voltage_linear_range, + .map_voltage = regulator_map_voltage_linear_range, + .set_voltage_time_sel = regulator_set_voltage_time_sel, +}; + +static struct regulator_ops tps65917_ops_ext_control_smps = { + .set_mode = palmas_set_mode_smps, + .get_mode = palmas_get_mode_smps, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .list_voltage = regulator_list_voltage_linear_range, + .map_voltage = regulator_map_voltage_linear_range, +}; + static int palmas_is_enabled_ldo(struct regulator_dev *dev) { struct palmas_pmic *pmic = rdev_get_drvdata(dev); @@ -492,6 +625,17 @@ static struct regulator_ops palmas_ops_extreg = { static struct regulator_ops palmas_ops_ext_control_extreg = { }; +static struct regulator_ops tps65917_ops_ldo = { + .is_enabled = palmas_is_enabled_ldo, + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .list_voltage = regulator_list_voltage_linear, + .map_voltage = regulator_map_voltage_linear, + .set_voltage_time_sel = regulator_set_voltage_time_sel, +}; + static int palmas_regulator_config_external(struct palmas *palmas, int id, struct palmas_reg_init *reg_init) { @@ -826,6 +970,111 @@ static int palmas_ldo_registration(struct palmas_pmic *pmic, return 0; } +static int tps65917_ldo_registration(struct palmas_pmic *pmic, + struct palmas_pmic_driver_data *ddata, + struct palmas_pmic_platform_data *pdata, + const char *pdev_name, + struct regulator_config config) +{ + int id, ret; + struct regulator_dev *rdev; + struct palmas_reg_init *reg_init; + + for (id = ddata->ldo_begin; id < ddata->max_reg; id++) { + if (pdata && pdata->reg_init[id]) + reg_init = pdata->reg_init[id]; + else + reg_init = NULL; + + /* Miss out regulators which are not available due + * to alternate functions. + */ + + /* Register the regulators */ + pmic->desc[id].name = ddata->palmas_regs_info[id].name; + pmic->desc[id].id = id; + pmic->desc[id].type = REGULATOR_VOLTAGE; + pmic->desc[id].owner = THIS_MODULE; + + if (id < TPS65917_REG_REGEN1) { + pmic->desc[id].n_voltages = PALMAS_LDO_NUM_VOLTAGES; + if (reg_init && reg_init->roof_floor) + pmic->desc[id].ops = + &palmas_ops_ext_control_ldo; + else + pmic->desc[id].ops = &tps65917_ops_ldo; + pmic->desc[id].min_uV = 900000; + pmic->desc[id].uV_step = 50000; + pmic->desc[id].linear_min_sel = 1; + pmic->desc[id].enable_time = 500; + pmic->desc[id].vsel_reg = + PALMAS_BASE_TO_REG(PALMAS_LDO_BASE, + ddata->palmas_regs_info[id].vsel_addr); + pmic->desc[id].vsel_mask = + PALMAS_LDO1_VOLTAGE_VSEL_MASK; + pmic->desc[id].enable_reg = + PALMAS_BASE_TO_REG(PALMAS_LDO_BASE, + ddata->palmas_regs_info[id].ctrl_addr); + pmic->desc[id].enable_mask = + PALMAS_LDO1_CTRL_MODE_ACTIVE; + /* + * To be confirmed. Discussion on going with PMIC Team. + * It is of the order of ~60mV/uS. + */ + pmic->desc[id].ramp_delay = 2500; + } else { + pmic->desc[id].n_voltages = 1; + if (reg_init && reg_init->roof_floor) + pmic->desc[id].ops = + &palmas_ops_ext_control_extreg; + else + pmic->desc[id].ops = &palmas_ops_extreg; + pmic->desc[id].enable_reg = + PALMAS_BASE_TO_REG(PALMAS_RESOURCE_BASE, + ddata->palmas_regs_info[id].ctrl_addr); + pmic->desc[id].enable_mask = + PALMAS_REGEN1_CTRL_MODE_ACTIVE; + } + + if (pdata) + config.init_data = pdata->reg_data[id]; + else + config.init_data = NULL; + + pmic->desc[id].supply_name = ddata->palmas_regs_info[id].sname; + config.of_node = ddata->palmas_matches[id].of_node; + + rdev = devm_regulator_register(pmic->dev, &pmic->desc[id], + &config); + if (IS_ERR(rdev)) { + dev_err(pmic->dev, + "failed to register %s regulator\n", + pdev_name); + return PTR_ERR(rdev); + } + + /* Save regulator for cleanup */ + pmic->rdev[id] = rdev; + + /* Initialise sleep/init values from platform data */ + if (pdata) { + reg_init = pdata->reg_init[id]; + if (reg_init) { + if (id < TPS65917_REG_REGEN1) + ret = palmas_ldo_init(pmic->palmas, + id, reg_init); + else + ret = palmas_extreg_init(pmic->palmas, + id, reg_init); + if (ret) + return ret; + } + } + } + + return 0; +} + static int palmas_smps_registration(struct palmas_pmic *pmic, struct palmas_pmic_driver_data *ddata, struct palmas_pmic_platform_data *pdata, @@ -996,6 +1245,109 @@ static int palmas_smps_registration(struct palmas_pmic *pmic, return 0; } +static int tps65917_smps_registration(struct palmas_pmic *pmic, + struct palmas_pmic_driver_data *ddata, + struct palmas_pmic_platform_data *pdata, + const char *pdev_name, + struct regulator_config config) +{ + int id, ret; + unsigned int addr, reg; + struct regulator_dev *rdev; + struct palmas_reg_init *reg_init; + + for (id = ddata->smps_start; id <= ddata->smps_end; id++) { + /* + * Miss out regulators which are not available due + * to slaving configurations. + */ + pmic->desc[id].n_linear_ranges = 3; + if ((id == TPS65917_REG_SMPS2) && pmic->smps12) + continue; + + /* Initialise sleep/init values from platform data */ + if (pdata && pdata->reg_init[id]) { + reg_init = pdata->reg_init[id]; + ret = palmas_smps_init(pmic->palmas, id, reg_init); + if (ret) + return ret; + } else { + reg_init = NULL; + } + + /* Register the regulators */ + pmic->desc[id].name = ddata->palmas_regs_info[id].name; + pmic->desc[id].id = id; + + /* + * Read and store the RANGE bit for later use + * This must be done before regulator is probed, + * otherwise we error in probe with unsupportable + * ranges. Read the current smps mode for later use. + */ + addr = ddata->palmas_regs_info[id].vsel_addr; + + ret = palmas_smps_read(pmic->palmas, addr, ®); + if (ret) + return ret; + if (reg & TPS65917_SMPS1_VOLTAGE_RANGE) + pmic->range[id] = 1; + + if (pmic->range[id]) + pmic->desc[id].linear_ranges = smps_high_ranges; + else + pmic->desc[id].linear_ranges = smps_low_ranges; + + + if (reg_init && reg_init->roof_floor) + pmic->desc[id].ops = + &tps65917_ops_ext_control_smps; + else + pmic->desc[id].ops = &tps65917_ops_smps; + pmic->desc[id].n_voltages = PALMAS_SMPS_NUM_VOLTAGES; + pmic->desc[id].vsel_reg = + PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE, + tps65917_regs_info[id].vsel_addr); + pmic->desc[id].vsel_mask = + PALMAS_SMPS12_VOLTAGE_VSEL_MASK; + + pmic->desc[id].ramp_delay = 2500; + + /* Read the smps mode for later use. */ + addr = ddata->palmas_regs_info[id].ctrl_addr; + ret = palmas_smps_read(pmic->palmas, addr, ®); + if (ret) + return ret; + pmic->current_reg_mode[id] = reg & + PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK; + + pmic->desc[id].type = REGULATOR_VOLTAGE; + pmic->desc[id].owner = THIS_MODULE; + + if (pdata) + config.init_data = pdata->reg_data[id]; + else + config.init_data = NULL; + + pmic->desc[id].supply_name = ddata->palmas_regs_info[id].sname; + config.of_node = ddata->palmas_matches[id].of_node; + + rdev = devm_regulator_register(pmic->dev, &pmic->desc[id], + &config); + if (IS_ERR(rdev)) { + dev_err(pmic->dev, + "failed to register %s regulator\n", + pdev_name); + return PTR_ERR(rdev); + } + + /* Save regulator for cleanup */ + pmic->rdev[id] = rdev; + } + + return 0; +} + static struct of_regulator_match palmas_matches[] = { { .name = "smps12", }, { .name = "smps123", }, @@ -1026,6 +1378,24 @@ static struct of_regulator_match palmas_matches[] = { { .name = "sysen2", }, }; +static struct of_regulator_match tps65917_matches[] = { + { .name = "smps1", }, + { .name = "smps2", }, + { .name = "smps3", }, + { .name = "smps4", }, + { .name = "smps5", }, + { .name = "ldo1", }, + { .name = "ldo2", }, + { .name = "ldo3", }, + { .name = "ldo4", }, + { .name = "ldo5", }, + { .name = "regen1", }, + { .name = "regen2", }, + { .name = "regen3", }, + { .name = "sysen1", }, + { .name = "sysen2", }, +}; + struct palmas_pmic_driver_data palmas_ddata = { .smps_start = PALMAS_REG_SMPS12, .smps_end = PALMAS_REG_SMPS10_OUT1, @@ -1039,6 +1409,19 @@ struct palmas_pmic_driver_data palmas_ddata = { .ldo_register = palmas_ldo_registration, }; +struct palmas_pmic_driver_data tps65917_ddata = { + .smps_start = TPS65917_REG_SMPS1, + .smps_end = TPS65917_REG_SMPS5, + .ldo_begin = TPS65917_REG_LDO1, + .ldo_end = TPS65917_REG_LDO5, + .max_reg = TPS65917_NUM_REGS, + .palmas_regs_info = tps65917_regs_info, + .palmas_matches = tps65917_matches, + .sleep_req_info = tps65917_sleep_req_info, + .smps_register = tps65917_smps_registration, + .ldo_register = tps65917_ldo_registration, +}; + static void palmas_dt_to_pdata(struct device *dev, struct device_node *node, struct palmas_pmic_platform_data *pdata, @@ -1159,6 +1542,10 @@ static struct of_device_id of_palmas_match_tbl[] = { { .compatible = "ti,tps659038-pmic", .data = &palmas_ddata, + }, + { + .compatible = "ti,tps65917-pmic", + .data = &tps65917_ddata, }, { /* end */ } }; -- cgit v1.2.2 From a181c1c702aea397b382aa5b11ebe04648b733e5 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Tue, 24 Jun 2014 13:54:43 +0530 Subject: regulator: as3722: Fix incorrect parameter initialization 'name' field was re-initialized and getting overwritten in some cases possibly due to a typo. Code inspection says the second time it should be 'sname' instead of 'name'. Replace it. Signed-off-by: Sachin Kamat Reviewed-by: Laxman Dewangan Signed-off-by: Mark Brown --- drivers/regulator/as3722-regulator.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/as3722-regulator.c b/drivers/regulator/as3722-regulator.c index 85585219ce82..51c6bf9badfc 100644 --- a/drivers/regulator/as3722-regulator.c +++ b/drivers/regulator/as3722-regulator.c @@ -219,7 +219,7 @@ static const struct as3722_register_mapping as3722_reg_lookup[] = { { .regulator_id = AS3722_REGULATOR_ID_LDO3, .name = "as3722-ldo3", - .name = "vin-ldo3-4", + .sname = "vin-ldo3-4", .vsel_reg = AS3722_LDO3_VOLTAGE_REG, .vsel_mask = AS3722_LDO3_VSEL_MASK, .enable_reg = AS3722_LDOCONTROL0_REG, @@ -231,7 +231,7 @@ static const struct as3722_register_mapping as3722_reg_lookup[] = { { .regulator_id = AS3722_REGULATOR_ID_LDO4, .name = "as3722-ldo4", - .name = "vin-ldo3-4", + .sname = "vin-ldo3-4", .vsel_reg = AS3722_LDO4_VOLTAGE_REG, .vsel_mask = AS3722_LDO_VSEL_MASK, .enable_reg = AS3722_LDOCONTROL0_REG, -- cgit v1.2.2 From 0a3ade7ec29bb616c0530ca23749493171970064 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Tue, 24 Jun 2014 14:10:04 +0530 Subject: regulator: s5m8767: Remove unused variable 'size' is not used in the function. Remove it. Signed-off-by: Sachin Kamat Signed-off-by: Mark Brown --- drivers/regulator/s5m8767.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/s5m8767.c b/drivers/regulator/s5m8767.c index c79af943a5c0..0ab5cbeeb797 100644 --- a/drivers/regulator/s5m8767.c +++ b/drivers/regulator/s5m8767.c @@ -686,7 +686,7 @@ static int s5m8767_pmic_probe(struct platform_device *pdev) struct sec_platform_data *pdata = iodev->pdata; struct regulator_config config = { }; struct s5m8767_info *s5m8767; - int i, ret, size, buck_init; + int i, ret, buck_init; if (!pdata) { dev_err(pdev->dev.parent, "Platform data not supplied\n"); @@ -725,8 +725,6 @@ static int s5m8767_pmic_probe(struct platform_device *pdev) if (!s5m8767) return -ENOMEM; - size = sizeof(struct regulator_dev *) * (S5M8767_REG_MAX - 2); - s5m8767->dev = &pdev->dev; s5m8767->iodev = iodev; s5m8767->num_regulators = pdata->num_regulators; -- cgit v1.2.2 From 6bdaaf0e5db1bc16fed8b9770a272957669cd99b Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Tue, 24 Jun 2014 13:59:15 +0530 Subject: regulator: tps65217: Fix build warnings rdev_get_id() returns an int. Convert rid to type int to avoid the following warnings: drivers/regulator/tps65217-regulator.c:73:10: warning: comparison of unsigned expression < 0 is always false [-Wtype-limits] drivers/regulator/tps65217-regulator.c:87:10: warning: comparison of unsigned expression < 0 is always false [-Wtype-limits] Signed-off-by: Sachin Kamat Signed-off-by: Mark Brown --- drivers/regulator/tps65217-regulator.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/tps65217-regulator.c b/drivers/regulator/tps65217-regulator.c index f7ed20a5a8b9..d58db72a63b0 100644 --- a/drivers/regulator/tps65217-regulator.c +++ b/drivers/regulator/tps65217-regulator.c @@ -68,7 +68,7 @@ static const struct regulator_linear_range tps65217_uv2_ranges[] = { static int tps65217_pmic_enable(struct regulator_dev *dev) { struct tps65217 *tps = rdev_get_drvdata(dev); - unsigned int rid = rdev_get_id(dev); + int rid = rdev_get_id(dev); if (rid < TPS65217_DCDC_1 || rid > TPS65217_LDO_4) return -EINVAL; @@ -82,7 +82,7 @@ static int tps65217_pmic_enable(struct regulator_dev *dev) static int tps65217_pmic_disable(struct regulator_dev *dev) { struct tps65217 *tps = rdev_get_drvdata(dev); - unsigned int rid = rdev_get_id(dev); + int rid = rdev_get_id(dev); if (rid < TPS65217_DCDC_1 || rid > TPS65217_LDO_4) return -EINVAL; -- cgit v1.2.2 From 5f986f7c2b878142f80cc23391631a71772692a8 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Tue, 24 Jun 2014 13:59:16 +0530 Subject: regulator: tps65218: Fix build warnings rdev_get_id() returns an int. Convert rid to type int to avoid the following warnings: drivers/regulator/tps65218-regulator.c:132:10: warning: comparison of unsigned expression < 0 is always false [-Wtype-limits] drivers/regulator/tps65218-regulator.c:146:10: warning: comparison of unsigned expression < 0 is always false [-Wtype-limits] Signed-off-by: Sachin Kamat Signed-off-by: Mark Brown --- drivers/regulator/tps65218-regulator.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/tps65218-regulator.c b/drivers/regulator/tps65218-regulator.c index 69b4b7750410..8b24404be0bd 100644 --- a/drivers/regulator/tps65218-regulator.c +++ b/drivers/regulator/tps65218-regulator.c @@ -127,7 +127,7 @@ static int tps65218_pmic_set_voltage_sel(struct regulator_dev *dev, static int tps65218_pmic_enable(struct regulator_dev *dev) { struct tps65218 *tps = rdev_get_drvdata(dev); - unsigned int rid = rdev_get_id(dev); + int rid = rdev_get_id(dev); if (rid < TPS65218_DCDC_1 || rid > TPS65218_LDO_1) return -EINVAL; @@ -141,7 +141,7 @@ static int tps65218_pmic_enable(struct regulator_dev *dev) static int tps65218_pmic_disable(struct regulator_dev *dev) { struct tps65218 *tps = rdev_get_drvdata(dev); - unsigned int rid = rdev_get_id(dev); + int rid = rdev_get_id(dev); if (rid < TPS65218_DCDC_1 || rid > TPS65218_LDO_1) return -EINVAL; -- cgit v1.2.2 From cd01e32d91db5e7d549671ffbb747c4639eb8c72 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 16 Jun 2014 09:44:20 +0800 Subject: regulator: twl: Convert to use devm_kmemdup() Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/twl-regulator.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c index fed28abef419..0b4f8660fdb4 100644 --- a/drivers/regulator/twl-regulator.c +++ b/drivers/regulator/twl-regulator.c @@ -1128,7 +1128,7 @@ static int twlreg_probe(struct platform_device *pdev) if (!initdata) return -EINVAL; - info = kmemdup(template, sizeof(*info), GFP_KERNEL); + info = devm_kmemdup(&pdev->dev, template, sizeof(*info), GFP_KERNEL); if (!info) return -ENOMEM; @@ -1192,7 +1192,6 @@ static int twlreg_probe(struct platform_device *pdev) if (IS_ERR(rdev)) { dev_err(&pdev->dev, "can't register %s, %ld\n", info->desc.name, PTR_ERR(rdev)); - kfree(info); return PTR_ERR(rdev); } platform_set_drvdata(pdev, rdev); @@ -1212,20 +1211,10 @@ static int twlreg_probe(struct platform_device *pdev) return 0; } -static int twlreg_remove(struct platform_device *pdev) -{ - struct regulator_dev *rdev = platform_get_drvdata(pdev); - struct twlreg_info *info = rdev->reg_data; - - kfree(info); - return 0; -} - MODULE_ALIAS("platform:twl_reg"); static struct platform_driver twlreg_driver = { .probe = twlreg_probe, - .remove = twlreg_remove, /* NOTE: short name, to work around driver model truncation of * "twl_regulator.12" (and friends) to "twl_regulator.1". */ -- cgit v1.2.2 From d7da152c52c15b41e4b4c9a9319d844a890ecb09 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 16 Jun 2014 10:12:25 +0800 Subject: regulator: max8952: Convert to devm_gpio_request_one() Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/max8952.c | 34 ++++++++++------------------------ 1 file changed, 10 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/max8952.c b/drivers/regulator/max8952.c index c2792f0271ab..f7f9efcfedb7 100644 --- a/drivers/regulator/max8952.c +++ b/drivers/regulator/max8952.c @@ -229,7 +229,6 @@ static int max8952_pmic_probe(struct i2c_client *client, config.ena_gpio_flags |= GPIOF_OUT_INIT_HIGH; rdev = devm_regulator_register(&client->dev, ®ulator, &config); - if (IS_ERR(rdev)) { ret = PTR_ERR(rdev); dev_err(&client->dev, "regulator init failed (%d)\n", ret); @@ -241,21 +240,19 @@ static int max8952_pmic_probe(struct i2c_client *client, if (gpio_is_valid(pdata->gpio_vid0) && gpio_is_valid(pdata->gpio_vid1)) { - if (!gpio_request(pdata->gpio_vid0, "MAX8952 VID0")) - gpio_direction_output(pdata->gpio_vid0, - (pdata->default_mode) & 0x1); - else + unsigned long gpio_flags; + + gpio_flags = max8952->vid0 ? + GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW; + if (devm_gpio_request_one(&client->dev, pdata->gpio_vid0, + gpio_flags, "MAX8952 VID0")) err = 1; - if (!gpio_request(pdata->gpio_vid1, "MAX8952 VID1")) - gpio_direction_output(pdata->gpio_vid1, - (pdata->default_mode >> 1) & 0x1); - else { - if (!err) - gpio_free(pdata->gpio_vid0); + gpio_flags = max8952->vid1 ? + GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW; + if (devm_gpio_request_one(&client->dev, pdata->gpio_vid1, + gpio_flags, "MAX8952 VID1")) err = 2; - } - } else err = 3; @@ -314,16 +311,6 @@ static int max8952_pmic_probe(struct i2c_client *client, return 0; } -static int max8952_pmic_remove(struct i2c_client *client) -{ - struct max8952_data *max8952 = i2c_get_clientdata(client); - struct max8952_platform_data *pdata = max8952->pdata; - - gpio_free(pdata->gpio_vid0); - gpio_free(pdata->gpio_vid1); - return 0; -} - static const struct i2c_device_id max8952_ids[] = { { "max8952", 0 }, { }, @@ -332,7 +319,6 @@ MODULE_DEVICE_TABLE(i2c, max8952_ids); static struct i2c_driver max8952_pmic_driver = { .probe = max8952_pmic_probe, - .remove = max8952_pmic_remove, .driver = { .name = "max8952", .of_match_table = of_match_ptr(max8952_dt_match), -- cgit v1.2.2 From 778b28b4348af9c72bb5ac0dc129363a706325ef Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 29 Jun 2014 17:55:54 +0100 Subject: regulator: core: convert to use gpio_desc internally Convert the regulator GPIO handling to use a gpio descriptor rather than numbers. This allows us to revise the interfaces to permit all GPIOs to be used with the regulator core. Signed-off-by: Russell King Signed-off-by: Mark Brown --- drivers/regulator/core.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 4c1f999041dd..03ce33387a5d 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -77,7 +78,7 @@ struct regulator_map { */ struct regulator_enable_gpio { struct list_head list; - int gpio; + struct gpio_desc *gpiod; u32 enable_count; /* a number of enabled shared GPIO */ u32 request_count; /* a number of requested shared GPIO */ unsigned int ena_gpio_invert:1; @@ -1660,10 +1661,13 @@ static int regulator_ena_gpio_request(struct regulator_dev *rdev, const struct regulator_config *config) { struct regulator_enable_gpio *pin; + struct gpio_desc *gpiod; int ret; + gpiod = gpio_to_desc(config->ena_gpio); + list_for_each_entry(pin, ®ulator_ena_gpio_list, list) { - if (pin->gpio == config->ena_gpio) { + if (pin->gpiod == gpiod) { rdev_dbg(rdev, "GPIO %d is already used\n", config->ena_gpio); goto update_ena_gpio_to_rdev; @@ -1682,7 +1686,7 @@ static int regulator_ena_gpio_request(struct regulator_dev *rdev, return -ENOMEM; } - pin->gpio = config->ena_gpio; + pin->gpiod = gpiod; pin->ena_gpio_invert = config->ena_gpio_invert; list_add(&pin->list, ®ulator_ena_gpio_list); @@ -1701,10 +1705,10 @@ static void regulator_ena_gpio_free(struct regulator_dev *rdev) /* Free the GPIO only in case of no use */ list_for_each_entry_safe(pin, n, ®ulator_ena_gpio_list, list) { - if (pin->gpio == rdev->ena_pin->gpio) { + if (pin->gpiod == rdev->ena_pin->gpiod) { if (pin->request_count <= 1) { pin->request_count = 0; - gpio_free(pin->gpio); + gpiod_put(pin->gpiod); list_del(&pin->list); kfree(pin); } else { @@ -1732,8 +1736,8 @@ static int regulator_ena_gpio_ctrl(struct regulator_dev *rdev, bool enable) if (enable) { /* Enable GPIO at initial use */ if (pin->enable_count == 0) - gpio_set_value_cansleep(pin->gpio, - !pin->ena_gpio_invert); + gpiod_set_value_cansleep(pin->gpiod, + !pin->ena_gpio_invert); pin->enable_count++; } else { @@ -1744,8 +1748,8 @@ static int regulator_ena_gpio_ctrl(struct regulator_dev *rdev, bool enable) /* Disable GPIO if not used */ if (pin->enable_count <= 1) { - gpio_set_value_cansleep(pin->gpio, - pin->ena_gpio_invert); + gpiod_set_value_cansleep(pin->gpiod, + pin->ena_gpio_invert); pin->enable_count = 0; } } -- cgit v1.2.2 From 4b09e17b6f9cec1b50991fa66d7b51bef38221d8 Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Mon, 30 Jun 2014 10:57:34 -0500 Subject: regulator: palmas: Squelch sparse warnings convert to static variables to squelch the following sparse warnings: drivers/regulator/palmas-regulator.c:325:36: warning: symbol 'palma_sleep_req_info' was not declared. Should it be static? drivers/regulator/palmas-regulator.c:1414:32: warning: symbol 'palmas_ddata' was not declared. Should it be static? drivers/regulator/palmas-regulator.c:1427:32: warning: symbol 'tps65917_ddata' was not declared. Should it be static? Signed-off-by: Nishanth Menon Tested-by: Stephen Warren Tested-by: Keerthy Signed-off-by: Mark Brown --- drivers/regulator/palmas-regulator.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c index 7c8b4417d7d8..91f60fa91d4b 100644 --- a/drivers/regulator/palmas-regulator.c +++ b/drivers/regulator/palmas-regulator.c @@ -322,7 +322,7 @@ static struct regs_info tps65917_regs_info[] = { .bit_pos = _pos, \ } -struct palmas_sleep_requestor_info palma_sleep_req_info[] = { +static struct palmas_sleep_requestor_info palma_sleep_req_info[] = { EXTERNAL_REQUESTOR(REGEN1, 0, 0), EXTERNAL_REQUESTOR(REGEN2, 0, 1), EXTERNAL_REQUESTOR(SYSEN1, 0, 2), @@ -1408,7 +1408,7 @@ static struct of_regulator_match tps65917_matches[] = { { .name = "sysen2", }, }; -struct palmas_pmic_driver_data palmas_ddata = { +static struct palmas_pmic_driver_data palmas_ddata = { .smps_start = PALMAS_REG_SMPS12, .smps_end = PALMAS_REG_SMPS10_OUT1, .ldo_begin = PALMAS_REG_LDO1, @@ -1421,7 +1421,7 @@ struct palmas_pmic_driver_data palmas_ddata = { .ldo_register = palmas_ldo_registration, }; -struct palmas_pmic_driver_data tps65917_ddata = { +static struct palmas_pmic_driver_data tps65917_ddata = { .smps_start = TPS65917_REG_SMPS1, .smps_end = TPS65917_REG_SMPS5, .ldo_begin = TPS65917_REG_LDO1, -- cgit v1.2.2 From e7cf34ef396d6ceaa776661830d4ce332da650f0 Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Mon, 30 Jun 2014 10:57:35 -0500 Subject: regulator: palmas: Rename reg_info to palmas_reg_info reg_info is a generic term which might cause conflict at a later point in time. To prevent such a thing from occuring in future, rename to palmas_reg_info. Signed-off-by: Nishanth Menon Acked-by: Lee Jones Tested-by: Stephen Warren Tested-by: Keerthy Signed-off-by: Mark Brown --- drivers/regulator/palmas-regulator.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c index 91f60fa91d4b..05f11b96e17f 100644 --- a/drivers/regulator/palmas-regulator.c +++ b/drivers/regulator/palmas-regulator.c @@ -41,7 +41,7 @@ static const struct regulator_linear_range smps_high_ranges[] = { REGULATOR_LINEAR_RANGE(3300000, 0x7A, 0x7f, 0), }; -static struct regs_info palmas_regs_info[] = { +static struct palmas_regs_info palmas_regs_info[] = { { .name = "SMPS12", .sname = "smps1-in", @@ -227,7 +227,7 @@ static struct regs_info palmas_regs_info[] = { }, }; -static struct regs_info tps65917_regs_info[] = { +static struct palmas_regs_info tps65917_regs_info[] = { { .name = "SMPS1", .sname = "smps1-in", -- cgit v1.2.2 From cf910b6b7101dae5eabaf2249b427e7698095abd Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Mon, 30 Jun 2014 10:57:36 -0500 Subject: regulator: palmas: Simplify code by using pointer to palmas_reg_info Palmas register information is part of the ddata pointer which is used through out the code by indexing off the driver data array. Instead, just do the indexing once and use the pointer to further reference structure fields. This simplifies code and prevents errors by accessing wrong variables. Signed-off-by: Nishanth Menon Tested-by: Stephen Warren Tested-by: Keerthy Signed-off-by: Mark Brown --- drivers/regulator/palmas-regulator.c | 109 ++++++++++++++++++----------------- 1 file changed, 56 insertions(+), 53 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c index 05f11b96e17f..f75fb90d7db3 100644 --- a/drivers/regulator/palmas-regulator.c +++ b/drivers/regulator/palmas-regulator.c @@ -434,14 +434,14 @@ static int palmas_ldo_write(struct palmas *palmas, unsigned int reg, static int palmas_set_mode_smps(struct regulator_dev *dev, unsigned int mode) { + int id = rdev_get_id(dev); struct palmas_pmic *pmic = rdev_get_drvdata(dev); struct palmas_pmic_driver_data *ddata = pmic->palmas->pmic_ddata; - int id = rdev_get_id(dev); + struct palmas_regs_info *rinfo = &ddata->palmas_regs_info[id]; unsigned int reg; bool rail_enable = true; - palmas_smps_read(pmic->palmas, ddata->palmas_regs_info[id].ctrl_addr, - ®); + palmas_smps_read(pmic->palmas, rinfo->ctrl_addr, ®); reg &= ~PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK; @@ -464,8 +464,7 @@ static int palmas_set_mode_smps(struct regulator_dev *dev, unsigned int mode) pmic->current_reg_mode[id] = reg & PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK; if (rail_enable) - palmas_smps_write(pmic->palmas, - ddata->palmas_regs_info[id].ctrl_addr, reg); + palmas_smps_write(pmic->palmas, rinfo->ctrl_addr, reg); /* Switch the enable value to ensure this is used for enable */ pmic->desc[id].enable_val = pmic->current_reg_mode[id]; @@ -496,11 +495,11 @@ static unsigned int palmas_get_mode_smps(struct regulator_dev *dev) static int palmas_smps_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay) { + int id = rdev_get_id(rdev); struct palmas_pmic *pmic = rdev_get_drvdata(rdev); struct palmas_pmic_driver_data *ddata = pmic->palmas->pmic_ddata; - int id = rdev_get_id(rdev); + struct palmas_regs_info *rinfo = &ddata->palmas_regs_info[id]; unsigned int reg = 0; - unsigned int addr = ddata->palmas_regs_info[id].tstep_addr; int ret; /* SMPS3 and SMPS7 do not have tstep_addr setting */ @@ -519,7 +518,7 @@ static int palmas_smps_set_ramp_delay(struct regulator_dev *rdev, else reg = 1; - ret = palmas_smps_write(pmic->palmas, addr, reg); + ret = palmas_smps_write(pmic->palmas, rinfo->tstep_addr, reg); if (ret < 0) { dev_err(pmic->palmas->dev, "TSTEP write failed: %d\n", ret); return ret; @@ -590,13 +589,13 @@ static struct regulator_ops tps65917_ops_ext_control_smps = { static int palmas_is_enabled_ldo(struct regulator_dev *dev) { + int id = rdev_get_id(dev); struct palmas_pmic *pmic = rdev_get_drvdata(dev); struct palmas_pmic_driver_data *ddata = pmic->palmas->pmic_ddata; - int id = rdev_get_id(dev); + struct palmas_regs_info *rinfo = &ddata->palmas_regs_info[id]; unsigned int reg; - palmas_ldo_read(pmic->palmas, - ddata->palmas_regs_info[id].ctrl_addr, ®); + palmas_ldo_read(pmic->palmas, rinfo->ctrl_addr, ®); reg &= PALMAS_LDO1_CTRL_STATUS; @@ -643,11 +642,12 @@ static struct regulator_ops tps65917_ops_ldo = { static int palmas_regulator_config_external(struct palmas *palmas, int id, struct palmas_reg_init *reg_init) { - int sleep_id = palmas_regs_info[id].sleep_id; + struct palmas_pmic_driver_data *ddata = palmas->pmic_ddata; + struct palmas_regs_info *rinfo = &ddata->palmas_regs_info[id]; int ret; - ret = palmas_ext_control_req_config(palmas, sleep_id, - reg_init->roof_floor, true); + ret = palmas_ext_control_req_config(palmas, rinfo->sleep_id, + reg_init->roof_floor, true); if (ret < 0) dev_err(palmas->dev, "Ext control config for regulator %d failed %d\n", @@ -665,12 +665,10 @@ static int palmas_smps_init(struct palmas *palmas, int id, struct palmas_reg_init *reg_init) { unsigned int reg; - unsigned int addr; int ret; - struct palmas_pmic_driver_data *ddata = palmas->pmic_ddata; - - addr = ddata->palmas_regs_info[id].ctrl_addr; + struct palmas_regs_info *rinfo = &ddata->palmas_regs_info[id]; + unsigned int addr = rinfo->ctrl_addr; ret = palmas_smps_read(palmas, addr, ®); if (ret) @@ -705,12 +703,11 @@ static int palmas_smps_init(struct palmas *palmas, int id, if (ret) return ret; - if (ddata->palmas_regs_info[id].vsel_addr && reg_init->vsel) { - addr = ddata->palmas_regs_info[id].vsel_addr; + if (rinfo->vsel_addr && reg_init->vsel) { reg = reg_init->vsel; - ret = palmas_smps_write(palmas, addr, reg); + ret = palmas_smps_write(palmas, rinfo->vsel_addr, reg); if (ret) return ret; } @@ -718,7 +715,6 @@ static int palmas_smps_init(struct palmas *palmas, int id, if (reg_init->roof_floor && (id != PALMAS_REG_SMPS10_OUT1) && (id != PALMAS_REG_SMPS10_OUT2)) { /* Enable externally controlled regulator */ - addr = ddata->palmas_regs_info[id].ctrl_addr; ret = palmas_smps_read(palmas, addr, ®); if (ret < 0) return ret; @@ -740,10 +736,10 @@ static int palmas_ldo_init(struct palmas *palmas, int id, unsigned int reg; unsigned int addr; int ret; - struct palmas_pmic_driver_data *ddata = palmas->pmic_ddata; + struct palmas_regs_info *rinfo = &ddata->palmas_regs_info[id]; - addr = ddata->palmas_regs_info[id].ctrl_addr; + addr = rinfo->ctrl_addr; ret = palmas_ldo_read(palmas, addr, ®); if (ret) @@ -765,7 +761,6 @@ static int palmas_ldo_init(struct palmas *palmas, int id, if (reg_init->roof_floor) { /* Enable externally controlled regulator */ - addr = ddata->palmas_regs_info[id].ctrl_addr; ret = palmas_update_bits(palmas, PALMAS_LDO_BASE, addr, PALMAS_LDO1_CTRL_MODE_ACTIVE, PALMAS_LDO1_CTRL_MODE_ACTIVE); @@ -786,10 +781,10 @@ static int palmas_extreg_init(struct palmas *palmas, int id, unsigned int addr; int ret; unsigned int val = 0; - struct palmas_pmic_driver_data *ddata = palmas->pmic_ddata; + struct palmas_regs_info *rinfo = &ddata->palmas_regs_info[id]; - addr = ddata->palmas_regs_info[id].ctrl_addr; + addr = rinfo->ctrl_addr; if (reg_init->mode_sleep) val = PALMAS_REGEN1_CTRL_MODE_SLEEP; @@ -804,7 +799,6 @@ static int palmas_extreg_init(struct palmas *palmas, int id, if (reg_init->roof_floor) { /* Enable externally controlled regulator */ - addr = ddata->palmas_regs_info[id].ctrl_addr; ret = palmas_update_bits(palmas, PALMAS_RESOURCE_BASE, addr, PALMAS_REGEN1_CTRL_MODE_ACTIVE, PALMAS_REGEN1_CTRL_MODE_ACTIVE); @@ -824,10 +818,11 @@ static void palmas_enable_ldo8_track(struct palmas *palmas) unsigned int reg; unsigned int addr; int ret; - struct palmas_pmic_driver_data *ddata = palmas->pmic_ddata; + struct palmas_regs_info *rinfo; - addr = ddata->palmas_regs_info[PALMAS_REG_LDO8].ctrl_addr; + rinfo = &ddata->palmas_regs_info[PALMAS_REG_LDO8]; + addr = rinfo->ctrl_addr; ret = palmas_ldo_read(palmas, addr, ®); if (ret) { @@ -846,7 +841,7 @@ static void palmas_enable_ldo8_track(struct palmas *palmas) * output is defined by the LDO8_VOLTAGE.VSEL register divided by two, * and can be set from 0.45 to 1.65 V. */ - addr = ddata->palmas_regs_info[PALMAS_REG_LDO8].vsel_addr; + addr = rinfo->vsel_addr; ret = palmas_ldo_read(palmas, addr, ®); if (ret) { dev_err(palmas->dev, "Error in reading ldo8 voltage reg\n"); @@ -870,6 +865,7 @@ static int palmas_ldo_registration(struct palmas_pmic *pmic, int id, ret; struct regulator_dev *rdev; struct palmas_reg_init *reg_init; + struct palmas_regs_info *rinfo; for (id = ddata->ldo_begin; id < ddata->max_reg; id++) { if (pdata && pdata->reg_init[id]) @@ -877,12 +873,13 @@ static int palmas_ldo_registration(struct palmas_pmic *pmic, else reg_init = NULL; + rinfo = &ddata->palmas_regs_info[id]; /* Miss out regulators which are not available due * to alternate functions. */ /* Register the regulators */ - pmic->desc[id].name = ddata->palmas_regs_info[id].name; + pmic->desc[id].name = rinfo->name; pmic->desc[id].id = id; pmic->desc[id].type = REGULATOR_VOLTAGE; pmic->desc[id].owner = THIS_MODULE; @@ -900,12 +897,12 @@ static int palmas_ldo_registration(struct palmas_pmic *pmic, pmic->desc[id].enable_time = 500; pmic->desc[id].vsel_reg = PALMAS_BASE_TO_REG(PALMAS_LDO_BASE, - ddata->palmas_regs_info[id].vsel_addr); + rinfo->vsel_addr); pmic->desc[id].vsel_mask = PALMAS_LDO1_VOLTAGE_VSEL_MASK; pmic->desc[id].enable_reg = PALMAS_BASE_TO_REG(PALMAS_LDO_BASE, - ddata->palmas_regs_info[id].ctrl_addr); + rinfo->ctrl_addr); pmic->desc[id].enable_mask = PALMAS_LDO1_CTRL_MODE_ACTIVE; @@ -930,7 +927,7 @@ static int palmas_ldo_registration(struct palmas_pmic *pmic, pmic->desc[id].ops = &palmas_ops_extreg; pmic->desc[id].enable_reg = PALMAS_BASE_TO_REG(PALMAS_RESOURCE_BASE, - ddata->palmas_regs_info[id].ctrl_addr); + rinfo->ctrl_addr); pmic->desc[id].enable_mask = PALMAS_REGEN1_CTRL_MODE_ACTIVE; } @@ -940,7 +937,7 @@ static int palmas_ldo_registration(struct palmas_pmic *pmic, else config.init_data = NULL; - pmic->desc[id].supply_name = ddata->palmas_regs_info[id].sname; + pmic->desc[id].supply_name = rinfo->sname; config.of_node = ddata->palmas_matches[id].of_node; rdev = devm_regulator_register(pmic->dev, &pmic->desc[id], @@ -983,6 +980,7 @@ static int tps65917_ldo_registration(struct palmas_pmic *pmic, int id, ret; struct regulator_dev *rdev; struct palmas_reg_init *reg_init; + struct palmas_regs_info *rinfo; for (id = ddata->ldo_begin; id < ddata->max_reg; id++) { if (pdata && pdata->reg_init[id]) @@ -993,9 +991,10 @@ static int tps65917_ldo_registration(struct palmas_pmic *pmic, /* Miss out regulators which are not available due * to alternate functions. */ + rinfo = &ddata->palmas_regs_info[id]; /* Register the regulators */ - pmic->desc[id].name = ddata->palmas_regs_info[id].name; + pmic->desc[id].name = rinfo->name; pmic->desc[id].id = id; pmic->desc[id].type = REGULATOR_VOLTAGE; pmic->desc[id].owner = THIS_MODULE; @@ -1013,12 +1012,12 @@ static int tps65917_ldo_registration(struct palmas_pmic *pmic, pmic->desc[id].enable_time = 500; pmic->desc[id].vsel_reg = PALMAS_BASE_TO_REG(PALMAS_LDO_BASE, - ddata->palmas_regs_info[id].vsel_addr); + rinfo->vsel_addr); pmic->desc[id].vsel_mask = PALMAS_LDO1_VOLTAGE_VSEL_MASK; pmic->desc[id].enable_reg = PALMAS_BASE_TO_REG(PALMAS_LDO_BASE, - ddata->palmas_regs_info[id].ctrl_addr); + rinfo->ctrl_addr); pmic->desc[id].enable_mask = PALMAS_LDO1_CTRL_MODE_ACTIVE; /* @@ -1035,7 +1034,7 @@ static int tps65917_ldo_registration(struct palmas_pmic *pmic, pmic->desc[id].ops = &palmas_ops_extreg; pmic->desc[id].enable_reg = PALMAS_BASE_TO_REG(PALMAS_RESOURCE_BASE, - ddata->palmas_regs_info[id].ctrl_addr); + rinfo->ctrl_addr); pmic->desc[id].enable_mask = PALMAS_REGEN1_CTRL_MODE_ACTIVE; } @@ -1045,7 +1044,7 @@ static int tps65917_ldo_registration(struct palmas_pmic *pmic, else config.init_data = NULL; - pmic->desc[id].supply_name = ddata->palmas_regs_info[id].sname; + pmic->desc[id].supply_name = rinfo->sname; config.of_node = ddata->palmas_matches[id].of_node; rdev = devm_regulator_register(pmic->dev, &pmic->desc[id], @@ -1089,6 +1088,7 @@ static int palmas_smps_registration(struct palmas_pmic *pmic, unsigned int addr, reg; struct regulator_dev *rdev; struct palmas_reg_init *reg_init; + struct palmas_regs_info *rinfo; for (id = ddata->smps_start; id <= ddata->smps_end; id++) { bool ramp_delay_support = false; @@ -1127,12 +1127,13 @@ static int palmas_smps_registration(struct palmas_pmic *pmic, if (!PALMAS_PMIC_HAS(pmic->palmas, SMPS10_BOOST)) continue; } + rinfo = &ddata->palmas_regs_info[id]; if ((id == PALMAS_REG_SMPS6) || (id == PALMAS_REG_SMPS8)) ramp_delay_support = true; if (ramp_delay_support) { - addr = ddata->palmas_regs_info[id].tstep_addr; + addr = rinfo->tstep_addr; ret = palmas_smps_read(pmic->palmas, addr, ®); if (ret < 0) { dev_err(pmic->dev, @@ -1155,7 +1156,7 @@ static int palmas_smps_registration(struct palmas_pmic *pmic, } /* Register the regulators */ - pmic->desc[id].name = ddata->palmas_regs_info[id].name; + pmic->desc[id].name = rinfo->name; pmic->desc[id].id = id; switch (id) { @@ -1188,7 +1189,7 @@ static int palmas_smps_registration(struct palmas_pmic *pmic, * otherwise we error in probe with unsupportable * ranges. Read the current smps mode for later use. */ - addr = palmas_regs_info[id].vsel_addr; + addr = rinfo->vsel_addr; pmic->desc[id].n_linear_ranges = 3; ret = palmas_smps_read(pmic->palmas, addr, ®); @@ -1209,12 +1210,12 @@ static int palmas_smps_registration(struct palmas_pmic *pmic, pmic->desc[id].n_voltages = PALMAS_SMPS_NUM_VOLTAGES; pmic->desc[id].vsel_reg = PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE, - palmas_regs_info[id].vsel_addr); + rinfo->vsel_addr); pmic->desc[id].vsel_mask = PALMAS_SMPS12_VOLTAGE_VSEL_MASK; /* Read the smps mode for later use. */ - addr = palmas_regs_info[id].ctrl_addr; + addr = rinfo->ctrl_addr; ret = palmas_smps_read(pmic->palmas, addr, ®); if (ret) return ret; @@ -1223,7 +1224,7 @@ static int palmas_smps_registration(struct palmas_pmic *pmic, pmic->desc[id].enable_reg = PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE, - palmas_regs_info[id].ctrl_addr); + rinfo->ctrl_addr); pmic->desc[id].enable_mask = PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK; /* set_mode overrides this value */ @@ -1238,7 +1239,7 @@ static int palmas_smps_registration(struct palmas_pmic *pmic, else config.init_data = NULL; - pmic->desc[id].supply_name = ddata->palmas_regs_info[id].sname; + pmic->desc[id].supply_name = rinfo->sname; config.of_node = ddata->palmas_matches[id].of_node; rdev = devm_regulator_register(pmic->dev, &pmic->desc[id], @@ -1267,6 +1268,7 @@ static int tps65917_smps_registration(struct palmas_pmic *pmic, unsigned int addr, reg; struct regulator_dev *rdev; struct palmas_reg_init *reg_init; + struct palmas_regs_info *rinfo; for (id = ddata->smps_start; id <= ddata->smps_end; id++) { /* @@ -1286,9 +1288,10 @@ static int tps65917_smps_registration(struct palmas_pmic *pmic, } else { reg_init = NULL; } + rinfo = &ddata->palmas_regs_info[id]; /* Register the regulators */ - pmic->desc[id].name = ddata->palmas_regs_info[id].name; + pmic->desc[id].name = rinfo->name; pmic->desc[id].id = id; /* @@ -1297,7 +1300,7 @@ static int tps65917_smps_registration(struct palmas_pmic *pmic, * otherwise we error in probe with unsupportable * ranges. Read the current smps mode for later use. */ - addr = ddata->palmas_regs_info[id].vsel_addr; + addr = rinfo->vsel_addr; ret = palmas_smps_read(pmic->palmas, addr, ®); if (ret) @@ -1319,14 +1322,14 @@ static int tps65917_smps_registration(struct palmas_pmic *pmic, pmic->desc[id].n_voltages = PALMAS_SMPS_NUM_VOLTAGES; pmic->desc[id].vsel_reg = PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE, - tps65917_regs_info[id].vsel_addr); + rinfo->vsel_addr); pmic->desc[id].vsel_mask = PALMAS_SMPS12_VOLTAGE_VSEL_MASK; pmic->desc[id].ramp_delay = 2500; /* Read the smps mode for later use. */ - addr = ddata->palmas_regs_info[id].ctrl_addr; + addr = rinfo->ctrl_addr; ret = palmas_smps_read(pmic->palmas, addr, ®); if (ret) return ret; @@ -1341,7 +1344,7 @@ static int tps65917_smps_registration(struct palmas_pmic *pmic, else config.init_data = NULL; - pmic->desc[id].supply_name = ddata->palmas_regs_info[id].sname; + pmic->desc[id].supply_name = rinfo->sname; config.of_node = ddata->palmas_matches[id].of_node; rdev = devm_regulator_register(pmic->dev, &pmic->desc[id], -- cgit v1.2.2 From 6839cd6f6487969e969ced2245bfdabaf7005f6b Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Mon, 30 Jun 2014 10:57:37 -0500 Subject: regulator: palmas: Rename palmas_regs_info to palmas_generic_regs_info With commit d6f83370ed978d5570b7c8c22988310cb9376202 (regulator: palmas: Add tps65917 PMIC support) palmas_regs_info naming is confusing as it is a driver data parameter and a local variable. To prevent mistaken updates, rename the local variable to palmas_generic_regs_info. Signed-off-by: Nishanth Menon Tested-by: Stephen Warren Tested-by: Keerthy Signed-off-by: Mark Brown --- drivers/regulator/palmas-regulator.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c index f75fb90d7db3..d6b734f397dc 100644 --- a/drivers/regulator/palmas-regulator.c +++ b/drivers/regulator/palmas-regulator.c @@ -41,7 +41,7 @@ static const struct regulator_linear_range smps_high_ranges[] = { REGULATOR_LINEAR_RANGE(3300000, 0x7A, 0x7f, 0), }; -static struct palmas_regs_info palmas_regs_info[] = { +static struct palmas_regs_info palmas_generic_regs_info[] = { { .name = "SMPS12", .sname = "smps1-in", @@ -1417,7 +1417,7 @@ static struct palmas_pmic_driver_data palmas_ddata = { .ldo_begin = PALMAS_REG_LDO1, .ldo_end = PALMAS_REG_LDOUSB, .max_reg = PALMAS_NUM_REGS, - .palmas_regs_info = palmas_regs_info, + .palmas_regs_info = palmas_generic_regs_info, .palmas_matches = palmas_matches, .sleep_req_info = palma_sleep_req_info, .smps_register = palmas_smps_registration, -- cgit v1.2.2 From 429222d00531b348076862ea4fd8cd694bf064a9 Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Mon, 30 Jun 2014 10:57:38 -0500 Subject: regulator: palmas: Simplify code by not indexing regulator_desc unnecessarily Palmas regulator needs to full up the regulator_desc based on PMIC and type of regulator. However, we dont need to do desc[id] every time. we can simplify by using a pointer to desc[id] and filling up the parameters. Signed-off-by: Nishanth Menon Tested-by: Stephen Warren Tested-by: Keerthy Signed-off-by: Mark Brown --- drivers/regulator/palmas-regulator.c | 248 ++++++++++++++++------------------- 1 file changed, 112 insertions(+), 136 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c index d6b734f397dc..ae0f639096fb 100644 --- a/drivers/regulator/palmas-regulator.c +++ b/drivers/regulator/palmas-regulator.c @@ -866,6 +866,7 @@ static int palmas_ldo_registration(struct palmas_pmic *pmic, struct regulator_dev *rdev; struct palmas_reg_init *reg_init; struct palmas_regs_info *rinfo; + struct regulator_desc *desc; for (id = ddata->ldo_begin; id < ddata->max_reg; id++) { if (pdata && pdata->reg_init[id]) @@ -879,57 +880,51 @@ static int palmas_ldo_registration(struct palmas_pmic *pmic, */ /* Register the regulators */ - pmic->desc[id].name = rinfo->name; - pmic->desc[id].id = id; - pmic->desc[id].type = REGULATOR_VOLTAGE; - pmic->desc[id].owner = THIS_MODULE; + desc = &pmic->desc[id]; + desc->name = rinfo->name; + desc->id = id; + desc->type = REGULATOR_VOLTAGE; + desc->owner = THIS_MODULE; if (id < PALMAS_REG_REGEN1) { - pmic->desc[id].n_voltages = PALMAS_LDO_NUM_VOLTAGES; + desc->n_voltages = PALMAS_LDO_NUM_VOLTAGES; if (reg_init && reg_init->roof_floor) - pmic->desc[id].ops = - &palmas_ops_ext_control_ldo; + desc->ops = &palmas_ops_ext_control_ldo; else - pmic->desc[id].ops = &palmas_ops_ldo; - pmic->desc[id].min_uV = 900000; - pmic->desc[id].uV_step = 50000; - pmic->desc[id].linear_min_sel = 1; - pmic->desc[id].enable_time = 500; - pmic->desc[id].vsel_reg = - PALMAS_BASE_TO_REG(PALMAS_LDO_BASE, - rinfo->vsel_addr); - pmic->desc[id].vsel_mask = - PALMAS_LDO1_VOLTAGE_VSEL_MASK; - pmic->desc[id].enable_reg = - PALMAS_BASE_TO_REG(PALMAS_LDO_BASE, - rinfo->ctrl_addr); - pmic->desc[id].enable_mask = - PALMAS_LDO1_CTRL_MODE_ACTIVE; + desc->ops = &palmas_ops_ldo; + desc->min_uV = 900000; + desc->uV_step = 50000; + desc->linear_min_sel = 1; + desc->enable_time = 500; + desc->vsel_reg = PALMAS_BASE_TO_REG(PALMAS_LDO_BASE, + rinfo->vsel_addr); + desc->vsel_mask = PALMAS_LDO1_VOLTAGE_VSEL_MASK; + desc->enable_reg = PALMAS_BASE_TO_REG(PALMAS_LDO_BASE, + rinfo->ctrl_addr); + desc->enable_mask = PALMAS_LDO1_CTRL_MODE_ACTIVE; /* Check if LDO8 is in tracking mode or not */ if (pdata && (id == PALMAS_REG_LDO8) && pdata->enable_ldo8_tracking) { palmas_enable_ldo8_track(pmic->palmas); - pmic->desc[id].min_uV = 450000; - pmic->desc[id].uV_step = 25000; + desc->min_uV = 450000; + desc->uV_step = 25000; } /* LOD6 in vibrator mode will have enable time 2000us */ if (pdata && pdata->ldo6_vibrator && (id == PALMAS_REG_LDO6)) - pmic->desc[id].enable_time = 2000; + desc->enable_time = 2000; } else { - pmic->desc[id].n_voltages = 1; + desc->n_voltages = 1; if (reg_init && reg_init->roof_floor) - pmic->desc[id].ops = - &palmas_ops_ext_control_extreg; + desc->ops = &palmas_ops_ext_control_extreg; else - pmic->desc[id].ops = &palmas_ops_extreg; - pmic->desc[id].enable_reg = + desc->ops = &palmas_ops_extreg; + desc->enable_reg = PALMAS_BASE_TO_REG(PALMAS_RESOURCE_BASE, rinfo->ctrl_addr); - pmic->desc[id].enable_mask = - PALMAS_REGEN1_CTRL_MODE_ACTIVE; + desc->enable_mask = PALMAS_REGEN1_CTRL_MODE_ACTIVE; } if (pdata) @@ -937,11 +932,10 @@ static int palmas_ldo_registration(struct palmas_pmic *pmic, else config.init_data = NULL; - pmic->desc[id].supply_name = rinfo->sname; + desc->supply_name = rinfo->sname; config.of_node = ddata->palmas_matches[id].of_node; - rdev = devm_regulator_register(pmic->dev, &pmic->desc[id], - &config); + rdev = devm_regulator_register(pmic->dev, desc, &config); if (IS_ERR(rdev)) { dev_err(pmic->dev, "failed to register %s regulator\n", @@ -981,6 +975,7 @@ static int tps65917_ldo_registration(struct palmas_pmic *pmic, struct regulator_dev *rdev; struct palmas_reg_init *reg_init; struct palmas_regs_info *rinfo; + struct regulator_desc *desc; for (id = ddata->ldo_begin; id < ddata->max_reg; id++) { if (pdata && pdata->reg_init[id]) @@ -994,49 +989,43 @@ static int tps65917_ldo_registration(struct palmas_pmic *pmic, rinfo = &ddata->palmas_regs_info[id]; /* Register the regulators */ - pmic->desc[id].name = rinfo->name; - pmic->desc[id].id = id; - pmic->desc[id].type = REGULATOR_VOLTAGE; - pmic->desc[id].owner = THIS_MODULE; + desc = &pmic->desc[id]; + desc->name = rinfo->name; + desc->id = id; + desc->type = REGULATOR_VOLTAGE; + desc->owner = THIS_MODULE; if (id < TPS65917_REG_REGEN1) { - pmic->desc[id].n_voltages = PALMAS_LDO_NUM_VOLTAGES; + desc->n_voltages = PALMAS_LDO_NUM_VOLTAGES; if (reg_init && reg_init->roof_floor) - pmic->desc[id].ops = - &palmas_ops_ext_control_ldo; + desc->ops = &palmas_ops_ext_control_ldo; else - pmic->desc[id].ops = &tps65917_ops_ldo; - pmic->desc[id].min_uV = 900000; - pmic->desc[id].uV_step = 50000; - pmic->desc[id].linear_min_sel = 1; - pmic->desc[id].enable_time = 500; - pmic->desc[id].vsel_reg = - PALMAS_BASE_TO_REG(PALMAS_LDO_BASE, - rinfo->vsel_addr); - pmic->desc[id].vsel_mask = - PALMAS_LDO1_VOLTAGE_VSEL_MASK; - pmic->desc[id].enable_reg = - PALMAS_BASE_TO_REG(PALMAS_LDO_BASE, - rinfo->ctrl_addr); - pmic->desc[id].enable_mask = - PALMAS_LDO1_CTRL_MODE_ACTIVE; + desc->ops = &tps65917_ops_ldo; + desc->min_uV = 900000; + desc->uV_step = 50000; + desc->linear_min_sel = 1; + desc->enable_time = 500; + desc->vsel_reg = PALMAS_BASE_TO_REG(PALMAS_LDO_BASE, + rinfo->vsel_addr); + desc->vsel_mask = PALMAS_LDO1_VOLTAGE_VSEL_MASK; + desc->enable_reg = PALMAS_BASE_TO_REG(PALMAS_LDO_BASE, + rinfo->ctrl_addr); + desc->enable_mask = PALMAS_LDO1_CTRL_MODE_ACTIVE; /* * To be confirmed. Discussion on going with PMIC Team. * It is of the order of ~60mV/uS. */ - pmic->desc[id].ramp_delay = 2500; + desc->ramp_delay = 2500; } else { - pmic->desc[id].n_voltages = 1; + desc->n_voltages = 1; if (reg_init && reg_init->roof_floor) - pmic->desc[id].ops = - &palmas_ops_ext_control_extreg; + desc->ops = &palmas_ops_ext_control_extreg; else - pmic->desc[id].ops = &palmas_ops_extreg; - pmic->desc[id].enable_reg = + desc->ops = &palmas_ops_extreg; + desc->enable_reg = PALMAS_BASE_TO_REG(PALMAS_RESOURCE_BASE, rinfo->ctrl_addr); - pmic->desc[id].enable_mask = - PALMAS_REGEN1_CTRL_MODE_ACTIVE; + desc->enable_mask = PALMAS_REGEN1_CTRL_MODE_ACTIVE; } if (pdata) @@ -1044,11 +1033,10 @@ static int tps65917_ldo_registration(struct palmas_pmic *pmic, else config.init_data = NULL; - pmic->desc[id].supply_name = rinfo->sname; + desc->supply_name = rinfo->sname; config.of_node = ddata->palmas_matches[id].of_node; - rdev = devm_regulator_register(pmic->dev, &pmic->desc[id], - &config); + rdev = devm_regulator_register(pmic->dev, desc, &config); if (IS_ERR(rdev)) { dev_err(pmic->dev, "failed to register %s regulator\n", @@ -1089,6 +1077,7 @@ static int palmas_smps_registration(struct palmas_pmic *pmic, struct regulator_dev *rdev; struct palmas_reg_init *reg_init; struct palmas_regs_info *rinfo; + struct regulator_desc *desc; for (id = ddata->smps_start; id <= ddata->smps_end; id++) { bool ramp_delay_support = false; @@ -1128,6 +1117,7 @@ static int palmas_smps_registration(struct palmas_pmic *pmic, continue; } rinfo = &ddata->palmas_regs_info[id]; + desc = &pmic->desc[id]; if ((id == PALMAS_REG_SMPS6) || (id == PALMAS_REG_SMPS8)) ramp_delay_support = true; @@ -1140,9 +1130,8 @@ static int palmas_smps_registration(struct palmas_pmic *pmic, "reading TSTEP reg failed: %d\n", ret); return ret; } - pmic->desc[id].ramp_delay = - palmas_smps_ramp_delay[reg & 0x3]; - pmic->ramp_delay[id] = pmic->desc[id].ramp_delay; + desc->ramp_delay = palmas_smps_ramp_delay[reg & 0x3]; + pmic->ramp_delay[id] = desc->ramp_delay; } /* Initialise sleep/init values from platform data */ @@ -1156,31 +1145,28 @@ static int palmas_smps_registration(struct palmas_pmic *pmic, } /* Register the regulators */ - pmic->desc[id].name = rinfo->name; - pmic->desc[id].id = id; + desc->name = rinfo->name; + desc->id = id; switch (id) { case PALMAS_REG_SMPS10_OUT1: case PALMAS_REG_SMPS10_OUT2: - pmic->desc[id].n_voltages = PALMAS_SMPS10_NUM_VOLTAGES; - pmic->desc[id].ops = &palmas_ops_smps10; - pmic->desc[id].vsel_reg = - PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE, - PALMAS_SMPS10_CTRL); - pmic->desc[id].vsel_mask = SMPS10_VSEL; - pmic->desc[id].enable_reg = - PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE, - PALMAS_SMPS10_CTRL); + desc->n_voltages = PALMAS_SMPS10_NUM_VOLTAGES; + desc->ops = &palmas_ops_smps10; + desc->vsel_reg = PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE, + PALMAS_SMPS10_CTRL); + desc->vsel_mask = SMPS10_VSEL; + desc->enable_reg = PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE, + PALMAS_SMPS10_CTRL); if (id == PALMAS_REG_SMPS10_OUT1) - pmic->desc[id].enable_mask = SMPS10_SWITCH_EN; + desc->enable_mask = SMPS10_SWITCH_EN; else - pmic->desc[id].enable_mask = SMPS10_BOOST_EN; - pmic->desc[id].bypass_reg = - PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE, - PALMAS_SMPS10_CTRL); - pmic->desc[id].bypass_mask = SMPS10_BYPASS_EN; - pmic->desc[id].min_uV = 3750000; - pmic->desc[id].uV_step = 1250000; + desc->enable_mask = SMPS10_BOOST_EN; + desc->bypass_reg = PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE, + PALMAS_SMPS10_CTRL); + desc->bypass_mask = SMPS10_BYPASS_EN; + desc->min_uV = 3750000; + desc->uV_step = 1250000; break; default: /* @@ -1190,7 +1176,7 @@ static int palmas_smps_registration(struct palmas_pmic *pmic, * ranges. Read the current smps mode for later use. */ addr = rinfo->vsel_addr; - pmic->desc[id].n_linear_ranges = 3; + desc->n_linear_ranges = 3; ret = palmas_smps_read(pmic->palmas, addr, ®); if (ret) @@ -1198,21 +1184,18 @@ static int palmas_smps_registration(struct palmas_pmic *pmic, if (reg & PALMAS_SMPS12_VOLTAGE_RANGE) pmic->range[id] = 1; if (pmic->range[id]) - pmic->desc[id].linear_ranges = smps_high_ranges; + desc->linear_ranges = smps_high_ranges; else - pmic->desc[id].linear_ranges = smps_low_ranges; + desc->linear_ranges = smps_low_ranges; if (reg_init && reg_init->roof_floor) - pmic->desc[id].ops = - &palmas_ops_ext_control_smps; + desc->ops = &palmas_ops_ext_control_smps; else - pmic->desc[id].ops = &palmas_ops_smps; - pmic->desc[id].n_voltages = PALMAS_SMPS_NUM_VOLTAGES; - pmic->desc[id].vsel_reg = - PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE, - rinfo->vsel_addr); - pmic->desc[id].vsel_mask = - PALMAS_SMPS12_VOLTAGE_VSEL_MASK; + desc->ops = &palmas_ops_smps; + desc->n_voltages = PALMAS_SMPS_NUM_VOLTAGES; + desc->vsel_reg = PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE, + rinfo->vsel_addr); + desc->vsel_mask = PALMAS_SMPS12_VOLTAGE_VSEL_MASK; /* Read the smps mode for later use. */ addr = rinfo->ctrl_addr; @@ -1222,28 +1205,25 @@ static int palmas_smps_registration(struct palmas_pmic *pmic, pmic->current_reg_mode[id] = reg & PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK; - pmic->desc[id].enable_reg = - PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE, - rinfo->ctrl_addr); - pmic->desc[id].enable_mask = - PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK; + desc->enable_reg = PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE, + rinfo->ctrl_addr); + desc->enable_mask = PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK; /* set_mode overrides this value */ - pmic->desc[id].enable_val = SMPS_CTRL_MODE_ON; + desc->enable_val = SMPS_CTRL_MODE_ON; } - pmic->desc[id].type = REGULATOR_VOLTAGE; - pmic->desc[id].owner = THIS_MODULE; + desc->type = REGULATOR_VOLTAGE; + desc->owner = THIS_MODULE; if (pdata) config.init_data = pdata->reg_data[id]; else config.init_data = NULL; - pmic->desc[id].supply_name = rinfo->sname; + desc->supply_name = rinfo->sname; config.of_node = ddata->palmas_matches[id].of_node; - rdev = devm_regulator_register(pmic->dev, &pmic->desc[id], - &config); + rdev = devm_regulator_register(pmic->dev, desc, &config); if (IS_ERR(rdev)) { dev_err(pmic->dev, "failed to register %s regulator\n", @@ -1269,13 +1249,15 @@ static int tps65917_smps_registration(struct palmas_pmic *pmic, struct regulator_dev *rdev; struct palmas_reg_init *reg_init; struct palmas_regs_info *rinfo; + struct regulator_desc *desc; for (id = ddata->smps_start; id <= ddata->smps_end; id++) { /* * Miss out regulators which are not available due * to slaving configurations. */ - pmic->desc[id].n_linear_ranges = 3; + desc = &pmic->desc[id]; + desc->n_linear_ranges = 3; if ((id == TPS65917_REG_SMPS2) && pmic->smps12) continue; @@ -1291,8 +1273,8 @@ static int tps65917_smps_registration(struct palmas_pmic *pmic, rinfo = &ddata->palmas_regs_info[id]; /* Register the regulators */ - pmic->desc[id].name = rinfo->name; - pmic->desc[id].id = id; + desc->name = rinfo->name; + desc->id = id; /* * Read and store the RANGE bit for later use @@ -1309,24 +1291,19 @@ static int tps65917_smps_registration(struct palmas_pmic *pmic, pmic->range[id] = 1; if (pmic->range[id]) - pmic->desc[id].linear_ranges = smps_high_ranges; - else - pmic->desc[id].linear_ranges = smps_low_ranges; - + desc->linear_ranges = smps_high_ranges; + else + desc->linear_ranges = smps_low_ranges; if (reg_init && reg_init->roof_floor) - pmic->desc[id].ops = - &tps65917_ops_ext_control_smps; + desc->ops = &tps65917_ops_ext_control_smps; else - pmic->desc[id].ops = &tps65917_ops_smps; - pmic->desc[id].n_voltages = PALMAS_SMPS_NUM_VOLTAGES; - pmic->desc[id].vsel_reg = - PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE, - rinfo->vsel_addr); - pmic->desc[id].vsel_mask = - PALMAS_SMPS12_VOLTAGE_VSEL_MASK; - - pmic->desc[id].ramp_delay = 2500; + desc->ops = &tps65917_ops_smps; + desc->n_voltages = PALMAS_SMPS_NUM_VOLTAGES; + desc->vsel_reg = PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE, + rinfo->vsel_addr); + desc->vsel_mask = PALMAS_SMPS12_VOLTAGE_VSEL_MASK; + desc->ramp_delay = 2500; /* Read the smps mode for later use. */ addr = rinfo->ctrl_addr; @@ -1336,19 +1313,18 @@ static int tps65917_smps_registration(struct palmas_pmic *pmic, pmic->current_reg_mode[id] = reg & PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK; - pmic->desc[id].type = REGULATOR_VOLTAGE; - pmic->desc[id].owner = THIS_MODULE; + desc->type = REGULATOR_VOLTAGE; + desc->owner = THIS_MODULE; if (pdata) config.init_data = pdata->reg_data[id]; else config.init_data = NULL; - pmic->desc[id].supply_name = rinfo->sname; + desc->supply_name = rinfo->sname; config.of_node = ddata->palmas_matches[id].of_node; - rdev = devm_regulator_register(pmic->dev, &pmic->desc[id], - &config); + rdev = devm_regulator_register(pmic->dev, desc, &config); if (IS_ERR(rdev)) { dev_err(pmic->dev, "failed to register %s regulator\n", -- cgit v1.2.2 From b632815e9a8d2f8c0c0486b209cf90fa942c527b Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Mon, 30 Jun 2014 10:57:39 -0500 Subject: regulator: palmas: Fix SMPS enable/disable/is_enable for tps65917 We use regmap regulator ops to enable/disable and check if regulator is enabled for various SMPS. However, these depend on valid enable_reg, enable_mask and enable_value in regulator descriptor. So, similar to fix we did in commit 318dbb02b50c ("regulator: palmas: Fix SMPS enable/disable/is_enabled"), populate the same for TPS65917 SMPS registration. LDO definitions are already in place. Fixes: d6f83370ed97 ("regulator: palmas: Add tps65917 PMIC support") Signed-off-by: Nishanth Menon Tested-by: Stephen Warren Tested-by: Keerthy Signed-off-by: Mark Brown --- drivers/regulator/palmas-regulator.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c index ae0f639096fb..a7ce34d1b5f2 100644 --- a/drivers/regulator/palmas-regulator.c +++ b/drivers/regulator/palmas-regulator.c @@ -1312,6 +1312,11 @@ static int tps65917_smps_registration(struct palmas_pmic *pmic, return ret; pmic->current_reg_mode[id] = reg & PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK; + desc->enable_reg = PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE, + rinfo->ctrl_addr); + desc->enable_mask = PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK; + /* set_mode overrides this value */ + desc->enable_val = SMPS_CTRL_MODE_ON; desc->type = REGULATOR_VOLTAGE; desc->owner = THIS_MODULE; -- cgit v1.2.2 From 5b919f3ebb533cbe400664837e24f66a0836b907 Mon Sep 17 00:00:00 2001 From: Nikesh Oswal Date: Fri, 4 Jul 2014 09:55:16 +0100 Subject: regulator: arizona-ldo1: remove bypass functionality WM5110/8280 devices do not support bypass mode for LDO1 so remove the bypass callbacks registered with regulator core. Signed-off-by: Nikesh Oswal Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- drivers/regulator/arizona-ldo1.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/arizona-ldo1.c b/drivers/regulator/arizona-ldo1.c index 04f262a836b2..4c9db589f6c1 100644 --- a/drivers/regulator/arizona-ldo1.c +++ b/drivers/regulator/arizona-ldo1.c @@ -143,8 +143,6 @@ static struct regulator_ops arizona_ldo1_ops = { .map_voltage = regulator_map_voltage_linear, .get_voltage_sel = regulator_get_voltage_sel_regmap, .set_voltage_sel = regulator_set_voltage_sel_regmap, - .get_bypass = regulator_get_bypass_regmap, - .set_bypass = regulator_set_bypass_regmap, }; static const struct regulator_desc arizona_ldo1 = { -- cgit v1.2.2 From 732714d0da4f3273e4b9a9dbe3e7556ea1188e36 Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Sat, 5 Jul 2014 15:20:53 +0200 Subject: regulator: act8865: set correct number of regulators in pdata act8865_pdata_from_dt() populates the array pdata->regulators with all the regulators and then assigns the field init_data only for the ones actually found in the DT. The patch changes the value assigned to pdata->num_regulators to match the size of the array. Signed-off-by: Beniamino Galvani Tested-by: Wenyou Yang Reviewed-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/act8865-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/regulator/act8865-regulator.c b/drivers/regulator/act8865-regulator.c index b92d7dd01a18..89f9f0c0f64d 100644 --- a/drivers/regulator/act8865-regulator.c +++ b/drivers/regulator/act8865-regulator.c @@ -230,7 +230,7 @@ static int act8865_pdata_from_dt(struct device *dev, if (!pdata->regulators) return -ENOMEM; - pdata->num_regulators = matched; + pdata->num_regulators = ARRAY_SIZE(act8865_matches); regulator = pdata->regulators; for (i = 0; i < ARRAY_SIZE(act8865_matches); i++) { -- cgit v1.2.2 From 42ab0f3915f22728f54bb1f3c0dcf38ab2335b5b Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 8 Jul 2014 14:09:12 -0500 Subject: regulator: tps65218: fix DCDC4 linear voltage range The second range of this particular regulator, starts at 1.60V, not as 1.55V as it was originally implied by code. Signed-off-by: Felipe Balbi Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- drivers/regulator/tps65218-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/regulator/tps65218-regulator.c b/drivers/regulator/tps65218-regulator.c index 9effe48c605e..8b7a0a9ebdfe 100644 --- a/drivers/regulator/tps65218-regulator.c +++ b/drivers/regulator/tps65218-regulator.c @@ -68,7 +68,7 @@ static const struct regulator_linear_range ldo1_dcdc3_ranges[] = { static const struct regulator_linear_range dcdc4_ranges[] = { REGULATOR_LINEAR_RANGE(1175000, 0x0, 0xf, 25000), - REGULATOR_LINEAR_RANGE(1550000, 0x10, 0x34, 50000), + REGULATOR_LINEAR_RANGE(1600000, 0x10, 0x34, 50000), }; static struct tps_info tps65218_pmic_regs[] = { -- cgit v1.2.2 From dd648ef2471602d5fc1ec80a546eb0c3f57ca172 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 8 Jul 2014 14:09:13 -0500 Subject: regulator: tps65218: drop unneeded field from our regulator macro volt table is always NULL for all regulators, might as well drop the argument. Signed-off-by: Felipe Balbi Signed-off-by: Mark Brown --- drivers/regulator/tps65218-regulator.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/tps65218-regulator.c b/drivers/regulator/tps65218-regulator.c index f56bc06389e4..633d793cd053 100644 --- a/drivers/regulator/tps65218-regulator.c +++ b/drivers/regulator/tps65218-regulator.c @@ -29,7 +29,7 @@ enum tps65218_regulators { DCDC1, DCDC2, DCDC3, DCDC4, DCDC5, DCDC6, LDO1 }; -#define TPS65218_REGULATOR(_name, _id, _ops, _n, _vr, _vm, _er, _em, _t, \ +#define TPS65218_REGULATOR(_name, _id, _ops, _n, _vr, _vm, _er, _em, \ _lr, _nlr, _delay) \ { \ .name = _name, \ @@ -42,7 +42,7 @@ enum tps65218_regulators { DCDC1, DCDC2, DCDC3, DCDC4, DCDC5, DCDC6, LDO1 }; .vsel_mask = _vm, \ .enable_reg = _er, \ .enable_mask = _em, \ - .volt_table = _t, \ + .volt_table = NULL, \ .linear_ranges = _lr, \ .n_linear_ranges = _nlr, \ .ramp_delay = _delay, \ @@ -185,33 +185,32 @@ static const struct regulator_desc regulators[] = { TPS65218_REGULATOR("DCDC1", TPS65218_DCDC_1, tps65218_dcdc12_ops, 64, TPS65218_REG_CONTROL_DCDC1, TPS65218_CONTROL_DCDC1_MASK, - TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC1_EN, NULL, + TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC1_EN, dcdc1_dcdc2_ranges, 2, 4000), TPS65218_REGULATOR("DCDC2", TPS65218_DCDC_2, tps65218_dcdc12_ops, 64, TPS65218_REG_CONTROL_DCDC2, TPS65218_CONTROL_DCDC2_MASK, - TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC2_EN, NULL, + TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC2_EN, dcdc1_dcdc2_ranges, 2, 4000), TPS65218_REGULATOR("DCDC3", TPS65218_DCDC_3, tps65218_ldo1_dcdc34_ops, 64, TPS65218_REG_CONTROL_DCDC3, TPS65218_CONTROL_DCDC3_MASK, TPS65218_REG_ENABLE1, - TPS65218_ENABLE1_DC3_EN, NULL, - ldo1_dcdc3_ranges, 2, 0), + TPS65218_ENABLE1_DC3_EN, ldo1_dcdc3_ranges, 2, 0), TPS65218_REGULATOR("DCDC4", TPS65218_DCDC_4, tps65218_ldo1_dcdc34_ops, 53, TPS65218_REG_CONTROL_DCDC4, TPS65218_CONTROL_DCDC4_MASK, - TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC4_EN, NULL, + TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC4_EN, dcdc4_ranges, 2, 0), TPS65218_REGULATOR("DCDC5", TPS65218_DCDC_5, tps65218_dcdc56_pmic_ops, 1, -1, -1, TPS65218_REG_ENABLE1, - TPS65218_ENABLE1_DC5_EN, NULL, NULL, 0, 0), + TPS65218_ENABLE1_DC5_EN, NULL, 0, 0), TPS65218_REGULATOR("DCDC6", TPS65218_DCDC_6, tps65218_dcdc56_pmic_ops, 1, -1, -1, TPS65218_REG_ENABLE1, - TPS65218_ENABLE1_DC6_EN, NULL, NULL, 0, 0), + TPS65218_ENABLE1_DC6_EN, NULL, 0, 0), TPS65218_REGULATOR("LDO1", TPS65218_LDO_1, tps65218_ldo1_dcdc34_ops, 64, TPS65218_REG_CONTROL_LDO1, TPS65218_CONTROL_LDO1_MASK, TPS65218_REG_ENABLE2, - TPS65218_ENABLE2_LDO1_EN, NULL, ldo1_dcdc3_ranges, + TPS65218_ENABLE2_LDO1_EN, ldo1_dcdc3_ranges, 2, 0), }; -- cgit v1.2.2 From 6a5e06d9f4443c6f967ea7352cf30abdd681accf Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 8 Jul 2014 14:09:14 -0500 Subject: regulator: tps65218: drop order dependency By just using GCC's array initialization extension, we can easily drop order dependency between tps65218_regulattors enumeration and tps65218_pmic_regs array. Signed-of-by: Felipe Balbi Signed-off-by: Mark Brown --- drivers/regulator/tps65218-regulator.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/tps65218-regulator.c b/drivers/regulator/tps65218-regulator.c index 633d793cd053..e610dadcf6d1 100644 --- a/drivers/regulator/tps65218-regulator.c +++ b/drivers/regulator/tps65218-regulator.c @@ -49,7 +49,7 @@ enum tps65218_regulators { DCDC1, DCDC2, DCDC3, DCDC4, DCDC5, DCDC6, LDO1 }; } \ #define TPS65218_INFO(_id, _nm, _min, _max) \ - { \ + [_id] = { \ .id = _id, \ .name = _nm, \ .min_uV = _min, \ @@ -72,13 +72,13 @@ static const struct regulator_linear_range dcdc4_ranges[] = { }; static struct tps_info tps65218_pmic_regs[] = { - TPS65218_INFO(0, "DCDC1", 850000, 167500), - TPS65218_INFO(1, "DCDC2", 850000, 1675000), - TPS65218_INFO(2, "DCDC3", 900000, 3400000), - TPS65218_INFO(3, "DCDC4", 1175000, 3400000), - TPS65218_INFO(4, "DCDC5", 1000000, 1000000), - TPS65218_INFO(5, "DCDC6", 1800000, 1800000), - TPS65218_INFO(6, "LDO1", 900000, 3400000), + TPS65218_INFO(DCDC1, "DCDC1", 850000, 167500), + TPS65218_INFO(DCDC2, "DCDC2", 850000, 1675000), + TPS65218_INFO(DCDC3, "DCDC3", 900000, 3400000), + TPS65218_INFO(DCDC4, "DCDC4", 1175000, 3400000), + TPS65218_INFO(DCDC5, "DCDC5", 1000000, 1000000), + TPS65218_INFO(DCDC6, "DCDC6", 1800000, 1800000), + TPS65218_INFO(LDO1, "LDO1", 900000, 3400000), }; #define TPS65218_OF_MATCH(comp, label) \ -- cgit v1.2.2 From 57135250358e54c237450f30474616f3d850b8de Mon Sep 17 00:00:00 2001 From: Himangi Saraogi Date: Mon, 7 Jul 2014 21:12:14 +0530 Subject: regulator: lp8755: Use devm_regulator_register This patch moves data allocated using regulator_register to devm_regulator_register and does away with the calls to regulator_unregister. Also some labels are removed and a new labelerr is introduced which is less specific to context. Signed-off-by: Himangi Saraogi Acked-by: Julia Lawall Signed-off-by: Mark Brown --- drivers/regulator/lp8755.c | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/lp8755.c b/drivers/regulator/lp8755.c index 785a25e9a437..4a415d4ee463 100644 --- a/drivers/regulator/lp8755.c +++ b/drivers/regulator/lp8755.c @@ -339,22 +339,18 @@ static int lp8755_regulator_init(struct lp8755_chip *pchip) rconfig.init_data = pdata->buck_data[buck_num]; rconfig.of_node = pchip->dev->of_node; pchip->rdev[buck_num] = - regulator_register(&lp8755_regulators[buck_num], &rconfig); + devm_regulator_register(pchip->dev, + &lp8755_regulators[buck_num], &rconfig); if (IS_ERR(pchip->rdev[buck_num])) { ret = PTR_ERR(pchip->rdev[buck_num]); pchip->rdev[buck_num] = NULL; dev_err(pchip->dev, "regulator init failed: buck %d\n", buck_num); - goto err_buck; + return ret; } } return 0; - -err_buck: - for (icnt = 0; icnt < LP8755_BUCK_MAX; icnt++) - regulator_unregister(pchip->rdev[icnt]); - return ret; } static irqreturn_t lp8755_irq_handler(int irq, void *data) @@ -490,23 +486,19 @@ static int lp8755_probe(struct i2c_client *client, ret = lp8755_regulator_init(pchip); if (ret < 0) { dev_err(&client->dev, "fail to initialize regulators\n"); - goto err_regulator; + goto err; } pchip->irq = client->irq; ret = lp8755_int_config(pchip); if (ret < 0) { dev_err(&client->dev, "fail to irq config\n"); - goto err_irq; + goto err; } return ret; -err_irq: - for (icnt = 0; icnt < mphase_buck[pchip->mphase].nreg; icnt++) - regulator_unregister(pchip->rdev[icnt]); - -err_regulator: +err: /* output disable */ for (icnt = 0; icnt < LP8755_BUCK_MAX; icnt++) lp8755_write(pchip, icnt, 0x00); @@ -519,9 +511,6 @@ static int lp8755_remove(struct i2c_client *client) int icnt; struct lp8755_chip *pchip = i2c_get_clientdata(client); - for (icnt = 0; icnt < mphase_buck[pchip->mphase].nreg; icnt++) - regulator_unregister(pchip->rdev[icnt]); - for (icnt = 0; icnt < LP8755_BUCK_MAX; icnt++) lp8755_write(pchip, icnt, 0x00); -- cgit v1.2.2 From 7753d2d41f658fe42de148732173e35999fd5e39 Mon Sep 17 00:00:00 2001 From: Keerthy Date: Wed, 9 Jul 2014 15:52:59 +0530 Subject: regulator: tps65218: Add fixed_uV fields for dcdc5 and dcdc6 Add fixed_uV fields for dcdc5 and dcdc6. Signed-off-by: Keerthy Signed-off-by: Mark Brown --- drivers/regulator/tps65218-regulator.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/tps65218-regulator.c b/drivers/regulator/tps65218-regulator.c index e610dadcf6d1..f0a40281b9c1 100644 --- a/drivers/regulator/tps65218-regulator.c +++ b/drivers/regulator/tps65218-regulator.c @@ -30,7 +30,7 @@ enum tps65218_regulators { DCDC1, DCDC2, DCDC3, DCDC4, DCDC5, DCDC6, LDO1 }; #define TPS65218_REGULATOR(_name, _id, _ops, _n, _vr, _vm, _er, _em, \ - _lr, _nlr, _delay) \ + _lr, _nlr, _delay, _fuv) \ { \ .name = _name, \ .id = _id, \ @@ -46,6 +46,7 @@ enum tps65218_regulators { DCDC1, DCDC2, DCDC3, DCDC4, DCDC5, DCDC6, LDO1 }; .linear_ranges = _lr, \ .n_linear_ranges = _nlr, \ .ramp_delay = _delay, \ + .fixed_uV = _fuv \ } \ #define TPS65218_INFO(_id, _nm, _min, _max) \ @@ -186,32 +187,32 @@ static const struct regulator_desc regulators[] = { TPS65218_REG_CONTROL_DCDC1, TPS65218_CONTROL_DCDC1_MASK, TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC1_EN, - dcdc1_dcdc2_ranges, 2, 4000), + dcdc1_dcdc2_ranges, 2, 4000, 0), TPS65218_REGULATOR("DCDC2", TPS65218_DCDC_2, tps65218_dcdc12_ops, 64, TPS65218_REG_CONTROL_DCDC2, TPS65218_CONTROL_DCDC2_MASK, TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC2_EN, - dcdc1_dcdc2_ranges, 2, 4000), + dcdc1_dcdc2_ranges, 2, 4000, 0), TPS65218_REGULATOR("DCDC3", TPS65218_DCDC_3, tps65218_ldo1_dcdc34_ops, 64, TPS65218_REG_CONTROL_DCDC3, TPS65218_CONTROL_DCDC3_MASK, TPS65218_REG_ENABLE1, - TPS65218_ENABLE1_DC3_EN, ldo1_dcdc3_ranges, 2, 0), + TPS65218_ENABLE1_DC3_EN, ldo1_dcdc3_ranges, 2, 0, 0), TPS65218_REGULATOR("DCDC4", TPS65218_DCDC_4, tps65218_ldo1_dcdc34_ops, 53, TPS65218_REG_CONTROL_DCDC4, TPS65218_CONTROL_DCDC4_MASK, TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC4_EN, - dcdc4_ranges, 2, 0), + dcdc4_ranges, 2, 0, 0), TPS65218_REGULATOR("DCDC5", TPS65218_DCDC_5, tps65218_dcdc56_pmic_ops, 1, -1, -1, TPS65218_REG_ENABLE1, - TPS65218_ENABLE1_DC5_EN, NULL, 0, 0), + TPS65218_ENABLE1_DC5_EN, NULL, 0, 0, 1000000), TPS65218_REGULATOR("DCDC6", TPS65218_DCDC_6, tps65218_dcdc56_pmic_ops, 1, -1, -1, TPS65218_REG_ENABLE1, - TPS65218_ENABLE1_DC6_EN, NULL, 0, 0), + TPS65218_ENABLE1_DC6_EN, NULL, 0, 0, 1800000), TPS65218_REGULATOR("LDO1", TPS65218_LDO_1, tps65218_ldo1_dcdc34_ops, 64, TPS65218_REG_CONTROL_LDO1, TPS65218_CONTROL_LDO1_MASK, TPS65218_REG_ENABLE2, TPS65218_ENABLE2_LDO1_EN, ldo1_dcdc3_ranges, - 2, 0), + 2, 0, 0), }; static int tps65218_regulator_probe(struct platform_device *pdev) -- cgit v1.2.2 From 1028a37daa148cc6cf85aa2aecb4390ddf1e1e56 Mon Sep 17 00:00:00 2001 From: James Ban Date: Mon, 14 Jul 2014 13:48:45 +0900 Subject: regulator: da9211: new regulator driver This is the driver for the Dialog DA9211 Multi-phase 12A DC-DC Buck Converter regulator. It communicates via an I2C bus to the device. Signed-off-by: James Ban Signed-off-by: Mark Brown --- drivers/regulator/Kconfig | 10 + drivers/regulator/Makefile | 1 + drivers/regulator/da9211-regulator.c | 388 +++++++++++++++++++++++++++++++++++ drivers/regulator/da9211-regulator.h | 271 ++++++++++++++++++++++++ 4 files changed, 670 insertions(+) create mode 100644 drivers/regulator/da9211-regulator.c create mode 100644 drivers/regulator/da9211-regulator.h (limited to 'drivers') diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 789eb46090e3..f5040fc49a3a 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -198,6 +198,16 @@ config REGULATOR_DA9210 converter 12A DC-DC Buck controlled through an I2C interface. +config REGULATOR_DA9211 + tristate "Dialog Semiconductor DA9211/DA9212 regulator" + depends on I2C + select REGMAP_I2C + help + Say y here to support for the Dialog Semiconductor DA9211/DA9212. + The DA9211/DA9212 is a multi-phase synchronous step down + converter 12A DC-DC Buck controlled through an I2C + interface. + config REGULATOR_DBX500_PRCMU bool diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index d461110f4463..aa4a6aa7b558 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_REGULATOR_DA9052) += da9052-regulator.o obj-$(CONFIG_REGULATOR_DA9055) += da9055-regulator.o obj-$(CONFIG_REGULATOR_DA9063) += da9063-regulator.o obj-$(CONFIG_REGULATOR_DA9210) += da9210-regulator.o +obj-$(CONFIG_REGULATOR_DA9211) += da9211-regulator.o obj-$(CONFIG_REGULATOR_DBX500_PRCMU) += dbx500-prcmu.o obj-$(CONFIG_REGULATOR_DB8500_PRCMU) += db8500-prcmu.o obj-$(CONFIG_REGULATOR_FAN53555) += fan53555.o diff --git a/drivers/regulator/da9211-regulator.c b/drivers/regulator/da9211-regulator.c new file mode 100644 index 000000000000..bd1850658a3f --- /dev/null +++ b/drivers/regulator/da9211-regulator.c @@ -0,0 +1,388 @@ +/* + * da9211-regulator.c - Regulator device driver for DA9211 + * Copyright (C) 2014 Dialog Semiconductor Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "da9211-regulator.h" + +#define DA9211_BUCK_MODE_SLEEP 1 +#define DA9211_BUCK_MODE_SYNC 2 +#define DA9211_BUCK_MODE_AUTO 3 + +/* DA9211 REGULATOR IDs */ +#define DA9211_ID_BUCKA 0 +#define DA9211_ID_BUCKB 1 + +struct da9211 { + struct device *dev; + struct regmap *regmap; + struct da9211_pdata *pdata; + struct regulator_dev *rdev[DA9211_MAX_REGULATORS]; + int num_regulator; + int chip_irq; +}; + +static const struct regmap_range_cfg da9211_regmap_range[] = { + { + .selector_reg = DA9211_REG_PAGE_CON, + .selector_mask = DA9211_REG_PAGE_MASK, + .selector_shift = DA9211_REG_PAGE_SHIFT, + .window_start = 0, + .window_len = 256, + .range_min = 0, + .range_max = 2*256, + }, +}; + +static const struct regmap_config da9211_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .max_register = 2 * 256, + .ranges = da9211_regmap_range, + .num_ranges = ARRAY_SIZE(da9211_regmap_range), +}; + +/* Default limits measured in millivolts and milliamps */ +#define DA9211_MIN_MV 300 +#define DA9211_MAX_MV 1570 +#define DA9211_STEP_MV 10 + +/* Current limits for buck (uA) indices corresponds with register values */ +static const int da9211_current_limits[] = { + 2000000, 2200000, 2400000, 2600000, 2800000, 3000000, 3200000, 3400000, + 3600000, 3800000, 4000000, 4200000, 4400000, 4600000, 4800000, 5000000 +}; + +static unsigned int da9211_buck_get_mode(struct regulator_dev *rdev) +{ + int id = rdev_get_id(rdev); + struct da9211 *chip = rdev_get_drvdata(rdev); + unsigned int data; + int ret, mode = 0; + + ret = regmap_read(chip->regmap, DA9211_REG_BUCKA_CONF+id, &data); + if (ret < 0) + return ret; + + switch (data & 0x03) { + case DA9211_BUCK_MODE_SYNC: + mode = REGULATOR_MODE_FAST; + break; + case DA9211_BUCK_MODE_AUTO: + mode = REGULATOR_MODE_NORMAL; + break; + case DA9211_BUCK_MODE_SLEEP: + mode = REGULATOR_MODE_STANDBY; + break; + } + + return mode; +} + +static int da9211_buck_set_mode(struct regulator_dev *rdev, + unsigned int mode) +{ + int id = rdev_get_id(rdev); + struct da9211 *chip = rdev_get_drvdata(rdev); + int val = 0; + + switch (mode) { + case REGULATOR_MODE_FAST: + val = DA9211_BUCK_MODE_SYNC; + break; + case REGULATOR_MODE_NORMAL: + val = DA9211_BUCK_MODE_AUTO; + break; + case REGULATOR_MODE_STANDBY: + val = DA9211_BUCK_MODE_SLEEP; + break; + } + + return regmap_update_bits(chip->regmap, DA9211_REG_BUCKA_CONF+id, + 0x03, val); +} + +static int da9211_set_current_limit(struct regulator_dev *rdev, int min, + int max) +{ + int id = rdev_get_id(rdev); + struct da9211 *chip = rdev_get_drvdata(rdev); + int i; + + /* search for closest to maximum */ + for (i = ARRAY_SIZE(da9211_current_limits)-1; i >= 0; i--) { + if (min <= da9211_current_limits[i] && + max >= da9211_current_limits[i]) { + return regmap_update_bits(chip->regmap, + DA9211_REG_BUCK_ILIM, + (0x0F << id*4), (i << id*4)); + } + } + + return -EINVAL; +} + +static int da9211_get_current_limit(struct regulator_dev *rdev) +{ + int id = rdev_get_id(rdev); + struct da9211 *chip = rdev_get_drvdata(rdev); + unsigned int data; + int ret; + + ret = regmap_read(chip->regmap, DA9211_REG_BUCK_ILIM, &data); + if (ret < 0) + return ret; + + /* select one of 16 values: 0000 (2000mA) to 1111 (5000mA) */ + data = (data >> id*4) & 0x0F; + return da9211_current_limits[data]; +} + +static struct regulator_ops da9211_buck_ops = { + .get_mode = da9211_buck_get_mode, + .set_mode = da9211_buck_set_mode, + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .list_voltage = regulator_list_voltage_linear, + .set_current_limit = da9211_set_current_limit, + .get_current_limit = da9211_get_current_limit, +}; + +#define DA9211_BUCK(_id) \ +{\ + .name = #_id,\ + .ops = &da9211_buck_ops,\ + .type = REGULATOR_VOLTAGE,\ + .id = DA9211_ID_##_id,\ + .n_voltages = (DA9211_MAX_MV - DA9211_MIN_MV) / DA9211_STEP_MV + 1,\ + .min_uV = (DA9211_MIN_MV * 1000),\ + .uV_step = (DA9211_STEP_MV * 1000),\ + .enable_reg = DA9211_REG_BUCKA_CONT + DA9211_ID_##_id,\ + .enable_mask = DA9211_BUCKA_EN,\ + .vsel_reg = DA9211_REG_VBUCKA_A + DA9211_ID_##_id * 2,\ + .vsel_mask = DA9211_VBUCK_MASK,\ + .owner = THIS_MODULE,\ +} + +static struct regulator_desc da9211_regulators[] = { + DA9211_BUCK(BUCKA), + DA9211_BUCK(BUCKB), +}; + +static irqreturn_t da9211_irq_handler(int irq, void *data) +{ + struct da9211 *chip = data; + int reg_val, err, ret = IRQ_NONE; + + err = regmap_read(chip->regmap, DA9211_REG_EVENT_B, ®_val); + if (err < 0) + goto error_i2c; + + if (reg_val & DA9211_E_OV_CURR_A) { + regulator_notifier_call_chain(chip->rdev[0], + REGULATOR_EVENT_OVER_CURRENT, + rdev_get_drvdata(chip->rdev[0])); + + err = regmap_write(chip->regmap, DA9211_REG_EVENT_B, + DA9211_E_OV_CURR_A); + if (err < 0) + goto error_i2c; + + ret = IRQ_HANDLED; + } + + if (reg_val & DA9211_E_OV_CURR_B) { + regulator_notifier_call_chain(chip->rdev[1], + REGULATOR_EVENT_OVER_CURRENT, + rdev_get_drvdata(chip->rdev[1])); + + err = regmap_write(chip->regmap, DA9211_REG_EVENT_B, + DA9211_E_OV_CURR_B); + if (err < 0) + goto error_i2c; + + ret = IRQ_HANDLED; + } + + return ret; + +error_i2c: + dev_err(chip->dev, "I2C error : %d\n", err); + return IRQ_NONE; +} + +static int da9211_regulator_init(struct da9211 *chip) +{ + struct regulator_config config = { }; + int i, ret; + unsigned int data; + + ret = regmap_read(chip->regmap, DA9211_REG_CONFIG_E, &data); + if (ret < 0) { + dev_err(chip->dev, "Failed to read CONTROL_E reg: %d\n", ret); + goto err; + } + + data &= DA9211_SLAVE_SEL; + /* If configuration for 1/2 bucks is different between platform data + * and the register, driver should exit. + */ + if ((chip->pdata->num_buck == 2 && data == 0x40) + || (chip->pdata->num_buck == 1 && data == 0x00)) { + if (data == 0) + chip->num_regulator = 1; + else + chip->num_regulator = 2; + } else { + ret = -EINVAL; + dev_err(chip->dev, "Configuration is mismatched\n"); + goto err; + } + + for (i = 0; i < chip->num_regulator; i++) { + if (chip->pdata) + config.init_data = + &(chip->pdata->init_data[i]); + + config.dev = chip->dev; + config.driver_data = chip; + config.regmap = chip->regmap; + + chip->rdev[i] = devm_regulator_register(chip->dev, + &da9211_regulators[i], &config); + if (IS_ERR(chip->rdev[i])) { + dev_err(chip->dev, + "Failed to register DA9211 regulator\n"); + ret = PTR_ERR(chip->rdev[i]); + goto err_regulator; + } + + if (chip->chip_irq != 0) { + ret = regmap_update_bits(chip->regmap, + DA9211_REG_MASK_B, DA9211_M_OV_CURR_A << i, 1); + if (ret < 0) { + dev_err(chip->dev, + "Failed to update mask reg: %d\n", ret); + goto err_regulator; + } + } + } + + return 0; + +err_regulator: + while (--i >= 0) + devm_regulator_unregister(chip->dev, chip->rdev[i]); +err: + return ret; +} +/* + * I2C driver interface functions + */ +static int da9211_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + struct da9211 *chip; + int error, ret; + + chip = devm_kzalloc(&i2c->dev, sizeof(struct da9211), GFP_KERNEL); + + chip->dev = &i2c->dev; + chip->regmap = devm_regmap_init_i2c(i2c, &da9211_regmap_config); + if (IS_ERR(chip->regmap)) { + error = PTR_ERR(chip->regmap); + dev_err(&i2c->dev, "Failed to allocate register map: %d\n", + error); + return error; + } + + i2c_set_clientdata(i2c, chip); + + chip->pdata = i2c->dev.platform_data; + if (!chip->pdata) { + dev_err(&i2c->dev, "No platform init data supplied\n"); + return -ENODEV; + } + + chip->chip_irq = i2c->irq; + + if (chip->chip_irq != 0) { + ret = devm_request_threaded_irq(chip->dev, chip->chip_irq, NULL, + da9211_irq_handler, + IRQF_TRIGGER_LOW|IRQF_ONESHOT, + "da9211", chip); + if (ret != 0) { + dev_err(chip->dev, "Failed to request IRQ: %d\n", + chip->chip_irq); + return ret; + } + } else { + dev_warn(chip->dev, "No IRQ configured\n"); + } + + ret = da9211_regulator_init(chip); + + if (ret < 0) + dev_err(&i2c->dev, "Failed to initialize regulator: %d\n", ret); + + return ret; +} + +static int da9211_i2c_remove(struct i2c_client *i2c) +{ + struct da9211 *chip = i2c_get_clientdata(i2c); + int i; + + for (i = 0; i < chip->num_regulator; i++) + devm_regulator_unregister(chip->dev, chip->rdev[i]); + + return 0; +} + +static const struct i2c_device_id da9211_i2c_id[] = { + {"da9211", 0}, + {}, +}; + +MODULE_DEVICE_TABLE(i2c, da9211_i2c_id); + +static struct i2c_driver da9211_regulator_driver = { + .driver = { + .name = "da9211", + .owner = THIS_MODULE, + }, + .probe = da9211_i2c_probe, + .remove = da9211_i2c_remove, + .id_table = da9211_i2c_id, +}; + +module_i2c_driver(da9211_regulator_driver); + +MODULE_AUTHOR("James Ban "); +MODULE_DESCRIPTION("Regulator device driver for Dialog DA9211"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/regulator/da9211-regulator.h b/drivers/regulator/da9211-regulator.h new file mode 100644 index 000000000000..88b1769e8058 --- /dev/null +++ b/drivers/regulator/da9211-regulator.h @@ -0,0 +1,271 @@ +/* + * da9211-regulator.h - Regulator definitions for DA9211 + * Copyright (C) 2014 Dialog Semiconductor Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + */ + +#ifndef __DA9211_REGISTERS_H__ +#define __DA9211_REGISTERS_H__ + +/* Page selection */ +#define DA9211_REG_PAGE_CON 0x00 + +/* System Control and Event Registers */ +#define DA9211_REG_STATUS_A 0x50 +#define DA9211_REG_STATUS_B 0x51 +#define DA9211_REG_EVENT_A 0x52 +#define DA9211_REG_EVENT_B 0x53 +#define DA9211_REG_MASK_A 0x54 +#define DA9211_REG_MASK_B 0x55 +#define DA9211_REG_CONTROL_A 0x56 + +/* GPIO Control Registers */ +#define DA9211_REG_GPIO_0_1 0x58 +#define DA9211_REG_GPIO_2_3 0x59 +#define DA9211_REG_GPIO_4 0x5A + +/* Regulator Registers */ +#define DA9211_REG_BUCKA_CONT 0x5D +#define DA9211_REG_BUCKB_CONT 0x5E +#define DA9211_REG_BUCK_ILIM 0xD0 +#define DA9211_REG_BUCKA_CONF 0xD1 +#define DA9211_REG_BUCKB_CONF 0xD2 +#define DA9211_REG_BUCK_CONF 0xD3 +#define DA9211_REG_VBACKA_MAX 0xD5 +#define DA9211_REG_VBACKB_MAX 0xD6 +#define DA9211_REG_VBUCKA_A 0xD7 +#define DA9211_REG_VBUCKA_B 0xD8 +#define DA9211_REG_VBUCKB_A 0xD9 +#define DA9211_REG_VBUCKB_B 0xDA + +/* I2C Interface Settings */ +#define DA9211_REG_INTERFACE 0x105 + +/* BUCK Phase Selection*/ +#define DA9211_REG_CONFIG_E 0x147 + +/* + * Registers bits + */ +/* DA9211_REG_PAGE_CON (addr=0x00) */ +#define DA9211_REG_PAGE_SHIFT 1 +#define DA9211_REG_PAGE_MASK 0x02 +/* On I2C registers 0x00 - 0xFF */ +#define DA9211_REG_PAGE0 0 +/* On I2C registers 0x100 - 0x1FF */ +#define DA9211_REG_PAGE2 2 +#define DA9211_PAGE_WRITE_MODE 0x00 +#define DA9211_REPEAT_WRITE_MODE 0x40 +#define DA9211_PAGE_REVERT 0x80 + +/* DA9211_REG_STATUS_A (addr=0x50) */ +#define DA9211_GPI0 0x01 +#define DA9211_GPI1 0x02 +#define DA9211_GPI2 0x04 +#define DA9211_GPI3 0x08 +#define DA9211_GPI4 0x10 + +/* DA9211_REG_EVENT_A (addr=0x52) */ +#define DA9211_E_GPI0 0x01 +#define DA9211_E_GPI1 0x02 +#define DA9211_E_GPI2 0x04 +#define DA9211_E_GPI3 0x08 +#define DA9211_E_GPI4 0x10 +#define DA9211_E_UVLO_IO 0x40 + +/* DA9211_REG_EVENT_B (addr=0x53) */ +#define DA9211_E_PWRGOOD_A 0x01 +#define DA9211_E_PWRGOOD_B 0x02 +#define DA9211_E_TEMP_WARN 0x04 +#define DA9211_E_TEMP_CRIT 0x08 +#define DA9211_E_OV_CURR_A 0x10 +#define DA9211_E_OV_CURR_B 0x20 + +/* DA9211_REG_MASK_A (addr=0x54) */ +#define DA9211_M_GPI0 0x01 +#define DA9211_M_GPI1 0x02 +#define DA9211_M_GPI2 0x04 +#define DA9211_M_GPI3 0x08 +#define DA9211_M_GPI4 0x10 +#define DA9211_M_UVLO_IO 0x40 + +/* DA9211_REG_MASK_B (addr=0x55) */ +#define DA9211_M_PWRGOOD_A 0x01 +#define DA9211_M_PWRGOOD_B 0x02 +#define DA9211_M_TEMP_WARN 0x04 +#define DA9211_M_TEMP_CRIT 0x08 +#define DA9211_M_OV_CURR_A 0x10 +#define DA9211_M_OV_CURR_B 0x20 + +/* DA9211_REG_CONTROL_A (addr=0x56) */ +#define DA9211_DEBOUNCING_SHIFT 0 +#define DA9211_DEBOUNCING_MASK 0x07 +#define DA9211_SLEW_RATE_SHIFT 3 +#define DA9211_SLEW_RATE_A_MASK 0x18 +#define DA9211_SLEW_RATE_B_SHIFT 5 +#define DA9211_SLEW_RATE_B_MASK 0x60 +#define DA9211_V_LOCK 0x80 + +/* DA9211_REG_GPIO_0_1 (addr=0x58) */ +#define DA9211_GPIO0_PIN_SHIFT 0 +#define DA9211_GPIO0_PIN_MASK 0x03 +#define DA9211_GPIO0_PIN_GPI 0x00 +#define DA9211_GPIO0_PIN_GPO_OD 0x02 +#define DA9211_GPIO0_PIN_GPO 0x03 +#define DA9211_GPIO0_TYPE 0x04 +#define DA9211_GPIO0_TYPE_GPI 0x00 +#define DA9211_GPIO0_TYPE_GPO 0x04 +#define DA9211_GPIO0_MODE 0x08 +#define DA9211_GPIO1_PIN_SHIFT 4 +#define DA9211_GPIO1_PIN_MASK 0x30 +#define DA9211_GPIO1_PIN_GPI 0x00 +#define DA9211_GPIO1_PIN_VERROR 0x10 +#define DA9211_GPIO1_PIN_GPO_OD 0x20 +#define DA9211_GPIO1_PIN_GPO 0x30 +#define DA9211_GPIO1_TYPE_SHIFT 0x40 +#define DA9211_GPIO1_TYPE_GPI 0x00 +#define DA9211_GPIO1_TYPE_GPO 0x40 +#define DA9211_GPIO1_MODE 0x80 + +/* DA9211_REG_GPIO_2_3 (addr=0x59) */ +#define DA9211_GPIO2_PIN_SHIFT 0 +#define DA9211_GPIO2_PIN_MASK 0x03 +#define DA9211_GPIO2_PIN_GPI 0x00 +#define DA9211_GPIO5_PIN_BUCK_CLK 0x10 +#define DA9211_GPIO2_PIN_GPO_OD 0x02 +#define DA9211_GPIO2_PIN_GPO 0x03 +#define DA9211_GPIO2_TYPE 0x04 +#define DA9211_GPIO2_TYPE_GPI 0x00 +#define DA9211_GPIO2_TYPE_GPO 0x04 +#define DA9211_GPIO2_MODE 0x08 +#define DA9211_GPIO3_PIN_SHIFT 4 +#define DA9211_GPIO3_PIN_MASK 0x30 +#define DA9211_GPIO3_PIN_GPI 0x00 +#define DA9211_GPIO3_PIN_IERROR 0x10 +#define DA9211_GPIO3_PIN_GPO_OD 0x20 +#define DA9211_GPIO3_PIN_GPO 0x30 +#define DA9211_GPIO3_TYPE_SHIFT 0x40 +#define DA9211_GPIO3_TYPE_GPI 0x00 +#define DA9211_GPIO3_TYPE_GPO 0x40 +#define DA9211_GPIO3_MODE 0x80 + +/* DA9211_REG_GPIO_4 (addr=0x5A) */ +#define DA9211_GPIO4_PIN_SHIFT 0 +#define DA9211_GPIO4_PIN_MASK 0x03 +#define DA9211_GPIO4_PIN_GPI 0x00 +#define DA9211_GPIO4_PIN_GPO_OD 0x02 +#define DA9211_GPIO4_PIN_GPO 0x03 +#define DA9211_GPIO4_TYPE 0x04 +#define DA9211_GPIO4_TYPE_GPI 0x00 +#define DA9211_GPIO4_TYPE_GPO 0x04 +#define DA9211_GPIO4_MODE 0x08 + +/* DA9211_REG_BUCKA_CONT (addr=0x5D) */ +#define DA9211_BUCKA_EN 0x01 +#define DA9211_BUCKA_GPI_SHIFT 1 +#define DA9211_BUCKA_GPI_MASK 0x06 +#define DA9211_BUCKA_GPI_OFF 0x00 +#define DA9211_BUCKA_GPI_GPIO0 0x02 +#define DA9211_BUCKA_GPI_GPIO1 0x04 +#define DA9211_BUCKA_GPI_GPIO3 0x06 +#define DA9211_BUCKA_PD_DIS 0x08 +#define DA9211_VBUCKA_SEL 0x10 +#define DA9211_VBUCKA_SEL_A 0x00 +#define DA9211_VBUCKA_SEL_B 0x10 +#define DA9211_VBUCKA_GPI_SHIFT 5 +#define DA9211_VBUCKA_GPI_MASK 0x60 +#define DA9211_VBUCKA_GPI_OFF 0x00 +#define DA9211_VBUCKA_GPI_GPIO1 0x20 +#define DA9211_VBUCKA_GPI_GPIO2 0x40 +#define DA9211_VBUCKA_GPI_GPIO4 0x60 + +/* DA9211_REG_BUCKB_CONT (addr=0x5E) */ +#define DA9211_BUCKB_EN 0x01 +#define DA9211_BUCKB_GPI_SHIFT 1 +#define DA9211_BUCKB_GPI_MASK 0x06 +#define DA9211_BUCKB_GPI_OFF 0x00 +#define DA9211_BUCKB_GPI_GPIO0 0x02 +#define DA9211_BUCKB_GPI_GPIO1 0x04 +#define DA9211_BUCKB_GPI_GPIO3 0x06 +#define DA9211_BUCKB_PD_DIS 0x08 +#define DA9211_VBUCKB_SEL 0x10 +#define DA9211_VBUCKB_SEL_A 0x00 +#define DA9211_VBUCKB_SEL_B 0x10 +#define DA9211_VBUCKB_GPI_SHIFT 5 +#define DA9211_VBUCKB_GPI_MASK 0x60 +#define DA9211_VBUCKB_GPI_OFF 0x00 +#define DA9211_VBUCKB_GPI_GPIO1 0x20 +#define DA9211_VBUCKB_GPI_GPIO2 0x40 +#define DA9211_VBUCKB_GPI_GPIO4 0x60 + +/* DA9211_REG_BUCK_ILIM (addr=0xD0) */ +#define DA9211_BUCKA_ILIM_SHIFT 0 +#define DA9211_BUCKA_ILIM_MASK 0x0F +#define DA9211_BUCKB_ILIM_SHIFT 4 +#define DA9211_BUCKB_ILIM_MASK 0xF0 + +/* DA9211_REG_BUCKA_CONF (addr=0xD1) */ +#define DA9211_BUCKA_MODE_SHIFT 0 +#define DA9211_BUCKA_MODE_MASK 0x03 +#define DA9211_BUCKA_MODE_MANUAL 0x00 +#define DA9211_BUCKA_MODE_SLEEP 0x01 +#define DA9211_BUCKA_MODE_SYNC 0x02 +#define DA9211_BUCKA_MODE_AUTO 0x03 +#define DA9211_BUCKA_UP_CTRL_SHIFT 2 +#define DA9211_BUCKA_UP_CTRL_MASK 0x1C +#define DA9211_BUCKA_DOWN_CTRL_SHIFT 5 +#define DA9211_BUCKA_DOWN_CTRL_MASK 0xE0 + +/* DA9211_REG_BUCKB_CONF (addr=0xD2) */ +#define DA9211_BUCKB_MODE_SHIFT 0 +#define DA9211_BUCKB_MODE_MASK 0x03 +#define DA9211_BUCKB_MODE_MANUAL 0x00 +#define DA9211_BUCKB_MODE_SLEEP 0x01 +#define DA9211_BUCKB_MODE_SYNC 0x02 +#define DA9211_BUCKB_MODE_AUTO 0x03 +#define DA9211_BUCKB_UP_CTRL_SHIFT 2 +#define DA9211_BUCKB_UP_CTRL_MASK 0x1C +#define DA9211_BUCKB_DOWN_CTRL_SHIFT 5 +#define DA9211_BUCKB_DOWN_CTRL_MASK 0xE0 + +/* DA9211_REG_BUCK_CONF (addr=0xD3) */ +#define DA9211_PHASE_SEL_A_SHIFT 0 +#define DA9211_PHASE_SEL_A_MASK 0x03 +#define DA9211_PHASE_SEL_B_SHIFT 2 +#define DA9211_PHASE_SEL_B_MASK 0x04 +#define DA9211_PH_SH_EN_A_SHIFT 3 +#define DA9211_PH_SH_EN_A_MASK 0x08 +#define DA9211_PH_SH_EN_B_SHIFT 4 +#define DA9211_PH_SH_EN_B_MASK 0x10 + +/* DA9211_REG_VBUCKA_MAX (addr=0xD5) */ +#define DA9211_VBUCKA_BASE_SHIFT 0 +#define DA9211_VBUCKA_BASE_MASK 0x7F + +/* DA9211_REG_VBUCKB_MAX (addr=0xD6) */ +#define DA9211_VBUCKB_BASE_SHIFT 0 +#define DA9211_VBUCKB_BASE_MASK 0x7F + +/* DA9211_REG_VBUCKA/B_A/B (addr=0xD7/0xD8/0xD9/0xDA) */ +#define DA9211_VBUCK_SHIFT 0 +#define DA9211_VBUCK_MASK 0x7F +#define DA9211_VBUCK_BIAS 0 +#define DA9211_BUCK_SL 0x80 + +/* DA9211_REG_INTERFACE (addr=0x105) */ +#define DA9211_IF_BASE_ADDR_SHIFT 4 +#define DA9211_IF_BASE_ADDR_MASK 0xF0 + +/* DA9211_REG_CONFIG_E (addr=0x147) */ +#define DA9211_SLAVE_SEL 0x40 + +#endif /* __DA9211_REGISTERS_H__ */ -- cgit v1.2.2 From 516c1514b089e1c60a392b281f6c90f4b8e49183 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sun, 20 Jul 2014 19:19:35 +0800 Subject: regulator: da9211: Remove unnecessary devm_regulator_unregister() calls Current code uses devm_regulator_register(), so the resource management code will ensure that the resource is freed. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/da9211-regulator.c | 28 ++++------------------------ 1 file changed, 4 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/da9211-regulator.c b/drivers/regulator/da9211-regulator.c index bd1850658a3f..1482adafa1ad 100644 --- a/drivers/regulator/da9211-regulator.c +++ b/drivers/regulator/da9211-regulator.c @@ -245,7 +245,7 @@ static int da9211_regulator_init(struct da9211 *chip) ret = regmap_read(chip->regmap, DA9211_REG_CONFIG_E, &data); if (ret < 0) { dev_err(chip->dev, "Failed to read CONTROL_E reg: %d\n", ret); - goto err; + return ret; } data &= DA9211_SLAVE_SEL; @@ -259,9 +259,8 @@ static int da9211_regulator_init(struct da9211 *chip) else chip->num_regulator = 2; } else { - ret = -EINVAL; dev_err(chip->dev, "Configuration is mismatched\n"); - goto err; + return -EINVAL; } for (i = 0; i < chip->num_regulator; i++) { @@ -278,8 +277,7 @@ static int da9211_regulator_init(struct da9211 *chip) if (IS_ERR(chip->rdev[i])) { dev_err(chip->dev, "Failed to register DA9211 regulator\n"); - ret = PTR_ERR(chip->rdev[i]); - goto err_regulator; + return PTR_ERR(chip->rdev[i]); } if (chip->chip_irq != 0) { @@ -288,18 +286,12 @@ static int da9211_regulator_init(struct da9211 *chip) if (ret < 0) { dev_err(chip->dev, "Failed to update mask reg: %d\n", ret); - goto err_regulator; + return ret; } } } return 0; - -err_regulator: - while (--i >= 0) - devm_regulator_unregister(chip->dev, chip->rdev[i]); -err: - return ret; } /* * I2C driver interface functions @@ -353,17 +345,6 @@ static int da9211_i2c_probe(struct i2c_client *i2c, return ret; } -static int da9211_i2c_remove(struct i2c_client *i2c) -{ - struct da9211 *chip = i2c_get_clientdata(i2c); - int i; - - for (i = 0; i < chip->num_regulator; i++) - devm_regulator_unregister(chip->dev, chip->rdev[i]); - - return 0; -} - static const struct i2c_device_id da9211_i2c_id[] = { {"da9211", 0}, {}, @@ -377,7 +358,6 @@ static struct i2c_driver da9211_regulator_driver = { .owner = THIS_MODULE, }, .probe = da9211_i2c_probe, - .remove = da9211_i2c_remove, .id_table = da9211_i2c_id, }; -- cgit v1.2.2 From 8d7d3972a9ae962bbf8ce49c83f4a40082708f69 Mon Sep 17 00:00:00 2001 From: Tuomas Tynkkynen Date: Mon, 21 Jul 2014 18:38:47 +0300 Subject: regmap: Add regmap_get_device Add a new function regmap_get_device to obtain the underlying struct device from a regmap. Signed-off-by: Tuomas Tynkkynen Signed-off-by: Mark Brown --- drivers/base/regmap/regmap.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'drivers') diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index 74d8c0672cf6..5ba0263fce21 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -1073,6 +1073,18 @@ struct regmap *dev_get_regmap(struct device *dev, const char *name) } EXPORT_SYMBOL_GPL(dev_get_regmap); +/** + * regmap_get_device(): Obtain the device from a regmap + * + * @map: Register map to operate on. + * + * Returns the underlying device that the regmap has been created for. + */ +struct device *regmap_get_device(struct regmap *map) +{ + return map->dev; +} + static int _regmap_select_page(struct regmap *map, unsigned int *reg, struct regmap_range_node *range, unsigned int val_num) -- cgit v1.2.2 From fa2fbe4a981a70866d20cee62af0d89eb6b6027e Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 25 Jul 2014 18:30:31 +0100 Subject: regmap: Allow regmap_get_device() to be used by modules Signed-off-by: Mark Brown --- drivers/base/regmap/regmap.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index 5ba0263fce21..78f43fb2fe84 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -1084,6 +1084,7 @@ struct device *regmap_get_device(struct regmap *map) { return map->dev; } +EXPORT_SYMBOL_GPL(regmap_get_device); static int _regmap_select_page(struct regmap *map, unsigned int *reg, struct regmap_range_node *range, -- cgit v1.2.2 From 04eca28cde52cdf9eb91e127cc358ad79a8ec53b Mon Sep 17 00:00:00 2001 From: Tuomas Tynkkynen Date: Mon, 21 Jul 2014 18:38:48 +0300 Subject: regulator: Add helpers for low-level register access Add helper functions that allow regulator consumers to obtain low-level details about the regulator hardware, like the voltage selector register address and such. These details can be useful when configuring hardware or firmware that want to do low-level access to regulators, with no involvement from the kernel. The use-case for Tegra is a voltage-controlled oscillator clocksource which has control logic to change the supply voltage via I2C to achieve a desired output clock rate. Signed-off-by: Tuomas Tynkkynen Signed-off-by: Mark Brown --- drivers/regulator/core.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) (limited to 'drivers') diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 4c1f999041dd..486b5908469e 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -2221,6 +2221,77 @@ int regulator_list_voltage(struct regulator *regulator, unsigned selector) } EXPORT_SYMBOL_GPL(regulator_list_voltage); +/** + * regulator_get_regmap - get the regulator's register map + * @regulator: regulator source + * + * Returns the register map for the given regulator, or an ERR_PTR value + * if the regulator doesn't use regmap. + */ +struct regmap *regulator_get_regmap(struct regulator *regulator) +{ + struct regmap *map = regulator->rdev->regmap; + + return map ? map : ERR_PTR(-EOPNOTSUPP); +} + +/** + * regulator_get_hardware_vsel_register - get the HW voltage selector register + * @regulator: regulator source + * @vsel_reg: voltage selector register, output parameter + * @vsel_mask: mask for voltage selector bitfield, output parameter + * + * Returns the hardware register offset and bitmask used for setting the + * regulator voltage. This might be useful when configuring voltage-scaling + * hardware or firmware that can make I2C requests behind the kernel's back, + * for example. + * + * On success, the output parameters @vsel_reg and @vsel_mask are filled in + * and 0 is returned, otherwise a negative errno is returned. + */ +int regulator_get_hardware_vsel_register(struct regulator *regulator, + unsigned *vsel_reg, + unsigned *vsel_mask) +{ + struct regulator_dev *rdev = regulator->rdev; + struct regulator_ops *ops = rdev->desc->ops; + + if (ops->set_voltage_sel != regulator_set_voltage_sel_regmap) + return -EOPNOTSUPP; + + *vsel_reg = rdev->desc->vsel_reg; + *vsel_mask = rdev->desc->vsel_mask; + + return 0; +} +EXPORT_SYMBOL_GPL(regulator_get_hardware_vsel_register); + +/** + * regulator_list_hardware_vsel - get the HW-specific register value for a selector + * @regulator: regulator source + * @selector: identify voltage to list + * + * Converts the selector to a hardware-specific voltage selector that can be + * directly written to the regulator registers. The address of the voltage + * register can be determined by calling @regulator_get_hardware_vsel_register. + * + * On error a negative errno is returned. + */ +int regulator_list_hardware_vsel(struct regulator *regulator, + unsigned selector) +{ + struct regulator_dev *rdev = regulator->rdev; + struct regulator_ops *ops = rdev->desc->ops; + + if (selector >= rdev->desc->n_voltages) + return -EINVAL; + if (ops->set_voltage_sel != regulator_set_voltage_sel_regmap) + return -EOPNOTSUPP; + + return selector; +} +EXPORT_SYMBOL_GPL(regulator_list_hardware_vsel); + /** * regulator_get_linear_step - return the voltage step size between VSEL values * @regulator: regulator source -- cgit v1.2.2 From cad35c3f463ddfaff519e037cceac4ad971a9d60 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 23 Jul 2014 16:47:31 +0800 Subject: regulator: s2mps11: Update module description and Kconfig to add S2MPU02 support This driver also supports S2MPU02 now, thus update module description and Kconfig accordingly. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/Kconfig | 4 ++-- drivers/regulator/s2mps11.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 789eb46090e3..203c02d7f283 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -457,10 +457,10 @@ config REGULATOR_S2MPA01 via I2C bus. S2MPA01 has 10 Bucks and 26 LDO outputs. config REGULATOR_S2MPS11 - tristate "Samsung S2MPS11/S2MPS14 voltage regulator" + tristate "Samsung S2MPS11/S2MPS14/S2MPU02 voltage regulator" depends on MFD_SEC_CORE help - This driver supports a Samsung S2MPS11/S2MPS14 voltage output + This driver supports a Samsung S2MPS11/S2MPS14/S2MPU02 voltage output regulator via I2C bus. The chip is comprised of high efficient Buck converters including Dual-Phase Buck converter, Buck-Boost converter, various LDOs. diff --git a/drivers/regulator/s2mps11.c b/drivers/regulator/s2mps11.c index 02e2fb2fca66..2b7e9e220497 100644 --- a/drivers/regulator/s2mps11.c +++ b/drivers/regulator/s2mps11.c @@ -766,5 +766,5 @@ module_exit(s2mps11_pmic_exit); /* Module information */ MODULE_AUTHOR("Sangbeom Kim "); -MODULE_DESCRIPTION("SAMSUNG S2MPS11/S2MPS14 Regulator Driver"); +MODULE_DESCRIPTION("SAMSUNG S2MPS11/S2MPS14/S2MPU02 Regulator Driver"); MODULE_LICENSE("GPL"); -- cgit v1.2.2 From 404d4df260bc7b224ba51c704d24b7e452d8b68c Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 28 Jul 2014 12:32:04 +0100 Subject: regulator: lp872x: Don't set constraints within the regulator driver Regulator drivers should not be specifying constraints since the valid configurations depend on how the device is used in a given system, there is no way to know if a configuration is safe for a given board. Signed-off-by: Mark Brown --- drivers/regulator/lp872x.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/lp872x.c b/drivers/regulator/lp872x.c index 2e022aabd951..021d64d856bb 100644 --- a/drivers/regulator/lp872x.c +++ b/drivers/regulator/lp872x.c @@ -845,7 +845,6 @@ static struct lp872x_platform_data struct device_node *np = dev->of_node; struct lp872x_platform_data *pdata; struct of_regulator_match *match; - struct regulator_init_data *d; int num_matches; int count; int i; @@ -892,14 +891,6 @@ static struct lp872x_platform_data pdata->regulator_data[i].id = (enum lp872x_regulator_id)match[i].driver_data; pdata->regulator_data[i].init_data = match[i].init_data; - - /* Operation mode configuration for buck/buck1/buck2 */ - if (strncmp(match[i].name, "buck", 4)) - continue; - - d = pdata->regulator_data[i].init_data; - d->constraints.valid_modes_mask |= LP872X_VALID_OPMODE; - d->constraints.valid_ops_mask |= REGULATOR_CHANGE_MODE; } out: return pdata; -- cgit v1.2.2 From e303996e94b8705c85f3d78f3c094d05b0620c9d Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Tue, 29 Jul 2014 18:28:55 +0200 Subject: regulator: core: Get voltage from parent if not available Load switches are modeled as regulators but they just provide the voltage of their parent input supply. So the drivers for these switches usually don't provide a .get_voltage function handler but there is code in the kernel that assumes that all regulators should be able to provide its current voltage rail. So, if the output voltage for a regulator is not available and it has a parent supply, then pass the voltage of its parent. Signed-off-by: Javier Martinez Canillas Signed-off-by: Mark Brown --- drivers/regulator/core.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index b4902ab64abe..57fe446fabce 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -2620,6 +2620,8 @@ static int _regulator_get_voltage(struct regulator_dev *rdev) ret = rdev->desc->ops->list_voltage(rdev, 0); } else if (rdev->desc->fixed_uV && (rdev->desc->n_voltages == 1)) { ret = rdev->desc->fixed_uV; + } else if (rdev->supply) { + ret = regulator_get_voltage(rdev->supply); } else { return -EINVAL; } -- cgit v1.2.2 From 26988efe11b1dc44853035122927ced25578f302 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Tue, 29 Jul 2014 18:28:56 +0200 Subject: regulator: core: Allow to get voltage count and list from parent Load switches are modeled as regulators but they just provide the voltage of their parent input supply. So, the drivers for these switches usually neither provide a .list_voltage handler not set a .n_voltages count. But there is code in the kernel that assumes that all regulators should be able to provide this information (e.g: cpufreq and mmc subsystems). If the voltage count and list are not available for a regulator and it has a parent input supply, then use the parent values. Signed-off-by: Javier Martinez Canillas Signed-off-by: Mark Brown --- drivers/regulator/core.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 57fe446fabce..5299456d07ee 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -2182,7 +2182,13 @@ int regulator_count_voltages(struct regulator *regulator) { struct regulator_dev *rdev = regulator->rdev; - return rdev->desc->n_voltages ? : -EINVAL; + if (rdev->desc->n_voltages) + return rdev->desc->n_voltages; + + if (!rdev->supply) + return -EINVAL; + + return regulator_count_voltages(rdev->supply); } EXPORT_SYMBOL_GPL(regulator_count_voltages); @@ -2205,12 +2211,17 @@ int regulator_list_voltage(struct regulator *regulator, unsigned selector) if (rdev->desc->fixed_uV && rdev->desc->n_voltages == 1 && !selector) return rdev->desc->fixed_uV; - if (!ops->list_voltage || selector >= rdev->desc->n_voltages) + if (ops->list_voltage) { + if (selector >= rdev->desc->n_voltages) + return -EINVAL; + mutex_lock(&rdev->mutex); + ret = ops->list_voltage(rdev, selector); + mutex_unlock(&rdev->mutex); + } else if (rdev->supply) { + ret = regulator_list_voltage(rdev->supply, selector); + } else { return -EINVAL; - - mutex_lock(&rdev->mutex); - ret = ops->list_voltage(rdev, selector); - mutex_unlock(&rdev->mutex); + } if (ret > 0) { if (ret < rdev->constraints->min_uV) -- cgit v1.2.2 From 4f2352cf52738bd980713e85e8ae631c6c3a8feb Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Thu, 31 Jul 2014 14:31:05 +0200 Subject: regulator: tps65090: Set voltage for fixed regulators According to the tps65090 data manual [0], the DCDC1 and DCDC2 step-down converters and the LDO's have a fixed output voltage. Add this information to the driver since these fixed regulators can be used as parent input supply for switches that don't have an output voltage defined. So the regulator core needs to fetch the FET parent output voltage if the child voltage is queried. [0]: http://www.ti.com/lit/gpn/tps65090 Signed-off-by: Javier Martinez Canillas Signed-off-by: Mark Brown --- drivers/regulator/tps65090-regulator.c | 76 +++++++++++++++++++--------------- 1 file changed, 42 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/tps65090-regulator.c b/drivers/regulator/tps65090-regulator.c index 2064b3fd45f7..d5df1e9ad1da 100644 --- a/drivers/regulator/tps65090-regulator.c +++ b/drivers/regulator/tps65090-regulator.c @@ -192,12 +192,14 @@ static struct regulator_ops tps65090_fet_control_ops = { static struct regulator_ops tps65090_ldo_ops = { }; -#define tps65090_REG_DESC(_id, _sname, _en_reg, _en_bits, _ops) \ +#define tps65090_REG_DESC(_id, _sname, _en_reg, _en_bits, _nvolt, _volt, _ops) \ { \ .name = "TPS65090_RAILS"#_id, \ .supply_name = _sname, \ .id = TPS65090_REGULATOR_##_id, \ + .n_voltages = _nvolt, \ .ops = &_ops, \ + .fixed_uV = _volt, \ .enable_reg = _en_reg, \ .enable_val = _en_bits, \ .enable_mask = _en_bits, \ @@ -205,40 +207,46 @@ static struct regulator_ops tps65090_ldo_ops = { .owner = THIS_MODULE, \ } +#define tps65090_REG_FIXEDV(_id, _sname, en_reg, _en_bits, _volt, _ops) \ + tps65090_REG_DESC(_id, _sname, en_reg, _en_bits, 1, _volt, _ops) + +#define tps65090_REG_SWITCH(_id, _sname, en_reg, _en_bits, _ops) \ + tps65090_REG_DESC(_id, _sname, en_reg, _en_bits, 0, 0, _ops) + static struct regulator_desc tps65090_regulator_desc[] = { - tps65090_REG_DESC(DCDC1, "vsys1", 0x0C, BIT(CTRL_EN_BIT), - tps65090_reg_control_ops), - tps65090_REG_DESC(DCDC2, "vsys2", 0x0D, BIT(CTRL_EN_BIT), - tps65090_reg_control_ops), - tps65090_REG_DESC(DCDC3, "vsys3", 0x0E, BIT(CTRL_EN_BIT), - tps65090_reg_control_ops), - - tps65090_REG_DESC(FET1, "infet1", 0x0F, - BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT), - tps65090_fet_control_ops), - tps65090_REG_DESC(FET2, "infet2", 0x10, - BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT), - tps65090_fet_control_ops), - tps65090_REG_DESC(FET3, "infet3", 0x11, - BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT), - tps65090_fet_control_ops), - tps65090_REG_DESC(FET4, "infet4", 0x12, - BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT), - tps65090_fet_control_ops), - tps65090_REG_DESC(FET5, "infet5", 0x13, - BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT), - tps65090_fet_control_ops), - tps65090_REG_DESC(FET6, "infet6", 0x14, - BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT), - tps65090_fet_control_ops), - tps65090_REG_DESC(FET7, "infet7", 0x15, - BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT), - tps65090_fet_control_ops), - - tps65090_REG_DESC(LDO1, "vsys-l1", 0, 0, - tps65090_ldo_ops), - tps65090_REG_DESC(LDO2, "vsys-l2", 0, 0, - tps65090_ldo_ops), + tps65090_REG_FIXEDV(DCDC1, "vsys1", 0x0C, BIT(CTRL_EN_BIT), 5000000, + tps65090_reg_control_ops), + tps65090_REG_FIXEDV(DCDC2, "vsys2", 0x0D, BIT(CTRL_EN_BIT), 3300000, + tps65090_reg_control_ops), + tps65090_REG_SWITCH(DCDC3, "vsys3", 0x0E, BIT(CTRL_EN_BIT), + tps65090_reg_control_ops), + + tps65090_REG_SWITCH(FET1, "infet1", 0x0F, + BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT), + tps65090_fet_control_ops), + tps65090_REG_SWITCH(FET2, "infet2", 0x10, + BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT), + tps65090_fet_control_ops), + tps65090_REG_SWITCH(FET3, "infet3", 0x11, + BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT), + tps65090_fet_control_ops), + tps65090_REG_SWITCH(FET4, "infet4", 0x12, + BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT), + tps65090_fet_control_ops), + tps65090_REG_SWITCH(FET5, "infet5", 0x13, + BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT), + tps65090_fet_control_ops), + tps65090_REG_SWITCH(FET6, "infet6", 0x14, + BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT), + tps65090_fet_control_ops), + tps65090_REG_SWITCH(FET7, "infet7", 0x15, + BIT(CTRL_EN_BIT) | BIT(CTRL_PG_BIT), + tps65090_fet_control_ops), + + tps65090_REG_FIXEDV(LDO1, "vsys-l1", 0, 0, 5000000, + tps65090_ldo_ops), + tps65090_REG_FIXEDV(LDO2, "vsys-l2", 0, 0, 3300000, + tps65090_ldo_ops), }; static inline bool is_dcdc(int id) -- cgit v1.2.2 From 48a1e1b50d9e848fea9708795bd5d9aa97aa9c2a Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Sun, 22 Jun 2014 17:31:41 +0200 Subject: regulator: act8865: fix parsing of platform data The driver loops through all available regulators (ACT8865_REG_NUM) and accesses pdata->regulators[i].platform_data without checking the actual value of num_regulators in platform data, potentially causing a invalid memory access. Fix this and look up the regulator init_data by id in platform data. Signed-off-by: Beniamino Galvani Tested-by Wenyou.Yang Signed-off-by: Mark Brown --- drivers/regulator/act8865-regulator.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/act8865-regulator.c b/drivers/regulator/act8865-regulator.c index b92d7dd01a18..fe2c038f8cbc 100644 --- a/drivers/regulator/act8865-regulator.c +++ b/drivers/regulator/act8865-regulator.c @@ -252,6 +252,22 @@ static inline int act8865_pdata_from_dt(struct device *dev, } #endif +static struct regulator_init_data +*act8865_get_init_data(int id, struct act8865_platform_data *pdata) +{ + int i; + + if (!pdata) + return NULL; + + for (i = 0; i < pdata->num_regulators; i++) { + if (pdata->regulators[i].id == id) + return pdata->regulators[i].platform_data; + } + + return NULL; +} + static int act8865_pmic_probe(struct i2c_client *client, const struct i2c_device_id *i2c_id) { @@ -261,7 +277,7 @@ static int act8865_pmic_probe(struct i2c_client *client, struct regulator_config config = { }; struct act8865 *act8865; struct device_node *of_node[ACT8865_REG_NUM]; - int i, id; + int i; int ret = -EINVAL; int error; @@ -299,20 +315,17 @@ static int act8865_pmic_probe(struct i2c_client *client, /* Finally register devices */ for (i = 0; i < ACT8865_REG_NUM; i++) { - - id = pdata->regulators[i].id; + const struct regulator_desc *desc = &act8865_reg[i]; config.dev = dev; - config.init_data = pdata->regulators[i].platform_data; + config.init_data = act8865_get_init_data(desc->id, pdata); config.of_node = of_node[i]; config.driver_data = act8865; config.regmap = act8865->regmap; - rdev = devm_regulator_register(&client->dev, &act8865_reg[i], - &config); + rdev = devm_regulator_register(&client->dev, desc, &config); if (IS_ERR(rdev)) { - dev_err(dev, "failed to register %s\n", - act8865_reg[id].name); + dev_err(dev, "failed to register %s\n", desc->name); return PTR_ERR(rdev); } } -- cgit v1.2.2 From 40d3bc19667337d4cbad0075d048261fcbe39117 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 30 Jun 2014 15:32:09 +0800 Subject: regulator: act8865: Remove error variable in act8865_pmic_probe Simply use ret variable instead. Also remove unneeded initialize for ret variable. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/act8865-regulator.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/act8865-regulator.c b/drivers/regulator/act8865-regulator.c index fe2c038f8cbc..f07be3647985 100644 --- a/drivers/regulator/act8865-regulator.c +++ b/drivers/regulator/act8865-regulator.c @@ -278,8 +278,7 @@ static int act8865_pmic_probe(struct i2c_client *client, struct act8865 *act8865; struct device_node *of_node[ACT8865_REG_NUM]; int i; - int ret = -EINVAL; - int error; + int ret; if (dev->of_node && !pdata) { const struct of_device_id *id; @@ -307,10 +306,10 @@ static int act8865_pmic_probe(struct i2c_client *client, act8865->regmap = devm_regmap_init_i2c(client, &act8865_regmap_config); if (IS_ERR(act8865->regmap)) { - error = PTR_ERR(act8865->regmap); + ret = PTR_ERR(act8865->regmap); dev_err(&client->dev, "Failed to allocate register map: %d\n", - error); - return error; + ret); + return ret; } /* Finally register devices */ -- cgit v1.2.2 From bbb83f38a8b0702f1b333aef1e8a3aa14068cdc7 Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Sat, 5 Jul 2014 15:20:53 +0200 Subject: regulator: act8865: set correct number of regulators in pdata act8865_pdata_from_dt() populates the array pdata->regulators with all the regulators and then assigns the field init_data only for the ones actually found in the DT. The patch changes the value assigned to pdata->num_regulators to match the size of the array. Signed-off-by: Beniamino Galvani Tested-by: Wenyou Yang Reviewed-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/act8865-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/regulator/act8865-regulator.c b/drivers/regulator/act8865-regulator.c index f07be3647985..52d1b6cad76f 100644 --- a/drivers/regulator/act8865-regulator.c +++ b/drivers/regulator/act8865-regulator.c @@ -230,7 +230,7 @@ static int act8865_pdata_from_dt(struct device *dev, if (!pdata->regulators) return -ENOMEM; - pdata->num_regulators = matched; + pdata->num_regulators = ARRAY_SIZE(act8865_matches); regulator = pdata->regulators; for (i = 0; i < ARRAY_SIZE(act8865_matches); i++) { -- cgit v1.2.2 From 50a03e35b09ea5098ca42a59ad3fdb56a965f2dd Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Sat, 5 Jul 2014 15:20:54 +0200 Subject: regulator: act8865: prepare support for other act88xx devices This patch prepares support for other devices in the act88xx family of PMUs manufactured by Active-Semi. http://www.active-semi.com/products/power-management-units/act88xx/ Signed-off-by: Beniamino Galvani Tested-by: Wenyou Yang Reviewed-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/act8865-regulator.c | 211 +++++++++++++--------------------- 1 file changed, 83 insertions(+), 128 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/act8865-regulator.c b/drivers/regulator/act8865-regulator.c index 52d1b6cad76f..b26eaf7580fc 100644 --- a/drivers/regulator/act8865-regulator.c +++ b/drivers/regulator/act8865-regulator.c @@ -1,6 +1,7 @@ /* - * act8865-regulator.c - Voltage regulation for the active-semi ACT8865 - * http://www.active-semi.com/sheets/ACT8865_Datasheet.pdf + * act8865-regulator.c - Voltage regulation for active-semi ACT88xx PMUs + * + * http://www.active-semi.com/products/power-management-units/act88xx/ * * Copyright (C) 2013 Atmel Corporation * @@ -70,7 +71,7 @@ static const struct regmap_config act8865_regmap_config = { .val_bits = 8, }; -static const struct regulator_linear_range act8865_volatge_ranges[] = { +static const struct regulator_linear_range act8865_voltage_ranges[] = { REGULATOR_LINEAR_RANGE(600000, 0, 23, 25000), REGULATOR_LINEAR_RANGE(1200000, 24, 47, 50000), REGULATOR_LINEAR_RANGE(2400000, 48, 63, 100000), @@ -86,110 +87,35 @@ static struct regulator_ops act8865_ops = { .is_enabled = regulator_is_enabled_regmap, }; -static const struct regulator_desc act8865_reg[] = { - { - .name = "DCDC_REG1", - .id = ACT8865_ID_DCDC1, - .ops = &act8865_ops, - .type = REGULATOR_VOLTAGE, - .n_voltages = ACT8865_VOLTAGE_NUM, - .linear_ranges = act8865_volatge_ranges, - .n_linear_ranges = ARRAY_SIZE(act8865_volatge_ranges), - .vsel_reg = ACT8865_DCDC1_VSET1, - .vsel_mask = ACT8865_VSEL_MASK, - .enable_reg = ACT8865_DCDC1_CTRL, - .enable_mask = ACT8865_ENA, - .owner = THIS_MODULE, - }, - { - .name = "DCDC_REG2", - .id = ACT8865_ID_DCDC2, - .ops = &act8865_ops, - .type = REGULATOR_VOLTAGE, - .n_voltages = ACT8865_VOLTAGE_NUM, - .linear_ranges = act8865_volatge_ranges, - .n_linear_ranges = ARRAY_SIZE(act8865_volatge_ranges), - .vsel_reg = ACT8865_DCDC2_VSET1, - .vsel_mask = ACT8865_VSEL_MASK, - .enable_reg = ACT8865_DCDC2_CTRL, - .enable_mask = ACT8865_ENA, - .owner = THIS_MODULE, - }, - { - .name = "DCDC_REG3", - .id = ACT8865_ID_DCDC3, - .ops = &act8865_ops, - .type = REGULATOR_VOLTAGE, - .n_voltages = ACT8865_VOLTAGE_NUM, - .linear_ranges = act8865_volatge_ranges, - .n_linear_ranges = ARRAY_SIZE(act8865_volatge_ranges), - .vsel_reg = ACT8865_DCDC3_VSET1, - .vsel_mask = ACT8865_VSEL_MASK, - .enable_reg = ACT8865_DCDC3_CTRL, - .enable_mask = ACT8865_ENA, - .owner = THIS_MODULE, - }, - { - .name = "LDO_REG1", - .id = ACT8865_ID_LDO1, - .ops = &act8865_ops, - .type = REGULATOR_VOLTAGE, - .n_voltages = ACT8865_VOLTAGE_NUM, - .linear_ranges = act8865_volatge_ranges, - .n_linear_ranges = ARRAY_SIZE(act8865_volatge_ranges), - .vsel_reg = ACT8865_LDO1_VSET, - .vsel_mask = ACT8865_VSEL_MASK, - .enable_reg = ACT8865_LDO1_CTRL, - .enable_mask = ACT8865_ENA, - .owner = THIS_MODULE, - }, - { - .name = "LDO_REG2", - .id = ACT8865_ID_LDO2, - .ops = &act8865_ops, - .type = REGULATOR_VOLTAGE, - .n_voltages = ACT8865_VOLTAGE_NUM, - .linear_ranges = act8865_volatge_ranges, - .n_linear_ranges = ARRAY_SIZE(act8865_volatge_ranges), - .vsel_reg = ACT8865_LDO2_VSET, - .vsel_mask = ACT8865_VSEL_MASK, - .enable_reg = ACT8865_LDO2_CTRL, - .enable_mask = ACT8865_ENA, - .owner = THIS_MODULE, - }, - { - .name = "LDO_REG3", - .id = ACT8865_ID_LDO3, - .ops = &act8865_ops, - .type = REGULATOR_VOLTAGE, - .n_voltages = ACT8865_VOLTAGE_NUM, - .linear_ranges = act8865_volatge_ranges, - .n_linear_ranges = ARRAY_SIZE(act8865_volatge_ranges), - .vsel_reg = ACT8865_LDO3_VSET, - .vsel_mask = ACT8865_VSEL_MASK, - .enable_reg = ACT8865_LDO3_CTRL, - .enable_mask = ACT8865_ENA, - .owner = THIS_MODULE, - }, - { - .name = "LDO_REG4", - .id = ACT8865_ID_LDO4, - .ops = &act8865_ops, - .type = REGULATOR_VOLTAGE, - .n_voltages = ACT8865_VOLTAGE_NUM, - .linear_ranges = act8865_volatge_ranges, - .n_linear_ranges = ARRAY_SIZE(act8865_volatge_ranges), - .vsel_reg = ACT8865_LDO4_VSET, - .vsel_mask = ACT8865_VSEL_MASK, - .enable_reg = ACT8865_LDO4_CTRL, - .enable_mask = ACT8865_ENA, - .owner = THIS_MODULE, - }, +#define ACT88xx_REG(_name, _family, _id, _vsel_reg) \ + [_family##_ID_##_id] = { \ + .name = _name, \ + .id = _family##_ID_##_id, \ + .type = REGULATOR_VOLTAGE, \ + .ops = &act8865_ops, \ + .n_voltages = ACT8865_VOLTAGE_NUM, \ + .linear_ranges = act8865_voltage_ranges, \ + .n_linear_ranges = ARRAY_SIZE(act8865_voltage_ranges), \ + .vsel_reg = _family##_##_id##_##_vsel_reg, \ + .vsel_mask = ACT8865_VSEL_MASK, \ + .enable_reg = _family##_##_id##_CTRL, \ + .enable_mask = ACT8865_ENA, \ + .owner = THIS_MODULE, \ + } + +static const struct regulator_desc act8865_regulators[] = { + ACT88xx_REG("DCDC_REG1", ACT8865, DCDC1, VSET1), + ACT88xx_REG("DCDC_REG2", ACT8865, DCDC2, VSET1), + ACT88xx_REG("DCDC_REG3", ACT8865, DCDC3, VSET1), + ACT88xx_REG("LDO_REG1", ACT8865, LDO1, VSET), + ACT88xx_REG("LDO_REG2", ACT8865, LDO2, VSET), + ACT88xx_REG("LDO_REG3", ACT8865, LDO3, VSET), + ACT88xx_REG("LDO_REG4", ACT8865, LDO4, VSET), }; #ifdef CONFIG_OF static const struct of_device_id act8865_dt_ids[] = { - { .compatible = "active-semi,act8865" }, + { .compatible = "active-semi,act8865", .data = (void *)ACT8865 }, { } }; MODULE_DEVICE_TABLE(of, act8865_dt_ids); @@ -206,7 +132,9 @@ static struct of_regulator_match act8865_matches[] = { static int act8865_pdata_from_dt(struct device *dev, struct device_node **of_node, - struct act8865_platform_data *pdata) + struct act8865_platform_data *pdata, + struct of_regulator_match *matches, + int num_matches) { int matched, i; struct device_node *np; @@ -218,26 +146,25 @@ static int act8865_pdata_from_dt(struct device *dev, return -EINVAL; } - matched = of_regulator_match(dev, np, - act8865_matches, ARRAY_SIZE(act8865_matches)); + matched = of_regulator_match(dev, np, matches, num_matches); of_node_put(np); if (matched <= 0) return matched; pdata->regulators = devm_kzalloc(dev, - sizeof(struct act8865_regulator_data) * - ARRAY_SIZE(act8865_matches), GFP_KERNEL); + sizeof(struct act8865_regulator_data) * + num_matches, GFP_KERNEL); if (!pdata->regulators) return -ENOMEM; - pdata->num_regulators = ARRAY_SIZE(act8865_matches); + pdata->num_regulators = num_matches; regulator = pdata->regulators; - for (i = 0; i < ARRAY_SIZE(act8865_matches); i++) { + for (i = 0; i < num_matches; i++) { regulator->id = i; - regulator->name = act8865_matches[i].name; - regulator->platform_data = act8865_matches[i].init_data; - of_node[i] = act8865_matches[i].of_node; + regulator->name = matches[i].name; + regulator->platform_data = matches[i].init_data; + of_node[i] = matches[i].of_node; regulator++; } @@ -269,34 +196,59 @@ static struct regulator_init_data } static int act8865_pmic_probe(struct i2c_client *client, - const struct i2c_device_id *i2c_id) + const struct i2c_device_id *i2c_id) { - struct regulator_dev *rdev; + static const struct regulator_desc *regulators; + struct act8865_platform_data pdata_of, *pdata; + struct of_regulator_match *matches; struct device *dev = &client->dev; - struct act8865_platform_data *pdata = dev_get_platdata(dev); - struct regulator_config config = { }; + struct device_node **of_node; + int i, ret, num_regulators; struct act8865 *act8865; - struct device_node *of_node[ACT8865_REG_NUM]; - int i; - int ret; + unsigned long type; + + pdata = dev_get_platdata(dev); if (dev->of_node && !pdata) { const struct of_device_id *id; - struct act8865_platform_data pdata_of; id = of_match_device(of_match_ptr(act8865_dt_ids), dev); if (!id) return -ENODEV; - ret = act8865_pdata_from_dt(dev, of_node, &pdata_of); + type = (unsigned long) id->data; + } else { + type = i2c_id->driver_data; + } + + switch (type) { + case ACT8865: + matches = act8865_matches; + regulators = act8865_regulators; + num_regulators = ARRAY_SIZE(act8865_regulators); + break; + default: + dev_err(dev, "invalid device id %lu\n", type); + return -EINVAL; + } + + of_node = devm_kzalloc(dev, sizeof(struct device_node *) * + num_regulators, GFP_KERNEL); + if (!of_node) + return -ENOMEM; + + if (dev->of_node && !pdata) { + ret = act8865_pdata_from_dt(dev, of_node, &pdata_of, matches, + num_regulators); if (ret < 0) return ret; pdata = &pdata_of; } - if (pdata->num_regulators > ACT8865_REG_NUM) { - dev_err(dev, "Too many regulators found!\n"); + if (pdata->num_regulators > num_regulators) { + dev_err(dev, "too many regulators: %d\n", + pdata->num_regulators); return -EINVAL; } @@ -313,8 +265,10 @@ static int act8865_pmic_probe(struct i2c_client *client, } /* Finally register devices */ - for (i = 0; i < ACT8865_REG_NUM; i++) { - const struct regulator_desc *desc = &act8865_reg[i]; + for (i = 0; i < num_regulators; i++) { + const struct regulator_desc *desc = ®ulators[i]; + struct regulator_config config = { }; + struct regulator_dev *rdev; config.dev = dev; config.init_data = act8865_get_init_data(desc->id, pdata); @@ -330,12 +284,13 @@ static int act8865_pmic_probe(struct i2c_client *client, } i2c_set_clientdata(client, act8865); + devm_kfree(dev, of_node); return 0; } static const struct i2c_device_id act8865_ids[] = { - { "act8865", 0 }, + { .name = "act8865", .driver_data = ACT8865 }, { }, }; MODULE_DEVICE_TABLE(i2c, act8865_ids); @@ -351,6 +306,6 @@ static struct i2c_driver act8865_pmic_driver = { module_i2c_driver(act8865_pmic_driver); -MODULE_DESCRIPTION("active-semi act8865 voltage regulator driver"); +MODULE_DESCRIPTION("active-semi act88xx voltage regulator driver"); MODULE_AUTHOR("Wenyou Yang "); MODULE_LICENSE("GPL v2"); -- cgit v1.2.2 From ac0c0ea8b62949eb371b3227481385362a1425c6 Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Sat, 5 Jul 2014 15:20:55 +0200 Subject: regulator: act8865: add support for act8846 Add device id and definition of registers and regulators to support the act8846 PMU. Signed-off-by: Beniamino Galvani Tested-by: Wenyou Yang Reviewed-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/act8865-regulator.c | 71 +++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) (limited to 'drivers') diff --git a/drivers/regulator/act8865-regulator.c b/drivers/regulator/act8865-regulator.c index b26eaf7580fc..a5ad69a0aca9 100644 --- a/drivers/regulator/act8865-regulator.c +++ b/drivers/regulator/act8865-regulator.c @@ -28,6 +28,40 @@ #include #include +/* + * ACT8846 Global Register Map. + */ +#define ACT8846_SYS0 0x00 +#define ACT8846_SYS1 0x01 +#define ACT8846_REG1_VSET 0x10 +#define ACT8846_REG1_CTRL 0x12 +#define ACT8846_REG2_VSET0 0x20 +#define ACT8846_REG2_VSET1 0x21 +#define ACT8846_REG2_CTRL 0x22 +#define ACT8846_REG3_VSET0 0x30 +#define ACT8846_REG3_VSET1 0x31 +#define ACT8846_REG3_CTRL 0x32 +#define ACT8846_REG4_VSET0 0x40 +#define ACT8846_REG4_VSET1 0x41 +#define ACT8846_REG4_CTRL 0x42 +#define ACT8846_REG5_VSET 0x50 +#define ACT8846_REG5_CTRL 0x51 +#define ACT8846_REG6_VSET 0x58 +#define ACT8846_REG6_CTRL 0x59 +#define ACT8846_REG7_VSET 0x60 +#define ACT8846_REG7_CTRL 0x61 +#define ACT8846_REG8_VSET 0x68 +#define ACT8846_REG8_CTRL 0x69 +#define ACT8846_REG9_VSET 0x70 +#define ACT8846_REG9_CTRL 0x71 +#define ACT8846_REG10_VSET 0x80 +#define ACT8846_REG10_CTRL 0x81 +#define ACT8846_REG11_VSET 0x90 +#define ACT8846_REG11_CTRL 0x91 +#define ACT8846_REG12_VSET 0xa0 +#define ACT8846_REG12_CTRL 0xa1 +#define ACT8846_REG13_CTRL 0xb1 + /* * ACT8865 Global Register Map. */ @@ -103,6 +137,21 @@ static struct regulator_ops act8865_ops = { .owner = THIS_MODULE, \ } +static const struct regulator_desc act8846_regulators[] = { + ACT88xx_REG("REG1", ACT8846, REG1, VSET), + ACT88xx_REG("REG2", ACT8846, REG2, VSET0), + ACT88xx_REG("REG3", ACT8846, REG3, VSET0), + ACT88xx_REG("REG4", ACT8846, REG4, VSET0), + ACT88xx_REG("REG5", ACT8846, REG5, VSET), + ACT88xx_REG("REG6", ACT8846, REG6, VSET), + ACT88xx_REG("REG7", ACT8846, REG7, VSET), + ACT88xx_REG("REG8", ACT8846, REG8, VSET), + ACT88xx_REG("REG9", ACT8846, REG9, VSET), + ACT88xx_REG("REG10", ACT8846, REG10, VSET), + ACT88xx_REG("REG11", ACT8846, REG11, VSET), + ACT88xx_REG("REG12", ACT8846, REG12, VSET), +}; + static const struct regulator_desc act8865_regulators[] = { ACT88xx_REG("DCDC_REG1", ACT8865, DCDC1, VSET1), ACT88xx_REG("DCDC_REG2", ACT8865, DCDC2, VSET1), @@ -115,11 +164,27 @@ static const struct regulator_desc act8865_regulators[] = { #ifdef CONFIG_OF static const struct of_device_id act8865_dt_ids[] = { + { .compatible = "active-semi,act8846", .data = (void *)ACT8846 }, { .compatible = "active-semi,act8865", .data = (void *)ACT8865 }, { } }; MODULE_DEVICE_TABLE(of, act8865_dt_ids); +static struct of_regulator_match act8846_matches[] = { + [ACT8846_ID_REG1] = { .name = "REG1" }, + [ACT8846_ID_REG2] = { .name = "REG2" }, + [ACT8846_ID_REG3] = { .name = "REG3" }, + [ACT8846_ID_REG4] = { .name = "REG4" }, + [ACT8846_ID_REG5] = { .name = "REG5" }, + [ACT8846_ID_REG6] = { .name = "REG6" }, + [ACT8846_ID_REG7] = { .name = "REG7" }, + [ACT8846_ID_REG8] = { .name = "REG8" }, + [ACT8846_ID_REG9] = { .name = "REG9" }, + [ACT8846_ID_REG10] = { .name = "REG10" }, + [ACT8846_ID_REG11] = { .name = "REG11" }, + [ACT8846_ID_REG12] = { .name = "REG12" }, +}; + static struct of_regulator_match act8865_matches[] = { [ACT8865_ID_DCDC1] = { .name = "DCDC_REG1"}, [ACT8865_ID_DCDC2] = { .name = "DCDC_REG2"}, @@ -222,6 +287,11 @@ static int act8865_pmic_probe(struct i2c_client *client, } switch (type) { + case ACT8846: + matches = act8846_matches; + regulators = act8846_regulators; + num_regulators = ARRAY_SIZE(act8846_regulators); + break; case ACT8865: matches = act8865_matches; regulators = act8865_regulators; @@ -290,6 +360,7 @@ static int act8865_pmic_probe(struct i2c_client *client, } static const struct i2c_device_id act8865_ids[] = { + { .name = "act8846", .driver_data = ACT8846 }, { .name = "act8865", .driver_data = ACT8865 }, { }, }; -- cgit v1.2.2 From 34e0247ffcae3228684668a6244a7308b78571c7 Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Mon, 7 Jul 2014 23:40:47 +0200 Subject: regulator: act8865: fix build when OF is not enabled act8846_matches and act8865_matches are defined only when OF is enabled. Move references to them to the act8865_pdata_from_dt() function to avoid a build error when OF is disabled. Reported-by: kbuild test robot Signed-off-by: Beniamino Galvani Signed-off-by: Mark Brown --- drivers/regulator/act8865-regulator.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/act8865-regulator.c b/drivers/regulator/act8865-regulator.c index a5ad69a0aca9..afd06f92dfdf 100644 --- a/drivers/regulator/act8865-regulator.c +++ b/drivers/regulator/act8865-regulator.c @@ -198,12 +198,12 @@ static struct of_regulator_match act8865_matches[] = { static int act8865_pdata_from_dt(struct device *dev, struct device_node **of_node, struct act8865_platform_data *pdata, - struct of_regulator_match *matches, - int num_matches) + unsigned long type) { - int matched, i; + int matched, i, num_matches; struct device_node *np; struct act8865_regulator_data *regulator; + struct of_regulator_match *matches; np = of_get_child_by_name(dev->of_node, "regulators"); if (!np) { @@ -211,6 +211,20 @@ static int act8865_pdata_from_dt(struct device *dev, return -EINVAL; } + switch (type) { + case ACT8846: + matches = act8846_matches; + num_matches = ARRAY_SIZE(act8846_matches); + break; + case ACT8865: + matches = act8865_matches; + num_matches = ARRAY_SIZE(act8865_matches); + break; + default: + dev_err(dev, "invalid device id %lu\n", type); + return -EINVAL; + } + matched = of_regulator_match(dev, np, matches, num_matches); of_node_put(np); if (matched <= 0) @@ -238,7 +252,8 @@ static int act8865_pdata_from_dt(struct device *dev, #else static inline int act8865_pdata_from_dt(struct device *dev, struct device_node **of_node, - struct act8865_platform_data *pdata) + struct act8865_platform_data *pdata, + unsigned long type) { return 0; } @@ -265,7 +280,6 @@ static int act8865_pmic_probe(struct i2c_client *client, { static const struct regulator_desc *regulators; struct act8865_platform_data pdata_of, *pdata; - struct of_regulator_match *matches; struct device *dev = &client->dev; struct device_node **of_node; int i, ret, num_regulators; @@ -288,12 +302,10 @@ static int act8865_pmic_probe(struct i2c_client *client, switch (type) { case ACT8846: - matches = act8846_matches; regulators = act8846_regulators; num_regulators = ARRAY_SIZE(act8846_regulators); break; case ACT8865: - matches = act8865_matches; regulators = act8865_regulators; num_regulators = ARRAY_SIZE(act8865_regulators); break; @@ -308,8 +320,7 @@ static int act8865_pmic_probe(struct i2c_client *client, return -ENOMEM; if (dev->of_node && !pdata) { - ret = act8865_pdata_from_dt(dev, of_node, &pdata_of, matches, - num_regulators); + ret = act8865_pdata_from_dt(dev, of_node, &pdata_of, type); if (ret < 0) return ret; -- cgit v1.2.2