aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorBengt Jonsson <bengt.g.jonsson@stericsson.com>2011-05-24 10:40:38 +0200
committersaid m bagheri <ebgheri@steludxu2848.(none)>2011-06-17 13:42:03 +0200
commit8c65027c5132919be6ad840b6cd45fd8c4f2aab9 (patch)
tree0ecd317d8eeea399bd095d9fc96faf91b20a807f /drivers
parent2c7644d01ff41ed5aed35a8a99d395fc8b56b316 (diff)
regulators: Added get_optimum_mode on regulators with idle mode
With this change, Vtvout, Vintcore12, Vaux1, 2 and 3 regulators support DRMS (Dynamic Regulator Mode Switching) which will dynamically handle requests for max current consumption from several consumers and select a suitable regulator mode. ST-Ericsson Linux next: N/A ST-Ericsson ID: CR339486 ST-Ericsson FOSS-OUT ID: Trivial Change-Id: Icdaed40df47859eb3e9701da296a814b38a48b56 Signed-off-by: Bengt Jonsson <bengt.g.jonsson@stericsson.com> Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/23859 Reviewed-by: Mattias WALLIN <mattias.wallin@stericsson.com> Reviewed-by: QATEST
Diffstat (limited to 'drivers')
-rw-r--r--drivers/regulator/ab8500.c121
1 files changed, 89 insertions, 32 deletions
diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c
index 8b94f67d677..db9a93d513c 100644
--- a/drivers/regulator/ab8500.c
+++ b/drivers/regulator/ab8500.c
@@ -32,6 +32,7 @@
* @max_uV: maximum voltage (for variable voltage supplies)
* @min_uV: minimum voltage (for variable voltage supplies)
* @fixed_uV: typical voltage (for fixed voltage supplies)
+ * @load_lp_uA: maximum load in idle (low power) mode
* @update_bank: bank to control on/off
* @update_reg: register to control on/off
* @update_mask: mask to enable/disable and set mode of regulator
@@ -54,6 +55,7 @@ struct ab8500_regulator_info {
int max_uV;
int min_uV;
int fixed_uV;
+ int load_lp_uA;
u8 update_bank;
u8 update_reg;
u8 update_mask;
@@ -164,6 +166,27 @@ static int ab8500_regulator_disable(struct regulator_dev *rdev)
return ret;
}
+static unsigned int ab8500_regulator_get_optimum_mode(
+ struct regulator_dev *rdev, int input_uV,
+ int output_uV, int load_uA)
+{
+ unsigned int mode;
+
+ struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
+
+ if (info == NULL) {
+ dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
+ return -EINVAL;
+ }
+
+ if (load_uA <= info->load_lp_uA)
+ mode = REGULATOR_MODE_IDLE;
+ else
+ mode = REGULATOR_MODE_NORMAL;
+
+ return mode;
+}
+
static int ab8500_regulator_set_mode(struct regulator_dev *rdev,
unsigned int mode)
{
@@ -194,6 +217,12 @@ static int ab8500_regulator_set_mode(struct regulator_dev *rdev,
if (ret < 0)
dev_err(rdev_get_dev(rdev),
"couldn't set regulator mode\n");
+
+ dev_vdbg(rdev_get_dev(rdev),
+ "%s-set_mode (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);
}
return ret;
@@ -390,17 +419,18 @@ static int ab8500_regulator_set_voltage_time_sel(struct regulator_dev *rdev,
return info->delay;
}
-static struct regulator_ops ab8500_regulator_ops = {
- .enable = ab8500_regulator_enable,
- .disable = ab8500_regulator_disable,
- .set_mode = ab8500_regulator_set_mode,
- .get_mode = ab8500_regulator_get_mode,
- .is_enabled = ab8500_regulator_is_enabled,
- .get_voltage = ab8500_regulator_get_voltage,
- .set_voltage = ab8500_regulator_set_voltage,
- .list_voltage = ab8500_list_voltage,
- .enable_time = ab8500_regulator_enable_time,
- .set_voltage_time_sel = ab8500_regulator_set_voltage_time_sel,
+static struct regulator_ops ab8500_regulator_volt_mode_ops = {
+ .enable = ab8500_regulator_enable,
+ .disable = ab8500_regulator_disable,
+ .is_enabled = ab8500_regulator_is_enabled,
+ .get_optimum_mode = ab8500_regulator_get_optimum_mode,
+ .set_mode = ab8500_regulator_set_mode,
+ .get_mode = ab8500_regulator_get_mode,
+ .get_voltage = ab8500_regulator_get_voltage,
+ .set_voltage = ab8500_regulator_set_voltage,
+ .list_voltage = ab8500_list_voltage,
+ .enable_time = ab8500_regulator_enable_time,
+ .set_voltage_time_sel = ab8500_regulator_set_voltage_time_sel,
};
static int ab8500_fixed_get_voltage(struct regulator_dev *rdev)
@@ -415,14 +445,27 @@ static int ab8500_fixed_get_voltage(struct regulator_dev *rdev)
return info->fixed_uV;
}
-static struct regulator_ops ab8500_regulator_fixed_ops = {
- .enable = ab8500_regulator_enable,
- .disable = ab8500_regulator_disable,
- .is_enabled = ab8500_regulator_is_enabled,
- .get_voltage = ab8500_fixed_get_voltage,
- .list_voltage = ab8500_list_voltage,
- .enable_time = ab8500_regulator_enable_time,
- .set_voltage_time_sel = ab8500_regulator_set_voltage_time_sel,
+static struct regulator_ops ab8500_regulator_mode_ops = {
+ .enable = ab8500_regulator_enable,
+ .disable = ab8500_regulator_disable,
+ .is_enabled = ab8500_regulator_is_enabled,
+ .get_optimum_mode = ab8500_regulator_get_optimum_mode,
+ .set_mode = ab8500_regulator_set_mode,
+ .get_mode = ab8500_regulator_get_mode,
+ .get_voltage = ab8500_fixed_get_voltage,
+ .list_voltage = ab8500_list_voltage,
+ .enable_time = ab8500_regulator_enable_time,
+ .set_voltage_time_sel = ab8500_regulator_set_voltage_time_sel,
+};
+
+static struct regulator_ops ab8500_regulator_ops = {
+ .enable = ab8500_regulator_enable,
+ .disable = ab8500_regulator_disable,
+ .is_enabled = ab8500_regulator_is_enabled,
+ .get_voltage = ab8500_fixed_get_voltage,
+ .list_voltage = ab8500_list_voltage,
+ .enable_time = ab8500_regulator_enable_time,
+ .set_voltage_time_sel = ab8500_regulator_set_voltage_time_sel,
};
static int ab8500_sysclkreq_enable(struct regulator_dev *rdev)
@@ -516,7 +559,7 @@ static struct regulator_ops ab8500_sysclkreq_ops = {
static struct ab8500_regulator_info
ab8500_regulator_info[AB8500_NUM_REGULATORS] = {
/*
- * Variable Voltage Regulators
+ * Variable Voltage Regulators and normal/idle modes
* name, min mV, max mV,
* update bank, reg, mask, enable val
* volt bank, reg, mask, table, table length
@@ -524,7 +567,7 @@ static struct ab8500_regulator_info
[AB8500_LDO_AUX1] = {
.desc = {
.name = "LDO-AUX1",
- .ops = &ab8500_regulator_ops,
+ .ops = &ab8500_regulator_volt_mode_ops,
.type = REGULATOR_VOLTAGE,
.id = AB8500_LDO_AUX1,
.owner = THIS_MODULE,
@@ -532,6 +575,7 @@ static struct ab8500_regulator_info
},
.min_uV = 1100000,
.max_uV = 3300000,
+ .load_lp_uA = 5000,
.update_bank = 0x04,
.update_reg = 0x09,
.update_mask = 0x03,
@@ -547,7 +591,7 @@ static struct ab8500_regulator_info
[AB8500_LDO_AUX2] = {
.desc = {
.name = "LDO-AUX2",
- .ops = &ab8500_regulator_ops,
+ .ops = &ab8500_regulator_volt_mode_ops,
.type = REGULATOR_VOLTAGE,
.id = AB8500_LDO_AUX2,
.owner = THIS_MODULE,
@@ -555,6 +599,7 @@ static struct ab8500_regulator_info
},
.min_uV = 1100000,
.max_uV = 3300000,
+ .load_lp_uA = 5000,
.update_bank = 0x04,
.update_reg = 0x09,
.update_mask = 0x0c,
@@ -570,7 +615,7 @@ static struct ab8500_regulator_info
[AB8500_LDO_AUX3] = {
.desc = {
.name = "LDO-AUX3",
- .ops = &ab8500_regulator_ops,
+ .ops = &ab8500_regulator_volt_mode_ops,
.type = REGULATOR_VOLTAGE,
.id = AB8500_LDO_AUX3,
.owner = THIS_MODULE,
@@ -578,6 +623,7 @@ static struct ab8500_regulator_info
},
.min_uV = 1100000,
.max_uV = 3300000,
+ .load_lp_uA = 5000,
.update_bank = 0x04,
.update_reg = 0x0a,
.update_mask = 0x03,
@@ -593,7 +639,7 @@ static struct ab8500_regulator_info
[AB8500_LDO_INTCORE] = {
.desc = {
.name = "LDO-INTCORE",
- .ops = &ab8500_regulator_ops,
+ .ops = &ab8500_regulator_volt_mode_ops,
.type = REGULATOR_VOLTAGE,
.id = AB8500_LDO_INTCORE,
.owner = THIS_MODULE,
@@ -601,6 +647,7 @@ static struct ab8500_regulator_info
},
.min_uV = 1100000,
.max_uV = 3300000,
+ .load_lp_uA = 5000,
.update_bank = 0x03,
.update_reg = 0x80,
.update_mask = 0x44,
@@ -615,14 +662,14 @@ static struct ab8500_regulator_info
},
/*
- * Fixed Voltage Regulators
+ * Fixed Voltage Regulators and normal/idle modes
* name, fixed mV,
* update bank, reg, mask, enable val
*/
[AB8500_LDO_TVOUT] = {
.desc = {
.name = "LDO-TVOUT",
- .ops = &ab8500_regulator_fixed_ops,
+ .ops = &ab8500_regulator_mode_ops,
.type = REGULATOR_VOLTAGE,
.id = AB8500_LDO_TVOUT,
.owner = THIS_MODULE,
@@ -630,15 +677,18 @@ static struct ab8500_regulator_info
},
.delay = 10000,
.fixed_uV = 2000000,
+ .load_lp_uA = 1000,
.update_bank = 0x03,
.update_reg = 0x80,
.update_mask = 0x82,
.update_val = 0x02,
+ .update_val_idle = 0x82,
+ .update_val_normal = 0x02,
},
[AB8500_LDO_USB] = {
.desc = {
.name = "LDO-USB",
- .ops = &ab8500_regulator_fixed_ops,
+ .ops = &ab8500_regulator_mode_ops,
.type = REGULATOR_VOLTAGE,
.id = AB8500_LDO_USB,
.owner = THIS_MODULE,
@@ -653,7 +703,7 @@ static struct ab8500_regulator_info
[AB8500_LDO_AUDIO] = {
.desc = {
.name = "LDO-AUDIO",
- .ops = &ab8500_regulator_fixed_ops,
+ .ops = &ab8500_regulator_ops,
.type = REGULATOR_VOLTAGE,
.id = AB8500_LDO_AUDIO,
.owner = THIS_MODULE,
@@ -668,7 +718,7 @@ static struct ab8500_regulator_info
[AB8500_LDO_ANAMIC1] = {
.desc = {
.name = "LDO-ANAMIC1",
- .ops = &ab8500_regulator_fixed_ops,
+ .ops = &ab8500_regulator_ops,
.type = REGULATOR_VOLTAGE,
.id = AB8500_LDO_ANAMIC1,
.owner = THIS_MODULE,
@@ -683,7 +733,7 @@ static struct ab8500_regulator_info
[AB8500_LDO_ANAMIC2] = {
.desc = {
.name = "LDO-ANAMIC2",
- .ops = &ab8500_regulator_fixed_ops,
+ .ops = &ab8500_regulator_ops,
.type = REGULATOR_VOLTAGE,
.id = AB8500_LDO_ANAMIC2,
.owner = THIS_MODULE,
@@ -698,7 +748,7 @@ static struct ab8500_regulator_info
[AB8500_LDO_DMIC] = {
.desc = {
.name = "LDO-DMIC",
- .ops = &ab8500_regulator_fixed_ops,
+ .ops = &ab8500_regulator_ops,
.type = REGULATOR_VOLTAGE,
.id = AB8500_LDO_DMIC,
.owner = THIS_MODULE,
@@ -710,20 +760,27 @@ static struct ab8500_regulator_info
.update_mask = 0x04,
.update_val = 0x04,
},
+
+ /*
+ * Regulators with fixed voltage and normal/idle modes
+ */
[AB8500_LDO_ANA] = {
.desc = {
.name = "LDO-ANA",
- .ops = &ab8500_regulator_fixed_ops,
+ .ops = &ab8500_regulator_mode_ops,
.type = REGULATOR_VOLTAGE,
.id = AB8500_LDO_ANA,
.owner = THIS_MODULE,
.n_voltages = 1,
},
.fixed_uV = 1200000,
+ .load_lp_uA = 1000,
.update_bank = 0x04,
.update_reg = 0x06,
.update_mask = 0x0c,
.update_val = 0x04,
+ .update_val_idle = 0x0c,
+ .update_val_normal = 0x04,
},
/*