13 #include <linux/kernel.h>
14 #include <linux/device.h>
15 #include <linux/errno.h>
17 #include <linux/list.h>
19 #include <linux/usb/ch9.h>
23 #include <linux/wait.h>
35 static unsigned streaming_interval = 1;
39 static unsigned streaming_maxpacket = 1024;
43 static unsigned streaming_mult;
47 static unsigned streaming_maxburst;
57 #define UVC_STRING_ASSOCIATION_IDX 0
58 #define UVC_STRING_CONTROL_IDX 1
59 #define UVC_STRING_STREAMING_IDX 2
61 static struct usb_string uvc_en_us_strings[] = {
70 .strings = uvc_en_us_strings,
78 #define UVC_INTF_VIDEO_CONTROL 0
79 #define UVC_INTF_VIDEO_STREAMING 1
81 #define STATUS_BYTECOUNT 16
84 .bLength =
sizeof(uvc_iad),
98 .bAlternateSetting = 0,
102 .bInterfaceProtocol = 0x00,
126 .bAlternateSetting = 0,
130 .bInterfaceProtocol = 0x00,
138 .bAlternateSetting = 1,
142 .bInterfaceProtocol = 0x00,
176 .
bLength =
sizeof uvc_ss_control_comp,
196 .
bLength =
sizeof uvc_ss_streaming_comp,
235 if (uvc->event_setup_out) {
236 uvc->event_setup_out = 0;
238 memset(&v4l2_event, 0,
sizeof(v4l2_event));
259 INFO(f->
config->cdev,
"invalid request type\n");
267 memset(&v4l2_event, 0,
sizeof(v4l2_event));
280 INFO(f->
config->cdev,
"uvc_function_get_alt(%u)\n", interface);
282 if (interface == uvc->control_intf)
284 else if (interface != uvc->streaming_intf)
287 return uvc->
state == UVC_STATE_STREAMING ? 1 : 0;
291 uvc_function_set_alt(
struct usb_function *f,
unsigned interface,
unsigned alt)
298 INFO(f->
config->cdev,
"uvc_function_set_alt(%u, %u)\n", interface, alt);
300 if (interface == uvc->control_intf) {
304 if (uvc->
state == UVC_STATE_DISCONNECTED) {
305 memset(&v4l2_event, 0,
sizeof(v4l2_event));
310 uvc->
state = UVC_STATE_CONNECTED;
316 if (interface != uvc->streaming_intf)
326 if (uvc->
state != UVC_STATE_STREAMING)
330 usb_ep_disable(uvc->video.ep);
332 memset(&v4l2_event, 0,
sizeof(v4l2_event));
336 uvc->
state = UVC_STATE_CONNECTED;
340 if (uvc->
state != UVC_STATE_CONNECTED)
345 &(uvc->func), uvc->video.ep);
348 usb_ep_enable(uvc->video.ep);
351 memset(&v4l2_event, 0,
sizeof(v4l2_event));
355 uvc->
state = UVC_STATE_STREAMING;
371 INFO(f->
config->cdev,
"uvc_function_disable\n");
373 memset(&v4l2_event, 0,
sizeof(v4l2_event));
377 uvc->
state = UVC_STATE_DISCONNECTED;
391 INFO(cdev,
"UVC connect failed with %d\n", ret);
401 INFO(cdev,
"UVC disconnect failed with %d\n", ret);
421 video->
fops = &uvc_v4l2_fops;
426 video_set_drvdata(video, uvc);
431 #define UVC_COPY_DESCRIPTOR(mem, dst, desc) \
433 memcpy(mem, desc, (desc)->bLength); \
435 mem += (desc)->bLength; \
438 #define UVC_COPY_DESCRIPTORS(mem, dst, src) \
440 const struct usb_descriptor_header * const *__src; \
441 for (__src = src; *__src; ++__src) { \
442 memcpy(mem, *__src, (*__src)->bLength); \
444 mem += (*__src)->bLength; \
460 unsigned int control_size;
461 unsigned int streaming_size;
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;
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;
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;
507 + uvc_streaming_intf_alt0.
bLength;
510 bytes += uvc_ss_control_comp.
bLength;
518 control_size += (*src)->bLength;
519 bytes += (*src)->bLength;
524 streaming_size += (*src)->bLength;
525 bytes += (*src)->bLength;
528 for (src = uvc_streaming_std; *
src; ++
src) {
529 bytes += (*src)->bLength;
539 mem += (n_desc + 1) *
sizeof(*src);
545 uvc_control_header =
mem;
559 uvc_streaming_header =
mem;
578 INFO(cdev,
"uvc_function_unbind\n");
581 if (uvc->
vdev->minor == -1)
589 uvc->control_ep->driver_data =
NULL;
591 uvc->video.ep->driver_data =
NULL;
593 if (uvc->control_req) {
594 usb_ep_free_request(cdev->
gadget->ep0, uvc->control_req);
595 kfree(uvc->control_buf);
613 INFO(cdev,
"uvc_function_bind\n");
616 if (streaming_interval < 1)
617 streaming_interval = 1;
618 if (streaming_interval > 16)
619 streaming_interval = 16;
620 if (streaming_mult > 2)
622 if (streaming_maxburst > 15)
623 streaming_maxburst = 15;
630 1023 : streaming_maxpacket;
631 uvc_fs_streaming_ep.
bInterval = streaming_interval;
636 INFO(cdev,
"Unable to allocate control EP\n");
639 uvc->control_ep = ep;
644 INFO(cdev,
"Unable to allocate streaming EP\n");
653 uvc_iad.bFirstInterface =
ret;
655 uvc->control_intf =
ret;
661 uvc->streaming_intf =
ret;
664 if (streaming_maxpacket > 1024)
665 streaming_maxpacket = 1024;
671 if (gadget_is_dualspeed(cdev->
gadget)) {
680 uvc_hs_streaming_ep.
bInterval = streaming_interval;
689 if (gadget_is_superspeed(c->
cdev->gadget)) {
697 uvc_ss_streaming_ep.
bInterval = streaming_interval;
699 uvc_ss_streaming_comp.
bMaxBurst = streaming_maxburst;
701 streaming_maxpacket * (streaming_mult + 1) *
702 (streaming_maxburst + 1);
713 if (uvc->control_req ==
NULL || uvc->control_buf ==
NULL) {
718 uvc->control_req->buf = uvc->control_buf;
719 uvc->control_req->complete = uvc_function_ep0_complete;
720 uvc->control_req->context = uvc;
734 ret = uvc_register_video(uvc);
743 uvc_function_unbind(c, f);
775 if (!gadget_is_dualspeed(c->
cdev->gadget))
782 uvc->
state = UVC_STATE_DISCONNECTED;
785 if (fs_control ==
NULL || fs_control[0] ==
NULL ||
789 if (ss_control ==
NULL || ss_control[0] ==
NULL ||
793 if (fs_streaming ==
NULL || fs_streaming[0] ==
NULL ||
797 if (hs_streaming ==
NULL || hs_streaming[0] ==
NULL ||
801 if (ss_streaming ==
NULL || ss_streaming[0] ==
NULL ||
805 uvc->desc.fs_control = fs_control;
806 uvc->desc.ss_control = ss_control;
807 uvc->desc.fs_streaming = fs_streaming;
808 uvc->desc.hs_streaming = hs_streaming;
809 uvc->desc.ss_streaming = ss_streaming;
818 uvc_iad.iFunction =
ret;
835 uvc->func.
name =
"uvc";
836 uvc->func.strings = uvc_function_strings;
837 uvc->func.bind = uvc_function_bind;
838 uvc->func.unbind = uvc_function_unbind;
839 uvc->func.get_alt = uvc_function_get_alt;
840 uvc->func.set_alt = uvc_function_set_alt;
841 uvc->func.disable = uvc_function_disable;
842 uvc->func.setup = uvc_function_setup;