summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@quicinc.com>2017-07-17 05:28:29 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2017-07-17 05:28:28 -0700
commit586a3ac45131d13551880dcf4da7ff7063111074 (patch)
tree84e6d14d952f58a4986acf99d5632062c38a5d80
parent9875d5f19c396ffe191d91cd1620d0cf74c75491 (diff)
parent160b3f91698a2e6a3936b93e26cc352d54f6cce8 (diff)
Merge "power: smb-lib: Improve the OTG enable workaround for PM660"
-rw-r--r--drivers/power/supply/qcom/smb-lib.c102
1 files changed, 72 insertions, 30 deletions
diff --git a/drivers/power/supply/qcom/smb-lib.c b/drivers/power/supply/qcom/smb-lib.c
index 64ed53185e88..64d71727f7e6 100644
--- a/drivers/power/supply/qcom/smb-lib.c
+++ b/drivers/power/supply/qcom/smb-lib.c
@@ -1332,68 +1332,110 @@ int smblib_vconn_regulator_is_enabled(struct regulator_dev *rdev)
#define MAX_RETRY 15
#define MIN_DELAY_US 2000
#define MAX_DELAY_US 9000
-static int _smblib_vbus_regulator_enable(struct regulator_dev *rdev)
+static int otg_current[] = {250000, 500000, 1000000, 1500000};
+static int smblib_enable_otg_wa(struct smb_charger *chg)
{
- struct smb_charger *chg = rdev_get_drvdata(rdev);
- int rc, retry_count = 0, min_delay = MIN_DELAY_US;
u8 stat;
+ int rc, i, retry_count = 0, min_delay = MIN_DELAY_US;
- smblib_dbg(chg, PR_OTG, "halt 1 in 8 mode\n");
- rc = smblib_masked_write(chg, OTG_ENG_OTG_CFG_REG,
- ENG_BUCKBOOST_HALT1_8_MODE_BIT,
- ENG_BUCKBOOST_HALT1_8_MODE_BIT);
- if (rc < 0) {
- smblib_err(chg, "Couldn't set OTG_ENG_OTG_CFG_REG rc=%d\n",
- rc);
- return rc;
- }
+ for (i = 0; i < ARRAY_SIZE(otg_current); i++) {
+ smblib_dbg(chg, PR_OTG, "enabling OTG with %duA\n",
+ otg_current[i]);
+ rc = smblib_set_charge_param(chg, &chg->param.otg_cl,
+ otg_current[i]);
+ if (rc < 0) {
+ smblib_err(chg, "Couldn't set otg limit rc=%d\n", rc);
+ return rc;
+ }
- smblib_dbg(chg, PR_OTG, "enabling OTG\n");
- rc = smblib_write(chg, CMD_OTG_REG, OTG_EN_BIT);
- if (rc < 0) {
- smblib_err(chg, "Couldn't enable OTG regulator rc=%d\n", rc);
- return rc;
- }
+ rc = smblib_write(chg, CMD_OTG_REG, OTG_EN_BIT);
+ if (rc < 0) {
+ smblib_err(chg, "Couldn't enable OTG rc=%d\n", rc);
+ return rc;
+ }
- if (chg->wa_flags & OTG_WA) {
- /* check for softstart */
+ retry_count = 0;
+ min_delay = MIN_DELAY_US;
do {
usleep_range(min_delay, min_delay + 100);
rc = smblib_read(chg, OTG_STATUS_REG, &stat);
if (rc < 0) {
- smblib_err(chg,
- "Couldn't read OTG status rc=%d\n",
- rc);
+ smblib_err(chg, "Couldn't read OTG status rc=%d\n",
+ rc);
goto out;
}
if (stat & BOOST_SOFTSTART_DONE_BIT) {
rc = smblib_set_charge_param(chg,
&chg->param.otg_cl, chg->otg_cl_ua);
- if (rc < 0)
- smblib_err(chg,
- "Couldn't set otg limit\n");
+ if (rc < 0) {
+ smblib_err(chg, "Couldn't set otg limit rc=%d\n",
+ rc);
+ goto out;
+ }
break;
}
-
/* increase the delay for following iterations */
if (retry_count > 5)
min_delay = MAX_DELAY_US;
+
} while (retry_count++ < MAX_RETRY);
if (retry_count >= MAX_RETRY) {
- smblib_dbg(chg, PR_OTG, "Boost Softstart not done\n");
- goto out;
+ smblib_dbg(chg, PR_OTG, "OTG enable failed with %duA\n",
+ otg_current[i]);
+ rc = smblib_write(chg, CMD_OTG_REG, 0);
+ if (rc < 0) {
+ smblib_err(chg, "disable OTG rc=%d\n", rc);
+ goto out;
+ }
+ } else {
+ smblib_dbg(chg, PR_OTG, "OTG enabled\n");
+ return 0;
}
}
+ if (i == ARRAY_SIZE(otg_current)) {
+ rc = -EINVAL;
+ goto out;
+ }
+
return 0;
out:
- /* disable OTG if softstart failed */
smblib_write(chg, CMD_OTG_REG, 0);
return rc;
}
+static int _smblib_vbus_regulator_enable(struct regulator_dev *rdev)
+{
+ struct smb_charger *chg = rdev_get_drvdata(rdev);
+ int rc;
+
+ smblib_dbg(chg, PR_OTG, "halt 1 in 8 mode\n");
+ rc = smblib_masked_write(chg, OTG_ENG_OTG_CFG_REG,
+ ENG_BUCKBOOST_HALT1_8_MODE_BIT,
+ ENG_BUCKBOOST_HALT1_8_MODE_BIT);
+ if (rc < 0) {
+ smblib_err(chg, "Couldn't set OTG_ENG_OTG_CFG_REG rc=%d\n",
+ rc);
+ return rc;
+ }
+
+ smblib_dbg(chg, PR_OTG, "enabling OTG\n");
+
+ if (chg->wa_flags & OTG_WA) {
+ rc = smblib_enable_otg_wa(chg);
+ if (rc < 0)
+ smblib_err(chg, "Couldn't enable OTG rc=%d\n", rc);
+ } else {
+ rc = smblib_write(chg, CMD_OTG_REG, OTG_EN_BIT);
+ if (rc < 0)
+ smblib_err(chg, "Couldn't enable OTG rc=%d\n", rc);
+ }
+
+ return rc;
+}
+
int smblib_vbus_regulator_enable(struct regulator_dev *rdev)
{
struct smb_charger *chg = rdev_get_drvdata(rdev);