Skip to contentSkip to conversation

regulator: palmas: Fix calculating selector in palmas_map_voltage_ldo

PATCH In review Axel Lin 2 participants 7 messages Jul 18, 2012 – Aug 1, 2012

Subsystems (2)
lore
Share & tools
lore

Axel Lin

author
#0 lore raw

PATCH 1/5 regulator: palmas: Fix calculating selector in palmas_map_voltage_ldo

This patch fixes below issues when choosing selector:

1. Current code returns negative selector if min_uV < 900000 which is wrong. For example, it is possible to satisfy the request with selector = 1 if the requested min_uV is 850000.
2. Current code may select a voltage lower than requested min_uV. For example, if the requested min_uV is 945000, current code chooses selector = 1 which is lower than requested min_uV. DIV_ROUND_UP to avoid this case.

---
 drivers/regulator/palmas-regulator.c |    9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)
drivers/regulator/palmas-regulator.c +6 -3
index 17d19fb..0fcf355 100644
@@ -486,9 +486,12 @@ static int palmas_map_voltage_ldo(struct regulator_dev *rdev,
 {
 	int ret, voltage;
 
-	ret = ((min_uV - 900000) / 50000) + 1;
-	if (ret < 0)
-		return ret;
+	if (min_uV == 0)
+		return 0;
+
+	if (min_uV < 900000)
+		min_uV = 900000;
+	ret = DIV_ROUND_UP(min_uV - 900000, 50000) + 1;
 
 	/* Map back into a voltage to verify we're still in bounds */
 	voltage = palmas_list_voltage_ldo(rdev, ret);
Signature · 1 line
1.7.9.5
author
#1 lore raw

PATCH 2/5 regulator: palmas: Fix regmap offsets for PALMAS_REG_SMPS10 vsel_reg

---
 drivers/regulator/palmas-regulator.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/regulator/palmas-regulator.c +3 -1
index 0fcf355..9e3e7f3 100644
@@ -679,7 +679,9 @@ static __devinit int palmas_probe(struct platform_device *pdev)
 		case PALMAS_REG_SMPS10:
 			pmic->desc[id].n_voltages = PALMAS_SMPS10_NUM_VOLTAGES;
 			pmic->desc[id].ops = &palmas_ops_smps10;
-			pmic->desc[id].vsel_reg = PALMAS_SMPS10_CTRL;
+			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,
Signature · 1 line
1.7.9.5
author
#2 lore raw

PATCH 3/5 regulator: palmas: Call palmas_ldo_[read|write] in palmas_ldo_init

In reply to Axel Lin

Current code uses wrong calls palmas_smps_[read|write] in palmas_ldo_init(), should be palmas_ldo_[read|write] instead.

---
 drivers/regulator/palmas-regulator.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/regulator/palmas-regulator.c +2 -2
index 9e3e7f3..de68347 100644
@@ -589,7 +589,7 @@ static int palmas_ldo_init(struct palmas *palmas, int id,
 
 	addr = palmas_regs_info[id].ctrl_addr;
 
-	ret = palmas_smps_read(palmas, addr, &reg);
+	ret = palmas_ldo_read(palmas, addr, &reg);
 	if (ret)
 		return ret;
 
@@ -599,7 +599,7 @@ static int palmas_ldo_init(struct palmas *palmas, int id,
 	if (reg_init->mode_sleep)
 		reg |= PALMAS_LDO1_CTRL_MODE_SLEEP;
 
-	ret = palmas_smps_write(palmas, addr, reg);
+	ret = palmas_ldo_write(palmas, addr, reg);
 	if (ret)
 		return ret;
 
Signature · 1 line
1.7.9.5
author
#3 lore raw

PATCH 4/5 regulator: palmas: Fix palmas_probe error handling

In reply to Axel Lin

Fix below error handling cases:

1. If reading PALMAS_SMPS_CTRL fails, simply returns ret rather than goto err_unregister_regulator because we have not call regulator_register().
2. If palmas_ldo_init() fails, we need to call regulator_unregister() for the regulator we just successfully registered in this for loop iteration.

---
 drivers/regulator/palmas-regulator.c |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/regulator/palmas-regulator.c +4 -2
index de68347..46c7e88 100644
@@ -633,7 +633,7 @@ static __devinit int palmas_probe(struct platform_device *pdev)
 
 	ret = palmas_smps_read(palmas, PALMAS_SMPS_CTRL, &reg);
 	if (ret)
-		goto err_unregister_regulator;
+		return ret;
 
 	if (reg & PALMAS_SMPS_CTRL_SMPS12_SMPS123_EN)
 		pmic->smps123 = 1;
@@ -783,8 +783,10 @@ static __devinit int palmas_probe(struct platform_device *pdev)
 			reg_init = pdata->reg_init[id];
 			if (reg_init) {
 				ret = palmas_ldo_init(palmas, id, reg_init);
-				if (ret)
+				if (ret) {
+					regulator_unregister(pmic->rdev[id]);
 					goto err_unregister_regulator;
+				}
 			}
 		}
 	}
Signature · 1 line
1.7.9.5
author
#4 lore raw

PATCH v2 5/5 regulator: palmas: Convert palmas_ops_ldo to [get|set]_voltage_sel_regmap

In reply to Axel Lin
---
 drivers/regulator/palmas-regulator.c |   45 ++++------------------------------
 1 file changed, 5 insertions(+), 40 deletions(-)
drivers/regulator/palmas-regulator.c +5 -40
index 46c7e88..2ba7502 100644
@@ -443,44 +443,6 @@ static int palmas_list_voltage_ldo(struct regulator_dev *dev,
 	return  850000 + (selector * 50000);
 }
 
-static int palmas_get_voltage_ldo_sel(struct regulator_dev *dev)
-{
-	struct palmas_pmic *pmic = rdev_get_drvdata(dev);
-	int id = rdev_get_id(dev);
-	int selector;
-	unsigned int reg;
-	unsigned int addr;
-
-	addr = palmas_regs_info[id].vsel_addr;
-
-	palmas_ldo_read(pmic->palmas, addr, &reg);
-
-	selector = reg & PALMAS_LDO1_VOLTAGE_VSEL_MASK;
-
-	/* Adjust selector to match list_voltage ranges */
-	if (selector > 49)
-		selector = 49;
-
-	return selector;
-}
-
-static int palmas_set_voltage_ldo_sel(struct regulator_dev *dev,
-		unsigned selector)
-{
-	struct palmas_pmic *pmic = rdev_get_drvdata(dev);
-	int id = rdev_get_id(dev);
-	unsigned int reg = 0;
-	unsigned int addr;
-
-	addr = palmas_regs_info[id].vsel_addr;
-
-	reg = selector;
-
-	palmas_ldo_write(pmic->palmas, addr, reg);
-
-	return 0;
-}
-
 static int palmas_map_voltage_ldo(struct regulator_dev *rdev,
 		int min_uV, int max_uV)
 {
@@ -505,8 +467,8 @@ static struct regulator_ops palmas_ops_ldo = {
 	.is_enabled		= palmas_is_enabled_ldo,
 	.enable			= regulator_enable_regmap,
 	.disable		= regulator_disable_regmap,
-	.get_voltage_sel	= palmas_get_voltage_ldo_sel,
-	.set_voltage_sel	= palmas_set_voltage_ldo_sel,
+	.get_voltage_sel	= regulator_get_voltage_sel_regmap,
+	.set_voltage_sel	= regulator_set_voltage_sel_regmap,
 	.list_voltage		= palmas_list_voltage_ldo,
 	.map_voltage		= palmas_map_voltage_ldo,
 };
@@ -757,6 +719,9 @@ static __devinit int palmas_probe(struct platform_device *pdev)
 
 		pmic->desc[id].type = REGULATOR_VOLTAGE;
 		pmic->desc[id].owner = THIS_MODULE;
+		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;
Signature · 1 line
1.7.9.5
#6 lore raw
In reply to Axel Lin
Quoted 5 lines · Axel Lin

This patch fixes below issues when choosing selector:

1. Current code returns negative selector if min_uV < 900000 which is wrong. For example, it is possible to satisfy the request with selector = 1 if the requested min_uV is 850000.

Applied 1-4, thanks.