15 #include <linux/kernel.h>
16 #include <linux/list.h>
17 #include <linux/module.h>
18 #include <linux/slab.h>
20 #include <linux/videodev2.h>
22 #include <linux/wait.h>
23 #include <linux/version.h>
24 #include <asm/unaligned.h>
30 #define DRIVER_AUTHOR "Laurent Pinchart " \
32 #define DRIVER_DESC "USB Video Class driver"
36 static unsigned int uvc_quirks_param = -1;
46 .name =
"YUV 4:2:2 (YUYV)",
51 .name =
"YUV 4:2:2 (YUYV)",
56 .name =
"YUV 4:2:0 (NV12)",
66 .name =
"YVU 4:2:0 (YV12)",
71 .name =
"YUV 4:2:0 (I420)",
76 .name =
"YUV 4:2:0 (M420)",
81 .name =
"YUV 4:2:2 (UYVY)",
86 .name =
"Greyscale 8-bit (Y800)",
91 .name =
"Greyscale 8-bit (Y8 )",
96 .name =
"Greyscale 10-bit (Y10 )",
101 .name =
"Greyscale 12-bit (Y12 )",
106 .name =
"Greyscale 16-bit (Y16 )",
134 struct usb_host_endpoint *ep;
137 for (i = 0; i < alts->desc.bNumEndpoints; ++
i) {
138 ep = &alts->endpoint[
i];
139 if (ep->desc.bEndpointAddress == epaddr)
151 for (i = 0; i < len; ++
i) {
152 if (
memcmp(guid, uvc_fmts[i].guid, 16) == 0)
159 static __u32 uvc_colorspace(
const __u8 primaries)
161 static const __u8 colorprimaries[] = {
171 return colorprimaries[primaries];
184 unsigned int n_terms,
unsigned int threshold)
202 for (n = 0; n < n_terms && y != 0; ++
n) {
204 if (an[n] >= threshold) {
219 for (i = n; i > 0; --
i) {
239 if (denominator == 0 ||
240 numerator/denominator >= ((
uint32_t)-1)/10000000)
247 multiplier = 10000000;
248 while (numerator > ((
uint32_t)-1)/multiplier) {
253 return denominator ? numerator * multiplier / denominator : 0;
265 if (entity->
id ==
id)
294 if (stream->
header.bTerminalLink ==
id)
305 static int uvc_parse_format(
struct uvc_device *dev,
310 struct usb_host_interface *alts = intf->cur_altsetting;
318 format->
type = buffer[2];
319 format->
index = buffer[3];
327 "interface %d FORMAT error\n",
329 alts->desc.bInterfaceNumber);
334 fmtdesc = uvc_format_by_guid(&buffer[5]);
336 if (fmtdesc !=
NULL) {
338 sizeof format->
name);
339 format->
fcc = fmtdesc->
fcc;
348 format->
bpp = buffer[21];
361 "interface %d FORMAT error\n",
363 alts->desc.bInterfaceNumber);
377 "interface %d FORMAT error\n",
379 alts->desc.bInterfaceNumber);
383 switch (buffer[8] & 0x7f) {
395 "interface %d: unknown DV format %u\n",
397 alts->desc.bInterfaceNumber, buffer[8]);
401 strlcat(format->
name, buffer[8] & (1 << 7) ?
" 60Hz" :
" 50Hz",
402 sizeof format->
name);
410 frame = &format->
frame[0];
424 "interface %d unsupported format %u\n",
425 dev->
udev->devnum, alts->desc.bInterfaceNumber,
439 buffer[2] == ftype) {
442 n = buflen > 25 ? buffer[25] : 0;
444 n = buflen > 21 ? buffer[21] : 0;
448 if (buflen < 26 + 4*n) {
450 "interface %d FRAME error\n", dev->
udev->devnum,
451 alts->desc.bInterfaceNumber);
457 frame->
wWidth = get_unaligned_le16(&buffer[5]);
458 frame->
wHeight = get_unaligned_le16(&buffer[7]);
492 for (i = 0; i <
n; ++
i) {
494 *(*intervals)++ = interval ? interval : 1;
532 "interface %d COLORFORMAT error\n",
534 alts->desc.bInterfaceNumber);
538 format->
colorspace = uvc_colorspace(buffer[3]);
544 return buffer -
start;
547 static int uvc_parse_streaming(
struct uvc_device *dev,
553 struct usb_host_interface *alts = &intf->altsetting[0];
554 unsigned char *
_buffer, *buffer = alts->extra;
555 int _buflen, buflen = alts->extralen;
556 unsigned int nformats = 0, nframes = 0, nintervals = 0;
562 if (intf->cur_altsetting->desc.bInterfaceSubClass
565 "video streaming interface\n", dev->
udev->devnum,
566 intf->altsetting[0].desc.bInterfaceNumber);
572 "claimed\n", dev->
udev->devnum,
573 intf->altsetting[0].desc.bInterfaceNumber);
577 streaming = kzalloc(
sizeof *streaming,
GFP_KERNEL);
578 if (streaming ==
NULL) {
586 streaming->
intfnum = intf->cur_altsetting->desc.bInterfaceNumber;
592 for (i = 0; i < alts->desc.bNumEndpoints; ++
i) {
593 struct usb_host_endpoint *ep = &alts->endpoint[
i];
595 if (ep->extralen == 0)
598 if (ep->extralen > 2 &&
601 "from endpoint %u.\n", i);
602 buffer = alts->endpoint[
i].extra;
603 buflen = alts->endpoint[
i].extralen;
617 "interface descriptors found.\n");
635 "%d HEADER descriptor not found.\n", dev->
udev->devnum,
636 alts->desc.bInterfaceNumber);
640 p = buflen >= 4 ? buffer[3] : 0;
641 n = buflen >= size ? buffer[size-1] : 0;
643 if (buflen < size + p*n) {
645 "interface %d HEADER descriptor is invalid.\n",
646 dev->
udev->devnum, alts->desc.bInterfaceNumber);
650 streaming->
header.bNumFormats =
p;
651 streaming->
header.bEndpointAddress = buffer[6];
653 streaming->
header.bmInfo = buffer[7];
654 streaming->
header.bTerminalLink = buffer[8];
655 streaming->
header.bStillCaptureMethod = buffer[9];
656 streaming->
header.bTriggerSupport = buffer[10];
657 streaming->
header.bTriggerUsage = buffer[11];
659 streaming->
header.bTerminalLink = buffer[7];
661 streaming->
header.bControlSize =
n;
663 streaming->
header.bmaControls =
kmemdup(&buffer[size], p * n,
678 switch (_buffer[2]) {
697 "interface %d FORMAT %u is not supported.\n",
699 alts->desc.bInterfaceNumber, _buffer[2]);
706 nintervals += _buffer[25] ? _buffer[25] : 3;
712 nintervals += _buffer[21] ? _buffer[21] : 3;
716 _buflen -= _buffer[0];
717 _buffer += _buffer[0];
722 "%d has no supported formats defined.\n",
723 dev->
udev->devnum, alts->desc.bInterfaceNumber);
727 size = nformats *
sizeof *format + nframes *
sizeof *frame
730 if (format ==
NULL) {
735 frame = (
struct uvc_frame *)&format[nformats];
736 interval = (
__u32 *)&frame[nframes];
749 ret = uvc_parse_format(dev, streaming, format,
750 &interval, buffer, buflen);
771 "%d has %u bytes of trailing descriptor garbage.\n",
772 dev->
udev->devnum, alts->desc.bInterfaceNumber, buflen);
775 for (i = 0; i < intf->num_altsetting; ++
i) {
776 struct usb_host_endpoint *ep;
777 alts = &intf->altsetting[
i];
779 streaming->
header.bEndpointAddress);
784 psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3));
805 unsigned int num_inputs;
809 extra_size =
ALIGN(extra_size,
sizeof(*entity->
pads));
811 size =
sizeof(*entity) + extra_size +
sizeof(*entity->
pads) * num_pads
820 entity->num_links = 0;
822 entity->pads = ((
void *)(entity + 1)) + extra_size;
824 for (i = 0; i < num_inputs; ++
i)
829 entity->bNrInPins = num_inputs;
836 static int uvc_parse_vendor_control(
struct uvc_device *dev,
837 const unsigned char *buffer,
int buflen)
839 struct usb_device *
udev = dev->
udev;
840 struct usb_host_interface *alts = dev->
intf->cur_altsetting;
847 if (buffer[1] != 0x41 || buffer[2] != 0x01)
876 p = buflen >= 22 ? buffer[21] : 0;
877 n = buflen >= 25 + p ? buffer[22+
p] : 0;
879 if (buflen < 25 + p + 2*n) {
881 "interface %d EXTENSION_UNIT error\n",
882 udev->devnum, alts->desc.bInterfaceNumber);
892 unit->
extension.bNumControls = buffer[20];
896 unit->
extension.bmControlsType = (
__u8 *)unit +
sizeof(*unit)
900 if (buffer[24+p+2*n] != 0)
914 static int uvc_parse_standard_control(
struct uvc_device *dev,
915 const unsigned char *buffer,
int buflen)
917 struct usb_device *udev = dev->
udev;
920 struct usb_host_interface *alts = dev->
intf->cur_altsetting;
921 unsigned int i,
n,
p, len;
926 n = buflen >= 12 ? buffer[11] : 0;
928 if (buflen < 12 || buflen < 12 + n) {
930 "interface %d HEADER error\n", udev->devnum,
931 alts->desc.bInterfaceNumber);
939 for (i = 0; i <
n; ++
i) {
943 "interface %d doesn't exists\n",
948 uvc_parse_streaming(dev, intf);
955 "interface %d INPUT_TERMINAL error\n",
956 udev->devnum, alts->desc.bInterfaceNumber);
963 type = get_unaligned_le16(&buffer[4]);
964 if ((type & 0xff00) == 0) {
966 "interface %d INPUT_TERMINAL %d has invalid "
967 "type 0x%04x, skipping\n", udev->devnum,
968 alts->desc.bInterfaceNumber,
978 n = buflen >= 15 ? buffer[14] : 0;
982 n = buflen >= 9 ? buffer[8] : 0;
983 p = buflen >= 10 + n ? buffer[9+
n] : 0;
987 if (buflen < len + n + p) {
989 "interface %d INPUT_TERMINAL error\n",
990 udev->devnum, alts->desc.bInterfaceNumber);
1000 term->
camera.bControlSize =
n;
1001 term->
camera.bmControls = (
__u8 *)term +
sizeof *term;
1002 term->
camera.wObjectiveFocalLengthMin =
1003 get_unaligned_le16(&buffer[8]);
1004 term->
camera.wObjectiveFocalLengthMax =
1005 get_unaligned_le16(&buffer[10]);
1006 term->
camera.wOcularFocalLength =
1007 get_unaligned_le16(&buffer[12]);
1011 term->
media.bControlSize =
n;
1012 term->
media.bmControls = (
__u8 *)term +
sizeof *term;
1013 term->
media.bTransportModeSize =
p;
1014 term->
media.bmTransportModes = (
__u8 *)term
1017 memcpy(term->
media.bmTransportModes, &buffer[10+n], p);
1036 "interface %d OUTPUT_TERMINAL error\n",
1037 udev->devnum, alts->desc.bInterfaceNumber);
1044 type = get_unaligned_le16(&buffer[4]);
1045 if ((type & 0xff00) == 0) {
1047 "interface %d OUTPUT_TERMINAL %d has invalid "
1048 "type 0x%04x, skipping\n", udev->devnum,
1049 alts->desc.bInterfaceNumber, buffer[3], type);
1070 p = buflen >= 5 ? buffer[4] : 0;
1072 if (buflen < 5 || buflen < 6 + p) {
1074 "interface %d SELECTOR_UNIT error\n",
1075 udev->devnum, alts->desc.bInterfaceNumber);
1079 unit = uvc_alloc_entity(buffer[2], buffer[3], p + 1, 0);
1085 if (buffer[5+p] != 0)
1095 n = buflen >= 8 ? buffer[7] : 0;
1098 if (buflen < p + n) {
1100 "interface %d PROCESSING_UNIT error\n",
1101 udev->devnum, alts->desc.bInterfaceNumber);
1105 unit = uvc_alloc_entity(buffer[2], buffer[3], 2, n);
1111 get_unaligned_le16(&buffer[5]);
1118 if (buffer[8+n] != 0)
1128 p = buflen >= 22 ? buffer[21] : 0;
1129 n = buflen >= 24 + p ? buffer[22+
p] : 0;
1131 if (buflen < 24 + p + n) {
1133 "interface %d EXTENSION_UNIT error\n",
1134 udev->devnum, alts->desc.bInterfaceNumber);
1138 unit = uvc_alloc_entity(buffer[2], buffer[3], p + 1, n);
1143 unit->
extension.bNumControls = buffer[20];
1149 if (buffer[23+p+n] != 0)
1160 "descriptor (%u)\n", buffer[2]);
1167 static int uvc_parse_control(
struct uvc_device *dev)
1169 struct usb_host_interface *alts = dev->
intf->cur_altsetting;
1170 unsigned char *buffer = alts->extra;
1171 int buflen = alts->extralen;
1179 while (buflen > 2) {
1180 if (uvc_parse_vendor_control(dev, buffer, buflen) ||
1182 goto next_descriptor;
1184 if ((ret = uvc_parse_standard_control(dev, buffer, buflen)) < 0)
1188 buflen -= buffer[0];
1189 buffer += buffer[0];
1197 if (alts->desc.bNumEndpoints == 1 &&
1199 struct usb_host_endpoint *ep = &alts->endpoint[0];
1202 if (usb_endpoint_is_int_in(desc) &&
1254 "than 1 input pin.\n", entity->
id);
1266 "Processing Units in chain.\n");
1283 "Units in chain.\n");
1338 forward = uvc_entity_by_reference(chain->
dev, entity->
id,
1340 if (forward ==
NULL)
1342 if (forward == prev)
1349 "has more than 1 input pin.\n",
1370 "terminal %u.\n", forward->
id);
1420 "input %d isn't connected to an "
1421 "input terminal\n", entity->
id, i);
1429 uvc_scan_chain_forward(chain, term, entity);
1455 if (entity ==
NULL) {
1457 "unknown entity %d.\n",
id);
1470 uvc_trace(UVC_TRACE_PROBE,
"Scanning UVC chain:");
1475 while (entity !=
NULL) {
1477 if (entity->
chain.next || entity->
chain.prev) {
1479 "entity %d already in chain.\n", entity->
id);
1484 if (uvc_scan_chain_entity(chain, entity) < 0)
1488 if (uvc_scan_chain_forward(chain, entity, prev) < 0)
1493 if (uvc_scan_chain_backward(chain, &entity) < 0)
1500 static unsigned int uvc_print_terms(
struct list_head *terms,
u16 dir,
1504 unsigned int nterms = 0;
1514 if (++nterms >= 4) {
1526 static char buffer[43];
1541 static int uvc_scan_device(
struct uvc_device *dev)
1566 if (uvc_scan_chain(chain, term) < 0) {
1571 uvc_trace(UVC_TRACE_PROBE,
"Found a valid video chain (%s).\n",
1572 uvc_print_chain(chain));
1577 if (list_empty(&dev->
chains)) {
1599 static void uvc_delete(
struct uvc_device *dev)
1611 #ifdef CONFIG_MEDIA_CONTROLLER
1612 if (media_devnode_is_registered(&dev->mdev.devnode))
1625 #ifdef CONFIG_MEDIA_CONTROLLER
1664 static void uvc_unregister_video(
struct uvc_device *dev)
1692 static int uvc_register_video(
struct uvc_device *dev,
1732 stream->
vdev = vdev;
1733 video_set_drvdata(vdev, stream);
1751 static int uvc_register_terms(
struct uvc_device *dev,
1762 stream = uvc_stream_by_id(dev, term->
id);
1763 if (stream ==
NULL) {
1765 "for terminal %u.", term->
id);
1770 ret = uvc_register_video(dev, stream);
1780 static int uvc_register_chains(
struct uvc_device *dev)
1786 ret = uvc_register_terms(dev, chain);
1790 #ifdef CONFIG_MEDIA_CONTROLLER
1809 struct usb_device *udev = interface_to_usbdev(intf);
1814 uvc_trace(UVC_TRACE_PROBE,
"Probing known UVC device %s "
1815 "(%04x:%04x)\n", udev->devpath, id->
idVendor,
1818 uvc_trace(UVC_TRACE_PROBE,
"Probing generic UVC device %s\n",
1826 INIT_LIST_HEAD(&dev->
chains);
1827 INIT_LIST_HEAD(&dev->
streams);
1834 dev->
intfnum = intf->cur_altsetting->desc.bInterfaceNumber;
1835 dev->
quirks = (uvc_quirks_param == -1)
1836 ? id->driver_info : uvc_quirks_param;
1838 if (udev->product !=
NULL)
1842 "UVC Camera (%04x:%04x)",
1847 if (uvc_parse_control(dev) < 0) {
1848 uvc_trace(UVC_TRACE_PROBE,
"Unable to parse UVC "
1855 udev->product ? udev->product :
"<unnamed>",
1859 if (dev->
quirks != id->driver_info) {
1861 "parameter for testing purpose.\n", dev->
quirks);
1863 "linux-uvc-devel mailing list.\n");
1867 #ifdef CONFIG_MEDIA_CONTROLLER
1868 dev->mdev.dev = &intf->dev;
1869 strlcpy(dev->mdev.model, dev->
name,
sizeof(dev->mdev.model));
1871 strlcpy(dev->mdev.serial, udev->serial,
1872 sizeof(dev->mdev.serial));
1873 strcpy(dev->mdev.bus_info, udev->devpath);
1874 dev->mdev.hw_revision =
le16_to_cpu(udev->descriptor.bcdDevice);
1875 dev->mdev.driver_version = LINUX_VERSION_CODE;
1879 dev->
vdev.mdev = &dev->mdev;
1889 if (uvc_scan_device(dev) < 0)
1893 if (uvc_register_chains(dev) < 0)
1897 usb_set_intfdata(intf, dev);
1902 "endpoint (%d), status interrupt will not be "
1903 "supported.\n", ret);
1906 uvc_trace(UVC_TRACE_PROBE,
"UVC device initialized.\n");
1907 usb_enable_autosuspend(udev);
1911 uvc_unregister_video(dev);
1917 struct uvc_device *dev = usb_get_intfdata(intf);
1922 usb_set_intfdata(intf,
NULL);
1924 if (intf->cur_altsetting->desc.bInterfaceSubClass ==
1930 uvc_unregister_video(dev);
1935 struct uvc_device *dev = usb_get_intfdata(intf);
1939 intf->cur_altsetting->desc.bInterfaceNumber);
1942 if (intf->cur_altsetting->desc.bInterfaceSubClass ==
1947 if (stream->
intf == intf)
1956 static int __uvc_resume(
struct usb_interface *intf,
int reset)
1958 struct uvc_device *dev = usb_get_intfdata(intf);
1962 intf->cur_altsetting->desc.bInterfaceNumber);
1964 if (intf->cur_altsetting->desc.bInterfaceSubClass ==
1977 if (stream->
intf == intf)
1988 return __uvc_resume(intf, 0);
1993 return __uvc_resume(intf, 1);
2000 static int uvc_clock_param_get(
char *buffer,
struct kernel_param *kp)
2003 return sprintf(buffer,
"CLOCK_MONOTONIC");
2005 return sprintf(buffer,
"CLOCK_REALTIME");
2008 static int uvc_clock_param_set(
const char *
val,
struct kernel_param *kp)
2046 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2047 | USB_DEVICE_ID_MATCH_INT_INFO,
2049 .idProduct = 0xa91a,
2051 .bInterfaceSubClass = 1,
2052 .bInterfaceProtocol = 0,
2055 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2056 | USB_DEVICE_ID_MATCH_INT_INFO,
2058 .idProduct = 0x706e,
2060 .bInterfaceSubClass = 1,
2061 .bInterfaceProtocol = 0,
2064 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2065 | USB_DEVICE_ID_MATCH_INT_INFO,
2067 .idProduct = 0x00f8,
2069 .bInterfaceSubClass = 1,
2070 .bInterfaceProtocol = 0,
2073 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2074 | USB_DEVICE_ID_MATCH_INT_INFO,
2076 .idProduct = 0x0723,
2078 .bInterfaceSubClass = 1,
2079 .bInterfaceProtocol = 0,
2082 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2083 | USB_DEVICE_ID_MATCH_INT_INFO,
2085 .idProduct = 0x08c1,
2087 .bInterfaceSubClass = 1,
2088 .bInterfaceProtocol = 0 },
2090 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2091 | USB_DEVICE_ID_MATCH_INT_INFO,
2093 .idProduct = 0x08c2,
2095 .bInterfaceSubClass = 1,
2096 .bInterfaceProtocol = 0 },
2098 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2099 | USB_DEVICE_ID_MATCH_INT_INFO,
2101 .idProduct = 0x08c3,
2103 .bInterfaceSubClass = 1,
2104 .bInterfaceProtocol = 0 },
2106 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2107 | USB_DEVICE_ID_MATCH_INT_INFO,
2109 .idProduct = 0x08c5,
2111 .bInterfaceSubClass = 1,
2112 .bInterfaceProtocol = 0 },
2114 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2115 | USB_DEVICE_ID_MATCH_INT_INFO,
2117 .idProduct = 0x08c6,
2119 .bInterfaceSubClass = 1,
2120 .bInterfaceProtocol = 0 },
2122 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2123 | USB_DEVICE_ID_MATCH_INT_INFO,
2125 .idProduct = 0x08c7,
2127 .bInterfaceSubClass = 1,
2128 .bInterfaceProtocol = 0 },
2130 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2131 | USB_DEVICE_ID_MATCH_INT_INFO,
2133 .idProduct = 0xb071,
2135 .bInterfaceSubClass = 1,
2136 .bInterfaceProtocol = 0,
2139 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2140 | USB_DEVICE_ID_MATCH_INT_INFO,
2142 .idProduct = 0x3820,
2144 .bInterfaceSubClass = 1,
2145 .bInterfaceProtocol = 0,
2148 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2149 | USB_DEVICE_ID_MATCH_INT_INFO,
2151 .idProduct = 0x2640,
2153 .bInterfaceSubClass = 1,
2154 .bInterfaceProtocol = 0,
2157 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2158 | USB_DEVICE_ID_MATCH_INT_INFO,
2160 .idProduct = 0x8501,
2162 .bInterfaceSubClass = 1,
2163 .bInterfaceProtocol = 0,
2167 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2168 | USB_DEVICE_ID_MATCH_INT_INFO,
2170 .idProduct = 0x0403,
2172 .bInterfaceSubClass = 1,
2173 .bInterfaceProtocol = 0,
2176 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2177 | USB_DEVICE_ID_MATCH_INT_INFO,
2179 .idProduct = 0x0505,
2181 .bInterfaceSubClass = 1,
2182 .bInterfaceProtocol = 0,
2185 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2186 | USB_DEVICE_ID_MATCH_INT_INFO,
2188 .idProduct = 0x300c,
2190 .bInterfaceSubClass = 1,
2191 .bInterfaceProtocol = 0,
2194 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2195 | USB_DEVICE_ID_MATCH_INT_INFO,
2197 .idProduct = 0x332d,
2199 .bInterfaceSubClass = 1,
2200 .bInterfaceProtocol = 0,
2203 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2204 | USB_DEVICE_ID_MATCH_INT_INFO,
2206 .idProduct = 0x3410,
2208 .bInterfaceSubClass = 1,
2209 .bInterfaceProtocol = 0,
2212 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2213 | USB_DEVICE_ID_MATCH_INT_INFO,
2215 .idProduct = 0x3420,
2217 .bInterfaceSubClass = 1,
2218 .bInterfaceProtocol = 0,
2221 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2222 | USB_DEVICE_ID_MATCH_INT_INFO,
2224 .idProduct = 0x0555,
2226 .bInterfaceSubClass = 1,
2227 .bInterfaceProtocol = 0,
2230 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2231 | USB_DEVICE_ID_MATCH_INT_INFO,
2233 .idProduct = 0x0004,
2235 .bInterfaceSubClass = 1,
2236 .bInterfaceProtocol = 0,
2240 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2241 | USB_DEVICE_ID_MATCH_INT_INFO,
2243 .idProduct = 0x5103,
2245 .bInterfaceSubClass = 1,
2246 .bInterfaceProtocol = 0,
2249 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2250 | USB_DEVICE_ID_MATCH_INT_INFO,
2252 .idProduct = 0x0310,
2254 .bInterfaceSubClass = 1,
2255 .bInterfaceProtocol = 0,
2258 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2259 | USB_DEVICE_ID_MATCH_INT_INFO,
2261 .idProduct = 0x5212,
2263 .bInterfaceSubClass = 1,
2264 .bInterfaceProtocol = 0,
2267 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2268 | USB_DEVICE_ID_MATCH_INT_INFO,
2270 .idProduct = 0x5931,
2272 .bInterfaceSubClass = 1,
2273 .bInterfaceProtocol = 0,
2276 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2277 | USB_DEVICE_ID_MATCH_INT_INFO,
2279 .idProduct = 0x8a12,
2281 .bInterfaceSubClass = 1,
2282 .bInterfaceProtocol = 0,
2285 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2286 | USB_DEVICE_ID_MATCH_INT_INFO,
2288 .idProduct = 0x8a31,
2290 .bInterfaceSubClass = 1,
2291 .bInterfaceProtocol = 0,
2294 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2295 | USB_DEVICE_ID_MATCH_INT_INFO,
2297 .idProduct = 0x8a33,
2299 .bInterfaceSubClass = 1,
2300 .bInterfaceProtocol = 0,
2303 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2304 | USB_DEVICE_ID_MATCH_INT_INFO,
2306 .idProduct = 0x8a34,
2308 .bInterfaceSubClass = 1,
2309 .bInterfaceProtocol = 0,
2312 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2313 | USB_DEVICE_ID_MATCH_INT_INFO,
2315 .idProduct = 0x0202,
2317 .bInterfaceSubClass = 1,
2318 .bInterfaceProtocol = 0,
2321 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2322 | USB_DEVICE_ID_MATCH_INT_INFO,
2324 .idProduct = 0x480b,
2326 .bInterfaceSubClass = 1,
2327 .bInterfaceProtocol = 0,
2330 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2331 | USB_DEVICE_ID_MATCH_INT_INFO,
2333 .idProduct = 0x0306,
2335 .bInterfaceSubClass = 1,
2336 .bInterfaceProtocol = 0,
2340 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2341 | USB_DEVICE_ID_MATCH_INT_INFO,
2343 .idProduct = 0xcafe,
2345 .bInterfaceSubClass = 1,
2346 .bInterfaceProtocol = 0,
2349 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2350 | USB_DEVICE_ID_MATCH_INT_INFO,
2352 .idProduct = 0x3188,
2354 .bInterfaceSubClass = 1,
2355 .bInterfaceProtocol = 0,
2358 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2359 | USB_DEVICE_ID_MATCH_INT_INFO,
2361 .idProduct = 0x3288,
2363 .bInterfaceSubClass = 1,
2364 .bInterfaceProtocol = 0,
2367 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2368 | USB_DEVICE_ID_MATCH_INT_INFO,
2370 .idProduct = 0x3290,
2372 .bInterfaceSubClass = 1,
2373 .bInterfaceProtocol = 0,
2376 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2377 | USB_DEVICE_ID_MATCH_INT_INFO,
2379 .idProduct = 0x8102,
2381 .bInterfaceSubClass = 1,
2382 .bInterfaceProtocol = 0 },
2384 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2386 | USB_DEVICE_ID_MATCH_INT_INFO,
2388 .idProduct = 0x1000,
2389 .bcdDevice_hi = 0x0126,
2391 .bInterfaceSubClass = 1,
2392 .bInterfaceProtocol = 0,
2395 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2396 | USB_DEVICE_ID_MATCH_INT_INFO,
2398 .idProduct = 0x2951,
2400 .bInterfaceSubClass = 1,
2401 .bInterfaceProtocol = 0,
2404 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2405 | USB_DEVICE_ID_MATCH_INT_INFO,
2407 .idProduct = 0x3000,
2409 .bInterfaceSubClass = 1,
2410 .bInterfaceProtocol = 0,
2424 .disconnect = uvc_disconnect,
2425 .suspend = uvc_suspend,
2426 .resume = uvc_resume,
2427 .reset_resume = uvc_reset_resume,
2428 .id_table = uvc_ids,
2429 .supports_autosuspend = 1,
2433 static int __init uvc_init(
void)
2439 ret = usb_register(&uvc_driver.
driver);
2449 static void __exit uvc_cleanup(
void)