forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-09 95099d4622f8cb224d94e314c7a8e0df60b13f87
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];
....@@ -1517,6 +1594,31 @@
15171594 return -EINVAL;
15181595 }
15191596
1597
+ /*
1598
+ * Some devices reference an output terminal as the
1599
+ * source of extension units. This is incorrect, as
1600
+ * output terminals only have an input pin, and thus
1601
+ * can't be connected to any entity in the forward
1602
+ * direction. The resulting topology would cause issues
1603
+ * when registering the media controller graph. To
1604
+ * avoid this problem, connect the extension unit to
1605
+ * the source of the output terminal instead.
1606
+ */
1607
+ if (UVC_ENTITY_IS_OTERM(entity)) {
1608
+ struct uvc_entity *source;
1609
+
1610
+ source = uvc_entity_by_id(chain->dev,
1611
+ entity->baSourceID[0]);
1612
+ if (!source) {
1613
+ uvc_trace(UVC_TRACE_DESCR,
1614
+ "Can't connect extension unit %u in chain\n",
1615
+ forward->id);
1616
+ break;
1617
+ }
1618
+
1619
+ forward->baSourceID[0] = source->id;
1620
+ }
1621
+
15201622 list_add_tail(&forward->chain, &chain->entities);
15211623 if (uvc_trace_param & UVC_TRACE_PROBE) {
15221624 if (!found)
....@@ -1535,6 +1637,13 @@
15351637 uvc_trace(UVC_TRACE_DESCR, "Unsupported input "
15361638 "terminal %u.\n", forward->id);
15371639 return -EINVAL;
1640
+ }
1641
+
1642
+ if (UVC_ENTITY_IS_OTERM(entity)) {
1643
+ uvc_trace(UVC_TRACE_DESCR,
1644
+ "Unsupported connection between output terminals %u and %u\n",
1645
+ entity->id, forward->id);
1646
+ break;
15381647 }
15391648
15401649 list_add_tail(&forward->chain, &chain->entities);
....@@ -1999,7 +2108,7 @@
19992108 break;
20002109 }
20012110
2002
- strlcpy(vdev->name, dev->name, sizeof(vdev->name));
2111
+ strscpy(vdev->name, dev->name, sizeof(vdev->name));
20032112
20042113 /*
20052114 * Set the driver data before calling video_register_device, otherwise
....@@ -2007,7 +2116,7 @@
20072116 */
20082117 video_set_drvdata(vdev, stream);
20092118
2010
- ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
2119
+ ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1);
20112120 if (ret < 0) {
20122121 uvc_printk(KERN_ERR, "Failed to register %s device (%d).\n",
20132122 v4l2_type_names[type], ret);
....@@ -2094,10 +2203,9 @@
20942203
20952204 #ifdef CONFIG_MEDIA_CONTROLLER
20962205 ret = uvc_mc_register_entities(chain);
2097
- if (ret < 0) {
2098
- uvc_printk(KERN_INFO, "Failed to register entites "
2099
- "(%d).\n", ret);
2100
- }
2206
+ if (ret < 0)
2207
+ uvc_printk(KERN_INFO,
2208
+ "Failed to register entities (%d).\n", ret);
21012209 #endif
21022210 }
21032211
....@@ -2148,7 +2256,7 @@
21482256 ? dev->info->quirks : uvc_quirks_param;
21492257
21502258 if (udev->product != NULL)
2151
- strlcpy(dev->name, udev->product, sizeof(dev->name));
2259
+ strscpy(dev->name, udev->product, sizeof(dev->name));
21522260 else
21532261 snprintf(dev->name, sizeof(dev->name),
21542262 "UVC Camera (%04x:%04x)",
....@@ -2412,7 +2520,9 @@
24122520 .quirks = UVC_QUIRK_FORCE_Y8,
24132521 };
24142522
2415
-#define UVC_QUIRK_INFO(q) (kernel_ulong_t)&(struct uvc_device_info){.quirks = q}
2523
+#define UVC_INFO_QUIRK(q) (kernel_ulong_t)&(struct uvc_device_info){.quirks = q}
2524
+#define UVC_INFO_META(m) (kernel_ulong_t)&(struct uvc_device_info) \
2525
+ {.meta_format = m}
24162526
24172527 /*
24182528 * The Logitech cameras listed below have their interface class set to
....@@ -2521,7 +2631,7 @@
25212631 .bInterfaceClass = USB_CLASS_VIDEO,
25222632 .bInterfaceSubClass = 1,
25232633 .bInterfaceProtocol = 0,
2524
- .driver_info = UVC_QUIRK_INFO(UVC_QUIRK_RESTORE_CTRLS_ON_INIT) },
2634
+ .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_RESTORE_CTRLS_ON_INIT) },
25252635 /* Chicony CNF7129 (Asus EEE 100HE) */
25262636 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
25272637 | USB_DEVICE_ID_MATCH_INT_INFO,
....@@ -2530,7 +2640,7 @@
25302640 .bInterfaceClass = USB_CLASS_VIDEO,
25312641 .bInterfaceSubClass = 1,
25322642 .bInterfaceProtocol = 0,
2533
- .driver_info = UVC_QUIRK_INFO(UVC_QUIRK_RESTRICT_FRAME_RATE) },
2643
+ .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_RESTRICT_FRAME_RATE) },
25342644 /* Alcor Micro AU3820 (Future Boy PC USB Webcam) */
25352645 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
25362646 | USB_DEVICE_ID_MATCH_INT_INFO,
....@@ -2593,7 +2703,7 @@
25932703 .bInterfaceClass = USB_CLASS_VIDEO,
25942704 .bInterfaceSubClass = 1,
25952705 .bInterfaceProtocol = 0,
2596
- .driver_info = UVC_QUIRK_INFO(UVC_QUIRK_PROBE_MINMAX
2706
+ .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_PROBE_MINMAX
25972707 | UVC_QUIRK_BUILTIN_ISIGHT) },
25982708 /* Apple Built-In iSight via iBridge */
25992709 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
....@@ -2675,7 +2785,7 @@
26752785 .bInterfaceClass = USB_CLASS_VIDEO,
26762786 .bInterfaceSubClass = 1,
26772787 .bInterfaceProtocol = 0,
2678
- .driver_info = UVC_QUIRK_INFO(UVC_QUIRK_PROBE_MINMAX
2788
+ .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_PROBE_MINMAX
26792789 | UVC_QUIRK_PROBE_DEF) },
26802790 /* IMC Networks (Medion Akoya) */
26812791 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
....@@ -2775,7 +2885,7 @@
27752885 .bInterfaceClass = USB_CLASS_VIDEO,
27762886 .bInterfaceSubClass = 1,
27772887 .bInterfaceProtocol = 0,
2778
- .driver_info = UVC_QUIRK_INFO(UVC_QUIRK_PROBE_MINMAX
2888
+ .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_PROBE_MINMAX
27792889 | UVC_QUIRK_PROBE_EXTRAFIELDS) },
27802890 /* Aveo Technology USB 2.0 Camera (Tasco USB Microscope) */
27812891 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
....@@ -2793,7 +2903,7 @@
27932903 .bInterfaceClass = USB_CLASS_VIDEO,
27942904 .bInterfaceSubClass = 1,
27952905 .bInterfaceProtocol = 0,
2796
- .driver_info = UVC_QUIRK_INFO(UVC_QUIRK_PROBE_EXTRAFIELDS) },
2906
+ .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_PROBE_EXTRAFIELDS) },
27972907 /* Manta MM-353 Plako */
27982908 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
27992909 | USB_DEVICE_ID_MATCH_INT_INFO,
....@@ -2839,7 +2949,7 @@
28392949 .bInterfaceClass = USB_CLASS_VIDEO,
28402950 .bInterfaceSubClass = 1,
28412951 .bInterfaceProtocol = 0,
2842
- .driver_info = UVC_QUIRK_INFO(UVC_QUIRK_STATUS_INTERVAL) },
2952
+ .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_STATUS_INTERVAL) },
28432953 /* MSI StarCam 370i */
28442954 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
28452955 | USB_DEVICE_ID_MATCH_INT_INFO,
....@@ -2866,7 +2976,7 @@
28662976 .bInterfaceClass = USB_CLASS_VIDEO,
28672977 .bInterfaceSubClass = 1,
28682978 .bInterfaceProtocol = 0,
2869
- .driver_info = UVC_QUIRK_INFO(UVC_QUIRK_PROBE_MINMAX
2979
+ .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_PROBE_MINMAX
28702980 | UVC_QUIRK_IGNORE_SELECTOR_UNIT) },
28712981 /* Oculus VR Positional Tracker DK2 */
28722982 { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
....@@ -2886,6 +2996,24 @@
28862996 .bInterfaceSubClass = 1,
28872997 .bInterfaceProtocol = 0,
28882998 .driver_info = (kernel_ulong_t)&uvc_quirk_force_y8 },
2999
+ /* GEO Semiconductor GC6500 */
3000
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
3001
+ | USB_DEVICE_ID_MATCH_INT_INFO,
3002
+ .idVendor = 0x29fe,
3003
+ .idProduct = 0x4d53,
3004
+ .bInterfaceClass = USB_CLASS_VIDEO,
3005
+ .bInterfaceSubClass = 1,
3006
+ .bInterfaceProtocol = 0,
3007
+ .driver_info = UVC_INFO_QUIRK(UVC_QUIRK_FORCE_BPP) },
3008
+ /* Intel RealSense D4M */
3009
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
3010
+ | USB_DEVICE_ID_MATCH_INT_INFO,
3011
+ .idVendor = 0x8086,
3012
+ .idProduct = 0x0b03,
3013
+ .bInterfaceClass = USB_CLASS_VIDEO,
3014
+ .bInterfaceSubClass = 1,
3015
+ .bInterfaceProtocol = 0,
3016
+ .driver_info = UVC_INFO_META(V4L2_META_FMT_D4XX) },
28893017 /* Generic USB Video Class */
28903018 { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, UVC_PC_PROTOCOL_UNDEFINED) },
28913019 { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, UVC_PC_PROTOCOL_15) },