p9221_charger: Disable WLC_RX_SW_EN when leaving HPP

1. Disable WLC_RX_SW_EN when leaving HPP
2. Add log for WLC-DC related GPIOs enabled/disabled
3. Re-enabled WLC chip when MW wcin is 0

Bug: 238977623
Signed-off-by: yihsiangpeng <[email protected]>
Change-Id: I5f9c195751f0b6124599d91d8ede535ad745c5f0
diff --git a/gs101_usecase.c b/gs101_usecase.c
index 1ca75dd..74b36c6 100644
--- a/gs101_usecase.c
+++ b/gs101_usecase.c
@@ -556,6 +556,8 @@
 
 	/* from WLC-DC to STBY */
 	if (from_uc == GSU_MODE_WLC_DC) {
+		if (uc_data->dc_sw_gpio > 0)
+			gpio_set_value_cansleep(uc_data->dc_sw_gpio, 0);
 		ret = gs101_ext_mode(uc_data, EXT_MODE_OFF);
 		if (ret < 0) {
 			pr_debug("%s: cannot change extmode ret:%d\n",
diff --git a/p9221_charger.c b/p9221_charger.c
index 4c91914..d30c90f 100644
--- a/p9221_charger.c
+++ b/p9221_charger.c
@@ -615,14 +615,16 @@
 		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);
+			dev_warn(&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;
+			if (!charger->online) {
+				dev_err(&charger->client->dev, "%s: WLC offline\n", __func__);
+				return -ENODEV;
+			}
 		}
 
 		/* Check PropCurrPwr and P9412 Vout */
@@ -636,8 +638,10 @@
 			break;
 	}
 
-	if (count == 3)
-                return -ETIMEDOUT;
+	if (count == 3) {
+		dev_err(&charger->client->dev, "%s: timeout for change to bypass mode\n", __func__);
+		return -ETIMEDOUT;
+	}
 
 	/* Request Bypass mode */
 	ret = charger->chip_capdiv_en(charger, CDMODE_BYPASS_MODE);
@@ -661,14 +665,10 @@
 	const int extben_gpio = charger->pdata->ext_ben_gpio;
 	int ret;
 
-	if (!charger->wlc_dc_enabled)
-		return 0;
-
 	charger->wlc_dc_enabled = false;
-	if (dc_sw_gpio >= 0)
-		gpio_set_value_cansleep(dc_sw_gpio, 0);
-	if (extben_gpio)
-		gpio_set_value_cansleep(extben_gpio, 0);
+
+	p9xxx_gpio_set_value(charger, dc_sw_gpio, 0);
+	p9xxx_gpio_set_value(charger, extben_gpio, 0);
 
 	p9221_set_switch_reg(charger, false);
 
@@ -681,8 +681,10 @@
 	ret = p9xxx_set_bypass_mode(charger);
 	if (ret) {
 		/*
-		 * going to go offline and reset the state when fail to change
-		 * to bypass mode
+		 * going to go offline and reset the state when
+		 * 1. fail to change to bypass mode
+		 * 2. WLC offline(normal)
+		 * 3. MW wcin is 0 but WLC chip Vout > 0
 		 */
 		gvotable_cast_bool_vote(charger->wlc_disable_votable,
 					P9221_HPP_VOTER, true);
@@ -877,7 +879,8 @@
 	charger->sw_ramp_done = false;
 	charger->force_bpp = false;
 	charger->chg_on_rtx = false;
-	p9221_reset_wlc_dc(charger);
+	if (!charger->wait_for_online)
+		p9221_reset_wlc_dc(charger);
 	charger->prop_mode_en = false;
 	charger->hpp_hv = false;
 	charger->fod_mode = -1;
@@ -2249,7 +2252,7 @@
 
 		charger->wlc_dc_enabled = true;
 		if (extben_gpio)
-			gpio_set_value_cansleep(extben_gpio, 1);
+			p9xxx_gpio_set_value(charger, extben_gpio, 1);
 
 		p9221_set_switch_reg(charger, true);
 
@@ -2499,6 +2502,7 @@
 		if (!charger->wlc_dc_enabled) {
 			dev_dbg(&charger->client->dev,
 				"Not WLC-DC, not allow to set dc current\n");
+			ret = -EINVAL;
 			break;
 		}
 		/* uA */
@@ -2509,6 +2513,7 @@
 		if (!charger->wlc_dc_enabled) {
 			dev_dbg(&charger->client->dev,
 				"Not WLC-DC, not allow to set Vout\n");
+			ret = -EINVAL;
 			break;
 		}
 		/* uV */
diff --git a/p9221_charger.h b/p9221_charger.h
index d28e913..02dbb56 100644
--- a/p9221_charger.h
+++ b/p9221_charger.h
@@ -851,6 +851,7 @@
 int p9221_wlc_disable(struct p9221_charger_data *charger, int disable, u8 reason);
 int p9221_set_auth_dc_icl(struct p9221_charger_data *charger, bool enable);
 int p9xxx_sw_ramp_icl(struct p9221_charger_data *charger, const int icl_target);
+int p9xxx_gpio_set_value(struct p9221_charger_data *charger, unsigned gpio, int value);
 
 void p9xxx_gpio_init(struct p9221_charger_data *charger);
 extern int p9221_chip_init_funcs(struct p9221_charger_data *charger,
diff --git a/p9221_chip.c b/p9221_chip.c
index 0b579e5..e73eae4 100644
--- a/p9221_chip.c
+++ b/p9221_chip.c
@@ -1842,6 +1842,17 @@
 }
 
 #if IS_ENABLED(CONFIG_GPIOLIB)
+int p9xxx_gpio_set_value(struct p9221_charger_data *chgr, unsigned gpio, int value)
+{
+	if (gpio <= 0)
+		return -EINVAL;
+
+	logbuffer_log(chgr->log, "%s: set gpio %d to %d\n", __func__, gpio, value);
+	gpio_set_value_cansleep(gpio, value);
+
+	return 0;
+}
+
 static int p9xxx_gpio_get_direction(struct gpio_chip *chip,
 				    unsigned int offset)
 {
@@ -1903,9 +1914,8 @@
 		gpio_direction_output(charger->pdata->wlc_en, value);
 		break;
 	case P9XXX_GPIO_DC_SW_EN:
-		if (charger->pdata->dc_switch_gpio < 0)
-			break;
-		gpio_set_value_cansleep(charger->pdata->dc_switch_gpio, value);
+		ret = p9xxx_gpio_set_value(charger, charger->pdata->dc_switch_gpio, value);
+		break;
 	default:
 		ret = -EINVAL;
 		break;