pogo_transport: Fix HES mistriggered cases

There are two cases for the HES mistriggered events.

Case #1: H1S state 0 reported during the acc detection
[ 4164.863428] EV:H1S state 1
[ 4164.863633] H1S: accessory detection 0, mfg 0
[ 4164.863637] QUEUE EVENT 3
[ 4164.864567] POGO ACC IRQ triggered
[ 4164.864665] Pogo acc threaded irq running, acc_detect 0
[ 4164.864768] POGO ACC IRQ triggered
[ 4164.864816] Pogo acc threaded irq running, acc_detect 0
[ 4164.864961] POGO ACC IRQ triggered
[ 4164.864999] Pogo acc threaded irq running, acc_detect 1
[ 4164.865002] QUEUE EVENT 4
[ 4164.865082] EV:H1S state 0
[ 4164.865086] EV:ACC_GPIO_ACTIVE
[ 4164.865094] pending state change STANDBY -> STANDBY_ACC_DEBOUNCED @ 20 ms
[ 4164.867384] POGO ACC IRQ triggered
[ 4164.867434] Pogo acc threaded irq running, acc_detect 0
[ 4164.888241] [ 5805] state change STANDBY -> STANDBY_ACC_DEBOUNCED [delayed 20 ms] []

Case #2: H1S stays at 1 during the acc detection
[  861.585046] EV:H1S state 1
[  861.586088] POGO ACC IRQ triggered
[  861.586189] Pogo acc threaded irq running, acc_detect 0
[  861.586318] POGO ACC IRQ triggered
[  861.586358] Pogo acc threaded irq running, acc_detect 0
[  861.586391] POGO ACC IRQ triggered
[  861.586430] Pogo acc threaded irq running, acc_detect 1
[  861.586433] QUEUE EVENT 4
[  861.586571] EV:ACC_GPIO_ACTIVE
[  861.586584] pending state change STANDBY -> STANDBY_ACC_DEBOUNCED @ 20 ms
[  861.588522] POGO ACC IRQ triggered
[  861.588672] Pogo acc threaded irq running, acc_detect 0
[  861.609863] [ 1063] state change STANDBY -> STANDBY_ACC_DEBOUNCED [delayed 20 ms] []
[  865.464562] POGO ACC IRQ triggered
[  865.464805] Pogo acc threaded irq running, acc_detect 1
[  865.464818] QUEUE EVENT 4
[  865.465221] EV:ACC_GPIO_ACTIVE
[  865.465232] pending state change STANDBY_ACC_DEBOUNCED -> STANDBY_ACC_DEBOUNCED @ 20 ms
[  865.471192] POGO ACC IRQ triggered
[  865.471393] Pogo acc threaded irq running, acc_detect 0
[  865.486007] [ 1072] state change STANDBY_ACC_DEBOUNCED -> STANDBY_ACC_DEBOUNCED [delayed 20 ms] []
[  865.602370] POGO IRQ triggered
[  865.602636] Pogo threaded irq running, pogo_gpio 0

For Case #1, run acc detaching process when the ACC_GPIO_ACTIVE event is
triggered.

For Case #2, disable acc regulator when the POGO IRQ is triggered (GPIO
active) and continue to normal dock detection.

Bug: 288341638
Change-Id: I6f5c45ff892cec8d59f45eb7694db879f1978361
Signed-off-by: Kyle Tso <kyletso@google.com>
diff --git a/pogo/pogo_transport.c b/pogo/pogo_transport.c
index b2fad46..5920970 100644
--- a/pogo/pogo_transport.c
+++ b/pogo/pogo_transport.c
@@ -279,6 +279,8 @@
 	bool pogo_irq_enabled;
 	/* When true, acc irq is enabled */
 	bool acc_irq_enabled;
+	/* True if acc gpio was active before the acc irq was disabled */
+	bool acc_gpio_result_cache;
 	/* When true, hall1_s sensor reports attach event */
 	bool hall1_s_state;
 	/* When true, the path won't switch to pogo if accessory is attached */
