diff options
| author | Philippe Langlais <philippe.langlais@linaro.org> | 2011-06-08 15:58:09 +0200 |
|---|---|---|
| committer | Ulf Hansson <ulf.hansson@stericsson.com> | 2011-09-19 15:15:25 +0200 |
| commit | 39b80a2f3adbfeb64e4daab9ea34b4a389f71f69 (patch) | |
| tree | 3099f2976fb1968b4daefcfa561ee214bc153446 /drivers/regulator | |
| parent | 629bc362c5070f21831a86d47a052af935da1e8f (diff) | |
regulators: Fix for regulator_set_mode functionality
ST-Ericsson Linux next: Not tested
ST-Ericsson ID: ER339084
ST-Ericsson FOSS-OUT ID: Trivial
Change-Id: I1bad24d8b0b777afc7f8dee61e4c603bde3120df
Signed-off-by: Bengt Jonsson <bengt.g.jonsson@stericsson.com>
Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/23146
Reviewed-by: QATEST
Reviewed-by: Mattias WALLIN <mattias.wallin@stericsson.com>
Reviewed-by: Emeric VIGIER <emeric.vigier@stericsson.com>
Reviewed-by: Jonas ABERG <jonas.aberg@stericsson.com>
Conflicts:
drivers/regulator/ab8500.c
Diffstat (limited to 'drivers/regulator')
| -rw-r--r-- | drivers/regulator/ab8500.c | 88 |
1 files changed, 50 insertions, 38 deletions
diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c index ec651c4d241..b1f38f6cb26 100644 --- a/drivers/regulator/ab8500.c +++ b/drivers/regulator/ab8500.c @@ -28,15 +28,16 @@ * @dev: device pointer * @desc: regulator description * @regulator_dev: regulator device + * @is_enabled: status of regulator (on/off) * @max_uV: maximum voltage (for variable voltage supplies) * @min_uV: minimum voltage (for variable voltage supplies) * @fixed_uV: typical voltage (for fixed voltage supplies) * @update_bank: bank to control on/off * @update_reg: register to control on/off - * @update_mask: mask to enable/disable regulator + * @update_mask: mask to enable/disable and set mode of regulator * @update_val: bits holding the regulator current mode * @update_val_idle: bits to enable the regulator in idle (low power) mode - * @update_val_enable: bits to enable the regulator in normal (high power) mode + * @update_val_normal: bits to enable the regulator in normal (high power) mode * @voltage_bank: bank to control regulator voltage * @voltage_reg: register to control regulator voltage * @voltage_mask: mask to control regulator voltage @@ -49,6 +50,7 @@ struct ab8500_regulator_info { struct device *dev; struct regulator_desc desc; struct regulator_dev *regulator; + bool is_enabled; int max_uV; int min_uV; int fixed_uV; @@ -57,7 +59,7 @@ struct ab8500_regulator_info { u8 update_mask; u8 update_val; u8 update_val_idle; - u8 update_val_enable; + u8 update_val_normal; u8 voltage_bank; u8 voltage_reg; u8 voltage_mask; @@ -120,15 +122,17 @@ static int ab8500_regulator_enable(struct regulator_dev *rdev) ret = abx500_mask_and_set_register_interruptible(info->dev, info->update_bank, info->update_reg, - info->update_mask, info->update_val_enable); + info->update_mask, info->update_val); if (ret < 0) dev_err(rdev_get_dev(rdev), "couldn't set enable bits for regulator\n"); + info->is_enabled = true; + dev_vdbg(rdev_get_dev(rdev), "%s-enable (bank, reg, mask, value): 0x%x, 0x%x, 0x%x, 0x%x\n", info->desc.name, info->update_bank, info->update_reg, - info->update_mask, info->update_val_enable); + info->update_mask, info->update_val); return ret; } @@ -150,6 +154,8 @@ static int ab8500_regulator_disable(struct regulator_dev *rdev) dev_err(rdev_get_dev(rdev), "couldn't set disable bits for regulator\n"); + info->is_enabled = false; + dev_vdbg(rdev_get_dev(rdev), "%s-disable (bank, reg, mask, value): 0x%x, 0x%x, 0x%x, 0x%x\n", info->desc.name, info->update_bank, info->update_reg, @@ -158,8 +164,11 @@ static int ab8500_regulator_disable(struct regulator_dev *rdev) return ret; } -static int ab8500_regulator_set_mode(struct regulator_dev *rdev, unsigned int mode) +static int ab8500_regulator_set_mode(struct regulator_dev *rdev, + unsigned int mode) { + int ret = 0; + struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); if (info == NULL) { @@ -167,13 +176,9 @@ static int ab8500_regulator_set_mode(struct regulator_dev *rdev, unsigned int mo return -EINVAL; } - /* - * update_val_enable is protected by mutex - * into regulator/core.c layout - */ switch (mode) { case REGULATOR_MODE_NORMAL: - info->update_val = info->update_val_enable; + info->update_val = info->update_val_normal; break; case REGULATOR_MODE_IDLE: info->update_val = info->update_val_idle; @@ -182,32 +187,31 @@ static int ab8500_regulator_set_mode(struct regulator_dev *rdev, unsigned int mo return -EINVAL; } - return ab8500_regulator_enable(rdev); + if (info->is_enabled) { + ret = abx500_mask_and_set_register_interruptible(info->dev, + info->update_bank, info->update_reg, + info->update_mask, info->update_val); + if (ret < 0) + dev_err(rdev_get_dev(rdev), + "couldn't set regulator mode\n"); + } + + return ret; } static unsigned int ab8500_regulator_get_mode(struct regulator_dev *rdev) { struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); int ret; - u8 regval; if (info == NULL) { dev_err(rdev_get_dev(rdev), "regulator info null pointer\n"); return -EINVAL; } - ret = abx500_get_register_interruptible(info->dev, - info->update_bank, info->update_reg, ®val); - if (ret < 0) { - dev_err(rdev_get_dev(rdev), - "couldn't read 0x%x register\n", info->update_reg); - return ret; - } - - regval &=info->update_mask; - if (regval == info->update_val_enable) + if (info->update_val == info->update_val_normal) ret = REGULATOR_MODE_NORMAL; - else if (regval == info->update_val_idle) + else if (info->update_val == info->update_val_idle) ret = REGULATOR_MODE_IDLE; else ret = -EINVAL; @@ -241,9 +245,11 @@ static int ab8500_regulator_is_enabled(struct regulator_dev *rdev) info->update_mask, regval); if (regval & info->update_mask) - return true; + info->is_enabled = true; else - return false; + info->is_enabled = false; + + return info->is_enabled; } static int ab8500_list_voltage(struct regulator_dev *rdev, unsigned selector) @@ -436,6 +442,8 @@ static int ab8500_sysclkreq_enable(struct regulator_dev *rdev) return ret; } + info->is_enabled = true; + dev_vdbg(rdev_get_dev(rdev), "%s-enable (gpio_pin, gpio_select): %i, false\n", info->desc.name, info->gpio_pin); @@ -460,6 +468,8 @@ static int ab8500_sysclkreq_disable(struct regulator_dev *rdev) return ret; } + info->is_enabled = false; + dev_vdbg(rdev_get_dev(rdev), "%s-disable (gpio_pin, gpio_select): %i, true\n", info->desc.name, info->gpio_pin); @@ -486,11 +496,13 @@ static int ab8500_sysclkreq_is_enabled(struct regulator_dev *rdev) return ret; } + info->is_enabled = !gpio_select; + dev_vdbg(rdev_get_dev(rdev), "%s-is_enabled (gpio_pin, is_enabled): %i, %i\n", info->desc.name, info->gpio_pin, !gpio_select); - return !gpio_select; + return info->is_enabled; } static struct regulator_ops ab8500_sysclkreq_ops = { @@ -525,7 +537,7 @@ static struct ab8500_regulator_info .update_mask = 0x03, .update_val = 0x01, .update_val_idle = 0x03, - .update_val_enable = 0x01, + .update_val_normal = 0x01, .voltage_bank = 0x04, .voltage_reg = 0x1f, .voltage_mask = 0x0f, @@ -548,7 +560,7 @@ static struct ab8500_regulator_info .update_mask = 0x0c, .update_val = 0x04, .update_val_idle = 0x0c, - .update_val_enable = 0x04, + .update_val_normal = 0x04, .voltage_bank = 0x04, .voltage_reg = 0x20, .voltage_mask = 0x0f, @@ -571,7 +583,7 @@ static struct ab8500_regulator_info .update_mask = 0x03, .update_val = 0x01, .update_val_idle = 0x03, - .update_val_enable = 0x01, + .update_val_normal = 0x01, .voltage_bank = 0x04, .voltage_reg = 0x21, .voltage_mask = 0x07, @@ -594,7 +606,7 @@ static struct ab8500_regulator_info .update_mask = 0x44, .update_val = 0x04, .update_val_idle = 0x44, - .update_val_enable = 0x04, + .update_val_normal = 0x04, .voltage_bank = 0x03, .voltage_reg = 0x80, .voltage_mask = 0x38, @@ -621,7 +633,7 @@ static struct ab8500_regulator_info .update_bank = 0x03, .update_reg = 0x80, .update_mask = 0x82, - .update_val_enable = 0x02, + .update_val = 0x02, }, [AB8500_LDO_USB] = { .desc = { @@ -636,7 +648,7 @@ static struct ab8500_regulator_info .update_bank = 0x03, .update_reg = 0x82, .update_mask = 0x03, - .update_val_enable = 0x01, + .update_val = 0x01, }, [AB8500_LDO_AUDIO] = { .desc = { @@ -651,7 +663,7 @@ static struct ab8500_regulator_info .update_bank = 0x03, .update_reg = 0x83, .update_mask = 0x02, - .update_val_enable = 0x02, + .update_val = 0x02, }, [AB8500_LDO_ANAMIC1] = { .desc = { @@ -666,7 +678,7 @@ static struct ab8500_regulator_info .update_bank = 0x03, .update_reg = 0x83, .update_mask = 0x08, - .update_val_enable = 0x08, + .update_val = 0x08, }, [AB8500_LDO_ANAMIC2] = { .desc = { @@ -681,7 +693,7 @@ static struct ab8500_regulator_info .update_bank = 0x03, .update_reg = 0x83, .update_mask = 0x10, - .update_val_enable = 0x10, + .update_val = 0x10, }, [AB8500_LDO_DMIC] = { .desc = { @@ -696,7 +708,7 @@ static struct ab8500_regulator_info .update_bank = 0x03, .update_reg = 0x83, .update_mask = 0x04, - .update_val_enable = 0x04, + .update_val = 0x04, }, [AB8500_LDO_ANA] = { .desc = { @@ -711,7 +723,7 @@ static struct ab8500_regulator_info .update_bank = 0x04, .update_reg = 0x06, .update_mask = 0x0c, - .update_val_enable = 0x04, + .update_val = 0x04, }, /* |
