From 60767d93e50c5bc7e904eb217daa91fbd79c4853 Mon Sep 17 00:00:00 2001 From: William Wu Date: Thu, 7 Mar 2019 19:40:04 +0800 Subject: [PATCH] usb: gadget: f_uac2: fix some issues for Windows recognized We find that the UAC2 gadget can't be recognized on Windows 10. It's because that the descriptors of UAC2 doesn't meet the requirements of Windows. According to the USB Audio 2.0 Drivers of Windows [1], if the bmAttributes of OUT-EP in the audio stream interface is set to asynchronous (use USB_ENDPOINT_SYNC_ASYNC), then a feedback endpoint must be implemented in the respective alternate setting of the AS interface. The Windows driver does not support implicit feedback. However, it's difficult to implement the feedback endpoint now. So the patch changes the bmAttributes of OUT-EP to adaptive, and changes the bmAttributes of IN-EP to synchronous at the same time. This patch also sets the wTerminalType of terminal descriptor to microphone and speaker by default. With this patch, we also fix the wTotalLength of the ac_hdr_desc. [1] https://docs.microsoft.com/en-us/windows-hardware/drivers/audio/usb-2-0-audio-drivers Change-Id: I3597d5f321235fcbce56dbfbfe95172d02e58892 Signed-off-by: William Wu Signed-off-by: Frank Wang --- drivers/usb/gadget/function/f_uac2.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c index 6f03e944e0e3..f68768e30687 100644 --- a/drivers/usb/gadget/function/f_uac2.c +++ b/drivers/usb/gadget/function/f_uac2.c @@ -173,7 +173,7 @@ static struct uac2_input_terminal_descriptor io_in_it_desc = { .bDescriptorSubtype = UAC_INPUT_TERMINAL, /* .bTerminalID = DYNAMIC */ - .wTerminalType = cpu_to_le16(UAC_INPUT_TERMINAL_UNDEFINED), + .wTerminalType = cpu_to_le16(UAC_INPUT_TERMINAL_MICROPHONE), .bAssocTerminal = 0, /* .bCSourceID = DYNAMIC */ .iChannelNames = 0, @@ -201,7 +201,7 @@ static struct uac2_output_terminal_descriptor io_out_ot_desc = { .bDescriptorSubtype = UAC_OUTPUT_TERMINAL, /* .bTerminalID = DYNAMIC */ - .wTerminalType = cpu_to_le16(UAC_OUTPUT_TERMINAL_UNDEFINED), + .wTerminalType = cpu_to_le16(UAC_OUTPUT_TERMINAL_SPEAKER), .bAssocTerminal = 0, /* .bSourceID = DYNAMIC */ /* .bCSourceID = DYNAMIC */ @@ -212,10 +212,13 @@ static struct uac2_ac_header_descriptor ac_hdr_desc = { .bLength = sizeof ac_hdr_desc, .bDescriptorType = USB_DT_CS_INTERFACE, - .bDescriptorSubtype = UAC_MS_HEADER, + .bDescriptorSubtype = UAC_HEADER, .bcdADC = cpu_to_le16(0x200), .bCategory = UAC2_FUNCTION_IO_BOX, - /* .wTotalLength = DYNAMIC */ + .wTotalLength = cpu_to_le16(sizeof ac_hdr_desc + sizeof in_clk_src_desc + + sizeof out_clk_src_desc + sizeof usb_out_it_desc + + sizeof io_in_it_desc + sizeof usb_in_ot_desc + + sizeof io_out_ot_desc), .bmControls = 0, }; @@ -270,7 +273,7 @@ static struct usb_endpoint_descriptor fs_epout_desc = { .bDescriptorType = USB_DT_ENDPOINT, .bEndpointAddress = USB_DIR_OUT, - .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC, + .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ADAPTIVE, /* .wMaxPacketSize = DYNAMIC */ .bInterval = 1, }; @@ -279,7 +282,7 @@ static struct usb_endpoint_descriptor hs_epout_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, - .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC, + .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ADAPTIVE, /* .wMaxPacketSize = DYNAMIC */ .bInterval = 4, }; @@ -347,7 +350,7 @@ static struct usb_endpoint_descriptor fs_epin_desc = { .bDescriptorType = USB_DT_ENDPOINT, .bEndpointAddress = USB_DIR_IN, - .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC, + .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_SYNC, /* .wMaxPacketSize = DYNAMIC */ .bInterval = 1, }; @@ -356,7 +359,7 @@ static struct usb_endpoint_descriptor hs_epin_desc = { .bLength = USB_DT_ENDPOINT_SIZE, .bDescriptorType = USB_DT_ENDPOINT, - .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_ASYNC, + .bmAttributes = USB_ENDPOINT_XFER_ISOC | USB_ENDPOINT_SYNC_SYNC, /* .wMaxPacketSize = DYNAMIC */ .bInterval = 4, };