diff options
-rw-r--r-- | drivers/regulator/palmas-regulator.c | 34 | ||||
-rw-r--r-- | include/linux/mfd/palmas.h | 1 |
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 &= ~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 &= ~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 &= 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, ®); + 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]; }; |