diff options
author | Rabin Vincent <rabin.vincent@stericsson.com> | 2011-05-24 16:34:39 +0530 |
---|---|---|
committer | said m bagheri <ebgheri@steludxu2848.(none)> | 2011-06-17 13:42:00 +0200 |
commit | 0a848f2b71aab4cd8f6f53ce18791cccf600a501 (patch) | |
tree | 1d58863a61bb8a8ee81d339df1025c37471cb038 /drivers | |
parent | 3c15a66dade736881a53af26df5fd9a82f479dbc (diff) |
regulators: ab5500: add mode control
ST-Ericsson Linux next: -
ST-Ericsson ID: WP332185
ST-Ericsson FOSS-OUT ID: Trivial
Change-Id: I85075a61da5aaf6d71edd3a374ee7098d3cf5bce
Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/23774
Tested-by: Rabin VINCENT <rabin.vincent@stericsson.com>
Reviewed-by: QATEST
Reviewed-by: Srinidhi KASAGAR <srinidhi.kasagar@stericsson.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/regulator/ab5500.c | 85 |
1 files changed, 77 insertions, 8 deletions
diff --git a/drivers/regulator/ab5500.c b/drivers/regulator/ab5500.c index f01444ff42f..fc37c0371e1 100644 --- a/drivers/regulator/ab5500.c +++ b/drivers/regulator/ab5500.c @@ -59,9 +59,11 @@ struct ab5500_regulator { const int *voltages; int num_holes; bool pwrctrl; + bool enabled; int enable_time; u8 bank; u8 reg; + u8 mode; }; struct ab5500_regulators { @@ -82,11 +84,16 @@ static int ab5500_regulator_enable(struct regulator_dev *rdev) { struct ab5500_regulators *ab5500 = rdev_get_drvdata(rdev); struct ab5500_regulator *r = ab5500->regulator[rdev_get_id(rdev)]; - u8 regval = AB5500_LDO_MODE_FULLPOWER; + int ret; + + ret = abx500_mask_and_set(ab5500->dev, r->bank, r->reg, + AB5500_LDO_MODE_MASK, r->mode); + if (ret < 0) + return ret; + + r->enabled = true; - return abx500_mask_and_set_register_interruptible( - ab5500->dev, r->bank, r->reg, - AB5500_LDO_MODE_MASK, regval); + return 0; } static int ab5500_regulator_disable(struct regulator_dev *rdev) @@ -94,10 +101,50 @@ static int ab5500_regulator_disable(struct regulator_dev *rdev) struct ab5500_regulators *ab5500 = rdev_get_drvdata(rdev); struct ab5500_regulator *r = ab5500->regulator[rdev_get_id(rdev)]; u8 regval = r->pwrctrl ? AB5500_LDO_MODE_PWRCTRL : AB5500_LDO_MODE_OFF; + int ret; + + ret = abx500_mask_and_set(ab5500->dev, r->bank, r->reg, + AB5500_LDO_MODE_MASK, regval); + if (ret < 0) + return ret; + + r->enabled = false; + + return 0; +} + +static unsigned int ab5500_regulator_get_mode(struct regulator_dev *rdev) +{ + struct ab5500_regulators *ab5500 = rdev_get_drvdata(rdev); + struct ab5500_regulator *r = ab5500->regulator[rdev_get_id(rdev)]; + + if (r->mode == AB5500_LDO_MODE_LOWPOWER) + return REGULATOR_MODE_IDLE; - return abx500_mask_and_set_register_interruptible( - ab5500->dev, r->bank, r->reg, - AB5500_LDO_MODE_MASK, regval); + return REGULATOR_MODE_NORMAL; +} + +static int ab5500_regulator_set_mode(struct regulator_dev *rdev, + unsigned int mode) +{ + struct ab5500_regulators *ab5500 = rdev_get_drvdata(rdev); + struct ab5500_regulator *r = ab5500->regulator[rdev_get_id(rdev)]; + + switch (mode) { + case REGULATOR_MODE_NORMAL: + r->mode = AB5500_LDO_MODE_FULLPOWER; + break; + case REGULATOR_MODE_IDLE: + r->mode = AB5500_LDO_MODE_LOWPOWER; + break; + default: + return -EINVAL; + } + + if (r->enabled) + return ab5500_regulator_enable(rdev); + + return 0; } static int ab5500_regulator_is_enabled(struct regulator_dev *rdev) @@ -115,7 +162,17 @@ static int ab5500_regulator_is_enabled(struct regulator_dev *rdev) return err; } - return (regval & AB5500_LDO_MODE_MASK) == AB5500_LDO_MODE_FULLPOWER; + switch (regval & AB5500_LDO_MODE_MASK) { + case AB5500_LDO_MODE_PWRCTRL: + case AB5500_LDO_MODE_OFF: + r->enabled = false; + break; + default: + r->enabled = true; + break; + } + + return r->enabled; } static int @@ -241,6 +298,8 @@ static struct regulator_ops ab5500_regulator_variable_ops = { .get_voltage = ab5500_regulator_get_voltage, .set_voltage = ab5500_regulator_set_voltage, .list_voltage = ab5500_regulator_list_voltage, + .set_mode = ab5500_regulator_set_mode, + .get_mode = ab5500_regulator_get_mode, }; static struct regulator_ops ab5500_regulator_fixed_ops = { @@ -250,6 +309,8 @@ static struct regulator_ops ab5500_regulator_fixed_ops = { .enable_time = ab5500_regulator_enable_time, .get_voltage = ab5500_regulator_fixed_get_voltage, .list_voltage = ab5500_regulator_list_voltage, + .set_mode = ab5500_regulator_set_mode, + .get_mode = ab5500_regulator_get_mode, }; static const int ab5500_ldo_s_voltages[] = { @@ -314,6 +375,7 @@ static struct ab5500_regulator ab5500_regulators[] = { .voltages = ab5500_ldo_s_voltages, .enable_time = 400, .pwrctrl = true, + .mode = AB5500_LDO_MODE_FULLPOWER, }, [AB5500_LDO_D] = { .desc = { @@ -329,6 +391,7 @@ static struct ab5500_regulator ab5500_regulators[] = { .voltages = ab5500_ldo_d_voltages, .enable_time = 400, .pwrctrl = true, + .mode = AB5500_LDO_MODE_FULLPOWER, }, [AB5500_LDO_L] = { .desc = { @@ -344,6 +407,7 @@ static struct ab5500_regulator ab5500_regulators[] = { .voltages = ab5500_ldo_lg_voltages, .num_holes = 2, /* 2 register values unused */ .enable_time = 400, + .mode = AB5500_LDO_MODE_FULLPOWER, }, [AB5500_LDO_G] = { .desc = { @@ -359,6 +423,7 @@ static struct ab5500_regulator ab5500_regulators[] = { .voltages = ab5500_ldo_lg_voltages, .num_holes = 2, /* 2 register values unused */ .enable_time = 400, + .mode = AB5500_LDO_MODE_FULLPOWER, }, [AB5500_LDO_K] = { .desc = { @@ -373,6 +438,7 @@ static struct ab5500_regulator ab5500_regulators[] = { .reg = AB5500_LDO_K_ST, .voltages = ab5500_ldo_kh_voltages, .enable_time = 400, + .mode = AB5500_LDO_MODE_FULLPOWER, }, [AB5500_LDO_H] = { .desc = { @@ -387,6 +453,7 @@ static struct ab5500_regulator ab5500_regulators[] = { .reg = AB5500_LDO_H_ST, .voltages = ab5500_ldo_kh_voltages, .enable_time = 400, + .mode = AB5500_LDO_MODE_FULLPOWER, }, [AB5500_LDO_VDIGMIC] = { .desc = { @@ -401,6 +468,7 @@ static struct ab5500_regulator ab5500_regulators[] = { .reg = AB5500_LDO_VDIGMIC_ST, .voltages = ab5500_ldo_vdigmic_voltages, .enable_time = 450, + .mode = AB5500_LDO_MODE_FULLPOWER, }, [AB5500_LDO_SIM] = { .desc = { @@ -415,6 +483,7 @@ static struct ab5500_regulator ab5500_regulators[] = { .reg = AB5500_SIM_SUP, .voltages = ab5500_ldo_sim_voltages, .enable_time = 1000, + .mode = AB5500_LDO_MODE_FULLPOWER, }, }; |