2929
3030unsigned int uvc_gadget_trace_param ;
3131
32+ /*-------------------------------------------------------------------------*/
33+
34+ /* module parameters specific to the Video streaming endpoint */
35+ static unsigned streaming_interval = 1 ;
36+ module_param (streaming_interval , uint , S_IRUGO |S_IWUSR );
37+ MODULE_PARM_DESC (streaming_interval , "1 - 16" );
38+
39+ static unsigned streaming_maxpacket = 1024 ;
40+ module_param (streaming_maxpacket , uint , S_IRUGO |S_IWUSR );
41+ MODULE_PARM_DESC (streaming_maxpacket , "0 - 1023 (fs), 0 - 1024 (hs/ss)" );
42+
43+ static unsigned streaming_mult ;
44+ module_param (streaming_mult , uint , S_IRUGO |S_IWUSR );
45+ MODULE_PARM_DESC (streaming_mult , "0 - 2 (hs/ss only)" );
46+
47+ static unsigned streaming_maxburst ;
48+ module_param (streaming_maxburst , uint , S_IRUGO |S_IWUSR );
49+ MODULE_PARM_DESC (streaming_maxburst , "0 - 15 (ss only)" );
50+
3251/* --------------------------------------------------------------------------
3352 * Function descriptors
3453 */
@@ -84,7 +103,7 @@ static struct usb_interface_descriptor uvc_control_intf __initdata = {
84103 .iInterface = 0 ,
85104};
86105
87- static struct usb_endpoint_descriptor uvc_control_ep __initdata = {
106+ static struct usb_endpoint_descriptor uvc_fs_control_ep __initdata = {
88107 .bLength = USB_DT_ENDPOINT_SIZE ,
89108 .bDescriptorType = USB_DT_ENDPOINT ,
90109 .bEndpointAddress = USB_DIR_IN ,
@@ -124,7 +143,7 @@ static struct usb_interface_descriptor uvc_streaming_intf_alt1 __initdata = {
124143 .iInterface = 0 ,
125144};
126145
127- static struct usb_endpoint_descriptor uvc_streaming_ep = {
146+ static struct usb_endpoint_descriptor uvc_fs_streaming_ep = {
128147 .bLength = USB_DT_ENDPOINT_SIZE ,
129148 .bDescriptorType = USB_DT_ENDPOINT ,
130149 .bEndpointAddress = USB_DIR_IN ,
@@ -133,15 +152,72 @@ static struct usb_endpoint_descriptor uvc_streaming_ep = {
133152 .bInterval = 1 ,
134153};
135154
155+ static struct usb_endpoint_descriptor uvc_hs_streaming_ep = {
156+ .bLength = USB_DT_ENDPOINT_SIZE ,
157+ .bDescriptorType = USB_DT_ENDPOINT ,
158+ .bEndpointAddress = USB_DIR_IN ,
159+ .bmAttributes = USB_ENDPOINT_XFER_ISOC ,
160+ .wMaxPacketSize = cpu_to_le16 (1024 ),
161+ .bInterval = 1 ,
162+ };
163+
164+ /* super speed support */
165+ static struct usb_endpoint_descriptor uvc_ss_control_ep __initdata = {
166+ .bLength = USB_DT_ENDPOINT_SIZE ,
167+ .bDescriptorType = USB_DT_ENDPOINT ,
168+
169+ .bEndpointAddress = USB_DIR_IN ,
170+ .bmAttributes = USB_ENDPOINT_XFER_INT ,
171+ .wMaxPacketSize = cpu_to_le16 (STATUS_BYTECOUNT ),
172+ .bInterval = 8 ,
173+ };
174+
175+ static struct usb_ss_ep_comp_descriptor uvc_ss_control_comp __initdata = {
176+ .bLength = sizeof uvc_ss_control_comp ,
177+ .bDescriptorType = USB_DT_SS_ENDPOINT_COMP ,
178+
179+ /* the following 3 values can be tweaked if necessary */
180+ /* .bMaxBurst = 0, */
181+ /* .bmAttributes = 0, */
182+ .wBytesPerInterval = cpu_to_le16 (STATUS_BYTECOUNT ),
183+ };
184+
185+ static struct usb_endpoint_descriptor uvc_ss_streaming_ep __initdata = {
186+ .bLength = USB_DT_ENDPOINT_SIZE ,
187+ .bDescriptorType = USB_DT_ENDPOINT ,
188+
189+ .bEndpointAddress = USB_DIR_IN ,
190+ .bmAttributes = USB_ENDPOINT_XFER_ISOC ,
191+ .wMaxPacketSize = cpu_to_le16 (1024 ),
192+ .bInterval = 4 ,
193+ };
194+
195+ static struct usb_ss_ep_comp_descriptor uvc_ss_streaming_comp = {
196+ .bLength = sizeof uvc_ss_streaming_comp ,
197+ .bDescriptorType = USB_DT_SS_ENDPOINT_COMP ,
198+
199+ /* the following 3 values can be tweaked if necessary */
200+ .bMaxBurst = 0 ,
201+ .bmAttributes = 0 ,
202+ .wBytesPerInterval = cpu_to_le16 (1024 ),
203+ };
204+
136205static const struct usb_descriptor_header * const uvc_fs_streaming [] = {
137206 (struct usb_descriptor_header * ) & uvc_streaming_intf_alt1 ,
138- (struct usb_descriptor_header * ) & uvc_streaming_ep ,
207+ (struct usb_descriptor_header * ) & uvc_fs_streaming_ep ,
139208 NULL ,
140209};
141210
142211static const struct usb_descriptor_header * const uvc_hs_streaming [] = {
143212 (struct usb_descriptor_header * ) & uvc_streaming_intf_alt1 ,
144- (struct usb_descriptor_header * ) & uvc_streaming_ep ,
213+ (struct usb_descriptor_header * ) & uvc_hs_streaming_ep ,
214+ NULL ,
215+ };
216+
217+ static const struct usb_descriptor_header * const uvc_ss_streaming [] = {
218+ (struct usb_descriptor_header * ) & uvc_streaming_intf_alt1 ,
219+ (struct usb_descriptor_header * ) & uvc_ss_streaming_ep ,
220+ (struct usb_descriptor_header * ) & uvc_ss_streaming_comp ,
145221 NULL ,
146222};
147223
@@ -217,6 +293,7 @@ uvc_function_set_alt(struct usb_function *f, unsigned interface, unsigned alt)
217293 struct uvc_device * uvc = to_uvc (f );
218294 struct v4l2_event v4l2_event ;
219295 struct uvc_event * uvc_event = (void * )& v4l2_event .u .data ;
296+ int ret ;
220297
221298 INFO (f -> config -> cdev , "uvc_function_set_alt(%u, %u)\n" , interface , alt );
222299
@@ -264,7 +341,10 @@ uvc_function_set_alt(struct usb_function *f, unsigned interface, unsigned alt)
264341 return 0 ;
265342
266343 if (uvc -> video .ep ) {
267- uvc -> video .ep -> desc = & uvc_streaming_ep ;
344+ ret = config_ep_by_speed (f -> config -> cdev -> gadget ,
345+ & (uvc -> func ), uvc -> video .ep );
346+ if (ret )
347+ return ret ;
268348 usb_ep_enable (uvc -> video .ep );
269349 }
270350
@@ -370,9 +450,11 @@ uvc_copy_descriptors(struct uvc_device *uvc, enum usb_device_speed speed)
370450{
371451 struct uvc_input_header_descriptor * uvc_streaming_header ;
372452 struct uvc_header_descriptor * uvc_control_header ;
453+ const struct uvc_descriptor_header * const * uvc_control_desc ;
373454 const struct uvc_descriptor_header * const * uvc_streaming_cls ;
374455 const struct usb_descriptor_header * const * uvc_streaming_std ;
375456 const struct usb_descriptor_header * const * src ;
457+ static struct usb_endpoint_descriptor * uvc_control_ep ;
376458 struct usb_descriptor_header * * dst ;
377459 struct usb_descriptor_header * * hdr ;
378460 unsigned int control_size ;
@@ -381,10 +463,29 @@ uvc_copy_descriptors(struct uvc_device *uvc, enum usb_device_speed speed)
381463 unsigned int bytes ;
382464 void * mem ;
383465
384- uvc_streaming_cls = (speed == USB_SPEED_FULL )
385- ? uvc -> desc .fs_streaming : uvc -> desc .hs_streaming ;
386- uvc_streaming_std = (speed == USB_SPEED_FULL )
387- ? uvc_fs_streaming : uvc_hs_streaming ;
466+ switch (speed ) {
467+ case USB_SPEED_SUPER :
468+ uvc_control_desc = uvc -> desc .ss_control ;
469+ uvc_streaming_cls = uvc -> desc .ss_streaming ;
470+ uvc_streaming_std = uvc_ss_streaming ;
471+ uvc_control_ep = & uvc_ss_control_ep ;
472+ break ;
473+
474+ case USB_SPEED_HIGH :
475+ uvc_control_desc = uvc -> desc .fs_control ;
476+ uvc_streaming_cls = uvc -> desc .hs_streaming ;
477+ uvc_streaming_std = uvc_hs_streaming ;
478+ uvc_control_ep = & uvc_fs_control_ep ;
479+ break ;
480+
481+ case USB_SPEED_FULL :
482+ default :
483+ uvc_control_desc = uvc -> desc .fs_control ;
484+ uvc_streaming_cls = uvc -> desc .fs_streaming ;
485+ uvc_streaming_std = uvc_fs_streaming ;
486+ uvc_control_ep = & uvc_fs_control_ep ;
487+ break ;
488+ }
388489
389490 /* Descriptors layout
390491 *
@@ -402,16 +503,24 @@ uvc_copy_descriptors(struct uvc_device *uvc, enum usb_device_speed speed)
402503 control_size = 0 ;
403504 streaming_size = 0 ;
404505 bytes = uvc_iad .bLength + uvc_control_intf .bLength
405- + uvc_control_ep . bLength + uvc_control_cs_ep .bLength
506+ + uvc_control_ep -> bLength + uvc_control_cs_ep .bLength
406507 + uvc_streaming_intf_alt0 .bLength ;
407- n_desc = 5 ;
408508
409- for (src = (const struct usb_descriptor_header * * )uvc -> desc .control ; * src ; ++ src ) {
509+ if (speed == USB_SPEED_SUPER ) {
510+ bytes += uvc_ss_control_comp .bLength ;
511+ n_desc = 6 ;
512+ } else {
513+ n_desc = 5 ;
514+ }
515+
516+ for (src = (const struct usb_descriptor_header * * )uvc_control_desc ;
517+ * src ; ++ src ) {
410518 control_size += (* src )-> bLength ;
411519 bytes += (* src )-> bLength ;
412520 n_desc ++ ;
413521 }
414- for (src = (const struct usb_descriptor_header * * )uvc_streaming_cls ; * src ; ++ src ) {
522+ for (src = (const struct usb_descriptor_header * * )uvc_streaming_cls ;
523+ * src ; ++ src ) {
415524 streaming_size += (* src )-> bLength ;
416525 bytes += (* src )-> bLength ;
417526 n_desc ++ ;
@@ -435,20 +544,24 @@ uvc_copy_descriptors(struct uvc_device *uvc, enum usb_device_speed speed)
435544
436545 uvc_control_header = mem ;
437546 UVC_COPY_DESCRIPTORS (mem , dst ,
438- (const struct usb_descriptor_header * * )uvc -> desc . control );
547+ (const struct usb_descriptor_header * * )uvc_control_desc );
439548 uvc_control_header -> wTotalLength = cpu_to_le16 (control_size );
440549 uvc_control_header -> bInCollection = 1 ;
441550 uvc_control_header -> baInterfaceNr [0 ] = uvc -> streaming_intf ;
442551
443- UVC_COPY_DESCRIPTOR (mem , dst , & uvc_control_ep );
552+ UVC_COPY_DESCRIPTOR (mem , dst , uvc_control_ep );
553+ if (speed == USB_SPEED_SUPER )
554+ UVC_COPY_DESCRIPTOR (mem , dst , & uvc_ss_control_comp );
555+
444556 UVC_COPY_DESCRIPTOR (mem , dst , & uvc_control_cs_ep );
445557 UVC_COPY_DESCRIPTOR (mem , dst , & uvc_streaming_intf_alt0 );
446558
447559 uvc_streaming_header = mem ;
448560 UVC_COPY_DESCRIPTORS (mem , dst ,
449561 (const struct usb_descriptor_header * * )uvc_streaming_cls );
450562 uvc_streaming_header -> wTotalLength = cpu_to_le16 (streaming_size );
451- uvc_streaming_header -> bEndpointAddress = uvc_streaming_ep .bEndpointAddress ;
563+ uvc_streaming_header -> bEndpointAddress =
564+ uvc_fs_streaming_ep .bEndpointAddress ;
452565
453566 UVC_COPY_DESCRIPTORS (mem , dst , uvc_streaming_std );
454567
@@ -484,6 +597,7 @@ uvc_function_unbind(struct usb_configuration *c, struct usb_function *f)
484597
485598 kfree (f -> descriptors );
486599 kfree (f -> hs_descriptors );
600+ kfree (f -> ss_descriptors );
487601
488602 kfree (uvc );
489603}
@@ -498,16 +612,34 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f)
498612
499613 INFO (cdev , "uvc_function_bind\n" );
500614
615+ /* sanity check the streaming endpoint module parameters */
616+ if (streaming_interval < 1 )
617+ streaming_interval = 1 ;
618+ if (streaming_interval > 16 )
619+ streaming_interval = 16 ;
620+ if (streaming_mult > 2 )
621+ streaming_mult = 2 ;
622+ if (streaming_maxburst > 15 )
623+ streaming_maxburst = 15 ;
624+
625+ /*
626+ * fill in the FS video streaming specific descriptors from the
627+ * module parameters
628+ */
629+ uvc_fs_streaming_ep .wMaxPacketSize = streaming_maxpacket > 1023 ?
630+ 1023 : streaming_maxpacket ;
631+ uvc_fs_streaming_ep .bInterval = streaming_interval ;
632+
501633 /* Allocate endpoints. */
502- ep = usb_ep_autoconfig (cdev -> gadget , & uvc_control_ep );
634+ ep = usb_ep_autoconfig (cdev -> gadget , & uvc_fs_control_ep );
503635 if (!ep ) {
504636 INFO (cdev , "Unable to allocate control EP\n" );
505637 goto error ;
506638 }
507639 uvc -> control_ep = ep ;
508640 ep -> driver_data = uvc ;
509641
510- ep = usb_ep_autoconfig (cdev -> gadget , & uvc_streaming_ep );
642+ ep = usb_ep_autoconfig (cdev -> gadget , & uvc_fs_streaming_ep );
511643 if (!ep ) {
512644 INFO (cdev , "Unable to allocate streaming EP\n" );
513645 goto error ;
@@ -528,9 +660,52 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f)
528660 uvc_streaming_intf_alt1 .bInterfaceNumber = ret ;
529661 uvc -> streaming_intf = ret ;
530662
531- /* Copy descriptors. */
663+ /* sanity check the streaming endpoint module parameters */
664+ if (streaming_maxpacket > 1024 )
665+ streaming_maxpacket = 1024 ;
666+
667+ /* Copy descriptors for FS. */
532668 f -> descriptors = uvc_copy_descriptors (uvc , USB_SPEED_FULL );
533- f -> hs_descriptors = uvc_copy_descriptors (uvc , USB_SPEED_HIGH );
669+
670+ /* support high speed hardware */
671+ if (gadget_is_dualspeed (cdev -> gadget )) {
672+ /*
673+ * Fill in the HS descriptors from the module parameters for the
674+ * Video Streaming endpoint.
675+ * NOTE: We assume that the user knows what they are doing and
676+ * won't give parameters that their UDC doesn't support.
677+ */
678+ uvc_hs_streaming_ep .wMaxPacketSize = streaming_maxpacket ;
679+ uvc_hs_streaming_ep .wMaxPacketSize |= streaming_mult << 11 ;
680+ uvc_hs_streaming_ep .bInterval = streaming_interval ;
681+ uvc_hs_streaming_ep .bEndpointAddress =
682+ uvc_fs_streaming_ep .bEndpointAddress ;
683+
684+ /* Copy descriptors. */
685+ f -> hs_descriptors = uvc_copy_descriptors (uvc , USB_SPEED_HIGH );
686+ }
687+
688+ /* support super speed hardware */
689+ if (gadget_is_superspeed (c -> cdev -> gadget )) {
690+ /*
691+ * Fill in the SS descriptors from the module parameters for the
692+ * Video Streaming endpoint.
693+ * NOTE: We assume that the user knows what they are doing and
694+ * won't give parameters that their UDC doesn't support.
695+ */
696+ uvc_ss_streaming_ep .wMaxPacketSize = streaming_maxpacket ;
697+ uvc_ss_streaming_ep .bInterval = streaming_interval ;
698+ uvc_ss_streaming_comp .bmAttributes = streaming_mult ;
699+ uvc_ss_streaming_comp .bMaxBurst = streaming_maxburst ;
700+ uvc_ss_streaming_comp .wBytesPerInterval =
701+ streaming_maxpacket * (streaming_mult + 1 ) *
702+ (streaming_maxburst + 1 );
703+ uvc_ss_streaming_ep .bEndpointAddress =
704+ uvc_fs_streaming_ep .bEndpointAddress ;
705+
706+ /* Copy descriptors. */
707+ f -> ss_descriptors = uvc_copy_descriptors (uvc , USB_SPEED_SUPER );
708+ }
534709
535710 /* Preallocate control endpoint request. */
536711 uvc -> control_req = usb_ep_alloc_request (cdev -> gadget -> ep0 , GFP_KERNEL );
@@ -585,9 +760,11 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f)
585760 */
586761int __init
587762uvc_bind_config (struct usb_configuration * c ,
588- const struct uvc_descriptor_header * const * control ,
763+ const struct uvc_descriptor_header * const * fs_control ,
764+ const struct uvc_descriptor_header * const * ss_control ,
589765 const struct uvc_descriptor_header * const * fs_streaming ,
590- const struct uvc_descriptor_header * const * hs_streaming )
766+ const struct uvc_descriptor_header * const * hs_streaming ,
767+ const struct uvc_descriptor_header * const * ss_streaming )
591768{
592769 struct uvc_device * uvc ;
593770 int ret = 0 ;
@@ -605,21 +782,31 @@ uvc_bind_config(struct usb_configuration *c,
605782 uvc -> state = UVC_STATE_DISCONNECTED ;
606783
607784 /* Validate the descriptors. */
608- if (control == NULL || control [0 ] == NULL ||
609- control [0 ]-> bDescriptorSubType != UVC_VC_HEADER )
785+ if (fs_control == NULL || fs_control [0 ] == NULL ||
786+ fs_control [0 ]-> bDescriptorSubType != UVC_VC_HEADER )
787+ goto error ;
788+
789+ if (ss_control == NULL || ss_control [0 ] == NULL ||
790+ ss_control [0 ]-> bDescriptorSubType != UVC_VC_HEADER )
610791 goto error ;
611792
612793 if (fs_streaming == NULL || fs_streaming [0 ] == NULL ||
613- fs_streaming [0 ]-> bDescriptorSubType != UVC_VS_INPUT_HEADER )
794+ fs_streaming [0 ]-> bDescriptorSubType != UVC_VS_INPUT_HEADER )
614795 goto error ;
615796
616797 if (hs_streaming == NULL || hs_streaming [0 ] == NULL ||
617- hs_streaming [0 ]-> bDescriptorSubType != UVC_VS_INPUT_HEADER )
798+ hs_streaming [0 ]-> bDescriptorSubType != UVC_VS_INPUT_HEADER )
799+ goto error ;
800+
801+ if (ss_streaming == NULL || ss_streaming [0 ] == NULL ||
802+ ss_streaming [0 ]-> bDescriptorSubType != UVC_VS_INPUT_HEADER )
618803 goto error ;
619804
620- uvc -> desc .control = control ;
805+ uvc -> desc .fs_control = fs_control ;
806+ uvc -> desc .ss_control = ss_control ;
621807 uvc -> desc .fs_streaming = fs_streaming ;
622808 uvc -> desc .hs_streaming = hs_streaming ;
809+ uvc -> desc .ss_streaming = ss_streaming ;
623810
624811 /* maybe allocate device-global string IDs, and patch descriptors */
625812 if (uvc_en_us_strings [UVC_STRING_ASSOCIATION_IDX ].id == 0 ) {
0 commit comments