@@ -1240,25 +1242,31 @@
 {
 	switch (pogo_transport->state) {
 	case STANDBY:
+	case STANDBY_ACC_DEBOUNCED:
 		pogo_transport_set_state(pogo_transport, DOCKING_DEBOUNCED, POGO_PSY_DEBOUNCE_MS);
 		break;
 	case DEVICE_HUB:
+	case DEVICE_HUB_ACC_DEBOUNCED:
 		pogo_transport_set_state(pogo_transport, DEVICE_HUB_DOCKING_DEBOUNCED,
 					 POGO_PSY_DEBOUNCE_MS);
 		break;
 	case DEVICE_DIRECT:
+	case DEVICE_DIRECT_ACC_DEBOUNCED:
 		pogo_transport_set_state(pogo_transport, DEVICE_DOCKING_DEBOUNCED,
 					 POGO_PSY_DEBOUNCE_MS);
 		break;
 	case AUDIO_DIRECT:
+	case AUDIO_DIRECT_ACC_DEBOUNCED:
 		pogo_transport_set_state(pogo_transport, AUDIO_DIRECT_DOCKING_DEBOUNCED,
 					 POGO_PSY_DEBOUNCE_MS);
 		break;
 	case AUDIO_HUB:
+	case AUDIO_HUB_ACC_DEBOUNCED:
 		pogo_transport_set_state(pogo_transport, AUDIO_HUB_DOCKING_DEBOUNCED,
 					 POGO_PSY_DEBOUNCE_MS);
 		break;
 	case HOST_DIRECT:
+	case HOST_DIRECT_ACC_DEBOUNCED:
 		pogo_transport_set_state(pogo_transport, HOST_DIRECT_DOCKING_DEBOUNCED,
 					 POGO_PSY_DEBOUNCE_MS);
 		break;
@@ -2312,8 +2320,13 @@
 				pogo_transport_hes_acc_detached(pogo_transport);
 		}
 		if (events & EVENT_ACC_GPIO_ACTIVE) {
-			logbuffer_log(pogo_transport->log, "EV:ACC_GPIO_ACTIVE");
-			pogo_transport_acc_debouncing(pogo_transport);
+			logbuffer_log(pogo_transport->log, "EV:ACC_GPIO_ACTIVE, H1S %d",
+				      pogo_transport->hall1_s_state);
+			/* b/288341638 step to debouncing only if H1S stays active */
+			if (pogo_transport->hall1_s_state)
+				pogo_transport_acc_debouncing(pogo_transport);
+			else
+				pogo_transport_hes_acc_detached(pogo_transport);
 		}
 		if (events & EVENT_ACC_CONNECTED) {
 			logbuffer_log(pogo_transport->log, "EV:ACC_CONNECTED");
@@ -2394,18 +2407,23 @@
 static irqreturn_t pogo_acc_irq(int irq, void *dev_id)
 {
 	struct pogo_transport *pogo_transport = dev_id;
-	int pogo_acc_gpio = gpio_get_value(pogo_transport->pogo_acc_gpio);
+
+	/*
+	 * Cache the acc gpio result as it might change after the IRQ is disabled and we need the
+	 * latest acc gpio status before the disabling of the IRQ.
+	 */
+	pogo_transport->acc_gpio_result_cache = gpio_get_value(pogo_transport->pogo_acc_gpio);
 
 	logbuffer_log(pogo_transport->log, "Pogo acc threaded irq running, acc_detect %u",
-		      pogo_acc_gpio);
+		      pogo_transport->acc_gpio_result_cache);
 
 	if (pogo_transport->state_machine_enabled) {
-		if (pogo_acc_gpio)
+		if (pogo_transport->acc_gpio_result_cache)
 			pogo_transport_queue_event(pogo_transport, EVENT_ACC_GPIO_ACTIVE);
 		return IRQ_HANDLED;
 	}
 
-	if (pogo_acc_gpio)
+	if (pogo_transport->acc_gpio_result_cache)
 		pogo_transport_event(pogo_transport, EVENT_POGO_ACC_DEBOUNCED,
 				     pogo_transport->pogo_acc_gpio_debounce_ms);
 	else
@@ -2433,6 +2451,25 @@
 
 	if (pogo_transport->acc_detect_ldo &&
 	    regulator_is_enabled(pogo_transport->acc_detect_ldo) > 0) {
+		/*
+		 * b/288341638 If the cached acc gpio is not active, it means that the IV detection
+		 * has failed when the acc detection regulator is enabled. If the state machine
+		 * stays at *_ACC_DEBOUNCED states, i.e., the H1S state is still active, docking
+		 * will fail because it "looks like" a normal acc connection. Disable the acc
+		 * regulator in this situation and continue to the docking detection procedure.
+		 */
+		if (!pogo_transport->acc_gpio_result_cache) {
+			if (pogo_transport->acc_irq_enabled) {
+				disable_irq_nosync(pogo_transport->pogo_acc_irq);
+				pogo_transport->acc_irq_enabled = false;
+				logbuffer_log(pogo_transport->log, "acc_irq disabled");
+			}
+			pogo_transport_acc_regulator(pogo_transport, false);
+			logbuffer_log(pogo_transport->log,
+				      "HES mistriggered, begin docking detection");
+			goto dock_detection;
+		}
+
 		if (pogo_transport->pogo_irq_enabled) {
 			/* disable the irq to prevent the interrupt storm after pogo 5v out */
 			disable_irq_nosync(pogo_transport->pogo_irq);
@@ -2445,7 +2482,7 @@
 		return IRQ_HANDLED;
 	}
 
-
+dock_detection:
 	if (pogo_transport->pogo_ovp_en_gpio >= 0) {
 		int ret;