diff options
author | Jin Park <jinyoungp@nvidia.com> | 2011-12-12 15:20:30 -0800 |
---|---|---|
committer | Varun Wadekar <vwadekar@nvidia.com> | 2011-12-15 13:57:26 +0530 |
commit | 41e98204edf77b4240702237da8bf02b93d74685 (patch) | |
tree | c516e4fa9846817694b35feb049269327eb84575 /drivers/regulator | |
parent | 309cb2b8a32b6178cb6fe8ad73bccb770b916a64 (diff) |
regulator: max77663: Fix power rail turn-off when change FPS source
To prevent power rail turn-off when change FPS source,
it must set power mode to NORMAL before change FPS source to NONE
from SRC_0, SRC_1 and SRC_2.
Change-Id: I02be96bd91ffb756a79a440d319fafe1739ae514
Signed-off-by: Jin Park <jinyoungp@nvidia.com>
Reviewed-on: http://git-master/r/69566
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Varun Colbert <vcolbert@nvidia.com>
Tested-by: Varun Colbert <vcolbert@nvidia.com>
Diffstat (limited to 'drivers/regulator')
-rw-r--r-- | drivers/regulator/max77663-regulator.c | 142 |
1 files changed, 74 insertions, 68 deletions
diff --git a/drivers/regulator/max77663-regulator.c b/drivers/regulator/max77663-regulator.c index bd64a405552d..68b13dec1a66 100644 --- a/drivers/regulator/max77663-regulator.c +++ b/drivers/regulator/max77663-regulator.c @@ -224,7 +224,8 @@ max77663_regulator_set_fps_src(struct max77663_regulator *reg, { int ret; - if (reg->regs[FPS_REG].addr == MAX77663_REG_FPS_NONE) + if ((reg->regs[FPS_REG].addr == MAX77663_REG_FPS_NONE) || + (reg->fps_src == fps_src)) return 0; switch (fps_src) { @@ -308,11 +309,19 @@ max77663_regulator_set_fps_cfgs(struct max77663_regulator *reg, struct max77663_regulator_fps_cfg *fps_cfgs, int num_fps_cfgs) { + struct device *parent = _to_parent(reg); int i, ret; if (fps_cfg_init) return 0; + for (i = 0; i <= FPS_SRC_2; i++) { + ret = max77663_read(parent, fps_cfg_regs[i].addr, + &fps_cfg_regs[i].val, 1, 0); + if (ret < 0) + return ret; + } + for (i = 0; i < num_fps_cfgs; i++) { ret = max77663_regulator_set_fps_cfg(reg, &fps_cfgs[i]); if (ret < 0) @@ -481,7 +490,7 @@ static int max77663_regulator_disable(struct regulator_dev *rdev) return 0; } - return max77663_regulator_set_power_mode(reg, power_mode);; + return max77663_regulator_set_power_mode(reg, power_mode); } static int max77663_regulator_is_enabled(struct regulator_dev *rdev) @@ -553,7 +562,7 @@ static int max77663_regulator_preinit(struct max77663_regulator *reg) struct max77663_regulator_platform_data *pdata = _to_pdata(reg); struct device *parent = _to_parent(reg); int i; - u8 val; + u8 val, mask; int ret; /* Update registers */ @@ -568,17 +577,6 @@ static int max77663_regulator_preinit(struct max77663_regulator *reg) } } - for (i = 0; i <= FPS_SRC_2; i++) { - ret = max77663_read(parent, fps_cfg_regs[i].addr, - &fps_cfg_regs[i].val, 1, 0); - if (ret < 0) { - dev_err(reg->dev, - "preinit: Failed to get register 0x%x\n", - fps_cfg_regs[i].addr); - return ret; - } - } - /* Update FPS source */ if (reg->regs[FPS_REG].addr == MAX77663_REG_FPS_NONE) reg->fps_src = FPS_SRC_NONE; @@ -586,6 +584,12 @@ static int max77663_regulator_preinit(struct max77663_regulator *reg) reg->fps_src = (reg->regs[FPS_REG].val & FPS_SRC_MASK) >> FPS_SRC_SHIFT; + dev_dbg(reg->dev, "preinit: initial fps_src=%s\n", + fps_src_name(reg->fps_src)); + + /* Update power mode */ + max77663_regulator_get_power_mode(reg); + /* Check Chip Identification */ ret = max77663_read(parent, MAX77663_REG_CID5, &val, 1, 0); if (ret < 0) { @@ -602,6 +606,40 @@ static int max77663_regulator_preinit(struct max77663_regulator *reg) else reg->safe_down_uV = 0; + /* Set FPS */ + ret = max77663_regulator_set_fps_cfgs(reg, pdata->fps_cfgs, + pdata->num_fps_cfgs); + if (ret < 0) { + dev_err(reg->dev, "preinit: Failed to set FPSCFG\n"); + return ret; + } + + /* To prevent power rail turn-off when change FPS source, + * it must set power mode to NORMAL before change FPS source to NONE + * from SRC_0, SRC_1 and SRC_2. */ + if ((reg->fps_src != FPS_SRC_NONE) && (pdata->fps_src == FPS_SRC_NONE) + && (reg->power_mode != POWER_MODE_NORMAL)) { + ret = max77663_regulator_set_power_mode(reg, POWER_MODE_NORMAL); + if (ret < 0) { + dev_err(reg->dev, "preinit: Failed to " + "set power mode to POWER_MODE_NORMAL\n"); + return ret; + } + } + + ret = max77663_regulator_set_fps_src(reg, pdata->fps_src); + if (ret < 0) { + dev_err(reg->dev, "preinit: Failed to set FPSSRC to %d\n", + pdata->fps_src); + return ret; + } + + ret = max77663_regulator_set_fps(reg); + if (ret < 0) { + dev_err(reg->dev, "preinit: Failed to set FPS\n"); + return ret; + } + /* Set initial state */ if (!pdata->init_apply) goto skip_init_apply; @@ -628,50 +666,41 @@ static int max77663_regulator_preinit(struct max77663_regulator *reg) return ret; } - skip_init_apply: if (reg->type == REGULATOR_TYPE_SD) { + val = 0; + mask = 0; + if (pdata->flags & SD_SLEW_RATE_MASK) { + mask |= SD_SR_MASK; if (pdata->flags & SD_SLEW_RATE_SLOWEST) - val = SD_SR_13_75 << SD_SR_SHIFT; + val |= (SD_SR_13_75 << SD_SR_SHIFT); else if (pdata->flags & SD_SLEW_RATE_SLOW) - val = SD_SR_27_5 << SD_SR_SHIFT; + val |= (SD_SR_27_5 << SD_SR_SHIFT); else if (pdata->flags & SD_SLEW_RATE_FAST) - val = SD_SR_55 << SD_SR_SHIFT; + val |= (SD_SR_55 << SD_SR_SHIFT); else - val = SD_SR_100 << SD_SR_SHIFT; - - ret = max77663_regulator_cache_write(reg, - reg->regs[CFG_REG].addr, SD_SR_MASK, - val, ®->regs[CFG_REG].val); - if (ret < 0) { - dev_err(reg->dev, - "preinit: Failed to set slew rate\n"); - return ret; - } + val |= (SD_SR_100 << SD_SR_SHIFT); } if (pdata->flags & SD_FORCED_PWM_MODE) { - ret = max77663_regulator_cache_write(reg, - reg->regs[CFG_REG].addr, SD_FPWM_MASK, - SD_FPWM_MASK, ®->regs[CFG_REG].val); - if (ret < 0) { - dev_err(reg->dev, "preinit: " - "Failed to set forced pwm mode\n"); - return ret; - } + mask |= SD_FPWM_MASK; + val |= SD_FPWM_MASK; } if (pdata->flags & SD_FSRADE_DISABLE) { - ret = max77663_regulator_cache_write(reg, - reg->regs[CFG_REG].addr, - SD_FSRADE_MASK, SD_FSRADE_MASK, - ®->regs[CFG_REG].val); - if (ret < 0) { - dev_err(reg->dev, "preinit: Failed to set " - "falling slew-rate discharge mode\n"); - return ret; - } + mask |= SD_FSRADE_MASK; + val |= SD_FSRADE_MASK; + } + + ret = max77663_regulator_cache_write(reg, + reg->regs[CFG_REG].addr, mask, val, + ®->regs[CFG_REG].val); + if (ret < 0) { + dev_err(reg->dev, "preinit: " + "Failed to set register 0x%x\n", + reg->regs[CFG_REG].addr); + return ret; } if ((reg->id == MAX77663_REGULATOR_ID_SD0) @@ -685,9 +714,6 @@ skip_init_apply: return ret; } - if (reg->fps_src == FPS_SRC_NONE) - return 0; - ret = max77663_regulator_set_fps_src(reg, FPS_SRC_NONE); if (ret < 0) { dev_err(reg->dev, "preinit: " @@ -698,26 +724,6 @@ skip_init_apply: } } - ret = max77663_regulator_set_fps_cfgs(reg, pdata->fps_cfgs, - pdata->num_fps_cfgs); - if (ret < 0) { - dev_err(reg->dev, "preinit: Failed to set FPSCFG\n"); - return ret; - } - - ret = max77663_regulator_set_fps_src(reg, pdata->fps_src); - if (ret < 0) { - dev_err(reg->dev, "preinit: Failed to set FPSSRC to %d\n", - pdata->fps_src); - return ret; - } - - ret = max77663_regulator_set_fps(reg); - if (ret < 0) { - dev_err(reg->dev, "preinit: Failed to set FPS\n"); - return ret; - } - return 0; } |