diff options
| author | Ajay Agarwal <ajaya@codeaurora.org> | 2018-11-27 19:48:19 +0530 |
|---|---|---|
| committer | Ajay Agarwal <ajaya@codeaurora.org> | 2019-01-09 10:17:01 +0530 |
| commit | 7b33db7c8ef9de51e72c3e40156654a941cc1489 (patch) | |
| tree | 13b334ba36daa370ea5b2f92543b23c6cdd0d96b | |
| parent | 250bb0182b12f78a299c28873baba0a0828c0a29 (diff) | |
usb: gadget: f_uac1: Add support for UAC1 function
Add support for the UAC1 function with the configfs framework
along with following other changes:
- Add dynamic updation of AudioStreaming interface numbers in
the AudioControl interface descriptor.
- Add superspeed support.
- Stop playback on func disable so that pending request's
completion is called before request has been freed in unbind.
- Fix minor compilation issue.
Change-Id: Ib30fa735314c57b9543f89e18d1fb419ed5a2b9d
Signed-off-by: Ajay Agarwal <ajaya@codeaurora.org>
| -rw-r--r-- | drivers/usb/gadget/function/f_uac1.c | 70 |
1 files changed, 63 insertions, 7 deletions
diff --git a/drivers/usb/gadget/function/f_uac1.c b/drivers/usb/gadget/function/f_uac1.c index 29efbedc91f9..0445b2e1d8b5 100644 --- a/drivers/usb/gadget/function/f_uac1.c +++ b/drivers/usb/gadget/function/f_uac1.c @@ -79,11 +79,6 @@ static struct uac1_ac_header_descriptor_2 ac_header_desc = { .bcdADC = cpu_to_le16(0x0100), .wTotalLength = cpu_to_le16(UAC_DT_TOTAL_LENGTH), .bInCollection = F_AUDIO_NUM_INTERFACES, - .baInterfaceNr = { - /* Interface number of the AudioStream interfaces */ - [0] = 1, - [1] = 2, - } }; #define USB_OUT_IT_ID 1 @@ -209,6 +204,13 @@ static struct usb_endpoint_descriptor as_out_ep_desc = { .bInterval = 4, }; +static struct usb_ss_ep_comp_descriptor as_out_ep_comp_desc = { + .bLength = sizeof(as_out_ep_comp_desc), + .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, + + .wBytesPerInterval = cpu_to_le16(1024), +}; + /* Class-specific AS ISO OUT Endpoint Descriptor */ static struct uac_iso_endpoint_descriptor as_iso_out_desc = { .bLength = UAC_ISO_ENDPOINT_DESC_SIZE, @@ -240,6 +242,13 @@ static struct usb_endpoint_descriptor as_in_ep_desc = { .bInterval = 4, }; +static struct usb_ss_ep_comp_descriptor as_in_ep_comp_desc = { + .bLength = sizeof(as_in_ep_comp_desc), + .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, + + .wBytesPerInterval = cpu_to_le16(1024), +}; + /* Class-specific AS ISO OUT Endpoint Descriptor */ static struct uac_iso_endpoint_descriptor as_iso_in_desc = { .bLength = UAC_ISO_ENDPOINT_DESC_SIZE, @@ -279,6 +288,37 @@ static struct usb_descriptor_header *f_audio_desc[] = { NULL, }; +static struct usb_descriptor_header *f_audio_ss_desc[] = { + (struct usb_descriptor_header *)&ac_interface_desc, + (struct usb_descriptor_header *)&ac_header_desc, + + (struct usb_descriptor_header *)&usb_out_it_desc, + (struct usb_descriptor_header *)&io_out_ot_desc, + (struct usb_descriptor_header *)&io_in_it_desc, + (struct usb_descriptor_header *)&usb_in_ot_desc, + + (struct usb_descriptor_header *)&as_out_interface_alt_0_desc, + (struct usb_descriptor_header *)&as_out_interface_alt_1_desc, + (struct usb_descriptor_header *)&as_out_header_desc, + + (struct usb_descriptor_header *)&as_out_type_i_desc, + + (struct usb_descriptor_header *)&as_out_ep_desc, + (struct usb_descriptor_header *)&as_out_ep_comp_desc, + (struct usb_descriptor_header *)&as_iso_out_desc, + + (struct usb_descriptor_header *)&as_in_interface_alt_0_desc, + (struct usb_descriptor_header *)&as_in_interface_alt_1_desc, + (struct usb_descriptor_header *)&as_in_header_desc, + + (struct usb_descriptor_header *)&as_in_type_i_desc, + + (struct usb_descriptor_header *)&as_in_ep_desc, + (struct usb_descriptor_header *)&as_in_ep_comp_desc, + (struct usb_descriptor_header *)&as_iso_in_desc, + NULL, +}; + enum { STR_AC_IF, STR_USB_OUT_IT, @@ -504,6 +544,7 @@ static void f_audio_disable(struct usb_function *f) uac1->as_in_alt = 0; u_audio_stop_capture(&uac1->g_audio); + u_audio_stop_playback(&uac1->g_audio); } /*-------------------------------------------------------------------------*/ @@ -570,6 +611,7 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f) status = usb_interface_id(c, f); if (status < 0) goto fail; + ac_header_desc.baInterfaceNr[0] = status; as_out_interface_alt_0_desc.bInterfaceNumber = status; as_out_interface_alt_1_desc.bInterfaceNumber = status; uac1->as_out_intf = status; @@ -578,6 +620,7 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f) status = usb_interface_id(c, f); if (status < 0) goto fail; + ac_header_desc.baInterfaceNr[1] = status; as_in_interface_alt_0_desc.bInterfaceNumber = status; as_in_interface_alt_1_desc.bInterfaceNumber = status; uac1->as_in_intf = status; @@ -601,8 +644,8 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f) audio->in_ep->desc = &as_in_ep_desc; /* copy descriptors, and track endpoint copies */ - status = usb_assign_descriptors(f, f_audio_desc, f_audio_desc, NULL, - NULL); + status = usb_assign_descriptors(f, f_audio_desc, f_audio_desc, + f_audio_ss_desc); if (status) goto fail; @@ -798,5 +841,18 @@ static struct usb_function *f_audio_alloc(struct usb_function_instance *fi) } DECLARE_USB_FUNCTION_INIT(uac1, f_audio_alloc_inst, f_audio_alloc); + +static int __init afunc_init(void) +{ + return usb_function_register(&uac1usb_func); +} + +static void __exit afunc_exit(void) +{ + usb_function_unregister(&uac1usb_func); +} + +module_init(afunc_init); +module_exit(afunc_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Ruslan Bilovol"); |
