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>
This commit is contained in:
parent
a492035331
commit
3358aae869
2 changed files with 62 additions and 53 deletions
|
@ -33,11 +33,17 @@ Main node optional properties:
|
|||
always on during TTW mode.
|
||||
- qcom,skip-2nd-swire-cmd: A boolean property which indicates if
|
||||
the second SWIRE command needs to be skipped.
|
||||
- qcom,swire-2nd-cmd-delay: A integer value which specifes the
|
||||
- qcom,swire-2nd-cmd-delay: An integer value which specifes the
|
||||
delay in millisecs between the first and second
|
||||
SWIRE command. If not specified this value
|
||||
defaults to 20ms. This delay is applied only
|
||||
if 'qpnp,skip-2nd-swire-cmd' is defined.
|
||||
if 'qcom,skip-2nd-swire-cmd' is defined.
|
||||
- qcom,swire-ibb-ps-enable-delay: An integer value which specifes the delay
|
||||
in millisecs to enable IBB pulse-skipping
|
||||
after the skip-2nd-swire-cmd workaround is applied.
|
||||
If not specified this value default to 200ms.
|
||||
This property is applicable only if
|
||||
'qcom,skip-2nd-swire-cmd' is specified.
|
||||
- qcom,labibb-standalone: A boolean property which forces LAB and
|
||||
IBB to operate in standalone mode. If
|
||||
this is not specified, then LAB and IBB
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Add table
Reference in a new issue