From: Axel Lin <axel.lin@ingics.com>
To: Mark Brown <broonie@opensource.wolfsonmicro.com>
Cc: Laxman Dewangan <ldewangan@nvidia.com>,
Liam Girdwood <lgirdwood@gmail.com>,
linux-kernel@vger.kernel.org
Subject: [RFT][PATCH 1/2] regulator: tps80031: Fix LDO2 track mode for TPS80031 or TPS80032-ES1.0
Date: Wed, 17 Apr 2013 21:42:23 +0800 [thread overview]
Message-ID: <1366206143.3305.4.camel@phoenix> (raw)
Currently we have a special code in tps80031_ldo_set_voltage_sel() to handle
LDO2 track mode for TPS80031 or TPS80032-ES1.0. The purpose is to address below
issues:
Issue description:
- LDO2 traking mode is enabled
- LDO2 tracks SMPS2 voltage.
- LDO2 automatically switch-off when LDO2_CFG_VOLTAGE is changed to some discrete values (non exhaustive list):
00011001, 00011010, 00011011, 00011100, .
- LDO2 switch-on again when LDO2_CFG_VOLTAGE is changed to other values (non exhaustive list):
00011000, 00010111, .
LDOs have reserved codes. For these codes, LDO is switch-off.
In tracking, LDO2 ref comes from SMPS2.
However LDO2 enable is still gated by LDO2 VSEL decoding.
As a result, in tracking mode LDO2 will be disabled for following code (SMPS VSEL format):
000000 & 100000 (MSB not decoded)
011001 & 111001 (MSB not decoded)
011010 & 111010 (MSB not decoded)
011100 & 111100 (MSB not decoded)
011101 & 111101 (MSB not decoded)
011110 & 111110 (MSB not decoded)
However, current code has below bugs:
1. It uses regulator_list_voltage_linear, so list_voltage() still shows above
invalid selectors have supported voltage.
2. Current code may return -EINVAL in tps80031_ldo_set_voltage_sel() for
supported voltage. This is because when we use regulator_list_voltage_linear
as list_voltage callback, regulator core will default use
regulator_map_voltage_linear(). regulator_map_voltage_linear() has an
assumption that the voltages are linear which is not true for this case.
For example,
when request voltage range is: min_uV=950000 uV && max_uV=1200000 uV
regulator_map_voltage_linear() returns the selector is 29 (0x1D),
set_voltage_sel() returns -EINVAL.
(The selector is in invalid range, 0x19 ~ 0x1f).
In above case, map_voltage() should find the lowest valid voltage within
specific range (selector = 0x20) and set_voltage_sel() should successfully
set the voltage to 987500 uV.
This patch fixes these issues by:
1. Add checking valid setting for LDO2 track mode of TPS80031 or TPS80032-ES1.0
in list_voltage. So it returns -EINVAL for invalid selectors.
2. Implement tps80031_ldo_map_voltage, use regulator_map_voltage_iterate()
to find the lowest voltage within specific range for TPS80031 or
TPS80032-ES1.0. This is required when the voltage map is no longer linear.
Signed-off-by: Axel Lin <axel.lin@ingics.com>
---
Hi Laxman,
I don't have this hardware, can you test this patch serial?
Thank you,
Axel
drivers/regulator/tps80031-regulator.c | 38 ++++++++++++++++++++++++++++----
1 file changed, 34 insertions(+), 4 deletions(-)
diff --git a/drivers/regulator/tps80031-regulator.c b/drivers/regulator/tps80031-regulator.c
index 9019d0e..6430789 100644
--- a/drivers/regulator/tps80031-regulator.c
+++ b/drivers/regulator/tps80031-regulator.c
@@ -238,12 +238,11 @@ static int tps80031_dcdc_get_voltage_sel(struct regulator_dev *rdev)
return vsel & SMPS_VSEL_MASK;
}
-static int tps80031_ldo_set_voltage_sel(struct regulator_dev *rdev,
- unsigned sel)
+static int tps80031_ldo_list_voltage(struct regulator_dev *rdev,
+ unsigned int sel)
{
struct tps80031_regulator *ri = rdev_get_drvdata(rdev);
struct device *parent = to_tps80031_dev(rdev);
- int ret;
/* Check for valid setting for TPS80031 or TPS80032-ES1.0 */
if ((ri->rinfo->desc.id == TPS80031_REGULATOR_LDO2) &&
@@ -260,6 +259,36 @@ static int tps80031_ldo_set_voltage_sel(struct regulator_dev *rdev,
}
}
+ return regulator_list_voltage_linear(rdev, sel);
+}
+
+static int tps80031_ldo_map_voltage(struct regulator_dev *rdev,
+ int min_uV, int max_uV)
+{
+ struct tps80031_regulator *ri = rdev_get_drvdata(rdev);
+ struct device *parent = to_tps80031_dev(rdev);
+
+ /* Check for valid setting for TPS80031 or TPS80032-ES1.0 */
+ if ((ri->rinfo->desc.id == TPS80031_REGULATOR_LDO2) &&
+ (ri->device_flags & TRACK_MODE_ENABLE)) {
+ if (((tps80031_get_chip_info(parent) == TPS80031) ||
+ ((tps80031_get_chip_info(parent) == TPS80032) &&
+ (tps80031_get_pmu_version(parent) == 0x0)))) {
+ return regulator_map_voltage_iterate(rdev, min_uV,
+ max_uV);
+ }
+ }
+
+ return regulator_map_voltage_linear(rdev, min_uV, max_uV);
+}
+
+static int tps80031_ldo_set_voltage_sel(struct regulator_dev *rdev,
+ unsigned sel)
+{
+ struct tps80031_regulator *ri = rdev_get_drvdata(rdev);
+ struct device *parent = to_tps80031_dev(rdev);
+ int ret;
+
ret = tps80031_write(parent, ri->rinfo->volt_id,
ri->rinfo->volt_reg, sel);
if (ret < 0)
@@ -390,7 +419,8 @@ static struct regulator_ops tps80031_dcdc_ops = {
};
static struct regulator_ops tps80031_ldo_ops = {
- .list_voltage = regulator_list_voltage_linear,
+ .list_voltage = tps80031_ldo_list_voltage,
+ .map_voltage = tps80031_ldo_map_voltage,
.set_voltage_sel = tps80031_ldo_set_voltage_sel,
.get_voltage_sel = tps80031_ldo_get_voltage_sel,
.enable = tps80031_reg_enable,
--
1.7.10.4
next reply other threads:[~2013-04-17 13:42 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-04-17 13:42 Axel Lin [this message]
2013-04-17 13:43 ` [RFT][PATCH 2/2] regulator: tps80031: Convert tps80031_dcdc_ops to [get|set]_voltage_sel_regmap Axel Lin
2013-04-23 10:48 ` Mark Brown
2013-04-23 10:48 ` [RFT][PATCH 1/2] regulator: tps80031: Fix LDO2 track mode for TPS80031 or TPS80032-ES1.0 Mark Brown
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1366206143.3305.4.camel@phoenix \
--to=axel.lin@ingics.com \
--cc=broonie@opensource.wolfsonmicro.com \
--cc=ldewangan@nvidia.com \
--cc=lgirdwood@gmail.com \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.