Clear the sleep/warm reset bits when it is not selected through
regulator platform data. This will make sure that configuration
is inline with the platform data regardless of boot/POR
configuration.
Signed-off-by: Laxman Dewangan <[email protected]>
---
drivers/regulator/palmas-regulator.c | 18 ++++++++++++------
1 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c
index 7c54e31..7c7992b 100644
--- a/drivers/regulator/palmas-regulator.c
+++ b/drivers/regulator/palmas-regulator.c
@@ -444,24 +444,26 @@ static int palmas_smps_init(struct palmas *palmas, int id,
switch (id) {
case PALMAS_REG_SMPS10:
- if (reg_init->mode_sleep) {
- reg &= ~PALMAS_SMPS10_CTRL_MODE_SLEEP_MASK;
+ reg &= ~PALMAS_SMPS10_CTRL_MODE_SLEEP_MASK;
+ if (reg_init->mode_sleep)
reg |= reg_init->mode_sleep <<
PALMAS_SMPS10_CTRL_MODE_SLEEP_SHIFT;
- }
break;
default:
if (reg_init->warm_reset)
reg |= PALMAS_SMPS12_CTRL_WR_S;
+ else
+ reg &= ~PALMAS_SMPS12_CTRL_WR_S;
if (reg_init->roof_floor)
reg |= PALMAS_SMPS12_CTRL_ROOF_FLOOR_EN;
+ else
+ reg &= ~PALMAS_SMPS12_CTRL_ROOF_FLOOR_EN;
- if (reg_init->mode_sleep) {
- reg &= ~PALMAS_SMPS12_CTRL_MODE_SLEEP_MASK;
+ reg &= ~PALMAS_SMPS12_CTRL_MODE_SLEEP_MASK;
+ if (reg_init->mode_sleep)
reg |= reg_init->mode_sleep <<
PALMAS_SMPS12_CTRL_MODE_SLEEP_SHIFT;
- }
}
ret = palmas_smps_write(palmas, addr, reg);
@@ -507,9 +509,13 @@ static int palmas_ldo_init(struct palmas *palmas, int id,
if (reg_init->warm_reset)
reg |= PALMAS_LDO1_CTRL_WR_S;
+ else
+ reg &= ~PALMAS_LDO1_CTRL_WR_S;
if (reg_init->mode_sleep)
reg |= PALMAS_LDO1_CTRL_MODE_SLEEP;
+ else
+ reg &= ~PALMAS_LDO1_CTRL_MODE_SLEEP;
ret = palmas_ldo_write(palmas, addr, reg);
if (ret)
--
1.7.1.1
LDO8 of Palma device like tps65913 support the tracking mode
on which LDO8 track the SMPS45 voltage when SMPS45 is ON
and use the LDO8.VOLTAGE_SEL register when SMPS45 is OFF.
On track mode, the steps of voltage change for LDO8 is 25mV
where in non-tracking mode it is 50mV. Set the steps accordingly.
Number of voltage count is still same for both the cases.
Signed-off-by: Laxman Dewangan <[email protected]>
---
drivers/regulator/palmas-regulator.c | 53 ++++++++++++++++++++++++++++++++++
include/linux/mfd/palmas.h | 3 ++
2 files changed, 56 insertions(+), 0 deletions(-)
diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c
index 28080a7..d6efaf1 100644
--- a/drivers/regulator/palmas-regulator.c
+++ b/drivers/regulator/palmas-regulator.c
@@ -572,6 +572,46 @@ static int palmas_extreg_init(struct palmas *palmas, int id,
return 0;
}
+static void palmas_enable_ldo8_track(struct palmas *palmas)
+{
+ unsigned int reg;
+ unsigned int addr;
+ int ret;
+
+ addr = palmas_regs_info[PALMAS_REG_LDO8].ctrl_addr;
+
+ ret = palmas_ldo_read(palmas, addr, ®);
+ if (ret) {
+ dev_err(palmas->dev, "Error in reading ldo8 control reg\n");
+ return;
+ }
+
+ reg |= PALMAS_LDO8_CTRL_LDO_TRACKING_EN;
+ ret = palmas_ldo_write(palmas, addr, reg);
+ if (ret < 0) {
+ dev_err(palmas->dev, "Error in enabling tracking mode\n");
+ return;
+ }
+ /*
+ * When SMPS45 is set to off and LDO8 tracking is enabled, the LDO8
+ * 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;
+ ret = palmas_ldo_read(palmas, addr, ®);
+ if (ret) {
+ dev_err(palmas->dev, "Error in reading ldo8 voltage reg\n");
+ return;
+ }
+
+ reg = (reg << 1) & PALMAS_LDO8_VOLTAGE_VSEL_MASK;
+ ret = palmas_ldo_write(palmas, addr, reg);
+ if (ret < 0)
+ dev_err(palmas->dev, "Error in setting ldo8 voltage reg\n");
+
+ return;
+}
+
static struct of_regulator_match palmas_matches[] = {
{ .name = "smps12", },
{ .name = "smps123", },
@@ -657,6 +697,11 @@ static void palmas_dt_to_pdata(struct device *dev,
if (ret)
pdata->reg_init[idx]->vsel =
PALMAS_SMPS12_VOLTAGE_RANGE;
+
+ if (idx == PALMAS_REG_LDO8)
+ pdata->enable_ldo8_tracking = of_property_read_bool(
+ palmas_matches[idx].of_node,
+ "ti,enable-ldo8-tracking");
}
pdata->ldo6_vibrator = of_property_read_bool(node, "ti,ldo6-vibrator");
@@ -836,6 +881,13 @@ static int palmas_regulators_probe(struct platform_device *pdev)
palmas_regs_info[id].ctrl_addr);
pmic->desc[id].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(palmas);
+ pmic->desc[id].uV_step = 25000;
+ }
} else {
pmic->desc[id].n_voltages = 1;
pmic->desc[id].ops = &palmas_ops_extreg;
@@ -884,6 +936,7 @@ static int palmas_regulators_probe(struct platform_device *pdev)
}
}
+
return 0;
err_unregister_regulator:
diff --git a/include/linux/mfd/palmas.h b/include/linux/mfd/palmas.h
index fb04d07..12d8a62 100644
--- a/include/linux/mfd/palmas.h
+++ b/include/linux/mfd/palmas.h
@@ -187,6 +187,9 @@ struct palmas_pmic_platform_data {
/* use LDO6 for vibrator control */
int ldo6_vibrator;
+
+ /* Enable tracking mode of LDO8 */
+ bool enable_ldo8_tracking;
};
struct palmas_usb_platform_data {
--
1.7.1.1
Palmas device have control outputs like REGEN1, REGEN2, REGEN3,
SYSEN1 and SYSEN2. These control outputs can be used for controlling
external voltage switches to enabled/disable voltage outputs.
Add support of these control outputs through regulator framework.
Signed-off-by: Laxman Dewangan <[email protected]>
---
drivers/regulator/palmas-regulator.c | 95 +++++++++++++++++++++++++++++----
include/linux/mfd/palmas.h | 6 ++
2 files changed, 89 insertions(+), 12 deletions(-)
diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c
index 7c7992b..28080a7 100644
--- a/drivers/regulator/palmas-regulator.c
+++ b/drivers/regulator/palmas-regulator.c
@@ -166,6 +166,26 @@ static const struct regs_info palmas_regs_info[] = {
.vsel_addr = PALMAS_LDOUSB_VOLTAGE,
.ctrl_addr = PALMAS_LDOUSB_CTRL,
},
+ {
+ .name = "REGEN1",
+ .ctrl_addr = PALMAS_REGEN1_CTRL,
+ },
+ {
+ .name = "REGEN2",
+ .ctrl_addr = PALMAS_REGEN2_CTRL,
+ },
+ {
+ .name = "REGEN3",
+ .ctrl_addr = PALMAS_REGEN3_CTRL,
+ },
+ {
+ .name = "SYSEN1",
+ .ctrl_addr = PALMAS_SYSEN1_CTRL,
+ },
+ {
+ .name = "SYSEN2",
+ .ctrl_addr = PALMAS_SYSEN2_CTRL,
+ },
};
#define SMPS_CTRL_MODE_OFF 0x00
@@ -423,6 +443,12 @@ static struct regulator_ops palmas_ops_ldo = {
.map_voltage = regulator_map_voltage_linear,
};
+static struct regulator_ops palmas_ops_extreg = {
+ .is_enabled = regulator_is_enabled_regmap,
+ .enable = regulator_enable_regmap,
+ .disable = regulator_disable_regmap,
+};
+
/*
* setup the hardware based sleep configuration of the SMPS/LDO regulators
* from the platform data. This is different to the software based control
@@ -524,6 +550,28 @@ static int palmas_ldo_init(struct palmas *palmas, int id,
return 0;
}
+static int palmas_extreg_init(struct palmas *palmas, int id,
+ struct palmas_reg_init *reg_init)
+{
+ unsigned int addr;
+ int ret;
+ unsigned int val = 0;
+
+ addr = palmas_regs_info[id].ctrl_addr;
+
+ if (reg_init->mode_sleep)
+ val = PALMAS_REGEN1_CTRL_MODE_SLEEP;
+
+ ret = palmas_update_bits(palmas, PALMAS_RESOURCE_BASE,
+ addr, PALMAS_REGEN1_CTRL_MODE_SLEEP, val);
+ if (ret < 0) {
+ dev_err(palmas->dev, "Resource reg 0x%02x update failed %d\n",
+ addr, ret);
+ return ret;
+ }
+ return 0;
+}
+
static struct of_regulator_match palmas_matches[] = {
{ .name = "smps12", },
{ .name = "smps123", },
@@ -546,6 +594,11 @@ static struct of_regulator_match palmas_matches[] = {
{ .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,
@@ -764,21 +817,34 @@ static int palmas_regulators_probe(struct platform_device *pdev)
/* Register the regulators */
pmic->desc[id].name = palmas_regs_info[id].name;
pmic->desc[id].id = id;
- pmic->desc[id].n_voltages = PALMAS_LDO_NUM_VOLTAGES;
-
- pmic->desc[id].ops = &palmas_ops_ldo;
-
pmic->desc[id].type = REGULATOR_VOLTAGE;
pmic->desc[id].owner = THIS_MODULE;
- pmic->desc[id].min_uV = 900000;
- pmic->desc[id].uV_step = 50000;
- pmic->desc[id].linear_min_sel = 1;
- pmic->desc[id].vsel_reg = PALMAS_BASE_TO_REG(PALMAS_LDO_BASE,
+
+ if (id < PALMAS_REG_REGEN1) {
+ pmic->desc[id].n_voltages = PALMAS_LDO_NUM_VOLTAGES;
+ 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].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,
+ 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;
+ } else {
+ pmic->desc[id].n_voltages = 1;
+ 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_LDO1_CTRL_MODE_ACTIVE;
+ pmic->desc[id].enable_mask =
+ PALMAS_REGEN1_CTRL_MODE_ACTIVE;
+ }
if (pdata)
config.init_data = pdata->reg_data[id];
@@ -804,7 +870,12 @@ static int palmas_regulators_probe(struct platform_device *pdev)
if (pdata) {
reg_init = pdata->reg_init[id];
if (reg_init) {
- ret = palmas_ldo_init(palmas, id, 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) {
regulator_unregister(pmic->rdev[id]);
goto err_unregister_regulator;
diff --git a/include/linux/mfd/palmas.h b/include/linux/mfd/palmas.h
index 4a066d0..fb04d07 100644
--- a/include/linux/mfd/palmas.h
+++ b/include/linux/mfd/palmas.h
@@ -164,6 +164,12 @@ enum palmas_regulators {
PALMAS_REG_LDO9,
PALMAS_REG_LDOLN,
PALMAS_REG_LDOUSB,
+ /* External regulators */
+ PALMAS_REG_REGEN1,
+ PALMAS_REG_REGEN2,
+ PALMAS_REG_REGEN3,
+ PALMAS_REG_SYSEN1,
+ PALMAS_REG_SYSEN2,
/* Total number of regulators */
PALMAS_NUM_REGS,
};
--
1.7.1.1
This looks good to me with one proviso!
SYSEN1/2 are not necessarily for regulators as given by the name, they
are more for use indicating to other chips that power is now
available/stable.
But it will not break things to have them exposed in regulator API so I
shall leave this to Mark.
Graeme
On 17/04/13 10:43, Laxman Dewangan wrote:
> Palmas device have control outputs like REGEN1, REGEN2, REGEN3,
> SYSEN1 and SYSEN2. These control outputs can be used for controlling
> external voltage switches to enabled/disable voltage outputs.
>
> Add support of these control outputs through regulator framework.
>
> Signed-off-by: Laxman Dewangan <[email protected]>
> ---
> drivers/regulator/palmas-regulator.c | 95 +++++++++++++++++++++++++++++----
> include/linux/mfd/palmas.h | 6 ++
> 2 files changed, 89 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c
> index 7c7992b..28080a7 100644
> --- a/drivers/regulator/palmas-regulator.c
> +++ b/drivers/regulator/palmas-regulator.c
> @@ -166,6 +166,26 @@ static const struct regs_info palmas_regs_info[] = {
> .vsel_addr = PALMAS_LDOUSB_VOLTAGE,
> .ctrl_addr = PALMAS_LDOUSB_CTRL,
> },
> + {
> + .name = "REGEN1",
> + .ctrl_addr = PALMAS_REGEN1_CTRL,
> + },
> + {
> + .name = "REGEN2",
> + .ctrl_addr = PALMAS_REGEN2_CTRL,
> + },
> + {
> + .name = "REGEN3",
> + .ctrl_addr = PALMAS_REGEN3_CTRL,
> + },
> + {
> + .name = "SYSEN1",
> + .ctrl_addr = PALMAS_SYSEN1_CTRL,
> + },
> + {
> + .name = "SYSEN2",
> + .ctrl_addr = PALMAS_SYSEN2_CTRL,
> + },
> };
>
> #define SMPS_CTRL_MODE_OFF 0x00
> @@ -423,6 +443,12 @@ static struct regulator_ops palmas_ops_ldo = {
> .map_voltage = regulator_map_voltage_linear,
> };
>
> +static struct regulator_ops palmas_ops_extreg = {
> + .is_enabled = regulator_is_enabled_regmap,
> + .enable = regulator_enable_regmap,
> + .disable = regulator_disable_regmap,
> +};
> +
> /*
> * setup the hardware based sleep configuration of the SMPS/LDO regulators
> * from the platform data. This is different to the software based control
> @@ -524,6 +550,28 @@ static int palmas_ldo_init(struct palmas *palmas, int id,
> return 0;
> }
>
> +static int palmas_extreg_init(struct palmas *palmas, int id,
> + struct palmas_reg_init *reg_init)
> +{
> + unsigned int addr;
> + int ret;
> + unsigned int val = 0;
> +
> + addr = palmas_regs_info[id].ctrl_addr;
> +
> + if (reg_init->mode_sleep)
> + val = PALMAS_REGEN1_CTRL_MODE_SLEEP;
> +
> + ret = palmas_update_bits(palmas, PALMAS_RESOURCE_BASE,
> + addr, PALMAS_REGEN1_CTRL_MODE_SLEEP, val);
> + if (ret < 0) {
> + dev_err(palmas->dev, "Resource reg 0x%02x update failed %d\n",
> + addr, ret);
> + return ret;
> + }
> + return 0;
> +}
> +
> static struct of_regulator_match palmas_matches[] = {
> { .name = "smps12", },
> { .name = "smps123", },
> @@ -546,6 +594,11 @@ static struct of_regulator_match palmas_matches[] = {
> { .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,
> @@ -764,21 +817,34 @@ static int palmas_regulators_probe(struct platform_device *pdev)
> /* Register the regulators */
> pmic->desc[id].name = palmas_regs_info[id].name;
> pmic->desc[id].id = id;
> - pmic->desc[id].n_voltages = PALMAS_LDO_NUM_VOLTAGES;
> -
> - pmic->desc[id].ops = &palmas_ops_ldo;
> -
> pmic->desc[id].type = REGULATOR_VOLTAGE;
> pmic->desc[id].owner = THIS_MODULE;
> - pmic->desc[id].min_uV = 900000;
> - pmic->desc[id].uV_step = 50000;
> - pmic->desc[id].linear_min_sel = 1;
> - pmic->desc[id].vsel_reg = PALMAS_BASE_TO_REG(PALMAS_LDO_BASE,
> +
> + if (id < PALMAS_REG_REGEN1) {
> + pmic->desc[id].n_voltages = PALMAS_LDO_NUM_VOLTAGES;
> + 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].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,
> + 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;
> + } else {
> + pmic->desc[id].n_voltages = 1;
> + 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_LDO1_CTRL_MODE_ACTIVE;
> + pmic->desc[id].enable_mask =
> + PALMAS_REGEN1_CTRL_MODE_ACTIVE;
> + }
>
> if (pdata)
> config.init_data = pdata->reg_data[id];
> @@ -804,7 +870,12 @@ static int palmas_regulators_probe(struct platform_device *pdev)
> if (pdata) {
> reg_init = pdata->reg_init[id];
> if (reg_init) {
> - ret = palmas_ldo_init(palmas, id, 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) {
> regulator_unregister(pmic->rdev[id]);
> goto err_unregister_regulator;
> diff --git a/include/linux/mfd/palmas.h b/include/linux/mfd/palmas.h
> index 4a066d0..fb04d07 100644
> --- a/include/linux/mfd/palmas.h
> +++ b/include/linux/mfd/palmas.h
> @@ -164,6 +164,12 @@ enum palmas_regulators {
> PALMAS_REG_LDO9,
> PALMAS_REG_LDOLN,
> PALMAS_REG_LDOUSB,
> + /* External regulators */
> + PALMAS_REG_REGEN1,
> + PALMAS_REG_REGEN2,
> + PALMAS_REG_REGEN3,
> + PALMAS_REG_SYSEN1,
> + PALMAS_REG_SYSEN2,
> /* Total number of regulators */
> PALMAS_NUM_REGS,
> };
This is good with me, I originally had it like this and I cannot
remember why I convinced myself not to do it this way.
Acked-by: Graeme Gregory <[email protected]>
On 17/04/13 10:43, Laxman Dewangan wrote:
> Clear the sleep/warm reset bits when it is not selected through
> regulator platform data. This will make sure that configuration
> is inline with the platform data regardless of boot/POR
> configuration.
>
> Signed-off-by: Laxman Dewangan <[email protected]>
> ---
> drivers/regulator/palmas-regulator.c | 18 ++++++++++++------
> 1 files changed, 12 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c
> index 7c54e31..7c7992b 100644
> --- a/drivers/regulator/palmas-regulator.c
> +++ b/drivers/regulator/palmas-regulator.c
> @@ -444,24 +444,26 @@ static int palmas_smps_init(struct palmas *palmas, int id,
>
> switch (id) {
> case PALMAS_REG_SMPS10:
> - if (reg_init->mode_sleep) {
> - reg &= ~PALMAS_SMPS10_CTRL_MODE_SLEEP_MASK;
> + reg &= ~PALMAS_SMPS10_CTRL_MODE_SLEEP_MASK;
> + if (reg_init->mode_sleep)
> reg |= reg_init->mode_sleep <<
> PALMAS_SMPS10_CTRL_MODE_SLEEP_SHIFT;
> - }
> break;
> default:
> if (reg_init->warm_reset)
> reg |= PALMAS_SMPS12_CTRL_WR_S;
> + else
> + reg &= ~PALMAS_SMPS12_CTRL_WR_S;
>
> if (reg_init->roof_floor)
> reg |= PALMAS_SMPS12_CTRL_ROOF_FLOOR_EN;
> + else
> + reg &= ~PALMAS_SMPS12_CTRL_ROOF_FLOOR_EN;
>
> - if (reg_init->mode_sleep) {
> - reg &= ~PALMAS_SMPS12_CTRL_MODE_SLEEP_MASK;
> + reg &= ~PALMAS_SMPS12_CTRL_MODE_SLEEP_MASK;
> + if (reg_init->mode_sleep)
> reg |= reg_init->mode_sleep <<
> PALMAS_SMPS12_CTRL_MODE_SLEEP_SHIFT;
> - }
> }
>
> ret = palmas_smps_write(palmas, addr, reg);
> @@ -507,9 +509,13 @@ static int palmas_ldo_init(struct palmas *palmas, int id,
>
> if (reg_init->warm_reset)
> reg |= PALMAS_LDO1_CTRL_WR_S;
> + else
> + reg &= ~PALMAS_LDO1_CTRL_WR_S;
>
> if (reg_init->mode_sleep)
> reg |= PALMAS_LDO1_CTRL_MODE_SLEEP;
> + else
> + reg &= ~PALMAS_LDO1_CTRL_MODE_SLEEP;
>
> ret = palmas_ldo_write(palmas, addr, reg);
> if (ret)
Looks good to me, I don't actually know the use case for this feature!
Acked-by: Graeme Gregory <[email protected]>
On 17/04/13 10:43, Laxman Dewangan wrote:
> LDO8 of Palma device like tps65913 support the tracking mode
> on which LDO8 track the SMPS45 voltage when SMPS45 is ON
> and use the LDO8.VOLTAGE_SEL register when SMPS45 is OFF.
>
> On track mode, the steps of voltage change for LDO8 is 25mV
> where in non-tracking mode it is 50mV. Set the steps accordingly.
> Number of voltage count is still same for both the cases.
>
> Signed-off-by: Laxman Dewangan <[email protected]>
> ---
> drivers/regulator/palmas-regulator.c | 53 ++++++++++++++++++++++++++++++++++
> include/linux/mfd/palmas.h | 3 ++
> 2 files changed, 56 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c
> index 28080a7..d6efaf1 100644
> --- a/drivers/regulator/palmas-regulator.c
> +++ b/drivers/regulator/palmas-regulator.c
> @@ -572,6 +572,46 @@ static int palmas_extreg_init(struct palmas *palmas, int id,
> return 0;
> }
>
> +static void palmas_enable_ldo8_track(struct palmas *palmas)
> +{
> + unsigned int reg;
> + unsigned int addr;
> + int ret;
> +
> + addr = palmas_regs_info[PALMAS_REG_LDO8].ctrl_addr;
> +
> + ret = palmas_ldo_read(palmas, addr, ®);
> + if (ret) {
> + dev_err(palmas->dev, "Error in reading ldo8 control reg\n");
> + return;
> + }
> +
> + reg |= PALMAS_LDO8_CTRL_LDO_TRACKING_EN;
> + ret = palmas_ldo_write(palmas, addr, reg);
> + if (ret < 0) {
> + dev_err(palmas->dev, "Error in enabling tracking mode\n");
> + return;
> + }
> + /*
> + * When SMPS45 is set to off and LDO8 tracking is enabled, the LDO8
> + * 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;
> + ret = palmas_ldo_read(palmas, addr, ®);
> + if (ret) {
> + dev_err(palmas->dev, "Error in reading ldo8 voltage reg\n");
> + return;
> + }
> +
> + reg = (reg << 1) & PALMAS_LDO8_VOLTAGE_VSEL_MASK;
> + ret = palmas_ldo_write(palmas, addr, reg);
> + if (ret < 0)
> + dev_err(palmas->dev, "Error in setting ldo8 voltage reg\n");
> +
> + return;
> +}
> +
> static struct of_regulator_match palmas_matches[] = {
> { .name = "smps12", },
> { .name = "smps123", },
> @@ -657,6 +697,11 @@ static void palmas_dt_to_pdata(struct device *dev,
> if (ret)
> pdata->reg_init[idx]->vsel =
> PALMAS_SMPS12_VOLTAGE_RANGE;
> +
> + if (idx == PALMAS_REG_LDO8)
> + pdata->enable_ldo8_tracking = of_property_read_bool(
> + palmas_matches[idx].of_node,
> + "ti,enable-ldo8-tracking");
> }
>
> pdata->ldo6_vibrator = of_property_read_bool(node, "ti,ldo6-vibrator");
> @@ -836,6 +881,13 @@ static int palmas_regulators_probe(struct platform_device *pdev)
> palmas_regs_info[id].ctrl_addr);
> pmic->desc[id].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(palmas);
> + pmic->desc[id].uV_step = 25000;
> + }
> } else {
> pmic->desc[id].n_voltages = 1;
> pmic->desc[id].ops = &palmas_ops_extreg;
> @@ -884,6 +936,7 @@ static int palmas_regulators_probe(struct platform_device *pdev)
> }
> }
>
> +
> return 0;
>
> err_unregister_regulator:
> diff --git a/include/linux/mfd/palmas.h b/include/linux/mfd/palmas.h
> index fb04d07..12d8a62 100644
> --- a/include/linux/mfd/palmas.h
> +++ b/include/linux/mfd/palmas.h
> @@ -187,6 +187,9 @@ struct palmas_pmic_platform_data {
>
> /* use LDO6 for vibrator control */
> int ldo6_vibrator;
> +
> + /* Enable tracking mode of LDO8 */
> + bool enable_ldo8_tracking;
> };
>
> struct palmas_usb_platform_data {
On Wed, Apr 17, 2013 at 03:13:11PM +0530, Laxman Dewangan wrote:
> Clear the sleep/warm reset bits when it is not selected through
> regulator platform data. This will make sure that configuration
> is inline with the platform data regardless of boot/POR
> configuration.
Applied, thanks.
On Wed, Apr 17, 2013 at 02:51:34PM +0100, Graeme Gregory wrote:
> This looks good to me with one proviso!
> SYSEN1/2 are not necessarily for regulators as given by the name, they
> are more for use indicating to other chips that power is now
> available/stable.
> But it will not break things to have them exposed in regulator API so I
> shall leave this to Mark.
It's probably reasonable given that things like this normally end up
being part of the power sequencing or used for external regulators.
Applied, thanks.
On Wed, Apr 17, 2013 at 03:13:13PM +0530, Laxman Dewangan wrote:
> LDO8 of Palma device like tps65913 support the tracking mode
> on which LDO8 track the SMPS45 voltage when SMPS45 is ON
> and use the LDO8.VOLTAGE_SEL register when SMPS45 is OFF.
Applied, thanks.
On Wednesday 17 April 2013 07:24 PM, Graeme Gregory wrote:
> Looks good to me, I don't actually know the use case for this feature!
>
> Acked-by: Graeme Gregory <[email protected]>
>
This is require for Tegra.
The always ON section of Tegra (say vdd_ao) need to be same as the core
voltage(vdd_core) when system is active/idle. Hence the vdd_ao should be
track to vdd_core and for this we need to configure the rail in tracking
mode.