diff options
| author | Linux Build Service Account <lnxbuild@quicinc.com> | 2017-07-17 05:28:29 -0700 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2017-07-17 05:28:28 -0700 |
| commit | 586a3ac45131d13551880dcf4da7ff7063111074 (patch) | |
| tree | 84e6d14d952f58a4986acf99d5632062c38a5d80 | |
| parent | 9875d5f19c396ffe191d91cd1620d0cf74c75491 (diff) | |
| parent | 160b3f91698a2e6a3936b93e26cc352d54f6cce8 (diff) | |
Merge "power: smb-lib: Improve the OTG enable workaround for PM660"
| -rw-r--r-- | drivers/power/supply/qcom/smb-lib.c | 102 |
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); |
