aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget/f_uvc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/gadget/f_uvc.c')
-rw-r--r--drivers/usb/gadget/f_uvc.c262
1 files changed, 129 insertions, 133 deletions
diff --git a/drivers/usb/gadget/f_uvc.c b/drivers/usb/gadget/f_uvc.c
index 92efd6ec48af..38dcedddc52c 100644
--- a/drivers/usb/gadget/f_uvc.c
+++ b/drivers/usb/gadget/f_uvc.c
@@ -33,19 +33,15 @@ unsigned int uvc_gadget_trace_param;
33/*-------------------------------------------------------------------------*/ 33/*-------------------------------------------------------------------------*/
34 34
35/* module parameters specific to the Video streaming endpoint */ 35/* module parameters specific to the Video streaming endpoint */
36static unsigned streaming_interval = 1; 36static unsigned int streaming_interval = 1;
37module_param(streaming_interval, uint, S_IRUGO|S_IWUSR); 37module_param(streaming_interval, uint, S_IRUGO|S_IWUSR);
38MODULE_PARM_DESC(streaming_interval, "1 - 16"); 38MODULE_PARM_DESC(streaming_interval, "1 - 16");
39 39
40static unsigned streaming_maxpacket = 1024; 40static unsigned int streaming_maxpacket = 1024;
41module_param(streaming_maxpacket, uint, S_IRUGO|S_IWUSR); 41module_param(streaming_maxpacket, uint, S_IRUGO|S_IWUSR);
42MODULE_PARM_DESC(streaming_maxpacket, "0 - 1023 (fs), 0 - 1024 (hs/ss)"); 42MODULE_PARM_DESC(streaming_maxpacket, "1 - 1023 (FS), 1 - 3072 (hs/ss)");
43 43
44static unsigned streaming_mult; 44static unsigned int streaming_maxburst;
45module_param(streaming_mult, uint, S_IRUGO|S_IWUSR);
46MODULE_PARM_DESC(streaming_mult, "0 - 2 (hs/ss only)");
47
48static unsigned streaming_maxburst;
49module_param(streaming_maxburst, uint, S_IRUGO|S_IWUSR); 45module_param(streaming_maxburst, uint, S_IRUGO|S_IWUSR);
50MODULE_PARM_DESC(streaming_maxburst, "0 - 15 (ss only)"); 46MODULE_PARM_DESC(streaming_maxburst, "0 - 15 (ss only)");
51 47
@@ -55,13 +51,11 @@ MODULE_PARM_DESC(streaming_maxburst, "0 - 15 (ss only)");
55 51
56/* string IDs are assigned dynamically */ 52/* string IDs are assigned dynamically */
57 53
58#define UVC_STRING_ASSOCIATION_IDX 0 54#define UVC_STRING_CONTROL_IDX 0
59#define UVC_STRING_CONTROL_IDX 1 55#define UVC_STRING_STREAMING_IDX 1
60#define UVC_STRING_STREAMING_IDX 2
61 56
62static struct usb_string uvc_en_us_strings[] = { 57static struct usb_string uvc_en_us_strings[] = {
63 [UVC_STRING_ASSOCIATION_IDX].s = "UVC Camera", 58 [UVC_STRING_CONTROL_IDX].s = "UVC Camera",
64 [UVC_STRING_CONTROL_IDX].s = "Video Control",
65 [UVC_STRING_STREAMING_IDX].s = "Video Streaming", 59 [UVC_STRING_STREAMING_IDX].s = "Video Streaming",
66 { } 60 { }
67}; 61};
@@ -79,7 +73,7 @@ static struct usb_gadget_strings *uvc_function_strings[] = {
79#define UVC_INTF_VIDEO_CONTROL 0 73#define UVC_INTF_VIDEO_CONTROL 0
80#define UVC_INTF_VIDEO_STREAMING 1 74#define UVC_INTF_VIDEO_STREAMING 1
81 75
82#define STATUS_BYTECOUNT 16 /* 16 bytes status */ 76#define UVC_STATUS_MAX_PACKET_SIZE 16 /* 16 bytes status */
83 77
84static struct usb_interface_assoc_descriptor uvc_iad __initdata = { 78static struct usb_interface_assoc_descriptor uvc_iad __initdata = {
85 .bLength = sizeof(uvc_iad), 79 .bLength = sizeof(uvc_iad),
@@ -104,20 +98,29 @@ static struct usb_interface_descriptor uvc_control_intf __initdata = {
104 .iInterface = 0, 98 .iInterface = 0,
105}; 99};
106 100
107static struct usb_endpoint_descriptor uvc_fs_control_ep __initdata = { 101static struct usb_endpoint_descriptor uvc_control_ep __initdata = {
108 .bLength = USB_DT_ENDPOINT_SIZE, 102 .bLength = USB_DT_ENDPOINT_SIZE,
109 .bDescriptorType = USB_DT_ENDPOINT, 103 .bDescriptorType = USB_DT_ENDPOINT,
110 .bEndpointAddress = USB_DIR_IN, 104 .bEndpointAddress = USB_DIR_IN,
111 .bmAttributes = USB_ENDPOINT_XFER_INT, 105 .bmAttributes = USB_ENDPOINT_XFER_INT,
112 .wMaxPacketSize = cpu_to_le16(STATUS_BYTECOUNT), 106 .wMaxPacketSize = cpu_to_le16(UVC_STATUS_MAX_PACKET_SIZE),
113 .bInterval = 8, 107 .bInterval = 8,
114}; 108};
115 109
110static struct usb_ss_ep_comp_descriptor uvc_ss_control_comp __initdata = {
111 .bLength = sizeof(uvc_ss_control_comp),
112 .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
113 /* The following 3 values can be tweaked if necessary. */
114 .bMaxBurst = 0,
115 .bmAttributes = 0,
116 .wBytesPerInterval = cpu_to_le16(UVC_STATUS_MAX_PACKET_SIZE),
117};
118
116static struct uvc_control_endpoint_descriptor uvc_control_cs_ep __initdata = { 119static struct uvc_control_endpoint_descriptor uvc_control_cs_ep __initdata = {
117 .bLength = UVC_DT_CONTROL_ENDPOINT_SIZE, 120 .bLength = UVC_DT_CONTROL_ENDPOINT_SIZE,
118 .bDescriptorType = USB_DT_CS_ENDPOINT, 121 .bDescriptorType = USB_DT_CS_ENDPOINT,
119 .bDescriptorSubType = UVC_EP_INTERRUPT, 122 .bDescriptorSubType = UVC_EP_INTERRUPT,
120 .wMaxTransferSize = cpu_to_le16(STATUS_BYTECOUNT), 123 .wMaxTransferSize = cpu_to_le16(UVC_STATUS_MAX_PACKET_SIZE),
121}; 124};
122 125
123static struct usb_interface_descriptor uvc_streaming_intf_alt0 __initdata = { 126static struct usb_interface_descriptor uvc_streaming_intf_alt0 __initdata = {
@@ -144,63 +147,53 @@ static struct usb_interface_descriptor uvc_streaming_intf_alt1 __initdata = {
144 .iInterface = 0, 147 .iInterface = 0,
145}; 148};
146 149
147static struct usb_endpoint_descriptor uvc_fs_streaming_ep = { 150static struct usb_endpoint_descriptor uvc_fs_streaming_ep __initdata = {
148 .bLength = USB_DT_ENDPOINT_SIZE, 151 .bLength = USB_DT_ENDPOINT_SIZE,
149 .bDescriptorType = USB_DT_ENDPOINT, 152 .bDescriptorType = USB_DT_ENDPOINT,
150 .bEndpointAddress = USB_DIR_IN, 153 .bEndpointAddress = USB_DIR_IN,
151 .bmAttributes = USB_ENDPOINT_XFER_ISOC, 154 .bmAttributes = USB_ENDPOINT_SYNC_ASYNC
152 .wMaxPacketSize = cpu_to_le16(512), 155 | USB_ENDPOINT_XFER_ISOC,
153 .bInterval = 1, 156 /* The wMaxPacketSize and bInterval values will be initialized from
157 * module parameters.
158 */
159 .wMaxPacketSize = 0,
160 .bInterval = 0,
154}; 161};
155 162
156static struct usb_endpoint_descriptor uvc_hs_streaming_ep = { 163static struct usb_endpoint_descriptor uvc_hs_streaming_ep __initdata = {
157 .bLength = USB_DT_ENDPOINT_SIZE, 164 .bLength = USB_DT_ENDPOINT_SIZE,
158 .bDescriptorType = USB_DT_ENDPOINT, 165 .bDescriptorType = USB_DT_ENDPOINT,
159 .bEndpointAddress = USB_DIR_IN, 166 .bEndpointAddress = USB_DIR_IN,
160 .bmAttributes = USB_ENDPOINT_XFER_ISOC, 167 .bmAttributes = USB_ENDPOINT_SYNC_ASYNC
161 .wMaxPacketSize = cpu_to_le16(1024), 168 | USB_ENDPOINT_XFER_ISOC,
162 .bInterval = 1, 169 /* The wMaxPacketSize and bInterval values will be initialized from
163}; 170 * module parameters.
164 171 */
165/* super speed support */ 172 .wMaxPacketSize = 0,
166static struct usb_endpoint_descriptor uvc_ss_control_ep __initdata = { 173 .bInterval = 0,
167 .bLength = USB_DT_ENDPOINT_SIZE,
168 .bDescriptorType = USB_DT_ENDPOINT,
169
170 .bEndpointAddress = USB_DIR_IN,
171 .bmAttributes = USB_ENDPOINT_XFER_INT,
172 .wMaxPacketSize = cpu_to_le16(STATUS_BYTECOUNT),
173 .bInterval = 8,
174};
175
176static struct usb_ss_ep_comp_descriptor uvc_ss_control_comp __initdata = {
177 .bLength = sizeof uvc_ss_control_comp,
178 .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
179
180 /* the following 3 values can be tweaked if necessary */
181 /* .bMaxBurst = 0, */
182 /* .bmAttributes = 0, */
183 .wBytesPerInterval = cpu_to_le16(STATUS_BYTECOUNT),
184}; 174};
185 175
186static struct usb_endpoint_descriptor uvc_ss_streaming_ep __initdata = { 176static struct usb_endpoint_descriptor uvc_ss_streaming_ep __initdata = {
187 .bLength = USB_DT_ENDPOINT_SIZE, 177 .bLength = USB_DT_ENDPOINT_SIZE,
188 .bDescriptorType = USB_DT_ENDPOINT, 178 .bDescriptorType = USB_DT_ENDPOINT,
189 179
190 .bEndpointAddress = USB_DIR_IN, 180 .bEndpointAddress = USB_DIR_IN,
191 .bmAttributes = USB_ENDPOINT_XFER_ISOC, 181 .bmAttributes = USB_ENDPOINT_SYNC_ASYNC
192 .wMaxPacketSize = cpu_to_le16(1024), 182 | USB_ENDPOINT_XFER_ISOC,
193 .bInterval = 4, 183 /* The wMaxPacketSize and bInterval values will be initialized from
184 * module parameters.
185 */
186 .wMaxPacketSize = 0,
187 .bInterval = 0,
194}; 188};
195 189
196static struct usb_ss_ep_comp_descriptor uvc_ss_streaming_comp = { 190static struct usb_ss_ep_comp_descriptor uvc_ss_streaming_comp __initdata = {
197 .bLength = sizeof uvc_ss_streaming_comp, 191 .bLength = sizeof(uvc_ss_streaming_comp),
198 .bDescriptorType = USB_DT_SS_ENDPOINT_COMP, 192 .bDescriptorType = USB_DT_SS_ENDPOINT_COMP,
199 193 /* The following 3 values can be tweaked if necessary. */
200 /* the following 3 values can be tweaked if necessary */ 194 .bMaxBurst = 0,
201 .bMaxBurst = 0, 195 .bmAttributes = 0,
202 .bmAttributes = 0, 196 .wBytesPerInterval = cpu_to_le16(1024),
203 .wBytesPerInterval = cpu_to_le16(1024),
204}; 197};
205 198
206static const struct usb_descriptor_header * const uvc_fs_streaming[] = { 199static const struct usb_descriptor_header * const uvc_fs_streaming[] = {
@@ -273,6 +266,13 @@ uvc_function_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
273 return 0; 266 return 0;
274} 267}
275 268
269void uvc_function_setup_continue(struct uvc_device *uvc)
270{
271 struct usb_composite_dev *cdev = uvc->func.config->cdev;
272
273 usb_composite_setup_continue(cdev);
274}
275
276static int 276static int
277uvc_function_get_alt(struct usb_function *f, unsigned interface) 277uvc_function_get_alt(struct usb_function *f, unsigned interface)
278{ 278{
@@ -335,7 +335,7 @@ uvc_function_set_alt(struct usb_function *f, unsigned interface, unsigned alt)
335 v4l2_event_queue(uvc->vdev, &v4l2_event); 335 v4l2_event_queue(uvc->vdev, &v4l2_event);
336 336
337 uvc->state = UVC_STATE_CONNECTED; 337 uvc->state = UVC_STATE_CONNECTED;
338 break; 338 return 0;
339 339
340 case 1: 340 case 1:
341 if (uvc->state != UVC_STATE_CONNECTED) 341 if (uvc->state != UVC_STATE_CONNECTED)
@@ -352,15 +352,11 @@ uvc_function_set_alt(struct usb_function *f, unsigned interface, unsigned alt)
352 memset(&v4l2_event, 0, sizeof(v4l2_event)); 352 memset(&v4l2_event, 0, sizeof(v4l2_event));
353 v4l2_event.type = UVC_EVENT_STREAMON; 353 v4l2_event.type = UVC_EVENT_STREAMON;
354 v4l2_event_queue(uvc->vdev, &v4l2_event); 354 v4l2_event_queue(uvc->vdev, &v4l2_event);
355 355 return USB_GADGET_DELAYED_STATUS;
356 uvc->state = UVC_STATE_STREAMING;
357 break;
358 356
359 default: 357 default:
360 return -EINVAL; 358 return -EINVAL;
361 } 359 }
362
363 return 0;
364} 360}
365 361
366static void 362static void
@@ -454,7 +450,6 @@ uvc_copy_descriptors(struct uvc_device *uvc, enum usb_device_speed speed)
454 const struct uvc_descriptor_header * const *uvc_streaming_cls; 450 const struct uvc_descriptor_header * const *uvc_streaming_cls;
455 const struct usb_descriptor_header * const *uvc_streaming_std; 451 const struct usb_descriptor_header * const *uvc_streaming_std;
456 const struct usb_descriptor_header * const *src; 452 const struct usb_descriptor_header * const *src;
457 static struct usb_endpoint_descriptor *uvc_control_ep;
458 struct usb_descriptor_header **dst; 453 struct usb_descriptor_header **dst;
459 struct usb_descriptor_header **hdr; 454 struct usb_descriptor_header **hdr;
460 unsigned int control_size; 455 unsigned int control_size;
@@ -468,14 +463,12 @@ uvc_copy_descriptors(struct uvc_device *uvc, enum usb_device_speed speed)
468 uvc_control_desc = uvc->desc.ss_control; 463 uvc_control_desc = uvc->desc.ss_control;
469 uvc_streaming_cls = uvc->desc.ss_streaming; 464 uvc_streaming_cls = uvc->desc.ss_streaming;
470 uvc_streaming_std = uvc_ss_streaming; 465 uvc_streaming_std = uvc_ss_streaming;
471 uvc_control_ep = &uvc_ss_control_ep;
472 break; 466 break;
473 467
474 case USB_SPEED_HIGH: 468 case USB_SPEED_HIGH:
475 uvc_control_desc = uvc->desc.fs_control; 469 uvc_control_desc = uvc->desc.fs_control;
476 uvc_streaming_cls = uvc->desc.hs_streaming; 470 uvc_streaming_cls = uvc->desc.hs_streaming;
477 uvc_streaming_std = uvc_hs_streaming; 471 uvc_streaming_std = uvc_hs_streaming;
478 uvc_control_ep = &uvc_fs_control_ep;
479 break; 472 break;
480 473
481 case USB_SPEED_FULL: 474 case USB_SPEED_FULL:
@@ -483,7 +476,6 @@ uvc_copy_descriptors(struct uvc_device *uvc, enum usb_device_speed speed)
483 uvc_control_desc = uvc->desc.fs_control; 476 uvc_control_desc = uvc->desc.fs_control;
484 uvc_streaming_cls = uvc->desc.fs_streaming; 477 uvc_streaming_cls = uvc->desc.fs_streaming;
485 uvc_streaming_std = uvc_fs_streaming; 478 uvc_streaming_std = uvc_fs_streaming;
486 uvc_control_ep = &uvc_fs_control_ep;
487 break; 479 break;
488 } 480 }
489 481
@@ -494,6 +486,7 @@ uvc_copy_descriptors(struct uvc_device *uvc, enum usb_device_speed speed)
494 * Class-specific UVC control descriptors 486 * Class-specific UVC control descriptors
495 * uvc_control_ep 487 * uvc_control_ep
496 * uvc_control_cs_ep 488 * uvc_control_cs_ep
489 * uvc_ss_control_comp (for SS only)
497 * uvc_streaming_intf_alt0 490 * uvc_streaming_intf_alt0
498 * Class-specific UVC streaming descriptors 491 * Class-specific UVC streaming descriptors
499 * uvc_{fs|hs}_streaming 492 * uvc_{fs|hs}_streaming
@@ -503,7 +496,7 @@ uvc_copy_descriptors(struct uvc_device *uvc, enum usb_device_speed speed)
503 control_size = 0; 496 control_size = 0;
504 streaming_size = 0; 497 streaming_size = 0;
505 bytes = uvc_iad.bLength + uvc_control_intf.bLength 498 bytes = uvc_iad.bLength + uvc_control_intf.bLength
506 + uvc_control_ep->bLength + uvc_control_cs_ep.bLength 499 + uvc_control_ep.bLength + uvc_control_cs_ep.bLength
507 + uvc_streaming_intf_alt0.bLength; 500 + uvc_streaming_intf_alt0.bLength;
508 501
509 if (speed == USB_SPEED_SUPER) { 502 if (speed == USB_SPEED_SUPER) {
@@ -514,13 +507,13 @@ uvc_copy_descriptors(struct uvc_device *uvc, enum usb_device_speed speed)
514 } 507 }
515 508
516 for (src = (const struct usb_descriptor_header **)uvc_control_desc; 509 for (src = (const struct usb_descriptor_header **)uvc_control_desc;
517 *src; ++src) { 510 *src; ++src) {
518 control_size += (*src)->bLength; 511 control_size += (*src)->bLength;
519 bytes += (*src)->bLength; 512 bytes += (*src)->bLength;
520 n_desc++; 513 n_desc++;
521 } 514 }
522 for (src = (const struct usb_descriptor_header **)uvc_streaming_cls; 515 for (src = (const struct usb_descriptor_header **)uvc_streaming_cls;
523 *src; ++src) { 516 *src; ++src) {
524 streaming_size += (*src)->bLength; 517 streaming_size += (*src)->bLength;
525 bytes += (*src)->bLength; 518 bytes += (*src)->bLength;
526 n_desc++; 519 n_desc++;
@@ -549,7 +542,7 @@ uvc_copy_descriptors(struct uvc_device *uvc, enum usb_device_speed speed)
549 uvc_control_header->bInCollection = 1; 542 uvc_control_header->bInCollection = 1;
550 uvc_control_header->baInterfaceNr[0] = uvc->streaming_intf; 543 uvc_control_header->baInterfaceNr[0] = uvc->streaming_intf;
551 544
552 UVC_COPY_DESCRIPTOR(mem, dst, uvc_control_ep); 545 UVC_COPY_DESCRIPTOR(mem, dst, &uvc_control_ep);
553 if (speed == USB_SPEED_SUPER) 546 if (speed == USB_SPEED_SUPER)
554 UVC_COPY_DESCRIPTOR(mem, dst, &uvc_ss_control_comp); 547 UVC_COPY_DESCRIPTOR(mem, dst, &uvc_ss_control_comp);
555 548
@@ -560,8 +553,7 @@ uvc_copy_descriptors(struct uvc_device *uvc, enum usb_device_speed speed)
560 UVC_COPY_DESCRIPTORS(mem, dst, 553 UVC_COPY_DESCRIPTORS(mem, dst,
561 (const struct usb_descriptor_header**)uvc_streaming_cls); 554 (const struct usb_descriptor_header**)uvc_streaming_cls);
562 uvc_streaming_header->wTotalLength = cpu_to_le16(streaming_size); 555 uvc_streaming_header->wTotalLength = cpu_to_le16(streaming_size);
563 uvc_streaming_header->bEndpointAddress = 556 uvc_streaming_header->bEndpointAddress = uvc->video.ep->address;
564 uvc_fs_streaming_ep.bEndpointAddress;
565 557
566 UVC_COPY_DESCRIPTORS(mem, dst, uvc_streaming_std); 558 UVC_COPY_DESCRIPTORS(mem, dst, uvc_streaming_std);
567 559
@@ -581,7 +573,7 @@ uvc_function_unbind(struct usb_configuration *c, struct usb_function *f)
581 uvc->control_ep->driver_data = NULL; 573 uvc->control_ep->driver_data = NULL;
582 uvc->video.ep->driver_data = NULL; 574 uvc->video.ep->driver_data = NULL;
583 575
584 uvc_en_us_strings[UVC_STRING_ASSOCIATION_IDX].id = 0; 576 uvc_en_us_strings[UVC_STRING_CONTROL_IDX].id = 0;
585 usb_ep_free_request(cdev->gadget->ep0, uvc->control_req); 577 usb_ep_free_request(cdev->gadget->ep0, uvc->control_req);
586 kfree(uvc->control_buf); 578 kfree(uvc->control_buf);
587 579
@@ -595,31 +587,52 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f)
595{ 587{
596 struct usb_composite_dev *cdev = c->cdev; 588 struct usb_composite_dev *cdev = c->cdev;
597 struct uvc_device *uvc = to_uvc(f); 589 struct uvc_device *uvc = to_uvc(f);
590 unsigned int max_packet_mult;
591 unsigned int max_packet_size;
598 struct usb_ep *ep; 592 struct usb_ep *ep;
599 int ret = -EINVAL; 593 int ret = -EINVAL;
600 594
601 INFO(cdev, "uvc_function_bind\n"); 595 INFO(cdev, "uvc_function_bind\n");
602 596
603 /* sanity check the streaming endpoint module parameters */ 597 /* Sanity check the streaming endpoint module parameters.
604 if (streaming_interval < 1)
605 streaming_interval = 1;
606 if (streaming_interval > 16)
607 streaming_interval = 16;
608 if (streaming_mult > 2)
609 streaming_mult = 2;
610 if (streaming_maxburst > 15)
611 streaming_maxburst = 15;
612
613 /*
614 * fill in the FS video streaming specific descriptors from the
615 * module parameters
616 */ 598 */
617 uvc_fs_streaming_ep.wMaxPacketSize = streaming_maxpacket > 1023 ? 599 streaming_interval = clamp(streaming_interval, 1U, 16U);
618 1023 : streaming_maxpacket; 600 streaming_maxpacket = clamp(streaming_maxpacket, 1U, 3072U);
601 streaming_maxburst = min(streaming_maxburst, 15U);
602
603 /* Fill in the FS/HS/SS Video Streaming specific descriptors from the
604 * module parameters.
605 *
606 * NOTE: We assume that the user knows what they are doing and won't
607 * give parameters that their UDC doesn't support.
608 */
609 if (streaming_maxpacket <= 1024) {
610 max_packet_mult = 1;
611 max_packet_size = streaming_maxpacket;
612 } else if (streaming_maxpacket <= 2048) {
613 max_packet_mult = 2;
614 max_packet_size = streaming_maxpacket / 2;
615 } else {
616 max_packet_mult = 3;
617 max_packet_size = streaming_maxpacket / 3;
618 }
619
620 uvc_fs_streaming_ep.wMaxPacketSize = min(streaming_maxpacket, 1023U);
619 uvc_fs_streaming_ep.bInterval = streaming_interval; 621 uvc_fs_streaming_ep.bInterval = streaming_interval;
620 622
623 uvc_hs_streaming_ep.wMaxPacketSize = max_packet_size;
624 uvc_hs_streaming_ep.wMaxPacketSize |= ((max_packet_mult - 1) << 11);
625 uvc_hs_streaming_ep.bInterval = streaming_interval;
626
627 uvc_ss_streaming_ep.wMaxPacketSize = max_packet_size;
628 uvc_ss_streaming_ep.bInterval = streaming_interval;
629 uvc_ss_streaming_comp.bmAttributes = max_packet_mult - 1;
630 uvc_ss_streaming_comp.bMaxBurst = streaming_maxburst;
631 uvc_ss_streaming_comp.wBytesPerInterval =
632 max_packet_size * max_packet_mult * streaming_maxburst;
633
621 /* Allocate endpoints. */ 634 /* Allocate endpoints. */
622 ep = usb_ep_autoconfig(cdev->gadget, &uvc_fs_control_ep); 635 ep = usb_ep_autoconfig(cdev->gadget, &uvc_control_ep);
623 if (!ep) { 636 if (!ep) {
624 INFO(cdev, "Unable to allocate control EP\n"); 637 INFO(cdev, "Unable to allocate control EP\n");
625 goto error; 638 goto error;
@@ -627,7 +640,14 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f)
627 uvc->control_ep = ep; 640 uvc->control_ep = ep;
628 ep->driver_data = uvc; 641 ep->driver_data = uvc;
629 642
630 ep = usb_ep_autoconfig(cdev->gadget, &uvc_fs_streaming_ep); 643 if (gadget_is_superspeed(c->cdev->gadget))
644 ep = usb_ep_autoconfig_ss(cdev->gadget, &uvc_ss_streaming_ep,
645 &uvc_ss_streaming_comp);
646 else if (gadget_is_dualspeed(cdev->gadget))
647 ep = usb_ep_autoconfig(cdev->gadget, &uvc_hs_streaming_ep);
648 else
649 ep = usb_ep_autoconfig(cdev->gadget, &uvc_fs_streaming_ep);
650
631 if (!ep) { 651 if (!ep) {
632 INFO(cdev, "Unable to allocate streaming EP\n"); 652 INFO(cdev, "Unable to allocate streaming EP\n");
633 goto error; 653 goto error;
@@ -635,6 +655,10 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f)
635 uvc->video.ep = ep; 655 uvc->video.ep = ep;
636 ep->driver_data = uvc; 656 ep->driver_data = uvc;
637 657
658 uvc_fs_streaming_ep.bEndpointAddress = uvc->video.ep->address;
659 uvc_hs_streaming_ep.bEndpointAddress = uvc->video.ep->address;
660 uvc_ss_streaming_ep.bEndpointAddress = uvc->video.ep->address;
661
638 /* Allocate interface IDs. */ 662 /* Allocate interface IDs. */
639 if ((ret = usb_interface_id(c, f)) < 0) 663 if ((ret = usb_interface_id(c, f)) < 0)
640 goto error; 664 goto error;
@@ -648,37 +672,6 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f)
648 uvc_streaming_intf_alt1.bInterfaceNumber = ret; 672 uvc_streaming_intf_alt1.bInterfaceNumber = ret;
649 uvc->streaming_intf = ret; 673 uvc->streaming_intf = ret;
650 674
651 /* sanity check the streaming endpoint module parameters */
652 if (streaming_maxpacket > 1024)
653 streaming_maxpacket = 1024;
654 /*
655 * Fill in the HS descriptors from the module parameters for the Video
656 * Streaming endpoint.
657 * NOTE: We assume that the user knows what they are doing and won't
658 * give parameters that their UDC doesn't support.
659 */
660 uvc_hs_streaming_ep.wMaxPacketSize = streaming_maxpacket;
661 uvc_hs_streaming_ep.wMaxPacketSize |= streaming_mult << 11;
662 uvc_hs_streaming_ep.bInterval = streaming_interval;
663 uvc_hs_streaming_ep.bEndpointAddress =
664 uvc_fs_streaming_ep.bEndpointAddress;
665
666 /*
667 * Fill in the SS descriptors from the module parameters for the Video
668 * Streaming endpoint.
669 * NOTE: We assume that the user knows what they are doing and won't
670 * give parameters that their UDC doesn't support.
671 */
672 uvc_ss_streaming_ep.wMaxPacketSize = streaming_maxpacket;
673 uvc_ss_streaming_ep.bInterval = streaming_interval;
674 uvc_ss_streaming_comp.bmAttributes = streaming_mult;
675 uvc_ss_streaming_comp.bMaxBurst = streaming_maxburst;
676 uvc_ss_streaming_comp.wBytesPerInterval =
677 streaming_maxpacket * (streaming_mult + 1) *
678 (streaming_maxburst + 1);
679 uvc_ss_streaming_ep.bEndpointAddress =
680 uvc_fs_streaming_ep.bEndpointAddress;
681
682 /* Copy descriptors */ 675 /* Copy descriptors */
683 f->fs_descriptors = uvc_copy_descriptors(uvc, USB_SPEED_FULL); 676 f->fs_descriptors = uvc_copy_descriptors(uvc, USB_SPEED_FULL);
684 if (gadget_is_dualspeed(cdev->gadget)) 677 if (gadget_is_dualspeed(cdev->gadget))
@@ -775,23 +768,23 @@ uvc_bind_config(struct usb_configuration *c,
775 768
776 /* Validate the descriptors. */ 769 /* Validate the descriptors. */
777 if (fs_control == NULL || fs_control[0] == NULL || 770 if (fs_control == NULL || fs_control[0] == NULL ||
778 fs_control[0]->bDescriptorSubType != UVC_VC_HEADER) 771 fs_control[0]->bDescriptorSubType != UVC_VC_HEADER)
779 goto error; 772 goto error;
780 773
781 if (ss_control == NULL || ss_control[0] == NULL || 774 if (ss_control == NULL || ss_control[0] == NULL ||
782 ss_control[0]->bDescriptorSubType != UVC_VC_HEADER) 775 ss_control[0]->bDescriptorSubType != UVC_VC_HEADER)
783 goto error; 776 goto error;
784 777
785 if (fs_streaming == NULL || fs_streaming[0] == NULL || 778 if (fs_streaming == NULL || fs_streaming[0] == NULL ||
786 fs_streaming[0]->bDescriptorSubType != UVC_VS_INPUT_HEADER) 779 fs_streaming[0]->bDescriptorSubType != UVC_VS_INPUT_HEADER)
787 goto error; 780 goto error;
788 781
789 if (hs_streaming == NULL || hs_streaming[0] == NULL || 782 if (hs_streaming == NULL || hs_streaming[0] == NULL ||
790 hs_streaming[0]->bDescriptorSubType != UVC_VS_INPUT_HEADER) 783 hs_streaming[0]->bDescriptorSubType != UVC_VS_INPUT_HEADER)
791 goto error; 784 goto error;
792 785
793 if (ss_streaming == NULL || ss_streaming[0] == NULL || 786 if (ss_streaming == NULL || ss_streaming[0] == NULL ||
794 ss_streaming[0]->bDescriptorSubType != UVC_VS_INPUT_HEADER) 787 ss_streaming[0]->bDescriptorSubType != UVC_VS_INPUT_HEADER)
795 goto error; 788 goto error;
796 789
797 uvc->desc.fs_control = fs_control; 790 uvc->desc.fs_control = fs_control;
@@ -800,13 +793,16 @@ uvc_bind_config(struct usb_configuration *c,
800 uvc->desc.hs_streaming = hs_streaming; 793 uvc->desc.hs_streaming = hs_streaming;
801 uvc->desc.ss_streaming = ss_streaming; 794 uvc->desc.ss_streaming = ss_streaming;
802 795
803 /* Allocate string descriptor numbers. */ 796 /* String descriptors are global, we only need to allocate string IDs
804 if (uvc_en_us_strings[UVC_STRING_ASSOCIATION_IDX].id == 0) { 797 * for the first UVC function. UVC functions beyond the first (if any)
798 * will reuse the same IDs.
799 */
800 if (uvc_en_us_strings[UVC_STRING_CONTROL_IDX].id == 0) {
805 ret = usb_string_ids_tab(c->cdev, uvc_en_us_strings); 801 ret = usb_string_ids_tab(c->cdev, uvc_en_us_strings);
806 if (ret) 802 if (ret)
807 goto error; 803 goto error;
808 uvc_iad.iFunction = 804 uvc_iad.iFunction =
809 uvc_en_us_strings[UVC_STRING_ASSOCIATION_IDX].id; 805 uvc_en_us_strings[UVC_STRING_CONTROL_IDX].id;
810 uvc_control_intf.iInterface = 806 uvc_control_intf.iInterface =
811 uvc_en_us_strings[UVC_STRING_CONTROL_IDX].id; 807 uvc_en_us_strings[UVC_STRING_CONTROL_IDX].id;
812 ret = uvc_en_us_strings[UVC_STRING_STREAMING_IDX].id; 808 ret = uvc_en_us_strings[UVC_STRING_STREAMING_IDX].id;