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 <william.wu@rock-chips.com>
This commit is contained in:
William Wu
2019-03-07 19:40:04 +08:00
committed by Tao Huang
parent 01c1d8f735
commit dc70652f46

View File

@@ -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,10 @@ 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 = cpu_to_le16(sizeof in_clk_src_desc
.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),
@@ -273,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 = cpu_to_le16(1023),
.bInterval = 1,
};
@@ -282,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 = cpu_to_le16(1024),
.bInterval = 4,
};
@@ -350,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 = cpu_to_le16(1023),
.bInterval = 1,
};
@@ -359,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 = cpu_to_le16(1024),
.bInterval = 4,
};
@@ -501,7 +501,7 @@ static void setup_descriptor(struct f_uac2_opts *opts)
as_in_hdr_desc.bTerminalLink = usb_in_ot_desc.bTerminalID;
iad_desc.bInterfaceCount = 1;
ac_hdr_desc.wTotalLength = 0;
ac_hdr_desc.wTotalLength = sizeof ac_hdr_desc;
if (EPIN_EN(opts)) {
u16 len = le16_to_cpu(ac_hdr_desc.wTotalLength);