summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPuma Hsu <pumahsu@google.com>2022-08-18 11:02:37 +0800
committerPuma Hsu <pumahsu@google.com>2022-08-23 05:53:49 +0000
commit6dfb6d6157d9c407923a4057faf8816b3b62d417 (patch)
tree37975038de5f30be8860ceba94673230171f4443
parent058b74bd0e989d260d84109f937bf48e9ad25390 (diff)
downloadaoc-6dfb6d6157d9c407923a4057faf8816b3b62d417.tar.gz
aoc: usb: API for usb audio devices count
If the Host connected to a hub, user may connect more than two USB audio headsets or DACs. A caller can call this function to know how many USB audio devices are connected now. Bug: 241547770 Test: usb audio device works well Signed-off-by: Puma Hsu <pumahsu@google.com> Change-Id: I0093df434a0f09f382db07f3f600e2c502c0c309
-rw-r--r--usb/aoc_usb.h4
-rw-r--r--usb/xhci_hooks_impl_whi.c20
2 files changed, 24 insertions, 0 deletions
diff --git a/usb/aoc_usb.h b/usb/aoc_usb.h
index 1787a33..bc81f41 100644
--- a/usb/aoc_usb.h
+++ b/usb/aoc_usb.h
@@ -68,6 +68,9 @@ struct xhci_vendor_data {
bool dt_direct_usb_access;
bool offload_state;
+ /* count how many usb audio devices are connected */
+ int usb_audio_count;
+
enum usb_offload_op_mode op_mode;
struct workqueue_struct *irq_wq;
@@ -120,6 +123,7 @@ extern int xhci_handle_event(struct xhci_hcd *xhci);
extern void xhci_update_erst_dequeue(struct xhci_hcd *xhci,
union xhci_trb *event_ring_deq);
extern int xhci_exynos_register_vendor_ops(struct xhci_vendor_ops *vendor_ops);
+int xhci_get_usb_audio_count(struct xhci_hcd *xhci);
int xhci_set_offload_state(struct xhci_hcd *xhci, bool enabled);
struct xhci_hcd *get_xhci_hcd_by_udev(struct usb_device *udev);
diff --git a/usb/xhci_hooks_impl_whi.c b/usb/xhci_hooks_impl_whi.c
index 5ff72c4..3d322d9 100644
--- a/usb/xhci_hooks_impl_whi.c
+++ b/usb/xhci_hooks_impl_whi.c
@@ -37,6 +37,23 @@ int unregister_aoc_usb_notifier(struct notifier_block *nb)
return blocking_notifier_chain_unregister(&aoc_usb_notifier_list, nb);
}
+/*
+ * If the Host connected to a hub, user may connect more than two USB audio
+ * headsets or DACs. A caller can call this function to know how many USB
+ * audio devices are connected now.
+ */
+int xhci_get_usb_audio_count(struct xhci_hcd *xhci)
+{
+ struct xhci_vendor_data *vendor_data;
+
+ if (!xhci)
+ return -ENODEV;
+
+ vendor_data = xhci_to_priv(xhci)->vendor_data;
+
+ return vendor_data->usb_audio_count;
+}
+
int xhci_set_offload_state(struct xhci_hcd *xhci, bool enabled)
{
struct xhci_vendor_data *vendor_data;
@@ -316,6 +333,7 @@ static int xhci_udev_notify(struct notifier_block *self, unsigned long action,
USB_OFFLOAD_SIMPLE_AUDIO_ACCESSORY ||
vendor_data->op_mode ==
USB_OFFLOAD_DRAM) {
+ vendor_data->usb_audio_count++;
xhci_sync_conn_stat(udev->bus->busnum, udev->devnum, udev->slot_id,
USB_CONNECTED);
}
@@ -328,6 +346,7 @@ static int xhci_udev_notify(struct notifier_block *self, unsigned long action,
USB_OFFLOAD_SIMPLE_AUDIO_ACCESSORY ||
vendor_data->op_mode ==
USB_OFFLOAD_DRAM)) {
+ vendor_data->usb_audio_count--;
xhci_sync_conn_stat(udev->bus->busnum, udev->devnum, udev->slot_id,
USB_DISCONNECTED);
}
@@ -513,6 +532,7 @@ static int usb_audio_offload_init(struct xhci_hcd *xhci)
dev_warn(dev, "Direct USB access is not supported\n");
vendor_data->offload_state = true;
+ vendor_data->usb_audio_count = 0;
usb_register_notify(&xhci_udev_nb);
vendor_data->op_mode = USB_OFFLOAD_DRAM;