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.c287
1 files changed, 241 insertions, 46 deletions
diff --git a/drivers/usb/gadget/f_uvc.c b/drivers/usb/gadget/f_uvc.c
index 2022fe492148..2a8bf0655c60 100644
--- a/drivers/usb/gadget/f_uvc.c
+++ b/drivers/usb/gadget/f_uvc.c
@@ -29,6 +29,25 @@
29 29
30unsigned int uvc_gadget_trace_param; 30unsigned int uvc_gadget_trace_param;
31 31
32/*-------------------------------------------------------------------------*/
33
34/* module parameters specific to the Video streaming endpoint */
35static unsigned streaming_interval = 1;
36module_param(streaming_interval, uint, S_IRUGO|S_IWUSR);
37MODULE_PARM_DESC(streaming_interval, "1 - 16");
38
39static unsigned streaming_maxpacket = 1024;
40module_param(streaming_maxpacket, uint, S_IRUGO|S_IWUSR);
41MODULE_PARM_DESC(streaming_maxpacket, "0 - 1023 (fs), 0 - 1024 (hs/ss)");
42
43static unsigned streaming_mult;
44module_param(streaming_mult, uint, S_IRUGO|S_IWUSR);
45MODULE_PARM_DESC(streaming_mult, "0 - 2 (hs/ss only)");
46
47static unsigned streaming_maxburst;
48module_param(streaming_maxburst, uint, S_IRUGO|S_IWUSR);
49MODULE_PARM_DESC(streaming_maxburst, "0 - 15 (ss only)");
50
32/* -------------------------------------------------------------------------- 51/* --------------------------------------------------------------------------
33 * Function descriptors 52 * Function descriptors
34 */ 53 */
@@ -59,6 +78,8 @@ static struct usb_gadget_strings *uvc_function_strings[] = {
59#define UVC_INTF_VIDEO_CONTROL 0 78#define UVC_INTF_VIDEO_CONTROL 0
60#define UVC_INTF_VIDEO_STREAMING 1 79#define UVC_INTF_VIDEO_STREAMING 1
61 80
81#define STATUS_BYTECOUNT 16 /* 16 bytes status */
82
62static struct usb_interface_assoc_descriptor uvc_iad __initdata = { 83static struct usb_interface_assoc_descriptor uvc_iad __initdata = {
63 .bLength = sizeof(uvc_iad), 84 .bLength = sizeof(uvc_iad),
64 .bDescriptorType = USB_DT_INTERFACE_ASSOCIATION, 85 .bDescriptorType = USB_DT_INTERFACE_ASSOCIATION,
@@ -82,12 +103,12 @@ static struct usb_interface_descriptor uvc_control_intf __initdata = {
82 .iInterface = 0, 103 .iInterface = 0,
83}; 104};
84 105
85static struct usb_endpoint_descriptor uvc_control_ep __initdata = { 106static struct usb_endpoint_descriptor uvc_fs_control_ep __initdata = {
86 .bLength = USB_DT_ENDPOINT_SIZE, 107 .bLength = USB_DT_ENDPOINT_SIZE,
87 .bDescriptorType = USB_DT_ENDPOINT, 108 .bDescriptorType = USB_DT_ENDPOINT,
88 .bEndpointAddress = USB_DIR_IN, 109 .bEndpointAddress = USB_DIR_IN,
89 .bmAttributes = USB_ENDPOINT_XFER_INT, 110 .bmAttributes = USB_ENDPOINT_XFER_INT,
90 .wMaxPacketSize = cpu_to_le16(16), 111 .wMaxPacketSize = cpu_to_le16(STATUS_BYTECOUNT),
91 .bInterval = 8, 112 .bInterval = 8,
92}; 113};
93 114
@@ -95,7 +116,7 @@ static struct uvc_control_endpoint_descriptor uvc_control_cs_ep __initdata = {
95 .bLength = UVC_DT_CONTROL_ENDPOINT_SIZE, 116 .bLength = UVC_DT_CONTROL_ENDPOINT_SIZE,
96 .bDescriptorType = USB_DT_CS_ENDPOINT, 117 .bDescriptorType = USB_DT_CS_ENDPOINT,
97 .bDescriptorSubType = UVC_EP_INTERRUPT, 118 .bDescriptorSubType = UVC_EP_INTERRUPT,
98 .wMaxTransferSize = cpu_to_le16(16), 119 .wMaxTransferSize = cpu_to_le16(STATUS_BYTECOUNT),
99}; 120};
100 121
101static struct usb_interface_descriptor uvc_streaming_intf_alt0 __initdata = { 122static struct usb_interface_descriptor uvc_streaming_intf_alt0 __initdata = {
@@ -122,7 +143,7 @@ static struct usb_interface_descriptor uvc_streaming_intf_alt1 __initdata = {
122 .iInterface = 0, 143 .iInterface = 0,
123}; 144};
124 145
125static struct usb_endpoint_descriptor uvc_streaming_ep = { 146static struct usb_endpoint_descriptor uvc_fs_streaming_ep = {
126 .bLength = USB_DT_ENDPOINT_SIZE, 147 .bLength = USB_DT_ENDPOINT_SIZE,
127 .bDescriptorType = USB_DT_ENDPOINT, 148 .bDescriptorType = USB_DT_ENDPOINT,
128 .bEndpointAddress = USB_DIR_IN, 149 .bEndpointAddress = USB_DIR_IN,
@@ -131,15 +152,72 @@ static struct usb_endpoint_descriptor uvc_streaming_ep = {
131 .bInterval = 1, 152 .bInterval = 1,
132}; 153};
133 154
155static 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 */
165static 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
175static 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
185static 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
195static 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
134static const struct usb_descriptor_header * const uvc_fs_streaming[] = { 205static const struct usb_descriptor_header * const uvc_fs_streaming[] = {
135 (struct usb_descriptor_header *) &uvc_streaming_intf_alt1, 206 (struct usb_descriptor_header *) &uvc_streaming_intf_alt1,
136 (struct usb_descriptor_header *) &uvc_streaming_ep, 207 (struct usb_descriptor_header *) &uvc_fs_streaming_ep,
137 NULL, 208 NULL,
138}; 209};
139 210
140static const struct usb_descriptor_header * const uvc_hs_streaming[] = { 211static const struct usb_descriptor_header * const uvc_hs_streaming[] = {
141 (struct usb_descriptor_header *) &uvc_streaming_intf_alt1, 212 (struct usb_descriptor_header *) &uvc_streaming_intf_alt1,
142 (struct usb_descriptor_header *) &uvc_streaming_ep, 213 (struct usb_descriptor_header *) &uvc_hs_streaming_ep,
214 NULL,
215};
216
217static 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,
143 NULL, 221 NULL,
144}; 222};
145 223
@@ -215,6 +293,7 @@ uvc_function_set_alt(struct usb_function *f, unsigned interface, unsigned alt)
215 struct uvc_device *uvc = to_uvc(f); 293 struct uvc_device *uvc = to_uvc(f);
216 struct v4l2_event v4l2_event; 294 struct v4l2_event v4l2_event;
217 struct uvc_event *uvc_event = (void *)&v4l2_event.u.data; 295 struct uvc_event *uvc_event = (void *)&v4l2_event.u.data;
296 int ret;
218 297
219 INFO(f->config->cdev, "uvc_function_set_alt(%u, %u)\n", interface, alt); 298 INFO(f->config->cdev, "uvc_function_set_alt(%u, %u)\n", interface, alt);
220 299
@@ -262,7 +341,10 @@ uvc_function_set_alt(struct usb_function *f, unsigned interface, unsigned alt)
262 return 0; 341 return 0;
263 342
264 if (uvc->video.ep) { 343 if (uvc->video.ep) {
265 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;
266 usb_ep_enable(uvc->video.ep); 348 usb_ep_enable(uvc->video.ep);
267 } 349 }
268 350
@@ -368,9 +450,11 @@ uvc_copy_descriptors(struct uvc_device *uvc, enum usb_device_speed speed)
368{ 450{
369 struct uvc_input_header_descriptor *uvc_streaming_header; 451 struct uvc_input_header_descriptor *uvc_streaming_header;
370 struct uvc_header_descriptor *uvc_control_header; 452 struct uvc_header_descriptor *uvc_control_header;
453 const struct uvc_descriptor_header * const *uvc_control_desc;
371 const struct uvc_descriptor_header * const *uvc_streaming_cls; 454 const struct uvc_descriptor_header * const *uvc_streaming_cls;
372 const struct usb_descriptor_header * const *uvc_streaming_std; 455 const struct usb_descriptor_header * const *uvc_streaming_std;
373 const struct usb_descriptor_header * const *src; 456 const struct usb_descriptor_header * const *src;
457 static struct usb_endpoint_descriptor *uvc_control_ep;
374 struct usb_descriptor_header **dst; 458 struct usb_descriptor_header **dst;
375 struct usb_descriptor_header **hdr; 459 struct usb_descriptor_header **hdr;
376 unsigned int control_size; 460 unsigned int control_size;
@@ -379,10 +463,29 @@ uvc_copy_descriptors(struct uvc_device *uvc, enum usb_device_speed speed)
379 unsigned int bytes; 463 unsigned int bytes;
380 void *mem; 464 void *mem;
381 465
382 uvc_streaming_cls = (speed == USB_SPEED_FULL) 466 switch (speed) {
383 ? uvc->desc.fs_streaming : uvc->desc.hs_streaming; 467 case USB_SPEED_SUPER:
384 uvc_streaming_std = (speed == USB_SPEED_FULL) 468 uvc_control_desc = uvc->desc.ss_control;
385 ? uvc_fs_streaming : uvc_hs_streaming; 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 }
386 489
387 /* Descriptors layout 490 /* Descriptors layout
388 * 491 *
@@ -400,16 +503,24 @@ uvc_copy_descriptors(struct uvc_device *uvc, enum usb_device_speed speed)
400 control_size = 0; 503 control_size = 0;
401 streaming_size = 0; 504 streaming_size = 0;
402 bytes = uvc_iad.bLength + uvc_control_intf.bLength 505 bytes = uvc_iad.bLength + uvc_control_intf.bLength
403 + uvc_control_ep.bLength + uvc_control_cs_ep.bLength 506 + uvc_control_ep->bLength + uvc_control_cs_ep.bLength
404 + uvc_streaming_intf_alt0.bLength; 507 + uvc_streaming_intf_alt0.bLength;
405 n_desc = 5;
406 508
407 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) {
408 control_size += (*src)->bLength; 518 control_size += (*src)->bLength;
409 bytes += (*src)->bLength; 519 bytes += (*src)->bLength;
410 n_desc++; 520 n_desc++;
411 } 521 }
412 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) {
413 streaming_size += (*src)->bLength; 524 streaming_size += (*src)->bLength;
414 bytes += (*src)->bLength; 525 bytes += (*src)->bLength;
415 n_desc++; 526 n_desc++;
@@ -433,12 +544,15 @@ uvc_copy_descriptors(struct uvc_device *uvc, enum usb_device_speed speed)
433 544
434 uvc_control_header = mem; 545 uvc_control_header = mem;
435 UVC_COPY_DESCRIPTORS(mem, dst, 546 UVC_COPY_DESCRIPTORS(mem, dst,
436 (const struct usb_descriptor_header**)uvc->desc.control); 547 (const struct usb_descriptor_header **)uvc_control_desc);
437 uvc_control_header->wTotalLength = cpu_to_le16(control_size); 548 uvc_control_header->wTotalLength = cpu_to_le16(control_size);
438 uvc_control_header->bInCollection = 1; 549 uvc_control_header->bInCollection = 1;
439 uvc_control_header->baInterfaceNr[0] = uvc->streaming_intf; 550 uvc_control_header->baInterfaceNr[0] = uvc->streaming_intf;
440 551
441 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
442 UVC_COPY_DESCRIPTOR(mem, dst, &uvc_control_cs_ep); 556 UVC_COPY_DESCRIPTOR(mem, dst, &uvc_control_cs_ep);
443 UVC_COPY_DESCRIPTOR(mem, dst, &uvc_streaming_intf_alt0); 557 UVC_COPY_DESCRIPTOR(mem, dst, &uvc_streaming_intf_alt0);
444 558
@@ -446,7 +560,8 @@ uvc_copy_descriptors(struct uvc_device *uvc, enum usb_device_speed speed)
446 UVC_COPY_DESCRIPTORS(mem, dst, 560 UVC_COPY_DESCRIPTORS(mem, dst,
447 (const struct usb_descriptor_header**)uvc_streaming_cls); 561 (const struct usb_descriptor_header**)uvc_streaming_cls);
448 uvc_streaming_header->wTotalLength = cpu_to_le16(streaming_size); 562 uvc_streaming_header->wTotalLength = cpu_to_le16(streaming_size);
449 uvc_streaming_header->bEndpointAddress = uvc_streaming_ep.bEndpointAddress; 563 uvc_streaming_header->bEndpointAddress =
564 uvc_fs_streaming_ep.bEndpointAddress;
450 565
451 UVC_COPY_DESCRIPTORS(mem, dst, uvc_streaming_std); 566 UVC_COPY_DESCRIPTORS(mem, dst, uvc_streaming_std);
452 567
@@ -482,6 +597,7 @@ uvc_function_unbind(struct usb_configuration *c, struct usb_function *f)
482 597
483 kfree(f->descriptors); 598 kfree(f->descriptors);
484 kfree(f->hs_descriptors); 599 kfree(f->hs_descriptors);
600 kfree(f->ss_descriptors);
485 601
486 kfree(uvc); 602 kfree(uvc);
487} 603}
@@ -496,8 +612,26 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f)
496 612
497 INFO(cdev, "uvc_function_bind\n"); 613 INFO(cdev, "uvc_function_bind\n");
498 614
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
499 /* Allocate endpoints. */ 633 /* Allocate endpoints. */
500 ep = usb_ep_autoconfig(cdev->gadget, &uvc_control_ep); 634 ep = usb_ep_autoconfig(cdev->gadget, &uvc_fs_control_ep);
501 if (!ep) { 635 if (!ep) {
502 INFO(cdev, "Unable to allocate control EP\n"); 636 INFO(cdev, "Unable to allocate control EP\n");
503 goto error; 637 goto error;
@@ -505,7 +639,7 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f)
505 uvc->control_ep = ep; 639 uvc->control_ep = ep;
506 ep->driver_data = uvc; 640 ep->driver_data = uvc;
507 641
508 ep = usb_ep_autoconfig(cdev->gadget, &uvc_streaming_ep); 642 ep = usb_ep_autoconfig(cdev->gadget, &uvc_fs_streaming_ep);
509 if (!ep) { 643 if (!ep) {
510 INFO(cdev, "Unable to allocate streaming EP\n"); 644 INFO(cdev, "Unable to allocate streaming EP\n");
511 goto error; 645 goto error;
@@ -526,9 +660,52 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f)
526 uvc_streaming_intf_alt1.bInterfaceNumber = ret; 660 uvc_streaming_intf_alt1.bInterfaceNumber = ret;
527 uvc->streaming_intf = ret; 661 uvc->streaming_intf = ret;
528 662
529 /* 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. */
530 f->descriptors = uvc_copy_descriptors(uvc, USB_SPEED_FULL); 668 f->descriptors = uvc_copy_descriptors(uvc, USB_SPEED_FULL);
531 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 }
532 709
533 /* Preallocate control endpoint request. */ 710 /* Preallocate control endpoint request. */
534 uvc->control_req = usb_ep_alloc_request(cdev->gadget->ep0, GFP_KERNEL); 711 uvc->control_req = usb_ep_alloc_request(cdev->gadget->ep0, GFP_KERNEL);
@@ -583,9 +760,11 @@ error:
583 */ 760 */
584int __init 761int __init
585uvc_bind_config(struct usb_configuration *c, 762uvc_bind_config(struct usb_configuration *c,
586 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,
587 const struct uvc_descriptor_header * const *fs_streaming, 765 const struct uvc_descriptor_header * const *fs_streaming,
588 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)
589{ 768{
590 struct uvc_device *uvc; 769 struct uvc_device *uvc;
591 int ret = 0; 770 int ret = 0;
@@ -603,38 +782,54 @@ uvc_bind_config(struct usb_configuration *c,
603 uvc->state = UVC_STATE_DISCONNECTED; 782 uvc->state = UVC_STATE_DISCONNECTED;
604 783
605 /* Validate the descriptors. */ 784 /* Validate the descriptors. */
606 if (control == NULL || control[0] == NULL || 785 if (fs_control == NULL || fs_control[0] == NULL ||
607 control[0]->bDescriptorSubType != UVC_VC_HEADER) 786 fs_control[0]->bDescriptorSubType != UVC_VC_HEADER)
608 goto error; 787 goto error;
609 788
610 if (fs_streaming == NULL || fs_streaming[0] == NULL || 789 if (ss_control == NULL || ss_control[0] == NULL ||
611 fs_streaming[0]->bDescriptorSubType != UVC_VS_INPUT_HEADER) 790 ss_control[0]->bDescriptorSubType != UVC_VC_HEADER)
612 goto error; 791 goto error;
613 792
614 if (hs_streaming == NULL || hs_streaming[0] == NULL || 793 if (fs_streaming == NULL || fs_streaming[0] == NULL ||
615 hs_streaming[0]->bDescriptorSubType != UVC_VS_INPUT_HEADER) 794 fs_streaming[0]->bDescriptorSubType != UVC_VS_INPUT_HEADER)
616 goto error; 795 goto error;
617 796
618 uvc->desc.control = control; 797 if (hs_streaming == NULL || hs_streaming[0] == NULL ||
619 uvc->desc.fs_streaming = fs_streaming; 798 hs_streaming[0]->bDescriptorSubType != UVC_VS_INPUT_HEADER)
620 uvc->desc.hs_streaming = hs_streaming;
621
622 /* Allocate string descriptor numbers. */
623 if ((ret = usb_string_id(c->cdev)) < 0)
624 goto error; 799 goto error;
625 uvc_en_us_strings[UVC_STRING_ASSOCIATION_IDX].id = ret;
626 uvc_iad.iFunction = ret;
627 800
628 if ((ret = usb_string_id(c->cdev)) < 0) 801 if (ss_streaming == NULL || ss_streaming[0] == NULL ||
802 ss_streaming[0]->bDescriptorSubType != UVC_VS_INPUT_HEADER)
629 goto error; 803 goto error;
630 uvc_en_us_strings[UVC_STRING_CONTROL_IDX].id = ret;
631 uvc_control_intf.iInterface = ret;
632 804
633 if ((ret = usb_string_id(c->cdev)) < 0) 805 uvc->desc.fs_control = fs_control;
634 goto error; 806 uvc->desc.ss_control = ss_control;
635 uvc_en_us_strings[UVC_STRING_STREAMING_IDX].id = ret; 807 uvc->desc.fs_streaming = fs_streaming;
636 uvc_streaming_intf_alt0.iInterface = ret; 808 uvc->desc.hs_streaming = hs_streaming;
637 uvc_streaming_intf_alt1.iInterface = ret; 809 uvc->desc.ss_streaming = ss_streaming;
810
811 /* maybe allocate device-global string IDs, and patch descriptors */
812 if (uvc_en_us_strings[UVC_STRING_ASSOCIATION_IDX].id == 0) {
813 /* Allocate string descriptor numbers. */
814 ret = usb_string_id(c->cdev);
815 if (ret < 0)
816 goto error;
817 uvc_en_us_strings[UVC_STRING_ASSOCIATION_IDX].id = ret;
818 uvc_iad.iFunction = ret;
819
820 ret = usb_string_id(c->cdev);
821 if (ret < 0)
822 goto error;
823 uvc_en_us_strings[UVC_STRING_CONTROL_IDX].id = ret;
824 uvc_control_intf.iInterface = ret;
825
826 ret = usb_string_id(c->cdev);
827 if (ret < 0)
828 goto error;
829 uvc_en_us_strings[UVC_STRING_STREAMING_IDX].id = ret;
830 uvc_streaming_intf_alt0.iInterface = ret;
831 uvc_streaming_intf_alt1.iInterface = ret;
832 }
638 833
639 /* Register the function. */ 834 /* Register the function. */
640 uvc->func.name = "uvc"; 835 uvc->func.name = "uvc";