forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/drivers/media/usb/uvc/uvc_driver.c
....@@ -1,14 +1,9 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * uvc_driver.c -- USB Video Class driver
34 *
45 * Copyright (C) 2005-2010
56 * Laurent Pinchart (laurent.pinchart@ideasonboard.com)
6
- *
7
- * This program is free software; you can redistribute it and/or modify
8
- * it under the terms of the GNU General Public License as published by
9
- * the Free Software Foundation; either version 2 of the License, or
10
- * (at your option) any later version.
11
- *
127 */
138
149 #include <linux/atomic.h>
....@@ -220,6 +215,16 @@
220215 .guid = UVC_GUID_FORMAT_INZI,
221216 .fcc = V4L2_PIX_FMT_INZI,
222217 },
218
+ {
219
+ .name = "4-bit Depth Confidence (Packed)",
220
+ .guid = UVC_GUID_FORMAT_CNF4,
221
+ .fcc = V4L2_PIX_FMT_CNF4,
222
+ },
223
+ {
224
+ .name = "HEVC",
225
+ .guid = UVC_GUID_FORMAT_HEVC,
226
+ .fcc = V4L2_PIX_FMT_HEVC,
227
+ },
223228 };
224229
225230 /* ------------------------------------------------------------------------
....@@ -254,10 +259,10 @@
254259 return NULL;
255260 }
256261
257
-static u32 uvc_colorspace(const u8 primaries)
262
+static enum v4l2_colorspace uvc_colorspace(const u8 primaries)
258263 {
259
- static const u8 colorprimaries[] = {
260
- 0,
264
+ static const enum v4l2_colorspace colorprimaries[] = {
265
+ V4L2_COLORSPACE_DEFAULT, /* Unspecified */
261266 V4L2_COLORSPACE_SRGB,
262267 V4L2_COLORSPACE_470_SYSTEM_M,
263268 V4L2_COLORSPACE_470_SYSTEM_BG,
....@@ -268,7 +273,61 @@
268273 if (primaries < ARRAY_SIZE(colorprimaries))
269274 return colorprimaries[primaries];
270275
271
- return 0;
276
+ return V4L2_COLORSPACE_DEFAULT; /* Reserved */
277
+}
278
+
279
+static enum v4l2_xfer_func uvc_xfer_func(const u8 transfer_characteristics)
280
+{
281
+ /*
282
+ * V4L2 does not currently have definitions for all possible values of
283
+ * UVC transfer characteristics. If v4l2_xfer_func is extended with new
284
+ * values, the mapping below should be updated.
285
+ *
286
+ * Substitutions are taken from the mapping given for
287
+ * V4L2_XFER_FUNC_DEFAULT documented in videodev2.h.
288
+ */
289
+ static const enum v4l2_xfer_func xfer_funcs[] = {
290
+ V4L2_XFER_FUNC_DEFAULT, /* Unspecified */
291
+ V4L2_XFER_FUNC_709,
292
+ V4L2_XFER_FUNC_709, /* Substitution for BT.470-2 M */
293
+ V4L2_XFER_FUNC_709, /* Substitution for BT.470-2 B, G */
294
+ V4L2_XFER_FUNC_709, /* Substitution for SMPTE 170M */
295
+ V4L2_XFER_FUNC_SMPTE240M,
296
+ V4L2_XFER_FUNC_NONE,
297
+ V4L2_XFER_FUNC_SRGB,
298
+ };
299
+
300
+ if (transfer_characteristics < ARRAY_SIZE(xfer_funcs))
301
+ return xfer_funcs[transfer_characteristics];
302
+
303
+ return V4L2_XFER_FUNC_DEFAULT; /* Reserved */
304
+}
305
+
306
+static enum v4l2_ycbcr_encoding uvc_ycbcr_enc(const u8 matrix_coefficients)
307
+{
308
+ /*
309
+ * V4L2 does not currently have definitions for all possible values of
310
+ * UVC matrix coefficients. If v4l2_ycbcr_encoding is extended with new
311
+ * values, the mapping below should be updated.
312
+ *
313
+ * Substitutions are taken from the mapping given for
314
+ * V4L2_YCBCR_ENC_DEFAULT documented in videodev2.h.
315
+ *
316
+ * FCC is assumed to be close enough to 601.
317
+ */
318
+ static const enum v4l2_ycbcr_encoding ycbcr_encs[] = {
319
+ V4L2_YCBCR_ENC_DEFAULT, /* Unspecified */
320
+ V4L2_YCBCR_ENC_709,
321
+ V4L2_YCBCR_ENC_601, /* Substitution for FCC */
322
+ V4L2_YCBCR_ENC_601, /* Substitution for BT.470-2 B, G */
323
+ V4L2_YCBCR_ENC_601,
324
+ V4L2_YCBCR_ENC_SMPTE240M,
325
+ };
326
+
327
+ if (matrix_coefficients < ARRAY_SIZE(ycbcr_encs))
328
+ return ycbcr_encs[matrix_coefficients];
329
+
330
+ return V4L2_YCBCR_ENC_DEFAULT; /* Reserved */
272331 }
273332
274333 /* Simplify a fraction using a simple continued fraction decomposition. The
....@@ -290,7 +349,7 @@
290349 return;
291350
292351 /* Convert the fraction to a simple continued fraction. See
293
- * http://mathforum.org/dr.math/faq/faq.fractions.html
352
+ * https://mathforum.org/dr.math/faq/faq.fractions.html
294353 * Stop if the current term is bigger than or equal to the given
295354 * threshold.
296355 */
....@@ -477,7 +536,7 @@
477536 fmtdesc = uvc_format_by_guid(&buffer[5]);
478537
479538 if (fmtdesc != NULL) {
480
- strlcpy(format->name, fmtdesc->name,
539
+ strscpy(format->name, fmtdesc->name,
481540 sizeof(format->name));
482541 format->fcc = fmtdesc->fcc;
483542 } else {
....@@ -495,11 +554,27 @@
495554 */
496555 if (dev->quirks & UVC_QUIRK_FORCE_Y8) {
497556 if (format->fcc == V4L2_PIX_FMT_YUYV) {
498
- strlcpy(format->name, "Greyscale 8-bit (Y8 )",
557
+ strscpy(format->name, "Greyscale 8-bit (Y8 )",
499558 sizeof(format->name));
500559 format->fcc = V4L2_PIX_FMT_GREY;
501560 format->bpp = 8;
502561 width_multiplier = 2;
562
+ }
563
+ }
564
+
565
+ /* Some devices report bpp that doesn't match the format. */
566
+ if (dev->quirks & UVC_QUIRK_FORCE_BPP) {
567
+ const struct v4l2_format_info *info =
568
+ v4l2_format_info(format->fcc);
569
+
570
+ if (info) {
571
+ unsigned int div = info->hdiv * info->vdiv;
572
+
573
+ n = info->bpp[0] * div;
574
+ for (i = 1; i < info->comp_planes; i++)
575
+ n += info->bpp[i];
576
+
577
+ format->bpp = DIV_ROUND_UP(8 * n, div);
503578 }
504579 }
505580
....@@ -521,7 +596,7 @@
521596 return -EINVAL;
522597 }
523598
524
- strlcpy(format->name, "MJPEG", sizeof(format->name));
599
+ strscpy(format->name, "MJPEG", sizeof(format->name));
525600 format->fcc = V4L2_PIX_FMT_MJPEG;
526601 format->flags = UVC_FMT_FLAG_COMPRESSED;
527602 format->bpp = 0;
....@@ -539,13 +614,13 @@
539614
540615 switch (buffer[8] & 0x7f) {
541616 case 0:
542
- strlcpy(format->name, "SD-DV", sizeof(format->name));
617
+ strscpy(format->name, "SD-DV", sizeof(format->name));
543618 break;
544619 case 1:
545
- strlcpy(format->name, "SDL-DV", sizeof(format->name));
620
+ strscpy(format->name, "SDL-DV", sizeof(format->name));
546621 break;
547622 case 2:
548
- strlcpy(format->name, "HD-DV", sizeof(format->name));
623
+ strscpy(format->name, "HD-DV", sizeof(format->name));
549624 break;
550625 default:
551626 uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
....@@ -694,6 +769,8 @@
694769 }
695770
696771 format->colorspace = uvc_colorspace(buffer[3]);
772
+ format->xfer_func = uvc_xfer_func(buffer[4]);
773
+ format->ycbcr_enc = uvc_ycbcr_enc(buffer[5]);
697774
698775 buflen -= buffer[0];
699776 buffer += buffer[0];
....@@ -1050,10 +1127,8 @@
10501127 + n;
10511128 memcpy(unit->extension.bmControls, &buffer[23+p], 2*n);
10521129
1053
- if (buffer[24+p+2*n] != 0)
1054
- usb_string(udev, buffer[24+p+2*n], unit->name,
1055
- sizeof(unit->name));
1056
- else
1130
+ if (buffer[24+p+2*n] == 0 ||
1131
+ usb_string(udev, buffer[24+p+2*n], unit->name, sizeof(unit->name)) < 0)
10571132 sprintf(unit->name, "Extension %u", buffer[3]);
10581133
10591134 list_add_tail(&unit->list, &dev->entities);
....@@ -1178,15 +1253,15 @@
11781253 memcpy(term->media.bmTransportModes, &buffer[10+n], p);
11791254 }
11801255
1181
- if (buffer[7] != 0)
1182
- usb_string(udev, buffer[7], term->name,
1183
- sizeof(term->name));
1184
- else if (UVC_ENTITY_TYPE(term) == UVC_ITT_CAMERA)
1185
- sprintf(term->name, "Camera %u", buffer[3]);
1186
- else if (UVC_ENTITY_TYPE(term) == UVC_ITT_MEDIA_TRANSPORT_INPUT)
1187
- sprintf(term->name, "Media %u", buffer[3]);
1188
- else
1189
- sprintf(term->name, "Input %u", buffer[3]);
1256
+ if (buffer[7] == 0 ||
1257
+ usb_string(udev, buffer[7], term->name, sizeof(term->name)) < 0) {
1258
+ if (UVC_ENTITY_TYPE(term) == UVC_ITT_CAMERA)
1259
+ sprintf(term->name, "Camera %u", buffer[3]);
1260
+ if (UVC_ENTITY_TYPE(term) == UVC_ITT_MEDIA_TRANSPORT_INPUT)
1261
+ sprintf(term->name, "Media %u", buffer[3]);
1262
+ else
1263
+ sprintf(term->name, "Input %u", buffer[3]);
1264
+ }
11901265
11911266 list_add_tail(&term->list, &dev->entities);
11921267 break;
....@@ -1218,10 +1293,8 @@
12181293
12191294 memcpy(term->baSourceID, &buffer[7], 1);
12201295
1221
- if (buffer[8] != 0)
1222
- usb_string(udev, buffer[8], term->name,
1223
- sizeof(term->name));
1224
- else
1296
+ if (buffer[8] == 0 ||
1297
+ usb_string(udev, buffer[8], term->name, sizeof(term->name)) < 0)
12251298 sprintf(term->name, "Output %u", buffer[3]);
12261299
12271300 list_add_tail(&term->list, &dev->entities);
....@@ -1243,10 +1316,8 @@
12431316
12441317 memcpy(unit->baSourceID, &buffer[5], p);
12451318
1246
- if (buffer[5+p] != 0)
1247
- usb_string(udev, buffer[5+p], unit->name,
1248
- sizeof(unit->name));
1249
- else
1319
+ if (buffer[5+p] == 0 ||
1320
+ usb_string(udev, buffer[5+p], unit->name, sizeof(unit->name)) < 0)
12501321 sprintf(unit->name, "Selector %u", buffer[3]);
12511322
12521323 list_add_tail(&unit->list, &dev->entities);
....@@ -1276,10 +1347,8 @@
12761347 if (dev->uvc_version >= 0x0110)
12771348 unit->processing.bmVideoStandards = buffer[9+n];
12781349
1279
- if (buffer[8+n] != 0)
1280
- usb_string(udev, buffer[8+n], unit->name,
1281
- sizeof(unit->name));
1282
- else
1350
+ if (buffer[8+n] == 0 ||
1351
+ usb_string(udev, buffer[8+n], unit->name, sizeof(unit->name)) < 0)
12831352 sprintf(unit->name, "Processing %u", buffer[3]);
12841353
12851354 list_add_tail(&unit->list, &dev->entities);
....@@ -1307,10 +1376,8 @@
13071376 unit->extension.bmControls = (u8 *)unit + sizeof(*unit);
13081377 memcpy(unit->extension.bmControls, &buffer[23+p], n);
13091378
1310
- if (buffer[23+p+n] != 0)
1311
- usb_string(udev, buffer[23+p+n], unit->name,
1312
- sizeof(unit->name));
1313
- else
1379
+ if (buffer[23+p+n] == 0 ||
1380
+ usb_string(udev, buffer[23+p+n], unit->name, sizeof(unit->name)) < 0)
13141381 sprintf(unit->name, "Extension %u", buffer[3]);
13151382
13161383 list_add_tail(&unit->list, &dev->entities);
....@@ -1517,6 +1584,31 @@
15171584 return -EINVAL;
15181585 }
15191586
1587
+ /*
1588
+ * Some devices reference an output terminal as the
1589
+ * source of extension units. This is incorrect, as
1590
+ * output terminals only have an input pin, and thus
1591
+ * can't be connected to any entity in the forward
1592
+ * direction. The resulting topology would cause issues
1593
+ * when registering the media controller graph. To
1594
+ * avoid this problem, connect the extension unit to
1595
+ * the source of the output terminal instead.
1596
+ */
1597
+ if (UVC_ENTITY_IS_OTERM(entity)) {
1598
+ struct uvc_entity *source;
1599
+
1600
+ source = uvc_entity_by_id(chain->dev,
1601
+ entity->baSourceID[0]);
1602
+ if (!source) {
1603
+ uvc_trace(UVC_TRACE_DESCR,
1604
+ "Can't connect extension unit %u in chain\n",
1605
+ forward->id);
1606
+ break;
1607
+ }
1608
+
1609
+ forward->baSourceID[0] = source->id;
1610
+ }
1611
+
15201612 list_add_tail(&forward->chain, &chain->entities);
15211613 if (uvc_trace_param & UVC_TRACE_PROBE) {
15221614 if (!found)
....@@ -1535,6 +1627,13 @@
15351627 uvc_trace(UVC_TRACE_DESCR, "Unsupported input "
15361628 "terminal %u.\n", forward->id);
15371629 return -EINVAL;
1630
+ }
1631
+
1632
+ if (UVC_ENTITY_IS_OTERM(entity)) {
1633
+ uvc_trace(UVC_TRACE_DESCR,
1634
+ "Unsupported connection between output terminals %u and %u\n",
1635
+ entity->id, forward->id);
1636
+ break;
15381637 }
15391638
15401639 list_add_tail(&forward->chain, &chain->entities);
....@@ -1999,7 +2098,7 @@
19992098 break;
20002099 }
20012100
2002
- strlcpy(vdev->name, dev->name, sizeof(vdev->name));
2101
+ strscpy(vdev->name, dev->name, sizeof(vdev->name));
20032102
20042103 /*
20052104 * Set the driver data before calling video_register_device, otherwise
....@@ -2007,7 +2106,7 @@
20072106 */
20082107 video_set_drvdata(vdev, stream);
20092108
2010
- ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
2109
+ ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
20112110 if (ret < 0) {
20122111 uvc_printk(KERN_ERR, "Failed to register %s device (%d).\n",
20132112 v4l2_type_names[type], ret);
....@@ -2094,10 +2193,9 @@
20942193
20952194 #ifdef CONFIG_MEDIA_CONTROLLER
20962195 ret = uvc_mc_register_entities(chain);
2097
- if (ret < 0) {
2098
- uvc_printk(KERN_INFO, "Failed to register entites "
2099
- "(%d).\n", ret);
2100
- }
2196
+ if (ret < 0)
2197
+ uvc_printk(KERN_INFO,
2198
+ "Failed to register entities (%d).\n", ret);
21012199 #endif
21022200 }
21032201
....@@ -2148,7 +2246,7 @@
21482246 ? dev->info->quirks : uvc_quirks_param;
21492247
21502248 if (udev->product != NULL)
2151
- strlcpy(dev->name, udev->product, sizeof(dev->name));
2249
+ strscpy(dev->name, udev->product, sizeof(dev->name));
21522250 else
21532251 snprintf(dev->name, sizeof(dev->name),
21542252 "UVC Camera (%04x:%04x)",
....@@ -2412,7 +2510,9 @@
24122510 .quirks = UVC_QUIRK_FORCE_Y8,
24132511 };
24142512
2415
-#define UVC_QUIRK_INFO(q) (kernel_ulong_t)&(struct uvc_device_info){.quirks = q}
2513
+#define UVC_INFO_QUIRK(q) (kernel_ulong_t)&(struct uvc_device_info){.quirks = q}
2514
+#define UVC_INFO_META(m) (kernel_ulong_t)&(struct uvc_device_info) \
2515
+ {.meta_format = m}
24162516
24172517 /*
24182518 * The Logitech cameras listed below have their interface class set to
....@@ -2465,6 +2565,24 @@
24652565 .bInterfaceSubClass = 1,
24662566 .bInterfaceProtocol = 0,
24672567 .driver_info = (kernel_ulong_t)&uvc_quirk_probe_minmax },
2568
+ /* Logitech, Webcam C910 */
2569
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2570
+ | USB_DEVICE_ID_MATCH_INT_INFO,
2571
+ .idVendor = 0x046d,
2572
+ .idProduct = 0x0821,
2573
+ .bInterfaceClass = USB_CLASS_VIDEO,
2574
+ .bInterfaceSubClass = 1,
2575
+ .bInterfaceProtocol = 0,
2576
+ .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_WAKE_AUTOSUSPEND)},
2577
+ /* Logitech, Webcam B910 */
2578
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
2579
+ | USB_DEVICE_ID_MATCH_INT_INFO,
2580
+ .idVendor = 0x046d,
2581
+ .idProduct = 0x0823,
2582
+ .bInterfaceClass = USB_CLASS_VIDEO,
2583
+ .bInterfaceSubClass = 1,
2584
+ .bInterfaceProtocol = 0,
2585
+ .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_WAKE_AUTOSUSPEND)},
24682586 /* Logitech Quickcam Fusion */
24692587 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
24702588 | USB_DEVICE_ID_MATCH_INT_INFO,
....@@ -2521,7 +2639,7 @@
25212639 .bInterfaceClass = USB_CLASS_VIDEO,
25222640 .bInterfaceSubClass = 1,
25232641 .bInterfaceProtocol = 0,
2524
- .driver_info = UVC_QUIRK_INFO(UVC_QUIRK_RESTORE_CTRLS_ON_INIT) },
2642
+ .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_RESTORE_CTRLS_ON_INIT) },
25252643 /* Chicony CNF7129 (Asus EEE 100HE) */
25262644 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
25272645 | USB_DEVICE_ID_MATCH_INT_INFO,
....@@ -2530,7 +2648,7 @@
25302648 .bInterfaceClass = USB_CLASS_VIDEO,
25312649 .bInterfaceSubClass = 1,
25322650 .bInterfaceProtocol = 0,
2533
- .driver_info = UVC_QUIRK_INFO(UVC_QUIRK_RESTRICT_FRAME_RATE) },
2651
+ .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_RESTRICT_FRAME_RATE) },
25342652 /* Alcor Micro AU3820 (Future Boy PC USB Webcam) */
25352653 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
25362654 | USB_DEVICE_ID_MATCH_INT_INFO,
....@@ -2593,7 +2711,7 @@
25932711 .bInterfaceClass = USB_CLASS_VIDEO,
25942712 .bInterfaceSubClass = 1,
25952713 .bInterfaceProtocol = 0,
2596
- .driver_info = UVC_QUIRK_INFO(UVC_QUIRK_PROBE_MINMAX
2714
+ .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_PROBE_MINMAX
25972715 | UVC_QUIRK_BUILTIN_ISIGHT) },
25982716 /* Apple Built-In iSight via iBridge */
25992717 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
....@@ -2675,7 +2793,7 @@
26752793 .bInterfaceClass = USB_CLASS_VIDEO,
26762794 .bInterfaceSubClass = 1,
26772795 .bInterfaceProtocol = 0,
2678
- .driver_info = UVC_QUIRK_INFO(UVC_QUIRK_PROBE_MINMAX
2796
+ .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_PROBE_MINMAX
26792797 | UVC_QUIRK_PROBE_DEF) },
26802798 /* IMC Networks (Medion Akoya) */
26812799 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
....@@ -2775,7 +2893,7 @@
27752893 .bInterfaceClass = USB_CLASS_VIDEO,
27762894 .bInterfaceSubClass = 1,
27772895 .bInterfaceProtocol = 0,
2778
- .driver_info = UVC_QUIRK_INFO(UVC_QUIRK_PROBE_MINMAX
2896
+ .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_PROBE_MINMAX
27792897 | UVC_QUIRK_PROBE_EXTRAFIELDS) },
27802898 /* Aveo Technology USB 2.0 Camera (Tasco USB Microscope) */
27812899 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
....@@ -2793,7 +2911,7 @@
27932911 .bInterfaceClass = USB_CLASS_VIDEO,
27942912 .bInterfaceSubClass = 1,
27952913 .bInterfaceProtocol = 0,
2796
- .driver_info = UVC_QUIRK_INFO(UVC_QUIRK_PROBE_EXTRAFIELDS) },
2914
+ .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_PROBE_EXTRAFIELDS) },
27972915 /* Manta MM-353 Plako */
27982916 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
27992917 | USB_DEVICE_ID_MATCH_INT_INFO,
....@@ -2839,7 +2957,7 @@
28392957 .bInterfaceClass = USB_CLASS_VIDEO,
28402958 .bInterfaceSubClass = 1,
28412959 .bInterfaceProtocol = 0,
2842
- .driver_info = UVC_QUIRK_INFO(UVC_QUIRK_STATUS_INTERVAL) },
2960
+ .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_STATUS_INTERVAL) },
28432961 /* MSI StarCam 370i */
28442962 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
28452963 | USB_DEVICE_ID_MATCH_INT_INFO,
....@@ -2866,7 +2984,7 @@
28662984 .bInterfaceClass = USB_CLASS_VIDEO,
28672985 .bInterfaceSubClass = 1,
28682986 .bInterfaceProtocol = 0,
2869
- .driver_info = UVC_QUIRK_INFO(UVC_QUIRK_PROBE_MINMAX
2987
+ .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_PROBE_MINMAX
28702988 | UVC_QUIRK_IGNORE_SELECTOR_UNIT) },
28712989 /* Oculus VR Positional Tracker DK2 */
28722990 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
....@@ -2886,6 +3004,24 @@
28863004 .bInterfaceSubClass = 1,
28873005 .bInterfaceProtocol = 0,
28883006 .driver_info = (kernel_ulong_t)&uvc_quirk_force_y8 },
3007
+ /* GEO Semiconductor GC6500 */
3008
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
3009
+ | USB_DEVICE_ID_MATCH_INT_INFO,
3010
+ .idVendor = 0x29fe,
3011
+ .idProduct = 0x4d53,
3012
+ .bInterfaceClass = USB_CLASS_VIDEO,
3013
+ .bInterfaceSubClass = 1,
3014
+ .bInterfaceProtocol = 0,
3015
+ .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_FORCE_BPP) },
3016
+ /* Intel RealSense D4M */
3017
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
3018
+ | USB_DEVICE_ID_MATCH_INT_INFO,
3019
+ .idVendor = 0x8086,
3020
+ .idProduct = 0x0b03,
3021
+ .bInterfaceClass = USB_CLASS_VIDEO,
3022
+ .bInterfaceSubClass = 1,
3023
+ .bInterfaceProtocol = 0,
3024
+ .driver_info = UVC_INFO_META(V4L2_META_FMT_D4XX) },
28893025 /* Generic USB Video Class */
28903026 { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, UVC_PC_PROTOCOL_UNDEFINED) },
28913027 { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, UVC_PC_PROTOCOL_15) },