summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKyle Tso <kyletso@google.com>2024-03-05 04:27:32 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2024-03-05 04:27:32 +0000
commitfe1f895b8c385858cebcb3e95b5f7f68b8f0c380 (patch)
tree92509c9cf4da81bb18e457961e9cd5a97a2b440b
parent824c3dd037d87b658139dd593050bbe1ba211be4 (diff)
parentaeef6e6406e9d02f7c7d8e8afc2682becd383e29 (diff)
downloadtangorpro-android-gs-lynx-5.10-android15-dp.tar.gz
Original change: https://partner-android-review.googlesource.com/c/kernel/private/devices/google/tangorpro/+/2748032 Change-Id: Id63815e00d209058b64913124fc79d0c6e51d311 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r--pogo/pogo_transport.c51
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;