1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26#include <linux/kernel.h>
27#include <linux/list.h>
28#include <linux/module.h>
29#include <linux/slab.h>
30#include <linux/usb.h>
31#include <linux/videodev2.h>
32#include <linux/vmalloc.h>
33#include <linux/wait.h>
34#include <linux/version.h>
35#include <asm/atomic.h>
36#include <asm/unaligned.h>
37
38#include <media/v4l2-common.h>
39
40#include "uvcvideo.h"
41
42#define DRIVER_AUTHOR "Laurent Pinchart " \
43 "<laurent.pinchart@ideasonboard.com>"
44#define DRIVER_DESC "USB Video Class driver"
45
46unsigned int uvc_clock_param = CLOCK_MONOTONIC;
47unsigned int uvc_no_drop_param;
48static unsigned int uvc_quirks_param = -1;
49unsigned int uvc_trace_param;
50unsigned int uvc_timeout_param = UVC_CTRL_STREAMING_TIMEOUT;
51
52
53
54
55
56static struct uvc_format_desc uvc_fmts[] = {
57 {
58 .name = "YUV 4:2:2 (YUYV)",
59 .guid = UVC_GUID_FORMAT_YUY2,
60 .fcc = V4L2_PIX_FMT_YUYV,
61 },
62 {
63 .name = "YUV 4:2:2 (YUYV)",
64 .guid = UVC_GUID_FORMAT_YUY2_ISIGHT,
65 .fcc = V4L2_PIX_FMT_YUYV,
66 },
67 {
68 .name = "YUV 4:2:0 (NV12)",
69 .guid = UVC_GUID_FORMAT_NV12,
70 .fcc = V4L2_PIX_FMT_NV12,
71 },
72 {
73 .name = "MJPEG",
74 .guid = UVC_GUID_FORMAT_MJPEG,
75 .fcc = V4L2_PIX_FMT_MJPEG,
76 },
77 {
78 .name = "YVU 4:2:0 (YV12)",
79 .guid = UVC_GUID_FORMAT_YV12,
80 .fcc = V4L2_PIX_FMT_YVU420,
81 },
82 {
83 .name = "YUV 4:2:0 (I420)",
84 .guid = UVC_GUID_FORMAT_I420,
85 .fcc = V4L2_PIX_FMT_YUV420,
86 },
87 {
88 .name = "YUV 4:2:0 (M420)",
89 .guid = UVC_GUID_FORMAT_M420,
90 .fcc = V4L2_PIX_FMT_M420,
91 },
92 {
93 .name = "YUV 4:2:2 (UYVY)",
94 .guid = UVC_GUID_FORMAT_UYVY,
95 .fcc = V4L2_PIX_FMT_UYVY,
96 },
97 {
98 .name = "Greyscale (8-bit)",
99 .guid = UVC_GUID_FORMAT_Y800,
100 .fcc = V4L2_PIX_FMT_GREY,
101 },
102 {
103 .name = "Greyscale (16-bit)",
104 .guid = UVC_GUID_FORMAT_Y16,
105 .fcc = V4L2_PIX_FMT_Y16,
106 },
107 {
108 .name = "RGB Bayer",
109 .guid = UVC_GUID_FORMAT_BY8,
110 .fcc = V4L2_PIX_FMT_SBGGR8,
111 },
112 {
113 .name = "RGB565",
114 .guid = UVC_GUID_FORMAT_RGBP,
115 .fcc = V4L2_PIX_FMT_RGB565,
116 },
117 {
118 .name = "H.264",
119 .guid = UVC_GUID_FORMAT_H264,
120 .fcc = V4L2_PIX_FMT_H264,
121 },
122};
123
124
125
126
127
128struct usb_host_endpoint *uvc_find_endpoint(struct usb_host_interface *alts,
129 __u8 epaddr)
130{
131 struct usb_host_endpoint *ep;
132 unsigned int i;
133
134 for (i = 0; i < alts->desc.bNumEndpoints; ++i) {
135 ep = &alts->endpoint[i];
136 if (ep->desc.bEndpointAddress == epaddr)
137 return ep;
138 }
139
140 return NULL;
141}
142
143static struct uvc_format_desc *uvc_format_by_guid(const __u8 guid[16])
144{
145 unsigned int len = ARRAY_SIZE(uvc_fmts);
146 unsigned int i;
147
148 for (i = 0; i < len; ++i) {
149 if (memcmp(guid, uvc_fmts[i].guid, 16) == 0)
150 return &uvc_fmts[i];
151 }
152
153 return NULL;
154}
155
156static __u32 uvc_colorspace(const __u8 primaries)
157{
158 static const __u8 colorprimaries[] = {
159 0,
160 V4L2_COLORSPACE_SRGB,
161 V4L2_COLORSPACE_470_SYSTEM_M,
162 V4L2_COLORSPACE_470_SYSTEM_BG,
163 V4L2_COLORSPACE_SMPTE170M,
164 V4L2_COLORSPACE_SMPTE240M,
165 };
166
167 if (primaries < ARRAY_SIZE(colorprimaries))
168 return colorprimaries[primaries];
169
170 return 0;
171}
172
173
174
175
176
177
178
179
180void uvc_simplify_fraction(uint32_t *numerator, uint32_t *denominator,
181 unsigned int n_terms, unsigned int threshold)
182{
183 uint32_t *an;
184 uint32_t x, y, r;
185 unsigned int i, n;
186
187 an = kmalloc(n_terms * sizeof *an, GFP_KERNEL);
188 if (an == NULL)
189 return;
190
191
192
193
194
195
196 x = *numerator;
197 y = *denominator;
198
199 for (n = 0; n < n_terms && y != 0; ++n) {
200 an[n] = x / y;
201 if (an[n] >= threshold) {
202 if (n < 2)
203 n++;
204 break;
205 }
206
207 r = x - an[n] * y;
208 x = y;
209 y = r;
210 }
211
212
213 x = 0;
214 y = 1;
215
216 for (i = n; i > 0; --i) {
217 r = y;
218 y = an[i-1] * y + x;
219 x = r;
220 }
221
222 *numerator = y;
223 *denominator = x;
224 kfree(an);
225}
226
227
228
229
230
231uint32_t uvc_fraction_to_interval(uint32_t numerator, uint32_t denominator)
232{
233 uint32_t multiplier;
234
235
236 if (denominator == 0 ||
237 numerator/denominator >= ((uint32_t)-1)/10000000)
238 return (uint32_t)-1;
239
240
241
242
243
244 multiplier = 10000000;
245 while (numerator > ((uint32_t)-1)/multiplier) {
246 multiplier /= 2;
247 denominator /= 2;
248 }
249
250 return denominator ? numerator * multiplier / denominator : 0;
251}
252
253
254
255
256
257struct uvc_entity *uvc_entity_by_id(struct uvc_device *dev, int id)
258{
259 struct uvc_entity *entity;
260
261 list_for_each_entry(entity, &dev->entities, list) {
262 if (entity->id == id)
263 return entity;
264 }
265
266 return NULL;
267}
268
269static struct uvc_entity *uvc_entity_by_reference(struct uvc_device *dev,
270 int id, struct uvc_entity *entity)
271{
272 unsigned int i;
273
274 if (entity == NULL)
275 entity = list_entry(&dev->entities, struct uvc_entity, list);
276
277 list_for_each_entry_continue(entity, &dev->entities, list) {
278 for (i = 0; i < entity->bNrInPins; ++i)
279 if (entity->baSourceID[i] == id)
280 return entity;
281 }
282
283 return NULL;
284}
285
286static struct uvc_streaming *uvc_stream_by_id(struct uvc_device *dev, int id)
287{
288 struct uvc_streaming *stream;
289
290 list_for_each_entry(stream, &dev->streams, list) {
291 if (stream->header.bTerminalLink == id)
292 return stream;
293 }
294
295 return NULL;
296}
297
298
299
300
301
302static int uvc_parse_format(struct uvc_device *dev,
303 struct uvc_streaming *streaming, struct uvc_format *format,
304 __u32 **intervals, unsigned char *buffer, int buflen)
305{
306 struct usb_interface *intf = streaming->intf;
307 struct usb_host_interface *alts = intf->cur_altsetting;
308 struct uvc_format_desc *fmtdesc;
309 struct uvc_frame *frame;
310 const unsigned char *start = buffer;
311 unsigned int interval;
312 unsigned int i, n;
313 __u8 ftype;
314
315 format->type = buffer[2];
316 format->index = buffer[3];
317
318 switch (buffer[2]) {
319 case UVC_VS_FORMAT_UNCOMPRESSED:
320 case UVC_VS_FORMAT_FRAME_BASED:
321 n = buffer[2] == UVC_VS_FORMAT_UNCOMPRESSED ? 27 : 28;
322 if (buflen < n) {
323 uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
324 "interface %d FORMAT error\n",
325 dev->udev->devnum,
326 alts->desc.bInterfaceNumber);
327 return -EINVAL;
328 }
329
330
331 fmtdesc = uvc_format_by_guid(&buffer[5]);
332
333 if (fmtdesc != NULL) {
334 strlcpy(format->name, fmtdesc->name,
335 sizeof format->name);
336 format->fcc = fmtdesc->fcc;
337 } else {
338 uvc_printk(KERN_INFO, "Unknown video format %pUl\n",
339 &buffer[5]);
340 snprintf(format->name, sizeof(format->name), "%pUl\n",
341 &buffer[5]);
342 format->fcc = 0;
343 }
344
345 format->bpp = buffer[21];
346 if (buffer[2] == UVC_VS_FORMAT_UNCOMPRESSED) {
347 ftype = UVC_VS_FRAME_UNCOMPRESSED;
348 } else {
349 ftype = UVC_VS_FRAME_FRAME_BASED;
350 if (buffer[27])
351 format->flags = UVC_FMT_FLAG_COMPRESSED;
352 }
353 break;
354
355 case UVC_VS_FORMAT_MJPEG:
356 if (buflen < 11) {
357 uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
358 "interface %d FORMAT error\n",
359 dev->udev->devnum,
360 alts->desc.bInterfaceNumber);
361 return -EINVAL;
362 }
363
364 strlcpy(format->name, "MJPEG", sizeof format->name);
365 format->fcc = V4L2_PIX_FMT_MJPEG;
366 format->flags = UVC_FMT_FLAG_COMPRESSED;
367 format->bpp = 0;
368 ftype = UVC_VS_FRAME_MJPEG;
369 break;
370
371 case UVC_VS_FORMAT_DV:
372 if (buflen < 9) {
373 uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
374 "interface %d FORMAT error\n",
375 dev->udev->devnum,
376 alts->desc.bInterfaceNumber);
377 return -EINVAL;
378 }
379
380 switch (buffer[8] & 0x7f) {
381 case 0:
382 strlcpy(format->name, "SD-DV", sizeof format->name);
383 break;
384 case 1:
385 strlcpy(format->name, "SDL-DV", sizeof format->name);
386 break;
387 case 2:
388 strlcpy(format->name, "HD-DV", sizeof format->name);
389 break;
390 default:
391 uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
392 "interface %d: unknown DV format %u\n",
393 dev->udev->devnum,
394 alts->desc.bInterfaceNumber, buffer[8]);
395 return -EINVAL;
396 }
397
398 strlcat(format->name, buffer[8] & (1 << 7) ? " 60Hz" : " 50Hz",
399 sizeof format->name);
400
401 format->fcc = V4L2_PIX_FMT_DV;
402 format->flags = UVC_FMT_FLAG_COMPRESSED | UVC_FMT_FLAG_STREAM;
403 format->bpp = 0;
404 ftype = 0;
405
406
407 frame = &format->frame[0];
408 memset(&format->frame[0], 0, sizeof format->frame[0]);
409 frame->bFrameIntervalType = 1;
410 frame->dwDefaultFrameInterval = 1;
411 frame->dwFrameInterval = *intervals;
412 *(*intervals)++ = 1;
413 format->nframes = 1;
414 break;
415
416 case UVC_VS_FORMAT_MPEG2TS:
417 case UVC_VS_FORMAT_STREAM_BASED:
418
419 default:
420 uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
421 "interface %d unsupported format %u\n",
422 dev->udev->devnum, alts->desc.bInterfaceNumber,
423 buffer[2]);
424 return -EINVAL;
425 }
426
427 uvc_trace(UVC_TRACE_DESCR, "Found format %s.\n", format->name);
428
429 buflen -= buffer[0];
430 buffer += buffer[0];
431
432
433
434
435 while (buflen > 2 && buffer[1] == USB_DT_CS_INTERFACE &&
436 buffer[2] == ftype) {
437 frame = &format->frame[format->nframes];
438 if (ftype != UVC_VS_FRAME_FRAME_BASED)
439 n = buflen > 25 ? buffer[25] : 0;
440 else
441 n = buflen > 21 ? buffer[21] : 0;
442
443 n = n ? n : 3;
444
445 if (buflen < 26 + 4*n) {
446 uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
447 "interface %d FRAME error\n", dev->udev->devnum,
448 alts->desc.bInterfaceNumber);
449 return -EINVAL;
450 }
451
452 frame->bFrameIndex = buffer[3];
453 frame->bmCapabilities = buffer[4];
454 frame->wWidth = get_unaligned_le16(&buffer[5]);
455 frame->wHeight = get_unaligned_le16(&buffer[7]);
456 frame->dwMinBitRate = get_unaligned_le32(&buffer[9]);
457 frame->dwMaxBitRate = get_unaligned_le32(&buffer[13]);
458 if (ftype != UVC_VS_FRAME_FRAME_BASED) {
459 frame->dwMaxVideoFrameBufferSize =
460 get_unaligned_le32(&buffer[17]);
461 frame->dwDefaultFrameInterval =
462 get_unaligned_le32(&buffer[21]);
463 frame->bFrameIntervalType = buffer[25];
464 } else {
465 frame->dwMaxVideoFrameBufferSize = 0;
466 frame->dwDefaultFrameInterval =
467 get_unaligned_le32(&buffer[17]);
468 frame->bFrameIntervalType = buffer[21];
469 }
470 frame->dwFrameInterval = *intervals;
471
472
473
474
475
476
477
478
479
480 if (!(format->flags & UVC_FMT_FLAG_COMPRESSED))
481 frame->dwMaxVideoFrameBufferSize = format->bpp
482 * frame->wWidth * frame->wHeight / 8;
483
484
485
486
487
488
489 for (i = 0; i < n; ++i) {
490 interval = get_unaligned_le32(&buffer[26+4*i]);
491 *(*intervals)++ = interval ? interval : 1;
492 }
493
494
495
496
497 n -= frame->bFrameIntervalType ? 1 : 2;
498 frame->dwDefaultFrameInterval =
499 min(frame->dwFrameInterval[n],
500 max(frame->dwFrameInterval[0],
501 frame->dwDefaultFrameInterval));
502
503 if (dev->quirks & UVC_QUIRK_RESTRICT_FRAME_RATE) {
504 frame->bFrameIntervalType = 1;
505 frame->dwFrameInterval[0] =
506 frame->dwDefaultFrameInterval;
507 }
508
509 uvc_trace(UVC_TRACE_DESCR, "- %ux%u (%u.%u fps)\n",
510 frame->wWidth, frame->wHeight,
511 10000000/frame->dwDefaultFrameInterval,
512 (100000000/frame->dwDefaultFrameInterval)%10);
513
514 format->nframes++;
515 buflen -= buffer[0];
516 buffer += buffer[0];
517 }
518
519 if (buflen > 2 && buffer[1] == USB_DT_CS_INTERFACE &&
520 buffer[2] == UVC_VS_STILL_IMAGE_FRAME) {
521 buflen -= buffer[0];
522 buffer += buffer[0];
523 }
524
525 if (buflen > 2 && buffer[1] == USB_DT_CS_INTERFACE &&
526 buffer[2] == UVC_VS_COLORFORMAT) {
527 if (buflen < 6) {
528 uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
529 "interface %d COLORFORMAT error\n",
530 dev->udev->devnum,
531 alts->desc.bInterfaceNumber);
532 return -EINVAL;
533 }
534
535 format->colorspace = uvc_colorspace(buffer[3]);
536
537 buflen -= buffer[0];
538 buffer += buffer[0];
539 }
540
541 return buffer - start;
542}
543
544static int uvc_parse_streaming(struct uvc_device *dev,
545 struct usb_interface *intf)
546{
547 struct uvc_streaming *streaming = NULL;
548 struct uvc_format *format;
549 struct uvc_frame *frame;
550 struct usb_host_interface *alts = &intf->altsetting[0];
551 unsigned char *_buffer, *buffer = alts->extra;
552 int _buflen, buflen = alts->extralen;
553 unsigned int nformats = 0, nframes = 0, nintervals = 0;
554 unsigned int size, i, n, p;
555 __u32 *interval;
556 __u16 psize;
557 int ret = -EINVAL;
558
559 if (intf->cur_altsetting->desc.bInterfaceSubClass
560 != UVC_SC_VIDEOSTREAMING) {
561 uvc_trace(UVC_TRACE_DESCR, "device %d interface %d isn't a "
562 "video streaming interface\n", dev->udev->devnum,
563 intf->altsetting[0].desc.bInterfaceNumber);
564 return -EINVAL;
565 }
566
567 if (usb_driver_claim_interface(&uvc_driver.driver, intf, dev)) {
568 uvc_trace(UVC_TRACE_DESCR, "device %d interface %d is already "
569 "claimed\n", dev->udev->devnum,
570 intf->altsetting[0].desc.bInterfaceNumber);
571 return -EINVAL;
572 }
573
574 streaming = kzalloc(sizeof *streaming, GFP_KERNEL);
575 if (streaming == NULL) {
576 usb_driver_release_interface(&uvc_driver.driver, intf);
577 return -EINVAL;
578 }
579
580 mutex_init(&streaming->mutex);
581 streaming->dev = dev;
582 streaming->intf = usb_get_intf(intf);
583 streaming->intfnum = intf->cur_altsetting->desc.bInterfaceNumber;
584
585
586
587
588 if (buflen == 0) {
589 for (i = 0; i < alts->desc.bNumEndpoints; ++i) {
590 struct usb_host_endpoint *ep = &alts->endpoint[i];
591
592 if (ep->extralen == 0)
593 continue;
594
595 if (ep->extralen > 2 &&
596 ep->extra[1] == USB_DT_CS_INTERFACE) {
597 uvc_trace(UVC_TRACE_DESCR, "trying extra data "
598 "from endpoint %u.\n", i);
599 buffer = alts->endpoint[i].extra;
600 buflen = alts->endpoint[i].extralen;
601 break;
602 }
603 }
604 }
605
606
607 while (buflen > 2 && buffer[1] != USB_DT_CS_INTERFACE) {
608 buflen -= buffer[0];
609 buffer += buffer[0];
610 }
611
612 if (buflen <= 2) {
613 uvc_trace(UVC_TRACE_DESCR, "no class-specific streaming "
614 "interface descriptors found.\n");
615 goto error;
616 }
617
618
619 switch (buffer[2]) {
620 case UVC_VS_OUTPUT_HEADER:
621 streaming->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
622 size = 9;
623 break;
624
625 case UVC_VS_INPUT_HEADER:
626 streaming->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
627 size = 13;
628 break;
629
630 default:
631 uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming interface "
632 "%d HEADER descriptor not found.\n", dev->udev->devnum,
633 alts->desc.bInterfaceNumber);
634 goto error;
635 }
636
637 p = buflen >= 4 ? buffer[3] : 0;
638 n = buflen >= size ? buffer[size-1] : 0;
639
640 if (buflen < size + p*n) {
641 uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
642 "interface %d HEADER descriptor is invalid.\n",
643 dev->udev->devnum, alts->desc.bInterfaceNumber);
644 goto error;
645 }
646
647 streaming->header.bNumFormats = p;
648 streaming->header.bEndpointAddress = buffer[6];
649 if (buffer[2] == UVC_VS_INPUT_HEADER) {
650 streaming->header.bmInfo = buffer[7];
651 streaming->header.bTerminalLink = buffer[8];
652 streaming->header.bStillCaptureMethod = buffer[9];
653 streaming->header.bTriggerSupport = buffer[10];
654 streaming->header.bTriggerUsage = buffer[11];
655 } else {
656 streaming->header.bTerminalLink = buffer[7];
657 }
658 streaming->header.bControlSize = n;
659
660 streaming->header.bmaControls = kmemdup(&buffer[size], p * n,
661 GFP_KERNEL);
662 if (streaming->header.bmaControls == NULL) {
663 ret = -ENOMEM;
664 goto error;
665 }
666
667 buflen -= buffer[0];
668 buffer += buffer[0];
669
670 _buffer = buffer;
671 _buflen = buflen;
672
673
674 while (_buflen > 2 && _buffer[1] == USB_DT_CS_INTERFACE) {
675 switch (_buffer[2]) {
676 case UVC_VS_FORMAT_UNCOMPRESSED:
677 case UVC_VS_FORMAT_MJPEG:
678 case UVC_VS_FORMAT_FRAME_BASED:
679 nformats++;
680 break;
681
682 case UVC_VS_FORMAT_DV:
683
684
685
686 nformats++;
687 nframes++;
688 nintervals++;
689 break;
690
691 case UVC_VS_FORMAT_MPEG2TS:
692 case UVC_VS_FORMAT_STREAM_BASED:
693 uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
694 "interface %d FORMAT %u is not supported.\n",
695 dev->udev->devnum,
696 alts->desc.bInterfaceNumber, _buffer[2]);
697 break;
698
699 case UVC_VS_FRAME_UNCOMPRESSED:
700 case UVC_VS_FRAME_MJPEG:
701 nframes++;
702 if (_buflen > 25)
703 nintervals += _buffer[25] ? _buffer[25] : 3;
704 break;
705
706 case UVC_VS_FRAME_FRAME_BASED:
707 nframes++;
708 if (_buflen > 21)
709 nintervals += _buffer[21] ? _buffer[21] : 3;
710 break;
711 }
712
713 _buflen -= _buffer[0];
714 _buffer += _buffer[0];
715 }
716
717 if (nformats == 0) {
718 uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming interface "
719 "%d has no supported formats defined.\n",
720 dev->udev->devnum, alts->desc.bInterfaceNumber);
721 goto error;
722 }
723
724 size = nformats * sizeof *format + nframes * sizeof *frame
725 + nintervals * sizeof *interval;
726 format = kzalloc(size, GFP_KERNEL);
727 if (format == NULL) {
728 ret = -ENOMEM;
729 goto error;
730 }
731
732 frame = (struct uvc_frame *)&format[nformats];
733 interval = (__u32 *)&frame[nframes];
734
735 streaming->format = format;
736 streaming->nformats = nformats;
737
738
739 while (buflen > 2 && buffer[1] == USB_DT_CS_INTERFACE) {
740 switch (buffer[2]) {
741 case UVC_VS_FORMAT_UNCOMPRESSED:
742 case UVC_VS_FORMAT_MJPEG:
743 case UVC_VS_FORMAT_DV:
744 case UVC_VS_FORMAT_FRAME_BASED:
745 format->frame = frame;
746 ret = uvc_parse_format(dev, streaming, format,
747 &interval, buffer, buflen);
748 if (ret < 0)
749 goto error;
750
751 frame += format->nframes;
752 format++;
753
754 buflen -= ret;
755 buffer += ret;
756 continue;
757
758 default:
759 break;
760 }
761
762 buflen -= buffer[0];
763 buffer += buffer[0];
764 }
765
766 if (buflen)
767 uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming interface "
768 "%d has %u bytes of trailing descriptor garbage.\n",
769 dev->udev->devnum, alts->desc.bInterfaceNumber, buflen);
770
771
772 for (i = 0; i < intf->num_altsetting; ++i) {
773 struct usb_host_endpoint *ep;
774 alts = &intf->altsetting[i];
775 ep = uvc_find_endpoint(alts,
776 streaming->header.bEndpointAddress);
777 if (ep == NULL)
778 continue;
779
780 psize = le16_to_cpu(ep->desc.wMaxPacketSize);
781 psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3));
782 if (psize > streaming->maxpsize)
783 streaming->maxpsize = psize;
784 }
785
786 list_add_tail(&streaming->list, &dev->streams);
787 return 0;
788
789error:
790 usb_driver_release_interface(&uvc_driver.driver, intf);
791 usb_put_intf(intf);
792 kfree(streaming->format);
793 kfree(streaming->header.bmaControls);
794 kfree(streaming);
795 return ret;
796}
797
798static struct uvc_entity *uvc_alloc_entity(u16 type, u8 id,
799 unsigned int num_pads, unsigned int extra_size)
800{
801 struct uvc_entity *entity;
802 unsigned int num_inputs;
803 unsigned int size;
804 unsigned int i;
805
806 extra_size = ALIGN(extra_size, sizeof(*entity->pads));
807 num_inputs = (type & UVC_TERM_OUTPUT) ? num_pads : num_pads - 1;
808 size = sizeof(*entity) + extra_size + sizeof(*entity->pads) * num_pads
809 + num_inputs;
810 entity = kzalloc(size, GFP_KERNEL);
811 if (entity == NULL)
812 return NULL;
813
814 entity->id = id;
815 entity->type = type;
816
817 entity->num_links = 0;
818 entity->num_pads = num_pads;
819 entity->pads = ((void *)(entity + 1)) + extra_size;
820
821 for (i = 0; i < num_inputs; ++i)
822 entity->pads[i].flags = MEDIA_PAD_FL_SINK;
823 if (!UVC_ENTITY_IS_OTERM(entity))
824 entity->pads[num_pads-1].flags = MEDIA_PAD_FL_SOURCE;
825
826 entity->bNrInPins = num_inputs;
827 entity->baSourceID = (__u8 *)(&entity->pads[num_pads]);
828
829 return entity;
830}
831
832
833static int uvc_parse_vendor_control(struct uvc_device *dev,
834 const unsigned char *buffer, int buflen)
835{
836 struct usb_device *udev = dev->udev;
837 struct usb_host_interface *alts = dev->intf->cur_altsetting;
838 struct uvc_entity *unit;
839 unsigned int n, p;
840 int handled = 0;
841
842 switch (le16_to_cpu(dev->udev->descriptor.idVendor)) {
843 case 0x046d:
844 if (buffer[1] != 0x41 || buffer[2] != 0x01)
845 break;
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873 p = buflen >= 22 ? buffer[21] : 0;
874 n = buflen >= 25 + p ? buffer[22+p] : 0;
875
876 if (buflen < 25 + p + 2*n) {
877 uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol "
878 "interface %d EXTENSION_UNIT error\n",
879 udev->devnum, alts->desc.bInterfaceNumber);
880 break;
881 }
882
883 unit = uvc_alloc_entity(UVC_VC_EXTENSION_UNIT, buffer[3],
884 p + 1, 2*n);
885 if (unit == NULL)
886 return -ENOMEM;
887
888 memcpy(unit->extension.guidExtensionCode, &buffer[4], 16);
889 unit->extension.bNumControls = buffer[20];
890 memcpy(unit->baSourceID, &buffer[22], p);
891 unit->extension.bControlSize = buffer[22+p];
892 unit->extension.bmControls = (__u8 *)unit + sizeof(*unit);
893 unit->extension.bmControlsType = (__u8 *)unit + sizeof(*unit)
894 + n;
895 memcpy(unit->extension.bmControls, &buffer[23+p], 2*n);
896
897 if (buffer[24+p+2*n] != 0)
898 usb_string(udev, buffer[24+p+2*n], unit->name,
899 sizeof unit->name);
900 else
901 sprintf(unit->name, "Extension %u", buffer[3]);
902
903 list_add_tail(&unit->list, &dev->entities);
904 handled = 1;
905 break;
906 }
907
908 return handled;
909}
910
911static int uvc_parse_standard_control(struct uvc_device *dev,
912 const unsigned char *buffer, int buflen)
913{
914 struct usb_device *udev = dev->udev;
915 struct uvc_entity *unit, *term;
916 struct usb_interface *intf;
917 struct usb_host_interface *alts = dev->intf->cur_altsetting;
918 unsigned int i, n, p, len;
919 __u16 type;
920
921 switch (buffer[2]) {
922 case UVC_VC_HEADER:
923 n = buflen >= 12 ? buffer[11] : 0;
924
925 if (buflen < 12 || buflen < 12 + n) {
926 uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol "
927 "interface %d HEADER error\n", udev->devnum,
928 alts->desc.bInterfaceNumber);
929 return -EINVAL;
930 }
931
932 dev->uvc_version = get_unaligned_le16(&buffer[3]);
933 dev->clock_frequency = get_unaligned_le32(&buffer[7]);
934
935
936 for (i = 0; i < n; ++i) {
937 intf = usb_ifnum_to_if(udev, buffer[12+i]);
938 if (intf == NULL) {
939 uvc_trace(UVC_TRACE_DESCR, "device %d "
940 "interface %d doesn't exists\n",
941 udev->devnum, i);
942 continue;
943 }
944
945 uvc_parse_streaming(dev, intf);
946 }
947 break;
948
949 case UVC_VC_INPUT_TERMINAL:
950 if (buflen < 8) {
951 uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol "
952 "interface %d INPUT_TERMINAL error\n",
953 udev->devnum, alts->desc.bInterfaceNumber);
954 return -EINVAL;
955 }
956
957
958
959
960 type = get_unaligned_le16(&buffer[4]);
961 if ((type & 0xff00) == 0) {
962 uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol "
963 "interface %d INPUT_TERMINAL %d has invalid "
964 "type 0x%04x, skipping\n", udev->devnum,
965 alts->desc.bInterfaceNumber,
966 buffer[3], type);
967 return 0;
968 }
969
970 n = 0;
971 p = 0;
972 len = 8;
973
974 if (type == UVC_ITT_CAMERA) {
975 n = buflen >= 15 ? buffer[14] : 0;
976 len = 15;
977
978 } else if (type == UVC_ITT_MEDIA_TRANSPORT_INPUT) {
979 n = buflen >= 9 ? buffer[8] : 0;
980 p = buflen >= 10 + n ? buffer[9+n] : 0;
981 len = 10;
982 }
983
984 if (buflen < len + n + p) {
985 uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol "
986 "interface %d INPUT_TERMINAL error\n",
987 udev->devnum, alts->desc.bInterfaceNumber);
988 return -EINVAL;
989 }
990
991 term = uvc_alloc_entity(type | UVC_TERM_INPUT, buffer[3],
992 1, n + p);
993 if (term == NULL)
994 return -ENOMEM;
995
996 if (UVC_ENTITY_TYPE(term) == UVC_ITT_CAMERA) {
997 term->camera.bControlSize = n;
998 term->camera.bmControls = (__u8 *)term + sizeof *term;
999 term->camera.wObjectiveFocalLengthMin =
1000 get_unaligned_le16(&buffer[8]);
1001 term->camera.wObjectiveFocalLengthMax =
1002 get_unaligned_le16(&buffer[10]);
1003 term->camera.wOcularFocalLength =
1004 get_unaligned_le16(&buffer[12]);
1005 memcpy(term->camera.bmControls, &buffer[15], n);
1006 } else if (UVC_ENTITY_TYPE(term) ==
1007 UVC_ITT_MEDIA_TRANSPORT_INPUT) {
1008 term->media.bControlSize = n;
1009 term->media.bmControls = (__u8 *)term + sizeof *term;
1010 term->media.bTransportModeSize = p;
1011 term->media.bmTransportModes = (__u8 *)term
1012 + sizeof *term + n;
1013 memcpy(term->media.bmControls, &buffer[9], n);
1014 memcpy(term->media.bmTransportModes, &buffer[10+n], p);
1015 }
1016
1017 if (buffer[7] != 0)
1018 usb_string(udev, buffer[7], term->name,
1019 sizeof term->name);
1020 else if (UVC_ENTITY_TYPE(term) == UVC_ITT_CAMERA)
1021 sprintf(term->name, "Camera %u", buffer[3]);
1022 else if (UVC_ENTITY_TYPE(term) == UVC_ITT_MEDIA_TRANSPORT_INPUT)
1023 sprintf(term->name, "Media %u", buffer[3]);
1024 else
1025 sprintf(term->name, "Input %u", buffer[3]);
1026
1027 list_add_tail(&term->list, &dev->entities);
1028 break;
1029
1030 case UVC_VC_OUTPUT_TERMINAL:
1031 if (buflen < 9) {
1032 uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol "
1033 "interface %d OUTPUT_TERMINAL error\n",
1034 udev->devnum, alts->desc.bInterfaceNumber);
1035 return -EINVAL;
1036 }
1037
1038
1039
1040
1041 type = get_unaligned_le16(&buffer[4]);
1042 if ((type & 0xff00) == 0) {
1043 uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol "
1044 "interface %d OUTPUT_TERMINAL %d has invalid "
1045 "type 0x%04x, skipping\n", udev->devnum,
1046 alts->desc.bInterfaceNumber, buffer[3], type);
1047 return 0;
1048 }
1049
1050 term = uvc_alloc_entity(type | UVC_TERM_OUTPUT, buffer[3],
1051 1, 0);
1052 if (term == NULL)
1053 return -ENOMEM;
1054
1055 memcpy(term->baSourceID, &buffer[7], 1);
1056
1057 if (buffer[8] != 0)
1058 usb_string(udev, buffer[8], term->name,
1059 sizeof term->name);
1060 else
1061 sprintf(term->name, "Output %u", buffer[3]);
1062
1063 list_add_tail(&term->list, &dev->entities);
1064 break;
1065
1066 case UVC_VC_SELECTOR_UNIT:
1067 p = buflen >= 5 ? buffer[4] : 0;
1068
1069 if (buflen < 5 || buflen < 6 + p) {
1070 uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol "
1071 "interface %d SELECTOR_UNIT error\n",
1072 udev->devnum, alts->desc.bInterfaceNumber);
1073 return -EINVAL;
1074 }
1075
1076 unit = uvc_alloc_entity(buffer[2], buffer[3], p + 1, 0);
1077 if (unit == NULL)
1078 return -ENOMEM;
1079
1080 memcpy(unit->baSourceID, &buffer[5], p);
1081
1082 if (buffer[5+p] != 0)
1083 usb_string(udev, buffer[5+p], unit->name,
1084 sizeof unit->name);
1085 else
1086 sprintf(unit->name, "Selector %u", buffer[3]);
1087
1088 list_add_tail(&unit->list, &dev->entities);
1089 break;
1090
1091 case UVC_VC_PROCESSING_UNIT:
1092 n = buflen >= 8 ? buffer[7] : 0;
1093 p = dev->uvc_version >= 0x0110 ? 10 : 9;
1094
1095 if (buflen < p + n) {
1096 uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol "
1097 "interface %d PROCESSING_UNIT error\n",
1098 udev->devnum, alts->desc.bInterfaceNumber);
1099 return -EINVAL;
1100 }
1101
1102 unit = uvc_alloc_entity(buffer[2], buffer[3], 2, n);
1103 if (unit == NULL)
1104 return -ENOMEM;
1105
1106 memcpy(unit->baSourceID, &buffer[4], 1);
1107 unit->processing.wMaxMultiplier =
1108 get_unaligned_le16(&buffer[5]);
1109 unit->processing.bControlSize = buffer[7];
1110 unit->processing.bmControls = (__u8 *)unit + sizeof *unit;
1111 memcpy(unit->processing.bmControls, &buffer[8], n);
1112 if (dev->uvc_version >= 0x0110)
1113 unit->processing.bmVideoStandards = buffer[9+n];
1114
1115 if (buffer[8+n] != 0)
1116 usb_string(udev, buffer[8+n], unit->name,
1117 sizeof unit->name);
1118 else
1119 sprintf(unit->name, "Processing %u", buffer[3]);
1120
1121 list_add_tail(&unit->list, &dev->entities);
1122 break;
1123
1124 case UVC_VC_EXTENSION_UNIT:
1125 p = buflen >= 22 ? buffer[21] : 0;
1126 n = buflen >= 24 + p ? buffer[22+p] : 0;
1127
1128 if (buflen < 24 + p + n) {
1129 uvc_trace(UVC_TRACE_DESCR, "device %d videocontrol "
1130 "interface %d EXTENSION_UNIT error\n",
1131 udev->devnum, alts->desc.bInterfaceNumber);
1132 return -EINVAL;
1133 }
1134
1135 unit = uvc_alloc_entity(buffer[2], buffer[3], p + 1, n);
1136 if (unit == NULL)
1137 return -ENOMEM;
1138
1139 memcpy(unit->extension.guidExtensionCode, &buffer[4], 16);
1140 unit->extension.bNumControls = buffer[20];
1141 memcpy(unit->baSourceID, &buffer[22], p);
1142 unit->extension.bControlSize = buffer[22+p];
1143 unit->extension.bmControls = (__u8 *)unit + sizeof *unit;
1144 memcpy(unit->extension.bmControls, &buffer[23+p], n);
1145
1146 if (buffer[23+p+n] != 0)
1147 usb_string(udev, buffer[23+p+n], unit->name,
1148 sizeof unit->name);
1149 else
1150 sprintf(unit->name, "Extension %u", buffer[3]);
1151
1152 list_add_tail(&unit->list, &dev->entities);
1153 break;
1154
1155 default:
1156 uvc_trace(UVC_TRACE_DESCR, "Found an unknown CS_INTERFACE "
1157 "descriptor (%u)\n", buffer[2]);
1158 break;
1159 }
1160
1161 return 0;
1162}
1163
1164static int uvc_parse_control(struct uvc_device *dev)
1165{
1166 struct usb_host_interface *alts = dev->intf->cur_altsetting;
1167 unsigned char *buffer = alts->extra;
1168 int buflen = alts->extralen;
1169 int ret;
1170
1171
1172
1173
1174
1175
1176 while (buflen > 2) {
1177 if (uvc_parse_vendor_control(dev, buffer, buflen) ||
1178 buffer[1] != USB_DT_CS_INTERFACE)
1179 goto next_descriptor;
1180
1181 if ((ret = uvc_parse_standard_control(dev, buffer, buflen)) < 0)
1182 return ret;
1183
1184next_descriptor:
1185 buflen -= buffer[0];
1186 buffer += buffer[0];
1187 }
1188
1189
1190
1191
1192
1193
1194 if (alts->desc.bNumEndpoints == 1 &&
1195 !(dev->quirks & UVC_QUIRK_BUILTIN_ISIGHT)) {
1196 struct usb_host_endpoint *ep = &alts->endpoint[0];
1197 struct usb_endpoint_descriptor *desc = &ep->desc;
1198
1199 if (usb_endpoint_is_int_in(desc) &&
1200 le16_to_cpu(desc->wMaxPacketSize) >= 8 &&
1201 desc->bInterval != 0) {
1202 uvc_trace(UVC_TRACE_DESCR, "Found a Status endpoint "
1203 "(addr %02x).\n", desc->bEndpointAddress);
1204 dev->int_ep = ep;
1205 }
1206 }
1207
1208 return 0;
1209}
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241static int uvc_scan_chain_entity(struct uvc_video_chain *chain,
1242 struct uvc_entity *entity)
1243{
1244 switch (UVC_ENTITY_TYPE(entity)) {
1245 case UVC_VC_EXTENSION_UNIT:
1246 if (uvc_trace_param & UVC_TRACE_PROBE)
1247 printk(" <- XU %d", entity->id);
1248
1249 if (entity->bNrInPins != 1) {
1250 uvc_trace(UVC_TRACE_DESCR, "Extension unit %d has more "
1251 "than 1 input pin.\n", entity->id);
1252 return -1;
1253 }
1254
1255 break;
1256
1257 case UVC_VC_PROCESSING_UNIT:
1258 if (uvc_trace_param & UVC_TRACE_PROBE)
1259 printk(" <- PU %d", entity->id);
1260
1261 if (chain->processing != NULL) {
1262 uvc_trace(UVC_TRACE_DESCR, "Found multiple "
1263 "Processing Units in chain.\n");
1264 return -1;
1265 }
1266
1267 chain->processing = entity;
1268 break;
1269
1270 case UVC_VC_SELECTOR_UNIT:
1271 if (uvc_trace_param & UVC_TRACE_PROBE)
1272 printk(" <- SU %d", entity->id);
1273
1274
1275 if (entity->bNrInPins == 1)
1276 break;
1277
1278 if (chain->selector != NULL) {
1279 uvc_trace(UVC_TRACE_DESCR, "Found multiple Selector "
1280 "Units in chain.\n");
1281 return -1;
1282 }
1283
1284 chain->selector = entity;
1285 break;
1286
1287 case UVC_ITT_VENDOR_SPECIFIC:
1288 case UVC_ITT_CAMERA:
1289 case UVC_ITT_MEDIA_TRANSPORT_INPUT:
1290 if (uvc_trace_param & UVC_TRACE_PROBE)
1291 printk(" <- IT %d\n", entity->id);
1292
1293 break;
1294
1295 case UVC_OTT_VENDOR_SPECIFIC:
1296 case UVC_OTT_DISPLAY:
1297 case UVC_OTT_MEDIA_TRANSPORT_OUTPUT:
1298 if (uvc_trace_param & UVC_TRACE_PROBE)
1299 printk(" OT %d", entity->id);
1300
1301 break;
1302
1303 case UVC_TT_STREAMING:
1304 if (UVC_ENTITY_IS_ITERM(entity)) {
1305 if (uvc_trace_param & UVC_TRACE_PROBE)
1306 printk(" <- IT %d\n", entity->id);
1307 } else {
1308 if (uvc_trace_param & UVC_TRACE_PROBE)
1309 printk(" OT %d", entity->id);
1310 }
1311
1312 break;
1313
1314 default:
1315 uvc_trace(UVC_TRACE_DESCR, "Unsupported entity type "
1316 "0x%04x found in chain.\n", UVC_ENTITY_TYPE(entity));
1317 return -1;
1318 }
1319
1320 list_add_tail(&entity->chain, &chain->entities);
1321 return 0;
1322}
1323
1324static int uvc_scan_chain_forward(struct uvc_video_chain *chain,
1325 struct uvc_entity *entity, struct uvc_entity *prev)
1326{
1327 struct uvc_entity *forward;
1328 int found;
1329
1330
1331 forward = NULL;
1332 found = 0;
1333
1334 while (1) {
1335 forward = uvc_entity_by_reference(chain->dev, entity->id,
1336 forward);
1337 if (forward == NULL)
1338 break;
1339 if (forward == prev)
1340 continue;
1341
1342 switch (UVC_ENTITY_TYPE(forward)) {
1343 case UVC_VC_EXTENSION_UNIT:
1344 if (forward->bNrInPins != 1) {
1345 uvc_trace(UVC_TRACE_DESCR, "Extension unit %d "
1346 "has more than 1 input pin.\n",
1347 entity->id);
1348 return -EINVAL;
1349 }
1350
1351 list_add_tail(&forward->chain, &chain->entities);
1352 if (uvc_trace_param & UVC_TRACE_PROBE) {
1353 if (!found)
1354 printk(" (->");
1355
1356 printk(" XU %d", forward->id);
1357 found = 1;
1358 }
1359 break;
1360
1361 case UVC_OTT_VENDOR_SPECIFIC:
1362 case UVC_OTT_DISPLAY:
1363 case UVC_OTT_MEDIA_TRANSPORT_OUTPUT:
1364 case UVC_TT_STREAMING:
1365 if (UVC_ENTITY_IS_ITERM(forward)) {
1366 uvc_trace(UVC_TRACE_DESCR, "Unsupported input "
1367 "terminal %u.\n", forward->id);
1368 return -EINVAL;
1369 }
1370
1371 list_add_tail(&forward->chain, &chain->entities);
1372 if (uvc_trace_param & UVC_TRACE_PROBE) {
1373 if (!found)
1374 printk(" (->");
1375
1376 printk(" OT %d", forward->id);
1377 found = 1;
1378 }
1379 break;
1380 }
1381 }
1382 if (found)
1383 printk(")");
1384
1385 return 0;
1386}
1387
1388static int uvc_scan_chain_backward(struct uvc_video_chain *chain,
1389 struct uvc_entity **_entity)
1390{
1391 struct uvc_entity *entity = *_entity;
1392 struct uvc_entity *term;
1393 int id = -EINVAL, i;
1394
1395 switch (UVC_ENTITY_TYPE(entity)) {
1396 case UVC_VC_EXTENSION_UNIT:
1397 case UVC_VC_PROCESSING_UNIT:
1398 id = entity->baSourceID[0];
1399 break;
1400
1401 case UVC_VC_SELECTOR_UNIT:
1402
1403 if (entity->bNrInPins == 1) {
1404 id = entity->baSourceID[0];
1405 break;
1406 }
1407
1408 if (uvc_trace_param & UVC_TRACE_PROBE)
1409 printk(" <- IT");
1410
1411 chain->selector = entity;
1412 for (i = 0; i < entity->bNrInPins; ++i) {
1413 id = entity->baSourceID[i];
1414 term = uvc_entity_by_id(chain->dev, id);
1415 if (term == NULL || !UVC_ENTITY_IS_ITERM(term)) {
1416 uvc_trace(UVC_TRACE_DESCR, "Selector unit %d "
1417 "input %d isn't connected to an "
1418 "input terminal\n", entity->id, i);
1419 return -1;
1420 }
1421
1422 if (uvc_trace_param & UVC_TRACE_PROBE)
1423 printk(" %d", term->id);
1424
1425 list_add_tail(&term->chain, &chain->entities);
1426 uvc_scan_chain_forward(chain, term, entity);
1427 }
1428
1429 if (uvc_trace_param & UVC_TRACE_PROBE)
1430 printk("\n");
1431
1432 id = 0;
1433 break;
1434
1435 case UVC_ITT_VENDOR_SPECIFIC:
1436 case UVC_ITT_CAMERA:
1437 case UVC_ITT_MEDIA_TRANSPORT_INPUT:
1438 case UVC_OTT_VENDOR_SPECIFIC:
1439 case UVC_OTT_DISPLAY:
1440 case UVC_OTT_MEDIA_TRANSPORT_OUTPUT:
1441 case UVC_TT_STREAMING:
1442 id = UVC_ENTITY_IS_OTERM(entity) ? entity->baSourceID[0] : 0;
1443 break;
1444 }
1445
1446 if (id <= 0) {
1447 *_entity = NULL;
1448 return id;
1449 }
1450
1451 entity = uvc_entity_by_id(chain->dev, id);
1452 if (entity == NULL) {
1453 uvc_trace(UVC_TRACE_DESCR, "Found reference to "
1454 "unknown entity %d.\n", id);
1455 return -EINVAL;
1456 }
1457
1458 *_entity = entity;
1459 return 0;
1460}
1461
1462static int uvc_scan_chain(struct uvc_video_chain *chain,
1463 struct uvc_entity *term)
1464{
1465 struct uvc_entity *entity, *prev;
1466
1467 uvc_trace(UVC_TRACE_PROBE, "Scanning UVC chain:");
1468
1469 entity = term;
1470 prev = NULL;
1471
1472 while (entity != NULL) {
1473
1474 if (entity->chain.next || entity->chain.prev) {
1475 uvc_trace(UVC_TRACE_DESCR, "Found reference to "
1476 "entity %d already in chain.\n", entity->id);
1477 return -EINVAL;
1478 }
1479
1480
1481 if (uvc_scan_chain_entity(chain, entity) < 0)
1482 return -EINVAL;
1483
1484
1485 if (uvc_scan_chain_forward(chain, entity, prev) < 0)
1486 return -EINVAL;
1487
1488
1489 prev = entity;
1490 if (uvc_scan_chain_backward(chain, &entity) < 0)
1491 return -EINVAL;
1492 }
1493
1494 return 0;
1495}
1496
1497static unsigned int uvc_print_terms(struct list_head *terms, u16 dir,
1498 char *buffer)
1499{
1500 struct uvc_entity *term;
1501 unsigned int nterms = 0;
1502 char *p = buffer;
1503
1504 list_for_each_entry(term, terms, chain) {
1505 if (!UVC_ENTITY_IS_TERM(term) ||
1506 UVC_TERM_DIRECTION(term) != dir)
1507 continue;
1508
1509 if (nterms)
1510 p += sprintf(p, ",");
1511 if (++nterms >= 4) {
1512 p += sprintf(p, "...");
1513 break;
1514 }
1515 p += sprintf(p, "%u", term->id);
1516 }
1517
1518 return p - buffer;
1519}
1520
1521static const char *uvc_print_chain(struct uvc_video_chain *chain)
1522{
1523 static char buffer[43];
1524 char *p = buffer;
1525
1526 p += uvc_print_terms(&chain->entities, UVC_TERM_INPUT, p);
1527 p += sprintf(p, " -> ");
1528 uvc_print_terms(&chain->entities, UVC_TERM_OUTPUT, p);
1529
1530 return buffer;
1531}
1532
1533
1534
1535
1536
1537
1538static int uvc_scan_device(struct uvc_device *dev)
1539{
1540 struct uvc_video_chain *chain;
1541 struct uvc_entity *term;
1542
1543 list_for_each_entry(term, &dev->entities, list) {
1544 if (!UVC_ENTITY_IS_OTERM(term))
1545 continue;
1546
1547
1548
1549
1550
1551
1552 if (term->chain.next || term->chain.prev)
1553 continue;
1554
1555 chain = kzalloc(sizeof(*chain), GFP_KERNEL);
1556 if (chain == NULL)
1557 return -ENOMEM;
1558
1559 INIT_LIST_HEAD(&chain->entities);
1560 mutex_init(&chain->ctrl_mutex);
1561 chain->dev = dev;
1562
1563 if (uvc_scan_chain(chain, term) < 0) {
1564 kfree(chain);
1565 continue;
1566 }
1567
1568 uvc_trace(UVC_TRACE_PROBE, "Found a valid video chain (%s).\n",
1569 uvc_print_chain(chain));
1570
1571 list_add_tail(&chain->list, &dev->chains);
1572 }
1573
1574 if (list_empty(&dev->chains)) {
1575 uvc_printk(KERN_INFO, "No valid video chain found.\n");
1576 return -1;
1577 }
1578
1579 return 0;
1580}
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596static void uvc_delete(struct uvc_device *dev)
1597{
1598 struct list_head *p, *n;
1599
1600 usb_put_intf(dev->intf);
1601 usb_put_dev(dev->udev);
1602
1603 uvc_status_cleanup(dev);
1604 uvc_ctrl_cleanup_device(dev);
1605
1606 if (dev->vdev.dev)
1607 v4l2_device_unregister(&dev->vdev);
1608#ifdef CONFIG_MEDIA_CONTROLLER
1609 if (media_devnode_is_registered(&dev->mdev.devnode))
1610 media_device_unregister(&dev->mdev);
1611#endif
1612
1613 list_for_each_safe(p, n, &dev->chains) {
1614 struct uvc_video_chain *chain;
1615 chain = list_entry(p, struct uvc_video_chain, list);
1616 kfree(chain);
1617 }
1618
1619 list_for_each_safe(p, n, &dev->entities) {
1620 struct uvc_entity *entity;
1621 entity = list_entry(p, struct uvc_entity, list);
1622#ifdef CONFIG_MEDIA_CONTROLLER
1623 uvc_mc_cleanup_entity(entity);
1624#endif
1625 if (entity->vdev) {
1626 video_device_release(entity->vdev);
1627 entity->vdev = NULL;
1628 }
1629 kfree(entity);
1630 }
1631
1632 list_for_each_safe(p, n, &dev->streams) {
1633 struct uvc_streaming *streaming;
1634 streaming = list_entry(p, struct uvc_streaming, list);
1635 usb_driver_release_interface(&uvc_driver.driver,
1636 streaming->intf);
1637 usb_put_intf(streaming->intf);
1638 kfree(streaming->format);
1639 kfree(streaming->header.bmaControls);
1640 kfree(streaming);
1641 }
1642
1643 kfree(dev);
1644}
1645
1646static void uvc_release(struct video_device *vdev)
1647{
1648 struct uvc_streaming *stream = video_get_drvdata(vdev);
1649 struct uvc_device *dev = stream->dev;
1650
1651
1652
1653
1654 if (atomic_dec_and_test(&dev->nstreams))
1655 uvc_delete(dev);
1656}
1657
1658
1659
1660
1661static void uvc_unregister_video(struct uvc_device *dev)
1662{
1663 struct uvc_streaming *stream;
1664
1665
1666
1667
1668
1669
1670 atomic_inc(&dev->nstreams);
1671
1672 list_for_each_entry(stream, &dev->streams, list) {
1673 if (stream->vdev == NULL)
1674 continue;
1675
1676 video_unregister_device(stream->vdev);
1677 stream->vdev = NULL;
1678 }
1679
1680
1681
1682
1683 if (atomic_dec_and_test(&dev->nstreams))
1684 uvc_delete(dev);
1685}
1686
1687static int uvc_register_video(struct uvc_device *dev,
1688 struct uvc_streaming *stream)
1689{
1690 struct video_device *vdev;
1691 int ret;
1692
1693
1694
1695
1696 ret = uvc_video_init(stream);
1697 if (ret < 0) {
1698 uvc_printk(KERN_ERR, "Failed to initialize the device "
1699 "(%d).\n", ret);
1700 return ret;
1701 }
1702
1703
1704 vdev = video_device_alloc();
1705 if (vdev == NULL) {
1706 uvc_printk(KERN_ERR, "Failed to allocate video device (%d).\n",
1707 ret);
1708 return -ENOMEM;
1709 }
1710
1711
1712
1713
1714
1715 vdev->v4l2_dev = &dev->vdev;
1716 vdev->fops = &uvc_fops;
1717 vdev->release = uvc_release;
1718 strlcpy(vdev->name, dev->name, sizeof vdev->name);
1719
1720
1721
1722
1723 stream->vdev = vdev;
1724 video_set_drvdata(vdev, stream);
1725
1726 ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
1727 if (ret < 0) {
1728 uvc_printk(KERN_ERR, "Failed to register video device (%d).\n",
1729 ret);
1730 stream->vdev = NULL;
1731 video_device_release(vdev);
1732 return ret;
1733 }
1734
1735 atomic_inc(&dev->nstreams);
1736 return 0;
1737}
1738
1739
1740
1741
1742static int uvc_register_terms(struct uvc_device *dev,
1743 struct uvc_video_chain *chain)
1744{
1745 struct uvc_streaming *stream;
1746 struct uvc_entity *term;
1747 int ret;
1748
1749 list_for_each_entry(term, &chain->entities, chain) {
1750 if (UVC_ENTITY_TYPE(term) != UVC_TT_STREAMING)
1751 continue;
1752
1753 stream = uvc_stream_by_id(dev, term->id);
1754 if (stream == NULL) {
1755 uvc_printk(KERN_INFO, "No streaming interface found "
1756 "for terminal %u.", term->id);
1757 continue;
1758 }
1759
1760 stream->chain = chain;
1761 ret = uvc_register_video(dev, stream);
1762 if (ret < 0)
1763 return ret;
1764
1765 term->vdev = stream->vdev;
1766 }
1767
1768 return 0;
1769}
1770
1771static int uvc_register_chains(struct uvc_device *dev)
1772{
1773 struct uvc_video_chain *chain;
1774 int ret;
1775
1776 list_for_each_entry(chain, &dev->chains, list) {
1777 ret = uvc_register_terms(dev, chain);
1778 if (ret < 0)
1779 return ret;
1780
1781#ifdef CONFIG_MEDIA_CONTROLLER
1782 ret = uvc_mc_register_entities(chain);
1783 if (ret < 0) {
1784 uvc_printk(KERN_INFO, "Failed to register entites "
1785 "(%d).\n", ret);
1786 }
1787#endif
1788 }
1789
1790 return 0;
1791}
1792
1793
1794
1795
1796
1797static int uvc_probe(struct usb_interface *intf,
1798 const struct usb_device_id *id)
1799{
1800 struct usb_device *udev = interface_to_usbdev(intf);
1801 struct uvc_device *dev;
1802 int ret;
1803
1804 if (id->idVendor && id->idProduct)
1805 uvc_trace(UVC_TRACE_PROBE, "Probing known UVC device %s "
1806 "(%04x:%04x)\n", udev->devpath, id->idVendor,
1807 id->idProduct);
1808 else
1809 uvc_trace(UVC_TRACE_PROBE, "Probing generic UVC device %s\n",
1810 udev->devpath);
1811
1812
1813 if ((dev = kzalloc(sizeof *dev, GFP_KERNEL)) == NULL)
1814 return -ENOMEM;
1815
1816 INIT_LIST_HEAD(&dev->entities);
1817 INIT_LIST_HEAD(&dev->chains);
1818 INIT_LIST_HEAD(&dev->streams);
1819 atomic_set(&dev->nstreams, 0);
1820 atomic_set(&dev->users, 0);
1821 atomic_set(&dev->nmappings, 0);
1822
1823 dev->udev = usb_get_dev(udev);
1824 dev->intf = usb_get_intf(intf);
1825 dev->intfnum = intf->cur_altsetting->desc.bInterfaceNumber;
1826 dev->quirks = (uvc_quirks_param == -1)
1827 ? id->driver_info : uvc_quirks_param;
1828
1829 if (udev->product != NULL)
1830 strlcpy(dev->name, udev->product, sizeof dev->name);
1831 else
1832 snprintf(dev->name, sizeof dev->name,
1833 "UVC Camera (%04x:%04x)",
1834 le16_to_cpu(udev->descriptor.idVendor),
1835 le16_to_cpu(udev->descriptor.idProduct));
1836
1837
1838 if (uvc_parse_control(dev) < 0) {
1839 uvc_trace(UVC_TRACE_PROBE, "Unable to parse UVC "
1840 "descriptors.\n");
1841 goto error;
1842 }
1843
1844 uvc_printk(KERN_INFO, "Found UVC %u.%02x device %s (%04x:%04x)\n",
1845 dev->uvc_version >> 8, dev->uvc_version & 0xff,
1846 udev->product ? udev->product : "<unnamed>",
1847 le16_to_cpu(udev->descriptor.idVendor),
1848 le16_to_cpu(udev->descriptor.idProduct));
1849
1850 if (dev->quirks != id->driver_info) {
1851 uvc_printk(KERN_INFO, "Forcing device quirks to 0x%x by module "
1852 "parameter for testing purpose.\n", dev->quirks);
1853 uvc_printk(KERN_INFO, "Please report required quirks to the "
1854 "linux-uvc-devel mailing list.\n");
1855 }
1856
1857
1858#ifdef CONFIG_MEDIA_CONTROLLER
1859 dev->mdev.dev = &intf->dev;
1860 strlcpy(dev->mdev.model, dev->name, sizeof(dev->mdev.model));
1861 if (udev->serial)
1862 strlcpy(dev->mdev.serial, udev->serial,
1863 sizeof(dev->mdev.serial));
1864 strcpy(dev->mdev.bus_info, udev->devpath);
1865 dev->mdev.hw_revision = le16_to_cpu(udev->descriptor.bcdDevice);
1866 dev->mdev.driver_version = LINUX_VERSION_CODE;
1867 if (media_device_register(&dev->mdev) < 0)
1868 goto error;
1869
1870 dev->vdev.mdev = &dev->mdev;
1871#endif
1872 if (v4l2_device_register(&intf->dev, &dev->vdev) < 0)
1873 goto error;
1874
1875
1876 if (uvc_ctrl_init_device(dev) < 0)
1877 goto error;
1878
1879
1880 if (uvc_scan_device(dev) < 0)
1881 goto error;
1882
1883
1884 if (uvc_register_chains(dev) < 0)
1885 goto error;
1886
1887
1888 usb_set_intfdata(intf, dev);
1889
1890
1891 if ((ret = uvc_status_init(dev)) < 0) {
1892 uvc_printk(KERN_INFO, "Unable to initialize the status "
1893 "endpoint (%d), status interrupt will not be "
1894 "supported.\n", ret);
1895 }
1896
1897 uvc_trace(UVC_TRACE_PROBE, "UVC device initialized.\n");
1898 usb_enable_autosuspend(udev);
1899 return 0;
1900
1901error:
1902 uvc_unregister_video(dev);
1903 return -ENODEV;
1904}
1905
1906static void uvc_disconnect(struct usb_interface *intf)
1907{
1908 struct uvc_device *dev = usb_get_intfdata(intf);
1909
1910
1911
1912
1913 usb_set_intfdata(intf, NULL);
1914
1915 if (intf->cur_altsetting->desc.bInterfaceSubClass ==
1916 UVC_SC_VIDEOSTREAMING)
1917 return;
1918
1919 dev->state |= UVC_DEV_DISCONNECTED;
1920
1921 uvc_unregister_video(dev);
1922}
1923
1924static int uvc_suspend(struct usb_interface *intf, pm_message_t message)
1925{
1926 struct uvc_device *dev = usb_get_intfdata(intf);
1927 struct uvc_streaming *stream;
1928
1929 uvc_trace(UVC_TRACE_SUSPEND, "Suspending interface %u\n",
1930 intf->cur_altsetting->desc.bInterfaceNumber);
1931
1932
1933 if (intf->cur_altsetting->desc.bInterfaceSubClass ==
1934 UVC_SC_VIDEOCONTROL)
1935 return uvc_status_suspend(dev);
1936
1937 list_for_each_entry(stream, &dev->streams, list) {
1938 if (stream->intf == intf)
1939 return uvc_video_suspend(stream);
1940 }
1941
1942 uvc_trace(UVC_TRACE_SUSPEND, "Suspend: video streaming USB interface "
1943 "mismatch.\n");
1944 return -EINVAL;
1945}
1946
1947static int __uvc_resume(struct usb_interface *intf, int reset)
1948{
1949 struct uvc_device *dev = usb_get_intfdata(intf);
1950 struct uvc_streaming *stream;
1951
1952 uvc_trace(UVC_TRACE_SUSPEND, "Resuming interface %u\n",
1953 intf->cur_altsetting->desc.bInterfaceNumber);
1954
1955 if (intf->cur_altsetting->desc.bInterfaceSubClass ==
1956 UVC_SC_VIDEOCONTROL) {
1957 if (reset) {
1958 int ret = uvc_ctrl_resume_device(dev);
1959
1960 if (ret < 0)
1961 return ret;
1962 }
1963
1964 return uvc_status_resume(dev);
1965 }
1966
1967 list_for_each_entry(stream, &dev->streams, list) {
1968 if (stream->intf == intf)
1969 return uvc_video_resume(stream, reset);
1970 }
1971
1972 uvc_trace(UVC_TRACE_SUSPEND, "Resume: video streaming USB interface "
1973 "mismatch.\n");
1974 return -EINVAL;
1975}
1976
1977static int uvc_resume(struct usb_interface *intf)
1978{
1979 return __uvc_resume(intf, 0);
1980}
1981
1982static int uvc_reset_resume(struct usb_interface *intf)
1983{
1984 return __uvc_resume(intf, 1);
1985}
1986
1987
1988
1989
1990
1991static int uvc_clock_param_get(char *buffer, struct kernel_param *kp)
1992{
1993 if (uvc_clock_param == CLOCK_MONOTONIC)
1994 return sprintf(buffer, "CLOCK_MONOTONIC");
1995 else
1996 return sprintf(buffer, "CLOCK_REALTIME");
1997}
1998
1999static int uvc_clock_param_set(const char *val, struct kernel_param *kp)
2000{
2001 if (strncasecmp(val, "clock_", strlen("clock_")) == 0)
2002 val += strlen("clock_");
2003
2004 if (strcasecmp(val, "monotonic") == 0)
2005 uvc_clock_param = CLOCK_MONOTONIC;
2006 else if (strcasecmp(val, "realtime") == 0)
2007 uvc_clock_param = CLOCK_REALTIME;
2008 else
2009 return -EINVAL;
2010
2011 return 0;
2012}
2013
2014module_param_call(clock, uvc_clock_param_set, uvc_clock_param_get,
2015 &uvc_clock_param, S_IRUGO|S_IWUSR);
2016MODULE_PARM_DESC(clock, "Video buffers timestamp clock");
2017module_param_named(nodrop, uvc_no_drop_param, uint, S_IRUGO|S_IWUSR);
2018MODULE_PARM_DESC(nodrop, "Don't drop incomplete frames");
2019module_param_named(quirks, uvc_quirks_param, uint, S_IRUGO|S_IWUSR);
2020MODULE_PARM_DESC(quirks, "Forced device quirks");
2021module_param_named(trace, uvc_trace_param, uint, S_IRUGO|S_IWUSR);
2022MODULE_PARM_DESC(trace, "Trace level bitmask");
2023module_param_named(timeout, uvc_timeout_param, uint, S_IRUGO|S_IWUSR);
2024MODULE_PARM_DESC(timeout, "Streaming control requests timeout");
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035static struct usb_device_id uvc_ids[] = {
2036
2037 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2038 | USB_DEVICE_ID_MATCH_INT_INFO,
2039 .idVendor = 0x0458,
2040 .idProduct = 0x706e,
2041 .bInterfaceClass = USB_CLASS_VIDEO,
2042 .bInterfaceSubClass = 1,
2043 .bInterfaceProtocol = 0,
2044 .driver_info = UVC_QUIRK_PROBE_MINMAX },
2045
2046 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2047 | USB_DEVICE_ID_MATCH_INT_INFO,
2048 .idVendor = 0x045e,
2049 .idProduct = 0x00f8,
2050 .bInterfaceClass = USB_CLASS_VIDEO,
2051 .bInterfaceSubClass = 1,
2052 .bInterfaceProtocol = 0,
2053 .driver_info = UVC_QUIRK_PROBE_MINMAX },
2054
2055 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2056 | USB_DEVICE_ID_MATCH_INT_INFO,
2057 .idVendor = 0x045e,
2058 .idProduct = 0x0723,
2059 .bInterfaceClass = USB_CLASS_VIDEO,
2060 .bInterfaceSubClass = 1,
2061 .bInterfaceProtocol = 0,
2062 .driver_info = UVC_QUIRK_PROBE_MINMAX },
2063
2064 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2065 | USB_DEVICE_ID_MATCH_INT_INFO,
2066 .idVendor = 0x046d,
2067 .idProduct = 0x08c1,
2068 .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
2069 .bInterfaceSubClass = 1,
2070 .bInterfaceProtocol = 0 },
2071
2072 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2073 | USB_DEVICE_ID_MATCH_INT_INFO,
2074 .idVendor = 0x046d,
2075 .idProduct = 0x08c2,
2076 .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
2077 .bInterfaceSubClass = 1,
2078 .bInterfaceProtocol = 0 },
2079
2080 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2081 | USB_DEVICE_ID_MATCH_INT_INFO,
2082 .idVendor = 0x046d,
2083 .idProduct = 0x08c3,
2084 .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
2085 .bInterfaceSubClass = 1,
2086 .bInterfaceProtocol = 0 },
2087
2088 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2089 | USB_DEVICE_ID_MATCH_INT_INFO,
2090 .idVendor = 0x046d,
2091 .idProduct = 0x08c5,
2092 .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
2093 .bInterfaceSubClass = 1,
2094 .bInterfaceProtocol = 0 },
2095
2096 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2097 | USB_DEVICE_ID_MATCH_INT_INFO,
2098 .idVendor = 0x046d,
2099 .idProduct = 0x08c6,
2100 .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
2101 .bInterfaceSubClass = 1,
2102 .bInterfaceProtocol = 0 },
2103
2104 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2105 | USB_DEVICE_ID_MATCH_INT_INFO,
2106 .idVendor = 0x046d,
2107 .idProduct = 0x08c7,
2108 .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
2109 .bInterfaceSubClass = 1,
2110 .bInterfaceProtocol = 0 },
2111
2112 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2113 | USB_DEVICE_ID_MATCH_INT_INFO,
2114 .idVendor = 0x04f2,
2115 .idProduct = 0xb071,
2116 .bInterfaceClass = USB_CLASS_VIDEO,
2117 .bInterfaceSubClass = 1,
2118 .bInterfaceProtocol = 0,
2119 .driver_info = UVC_QUIRK_RESTRICT_FRAME_RATE },
2120
2121 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2122 | USB_DEVICE_ID_MATCH_INT_INFO,
2123 .idVendor = 0x058f,
2124 .idProduct = 0x3820,
2125 .bInterfaceClass = USB_CLASS_VIDEO,
2126 .bInterfaceSubClass = 1,
2127 .bInterfaceProtocol = 0,
2128 .driver_info = UVC_QUIRK_PROBE_MINMAX },
2129
2130 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2131 | USB_DEVICE_ID_MATCH_INT_INFO,
2132 .idVendor = 0x05ac,
2133 .idProduct = 0x8501,
2134 .bInterfaceClass = USB_CLASS_VIDEO,
2135 .bInterfaceSubClass = 1,
2136 .bInterfaceProtocol = 0,
2137 .driver_info = UVC_QUIRK_PROBE_MINMAX
2138 | UVC_QUIRK_BUILTIN_ISIGHT },
2139
2140 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2141 | USB_DEVICE_ID_MATCH_INT_INFO,
2142 .idVendor = 0x05c8,
2143 .idProduct = 0x0403,
2144 .bInterfaceClass = USB_CLASS_VIDEO,
2145 .bInterfaceSubClass = 1,
2146 .bInterfaceProtocol = 0,
2147 .driver_info = UVC_QUIRK_FIX_BANDWIDTH },
2148
2149 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2150 | USB_DEVICE_ID_MATCH_INT_INFO,
2151 .idVendor = 0x05e3,
2152 .idProduct = 0x0505,
2153 .bInterfaceClass = USB_CLASS_VIDEO,
2154 .bInterfaceSubClass = 1,
2155 .bInterfaceProtocol = 0,
2156 .driver_info = UVC_QUIRK_STREAM_NO_FID },
2157
2158 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2159 | USB_DEVICE_ID_MATCH_INT_INFO,
2160 .idVendor = 0x06f8,
2161 .idProduct = 0x300c,
2162 .bInterfaceClass = USB_CLASS_VIDEO,
2163 .bInterfaceSubClass = 1,
2164 .bInterfaceProtocol = 0,
2165 .driver_info = UVC_QUIRK_FIX_BANDWIDTH },
2166
2167 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2168 | USB_DEVICE_ID_MATCH_INT_INFO,
2169 .idVendor = 0x0ac8,
2170 .idProduct = 0x332d,
2171 .bInterfaceClass = USB_CLASS_VIDEO,
2172 .bInterfaceSubClass = 1,
2173 .bInterfaceProtocol = 0,
2174 .driver_info = UVC_QUIRK_FIX_BANDWIDTH },
2175
2176 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2177 | USB_DEVICE_ID_MATCH_INT_INFO,
2178 .idVendor = 0x0ac8,
2179 .idProduct = 0x3410,
2180 .bInterfaceClass = USB_CLASS_VIDEO,
2181 .bInterfaceSubClass = 1,
2182 .bInterfaceProtocol = 0,
2183 .driver_info = UVC_QUIRK_FIX_BANDWIDTH },
2184
2185 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2186 | USB_DEVICE_ID_MATCH_INT_INFO,
2187 .idVendor = 0x0ac8,
2188 .idProduct = 0x3420,
2189 .bInterfaceClass = USB_CLASS_VIDEO,
2190 .bInterfaceSubClass = 1,
2191 .bInterfaceProtocol = 0,
2192 .driver_info = UVC_QUIRK_FIX_BANDWIDTH },
2193
2194 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2195 | USB_DEVICE_ID_MATCH_INT_INFO,
2196 .idVendor = 0x0e8d,
2197 .idProduct = 0x0004,
2198 .bInterfaceClass = USB_CLASS_VIDEO,
2199 .bInterfaceSubClass = 1,
2200 .bInterfaceProtocol = 0,
2201 .driver_info = UVC_QUIRK_PROBE_MINMAX
2202 | UVC_QUIRK_PROBE_DEF },
2203
2204 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2205 | USB_DEVICE_ID_MATCH_INT_INFO,
2206 .idVendor = 0x13d3,
2207 .idProduct = 0x5103,
2208 .bInterfaceClass = USB_CLASS_VIDEO,
2209 .bInterfaceSubClass = 1,
2210 .bInterfaceProtocol = 0,
2211 .driver_info = UVC_QUIRK_STREAM_NO_FID },
2212
2213 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2214 | USB_DEVICE_ID_MATCH_INT_INFO,
2215 .idVendor = 0x152d,
2216 .idProduct = 0x0310,
2217 .bInterfaceClass = USB_CLASS_VIDEO,
2218 .bInterfaceSubClass = 1,
2219 .bInterfaceProtocol = 0,
2220 .driver_info = UVC_QUIRK_PROBE_MINMAX },
2221
2222 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2223 | USB_DEVICE_ID_MATCH_INT_INFO,
2224 .idVendor = 0x174f,
2225 .idProduct = 0x5212,
2226 .bInterfaceClass = USB_CLASS_VIDEO,
2227 .bInterfaceSubClass = 1,
2228 .bInterfaceProtocol = 0,
2229 .driver_info = UVC_QUIRK_STREAM_NO_FID },
2230
2231 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2232 | USB_DEVICE_ID_MATCH_INT_INFO,
2233 .idVendor = 0x174f,
2234 .idProduct = 0x5931,
2235 .bInterfaceClass = USB_CLASS_VIDEO,
2236 .bInterfaceSubClass = 1,
2237 .bInterfaceProtocol = 0,
2238 .driver_info = UVC_QUIRK_STREAM_NO_FID },
2239
2240 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2241 | USB_DEVICE_ID_MATCH_INT_INFO,
2242 .idVendor = 0x174f,
2243 .idProduct = 0x8a12,
2244 .bInterfaceClass = USB_CLASS_VIDEO,
2245 .bInterfaceSubClass = 1,
2246 .bInterfaceProtocol = 0,
2247 .driver_info = UVC_QUIRK_STREAM_NO_FID },
2248
2249 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2250 | USB_DEVICE_ID_MATCH_INT_INFO,
2251 .idVendor = 0x174f,
2252 .idProduct = 0x8a31,
2253 .bInterfaceClass = USB_CLASS_VIDEO,
2254 .bInterfaceSubClass = 1,
2255 .bInterfaceProtocol = 0,
2256 .driver_info = UVC_QUIRK_STREAM_NO_FID },
2257
2258 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2259 | USB_DEVICE_ID_MATCH_INT_INFO,
2260 .idVendor = 0x174f,
2261 .idProduct = 0x8a33,
2262 .bInterfaceClass = USB_CLASS_VIDEO,
2263 .bInterfaceSubClass = 1,
2264 .bInterfaceProtocol = 0,
2265 .driver_info = UVC_QUIRK_STREAM_NO_FID },
2266
2267 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2268 | USB_DEVICE_ID_MATCH_INT_INFO,
2269 .idVendor = 0x174f,
2270 .idProduct = 0x8a34,
2271 .bInterfaceClass = USB_CLASS_VIDEO,
2272 .bInterfaceSubClass = 1,
2273 .bInterfaceProtocol = 0,
2274 .driver_info = UVC_QUIRK_STREAM_NO_FID },
2275
2276 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2277 | USB_DEVICE_ID_MATCH_INT_INFO,
2278 .idVendor = 0x17dc,
2279 .idProduct = 0x0202,
2280 .bInterfaceClass = USB_CLASS_VIDEO,
2281 .bInterfaceSubClass = 1,
2282 .bInterfaceProtocol = 0,
2283 .driver_info = UVC_QUIRK_STREAM_NO_FID },
2284
2285 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2286 | USB_DEVICE_ID_MATCH_INT_INFO,
2287 .idVendor = 0x17ef,
2288 .idProduct = 0x480b,
2289 .bInterfaceClass = USB_CLASS_VIDEO,
2290 .bInterfaceSubClass = 1,
2291 .bInterfaceProtocol = 0,
2292 .driver_info = UVC_QUIRK_STREAM_NO_FID },
2293
2294 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2295 | USB_DEVICE_ID_MATCH_INT_INFO,
2296 .idVendor = 0x1871,
2297 .idProduct = 0x0306,
2298 .bInterfaceClass = USB_CLASS_VIDEO,
2299 .bInterfaceSubClass = 1,
2300 .bInterfaceProtocol = 0,
2301 .driver_info = UVC_QUIRK_PROBE_MINMAX
2302 | UVC_QUIRK_PROBE_EXTRAFIELDS },
2303
2304 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2305 | USB_DEVICE_ID_MATCH_INT_INFO,
2306 .idVendor = 0x18cd,
2307 .idProduct = 0xcafe,
2308 .bInterfaceClass = USB_CLASS_VIDEO,
2309 .bInterfaceSubClass = 1,
2310 .bInterfaceProtocol = 0,
2311 .driver_info = UVC_QUIRK_PROBE_EXTRAFIELDS },
2312
2313 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2314 | USB_DEVICE_ID_MATCH_INT_INFO,
2315 .idVendor = 0x18ec,
2316 .idProduct = 0x3188,
2317 .bInterfaceClass = USB_CLASS_VIDEO,
2318 .bInterfaceSubClass = 1,
2319 .bInterfaceProtocol = 0,
2320 .driver_info = UVC_QUIRK_PROBE_MINMAX },
2321
2322 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2323 | USB_DEVICE_ID_MATCH_INT_INFO,
2324 .idVendor = 0x18ec,
2325 .idProduct = 0x3288,
2326 .bInterfaceClass = USB_CLASS_VIDEO,
2327 .bInterfaceSubClass = 1,
2328 .bInterfaceProtocol = 0,
2329 .driver_info = UVC_QUIRK_PROBE_MINMAX },
2330
2331 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2332 | USB_DEVICE_ID_MATCH_INT_INFO,
2333 .idVendor = 0x18ec,
2334 .idProduct = 0x3290,
2335 .bInterfaceClass = USB_CLASS_VIDEO,
2336 .bInterfaceSubClass = 1,
2337 .bInterfaceProtocol = 0,
2338 .driver_info = UVC_QUIRK_PROBE_DEF },
2339
2340 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2341 | USB_DEVICE_ID_MATCH_INT_INFO,
2342 .idVendor = 0x199e,
2343 .idProduct = 0x8102,
2344 .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
2345 .bInterfaceSubClass = 1,
2346 .bInterfaceProtocol = 0 },
2347
2348 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2349 | USB_DEVICE_ID_MATCH_DEV_HI
2350 | USB_DEVICE_ID_MATCH_INT_INFO,
2351 .idVendor = 0x19ab,
2352 .idProduct = 0x1000,
2353 .bcdDevice_hi = 0x0126,
2354 .bInterfaceClass = USB_CLASS_VIDEO,
2355 .bInterfaceSubClass = 1,
2356 .bInterfaceProtocol = 0,
2357 .driver_info = UVC_QUIRK_STATUS_INTERVAL },
2358
2359 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2360 | USB_DEVICE_ID_MATCH_INT_INFO,
2361 .idVendor = 0x1b3b,
2362 .idProduct = 0x2951,
2363 .bInterfaceClass = USB_CLASS_VIDEO,
2364 .bInterfaceSubClass = 1,
2365 .bInterfaceProtocol = 0,
2366 .driver_info = UVC_QUIRK_PROBE_MINMAX },
2367
2368 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2369 | USB_DEVICE_ID_MATCH_INT_INFO,
2370 .idVendor = 0x1c4f,
2371 .idProduct = 0x3000,
2372 .bInterfaceClass = USB_CLASS_VIDEO,
2373 .bInterfaceSubClass = 1,
2374 .bInterfaceProtocol = 0,
2375 .driver_info = UVC_QUIRK_PROBE_MINMAX
2376 | UVC_QUIRK_IGNORE_SELECTOR_UNIT },
2377
2378 { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, 0) },
2379 {}
2380};
2381
2382MODULE_DEVICE_TABLE(usb, uvc_ids);
2383
2384struct uvc_driver uvc_driver = {
2385 .driver = {
2386 .name = "uvcvideo",
2387 .probe = uvc_probe,
2388 .disconnect = uvc_disconnect,
2389 .suspend = uvc_suspend,
2390 .resume = uvc_resume,
2391 .reset_resume = uvc_reset_resume,
2392 .id_table = uvc_ids,
2393 .supports_autosuspend = 1,
2394 },
2395};
2396
2397static int __init uvc_init(void)
2398{
2399 int result;
2400
2401 result = usb_register(&uvc_driver.driver);
2402 if (result == 0)
2403 printk(KERN_INFO DRIVER_DESC " (" DRIVER_VERSION ")\n");
2404 return result;
2405}
2406
2407static void __exit uvc_cleanup(void)
2408{
2409 usb_deregister(&uvc_driver.driver);
2410}
2411
2412module_init(uvc_init);
2413module_exit(uvc_cleanup);
2414
2415MODULE_AUTHOR(DRIVER_AUTHOR);
2416MODULE_DESCRIPTION(DRIVER_DESC);
2417MODULE_LICENSE("GPL");
2418MODULE_VERSION(DRIVER_VERSION);
2419
2420