aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorRabin Vincent <rabin.vincent@stericsson.com>2011-05-24 16:34:39 +0530
committersaid m bagheri <ebgheri@steludxu2848.(none)>2011-06-17 13:42:00 +0200
commit0a848f2b71aab4cd8f6f53ce18791cccf600a501 (patch)
tree1d58863a61bb8a8ee81d339df1025c37471cb038 /drivers
parent3c15a66dade736881a53af26df5fd9a82f479dbc (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.c85
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,
},
};