Merge "msm: saw-regulator: Support enable and disable"
diff --git a/arch/arm/mach-msm/board-8064-regulator.c b/arch/arm/mach-msm/board-8064-regulator.c
index 851f7d9..a66495d 100644
--- a/arch/arm/mach-msm/board-8064-regulator.c
+++ b/arch/arm/mach-msm/board-8064-regulator.c
@@ -455,7 +455,8 @@
{ \
.constraints = { \
.name = _name, \
- .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, \
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | \
+ REGULATOR_CHANGE_STATUS, \
.min_uV = _min_uV, \
.max_uV = _max_uV, \
}, \
diff --git a/arch/arm/mach-msm/board-8930-regulator-pm8038.c b/arch/arm/mach-msm/board-8930-regulator-pm8038.c
index 947697a..eaebea0 100644
--- a/arch/arm/mach-msm/board-8930-regulator-pm8038.c
+++ b/arch/arm/mach-msm/board-8930-regulator-pm8038.c
@@ -449,7 +449,8 @@
{ \
.constraints = { \
.name = _name, \
- .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, \
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | \
+ REGULATOR_CHANGE_STATUS, \
.min_uV = _min_uV, \
.max_uV = _max_uV, \
}, \
diff --git a/arch/arm/mach-msm/board-8930-regulator-pm8917.c b/arch/arm/mach-msm/board-8930-regulator-pm8917.c
index 3ee052b..9a2967a 100644
--- a/arch/arm/mach-msm/board-8930-regulator-pm8917.c
+++ b/arch/arm/mach-msm/board-8930-regulator-pm8917.c
@@ -487,7 +487,8 @@
{ \
.constraints = { \
.name = _name, \
- .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, \
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | \
+ REGULATOR_CHANGE_STATUS, \
.min_uV = _min_uV, \
.max_uV = _max_uV, \
}, \
diff --git a/arch/arm/mach-msm/board-8960-regulator.c b/arch/arm/mach-msm/board-8960-regulator.c
index f9e2c8e..397411d 100644
--- a/arch/arm/mach-msm/board-8960-regulator.c
+++ b/arch/arm/mach-msm/board-8960-regulator.c
@@ -382,7 +382,8 @@
{ \
.constraints = { \
.name = _name, \
- .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, \
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | \
+ REGULATOR_CHANGE_STATUS, \
.min_uV = _min_uV, \
.max_uV = _max_uV, \
}, \
diff --git a/arch/arm/mach-msm/saw-regulator.c b/arch/arm/mach-msm/saw-regulator.c
index 6762648..0a81a33 100644
--- a/arch/arm/mach-msm/saw-regulator.c
+++ b/arch/arm/mach-msm/saw-regulator.c
@@ -54,11 +54,17 @@
struct regulator_dev *rdev;
char *name;
int uV;
+ int last_set_uV;
+ unsigned vlevel;
+ bool online;
};
/* Minimum core operating voltage */
#define MIN_CORE_VOLTAGE 950000
+/* Specifies an uninitialized voltage */
+#define INVALID_VOLTAGE -1
+
/* Specifies the PMIC internal slew rate in uV/us. */
#define REGULATOR_SLEW_RATE 1250
@@ -69,12 +75,32 @@
return vreg->uV;
}
+static int _set_voltage(struct regulator_dev *rdev)
+{
+ struct saw_vreg *vreg = rdev_get_drvdata(rdev);
+ int rc;
+
+ rc = msm_spm_set_vdd(rdev_get_id(rdev), vreg->vlevel);
+ if (!rc) {
+ if (vreg->uV > vreg->last_set_uV) {
+ /* Wait for voltage to stabalize. */
+ udelay((vreg->uV - vreg->last_set_uV) /
+ REGULATOR_SLEW_RATE);
+ }
+ vreg->last_set_uV = vreg->uV;
+ } else {
+ pr_err("%s: msm_spm_set_vdd failed %d\n", vreg->name, rc);
+ vreg->uV = vreg->last_set_uV;
+ }
+
+ return rc;
+}
+
static int saw_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,
unsigned *selector)
{
struct saw_vreg *vreg = rdev_get_drvdata(rdev);
int uV = min_uV;
- int rc;
u8 vprog, band;
if (uV < FTSMPS_BAND1_UV_MIN && max_uV >= FTSMPS_BAND1_UV_MIN)
@@ -119,23 +145,51 @@
return -EINVAL;
}
- rc = msm_spm_set_vdd(rdev_get_id(rdev), band | vprog);
- if (!rc) {
- if (uV > vreg->uV) {
- /* Wait for voltage to stabalize. */
- udelay((uV - vreg->uV) / REGULATOR_SLEW_RATE);
- }
- vreg->uV = uV;
- } else {
- pr_err("%s: msm_spm_set_vdd failed %d\n", vreg->name, rc);
- }
+ vreg->vlevel = band | vprog;
+ vreg->uV = uV;
+
+ if (!vreg->online)
+ return 0;
+
+ return _set_voltage(rdev);
+}
+
+static int saw_enable(struct regulator_dev *rdev)
+{
+ struct saw_vreg *vreg = rdev_get_drvdata(rdev);
+ int rc = 0;
+
+ if (vreg->uV != vreg->last_set_uV)
+ rc = _set_voltage(rdev);
+
+ if (!rc)
+ vreg->online = true;
return rc;
}
+static int saw_disable(struct regulator_dev *rdev)
+{
+ struct saw_vreg *vreg = rdev_get_drvdata(rdev);
+
+ vreg->online = false;
+
+ return 0;
+}
+
+static int saw_is_enabled(struct regulator_dev *rdev)
+{
+ struct saw_vreg *vreg = rdev_get_drvdata(rdev);
+
+ return vreg->online;
+}
+
static struct regulator_ops saw_ops = {
.get_voltage = saw_get_voltage,
.set_voltage = saw_set_voltage,
+ .enable = saw_enable,
+ .disable = saw_disable,
+ .is_enabled = saw_is_enabled,
};
static int __devinit saw_probe(struct platform_device *pdev)
@@ -168,12 +222,13 @@
goto free_vreg;
}
- vreg->desc.name = vreg->name;
- vreg->desc.id = pdev->id;
- vreg->desc.ops = &saw_ops;
- vreg->desc.type = REGULATOR_VOLTAGE;
- vreg->desc.owner = THIS_MODULE;
- vreg->uV = MIN_CORE_VOLTAGE;
+ vreg->desc.name = vreg->name;
+ vreg->desc.id = pdev->id;
+ vreg->desc.ops = &saw_ops;
+ vreg->desc.type = REGULATOR_VOLTAGE;
+ vreg->desc.owner = THIS_MODULE;
+ vreg->uV = INVALID_VOLTAGE;
+ vreg->last_set_uV = MIN_CORE_VOLTAGE;
vreg->rdev = regulator_register(&vreg->desc, &pdev->dev,
init_data, vreg, NULL);
@@ -233,5 +288,4 @@
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("SAW regulator driver");
-MODULE_VERSION("1.0");
MODULE_ALIAS("platform:saw-regulator");