summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKyle Tso <kyletso@google.com>2023-03-05 22:17:53 +0800
committerKyle Tso <kyletso@google.com>2023-05-23 20:24:54 +0800
commitebe4425fd43129ef3d22392d8261b28752b6b710 (patch)
tree2e36514650bb3056ca4a5fe267e502d33c361f7f
parent88ff5e56b4667cf17eab289d15601dfc618101f2 (diff)
downloadtangorpro-ebe4425fd43129ef3d22392d8261b28752b6b710.tar.gz
pogo_transport: WA to detect the removal of USB accessories
DWC3 does not detect the physical disconnection of SuperSpeed USB accessories while Hub is enabled and Pogo Accessory keeps connected. Toggle the hub-mux to force disconnecting all the USB devices. Bug: 271669059 Change-Id: I200742ad7b0b9fb36df7b30f0f262e274b4041d7 Signed-off-by: Kyle Tso <kyletso@google.com> (cherry picked from commit 7d692e4093410ae63bef96ff6e73001abd920633)
-rw-r--r--pogo/pogo_transport.c38
1 files changed, 33 insertions, 5 deletions
diff --git a/pogo/pogo_transport.c b/pogo/pogo_transport.c
index 03b7cc0..9403ba1 100644
--- a/pogo/pogo_transport.c
+++ b/pogo/pogo_transport.c
@@ -273,6 +273,8 @@ struct pogo_transport {
/* Register the notifier from USB core */
struct notifier_block udev_nb;
+ /* When true, a superspeed (or better) USB device is enumerated */
+ bool ss_udev_attached;
/* To read voltage at the pogo pins */
struct power_supply *pogo_psy;
@@ -1279,6 +1281,9 @@ static void pogo_transport_usbc_host_on(struct pogo_transport *pogo_transport)
static void pogo_transport_usbc_host_off(struct pogo_transport *pogo_transport)
{
struct max77759_plat *chip = pogo_transport->chip;
+ bool ss_attached = pogo_transport->ss_udev_attached;
+
+ pogo_transport->ss_udev_attached = false;
switch (pogo_transport->state) {
case DOCK_DEVICE_HUB:
@@ -1309,6 +1314,19 @@ static void pogo_transport_usbc_host_off(struct pogo_transport *pogo_transport)
break;
case ACC_DEVICE_HUB:
case ACC_AUDIO_HUB:
+ /* b/271669059 */
+ if (ss_attached) {
+ /* USB_MUX_HUB_SEL set to 0 to bypass the hub */
+ gpio_set_value(pogo_transport->pogo_hub_sel_gpio, 0);
+ logbuffer_log(pogo_transport->log, "POGO: toggling hub-mux, hub-mux:%d",
+ gpio_get_value(pogo_transport->pogo_hub_sel_gpio));
+ mdelay(10);
+ /* USB_MUX_HUB_SEL set to 1 to switch the path to hub */
+ gpio_set_value(pogo_transport->pogo_hub_sel_gpio, 1);
+ logbuffer_log(pogo_transport->log, "POGO: hub-mux:%d",
+ gpio_get_value(pogo_transport->pogo_hub_sel_gpio));
+ }
+
/* Clear data_active since USB-C device is detached */
chip->data_active = false;
pogo_transport_set_state(pogo_transport, ACC_HUB, 0);
@@ -1981,13 +1999,19 @@ static void pogo_transport_udev_add(struct pogo_transport *pogo_transport, struc
{
struct usb_interface_descriptor *desc;
struct usb_host_config *config;
+ bool audio_dock = false;
bool audio_dev = false;
int i;
- /* Don't proceed to the event handling if the udev is an Audio Dock. Skip here. */
+ /* Don't proceed to the event handling if the udev is an Audio Dock. Skip the check. */
if (pogo_transport_match_udev(audio_dock_ids, le16_to_cpu(udev->descriptor.idVendor),
- le16_to_cpu(udev->descriptor.idProduct)))
- return;
+ le16_to_cpu(udev->descriptor.idProduct))) {
+ audio_dock = true;
+ goto skip_audio_check;
+ }
+
+ if (udev->speed >= USB_SPEED_SUPER)
+ pogo_transport->ss_udev_attached = true;
config = udev->config;
for (i = 0; i < config->desc.bNumInterfaces; i++) {
@@ -1998,10 +2022,14 @@ static void pogo_transport_udev_add(struct pogo_transport *pogo_transport, struc
}
}
- logbuffer_log(pogo_transport->log, "udev added %04X:%04X %s",
+skip_audio_check:
+ logbuffer_log(pogo_transport->log, "udev added %04X:%04X [%s%s%s%s]",
le16_to_cpu(udev->descriptor.idVendor),
le16_to_cpu(udev->descriptor.idProduct),
- audio_dev ? "(audio)" : "");
+ udev->speed >= USB_SPEED_SUPER ? "Ss" : "",
+ udev->descriptor.bDeviceClass == USB_CLASS_HUB ? "Hu" : "",
+ audio_dock ? "Do" : "",
+ audio_dev ? "Au" : "");
if (audio_dev && pogo_transport->state_machine_enabled)
pogo_transport_queue_event(pogo_transport, EVENT_AUDIO_DEV_ATTACHED);