p9221_charger: improvement of the HPP -> GPP transition
Bug: 237323599
Signed-off-by: yihsiangpeng <[email protected]>
Change-Id: Ib732cb707ea6b625be63d1387b16615e2075a1fe
diff --git a/p9221_charger.c b/p9221_charger.c
index acc62fa..4c91914 100644
--- a/p9221_charger.c
+++ b/p9221_charger.c
@@ -595,13 +595,71 @@
}
#define EPP_MODE_REQ_PWR 15
+#define EPP_MODE_REQ_VOUT 12000
+static int p9xxx_set_bypass_mode(struct p9221_charger_data *charger)
+{
+ const int req_pwr = EPP_MODE_REQ_PWR;
+ int i, count, ret;
+ u8 cdmode, currpwr;
+ u32 vout_mv;
+
+ /* Check it's in Cap Div mode */
+ ret = charger->reg_read_8(charger, P9412_CDMODE_STS_REG, &cdmode);
+ if (ret || (cdmode & CDMODE_BYPASS_MODE))
+ return ret;
+ dev_info(&charger->client->dev, "cdmode_reg=%02x\n", cdmode);
+
+ for (count = 0; count < 3; count++) {
+ /* Change the Requested Power to 15W */
+ ret = charger->reg_write_8(charger, P9412_PROP_REQ_PWR_REG, req_pwr * 2);
+ if (ret == 0)
+ ret = charger->chip_set_cmd(charger, PROP_REQ_PWR_CMD);
+ if (ret)
+ dev_err(&charger->client->dev,
+ "Fail to request Tx power(%d)\n", ret);
+
+ /* total 5 seconds wait and early exit when WLC offline */
+ for (i = 0; i < 50; i += 1) {
+ usleep_range(100 * USEC_PER_MSEC, 120 * USEC_PER_MSEC);
+ if (!charger->online)
+ return 0;
+ }
+
+ /* Check PropCurrPwr and P9412 Vout */
+ vout_mv = 0;
+ currpwr = 0;
+ ret = charger->chip_get_vout(charger, &vout_mv);
+ ret |= charger->reg_read_8(charger, P9412_PROP_CURR_PWR_REG, &currpwr);
+ dev_info(&charger->client->dev, "count=%d, currpwr=%02x, vout_mv=%u\n",
+ count, currpwr, vout_mv);
+ if (ret == 0 && currpwr == (req_pwr * 2) && vout_mv < EPP_MODE_REQ_VOUT)
+ break;
+ }
+
+ if (count == 3)
+ return -ETIMEDOUT;
+
+ /* Request Bypass mode */
+ ret = charger->chip_capdiv_en(charger, CDMODE_BYPASS_MODE);
+ if (ret) {
+ u8 mode_sts = 0, err_sts = 0;
+ int rc;
+
+ rc = charger->reg_read_8(charger, P9412_PROP_MODE_STATUS_REG, &mode_sts);
+ rc |= charger->reg_read_8(charger, P9412_PROP_MODE_ERR_STS_REG, &err_sts);
+ dev_err(&charger->client->dev,
+ "Fail to change to bypass mode(%d), rc=%d sts=%02x, err=%02x\n",
+ ret, rc, mode_sts, err_sts);
+ }
+
+ return ret;
+}
+
static int p9221_reset_wlc_dc(struct p9221_charger_data *charger)
{
const int dc_sw_gpio = charger->pdata->dc_switch_gpio;
const int extben_gpio = charger->pdata->ext_ben_gpio;
- const int req_pwr = EPP_MODE_REQ_PWR;
- int ret, i;
- u8 cdmode;
+ int ret;
if (!charger->wlc_dc_enabled)
return 0;
@@ -620,46 +678,23 @@
gvotable_cast_int_vote(charger->dc_icl_votable, P9221_HPP_VOTER, 0, false);
- /* Check it's in Cap Div mode */
- ret = charger->reg_read_8(charger, P9412_CDMODE_STS_REG, &cdmode);
- if (ret == 0)
- dev_info(&charger->client->dev,
- "p9221_reset_wlc_dc: cdmode_reg=%02x\n", cdmode);
- if (cdmode & CDMODE_BYPASS_MODE)
- return 0;
-
- /* Change the Requested Power to 15W */
- ret = charger->reg_write_8(charger, P9412_PROP_REQ_PWR_REG, req_pwr * 2);
- if (ret == 0) {
- ret = charger->chip_set_cmd(charger, PROP_REQ_PWR_CMD);
- if (ret)
- dev_err(&charger->client->dev,
- "p9221_reset_wlc_dc: Fail to request Tx power(%d)\n", ret);
- }
-
- /* total 3 seconds wait and early exit when WLC offline */
- for (i = 0; i < 30; i += 1) {
- usleep_range(100 * USEC_PER_MSEC, 120 * USEC_PER_MSEC);
- if (!charger->online)
- return 0;
- }
-
- /* Request Bypass mode */
- ret = charger->chip_capdiv_en(charger, CDMODE_BYPASS_MODE);
+ ret = p9xxx_set_bypass_mode(charger);
if (ret) {
- dev_err(&charger->client->dev,
- "p9221_reset_wlc_dc: Fail to change to bypass mode(%d)\n", ret);
+ /*
+ * going to go offline and reset the state when fail to change
+ * to bypass mode
+ */
+ gvotable_cast_bool_vote(charger->wlc_disable_votable,
+ P9221_HPP_VOTER, true);
+ usleep_range(200 * USEC_PER_MSEC, 220 * USEC_PER_MSEC);
+ gvotable_cast_bool_vote(charger->wlc_disable_votable,
+ P9221_HPP_VOTER, false);
} else {
- ret = charger->reg_read_8(charger, P9412_CDMODE_STS_REG, &cdmode);
- if (ret == 0) {
- dev_info(&charger->client->dev,
- "p9221_reset_wlc_dc: cdmode_reg=%02x\n", cdmode);
- charger->prop_mode_en = false;
- p9221_write_fod(charger);
- }
+ charger->prop_mode_en = false;
+ p9221_write_fod(charger);
}
- return 0;
+ return ret;
}
#define CHARGE_15W_VOUT_UV 12000000