aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/gadget/f_uvc.c241
-rw-r--r--drivers/usb/gadget/f_uvc.h8
-rw-r--r--drivers/usb/gadget/uvc.h4
-rw-r--r--drivers/usb/gadget/webcam.c29
4 files changed, 247 insertions, 35 deletions
diff --git a/drivers/usb/gadget/f_uvc.c b/drivers/usb/gadget/f_uvc.c
index dd7d7a98ed43..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 */
@@ -84,7 +103,7 @@ static struct usb_interface_descriptor uvc_control_intf __initdata = {
84 .iInterface = 0, 103 .iInterface = 0,
85}; 104};
86 105
87static struct usb_endpoint_descriptor uvc_control_ep __initdata = { 106static struct usb_endpoint_descriptor uvc_fs_control_ep __initdata = {
88 .bLength = USB_DT_ENDPOINT_SIZE, 107 .bLength = USB_DT_ENDPOINT_SIZE,
89 .bDescriptorType = USB_DT_ENDPOINT, 108 .bDescriptorType = USB_DT_ENDPOINT,
90 .bEndpointAddress = USB_DIR_IN, 109 .bEndpointAddress = USB_DIR_IN,
@@ -124,7 +143,7 @@ static struct usb_interface_descriptor uvc_streaming_intf_alt1 __initdata = {
124 .iInterface = 0, 143 .iInterface = 0,
125}; 144};
126 145
127static struct usb_endpoint_descriptor uvc_streaming_ep = { 146static struct usb_endpoint_descriptor uvc_fs_streaming_ep = {
128 .bLength = USB_DT_ENDPOINT_SIZE, 147 .bLength = USB_DT_ENDPOINT_SIZE,
129 .bDescriptorType = USB_DT_ENDPOINT, 148 .bDescriptorType = USB_DT_ENDPOINT,
130 .bEndpointAddress = USB_DIR_IN, 149 .bEndpointAddress = USB_DIR_IN,
@@ -133,15 +152,72 @@ static struct usb_endpoint_descriptor uvc_streaming_ep = {
133 .bInterval = 1, 152 .bInterval = 1,
134}; 153};
135 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
136static const struct usb_descriptor_header * const uvc_fs_streaming[] = { 205static const struct usb_descriptor_header * const uvc_fs_streaming[] = {
137 (struct usb_descriptor_header *) &uvc_streaming_intf_alt1, 206 (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,
139 NULL, 208 NULL,
140}; 209};
141 210
142static const struct usb_descriptor_header * const uvc_hs_streaming[] = { 211static const struct usb_descriptor_header * const uvc_hs_streaming[] = {
143 (struct usb_descriptor_header *) &uvc_streaming_intf_alt1, 212 (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
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,
145 NULL, 221 NULL,
146}; 222};
147 223
@@ -217,6 +293,7 @@ uvc_function_set_alt(struct usb_function *f, unsigned interface, unsigned alt)
217 struct uvc_device *uvc = to_uvc(f); 293 struct uvc_device *uvc = to_uvc(f);
218 struct v4l2_event v4l2_event; 294 struct v4l2_event v4l2_event;
219 struct uvc_event *uvc_event = (void *)&v4l2_event.u.data; 295 struct uvc_event *uvc_event = (void *)&v4l2_event.u.data;
296 int ret;
220 297
221 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);
222 299
@@ -264,7 +341,10 @@ uvc_function_set_alt(struct usb_function *f, unsigned interface, unsigned alt)
264 return 0; 341 return 0;
265 342
266 if (uvc->video.ep) { 343 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;
268 usb_ep_enable(uvc->video.ep); 348 usb_ep_enable(uvc->video.ep);
269 } 349 }
270 350
@@ -370,9 +450,11 @@ uvc_copy_descriptors(struct uvc_device *uvc, enum usb_device_speed speed)
370{ 450{
371 struct uvc_input_header_descriptor *uvc_streaming_header; 451 struct uvc_input_header_descriptor *uvc_streaming_header;
372 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;
373 const struct uvc_descriptor_header * const *uvc_streaming_cls; 454 const struct uvc_descriptor_header * const *uvc_streaming_cls;
374 const struct usb_descriptor_header * const *uvc_streaming_std; 455 const struct usb_descriptor_header * const *uvc_streaming_std;
375 const struct usb_descriptor_header * const *src; 456 const struct usb_descriptor_header * const *src;
457 static struct usb_endpoint_descriptor *uvc_control_ep;
376 struct usb_descriptor_header **dst; 458 struct usb_descriptor_header **dst;
377 struct usb_descriptor_header **hdr; 459 struct usb_descriptor_header **hdr;
378 unsigned int control_size; 460 unsigned int control_size;
@@ -381,10 +463,29 @@ uvc_copy_descriptors(struct uvc_device *uvc, enum usb_device_speed speed)
381 unsigned int bytes; 463 unsigned int bytes;
382 void *mem; 464 void *mem;
383 465
384 uvc_streaming_cls = (speed == USB_SPEED_FULL) 466 switch (speed) {
385 ? uvc->desc.fs_streaming : uvc->desc.hs_streaming; 467 case USB_SPEED_SUPER:
386 uvc_streaming_std = (speed == USB_SPEED_FULL) 468 uvc_control_desc = uvc->desc.ss_control;
387 ? 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 }
388 489
389 /* Descriptors layout 490 /* Descriptors layout
390 * 491 *
@@ -402,16 +503,24 @@ uvc_copy_descriptors(struct uvc_device *uvc, enum usb_device_speed speed)
402 control_size = 0; 503 control_size = 0;
403 streaming_size = 0; 504 streaming_size = 0;
404 bytes = uvc_iad.bLength + uvc_control_intf.bLength 505 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
406 + uvc_streaming_intf_alt0.bLength; 507 + uvc_streaming_intf_alt0.bLength;
407 n_desc = 5;
408 508
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) {
410 control_size += (*src)->bLength; 518 control_size += (*src)->bLength;
411 bytes += (*src)->bLength; 519 bytes += (*src)->bLength;
412 n_desc++; 520 n_desc++;
413 } 521 }
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) {
415 streaming_size += (*src)->bLength; 524 streaming_size += (*src)->bLength;
416 bytes += (*src)->bLength; 525 bytes += (*src)->bLength;
417 n_desc++; 526 n_desc++;
@@ -435,12 +544,15 @@ uvc_copy_descriptors(struct uvc_device *uvc, enum usb_device_speed speed)
435 544
436 uvc_control_header = mem; 545 uvc_control_header = mem;
437 UVC_COPY_DESCRIPTORS(mem, dst, 546 UVC_COPY_DESCRIPTORS(mem, dst,
438 (const struct usb_descriptor_header**)uvc->desc.control); 547 (const struct usb_descriptor_header **)uvc_control_desc);
439 uvc_control_header->wTotalLength = cpu_to_le16(control_size); 548 uvc_control_header->wTotalLength = cpu_to_le16(control_size);
440 uvc_control_header->bInCollection = 1; 549 uvc_control_header->bInCollection = 1;
441 uvc_control_header->baInterfaceNr[0] = uvc->streaming_intf; 550 uvc_control_header->baInterfaceNr[0] = uvc->streaming_intf;
442 551
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
444 UVC_COPY_DESCRIPTOR(mem, dst, &uvc_control_cs_ep); 556 UVC_COPY_DESCRIPTOR(mem, dst, &uvc_control_cs_ep);
445 UVC_COPY_DESCRIPTOR(mem, dst, &uvc_streaming_intf_alt0); 557 UVC_COPY_DESCRIPTOR(mem, dst, &uvc_streaming_intf_alt0);
446 558
@@ -448,7 +560,8 @@ uvc_copy_descriptors(struct uvc_device *uvc, enum usb_device_speed speed)
448 UVC_COPY_DESCRIPTORS(mem, dst, 560 UVC_COPY_DESCRIPTORS(mem, dst,
449 (const struct usb_descriptor_header**)uvc_streaming_cls); 561 (const struct usb_descriptor_header**)uvc_streaming_cls);
450 uvc_streaming_header->wTotalLength = cpu_to_le16(streaming_size); 562 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;
452 565
453 UVC_COPY_DESCRIPTORS(mem, dst, uvc_streaming_std); 566 UVC_COPY_DESCRIPTORS(mem, dst, uvc_streaming_std);
454 567
@@ -484,6 +597,7 @@ uvc_function_unbind(struct usb_configuration *c, struct usb_function *f)
484 597
485 kfree(f->descriptors); 598 kfree(f->descriptors);
486 kfree(f->hs_descriptors); 599 kfree(f->hs_descriptors);
600 kfree(f->ss_descriptors);
487 601
488 kfree(uvc); 602 kfree(uvc);
489} 603}
@@ -498,8 +612,26 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f)
498 612
499 INFO(cdev, "uvc_function_bind\n"); 613 INFO(cdev, "uvc_function_bind\n");
500 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
501 /* Allocate endpoints. */ 633 /* Allocate endpoints. */
502 ep = usb_ep_autoconfig(cdev->gadget, &uvc_control_ep); 634 ep = usb_ep_autoconfig(cdev->gadget, &uvc_fs_control_ep);
503 if (!ep) { 635 if (!ep) {
504 INFO(cdev, "Unable to allocate control EP\n"); 636 INFO(cdev, "Unable to allocate control EP\n");
505 goto error; 637 goto error;
@@ -507,7 +639,7 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f)
507 uvc->control_ep = ep; 639 uvc->control_ep = ep;
508 ep->driver_data = uvc; 640 ep->driver_data = uvc;
509 641
510 ep = usb_ep_autoconfig(cdev->gadget, &uvc_streaming_ep); 642 ep = usb_ep_autoconfig(cdev->gadget, &uvc_fs_streaming_ep);
511 if (!ep) { 643 if (!ep) {
512 INFO(cdev, "Unable to allocate streaming EP\n"); 644 INFO(cdev, "Unable to allocate streaming EP\n");
513 goto error; 645 goto error;
@@ -528,9 +660,52 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f)
528 uvc_streaming_intf_alt1.bInterfaceNumber = ret; 660 uvc_streaming_intf_alt1.bInterfaceNumber = ret;
529 uvc->streaming_intf = ret; 661 uvc->streaming_intf = ret;
530 662
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. */
532 f->descriptors = uvc_copy_descriptors(uvc, USB_SPEED_FULL); 668 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 }
534 709
535 /* Preallocate control endpoint request. */ 710 /* Preallocate control endpoint request. */
536 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);
@@ -585,9 +760,11 @@ error:
585 */ 760 */
586int __init 761int __init
587uvc_bind_config(struct usb_configuration *c, 762uvc_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,
589 const struct uvc_descriptor_header * const *fs_streaming, 765 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)
591{ 768{
592 struct uvc_device *uvc; 769 struct uvc_device *uvc;
593 int ret = 0; 770 int ret = 0;
@@ -605,21 +782,31 @@ uvc_bind_config(struct usb_configuration *c,
605 uvc->state = UVC_STATE_DISCONNECTED; 782 uvc->state = UVC_STATE_DISCONNECTED;
606 783
607 /* Validate the descriptors. */ 784 /* Validate the descriptors. */
608 if (control == NULL || control[0] == NULL || 785 if (fs_control == NULL || fs_control[0] == NULL ||
609 control[0]->bDescriptorSubType != UVC_VC_HEADER) 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)
610 goto error; 791 goto error;
611 792
612 if (fs_streaming == NULL || fs_streaming[0] == NULL || 793 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)
614 goto error; 795 goto error;
615 796
616 if (hs_streaming == NULL || hs_streaming[0] == NULL || 797 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)
618 goto error; 803 goto error;
619 804
620 uvc->desc.control = control; 805 uvc->desc.fs_control = fs_control;
806 uvc->desc.ss_control = ss_control;
621 uvc->desc.fs_streaming = fs_streaming; 807 uvc->desc.fs_streaming = fs_streaming;
622 uvc->desc.hs_streaming = hs_streaming; 808 uvc->desc.hs_streaming = hs_streaming;
809 uvc->desc.ss_streaming = ss_streaming;
623 810
624 /* maybe allocate device-global string IDs, and patch descriptors */ 811 /* maybe allocate device-global string IDs, and patch descriptors */
625 if (uvc_en_us_strings[UVC_STRING_ASSOCIATION_IDX].id == 0) { 812 if (uvc_en_us_strings[UVC_STRING_ASSOCIATION_IDX].id == 0) {
diff --git a/drivers/usb/gadget/f_uvc.h b/drivers/usb/gadget/f_uvc.h
index abf832935134..c3d258d30188 100644
--- a/drivers/usb/gadget/f_uvc.h
+++ b/drivers/usb/gadget/f_uvc.h
@@ -17,9 +17,11 @@
17#include <linux/usb/video.h> 17#include <linux/usb/video.h>
18 18
19extern int uvc_bind_config(struct usb_configuration *c, 19extern int uvc_bind_config(struct usb_configuration *c,
20 const struct uvc_descriptor_header * const *control, 20 const struct uvc_descriptor_header * const *fs_control,
21 const struct uvc_descriptor_header * const *fs_streaming, 21 const struct uvc_descriptor_header * const *hs_control,
22 const struct uvc_descriptor_header * const *hs_streaming); 22 const struct uvc_descriptor_header * const *fs_streaming,
23 const struct uvc_descriptor_header * const *hs_streaming,
24 const struct uvc_descriptor_header * const *ss_streaming);
23 25
24#endif /* _F_UVC_H_ */ 26#endif /* _F_UVC_H_ */
25 27
diff --git a/drivers/usb/gadget/uvc.h b/drivers/usb/gadget/uvc.h
index ca4e03a1c73a..93b0c1191115 100644
--- a/drivers/usb/gadget/uvc.h
+++ b/drivers/usb/gadget/uvc.h
@@ -153,9 +153,11 @@ struct uvc_device
153 153
154 /* Descriptors */ 154 /* Descriptors */
155 struct { 155 struct {
156 const struct uvc_descriptor_header * const *control; 156 const struct uvc_descriptor_header * const *fs_control;
157 const struct uvc_descriptor_header * const *ss_control;
157 const struct uvc_descriptor_header * const *fs_streaming; 158 const struct uvc_descriptor_header * const *fs_streaming;
158 const struct uvc_descriptor_header * const *hs_streaming; 159 const struct uvc_descriptor_header * const *hs_streaming;
160 const struct uvc_descriptor_header * const *ss_streaming;
159 } desc; 161 } desc;
160 162
161 unsigned int control_intf; 163 unsigned int control_intf;
diff --git a/drivers/usb/gadget/webcam.c b/drivers/usb/gadget/webcam.c
index 668fe128f2ef..120e134e805e 100644
--- a/drivers/usb/gadget/webcam.c
+++ b/drivers/usb/gadget/webcam.c
@@ -272,7 +272,15 @@ static const struct uvc_color_matching_descriptor uvc_color_matching = {
272 .bMatrixCoefficients = 4, 272 .bMatrixCoefficients = 4,
273}; 273};
274 274
275static const struct uvc_descriptor_header * const uvc_control_cls[] = { 275static const struct uvc_descriptor_header * const uvc_fs_control_cls[] = {
276 (const struct uvc_descriptor_header *) &uvc_control_header,
277 (const struct uvc_descriptor_header *) &uvc_camera_terminal,
278 (const struct uvc_descriptor_header *) &uvc_processing,
279 (const struct uvc_descriptor_header *) &uvc_output_terminal,
280 NULL,
281};
282
283static const struct uvc_descriptor_header * const uvc_ss_control_cls[] = {
276 (const struct uvc_descriptor_header *) &uvc_control_header, 284 (const struct uvc_descriptor_header *) &uvc_control_header,
277 (const struct uvc_descriptor_header *) &uvc_camera_terminal, 285 (const struct uvc_descriptor_header *) &uvc_camera_terminal,
278 (const struct uvc_descriptor_header *) &uvc_processing, 286 (const struct uvc_descriptor_header *) &uvc_processing,
@@ -304,6 +312,18 @@ static const struct uvc_descriptor_header * const uvc_hs_streaming_cls[] = {
304 NULL, 312 NULL,
305}; 313};
306 314
315static const struct uvc_descriptor_header * const uvc_ss_streaming_cls[] = {
316 (const struct uvc_descriptor_header *) &uvc_input_header,
317 (const struct uvc_descriptor_header *) &uvc_format_yuv,
318 (const struct uvc_descriptor_header *) &uvc_frame_yuv_360p,
319 (const struct uvc_descriptor_header *) &uvc_frame_yuv_720p,
320 (const struct uvc_descriptor_header *) &uvc_format_mjpg,
321 (const struct uvc_descriptor_header *) &uvc_frame_mjpg_360p,
322 (const struct uvc_descriptor_header *) &uvc_frame_mjpg_720p,
323 (const struct uvc_descriptor_header *) &uvc_color_matching,
324 NULL,
325};
326
307/* -------------------------------------------------------------------------- 327/* --------------------------------------------------------------------------
308 * USB configuration 328 * USB configuration
309 */ 329 */
@@ -311,8 +331,9 @@ static const struct uvc_descriptor_header * const uvc_hs_streaming_cls[] = {
311static int __init 331static int __init
312webcam_config_bind(struct usb_configuration *c) 332webcam_config_bind(struct usb_configuration *c)
313{ 333{
314 return uvc_bind_config(c, uvc_control_cls, uvc_fs_streaming_cls, 334 return uvc_bind_config(c, uvc_fs_control_cls, uvc_ss_control_cls,
315 uvc_hs_streaming_cls); 335 uvc_fs_streaming_cls, uvc_hs_streaming_cls,
336 uvc_ss_streaming_cls);
316} 337}
317 338
318static struct usb_configuration webcam_config_driver = { 339static struct usb_configuration webcam_config_driver = {
@@ -373,7 +394,7 @@ static struct usb_composite_driver webcam_driver = {
373 .name = "g_webcam", 394 .name = "g_webcam",
374 .dev = &webcam_device_descriptor, 395 .dev = &webcam_device_descriptor,
375 .strings = webcam_device_strings, 396 .strings = webcam_device_strings,
376 .max_speed = USB_SPEED_HIGH, 397 .max_speed = USB_SPEED_SUPER,
377 .unbind = webcam_unbind, 398 .unbind = webcam_unbind,
378}; 399};
379 400