summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilliam Wu <william.wu@rock-chips.com>2019-03-07 19:40:04 +0800
committerTao Huang <huangtao@rock-chips.com>2019-03-11 10:15:42 +0800
commit5e962a03f65f203a8d49aa771b5b7feeaa6fd6f5 (patch)
tree8f9e97b3b9dea800c68eeb5b629aecb160a43fdf
parent14e0a40eef766331a67585399cd3c33a149dceb5 (diff)
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>
-rw-r--r--drivers/usb/gadget/function/f_uac2.c18
1 files changed, 9 insertions, 9 deletions
diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c
index 56e565a6bcf1..30a509f3103d 100644
--- a/drivers/usb/gadget/function/f_uac2.c
+++ b/drivers/usb/gadget/function/f_uac2.c
@@ -177,7 +177,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,
@@ -205,7 +205,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 */
@@ -216,10 +216,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),
@@ -277,7 +277,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,
};
@@ -286,7 +286,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,
};
@@ -354,7 +354,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,
};
@@ -363,7 +363,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,
};
@@ -505,7 +505,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);