diff options
author | Kyle Tso <kyletso@google.com> | 2024-02-22 23:29:31 +0800 |
---|---|---|
committer | Kyle Tso <kyletso@google.com> | 2024-02-25 20:52:44 +0800 |
commit | aeef6e6406e9d02f7c7d8e8afc2682becd383e29 (patch) | |
tree | 92509c9cf4da81bb18e457961e9cd5a97a2b440b | |
parent | ea22069620bf709186b2ec8220bcc64eb0a6252c (diff) | |
download | tangorpro-aeef6e6406e9d02f7c7d8e8afc2682becd383e29.tar.gz |
pogo_transport: Fix HES mistriggered casesandroid-u-qpr3-beta-2.1_r0.4android-15-beta-1_r0.6android-15-beta-1_r0.4android-15-beta-1_r0.2android-15-beta-1_r0.1android-gs-tangorpro-5.10-android15-dpandroid-gs-pantah-5.10-android15-dpandroid-gs-pantah-5.10-android14-qpr3-betaandroid-gs-felix-5.10-android15-dpandroid-gs-bluejay-5.10-android15-dp
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>
-rw-r--r-- | pogo/pogo_transport.c | 51 |
1 files changed, 44 insertions, 7 deletions
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 @@ struct pogo_transport { 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 @@ static void pogo_transport_pogo_irq_active(struct pogo_transport *pogo_transport { 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 @@ static void pogo_transport_event_handler(struct kthread_work *work) 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 enum alarmtimer_restart lc_check_alarm_handler(struct alarm *alarm, ktime 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 @@ static irqreturn_t pogo_irq(int irq, void *dev_id) 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 @@ static irqreturn_t pogo_irq(int irq, void *dev_id) return IRQ_HANDLED; } - +dock_detection: if (pogo_transport->pogo_ovp_en_gpio >= 0) { int ret; |