summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/regulator/palmas-regulator.c34
-rw-r--r--include/linux/mfd/palmas.h1
2 files changed, 28 insertions, 7 deletions
diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c
index 5c233bfef779..b543df1d2864 100644
--- a/drivers/regulator/palmas-regulator.c
+++ b/drivers/regulator/palmas-regulator.c
@@ -305,7 +305,10 @@ static int palmas_enable_smps(struct regulator_dev *dev)
palmas_smps_read(pmic->palmas, palmas_regs_info[id].ctrl_addr, &reg);
reg &= ~PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK;
- reg |= SMPS_CTRL_MODE_ON;
+ if (pmic->current_mode_reg[id])
+ reg |= pmic->current_mode_reg[id];
+ else
+ reg |= SMPS_CTRL_MODE_ON;
palmas_smps_write(pmic->palmas, palmas_regs_info[id].ctrl_addr, reg);
@@ -327,16 +330,19 @@ static int palmas_disable_smps(struct regulator_dev *dev)
return 0;
}
-
static int palmas_set_mode_smps(struct regulator_dev *dev, unsigned int mode)
{
struct palmas_pmic *pmic = rdev_get_drvdata(dev);
int id = rdev_get_id(dev);
unsigned int reg;
+ int avoid_update = 0;
palmas_smps_read(pmic->palmas, palmas_regs_info[id].ctrl_addr, &reg);
reg &= ~PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK;
+ if (reg == SMPS_CTRL_MODE_OFF)
+ avoid_update = 1;
+
switch (mode) {
case REGULATOR_MODE_NORMAL:
reg |= SMPS_CTRL_MODE_ON;
@@ -347,11 +353,16 @@ static int palmas_set_mode_smps(struct regulator_dev *dev, unsigned int mode)
case REGULATOR_MODE_FAST:
reg |= SMPS_CTRL_MODE_PWM;
break;
+ case REGULATOR_MODE_STANDBY:
+ reg |= SMPS_CTRL_MODE_OFF;
+ break;
default:
return -EINVAL;
}
- palmas_smps_write(pmic->palmas, palmas_regs_info[id].ctrl_addr, reg);
-
+ pmic->current_mode_reg[id] = reg & PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK;
+ if (!avoid_update)
+ palmas_smps_write(pmic->palmas,
+ palmas_regs_info[id].ctrl_addr, reg);
return 0;
}
@@ -361,9 +372,7 @@ static unsigned int palmas_get_mode_smps(struct regulator_dev *dev)
int id = rdev_get_id(dev);
unsigned int reg;
- palmas_smps_read(pmic->palmas, palmas_regs_info[id].ctrl_addr, &reg);
- reg &= PALMAS_SMPS12_CTRL_STATUS_MASK;
- reg >>= PALMAS_SMPS12_CTRL_STATUS_SHIFT;
+ reg = pmic->current_mode_reg[id] & PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK;
switch (reg) {
case SMPS_CTRL_MODE_ON:
@@ -372,6 +381,8 @@ static unsigned int palmas_get_mode_smps(struct regulator_dev *dev)
return REGULATOR_MODE_IDLE;
case SMPS_CTRL_MODE_PWM:
return REGULATOR_MODE_FAST;
+ case SMPS_CTRL_MODE_OFF:
+ return REGULATOR_MODE_STANDBY;
}
return 0;
@@ -1337,6 +1348,7 @@ static __devinit int palmas_probe(struct platform_device *pdev)
* read and store the RANGE bit for later use
* This must be done before regulator is probed otherwise
* we error in probe with unsuportable ranges.
+ * Read the smps mode for later use.
*/
if (id != PALMAS_REG_SMPS10) {
addr = palmas_regs_info[id].vsel_addr;
@@ -1346,6 +1358,14 @@ static __devinit int palmas_probe(struct platform_device *pdev)
goto err_unregister_regulator;
if (reg & PALMAS_SMPS12_VOLTAGE_RANGE)
pmic->range[id] = 1;
+
+ /* Read the smps mode for later use. */
+ addr = palmas_regs_info[id].ctrl_addr;
+ ret = palmas_smps_read(pmic->palmas, addr, &reg);
+ if (ret)
+ goto err_unregister_regulator;
+ pmic->current_mode_reg[id] = reg &
+ PALMAS_SMPS12_CTRL_MODE_ACTIVE_MASK;
}
rdev = regulator_register(&pmic->desc[id],
diff --git a/include/linux/mfd/palmas.h b/include/linux/mfd/palmas.h
index 4dfc50bde015..3c21eaaa7254 100644
--- a/include/linux/mfd/palmas.h
+++ b/include/linux/mfd/palmas.h
@@ -279,6 +279,7 @@ struct palmas_pmic {
int smps457;
unsigned int ramp_delay[PALMAS_NUM_REGS];
+ unsigned int current_mode_reg[PALMAS_NUM_REGS];
int range[PALMAS_REG_SMPS10];
};