diff options
author | Anirudh Ghayal <aghayal@codeaurora.org> | 2016-05-03 22:34:07 +0530 |
---|---|---|
committer | Kyle Yan <kyan@codeaurora.org> | 2016-06-17 15:19:54 -0700 |
commit | 3358aae86980e436b7ac7f507543297a7dd7e29c (patch) | |
tree | 3edcbe85c5ef13df5a46943509f7f672435e3afd /drivers/regulator | |
parent | a492035331383753a1fc29ebb6ec4c3615ab13f1 (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.c | 105 |
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) { |