summaryrefslogtreecommitdiff
path: root/drivers/regulator
diff options
context:
space:
mode:
authorAnirudh Ghayal <aghayal@codeaurora.org>2016-05-03 22:34:07 +0530
committerKyle Yan <kyan@codeaurora.org>2016-06-17 15:19:54 -0700
commit3358aae86980e436b7ac7f507543297a7dd7e29c (patch)
tree3edcbe85c5ef13df5a46943509f7f672435e3afd /drivers/regulator
parenta492035331383753a1fc29ebb6ec4c3615ab13f1 (diff)
regulator: qpnp-labibb: Add support for controlling IBB pulse skip timing
The IBB pulse-skip and NLIMIT DAC configuration should be disabled before applying the 2nd SWIRE command skip logic, to guarantee that the IBB voltage changes immediately in the subsequent SWIRE command. After the WA is completed, the pulse-skip can be re-enabled after a programmable delay. Add this logic and a DT property 'qcom,swire-ibb-ps-enable-delay' to configure this delay. If this delay is not specified in the DT it defaults to 200ms. CRs-Fixed: 1010085 Change-Id: Ifec458a0028c16440ffd6ac1f6fa58eebc815c5a Signed-off-by: Anirudh Ghayal <aghayal@codeaurora.org>
Diffstat (limited to 'drivers/regulator')
-rw-r--r--drivers/regulator/qpnp-labibb-regulator.c105
1 files changed, 54 insertions, 51 deletions
diff --git a/drivers/regulator/qpnp-labibb-regulator.c b/drivers/regulator/qpnp-labibb-regulator.c
index 55ba6cfc25c2..2e41401f8580 100644
--- a/drivers/regulator/qpnp-labibb-regulator.c
+++ b/drivers/regulator/qpnp-labibb-regulator.c
@@ -250,7 +250,8 @@
#define IBB_WAIT_MBG_OK BIT(2)
/* Constants */
-#define SWIRE_DEFAULT_2ND_CMD_DLY_MS 20
+#define SWIRE_DEFAULT_2ND_CMD_DLY_MS 20
+#define SWIRE_DEFAULT_IBB_PS_ENABLE_DLY_MS 200
enum pmic_subtype {
PMI8994 = 10,
@@ -487,6 +488,7 @@ struct qpnp_labibb {
bool ttw_force_lab_on;
bool skip_2nd_swire_cmd;
u32 swire_2nd_cmd_delay;
+ u32 swire_ibb_ps_enable_delay;
};
enum ibb_settings_index {
@@ -677,6 +679,29 @@ static int qpnp_ibb_set_mode(struct qpnp_labibb *labibb, enum ibb_mode mode)
return rc;
}
+static int qpnp_ibb_ps_config(struct qpnp_labibb *labibb, bool enable)
+{
+ u8 val;
+ int rc;
+
+ val = enable ? IBB_PS_CTL_EN : IBB_PS_CTL_DISABLE;
+ rc = qpnp_labibb_write(labibb, labibb->ibb_base + REG_IBB_PS_CTL,
+ &val, 1);
+ if (rc) {
+ pr_err("qpnp_ibb_ps_config write register %x failed rc = %d\n",
+ REG_IBB_PS_CTL, rc);
+ return rc;
+ }
+
+ val = enable ? IBB_NLIMIT_DAC_EN : IBB_NLIMIT_DAC_DISABLE;
+ rc = qpnp_labibb_write(labibb, labibb->ibb_base + REG_IBB_NLIMIT_DAC,
+ &val, 1);
+ if (rc)
+ pr_err("qpnp_ibb_ps_config write register %x failed rc = %d\n",
+ REG_IBB_NLIMIT_DAC, rc);
+ return rc;
+}
+
static int qpnp_lab_dt_init(struct qpnp_labibb *labibb,
struct device_node *of_node)
{
@@ -1057,21 +1082,9 @@ static int qpnp_labibb_ttw_enter_ibb_pmi8950(struct qpnp_labibb *labibb)
int rc;
u8 val;
- val = 0;
- rc = qpnp_labibb_write(labibb, labibb->ibb_base + REG_IBB_NLIMIT_DAC,
- &val, 1);
+ rc = qpnp_ibb_ps_config(labibb, true);
if (rc) {
- pr_err("qpnp_labibb_write register %x failed rc = %d\n",
- REG_IBB_NLIMIT_DAC, rc);
- return rc;
- }
-
- val = IBB_PS_CTL_EN;
- rc = qpnp_labibb_write(labibb, labibb->ibb_base + REG_IBB_PS_CTL,
- &val, 1);
- if (rc) {
- pr_err("qpnp_labibb_write register %x failed rc = %d\n",
- REG_IBB_PS_CTL, rc);
+ pr_err("Failed to enable ibb_ps_config rc=%d\n", rc);
return rc;
}
@@ -1437,6 +1450,14 @@ static int qpnp_lab_regulator_enable(struct regulator_dev *rdev)
struct qpnp_labibb *labibb = rdev_get_drvdata(rdev);
+ if (labibb->skip_2nd_swire_cmd) {
+ rc = qpnp_ibb_ps_config(labibb, false);
+ if (rc) {
+ pr_err("Failed to disable IBB PS rc=%d\n", rc);
+ return rc;
+ }
+ }
+
if (!labibb->lab_vreg.vreg_enabled && !labibb->swire_control) {
if (!labibb->standalone)
@@ -1611,6 +1632,12 @@ static int qpnp_skip_swire_command(struct qpnp_labibb *labibb)
if (rc)
pr_err("Failed switch to IBB_HW_CONTROL rc=%d\n", rc);
+ /* delay before enabling the PS mode */
+ msleep(labibb->swire_ibb_ps_enable_delay);
+ rc = qpnp_ibb_ps_config(labibb, true);
+ if (rc)
+ pr_err("Unable to enable IBB PS rc=%d\n", rc);
+
return rc;
}
@@ -2120,47 +2147,16 @@ static int qpnp_ibb_dt_init(struct qpnp_labibb *labibb,
}
if (of_property_read_bool(of_node, "qcom,qpnp-ibb-ps-enable")) {
- val = IBB_PS_CTL_EN;
- rc = qpnp_labibb_write(labibb, labibb->ibb_base +
- REG_IBB_PS_CTL,
- &val,
- 1);
+ rc = qpnp_ibb_ps_config(labibb, true);
if (rc) {
- pr_err("qpnp_ibb_dt_init write register %x failed rc = %d\n",
- REG_IBB_PS_CTL, rc);
- return rc;
- }
-
- val = IBB_NLIMIT_DAC_EN;
- rc = qpnp_labibb_write(labibb, labibb->ibb_base +
- REG_IBB_NLIMIT_DAC,
- &val,
- 1);
- if (rc) {
- pr_err("qpnp_ibb_dt_init write register %x failed rc = %d\n",
- REG_IBB_NLIMIT_DAC, rc);
+ pr_err("qpnp_ibb_dt_init PS enable failed rc=%d\n", rc);
return rc;
}
} else {
- val = IBB_PS_CTL_DISABLE;
- rc = qpnp_labibb_write(labibb, labibb->ibb_base +
- REG_IBB_PS_CTL,
- &val,
- 1);
+ rc = qpnp_ibb_ps_config(labibb, false);
if (rc) {
- pr_err("qpnp_ibb_dt_init write register %x failed rc = %d\n",
- REG_IBB_PS_CTL, rc);
- return rc;
- }
-
- val = IBB_NLIMIT_DAC_DISABLE;
- rc = qpnp_labibb_write(labibb, labibb->ibb_base +
- REG_IBB_NLIMIT_DAC,
- &val,
- 1);
- if (rc) {
- pr_err("qpnp_ibb_dt_init write register %x failed rc = %d\n",
- REG_IBB_NLIMIT_DAC, rc);
+ pr_err("qpnp_ibb_dt_init PS disable failed rc=%d\n",
+ rc);
return rc;
}
}
@@ -2802,6 +2798,13 @@ static int qpnp_labibb_regulator_probe(struct platform_device *pdev)
if (rc)
labibb->swire_2nd_cmd_delay =
SWIRE_DEFAULT_2ND_CMD_DLY_MS;
+
+ rc = of_property_read_u32(labibb->dev->of_node,
+ "qcom,swire-ibb-ps-enable-delay",
+ &labibb->swire_ibb_ps_enable_delay);
+ if (rc)
+ labibb->swire_ibb_ps_enable_delay =
+ SWIRE_DEFAULT_IBB_PS_ENABLE_DLY_MS;
}
if (of_get_available_child_count(pdev->dev.of_node) == 0) {