0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/atomic.h>
0010 #include <linux/gpio/consumer.h>
0011 #include <linux/kernel.h>
0012 #include <linux/list.h>
0013 #include <linux/module.h>
0014 #include <linux/slab.h>
0015 #include <linux/usb.h>
0016 #include <linux/videodev2.h>
0017 #include <linux/vmalloc.h>
0018 #include <linux/wait.h>
0019 #include <asm/unaligned.h>
0020
0021 #include <media/v4l2-common.h>
0022 #include <media/v4l2-ioctl.h>
0023
0024 #include "uvcvideo.h"
0025
0026 #define DRIVER_AUTHOR "Laurent Pinchart " \
0027 "<laurent.pinchart@ideasonboard.com>"
0028 #define DRIVER_DESC "USB Video Class driver"
0029
0030 unsigned int uvc_clock_param = CLOCK_MONOTONIC;
0031 unsigned int uvc_hw_timestamps_param;
0032 unsigned int uvc_no_drop_param;
0033 static unsigned int uvc_quirks_param = -1;
0034 unsigned int uvc_dbg_param;
0035 unsigned int uvc_timeout_param = UVC_CTRL_STREAMING_TIMEOUT;
0036
0037
0038
0039
0040
0041 static struct uvc_format_desc uvc_fmts[] = {
0042 {
0043 .name = "YUV 4:2:2 (YUYV)",
0044 .guid = UVC_GUID_FORMAT_YUY2,
0045 .fcc = V4L2_PIX_FMT_YUYV,
0046 },
0047 {
0048 .name = "YUV 4:2:2 (YUYV)",
0049 .guid = UVC_GUID_FORMAT_YUY2_ISIGHT,
0050 .fcc = V4L2_PIX_FMT_YUYV,
0051 },
0052 {
0053 .name = "YUV 4:2:0 (NV12)",
0054 .guid = UVC_GUID_FORMAT_NV12,
0055 .fcc = V4L2_PIX_FMT_NV12,
0056 },
0057 {
0058 .name = "MJPEG",
0059 .guid = UVC_GUID_FORMAT_MJPEG,
0060 .fcc = V4L2_PIX_FMT_MJPEG,
0061 },
0062 {
0063 .name = "YVU 4:2:0 (YV12)",
0064 .guid = UVC_GUID_FORMAT_YV12,
0065 .fcc = V4L2_PIX_FMT_YVU420,
0066 },
0067 {
0068 .name = "YUV 4:2:0 (I420)",
0069 .guid = UVC_GUID_FORMAT_I420,
0070 .fcc = V4L2_PIX_FMT_YUV420,
0071 },
0072 {
0073 .name = "YUV 4:2:0 (M420)",
0074 .guid = UVC_GUID_FORMAT_M420,
0075 .fcc = V4L2_PIX_FMT_M420,
0076 },
0077 {
0078 .name = "YUV 4:2:2 (UYVY)",
0079 .guid = UVC_GUID_FORMAT_UYVY,
0080 .fcc = V4L2_PIX_FMT_UYVY,
0081 },
0082 {
0083 .name = "Greyscale 8-bit (Y800)",
0084 .guid = UVC_GUID_FORMAT_Y800,
0085 .fcc = V4L2_PIX_FMT_GREY,
0086 },
0087 {
0088 .name = "Greyscale 8-bit (Y8 )",
0089 .guid = UVC_GUID_FORMAT_Y8,
0090 .fcc = V4L2_PIX_FMT_GREY,
0091 },
0092 {
0093 .name = "Greyscale 8-bit (D3DFMT_L8)",
0094 .guid = UVC_GUID_FORMAT_D3DFMT_L8,
0095 .fcc = V4L2_PIX_FMT_GREY,
0096 },
0097 {
0098 .name = "IR 8-bit (L8_IR)",
0099 .guid = UVC_GUID_FORMAT_KSMEDIA_L8_IR,
0100 .fcc = V4L2_PIX_FMT_GREY,
0101 },
0102 {
0103 .name = "Greyscale 10-bit (Y10 )",
0104 .guid = UVC_GUID_FORMAT_Y10,
0105 .fcc = V4L2_PIX_FMT_Y10,
0106 },
0107 {
0108 .name = "Greyscale 12-bit (Y12 )",
0109 .guid = UVC_GUID_FORMAT_Y12,
0110 .fcc = V4L2_PIX_FMT_Y12,
0111 },
0112 {
0113 .name = "Greyscale 16-bit (Y16 )",
0114 .guid = UVC_GUID_FORMAT_Y16,
0115 .fcc = V4L2_PIX_FMT_Y16,
0116 },
0117 {
0118 .name = "BGGR Bayer (BY8 )",
0119 .guid = UVC_GUID_FORMAT_BY8,
0120 .fcc = V4L2_PIX_FMT_SBGGR8,
0121 },
0122 {
0123 .name = "BGGR Bayer (BA81)",
0124 .guid = UVC_GUID_FORMAT_BA81,
0125 .fcc = V4L2_PIX_FMT_SBGGR8,
0126 },
0127 {
0128 .name = "GBRG Bayer (GBRG)",
0129 .guid = UVC_GUID_FORMAT_GBRG,
0130 .fcc = V4L2_PIX_FMT_SGBRG8,
0131 },
0132 {
0133 .name = "GRBG Bayer (GRBG)",
0134 .guid = UVC_GUID_FORMAT_GRBG,
0135 .fcc = V4L2_PIX_FMT_SGRBG8,
0136 },
0137 {
0138 .name = "RGGB Bayer (RGGB)",
0139 .guid = UVC_GUID_FORMAT_RGGB,
0140 .fcc = V4L2_PIX_FMT_SRGGB8,
0141 },
0142 {
0143 .name = "RGB565",
0144 .guid = UVC_GUID_FORMAT_RGBP,
0145 .fcc = V4L2_PIX_FMT_RGB565,
0146 },
0147 {
0148 .name = "BGR 8:8:8 (BGR3)",
0149 .guid = UVC_GUID_FORMAT_BGR3,
0150 .fcc = V4L2_PIX_FMT_BGR24,
0151 },
0152 {
0153 .name = "H.264",
0154 .guid = UVC_GUID_FORMAT_H264,
0155 .fcc = V4L2_PIX_FMT_H264,
0156 },
0157 {
0158 .name = "H.265",
0159 .guid = UVC_GUID_FORMAT_H265,
0160 .fcc = V4L2_PIX_FMT_HEVC,
0161 },
0162 {
0163 .name = "Greyscale 8 L/R (Y8I)",
0164 .guid = UVC_GUID_FORMAT_Y8I,
0165 .fcc = V4L2_PIX_FMT_Y8I,
0166 },
0167 {
0168 .name = "Greyscale 12 L/R (Y12I)",
0169 .guid = UVC_GUID_FORMAT_Y12I,
0170 .fcc = V4L2_PIX_FMT_Y12I,
0171 },
0172 {
0173 .name = "Depth data 16-bit (Z16)",
0174 .guid = UVC_GUID_FORMAT_Z16,
0175 .fcc = V4L2_PIX_FMT_Z16,
0176 },
0177 {
0178 .name = "Bayer 10-bit (SRGGB10P)",
0179 .guid = UVC_GUID_FORMAT_RW10,
0180 .fcc = V4L2_PIX_FMT_SRGGB10P,
0181 },
0182 {
0183 .name = "Bayer 16-bit (SBGGR16)",
0184 .guid = UVC_GUID_FORMAT_BG16,
0185 .fcc = V4L2_PIX_FMT_SBGGR16,
0186 },
0187 {
0188 .name = "Bayer 16-bit (SGBRG16)",
0189 .guid = UVC_GUID_FORMAT_GB16,
0190 .fcc = V4L2_PIX_FMT_SGBRG16,
0191 },
0192 {
0193 .name = "Bayer 16-bit (SRGGB16)",
0194 .guid = UVC_GUID_FORMAT_RG16,
0195 .fcc = V4L2_PIX_FMT_SRGGB16,
0196 },
0197 {
0198 .name = "Bayer 16-bit (SGRBG16)",
0199 .guid = UVC_GUID_FORMAT_GR16,
0200 .fcc = V4L2_PIX_FMT_SGRBG16,
0201 },
0202 {
0203 .name = "Depth data 16-bit (Z16)",
0204 .guid = UVC_GUID_FORMAT_INVZ,
0205 .fcc = V4L2_PIX_FMT_Z16,
0206 },
0207 {
0208 .name = "Greyscale 10-bit (Y10 )",
0209 .guid = UVC_GUID_FORMAT_INVI,
0210 .fcc = V4L2_PIX_FMT_Y10,
0211 },
0212 {
0213 .name = "IR:Depth 26-bit (INZI)",
0214 .guid = UVC_GUID_FORMAT_INZI,
0215 .fcc = V4L2_PIX_FMT_INZI,
0216 },
0217 {
0218 .name = "4-bit Depth Confidence (Packed)",
0219 .guid = UVC_GUID_FORMAT_CNF4,
0220 .fcc = V4L2_PIX_FMT_CNF4,
0221 },
0222 {
0223 .name = "HEVC",
0224 .guid = UVC_GUID_FORMAT_HEVC,
0225 .fcc = V4L2_PIX_FMT_HEVC,
0226 },
0227 };
0228
0229
0230
0231
0232
0233 struct usb_host_endpoint *uvc_find_endpoint(struct usb_host_interface *alts,
0234 u8 epaddr)
0235 {
0236 struct usb_host_endpoint *ep;
0237 unsigned int i;
0238
0239 for (i = 0; i < alts->desc.bNumEndpoints; ++i) {
0240 ep = &alts->endpoint[i];
0241 if (ep->desc.bEndpointAddress == epaddr)
0242 return ep;
0243 }
0244
0245 return NULL;
0246 }
0247
0248 static struct uvc_format_desc *uvc_format_by_guid(const u8 guid[16])
0249 {
0250 unsigned int len = ARRAY_SIZE(uvc_fmts);
0251 unsigned int i;
0252
0253 for (i = 0; i < len; ++i) {
0254 if (memcmp(guid, uvc_fmts[i].guid, 16) == 0)
0255 return &uvc_fmts[i];
0256 }
0257
0258 return NULL;
0259 }
0260
0261 static enum v4l2_colorspace uvc_colorspace(const u8 primaries)
0262 {
0263 static const enum v4l2_colorspace colorprimaries[] = {
0264 V4L2_COLORSPACE_SRGB,
0265 V4L2_COLORSPACE_SRGB,
0266 V4L2_COLORSPACE_470_SYSTEM_M,
0267 V4L2_COLORSPACE_470_SYSTEM_BG,
0268 V4L2_COLORSPACE_SMPTE170M,
0269 V4L2_COLORSPACE_SMPTE240M,
0270 };
0271
0272 if (primaries < ARRAY_SIZE(colorprimaries))
0273 return colorprimaries[primaries];
0274
0275 return V4L2_COLORSPACE_SRGB;
0276 }
0277
0278 static enum v4l2_xfer_func uvc_xfer_func(const u8 transfer_characteristics)
0279 {
0280
0281
0282
0283
0284
0285
0286
0287
0288 static const enum v4l2_xfer_func xfer_funcs[] = {
0289 V4L2_XFER_FUNC_DEFAULT,
0290 V4L2_XFER_FUNC_709,
0291 V4L2_XFER_FUNC_709,
0292 V4L2_XFER_FUNC_709,
0293 V4L2_XFER_FUNC_709,
0294 V4L2_XFER_FUNC_SMPTE240M,
0295 V4L2_XFER_FUNC_NONE,
0296 V4L2_XFER_FUNC_SRGB,
0297 };
0298
0299 if (transfer_characteristics < ARRAY_SIZE(xfer_funcs))
0300 return xfer_funcs[transfer_characteristics];
0301
0302 return V4L2_XFER_FUNC_DEFAULT;
0303 }
0304
0305 static enum v4l2_ycbcr_encoding uvc_ycbcr_enc(const u8 matrix_coefficients)
0306 {
0307
0308
0309
0310
0311
0312
0313
0314
0315
0316
0317 static const enum v4l2_ycbcr_encoding ycbcr_encs[] = {
0318 V4L2_YCBCR_ENC_DEFAULT,
0319 V4L2_YCBCR_ENC_709,
0320 V4L2_YCBCR_ENC_601,
0321 V4L2_YCBCR_ENC_601,
0322 V4L2_YCBCR_ENC_601,
0323 V4L2_YCBCR_ENC_SMPTE240M,
0324 };
0325
0326 if (matrix_coefficients < ARRAY_SIZE(ycbcr_encs))
0327 return ycbcr_encs[matrix_coefficients];
0328
0329 return V4L2_YCBCR_ENC_DEFAULT;
0330 }
0331
0332
0333
0334
0335
0336
0337
0338
0339
0340 void uvc_simplify_fraction(u32 *numerator, u32 *denominator,
0341 unsigned int n_terms, unsigned int threshold)
0342 {
0343 u32 *an;
0344 u32 x, y, r;
0345 unsigned int i, n;
0346
0347 an = kmalloc_array(n_terms, sizeof(*an), GFP_KERNEL);
0348 if (an == NULL)
0349 return;
0350
0351
0352
0353
0354
0355
0356
0357 x = *numerator;
0358 y = *denominator;
0359
0360 for (n = 0; n < n_terms && y != 0; ++n) {
0361 an[n] = x / y;
0362 if (an[n] >= threshold) {
0363 if (n < 2)
0364 n++;
0365 break;
0366 }
0367
0368 r = x - an[n] * y;
0369 x = y;
0370 y = r;
0371 }
0372
0373
0374 x = 0;
0375 y = 1;
0376
0377 for (i = n; i > 0; --i) {
0378 r = y;
0379 y = an[i-1] * y + x;
0380 x = r;
0381 }
0382
0383 *numerator = y;
0384 *denominator = x;
0385 kfree(an);
0386 }
0387
0388
0389
0390
0391
0392
0393 u32 uvc_fraction_to_interval(u32 numerator, u32 denominator)
0394 {
0395 u32 multiplier;
0396
0397
0398 if (denominator == 0 ||
0399 numerator/denominator >= ((u32)-1)/10000000)
0400 return (u32)-1;
0401
0402
0403
0404
0405
0406
0407 multiplier = 10000000;
0408 while (numerator > ((u32)-1)/multiplier) {
0409 multiplier /= 2;
0410 denominator /= 2;
0411 }
0412
0413 return denominator ? numerator * multiplier / denominator : 0;
0414 }
0415
0416
0417
0418
0419
0420 struct uvc_entity *uvc_entity_by_id(struct uvc_device *dev, int id)
0421 {
0422 struct uvc_entity *entity;
0423
0424 list_for_each_entry(entity, &dev->entities, list) {
0425 if (entity->id == id)
0426 return entity;
0427 }
0428
0429 return NULL;
0430 }
0431
0432 static struct uvc_entity *uvc_entity_by_reference(struct uvc_device *dev,
0433 int id, struct uvc_entity *entity)
0434 {
0435 unsigned int i;
0436
0437 if (entity == NULL)
0438 entity = list_entry(&dev->entities, struct uvc_entity, list);
0439
0440 list_for_each_entry_continue(entity, &dev->entities, list) {
0441 for (i = 0; i < entity->bNrInPins; ++i)
0442 if (entity->baSourceID[i] == id)
0443 return entity;
0444 }
0445
0446 return NULL;
0447 }
0448
0449 static struct uvc_streaming *uvc_stream_by_id(struct uvc_device *dev, int id)
0450 {
0451 struct uvc_streaming *stream;
0452
0453 list_for_each_entry(stream, &dev->streams, list) {
0454 if (stream->header.bTerminalLink == id)
0455 return stream;
0456 }
0457
0458 return NULL;
0459 }
0460
0461
0462
0463
0464
0465 static void uvc_stream_delete(struct uvc_streaming *stream)
0466 {
0467 if (stream->async_wq)
0468 destroy_workqueue(stream->async_wq);
0469
0470 mutex_destroy(&stream->mutex);
0471
0472 usb_put_intf(stream->intf);
0473
0474 kfree(stream->format);
0475 kfree(stream->header.bmaControls);
0476 kfree(stream);
0477 }
0478
0479 static struct uvc_streaming *uvc_stream_new(struct uvc_device *dev,
0480 struct usb_interface *intf)
0481 {
0482 struct uvc_streaming *stream;
0483
0484 stream = kzalloc(sizeof(*stream), GFP_KERNEL);
0485 if (stream == NULL)
0486 return NULL;
0487
0488 mutex_init(&stream->mutex);
0489
0490 stream->dev = dev;
0491 stream->intf = usb_get_intf(intf);
0492 stream->intfnum = intf->cur_altsetting->desc.bInterfaceNumber;
0493
0494
0495 stream->async_wq = alloc_workqueue("uvcvideo", WQ_UNBOUND | WQ_HIGHPRI,
0496 0);
0497 if (!stream->async_wq) {
0498 uvc_stream_delete(stream);
0499 return NULL;
0500 }
0501
0502 return stream;
0503 }
0504
0505
0506
0507
0508
0509 static int uvc_parse_format(struct uvc_device *dev,
0510 struct uvc_streaming *streaming, struct uvc_format *format,
0511 u32 **intervals, unsigned char *buffer, int buflen)
0512 {
0513 struct usb_interface *intf = streaming->intf;
0514 struct usb_host_interface *alts = intf->cur_altsetting;
0515 struct uvc_format_desc *fmtdesc;
0516 struct uvc_frame *frame;
0517 const unsigned char *start = buffer;
0518 unsigned int width_multiplier = 1;
0519 unsigned int interval;
0520 unsigned int i, n;
0521 u8 ftype;
0522
0523 format->type = buffer[2];
0524 format->index = buffer[3];
0525
0526 switch (buffer[2]) {
0527 case UVC_VS_FORMAT_UNCOMPRESSED:
0528 case UVC_VS_FORMAT_FRAME_BASED:
0529 n = buffer[2] == UVC_VS_FORMAT_UNCOMPRESSED ? 27 : 28;
0530 if (buflen < n) {
0531 uvc_dbg(dev, DESCR,
0532 "device %d videostreaming interface %d FORMAT error\n",
0533 dev->udev->devnum,
0534 alts->desc.bInterfaceNumber);
0535 return -EINVAL;
0536 }
0537
0538
0539 fmtdesc = uvc_format_by_guid(&buffer[5]);
0540
0541 if (fmtdesc != NULL) {
0542 strscpy(format->name, fmtdesc->name,
0543 sizeof(format->name));
0544 format->fcc = fmtdesc->fcc;
0545 } else {
0546 dev_info(&streaming->intf->dev,
0547 "Unknown video format %pUl\n", &buffer[5]);
0548 snprintf(format->name, sizeof(format->name), "%pUl\n",
0549 &buffer[5]);
0550 format->fcc = 0;
0551 }
0552
0553 format->bpp = buffer[21];
0554
0555
0556
0557
0558
0559 if (dev->quirks & UVC_QUIRK_FORCE_Y8) {
0560 if (format->fcc == V4L2_PIX_FMT_YUYV) {
0561 strscpy(format->name, "Greyscale 8-bit (Y8 )",
0562 sizeof(format->name));
0563 format->fcc = V4L2_PIX_FMT_GREY;
0564 format->bpp = 8;
0565 width_multiplier = 2;
0566 }
0567 }
0568
0569
0570 if (dev->quirks & UVC_QUIRK_FORCE_BPP) {
0571 const struct v4l2_format_info *info =
0572 v4l2_format_info(format->fcc);
0573
0574 if (info) {
0575 unsigned int div = info->hdiv * info->vdiv;
0576
0577 n = info->bpp[0] * div;
0578 for (i = 1; i < info->comp_planes; i++)
0579 n += info->bpp[i];
0580
0581 format->bpp = DIV_ROUND_UP(8 * n, div);
0582 }
0583 }
0584
0585 if (buffer[2] == UVC_VS_FORMAT_UNCOMPRESSED) {
0586 ftype = UVC_VS_FRAME_UNCOMPRESSED;
0587 } else {
0588 ftype = UVC_VS_FRAME_FRAME_BASED;
0589 if (buffer[27])
0590 format->flags = UVC_FMT_FLAG_COMPRESSED;
0591 }
0592 break;
0593
0594 case UVC_VS_FORMAT_MJPEG:
0595 if (buflen < 11) {
0596 uvc_dbg(dev, DESCR,
0597 "device %d videostreaming interface %d FORMAT error\n",
0598 dev->udev->devnum,
0599 alts->desc.bInterfaceNumber);
0600 return -EINVAL;
0601 }
0602
0603 strscpy(format->name, "MJPEG", sizeof(format->name));
0604 format->fcc = V4L2_PIX_FMT_MJPEG;
0605 format->flags = UVC_FMT_FLAG_COMPRESSED;
0606 format->bpp = 0;
0607 ftype = UVC_VS_FRAME_MJPEG;
0608 break;
0609
0610 case UVC_VS_FORMAT_DV:
0611 if (buflen < 9) {
0612 uvc_dbg(dev, DESCR,
0613 "device %d videostreaming interface %d FORMAT error\n",
0614 dev->udev->devnum,
0615 alts->desc.bInterfaceNumber);
0616 return -EINVAL;
0617 }
0618
0619 switch (buffer[8] & 0x7f) {
0620 case 0:
0621 strscpy(format->name, "SD-DV", sizeof(format->name));
0622 break;
0623 case 1:
0624 strscpy(format->name, "SDL-DV", sizeof(format->name));
0625 break;
0626 case 2:
0627 strscpy(format->name, "HD-DV", sizeof(format->name));
0628 break;
0629 default:
0630 uvc_dbg(dev, DESCR,
0631 "device %d videostreaming interface %d: unknown DV format %u\n",
0632 dev->udev->devnum,
0633 alts->desc.bInterfaceNumber, buffer[8]);
0634 return -EINVAL;
0635 }
0636
0637 strlcat(format->name, buffer[8] & (1 << 7) ? " 60Hz" : " 50Hz",
0638 sizeof(format->name));
0639
0640 format->fcc = V4L2_PIX_FMT_DV;
0641 format->flags = UVC_FMT_FLAG_COMPRESSED | UVC_FMT_FLAG_STREAM;
0642 format->bpp = 0;
0643 ftype = 0;
0644
0645
0646 frame = &format->frame[0];
0647 memset(&format->frame[0], 0, sizeof(format->frame[0]));
0648 frame->bFrameIntervalType = 1;
0649 frame->dwDefaultFrameInterval = 1;
0650 frame->dwFrameInterval = *intervals;
0651 *(*intervals)++ = 1;
0652 format->nframes = 1;
0653 break;
0654
0655 case UVC_VS_FORMAT_MPEG2TS:
0656 case UVC_VS_FORMAT_STREAM_BASED:
0657
0658 default:
0659 uvc_dbg(dev, DESCR,
0660 "device %d videostreaming interface %d unsupported format %u\n",
0661 dev->udev->devnum, alts->desc.bInterfaceNumber,
0662 buffer[2]);
0663 return -EINVAL;
0664 }
0665
0666 uvc_dbg(dev, DESCR, "Found format %s\n", format->name);
0667
0668 buflen -= buffer[0];
0669 buffer += buffer[0];
0670
0671
0672
0673
0674
0675 while (buflen > 2 && buffer[1] == USB_DT_CS_INTERFACE &&
0676 buffer[2] == ftype) {
0677 frame = &format->frame[format->nframes];
0678 if (ftype != UVC_VS_FRAME_FRAME_BASED)
0679 n = buflen > 25 ? buffer[25] : 0;
0680 else
0681 n = buflen > 21 ? buffer[21] : 0;
0682
0683 n = n ? n : 3;
0684
0685 if (buflen < 26 + 4*n) {
0686 uvc_dbg(dev, DESCR,
0687 "device %d videostreaming interface %d FRAME error\n",
0688 dev->udev->devnum,
0689 alts->desc.bInterfaceNumber);
0690 return -EINVAL;
0691 }
0692
0693 frame->bFrameIndex = buffer[3];
0694 frame->bmCapabilities = buffer[4];
0695 frame->wWidth = get_unaligned_le16(&buffer[5])
0696 * width_multiplier;
0697 frame->wHeight = get_unaligned_le16(&buffer[7]);
0698 frame->dwMinBitRate = get_unaligned_le32(&buffer[9]);
0699 frame->dwMaxBitRate = get_unaligned_le32(&buffer[13]);
0700 if (ftype != UVC_VS_FRAME_FRAME_BASED) {
0701 frame->dwMaxVideoFrameBufferSize =
0702 get_unaligned_le32(&buffer[17]);
0703 frame->dwDefaultFrameInterval =
0704 get_unaligned_le32(&buffer[21]);
0705 frame->bFrameIntervalType = buffer[25];
0706 } else {
0707 frame->dwMaxVideoFrameBufferSize = 0;
0708 frame->dwDefaultFrameInterval =
0709 get_unaligned_le32(&buffer[17]);
0710 frame->bFrameIntervalType = buffer[21];
0711 }
0712 frame->dwFrameInterval = *intervals;
0713
0714
0715
0716
0717
0718
0719
0720
0721
0722
0723 if (!(format->flags & UVC_FMT_FLAG_COMPRESSED))
0724 frame->dwMaxVideoFrameBufferSize = format->bpp
0725 * frame->wWidth * frame->wHeight / 8;
0726
0727
0728
0729
0730
0731
0732
0733 for (i = 0; i < n; ++i) {
0734 interval = get_unaligned_le32(&buffer[26+4*i]);
0735 *(*intervals)++ = interval ? interval : 1;
0736 }
0737
0738
0739
0740
0741
0742 n -= frame->bFrameIntervalType ? 1 : 2;
0743 frame->dwDefaultFrameInterval =
0744 min(frame->dwFrameInterval[n],
0745 max(frame->dwFrameInterval[0],
0746 frame->dwDefaultFrameInterval));
0747
0748 if (dev->quirks & UVC_QUIRK_RESTRICT_FRAME_RATE) {
0749 frame->bFrameIntervalType = 1;
0750 frame->dwFrameInterval[0] =
0751 frame->dwDefaultFrameInterval;
0752 }
0753
0754 uvc_dbg(dev, DESCR, "- %ux%u (%u.%u fps)\n",
0755 frame->wWidth, frame->wHeight,
0756 10000000 / frame->dwDefaultFrameInterval,
0757 (100000000 / frame->dwDefaultFrameInterval) % 10);
0758
0759 format->nframes++;
0760 buflen -= buffer[0];
0761 buffer += buffer[0];
0762 }
0763
0764 if (buflen > 2 && buffer[1] == USB_DT_CS_INTERFACE &&
0765 buffer[2] == UVC_VS_STILL_IMAGE_FRAME) {
0766 buflen -= buffer[0];
0767 buffer += buffer[0];
0768 }
0769
0770 if (buflen > 2 && buffer[1] == USB_DT_CS_INTERFACE &&
0771 buffer[2] == UVC_VS_COLORFORMAT) {
0772 if (buflen < 6) {
0773 uvc_dbg(dev, DESCR,
0774 "device %d videostreaming interface %d COLORFORMAT error\n",
0775 dev->udev->devnum,
0776 alts->desc.bInterfaceNumber);
0777 return -EINVAL;
0778 }
0779
0780 format->colorspace = uvc_colorspace(buffer[3]);
0781 format->xfer_func = uvc_xfer_func(buffer[4]);
0782 format->ycbcr_enc = uvc_ycbcr_enc(buffer[5]);
0783
0784 buflen -= buffer[0];
0785 buffer += buffer[0];
0786 } else {
0787 format->colorspace = V4L2_COLORSPACE_SRGB;
0788 }
0789
0790 return buffer - start;
0791 }
0792
0793 static int uvc_parse_streaming(struct uvc_device *dev,
0794 struct usb_interface *intf)
0795 {
0796 struct uvc_streaming *streaming = NULL;
0797 struct uvc_format *format;
0798 struct uvc_frame *frame;
0799 struct usb_host_interface *alts = &intf->altsetting[0];
0800 unsigned char *_buffer, *buffer = alts->extra;
0801 int _buflen, buflen = alts->extralen;
0802 unsigned int nformats = 0, nframes = 0, nintervals = 0;
0803 unsigned int size, i, n, p;
0804 u32 *interval;
0805 u16 psize;
0806 int ret = -EINVAL;
0807
0808 if (intf->cur_altsetting->desc.bInterfaceSubClass
0809 != UVC_SC_VIDEOSTREAMING) {
0810 uvc_dbg(dev, DESCR,
0811 "device %d interface %d isn't a video streaming interface\n",
0812 dev->udev->devnum,
0813 intf->altsetting[0].desc.bInterfaceNumber);
0814 return -EINVAL;
0815 }
0816
0817 if (usb_driver_claim_interface(&uvc_driver.driver, intf, dev)) {
0818 uvc_dbg(dev, DESCR,
0819 "device %d interface %d is already claimed\n",
0820 dev->udev->devnum,
0821 intf->altsetting[0].desc.bInterfaceNumber);
0822 return -EINVAL;
0823 }
0824
0825 streaming = uvc_stream_new(dev, intf);
0826 if (streaming == NULL) {
0827 usb_driver_release_interface(&uvc_driver.driver, intf);
0828 return -ENOMEM;
0829 }
0830
0831
0832
0833
0834
0835 if (buflen == 0) {
0836 for (i = 0; i < alts->desc.bNumEndpoints; ++i) {
0837 struct usb_host_endpoint *ep = &alts->endpoint[i];
0838
0839 if (ep->extralen == 0)
0840 continue;
0841
0842 if (ep->extralen > 2 &&
0843 ep->extra[1] == USB_DT_CS_INTERFACE) {
0844 uvc_dbg(dev, DESCR,
0845 "trying extra data from endpoint %u\n",
0846 i);
0847 buffer = alts->endpoint[i].extra;
0848 buflen = alts->endpoint[i].extralen;
0849 break;
0850 }
0851 }
0852 }
0853
0854
0855 while (buflen > 2 && buffer[1] != USB_DT_CS_INTERFACE) {
0856 buflen -= buffer[0];
0857 buffer += buffer[0];
0858 }
0859
0860 if (buflen <= 2) {
0861 uvc_dbg(dev, DESCR,
0862 "no class-specific streaming interface descriptors found\n");
0863 goto error;
0864 }
0865
0866
0867 switch (buffer[2]) {
0868 case UVC_VS_OUTPUT_HEADER:
0869 streaming->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
0870 size = 9;
0871 break;
0872
0873 case UVC_VS_INPUT_HEADER:
0874 streaming->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
0875 size = 13;
0876 break;
0877
0878 default:
0879 uvc_dbg(dev, DESCR,
0880 "device %d videostreaming interface %d HEADER descriptor not found\n",
0881 dev->udev->devnum, alts->desc.bInterfaceNumber);
0882 goto error;
0883 }
0884
0885 p = buflen >= 4 ? buffer[3] : 0;
0886 n = buflen >= size ? buffer[size-1] : 0;
0887
0888 if (buflen < size + p*n) {
0889 uvc_dbg(dev, DESCR,
0890 "device %d videostreaming interface %d HEADER descriptor is invalid\n",
0891 dev->udev->devnum, alts->desc.bInterfaceNumber);
0892 goto error;
0893 }
0894
0895 streaming->header.bNumFormats = p;
0896 streaming->header.bEndpointAddress = buffer[6];
0897 if (buffer[2] == UVC_VS_INPUT_HEADER) {
0898 streaming->header.bmInfo = buffer[7];
0899 streaming->header.bTerminalLink = buffer[8];
0900 streaming->header.bStillCaptureMethod = buffer[9];
0901 streaming->header.bTriggerSupport = buffer[10];
0902 streaming->header.bTriggerUsage = buffer[11];
0903 } else {
0904 streaming->header.bTerminalLink = buffer[7];
0905 }
0906 streaming->header.bControlSize = n;
0907
0908 streaming->header.bmaControls = kmemdup(&buffer[size], p * n,
0909 GFP_KERNEL);
0910 if (streaming->header.bmaControls == NULL) {
0911 ret = -ENOMEM;
0912 goto error;
0913 }
0914
0915 buflen -= buffer[0];
0916 buffer += buffer[0];
0917
0918 _buffer = buffer;
0919 _buflen = buflen;
0920
0921
0922 while (_buflen > 2 && _buffer[1] == USB_DT_CS_INTERFACE) {
0923 switch (_buffer[2]) {
0924 case UVC_VS_FORMAT_UNCOMPRESSED:
0925 case UVC_VS_FORMAT_MJPEG:
0926 case UVC_VS_FORMAT_FRAME_BASED:
0927 nformats++;
0928 break;
0929
0930 case UVC_VS_FORMAT_DV:
0931
0932
0933
0934
0935 nformats++;
0936 nframes++;
0937 nintervals++;
0938 break;
0939
0940 case UVC_VS_FORMAT_MPEG2TS:
0941 case UVC_VS_FORMAT_STREAM_BASED:
0942 uvc_dbg(dev, DESCR,
0943 "device %d videostreaming interface %d FORMAT %u is not supported\n",
0944 dev->udev->devnum,
0945 alts->desc.bInterfaceNumber, _buffer[2]);
0946 break;
0947
0948 case UVC_VS_FRAME_UNCOMPRESSED:
0949 case UVC_VS_FRAME_MJPEG:
0950 nframes++;
0951 if (_buflen > 25)
0952 nintervals += _buffer[25] ? _buffer[25] : 3;
0953 break;
0954
0955 case UVC_VS_FRAME_FRAME_BASED:
0956 nframes++;
0957 if (_buflen > 21)
0958 nintervals += _buffer[21] ? _buffer[21] : 3;
0959 break;
0960 }
0961
0962 _buflen -= _buffer[0];
0963 _buffer += _buffer[0];
0964 }
0965
0966 if (nformats == 0) {
0967 uvc_dbg(dev, DESCR,
0968 "device %d videostreaming interface %d has no supported formats defined\n",
0969 dev->udev->devnum, alts->desc.bInterfaceNumber);
0970 goto error;
0971 }
0972
0973 size = nformats * sizeof(*format) + nframes * sizeof(*frame)
0974 + nintervals * sizeof(*interval);
0975 format = kzalloc(size, GFP_KERNEL);
0976 if (format == NULL) {
0977 ret = -ENOMEM;
0978 goto error;
0979 }
0980
0981 frame = (struct uvc_frame *)&format[nformats];
0982 interval = (u32 *)&frame[nframes];
0983
0984 streaming->format = format;
0985 streaming->nformats = nformats;
0986
0987
0988 while (buflen > 2 && buffer[1] == USB_DT_CS_INTERFACE) {
0989 switch (buffer[2]) {
0990 case UVC_VS_FORMAT_UNCOMPRESSED:
0991 case UVC_VS_FORMAT_MJPEG:
0992 case UVC_VS_FORMAT_DV:
0993 case UVC_VS_FORMAT_FRAME_BASED:
0994 format->frame = frame;
0995 ret = uvc_parse_format(dev, streaming, format,
0996 &interval, buffer, buflen);
0997 if (ret < 0)
0998 goto error;
0999
1000 frame += format->nframes;
1001 format++;
1002
1003 buflen -= ret;
1004 buffer += ret;
1005 continue;
1006
1007 default:
1008 break;
1009 }
1010
1011 buflen -= buffer[0];
1012 buffer += buffer[0];
1013 }
1014
1015 if (buflen)
1016 uvc_dbg(dev, DESCR,
1017 "device %d videostreaming interface %d has %u bytes of trailing descriptor garbage\n",
1018 dev->udev->devnum, alts->desc.bInterfaceNumber, buflen);
1019
1020
1021 for (i = 0; i < intf->num_altsetting; ++i) {
1022 struct usb_host_endpoint *ep;
1023 alts = &intf->altsetting[i];
1024 ep = uvc_find_endpoint(alts,
1025 streaming->header.bEndpointAddress);
1026 if (ep == NULL)
1027 continue;
1028 psize = uvc_endpoint_max_bpi(dev->udev, ep);
1029 if (psize > streaming->maxpsize)
1030 streaming->maxpsize = psize;
1031 }
1032
1033 list_add_tail(&streaming->list, &dev->streams);
1034 return 0;
1035
1036 error:
1037 usb_driver_release_interface(&uvc_driver.driver, intf);
1038 uvc_stream_delete(streaming);
1039 return ret;
1040 }
1041
1042 static const u8 uvc_camera_guid[16] = UVC_GUID_UVC_CAMERA;
1043 static const u8 uvc_gpio_guid[16] = UVC_GUID_EXT_GPIO_CONTROLLER;
1044 static const u8 uvc_media_transport_input_guid[16] =
1045 UVC_GUID_UVC_MEDIA_TRANSPORT_INPUT;
1046 static const u8 uvc_processing_guid[16] = UVC_GUID_UVC_PROCESSING;
1047
1048 static struct uvc_entity *uvc_alloc_entity(u16 type, u16 id,
1049 unsigned int num_pads, unsigned int extra_size)
1050 {
1051 struct uvc_entity *entity;
1052 unsigned int num_inputs;
1053 unsigned int size;
1054 unsigned int i;
1055
1056 extra_size = roundup(extra_size, sizeof(*entity->pads));
1057 if (num_pads)
1058 num_inputs = type & UVC_TERM_OUTPUT ? num_pads : num_pads - 1;
1059 else
1060 num_inputs = 0;
1061 size = sizeof(*entity) + extra_size + sizeof(*entity->pads) * num_pads
1062 + num_inputs;
1063 entity = kzalloc(size, GFP_KERNEL);
1064 if (entity == NULL)
1065 return NULL;
1066
1067 entity->id = id;
1068 entity->type = type;
1069
1070
1071
1072
1073
1074 switch (type) {
1075 case UVC_EXT_GPIO_UNIT:
1076 memcpy(entity->guid, uvc_gpio_guid, 16);
1077 break;
1078 case UVC_ITT_CAMERA:
1079 memcpy(entity->guid, uvc_camera_guid, 16);
1080 break;
1081 case UVC_ITT_MEDIA_TRANSPORT_INPUT:
1082 memcpy(entity->guid, uvc_media_transport_input_guid, 16);
1083 break;
1084 case UVC_VC_PROCESSING_UNIT:
1085 memcpy(entity->guid, uvc_processing_guid, 16);
1086 break;
1087 }
1088
1089 entity->num_links = 0;
1090 entity->num_pads = num_pads;
1091 entity->pads = ((void *)(entity + 1)) + extra_size;
1092
1093 for (i = 0; i < num_inputs; ++i)
1094 entity->pads[i].flags = MEDIA_PAD_FL_SINK;
1095 if (!UVC_ENTITY_IS_OTERM(entity) && num_pads)
1096 entity->pads[num_pads-1].flags = MEDIA_PAD_FL_SOURCE;
1097
1098 entity->bNrInPins = num_inputs;
1099 entity->baSourceID = (u8 *)(&entity->pads[num_pads]);
1100
1101 return entity;
1102 }
1103
1104
1105 static int uvc_parse_vendor_control(struct uvc_device *dev,
1106 const unsigned char *buffer, int buflen)
1107 {
1108 struct usb_device *udev = dev->udev;
1109 struct usb_host_interface *alts = dev->intf->cur_altsetting;
1110 struct uvc_entity *unit;
1111 unsigned int n, p;
1112 int handled = 0;
1113
1114 switch (le16_to_cpu(dev->udev->descriptor.idVendor)) {
1115 case 0x046d:
1116 if (buffer[1] != 0x41 || buffer[2] != 0x01)
1117 break;
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146 p = buflen >= 22 ? buffer[21] : 0;
1147 n = buflen >= 25 + p ? buffer[22+p] : 0;
1148
1149 if (buflen < 25 + p + 2*n) {
1150 uvc_dbg(dev, DESCR,
1151 "device %d videocontrol interface %d EXTENSION_UNIT error\n",
1152 udev->devnum, alts->desc.bInterfaceNumber);
1153 break;
1154 }
1155
1156 unit = uvc_alloc_entity(UVC_VC_EXTENSION_UNIT, buffer[3],
1157 p + 1, 2*n);
1158 if (unit == NULL)
1159 return -ENOMEM;
1160
1161 memcpy(unit->guid, &buffer[4], 16);
1162 unit->extension.bNumControls = buffer[20];
1163 memcpy(unit->baSourceID, &buffer[22], p);
1164 unit->extension.bControlSize = buffer[22+p];
1165 unit->extension.bmControls = (u8 *)unit + sizeof(*unit);
1166 unit->extension.bmControlsType = (u8 *)unit + sizeof(*unit)
1167 + n;
1168 memcpy(unit->extension.bmControls, &buffer[23+p], 2*n);
1169
1170 if (buffer[24+p+2*n] != 0)
1171 usb_string(udev, buffer[24+p+2*n], unit->name,
1172 sizeof(unit->name));
1173 else
1174 sprintf(unit->name, "Extension %u", buffer[3]);
1175
1176 list_add_tail(&unit->list, &dev->entities);
1177 handled = 1;
1178 break;
1179 }
1180
1181 return handled;
1182 }
1183
1184 static int uvc_parse_standard_control(struct uvc_device *dev,
1185 const unsigned char *buffer, int buflen)
1186 {
1187 struct usb_device *udev = dev->udev;
1188 struct uvc_entity *unit, *term;
1189 struct usb_interface *intf;
1190 struct usb_host_interface *alts = dev->intf->cur_altsetting;
1191 unsigned int i, n, p, len;
1192 u16 type;
1193
1194 switch (buffer[2]) {
1195 case UVC_VC_HEADER:
1196 n = buflen >= 12 ? buffer[11] : 0;
1197
1198 if (buflen < 12 + n) {
1199 uvc_dbg(dev, DESCR,
1200 "device %d videocontrol interface %d HEADER error\n",
1201 udev->devnum, alts->desc.bInterfaceNumber);
1202 return -EINVAL;
1203 }
1204
1205 dev->uvc_version = get_unaligned_le16(&buffer[3]);
1206 dev->clock_frequency = get_unaligned_le32(&buffer[7]);
1207
1208
1209 for (i = 0; i < n; ++i) {
1210 intf = usb_ifnum_to_if(udev, buffer[12+i]);
1211 if (intf == NULL) {
1212 uvc_dbg(dev, DESCR,
1213 "device %d interface %d doesn't exists\n",
1214 udev->devnum, i);
1215 continue;
1216 }
1217
1218 uvc_parse_streaming(dev, intf);
1219 }
1220 break;
1221
1222 case UVC_VC_INPUT_TERMINAL:
1223 if (buflen < 8) {
1224 uvc_dbg(dev, DESCR,
1225 "device %d videocontrol interface %d INPUT_TERMINAL error\n",
1226 udev->devnum, alts->desc.bInterfaceNumber);
1227 return -EINVAL;
1228 }
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241 type = get_unaligned_le16(&buffer[4]);
1242 if ((type & 0x7f00) == 0 || (type & 0x8000) != 0) {
1243 uvc_dbg(dev, DESCR,
1244 "device %d videocontrol interface %d INPUT_TERMINAL %d has invalid type 0x%04x, skipping\n",
1245 udev->devnum, alts->desc.bInterfaceNumber,
1246 buffer[3], type);
1247 return 0;
1248 }
1249
1250 n = 0;
1251 p = 0;
1252 len = 8;
1253
1254 if (type == UVC_ITT_CAMERA) {
1255 n = buflen >= 15 ? buffer[14] : 0;
1256 len = 15;
1257
1258 } else if (type == UVC_ITT_MEDIA_TRANSPORT_INPUT) {
1259 n = buflen >= 9 ? buffer[8] : 0;
1260 p = buflen >= 10 + n ? buffer[9+n] : 0;
1261 len = 10;
1262 }
1263
1264 if (buflen < len + n + p) {
1265 uvc_dbg(dev, DESCR,
1266 "device %d videocontrol interface %d INPUT_TERMINAL error\n",
1267 udev->devnum, alts->desc.bInterfaceNumber);
1268 return -EINVAL;
1269 }
1270
1271 term = uvc_alloc_entity(type | UVC_TERM_INPUT, buffer[3],
1272 1, n + p);
1273 if (term == NULL)
1274 return -ENOMEM;
1275
1276 if (UVC_ENTITY_TYPE(term) == UVC_ITT_CAMERA) {
1277 term->camera.bControlSize = n;
1278 term->camera.bmControls = (u8 *)term + sizeof(*term);
1279 term->camera.wObjectiveFocalLengthMin =
1280 get_unaligned_le16(&buffer[8]);
1281 term->camera.wObjectiveFocalLengthMax =
1282 get_unaligned_le16(&buffer[10]);
1283 term->camera.wOcularFocalLength =
1284 get_unaligned_le16(&buffer[12]);
1285 memcpy(term->camera.bmControls, &buffer[15], n);
1286 } else if (UVC_ENTITY_TYPE(term) ==
1287 UVC_ITT_MEDIA_TRANSPORT_INPUT) {
1288 term->media.bControlSize = n;
1289 term->media.bmControls = (u8 *)term + sizeof(*term);
1290 term->media.bTransportModeSize = p;
1291 term->media.bmTransportModes = (u8 *)term
1292 + sizeof(*term) + n;
1293 memcpy(term->media.bmControls, &buffer[9], n);
1294 memcpy(term->media.bmTransportModes, &buffer[10+n], p);
1295 }
1296
1297 if (buffer[7] != 0)
1298 usb_string(udev, buffer[7], term->name,
1299 sizeof(term->name));
1300 else if (UVC_ENTITY_TYPE(term) == UVC_ITT_CAMERA)
1301 sprintf(term->name, "Camera %u", buffer[3]);
1302 else if (UVC_ENTITY_TYPE(term) == UVC_ITT_MEDIA_TRANSPORT_INPUT)
1303 sprintf(term->name, "Media %u", buffer[3]);
1304 else
1305 sprintf(term->name, "Input %u", buffer[3]);
1306
1307 list_add_tail(&term->list, &dev->entities);
1308 break;
1309
1310 case UVC_VC_OUTPUT_TERMINAL:
1311 if (buflen < 9) {
1312 uvc_dbg(dev, DESCR,
1313 "device %d videocontrol interface %d OUTPUT_TERMINAL error\n",
1314 udev->devnum, alts->desc.bInterfaceNumber);
1315 return -EINVAL;
1316 }
1317
1318
1319
1320
1321
1322 type = get_unaligned_le16(&buffer[4]);
1323 if ((type & 0xff00) == 0) {
1324 uvc_dbg(dev, DESCR,
1325 "device %d videocontrol interface %d OUTPUT_TERMINAL %d has invalid type 0x%04x, skipping\n",
1326 udev->devnum, alts->desc.bInterfaceNumber,
1327 buffer[3], type);
1328 return 0;
1329 }
1330
1331 term = uvc_alloc_entity(type | UVC_TERM_OUTPUT, buffer[3],
1332 1, 0);
1333 if (term == NULL)
1334 return -ENOMEM;
1335
1336 memcpy(term->baSourceID, &buffer[7], 1);
1337
1338 if (buffer[8] != 0)
1339 usb_string(udev, buffer[8], term->name,
1340 sizeof(term->name));
1341 else
1342 sprintf(term->name, "Output %u", buffer[3]);
1343
1344 list_add_tail(&term->list, &dev->entities);
1345 break;
1346
1347 case UVC_VC_SELECTOR_UNIT:
1348 p = buflen >= 5 ? buffer[4] : 0;
1349
1350 if (buflen < 5 || buflen < 6 + p) {
1351 uvc_dbg(dev, DESCR,
1352 "device %d videocontrol interface %d SELECTOR_UNIT error\n",
1353 udev->devnum, alts->desc.bInterfaceNumber);
1354 return -EINVAL;
1355 }
1356
1357 unit = uvc_alloc_entity(buffer[2], buffer[3], p + 1, 0);
1358 if (unit == NULL)
1359 return -ENOMEM;
1360
1361 memcpy(unit->baSourceID, &buffer[5], p);
1362
1363 if (buffer[5+p] != 0)
1364 usb_string(udev, buffer[5+p], unit->name,
1365 sizeof(unit->name));
1366 else
1367 sprintf(unit->name, "Selector %u", buffer[3]);
1368
1369 list_add_tail(&unit->list, &dev->entities);
1370 break;
1371
1372 case UVC_VC_PROCESSING_UNIT:
1373 n = buflen >= 8 ? buffer[7] : 0;
1374 p = dev->uvc_version >= 0x0110 ? 10 : 9;
1375
1376 if (buflen < p + n) {
1377 uvc_dbg(dev, DESCR,
1378 "device %d videocontrol interface %d PROCESSING_UNIT error\n",
1379 udev->devnum, alts->desc.bInterfaceNumber);
1380 return -EINVAL;
1381 }
1382
1383 unit = uvc_alloc_entity(buffer[2], buffer[3], 2, n);
1384 if (unit == NULL)
1385 return -ENOMEM;
1386
1387 memcpy(unit->baSourceID, &buffer[4], 1);
1388 unit->processing.wMaxMultiplier =
1389 get_unaligned_le16(&buffer[5]);
1390 unit->processing.bControlSize = buffer[7];
1391 unit->processing.bmControls = (u8 *)unit + sizeof(*unit);
1392 memcpy(unit->processing.bmControls, &buffer[8], n);
1393 if (dev->uvc_version >= 0x0110)
1394 unit->processing.bmVideoStandards = buffer[9+n];
1395
1396 if (buffer[8+n] != 0)
1397 usb_string(udev, buffer[8+n], unit->name,
1398 sizeof(unit->name));
1399 else
1400 sprintf(unit->name, "Processing %u", buffer[3]);
1401
1402 list_add_tail(&unit->list, &dev->entities);
1403 break;
1404
1405 case UVC_VC_EXTENSION_UNIT:
1406 p = buflen >= 22 ? buffer[21] : 0;
1407 n = buflen >= 24 + p ? buffer[22+p] : 0;
1408
1409 if (buflen < 24 + p + n) {
1410 uvc_dbg(dev, DESCR,
1411 "device %d videocontrol interface %d EXTENSION_UNIT error\n",
1412 udev->devnum, alts->desc.bInterfaceNumber);
1413 return -EINVAL;
1414 }
1415
1416 unit = uvc_alloc_entity(buffer[2], buffer[3], p + 1, n);
1417 if (unit == NULL)
1418 return -ENOMEM;
1419
1420 memcpy(unit->guid, &buffer[4], 16);
1421 unit->extension.bNumControls = buffer[20];
1422 memcpy(unit->baSourceID, &buffer[22], p);
1423 unit->extension.bControlSize = buffer[22+p];
1424 unit->extension.bmControls = (u8 *)unit + sizeof(*unit);
1425 memcpy(unit->extension.bmControls, &buffer[23+p], n);
1426
1427 if (buffer[23+p+n] != 0)
1428 usb_string(udev, buffer[23+p+n], unit->name,
1429 sizeof(unit->name));
1430 else
1431 sprintf(unit->name, "Extension %u", buffer[3]);
1432
1433 list_add_tail(&unit->list, &dev->entities);
1434 break;
1435
1436 default:
1437 uvc_dbg(dev, DESCR,
1438 "Found an unknown CS_INTERFACE descriptor (%u)\n",
1439 buffer[2]);
1440 break;
1441 }
1442
1443 return 0;
1444 }
1445
1446 static int uvc_parse_control(struct uvc_device *dev)
1447 {
1448 struct usb_host_interface *alts = dev->intf->cur_altsetting;
1449 unsigned char *buffer = alts->extra;
1450 int buflen = alts->extralen;
1451 int ret;
1452
1453
1454
1455
1456
1457
1458
1459 while (buflen > 2) {
1460 if (uvc_parse_vendor_control(dev, buffer, buflen) ||
1461 buffer[1] != USB_DT_CS_INTERFACE)
1462 goto next_descriptor;
1463
1464 if ((ret = uvc_parse_standard_control(dev, buffer, buflen)) < 0)
1465 return ret;
1466
1467 next_descriptor:
1468 buflen -= buffer[0];
1469 buffer += buffer[0];
1470 }
1471
1472
1473
1474
1475
1476
1477
1478 if (alts->desc.bNumEndpoints == 1 &&
1479 !(dev->quirks & UVC_QUIRK_BUILTIN_ISIGHT)) {
1480 struct usb_host_endpoint *ep = &alts->endpoint[0];
1481 struct usb_endpoint_descriptor *desc = &ep->desc;
1482
1483 if (usb_endpoint_is_int_in(desc) &&
1484 le16_to_cpu(desc->wMaxPacketSize) >= 8 &&
1485 desc->bInterval != 0) {
1486 uvc_dbg(dev, DESCR,
1487 "Found a Status endpoint (addr %02x)\n",
1488 desc->bEndpointAddress);
1489 dev->int_ep = ep;
1490 }
1491 }
1492
1493 return 0;
1494 }
1495
1496
1497
1498
1499
1500 static void uvc_gpio_event(struct uvc_device *dev)
1501 {
1502 struct uvc_entity *unit = dev->gpio_unit;
1503 struct uvc_video_chain *chain;
1504 u8 new_val;
1505
1506 if (!unit)
1507 return;
1508
1509 new_val = gpiod_get_value_cansleep(unit->gpio.gpio_privacy);
1510
1511
1512 chain = list_first_entry(&dev->chains, struct uvc_video_chain, list);
1513 uvc_ctrl_status_event(chain, unit->controls, &new_val);
1514 }
1515
1516 static int uvc_gpio_get_cur(struct uvc_device *dev, struct uvc_entity *entity,
1517 u8 cs, void *data, u16 size)
1518 {
1519 if (cs != UVC_CT_PRIVACY_CONTROL || size < 1)
1520 return -EINVAL;
1521
1522 *(u8 *)data = gpiod_get_value_cansleep(entity->gpio.gpio_privacy);
1523
1524 return 0;
1525 }
1526
1527 static int uvc_gpio_get_info(struct uvc_device *dev, struct uvc_entity *entity,
1528 u8 cs, u8 *caps)
1529 {
1530 if (cs != UVC_CT_PRIVACY_CONTROL)
1531 return -EINVAL;
1532
1533 *caps = UVC_CONTROL_CAP_GET | UVC_CONTROL_CAP_AUTOUPDATE;
1534 return 0;
1535 }
1536
1537 static irqreturn_t uvc_gpio_irq(int irq, void *data)
1538 {
1539 struct uvc_device *dev = data;
1540
1541 uvc_gpio_event(dev);
1542 return IRQ_HANDLED;
1543 }
1544
1545 static int uvc_gpio_parse(struct uvc_device *dev)
1546 {
1547 struct uvc_entity *unit;
1548 struct gpio_desc *gpio_privacy;
1549 int irq;
1550
1551 gpio_privacy = devm_gpiod_get_optional(&dev->udev->dev, "privacy",
1552 GPIOD_IN);
1553 if (IS_ERR_OR_NULL(gpio_privacy))
1554 return PTR_ERR_OR_ZERO(gpio_privacy);
1555
1556 unit = uvc_alloc_entity(UVC_EXT_GPIO_UNIT, UVC_EXT_GPIO_UNIT_ID, 0, 1);
1557 if (!unit)
1558 return -ENOMEM;
1559
1560 irq = gpiod_to_irq(gpio_privacy);
1561 if (irq < 0) {
1562 if (irq != EPROBE_DEFER)
1563 dev_err(&dev->udev->dev,
1564 "No IRQ for privacy GPIO (%d)\n", irq);
1565 return irq;
1566 }
1567
1568 unit->gpio.gpio_privacy = gpio_privacy;
1569 unit->gpio.irq = irq;
1570 unit->gpio.bControlSize = 1;
1571 unit->gpio.bmControls = (u8 *)unit + sizeof(*unit);
1572 unit->gpio.bmControls[0] = 1;
1573 unit->get_cur = uvc_gpio_get_cur;
1574 unit->get_info = uvc_gpio_get_info;
1575 strscpy(unit->name, "GPIO", sizeof(unit->name));
1576
1577 list_add_tail(&unit->list, &dev->entities);
1578
1579 dev->gpio_unit = unit;
1580
1581 return 0;
1582 }
1583
1584 static int uvc_gpio_init_irq(struct uvc_device *dev)
1585 {
1586 struct uvc_entity *unit = dev->gpio_unit;
1587
1588 if (!unit || unit->gpio.irq < 0)
1589 return 0;
1590
1591 return devm_request_threaded_irq(&dev->udev->dev, unit->gpio.irq, NULL,
1592 uvc_gpio_irq,
1593 IRQF_ONESHOT | IRQF_TRIGGER_FALLING |
1594 IRQF_TRIGGER_RISING,
1595 "uvc_privacy_gpio", dev);
1596 }
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628 static int uvc_scan_chain_entity(struct uvc_video_chain *chain,
1629 struct uvc_entity *entity)
1630 {
1631 switch (UVC_ENTITY_TYPE(entity)) {
1632 case UVC_VC_EXTENSION_UNIT:
1633 uvc_dbg_cont(PROBE, " <- XU %d", entity->id);
1634
1635 if (entity->bNrInPins != 1) {
1636 uvc_dbg(chain->dev, DESCR,
1637 "Extension unit %d has more than 1 input pin\n",
1638 entity->id);
1639 return -1;
1640 }
1641
1642 break;
1643
1644 case UVC_VC_PROCESSING_UNIT:
1645 uvc_dbg_cont(PROBE, " <- PU %d", entity->id);
1646
1647 if (chain->processing != NULL) {
1648 uvc_dbg(chain->dev, DESCR,
1649 "Found multiple Processing Units in chain\n");
1650 return -1;
1651 }
1652
1653 chain->processing = entity;
1654 break;
1655
1656 case UVC_VC_SELECTOR_UNIT:
1657 uvc_dbg_cont(PROBE, " <- SU %d", entity->id);
1658
1659
1660 if (entity->bNrInPins == 1)
1661 break;
1662
1663 if (chain->selector != NULL) {
1664 uvc_dbg(chain->dev, DESCR,
1665 "Found multiple Selector Units in chain\n");
1666 return -1;
1667 }
1668
1669 chain->selector = entity;
1670 break;
1671
1672 case UVC_ITT_VENDOR_SPECIFIC:
1673 case UVC_ITT_CAMERA:
1674 case UVC_ITT_MEDIA_TRANSPORT_INPUT:
1675 uvc_dbg_cont(PROBE, " <- IT %d\n", entity->id);
1676
1677 break;
1678
1679 case UVC_OTT_VENDOR_SPECIFIC:
1680 case UVC_OTT_DISPLAY:
1681 case UVC_OTT_MEDIA_TRANSPORT_OUTPUT:
1682 uvc_dbg_cont(PROBE, " OT %d", entity->id);
1683
1684 break;
1685
1686 case UVC_TT_STREAMING:
1687 if (UVC_ENTITY_IS_ITERM(entity))
1688 uvc_dbg_cont(PROBE, " <- IT %d\n", entity->id);
1689 else
1690 uvc_dbg_cont(PROBE, " OT %d", entity->id);
1691
1692 break;
1693
1694 default:
1695 uvc_dbg(chain->dev, DESCR,
1696 "Unsupported entity type 0x%04x found in chain\n",
1697 UVC_ENTITY_TYPE(entity));
1698 return -1;
1699 }
1700
1701 list_add_tail(&entity->chain, &chain->entities);
1702 return 0;
1703 }
1704
1705 static int uvc_scan_chain_forward(struct uvc_video_chain *chain,
1706 struct uvc_entity *entity, struct uvc_entity *prev)
1707 {
1708 struct uvc_entity *forward;
1709 int found;
1710
1711
1712 forward = NULL;
1713 found = 0;
1714
1715 while (1) {
1716 forward = uvc_entity_by_reference(chain->dev, entity->id,
1717 forward);
1718 if (forward == NULL)
1719 break;
1720 if (forward == prev)
1721 continue;
1722 if (forward->chain.next || forward->chain.prev) {
1723 uvc_dbg(chain->dev, DESCR,
1724 "Found reference to entity %d already in chain\n",
1725 forward->id);
1726 return -EINVAL;
1727 }
1728
1729 switch (UVC_ENTITY_TYPE(forward)) {
1730 case UVC_VC_EXTENSION_UNIT:
1731 if (forward->bNrInPins != 1) {
1732 uvc_dbg(chain->dev, DESCR,
1733 "Extension unit %d has more than 1 input pin\n",
1734 forward->id);
1735 return -EINVAL;
1736 }
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748 if (UVC_ENTITY_IS_OTERM(entity)) {
1749 struct uvc_entity *source;
1750
1751 source = uvc_entity_by_id(chain->dev,
1752 entity->baSourceID[0]);
1753 if (!source) {
1754 uvc_dbg(chain->dev, DESCR,
1755 "Can't connect extension unit %u in chain\n",
1756 forward->id);
1757 break;
1758 }
1759
1760 forward->baSourceID[0] = source->id;
1761 }
1762
1763 list_add_tail(&forward->chain, &chain->entities);
1764 if (!found)
1765 uvc_dbg_cont(PROBE, " (->");
1766
1767 uvc_dbg_cont(PROBE, " XU %d", forward->id);
1768 found = 1;
1769 break;
1770
1771 case UVC_OTT_VENDOR_SPECIFIC:
1772 case UVC_OTT_DISPLAY:
1773 case UVC_OTT_MEDIA_TRANSPORT_OUTPUT:
1774 case UVC_TT_STREAMING:
1775 if (UVC_ENTITY_IS_ITERM(forward)) {
1776 uvc_dbg(chain->dev, DESCR,
1777 "Unsupported input terminal %u\n",
1778 forward->id);
1779 return -EINVAL;
1780 }
1781
1782 if (UVC_ENTITY_IS_OTERM(entity)) {
1783 uvc_dbg(chain->dev, DESCR,
1784 "Unsupported connection between output terminals %u and %u\n",
1785 entity->id, forward->id);
1786 break;
1787 }
1788
1789 list_add_tail(&forward->chain, &chain->entities);
1790 if (!found)
1791 uvc_dbg_cont(PROBE, " (->");
1792
1793 uvc_dbg_cont(PROBE, " OT %d", forward->id);
1794 found = 1;
1795 break;
1796 }
1797 }
1798 if (found)
1799 uvc_dbg_cont(PROBE, ")");
1800
1801 return 0;
1802 }
1803
1804 static int uvc_scan_chain_backward(struct uvc_video_chain *chain,
1805 struct uvc_entity **_entity)
1806 {
1807 struct uvc_entity *entity = *_entity;
1808 struct uvc_entity *term;
1809 int id = -EINVAL, i;
1810
1811 switch (UVC_ENTITY_TYPE(entity)) {
1812 case UVC_VC_EXTENSION_UNIT:
1813 case UVC_VC_PROCESSING_UNIT:
1814 id = entity->baSourceID[0];
1815 break;
1816
1817 case UVC_VC_SELECTOR_UNIT:
1818
1819 if (entity->bNrInPins == 1) {
1820 id = entity->baSourceID[0];
1821 break;
1822 }
1823
1824 uvc_dbg_cont(PROBE, " <- IT");
1825
1826 chain->selector = entity;
1827 for (i = 0; i < entity->bNrInPins; ++i) {
1828 id = entity->baSourceID[i];
1829 term = uvc_entity_by_id(chain->dev, id);
1830 if (term == NULL || !UVC_ENTITY_IS_ITERM(term)) {
1831 uvc_dbg(chain->dev, DESCR,
1832 "Selector unit %d input %d isn't connected to an input terminal\n",
1833 entity->id, i);
1834 return -1;
1835 }
1836
1837 if (term->chain.next || term->chain.prev) {
1838 uvc_dbg(chain->dev, DESCR,
1839 "Found reference to entity %d already in chain\n",
1840 term->id);
1841 return -EINVAL;
1842 }
1843
1844 uvc_dbg_cont(PROBE, " %d", term->id);
1845
1846 list_add_tail(&term->chain, &chain->entities);
1847 uvc_scan_chain_forward(chain, term, entity);
1848 }
1849
1850 uvc_dbg_cont(PROBE, "\n");
1851
1852 id = 0;
1853 break;
1854
1855 case UVC_ITT_VENDOR_SPECIFIC:
1856 case UVC_ITT_CAMERA:
1857 case UVC_ITT_MEDIA_TRANSPORT_INPUT:
1858 case UVC_OTT_VENDOR_SPECIFIC:
1859 case UVC_OTT_DISPLAY:
1860 case UVC_OTT_MEDIA_TRANSPORT_OUTPUT:
1861 case UVC_TT_STREAMING:
1862 id = UVC_ENTITY_IS_OTERM(entity) ? entity->baSourceID[0] : 0;
1863 break;
1864 }
1865
1866 if (id <= 0) {
1867 *_entity = NULL;
1868 return id;
1869 }
1870
1871 entity = uvc_entity_by_id(chain->dev, id);
1872 if (entity == NULL) {
1873 uvc_dbg(chain->dev, DESCR,
1874 "Found reference to unknown entity %d\n", id);
1875 return -EINVAL;
1876 }
1877
1878 *_entity = entity;
1879 return 0;
1880 }
1881
1882 static int uvc_scan_chain(struct uvc_video_chain *chain,
1883 struct uvc_entity *term)
1884 {
1885 struct uvc_entity *entity, *prev;
1886
1887 uvc_dbg(chain->dev, PROBE, "Scanning UVC chain:");
1888
1889 entity = term;
1890 prev = NULL;
1891
1892 while (entity != NULL) {
1893
1894 if (entity->chain.next || entity->chain.prev) {
1895 uvc_dbg(chain->dev, DESCR,
1896 "Found reference to entity %d already in chain\n",
1897 entity->id);
1898 return -EINVAL;
1899 }
1900
1901
1902 if (uvc_scan_chain_entity(chain, entity) < 0)
1903 return -EINVAL;
1904
1905
1906 if (uvc_scan_chain_forward(chain, entity, prev) < 0)
1907 return -EINVAL;
1908
1909
1910 prev = entity;
1911 if (uvc_scan_chain_backward(chain, &entity) < 0)
1912 return -EINVAL;
1913 }
1914
1915 return 0;
1916 }
1917
1918 static unsigned int uvc_print_terms(struct list_head *terms, u16 dir,
1919 char *buffer)
1920 {
1921 struct uvc_entity *term;
1922 unsigned int nterms = 0;
1923 char *p = buffer;
1924
1925 list_for_each_entry(term, terms, chain) {
1926 if (!UVC_ENTITY_IS_TERM(term) ||
1927 UVC_TERM_DIRECTION(term) != dir)
1928 continue;
1929
1930 if (nterms)
1931 p += sprintf(p, ",");
1932 if (++nterms >= 4) {
1933 p += sprintf(p, "...");
1934 break;
1935 }
1936 p += sprintf(p, "%u", term->id);
1937 }
1938
1939 return p - buffer;
1940 }
1941
1942 static const char *uvc_print_chain(struct uvc_video_chain *chain)
1943 {
1944 static char buffer[43];
1945 char *p = buffer;
1946
1947 p += uvc_print_terms(&chain->entities, UVC_TERM_INPUT, p);
1948 p += sprintf(p, " -> ");
1949 uvc_print_terms(&chain->entities, UVC_TERM_OUTPUT, p);
1950
1951 return buffer;
1952 }
1953
1954 static struct uvc_video_chain *uvc_alloc_chain(struct uvc_device *dev)
1955 {
1956 struct uvc_video_chain *chain;
1957
1958 chain = kzalloc(sizeof(*chain), GFP_KERNEL);
1959 if (chain == NULL)
1960 return NULL;
1961
1962 INIT_LIST_HEAD(&chain->entities);
1963 mutex_init(&chain->ctrl_mutex);
1964 chain->dev = dev;
1965 v4l2_prio_init(&chain->prio);
1966
1967 return chain;
1968 }
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983 static int uvc_scan_fallback(struct uvc_device *dev)
1984 {
1985 struct uvc_video_chain *chain;
1986 struct uvc_entity *iterm = NULL;
1987 struct uvc_entity *oterm = NULL;
1988 struct uvc_entity *entity;
1989 struct uvc_entity *prev;
1990
1991
1992
1993
1994
1995 list_for_each_entry(entity, &dev->entities, list) {
1996 if (UVC_ENTITY_IS_ITERM(entity)) {
1997 if (iterm)
1998 return -EINVAL;
1999 iterm = entity;
2000 }
2001
2002 if (UVC_ENTITY_IS_OTERM(entity)) {
2003 if (oterm)
2004 return -EINVAL;
2005 oterm = entity;
2006 }
2007 }
2008
2009 if (iterm == NULL || oterm == NULL)
2010 return -EINVAL;
2011
2012
2013 chain = uvc_alloc_chain(dev);
2014 if (chain == NULL)
2015 return -ENOMEM;
2016
2017 if (uvc_scan_chain_entity(chain, oterm) < 0)
2018 goto error;
2019
2020 prev = oterm;
2021
2022
2023
2024
2025
2026
2027
2028
2029 list_for_each_entry_reverse(entity, &dev->entities, list) {
2030 if (entity->type != UVC_VC_PROCESSING_UNIT &&
2031 entity->type != UVC_VC_EXTENSION_UNIT)
2032 continue;
2033
2034 if (entity->num_pads != 2)
2035 continue;
2036
2037 if (uvc_scan_chain_entity(chain, entity) < 0)
2038 goto error;
2039
2040 prev->baSourceID[0] = entity->id;
2041 prev = entity;
2042 }
2043
2044 if (uvc_scan_chain_entity(chain, iterm) < 0)
2045 goto error;
2046
2047 prev->baSourceID[0] = iterm->id;
2048
2049 list_add_tail(&chain->list, &dev->chains);
2050
2051 uvc_dbg(dev, PROBE, "Found a video chain by fallback heuristic (%s)\n",
2052 uvc_print_chain(chain));
2053
2054 return 0;
2055
2056 error:
2057 kfree(chain);
2058 return -EINVAL;
2059 }
2060
2061
2062
2063
2064
2065
2066 static int uvc_scan_device(struct uvc_device *dev)
2067 {
2068 struct uvc_video_chain *chain;
2069 struct uvc_entity *term;
2070
2071 list_for_each_entry(term, &dev->entities, list) {
2072 if (!UVC_ENTITY_IS_OTERM(term))
2073 continue;
2074
2075
2076
2077
2078
2079
2080
2081 if (term->chain.next || term->chain.prev)
2082 continue;
2083
2084 chain = uvc_alloc_chain(dev);
2085 if (chain == NULL)
2086 return -ENOMEM;
2087
2088 term->flags |= UVC_ENTITY_FLAG_DEFAULT;
2089
2090 if (uvc_scan_chain(chain, term) < 0) {
2091 kfree(chain);
2092 continue;
2093 }
2094
2095 uvc_dbg(dev, PROBE, "Found a valid video chain (%s)\n",
2096 uvc_print_chain(chain));
2097
2098 list_add_tail(&chain->list, &dev->chains);
2099 }
2100
2101 if (list_empty(&dev->chains))
2102 uvc_scan_fallback(dev);
2103
2104 if (list_empty(&dev->chains)) {
2105 dev_info(&dev->udev->dev, "No valid video chain found.\n");
2106 return -1;
2107 }
2108
2109
2110 if (dev->gpio_unit) {
2111 chain = list_first_entry(&dev->chains,
2112 struct uvc_video_chain, list);
2113 list_add_tail(&dev->gpio_unit->chain, &chain->entities);
2114 }
2115
2116 return 0;
2117 }
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133 static void uvc_delete(struct kref *kref)
2134 {
2135 struct uvc_device *dev = container_of(kref, struct uvc_device, ref);
2136 struct list_head *p, *n;
2137
2138 uvc_status_cleanup(dev);
2139 uvc_ctrl_cleanup_device(dev);
2140
2141 usb_put_intf(dev->intf);
2142 usb_put_dev(dev->udev);
2143
2144 #ifdef CONFIG_MEDIA_CONTROLLER
2145 media_device_cleanup(&dev->mdev);
2146 #endif
2147
2148 list_for_each_safe(p, n, &dev->chains) {
2149 struct uvc_video_chain *chain;
2150 chain = list_entry(p, struct uvc_video_chain, list);
2151 kfree(chain);
2152 }
2153
2154 list_for_each_safe(p, n, &dev->entities) {
2155 struct uvc_entity *entity;
2156 entity = list_entry(p, struct uvc_entity, list);
2157 #ifdef CONFIG_MEDIA_CONTROLLER
2158 uvc_mc_cleanup_entity(entity);
2159 #endif
2160 kfree(entity);
2161 }
2162
2163 list_for_each_safe(p, n, &dev->streams) {
2164 struct uvc_streaming *streaming;
2165 streaming = list_entry(p, struct uvc_streaming, list);
2166 usb_driver_release_interface(&uvc_driver.driver,
2167 streaming->intf);
2168 uvc_stream_delete(streaming);
2169 }
2170
2171 kfree(dev);
2172 }
2173
2174 static void uvc_release(struct video_device *vdev)
2175 {
2176 struct uvc_streaming *stream = video_get_drvdata(vdev);
2177 struct uvc_device *dev = stream->dev;
2178
2179 kref_put(&dev->ref, uvc_delete);
2180 }
2181
2182
2183
2184
2185 static void uvc_unregister_video(struct uvc_device *dev)
2186 {
2187 struct uvc_streaming *stream;
2188
2189 list_for_each_entry(stream, &dev->streams, list) {
2190 if (!video_is_registered(&stream->vdev))
2191 continue;
2192
2193 video_unregister_device(&stream->vdev);
2194 video_unregister_device(&stream->meta.vdev);
2195
2196 uvc_debugfs_cleanup_stream(stream);
2197 }
2198
2199 uvc_status_unregister(dev);
2200
2201 if (dev->vdev.dev)
2202 v4l2_device_unregister(&dev->vdev);
2203 #ifdef CONFIG_MEDIA_CONTROLLER
2204 if (media_devnode_is_registered(dev->mdev.devnode))
2205 media_device_unregister(&dev->mdev);
2206 #endif
2207 }
2208
2209 int uvc_register_video_device(struct uvc_device *dev,
2210 struct uvc_streaming *stream,
2211 struct video_device *vdev,
2212 struct uvc_video_queue *queue,
2213 enum v4l2_buf_type type,
2214 const struct v4l2_file_operations *fops,
2215 const struct v4l2_ioctl_ops *ioctl_ops)
2216 {
2217 int ret;
2218
2219
2220 ret = uvc_queue_init(queue, type, !uvc_no_drop_param);
2221 if (ret)
2222 return ret;
2223
2224
2225
2226
2227
2228
2229
2230
2231 vdev->v4l2_dev = &dev->vdev;
2232 vdev->fops = fops;
2233 vdev->ioctl_ops = ioctl_ops;
2234 vdev->release = uvc_release;
2235 vdev->prio = &stream->chain->prio;
2236 if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
2237 vdev->vfl_dir = VFL_DIR_TX;
2238 else
2239 vdev->vfl_dir = VFL_DIR_RX;
2240
2241 switch (type) {
2242 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
2243 default:
2244 vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
2245 break;
2246 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
2247 vdev->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
2248 break;
2249 case V4L2_BUF_TYPE_META_CAPTURE:
2250 vdev->device_caps = V4L2_CAP_META_CAPTURE | V4L2_CAP_STREAMING;
2251 break;
2252 }
2253
2254 strscpy(vdev->name, dev->name, sizeof(vdev->name));
2255
2256
2257
2258
2259
2260 video_set_drvdata(vdev, stream);
2261
2262 ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
2263 if (ret < 0) {
2264 dev_err(&stream->intf->dev,
2265 "Failed to register %s device (%d).\n",
2266 v4l2_type_names[type], ret);
2267 return ret;
2268 }
2269
2270 kref_get(&dev->ref);
2271 return 0;
2272 }
2273
2274 static int uvc_register_video(struct uvc_device *dev,
2275 struct uvc_streaming *stream)
2276 {
2277 int ret;
2278
2279
2280 ret = uvc_video_init(stream);
2281 if (ret < 0) {
2282 dev_err(&stream->intf->dev,
2283 "Failed to initialize the device (%d).\n", ret);
2284 return ret;
2285 }
2286
2287 if (stream->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
2288 stream->chain->caps |= V4L2_CAP_VIDEO_CAPTURE
2289 | V4L2_CAP_META_CAPTURE;
2290 else
2291 stream->chain->caps |= V4L2_CAP_VIDEO_OUTPUT;
2292
2293 uvc_debugfs_init_stream(stream);
2294
2295
2296 return uvc_register_video_device(dev, stream, &stream->vdev,
2297 &stream->queue, stream->type,
2298 &uvc_fops, &uvc_ioctl_ops);
2299 }
2300
2301
2302
2303
2304 static int uvc_register_terms(struct uvc_device *dev,
2305 struct uvc_video_chain *chain)
2306 {
2307 struct uvc_streaming *stream;
2308 struct uvc_entity *term;
2309 int ret;
2310
2311 list_for_each_entry(term, &chain->entities, chain) {
2312 if (UVC_ENTITY_TYPE(term) != UVC_TT_STREAMING)
2313 continue;
2314
2315 stream = uvc_stream_by_id(dev, term->id);
2316 if (stream == NULL) {
2317 dev_info(&dev->udev->dev,
2318 "No streaming interface found for terminal %u.",
2319 term->id);
2320 continue;
2321 }
2322
2323 stream->chain = chain;
2324 ret = uvc_register_video(dev, stream);
2325 if (ret < 0)
2326 return ret;
2327
2328
2329
2330
2331
2332 uvc_meta_register(stream);
2333
2334 term->vdev = &stream->vdev;
2335 }
2336
2337 return 0;
2338 }
2339
2340 static int uvc_register_chains(struct uvc_device *dev)
2341 {
2342 struct uvc_video_chain *chain;
2343 int ret;
2344
2345 list_for_each_entry(chain, &dev->chains, list) {
2346 ret = uvc_register_terms(dev, chain);
2347 if (ret < 0)
2348 return ret;
2349
2350 #ifdef CONFIG_MEDIA_CONTROLLER
2351 ret = uvc_mc_register_entities(chain);
2352 if (ret < 0)
2353 dev_info(&dev->udev->dev,
2354 "Failed to register entities (%d).\n", ret);
2355 #endif
2356 }
2357
2358 return 0;
2359 }
2360
2361
2362
2363
2364
2365 static const struct uvc_device_info uvc_quirk_none = { 0 };
2366
2367 static int uvc_probe(struct usb_interface *intf,
2368 const struct usb_device_id *id)
2369 {
2370 struct usb_device *udev = interface_to_usbdev(intf);
2371 struct uvc_device *dev;
2372 const struct uvc_device_info *info =
2373 (const struct uvc_device_info *)id->driver_info;
2374 int function;
2375 int ret;
2376
2377
2378 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
2379 if (dev == NULL)
2380 return -ENOMEM;
2381
2382 INIT_LIST_HEAD(&dev->entities);
2383 INIT_LIST_HEAD(&dev->chains);
2384 INIT_LIST_HEAD(&dev->streams);
2385 kref_init(&dev->ref);
2386 atomic_set(&dev->nmappings, 0);
2387 mutex_init(&dev->lock);
2388
2389 dev->udev = usb_get_dev(udev);
2390 dev->intf = usb_get_intf(intf);
2391 dev->intfnum = intf->cur_altsetting->desc.bInterfaceNumber;
2392 dev->info = info ? info : &uvc_quirk_none;
2393 dev->quirks = uvc_quirks_param == -1
2394 ? dev->info->quirks : uvc_quirks_param;
2395
2396 if (id->idVendor && id->idProduct)
2397 uvc_dbg(dev, PROBE, "Probing known UVC device %s (%04x:%04x)\n",
2398 udev->devpath, id->idVendor, id->idProduct);
2399 else
2400 uvc_dbg(dev, PROBE, "Probing generic UVC device %s\n",
2401 udev->devpath);
2402
2403 if (udev->product != NULL)
2404 strscpy(dev->name, udev->product, sizeof(dev->name));
2405 else
2406 snprintf(dev->name, sizeof(dev->name),
2407 "UVC Camera (%04x:%04x)",
2408 le16_to_cpu(udev->descriptor.idVendor),
2409 le16_to_cpu(udev->descriptor.idProduct));
2410
2411
2412
2413
2414
2415
2416 if (intf->intf_assoc && intf->intf_assoc->iFunction != 0)
2417 function = intf->intf_assoc->iFunction;
2418 else
2419 function = intf->cur_altsetting->desc.iInterface;
2420 if (function != 0) {
2421 size_t len;
2422
2423 strlcat(dev->name, ": ", sizeof(dev->name));
2424 len = strlen(dev->name);
2425 usb_string(udev, function, dev->name + len,
2426 sizeof(dev->name) - len);
2427 }
2428
2429
2430 #ifdef CONFIG_MEDIA_CONTROLLER
2431 dev->mdev.dev = &intf->dev;
2432 strscpy(dev->mdev.model, dev->name, sizeof(dev->mdev.model));
2433 if (udev->serial)
2434 strscpy(dev->mdev.serial, udev->serial,
2435 sizeof(dev->mdev.serial));
2436 usb_make_path(udev, dev->mdev.bus_info, sizeof(dev->mdev.bus_info));
2437 dev->mdev.hw_revision = le16_to_cpu(udev->descriptor.bcdDevice);
2438 media_device_init(&dev->mdev);
2439
2440 dev->vdev.mdev = &dev->mdev;
2441 #endif
2442
2443
2444 if (uvc_parse_control(dev) < 0) {
2445 uvc_dbg(dev, PROBE, "Unable to parse UVC descriptors\n");
2446 goto error;
2447 }
2448
2449
2450 if (uvc_gpio_parse(dev) < 0) {
2451 uvc_dbg(dev, PROBE, "Unable to parse UVC GPIOs\n");
2452 goto error;
2453 }
2454
2455 dev_info(&dev->udev->dev, "Found UVC %u.%02x device %s (%04x:%04x)\n",
2456 dev->uvc_version >> 8, dev->uvc_version & 0xff,
2457 udev->product ? udev->product : "<unnamed>",
2458 le16_to_cpu(udev->descriptor.idVendor),
2459 le16_to_cpu(udev->descriptor.idProduct));
2460
2461 if (dev->quirks != dev->info->quirks) {
2462 dev_info(&dev->udev->dev,
2463 "Forcing device quirks to 0x%x by module parameter for testing purpose.\n",
2464 dev->quirks);
2465 dev_info(&dev->udev->dev,
2466 "Please report required quirks to the linux-media mailing list.\n");
2467 }
2468
2469 if (dev->info->uvc_version) {
2470 dev->uvc_version = dev->info->uvc_version;
2471 dev_info(&dev->udev->dev, "Forcing UVC version to %u.%02x\n",
2472 dev->uvc_version >> 8, dev->uvc_version & 0xff);
2473 }
2474
2475
2476 if (v4l2_device_register(&intf->dev, &dev->vdev) < 0)
2477 goto error;
2478
2479
2480 if (uvc_scan_device(dev) < 0)
2481 goto error;
2482
2483
2484 if (uvc_ctrl_init_device(dev) < 0)
2485 goto error;
2486
2487
2488 if (uvc_register_chains(dev) < 0)
2489 goto error;
2490
2491 #ifdef CONFIG_MEDIA_CONTROLLER
2492
2493 if (media_device_register(&dev->mdev) < 0)
2494 goto error;
2495 #endif
2496
2497 usb_set_intfdata(intf, dev);
2498
2499
2500 if ((ret = uvc_status_init(dev)) < 0) {
2501 dev_info(&dev->udev->dev,
2502 "Unable to initialize the status endpoint (%d), status interrupt will not be supported.\n",
2503 ret);
2504 }
2505
2506 ret = uvc_gpio_init_irq(dev);
2507 if (ret < 0) {
2508 dev_err(&dev->udev->dev,
2509 "Unable to request privacy GPIO IRQ (%d)\n", ret);
2510 goto error;
2511 }
2512
2513 uvc_dbg(dev, PROBE, "UVC device initialized\n");
2514 usb_enable_autosuspend(udev);
2515 return 0;
2516
2517 error:
2518 uvc_unregister_video(dev);
2519 kref_put(&dev->ref, uvc_delete);
2520 return -ENODEV;
2521 }
2522
2523 static void uvc_disconnect(struct usb_interface *intf)
2524 {
2525 struct uvc_device *dev = usb_get_intfdata(intf);
2526
2527
2528
2529
2530
2531 usb_set_intfdata(intf, NULL);
2532
2533 if (intf->cur_altsetting->desc.bInterfaceSubClass ==
2534 UVC_SC_VIDEOSTREAMING)
2535 return;
2536
2537 uvc_unregister_video(dev);
2538 kref_put(&dev->ref, uvc_delete);
2539 }
2540
2541 static int uvc_suspend(struct usb_interface *intf, pm_message_t message)
2542 {
2543 struct uvc_device *dev = usb_get_intfdata(intf);
2544 struct uvc_streaming *stream;
2545
2546 uvc_dbg(dev, SUSPEND, "Suspending interface %u\n",
2547 intf->cur_altsetting->desc.bInterfaceNumber);
2548
2549
2550 if (intf->cur_altsetting->desc.bInterfaceSubClass ==
2551 UVC_SC_VIDEOCONTROL) {
2552 mutex_lock(&dev->lock);
2553 if (dev->users)
2554 uvc_status_stop(dev);
2555 mutex_unlock(&dev->lock);
2556 return 0;
2557 }
2558
2559 list_for_each_entry(stream, &dev->streams, list) {
2560 if (stream->intf == intf)
2561 return uvc_video_suspend(stream);
2562 }
2563
2564 uvc_dbg(dev, SUSPEND,
2565 "Suspend: video streaming USB interface mismatch\n");
2566 return -EINVAL;
2567 }
2568
2569 static int __uvc_resume(struct usb_interface *intf, int reset)
2570 {
2571 struct uvc_device *dev = usb_get_intfdata(intf);
2572 struct uvc_streaming *stream;
2573 int ret = 0;
2574
2575 uvc_dbg(dev, SUSPEND, "Resuming interface %u\n",
2576 intf->cur_altsetting->desc.bInterfaceNumber);
2577
2578 if (intf->cur_altsetting->desc.bInterfaceSubClass ==
2579 UVC_SC_VIDEOCONTROL) {
2580 if (reset) {
2581 ret = uvc_ctrl_restore_values(dev);
2582 if (ret < 0)
2583 return ret;
2584 }
2585
2586 mutex_lock(&dev->lock);
2587 if (dev->users)
2588 ret = uvc_status_start(dev, GFP_NOIO);
2589 mutex_unlock(&dev->lock);
2590
2591 return ret;
2592 }
2593
2594 list_for_each_entry(stream, &dev->streams, list) {
2595 if (stream->intf == intf) {
2596 ret = uvc_video_resume(stream, reset);
2597 if (ret < 0)
2598 uvc_queue_streamoff(&stream->queue,
2599 stream->queue.queue.type);
2600 return ret;
2601 }
2602 }
2603
2604 uvc_dbg(dev, SUSPEND,
2605 "Resume: video streaming USB interface mismatch\n");
2606 return -EINVAL;
2607 }
2608
2609 static int uvc_resume(struct usb_interface *intf)
2610 {
2611 return __uvc_resume(intf, 0);
2612 }
2613
2614 static int uvc_reset_resume(struct usb_interface *intf)
2615 {
2616 return __uvc_resume(intf, 1);
2617 }
2618
2619
2620
2621
2622
2623 static int uvc_clock_param_get(char *buffer, const struct kernel_param *kp)
2624 {
2625 if (uvc_clock_param == CLOCK_MONOTONIC)
2626 return sprintf(buffer, "CLOCK_MONOTONIC");
2627 else
2628 return sprintf(buffer, "CLOCK_REALTIME");
2629 }
2630
2631 static int uvc_clock_param_set(const char *val, const struct kernel_param *kp)
2632 {
2633 if (strncasecmp(val, "clock_", strlen("clock_")) == 0)
2634 val += strlen("clock_");
2635
2636 if (strcasecmp(val, "monotonic") == 0)
2637 uvc_clock_param = CLOCK_MONOTONIC;
2638 else if (strcasecmp(val, "realtime") == 0)
2639 uvc_clock_param = CLOCK_REALTIME;
2640 else
2641 return -EINVAL;
2642
2643 return 0;
2644 }
2645
2646 module_param_call(clock, uvc_clock_param_set, uvc_clock_param_get,
2647 &uvc_clock_param, S_IRUGO|S_IWUSR);
2648 MODULE_PARM_DESC(clock, "Video buffers timestamp clock");
2649 module_param_named(hwtimestamps, uvc_hw_timestamps_param, uint, S_IRUGO|S_IWUSR);
2650 MODULE_PARM_DESC(hwtimestamps, "Use hardware timestamps");
2651 module_param_named(nodrop, uvc_no_drop_param, uint, S_IRUGO|S_IWUSR);
2652 MODULE_PARM_DESC(nodrop, "Don't drop incomplete frames");
2653 module_param_named(quirks, uvc_quirks_param, uint, S_IRUGO|S_IWUSR);
2654 MODULE_PARM_DESC(quirks, "Forced device quirks");
2655 module_param_named(trace, uvc_dbg_param, uint, S_IRUGO|S_IWUSR);
2656 MODULE_PARM_DESC(trace, "Trace level bitmask");
2657 module_param_named(timeout, uvc_timeout_param, uint, S_IRUGO|S_IWUSR);
2658 MODULE_PARM_DESC(timeout, "Streaming control requests timeout");
2659
2660
2661
2662
2663
2664 static const struct uvc_menu_info power_line_frequency_controls_limited[] = {
2665 { 1, "50 Hz" },
2666 { 2, "60 Hz" },
2667 };
2668
2669 static const struct uvc_control_mapping uvc_ctrl_power_line_mapping_limited = {
2670 .id = V4L2_CID_POWER_LINE_FREQUENCY,
2671 .entity = UVC_GUID_UVC_PROCESSING,
2672 .selector = UVC_PU_POWER_LINE_FREQUENCY_CONTROL,
2673 .size = 2,
2674 .offset = 0,
2675 .v4l2_type = V4L2_CTRL_TYPE_MENU,
2676 .data_type = UVC_CTRL_DATA_TYPE_ENUM,
2677 .menu_info = power_line_frequency_controls_limited,
2678 .menu_count = ARRAY_SIZE(power_line_frequency_controls_limited),
2679 };
2680
2681 static const struct uvc_device_info uvc_ctrl_power_line_limited = {
2682 .mappings = (const struct uvc_control_mapping *[]) {
2683 &uvc_ctrl_power_line_mapping_limited,
2684 NULL,
2685 },
2686 };
2687
2688 static const struct uvc_device_info uvc_quirk_probe_minmax = {
2689 .quirks = UVC_QUIRK_PROBE_MINMAX,
2690 };
2691
2692 static const struct uvc_device_info uvc_quirk_fix_bandwidth = {
2693 .quirks = UVC_QUIRK_FIX_BANDWIDTH,
2694 };
2695
2696 static const struct uvc_device_info uvc_quirk_probe_def = {
2697 .quirks = UVC_QUIRK_PROBE_DEF,
2698 };
2699
2700 static const struct uvc_device_info uvc_quirk_stream_no_fid = {
2701 .quirks = UVC_QUIRK_STREAM_NO_FID,
2702 };
2703
2704 static const struct uvc_device_info uvc_quirk_force_y8 = {
2705 .quirks = UVC_QUIRK_FORCE_Y8,
2706 };
2707
2708 #define UVC_INFO_QUIRK(q) (kernel_ulong_t)&(struct uvc_device_info){.quirks = q}
2709 #define UVC_INFO_META(m) (kernel_ulong_t)&(struct uvc_device_info) \
2710 {.meta_format = m}
2711
2712
2713
2714
2715
2716
2717 static const struct usb_device_id uvc_ids[] = {
2718
2719 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2720 | USB_DEVICE_ID_MATCH_INT_INFO,
2721 .idVendor = 0x0408,
2722 .idProduct = 0x3090,
2723 .bInterfaceClass = USB_CLASS_VIDEO,
2724 .bInterfaceSubClass = 1,
2725 .bInterfaceProtocol = 0,
2726 .driver_info = (kernel_ulong_t)&uvc_ctrl_power_line_limited },
2727
2728 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2729 | USB_DEVICE_ID_MATCH_INT_INFO,
2730 .idVendor = 0x0408,
2731 .idProduct = 0x4030,
2732 .bInterfaceClass = USB_CLASS_VIDEO,
2733 .bInterfaceSubClass = 1,
2734 .bInterfaceProtocol = 0,
2735 .driver_info = (kernel_ulong_t)&uvc_ctrl_power_line_limited },
2736
2737 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2738 | USB_DEVICE_ID_MATCH_INT_INFO,
2739 .idVendor = 0x0408,
2740 .idProduct = 0x4034,
2741 .bInterfaceClass = USB_CLASS_VIDEO,
2742 .bInterfaceSubClass = 1,
2743 .bInterfaceProtocol = UVC_PC_PROTOCOL_15,
2744 .driver_info = (kernel_ulong_t)&uvc_ctrl_power_line_limited },
2745
2746 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2747 | USB_DEVICE_ID_MATCH_INT_INFO,
2748 .idVendor = 0x0416,
2749 .idProduct = 0xa91a,
2750 .bInterfaceClass = USB_CLASS_VIDEO,
2751 .bInterfaceSubClass = 1,
2752 .bInterfaceProtocol = 0,
2753 .driver_info = (kernel_ulong_t)&uvc_quirk_probe_minmax },
2754
2755 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2756 | USB_DEVICE_ID_MATCH_INT_INFO,
2757 .idVendor = 0x0458,
2758 .idProduct = 0x706e,
2759 .bInterfaceClass = USB_CLASS_VIDEO,
2760 .bInterfaceSubClass = 1,
2761 .bInterfaceProtocol = 0,
2762 .driver_info = (kernel_ulong_t)&uvc_quirk_probe_minmax },
2763
2764 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2765 | USB_DEVICE_ID_MATCH_INT_INFO,
2766 .idVendor = 0x045e,
2767 .idProduct = 0x00f8,
2768 .bInterfaceClass = USB_CLASS_VIDEO,
2769 .bInterfaceSubClass = 1,
2770 .bInterfaceProtocol = 0,
2771 .driver_info = (kernel_ulong_t)&uvc_quirk_probe_minmax },
2772
2773 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2774 | USB_DEVICE_ID_MATCH_INT_INFO,
2775 .idVendor = 0x045e,
2776 .idProduct = 0x0721,
2777 .bInterfaceClass = USB_CLASS_VIDEO,
2778 .bInterfaceSubClass = 1,
2779 .bInterfaceProtocol = 0,
2780 .driver_info = (kernel_ulong_t)&uvc_quirk_probe_def },
2781
2782 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2783 | USB_DEVICE_ID_MATCH_INT_INFO,
2784 .idVendor = 0x045e,
2785 .idProduct = 0x0723,
2786 .bInterfaceClass = USB_CLASS_VIDEO,
2787 .bInterfaceSubClass = 1,
2788 .bInterfaceProtocol = 0,
2789 .driver_info = (kernel_ulong_t)&uvc_quirk_probe_minmax },
2790
2791 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2792 | USB_DEVICE_ID_MATCH_INT_INFO,
2793 .idVendor = 0x046d,
2794 .idProduct = 0x08c1,
2795 .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
2796 .bInterfaceSubClass = 1,
2797 .bInterfaceProtocol = 0 },
2798
2799 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2800 | USB_DEVICE_ID_MATCH_INT_INFO,
2801 .idVendor = 0x046d,
2802 .idProduct = 0x08c2,
2803 .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
2804 .bInterfaceSubClass = 1,
2805 .bInterfaceProtocol = 0 },
2806
2807 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2808 | USB_DEVICE_ID_MATCH_INT_INFO,
2809 .idVendor = 0x046d,
2810 .idProduct = 0x08c3,
2811 .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
2812 .bInterfaceSubClass = 1,
2813 .bInterfaceProtocol = 0 },
2814
2815 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2816 | USB_DEVICE_ID_MATCH_INT_INFO,
2817 .idVendor = 0x046d,
2818 .idProduct = 0x08c5,
2819 .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
2820 .bInterfaceSubClass = 1,
2821 .bInterfaceProtocol = 0 },
2822
2823 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2824 | USB_DEVICE_ID_MATCH_INT_INFO,
2825 .idVendor = 0x046d,
2826 .idProduct = 0x08c6,
2827 .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
2828 .bInterfaceSubClass = 1,
2829 .bInterfaceProtocol = 0 },
2830
2831 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2832 | USB_DEVICE_ID_MATCH_INT_INFO,
2833 .idVendor = 0x046d,
2834 .idProduct = 0x08c7,
2835 .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
2836 .bInterfaceSubClass = 1,
2837 .bInterfaceProtocol = 0 },
2838
2839 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2840 | USB_DEVICE_ID_MATCH_INT_INFO,
2841 .idVendor = 0x046d,
2842 .idProduct = 0x082d,
2843 .bInterfaceClass = USB_CLASS_VIDEO,
2844 .bInterfaceSubClass = 1,
2845 .bInterfaceProtocol = 0,
2846 .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_RESTORE_CTRLS_ON_INIT) },
2847
2848 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2849 | USB_DEVICE_ID_MATCH_INT_INFO,
2850 .idVendor = 0x04f2,
2851 .idProduct = 0xb071,
2852 .bInterfaceClass = USB_CLASS_VIDEO,
2853 .bInterfaceSubClass = 1,
2854 .bInterfaceProtocol = 0,
2855 .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_RESTRICT_FRAME_RATE) },
2856
2857 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2858 | USB_DEVICE_ID_MATCH_INT_INFO,
2859 .idVendor = 0x04f2,
2860 .idProduct = 0xb5eb,
2861 .bInterfaceClass = USB_CLASS_VIDEO,
2862 .bInterfaceSubClass = 1,
2863 .bInterfaceProtocol = 0,
2864 .driver_info = (kernel_ulong_t)&uvc_ctrl_power_line_limited },
2865
2866 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2867 | USB_DEVICE_ID_MATCH_INT_INFO,
2868 .idVendor = 0x04f2,
2869 .idProduct = 0xb6ba,
2870 .bInterfaceClass = USB_CLASS_VIDEO,
2871 .bInterfaceSubClass = 1,
2872 .bInterfaceProtocol = 0,
2873 .driver_info = (kernel_ulong_t)&uvc_ctrl_power_line_limited },
2874
2875 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2876 | USB_DEVICE_ID_MATCH_INT_INFO,
2877 .idVendor = 0x04f2,
2878 .idProduct = 0xb746,
2879 .bInterfaceClass = USB_CLASS_VIDEO,
2880 .bInterfaceSubClass = 1,
2881 .bInterfaceProtocol = 0,
2882 .driver_info = (kernel_ulong_t)&uvc_ctrl_power_line_limited },
2883
2884 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2885 | USB_DEVICE_ID_MATCH_INT_INFO,
2886 .idVendor = 0x058f,
2887 .idProduct = 0x3820,
2888 .bInterfaceClass = USB_CLASS_VIDEO,
2889 .bInterfaceSubClass = 1,
2890 .bInterfaceProtocol = 0,
2891 .driver_info = (kernel_ulong_t)&uvc_quirk_probe_minmax },
2892
2893 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2894 | USB_DEVICE_ID_MATCH_INT_INFO,
2895 .idVendor = 0x05a9,
2896 .idProduct = 0x2640,
2897 .bInterfaceClass = USB_CLASS_VIDEO,
2898 .bInterfaceSubClass = 1,
2899 .bInterfaceProtocol = 0,
2900 .driver_info = (kernel_ulong_t)&uvc_quirk_probe_def },
2901
2902 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2903 | USB_DEVICE_ID_MATCH_INT_INFO,
2904 .idVendor = 0x05a9,
2905 .idProduct = 0x2641,
2906 .bInterfaceClass = USB_CLASS_VIDEO,
2907 .bInterfaceSubClass = 1,
2908 .bInterfaceProtocol = 0,
2909 .driver_info = (kernel_ulong_t)&uvc_quirk_probe_def },
2910
2911 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2912 | USB_DEVICE_ID_MATCH_INT_INFO,
2913 .idVendor = 0x05a9,
2914 .idProduct = 0x2643,
2915 .bInterfaceClass = USB_CLASS_VIDEO,
2916 .bInterfaceSubClass = 1,
2917 .bInterfaceProtocol = 0,
2918 .driver_info = (kernel_ulong_t)&uvc_quirk_probe_def },
2919
2920 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2921 | USB_DEVICE_ID_MATCH_INT_INFO,
2922 .idVendor = 0x05a9,
2923 .idProduct = 0x264a,
2924 .bInterfaceClass = USB_CLASS_VIDEO,
2925 .bInterfaceSubClass = 1,
2926 .bInterfaceProtocol = 0,
2927 .driver_info = (kernel_ulong_t)&uvc_quirk_probe_def },
2928
2929 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2930 | USB_DEVICE_ID_MATCH_INT_INFO,
2931 .idVendor = 0x05a9,
2932 .idProduct = 0x7670,
2933 .bInterfaceClass = USB_CLASS_VIDEO,
2934 .bInterfaceSubClass = 1,
2935 .bInterfaceProtocol = 0,
2936 .driver_info = (kernel_ulong_t)&uvc_quirk_probe_def },
2937
2938 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2939 | USB_DEVICE_ID_MATCH_INT_INFO,
2940 .idVendor = 0x05ac,
2941 .idProduct = 0x8501,
2942 .bInterfaceClass = USB_CLASS_VIDEO,
2943 .bInterfaceSubClass = 1,
2944 .bInterfaceProtocol = 0,
2945 .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_PROBE_MINMAX
2946 | UVC_QUIRK_BUILTIN_ISIGHT) },
2947
2948 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2949 | USB_DEVICE_ID_MATCH_INT_INFO,
2950 .idVendor = 0x05ac,
2951 .idProduct = 0x8514,
2952 .bInterfaceClass = USB_CLASS_VIDEO,
2953 .bInterfaceSubClass = 1,
2954 .bInterfaceProtocol = 0,
2955 .driver_info = (kernel_ulong_t)&uvc_quirk_probe_def },
2956
2957 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2958 | USB_DEVICE_ID_MATCH_INT_INFO,
2959 .idVendor = 0x05ac,
2960 .idProduct = 0x8600,
2961 .bInterfaceClass = USB_CLASS_VIDEO,
2962 .bInterfaceSubClass = 1,
2963 .bInterfaceProtocol = 0,
2964 .driver_info = (kernel_ulong_t)&uvc_quirk_probe_def },
2965
2966 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2967 | USB_DEVICE_ID_MATCH_INT_INFO,
2968 .idVendor = 0x05c8,
2969 .idProduct = 0x0403,
2970 .bInterfaceClass = USB_CLASS_VIDEO,
2971 .bInterfaceSubClass = 1,
2972 .bInterfaceProtocol = 0,
2973 .driver_info = (kernel_ulong_t)&uvc_quirk_fix_bandwidth },
2974
2975 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2976 | USB_DEVICE_ID_MATCH_INT_INFO,
2977 .idVendor = 0x05e3,
2978 .idProduct = 0x0505,
2979 .bInterfaceClass = USB_CLASS_VIDEO,
2980 .bInterfaceSubClass = 1,
2981 .bInterfaceProtocol = 0,
2982 .driver_info = (kernel_ulong_t)&uvc_quirk_stream_no_fid },
2983
2984 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2985 | USB_DEVICE_ID_MATCH_INT_INFO,
2986 .idVendor = 0x06f8,
2987 .idProduct = 0x300c,
2988 .bInterfaceClass = USB_CLASS_VIDEO,
2989 .bInterfaceSubClass = 1,
2990 .bInterfaceProtocol = 0,
2991 .driver_info = (kernel_ulong_t)&uvc_quirk_fix_bandwidth },
2992
2993 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2994 | USB_DEVICE_ID_MATCH_INT_INFO,
2995 .idVendor = 0x0ac8,
2996 .idProduct = 0x332d,
2997 .bInterfaceClass = USB_CLASS_VIDEO,
2998 .bInterfaceSubClass = 1,
2999 .bInterfaceProtocol = 0,
3000 .driver_info = (kernel_ulong_t)&uvc_quirk_fix_bandwidth },
3001
3002 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
3003 | USB_DEVICE_ID_MATCH_INT_INFO,
3004 .idVendor = 0x0ac8,
3005 .idProduct = 0x3410,
3006 .bInterfaceClass = USB_CLASS_VIDEO,
3007 .bInterfaceSubClass = 1,
3008 .bInterfaceProtocol = 0,
3009 .driver_info = (kernel_ulong_t)&uvc_quirk_fix_bandwidth },
3010
3011 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
3012 | USB_DEVICE_ID_MATCH_INT_INFO,
3013 .idVendor = 0x0ac8,
3014 .idProduct = 0x3420,
3015 .bInterfaceClass = USB_CLASS_VIDEO,
3016 .bInterfaceSubClass = 1,
3017 .bInterfaceProtocol = 0,
3018 .driver_info = (kernel_ulong_t)&uvc_quirk_fix_bandwidth },
3019
3020 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
3021 | USB_DEVICE_ID_MATCH_INT_INFO,
3022 .idVendor = 0x0bd3,
3023 .idProduct = 0x0555,
3024 .bInterfaceClass = USB_CLASS_VIDEO,
3025 .bInterfaceSubClass = 1,
3026 .bInterfaceProtocol = 0,
3027 .driver_info = (kernel_ulong_t)&uvc_quirk_probe_minmax },
3028
3029 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
3030 | USB_DEVICE_ID_MATCH_INT_INFO,
3031 .idVendor = 0x0e8d,
3032 .idProduct = 0x0004,
3033 .bInterfaceClass = USB_CLASS_VIDEO,
3034 .bInterfaceSubClass = 1,
3035 .bInterfaceProtocol = 0,
3036 .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_PROBE_MINMAX
3037 | UVC_QUIRK_PROBE_DEF) },
3038
3039 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
3040 | USB_DEVICE_ID_MATCH_INT_INFO,
3041 .idVendor = 0x13d3,
3042 .idProduct = 0x5103,
3043 .bInterfaceClass = USB_CLASS_VIDEO,
3044 .bInterfaceSubClass = 1,
3045 .bInterfaceProtocol = 0,
3046 .driver_info = (kernel_ulong_t)&uvc_quirk_stream_no_fid },
3047
3048 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
3049 | USB_DEVICE_ID_MATCH_INT_INFO,
3050 .idVendor = 0x152d,
3051 .idProduct = 0x0310,
3052 .bInterfaceClass = USB_CLASS_VIDEO,
3053 .bInterfaceSubClass = 1,
3054 .bInterfaceProtocol = 0,
3055 .driver_info = (kernel_ulong_t)&uvc_quirk_probe_minmax },
3056
3057 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
3058 | USB_DEVICE_ID_MATCH_INT_INFO,
3059 .idVendor = 0x174f,
3060 .idProduct = 0x5212,
3061 .bInterfaceClass = USB_CLASS_VIDEO,
3062 .bInterfaceSubClass = 1,
3063 .bInterfaceProtocol = 0,
3064 .driver_info = (kernel_ulong_t)&uvc_quirk_stream_no_fid },
3065
3066 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
3067 | USB_DEVICE_ID_MATCH_INT_INFO,
3068 .idVendor = 0x174f,
3069 .idProduct = 0x5931,
3070 .bInterfaceClass = USB_CLASS_VIDEO,
3071 .bInterfaceSubClass = 1,
3072 .bInterfaceProtocol = 0,
3073 .driver_info = (kernel_ulong_t)&uvc_quirk_stream_no_fid },
3074
3075 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
3076 | USB_DEVICE_ID_MATCH_INT_INFO,
3077 .idVendor = 0x174f,
3078 .idProduct = 0x8a12,
3079 .bInterfaceClass = USB_CLASS_VIDEO,
3080 .bInterfaceSubClass = 1,
3081 .bInterfaceProtocol = 0,
3082 .driver_info = (kernel_ulong_t)&uvc_quirk_stream_no_fid },
3083
3084 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
3085 | USB_DEVICE_ID_MATCH_INT_INFO,
3086 .idVendor = 0x174f,
3087 .idProduct = 0x8a31,
3088 .bInterfaceClass = USB_CLASS_VIDEO,
3089 .bInterfaceSubClass = 1,
3090 .bInterfaceProtocol = 0,
3091 .driver_info = (kernel_ulong_t)&uvc_quirk_stream_no_fid },
3092
3093 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
3094 | USB_DEVICE_ID_MATCH_INT_INFO,
3095 .idVendor = 0x174f,
3096 .idProduct = 0x8a33,
3097 .bInterfaceClass = USB_CLASS_VIDEO,
3098 .bInterfaceSubClass = 1,
3099 .bInterfaceProtocol = 0,
3100 .driver_info = (kernel_ulong_t)&uvc_quirk_stream_no_fid },
3101
3102 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
3103 | USB_DEVICE_ID_MATCH_INT_INFO,
3104 .idVendor = 0x174f,
3105 .idProduct = 0x8a34,
3106 .bInterfaceClass = USB_CLASS_VIDEO,
3107 .bInterfaceSubClass = 1,
3108 .bInterfaceProtocol = 0,
3109 .driver_info = (kernel_ulong_t)&uvc_quirk_stream_no_fid },
3110
3111 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
3112 | USB_DEVICE_ID_MATCH_INT_INFO,
3113 .idVendor = 0x17dc,
3114 .idProduct = 0x0202,
3115 .bInterfaceClass = USB_CLASS_VIDEO,
3116 .bInterfaceSubClass = 1,
3117 .bInterfaceProtocol = 0,
3118 .driver_info = (kernel_ulong_t)&uvc_quirk_stream_no_fid },
3119
3120 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
3121 | USB_DEVICE_ID_MATCH_INT_INFO,
3122 .idVendor = 0x17ef,
3123 .idProduct = 0x480b,
3124 .bInterfaceClass = USB_CLASS_VIDEO,
3125 .bInterfaceSubClass = 1,
3126 .bInterfaceProtocol = 0,
3127 .driver_info = (kernel_ulong_t)&uvc_quirk_stream_no_fid },
3128
3129 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
3130 | USB_DEVICE_ID_MATCH_INT_INFO,
3131 .idVendor = 0x1871,
3132 .idProduct = 0x0306,
3133 .bInterfaceClass = USB_CLASS_VIDEO,
3134 .bInterfaceSubClass = 1,
3135 .bInterfaceProtocol = 0,
3136 .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_PROBE_MINMAX
3137 | UVC_QUIRK_PROBE_EXTRAFIELDS) },
3138
3139 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
3140 | USB_DEVICE_ID_MATCH_INT_INFO,
3141 .idVendor = 0x1871,
3142 .idProduct = 0x0516,
3143 .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
3144 .bInterfaceSubClass = 1,
3145 .bInterfaceProtocol = 0 },
3146
3147 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
3148 | USB_DEVICE_ID_MATCH_INT_INFO,
3149 .idVendor = 0x18cd,
3150 .idProduct = 0xcafe,
3151 .bInterfaceClass = USB_CLASS_VIDEO,
3152 .bInterfaceSubClass = 1,
3153 .bInterfaceProtocol = 0,
3154 .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_PROBE_EXTRAFIELDS) },
3155
3156 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
3157 | USB_DEVICE_ID_MATCH_INT_INFO,
3158 .idVendor = 0x18ec,
3159 .idProduct = 0x3188,
3160 .bInterfaceClass = USB_CLASS_VIDEO,
3161 .bInterfaceSubClass = 1,
3162 .bInterfaceProtocol = 0,
3163 .driver_info = (kernel_ulong_t)&uvc_quirk_probe_minmax },
3164
3165 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
3166 | USB_DEVICE_ID_MATCH_INT_INFO,
3167 .idVendor = 0x18ec,
3168 .idProduct = 0x3288,
3169 .bInterfaceClass = USB_CLASS_VIDEO,
3170 .bInterfaceSubClass = 1,
3171 .bInterfaceProtocol = 0,
3172 .driver_info = (kernel_ulong_t)&uvc_quirk_probe_minmax },
3173
3174 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
3175 | USB_DEVICE_ID_MATCH_INT_INFO,
3176 .idVendor = 0x18ec,
3177 .idProduct = 0x3290,
3178 .bInterfaceClass = USB_CLASS_VIDEO,
3179 .bInterfaceSubClass = 1,
3180 .bInterfaceProtocol = 0,
3181 .driver_info = (kernel_ulong_t)&uvc_quirk_probe_def },
3182
3183 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
3184 | USB_DEVICE_ID_MATCH_INT_INFO,
3185 .idVendor = 0x199e,
3186 .idProduct = 0x8102,
3187 .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
3188 .bInterfaceSubClass = 1,
3189 .bInterfaceProtocol = 0 },
3190
3191 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
3192 | USB_DEVICE_ID_MATCH_DEV_HI
3193 | USB_DEVICE_ID_MATCH_INT_INFO,
3194 .idVendor = 0x19ab,
3195 .idProduct = 0x1000,
3196 .bcdDevice_hi = 0x0126,
3197 .bInterfaceClass = USB_CLASS_VIDEO,
3198 .bInterfaceSubClass = 1,
3199 .bInterfaceProtocol = 0,
3200 .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_STATUS_INTERVAL) },
3201
3202 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
3203 | USB_DEVICE_ID_MATCH_INT_INFO,
3204 .idVendor = 0x1b3b,
3205 .idProduct = 0x2951,
3206 .bInterfaceClass = USB_CLASS_VIDEO,
3207 .bInterfaceSubClass = 1,
3208 .bInterfaceProtocol = 0,
3209 .driver_info = (kernel_ulong_t)&uvc_quirk_probe_minmax },
3210
3211 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
3212 | USB_DEVICE_ID_MATCH_INT_INFO,
3213 .idVendor = 0x1b3f,
3214 .idProduct = 0x2002,
3215 .bInterfaceClass = USB_CLASS_VIDEO,
3216 .bInterfaceSubClass = 1,
3217 .bInterfaceProtocol = 0,
3218 .driver_info = (kernel_ulong_t)&uvc_quirk_probe_minmax },
3219
3220 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
3221 | USB_DEVICE_ID_MATCH_INT_INFO,
3222 .idVendor = 0x1bcf,
3223 .idProduct = 0x0b40,
3224 .bInterfaceClass = USB_CLASS_VIDEO,
3225 .bInterfaceSubClass = 1,
3226 .bInterfaceProtocol = 0,
3227 .driver_info = (kernel_ulong_t)&(const struct uvc_device_info){
3228 .uvc_version = 0x010a,
3229 } },
3230
3231 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
3232 | USB_DEVICE_ID_MATCH_INT_INFO,
3233 .idVendor = 0x1c4f,
3234 .idProduct = 0x3000,
3235 .bInterfaceClass = USB_CLASS_VIDEO,
3236 .bInterfaceSubClass = 1,
3237 .bInterfaceProtocol = 0,
3238 .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_PROBE_MINMAX
3239 | UVC_QUIRK_IGNORE_SELECTOR_UNIT) },
3240
3241 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
3242 | USB_DEVICE_ID_MATCH_INT_INFO,
3243 .idVendor = 0x2833,
3244 .idProduct = 0x0201,
3245 .bInterfaceClass = USB_CLASS_VIDEO,
3246 .bInterfaceSubClass = 1,
3247 .bInterfaceProtocol = 0,
3248 .driver_info = (kernel_ulong_t)&uvc_quirk_force_y8 },
3249
3250 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
3251 | USB_DEVICE_ID_MATCH_INT_INFO,
3252 .idVendor = 0x2833,
3253 .idProduct = 0x0211,
3254 .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
3255 .bInterfaceSubClass = 1,
3256 .bInterfaceProtocol = 0,
3257 .driver_info = (kernel_ulong_t)&uvc_quirk_force_y8 },
3258
3259 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
3260 | USB_DEVICE_ID_MATCH_INT_INFO,
3261 .idVendor = 0x29fe,
3262 .idProduct = 0x4d53,
3263 .bInterfaceClass = USB_CLASS_VIDEO,
3264 .bInterfaceSubClass = 1,
3265 .bInterfaceProtocol = 0,
3266 .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_FORCE_BPP) },
3267
3268 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
3269 | USB_DEVICE_ID_MATCH_INT_INFO,
3270 .idVendor = 0x5986,
3271 .idProduct = 0x1172,
3272 .bInterfaceClass = USB_CLASS_VIDEO,
3273 .bInterfaceSubClass = 1,
3274 .bInterfaceProtocol = 0,
3275 .driver_info = (kernel_ulong_t)&uvc_ctrl_power_line_limited },
3276
3277 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
3278 | USB_DEVICE_ID_MATCH_INT_INFO,
3279 .idVendor = 0x8086,
3280 .idProduct = 0x0b03,
3281 .bInterfaceClass = USB_CLASS_VIDEO,
3282 .bInterfaceSubClass = 1,
3283 .bInterfaceProtocol = 0,
3284 .driver_info = UVC_INFO_META(V4L2_META_FMT_D4XX) },
3285
3286 { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, UVC_PC_PROTOCOL_UNDEFINED) },
3287 { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, UVC_PC_PROTOCOL_15) },
3288 {}
3289 };
3290
3291 MODULE_DEVICE_TABLE(usb, uvc_ids);
3292
3293 struct uvc_driver uvc_driver = {
3294 .driver = {
3295 .name = "uvcvideo",
3296 .probe = uvc_probe,
3297 .disconnect = uvc_disconnect,
3298 .suspend = uvc_suspend,
3299 .resume = uvc_resume,
3300 .reset_resume = uvc_reset_resume,
3301 .id_table = uvc_ids,
3302 .supports_autosuspend = 1,
3303 },
3304 };
3305
3306 static int __init uvc_init(void)
3307 {
3308 int ret;
3309
3310 uvc_debugfs_init();
3311
3312 ret = usb_register(&uvc_driver.driver);
3313 if (ret < 0) {
3314 uvc_debugfs_cleanup();
3315 return ret;
3316 }
3317
3318 return 0;
3319 }
3320
3321 static void __exit uvc_cleanup(void)
3322 {
3323 usb_deregister(&uvc_driver.driver);
3324 uvc_debugfs_cleanup();
3325 }
3326
3327 module_init(uvc_init);
3328 module_exit(uvc_cleanup);
3329
3330 MODULE_AUTHOR(DRIVER_AUTHOR);
3331 MODULE_DESCRIPTION(DRIVER_DESC);
3332 MODULE_LICENSE("GPL");
3333 MODULE_VERSION(DRIVER_VERSION);
3334