Lines Matching +full:xps +full:- +full:gpio +full:- +full:1

1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * uvc_driver.c -- USB Video Class driver
5 * Copyright (C) 2005-2010
11 #include <linux/gpio/consumer.h>
24 #include <media/v4l2-common.h>
25 #include <media/v4l2-ioctl.h>
35 unsigned int uvc_no_drop_param = 1;
36 static unsigned int uvc_quirks_param = -1;
42 /* ------------------------------------------------------------------------
52 for (i = 0; i < alts->desc.bNumEndpoints; ++i) { in uvc_find_endpoint()
53 ep = &alts->endpoint[i]; in uvc_find_endpoint()
54 if (ep->desc.bEndpointAddress == epaddr) in uvc_find_endpoint()
91 V4L2_XFER_FUNC_709, /* Substitution for BT.470-2 M */ in uvc_xfer_func()
92 V4L2_XFER_FUNC_709, /* Substitution for BT.470-2 B, G */ in uvc_xfer_func()
121 V4L2_YCBCR_ENC_601, /* Substitution for BT.470-2 B, G */ in uvc_ycbcr_enc()
132 /* ------------------------------------------------------------------------
143 list_for_each_entry(entity, &dev->entities, list) { in uvc_entity_by_id()
144 if (entity->id == id) in uvc_entity_by_id()
157 entity = list_entry(&dev->entities, struct uvc_entity, list); in uvc_entity_by_reference()
159 list_for_each_entry_continue(entity, &dev->entities, list) { in uvc_entity_by_reference()
160 for (i = 0; i < entity->bNrInPins; ++i) in uvc_entity_by_reference()
161 if (entity->baSourceID[i] == id) in uvc_entity_by_reference()
173 list_for_each_entry(stream, &dev->streams, list) { in uvc_stream_by_id()
174 count += 1; in uvc_stream_by_id()
176 if (stream->header.bTerminalLink == id) in uvc_stream_by_id()
184 if (count == 1 && id == UVC_INVALID_ENTITY_ID) { in uvc_stream_by_id()
185 dev_warn(&dev->intf->dev, in uvc_stream_by_id()
193 /* ------------------------------------------------------------------------
199 if (stream->async_wq) in uvc_stream_delete()
200 destroy_workqueue(stream->async_wq); in uvc_stream_delete()
202 usb_put_intf(stream->intf); in uvc_stream_delete()
204 kfree(stream->formats); in uvc_stream_delete()
205 kfree(stream->header.bmaControls); in uvc_stream_delete()
218 stream->dev = dev; in uvc_stream_new()
219 stream->intf = usb_get_intf(intf); in uvc_stream_new()
220 stream->intfnum = intf->cur_altsetting->desc.bInterfaceNumber; in uvc_stream_new()
223 stream->async_wq = alloc_workqueue("uvcvideo", WQ_UNBOUND | WQ_HIGHPRI, in uvc_stream_new()
225 if (!stream->async_wq) { in uvc_stream_new()
233 /* ------------------------------------------------------------------------
243 struct usb_host_interface *alts = streaming->intf->cur_altsetting; in uvc_parse_frame()
258 dev->udev->devnum, alts->desc.bInterfaceNumber); in uvc_parse_frame()
259 return -EINVAL; in uvc_parse_frame()
262 frame->bFrameIndex = buffer[3]; in uvc_parse_frame()
263 frame->bmCapabilities = buffer[4]; in uvc_parse_frame()
264 frame->wWidth = get_unaligned_le16(&buffer[5]) * width_multiplier; in uvc_parse_frame()
265 frame->wHeight = get_unaligned_le16(&buffer[7]); in uvc_parse_frame()
266 frame->dwMinBitRate = get_unaligned_le32(&buffer[9]); in uvc_parse_frame()
267 frame->dwMaxBitRate = get_unaligned_le32(&buffer[13]); in uvc_parse_frame()
269 frame->dwMaxVideoFrameBufferSize = in uvc_parse_frame()
271 frame->dwDefaultFrameInterval = in uvc_parse_frame()
273 frame->bFrameIntervalType = buffer[25]; in uvc_parse_frame()
275 frame->dwMaxVideoFrameBufferSize = 0; in uvc_parse_frame()
276 frame->dwDefaultFrameInterval = in uvc_parse_frame()
278 frame->bFrameIntervalType = buffer[21]; in uvc_parse_frame()
286 * all null intervals to 1 fixes the problem and some other divisions in uvc_parse_frame()
289 frame->dwFrameInterval = *intervals; in uvc_parse_frame()
293 (*intervals)[i] = interval ? interval : 1; in uvc_parse_frame()
309 if (!(format->flags & UVC_FMT_FLAG_COMPRESSED)) in uvc_parse_frame()
310 frame->dwMaxVideoFrameBufferSize = format->bpp * frame->wWidth in uvc_parse_frame()
311 * frame->wHeight / 8; in uvc_parse_frame()
317 * dwFrameInterval[1] storing the maximum value. in uvc_parse_frame()
319 maxIntervalIndex = frame->bFrameIntervalType ? n - 1 : 1; in uvc_parse_frame()
320 frame->dwDefaultFrameInterval = in uvc_parse_frame()
321 clamp(frame->dwDefaultFrameInterval, in uvc_parse_frame()
322 frame->dwFrameInterval[0], in uvc_parse_frame()
323 frame->dwFrameInterval[maxIntervalIndex]); in uvc_parse_frame()
330 if (dev->quirks & UVC_QUIRK_RESTRICT_FRAME_RATE) { in uvc_parse_frame()
331 frame->bFrameIntervalType = 1; in uvc_parse_frame()
332 (*intervals)[0] = frame->dwDefaultFrameInterval; in uvc_parse_frame()
335 uvc_dbg(dev, DESCR, "- %ux%u (%u.%u fps)\n", in uvc_parse_frame()
336 frame->wWidth, frame->wHeight, in uvc_parse_frame()
337 10000000 / frame->dwDefaultFrameInterval, in uvc_parse_frame()
338 (100000000 / frame->dwDefaultFrameInterval) % 10); in uvc_parse_frame()
350 struct usb_host_interface *alts = streaming->intf->cur_altsetting; in uvc_parse_format()
354 unsigned int width_multiplier = 1; in uvc_parse_format()
360 return -EINVAL; in uvc_parse_format()
362 format->type = buffer[2]; in uvc_parse_format()
363 format->index = buffer[3]; in uvc_parse_format()
364 format->frames = frames; in uvc_parse_format()
373 dev->udev->devnum, in uvc_parse_format()
374 alts->desc.bInterfaceNumber); in uvc_parse_format()
375 return -EINVAL; in uvc_parse_format()
386 dev_info(&streaming->intf->dev, in uvc_parse_format()
391 format->fcc = fmtdesc->fcc; in uvc_parse_format()
392 format->bpp = buffer[21]; in uvc_parse_format()
398 if (dev->quirks & UVC_QUIRK_FORCE_Y8) { in uvc_parse_format()
399 if (format->fcc == V4L2_PIX_FMT_YUYV) { in uvc_parse_format()
400 format->fcc = V4L2_PIX_FMT_GREY; in uvc_parse_format()
401 format->bpp = 8; in uvc_parse_format()
407 if (dev->quirks & UVC_QUIRK_FORCE_BPP) { in uvc_parse_format()
409 v4l2_format_info(format->fcc); in uvc_parse_format()
412 unsigned int div = info->hdiv * info->vdiv; in uvc_parse_format()
414 n = info->bpp[0] * div; in uvc_parse_format()
415 for (i = 1; i < info->comp_planes; i++) in uvc_parse_format()
416 n += info->bpp[i]; in uvc_parse_format()
418 format->bpp = DIV_ROUND_UP(8 * n, div); in uvc_parse_format()
427 format->flags = UVC_FMT_FLAG_COMPRESSED; in uvc_parse_format()
435 dev->udev->devnum, in uvc_parse_format()
436 alts->desc.bInterfaceNumber); in uvc_parse_format()
437 return -EINVAL; in uvc_parse_format()
440 format->fcc = V4L2_PIX_FMT_MJPEG; in uvc_parse_format()
441 format->flags = UVC_FMT_FLAG_COMPRESSED; in uvc_parse_format()
442 format->bpp = 0; in uvc_parse_format()
450 dev->udev->devnum, in uvc_parse_format()
451 alts->desc.bInterfaceNumber); in uvc_parse_format()
452 return -EINVAL; in uvc_parse_format()
458 dev->udev->devnum, in uvc_parse_format()
459 alts->desc.bInterfaceNumber, buffer[8]); in uvc_parse_format()
460 return -EINVAL; in uvc_parse_format()
463 format->fcc = V4L2_PIX_FMT_DV; in uvc_parse_format()
464 format->flags = UVC_FMT_FLAG_COMPRESSED | UVC_FMT_FLAG_STREAM; in uvc_parse_format()
465 format->bpp = 0; in uvc_parse_format()
471 frame->bFrameIntervalType = 1; in uvc_parse_format()
472 frame->dwDefaultFrameInterval = 1; in uvc_parse_format()
473 frame->dwFrameInterval = *intervals; in uvc_parse_format()
474 *(*intervals)++ = 1; in uvc_parse_format()
475 format->nframes = 1; in uvc_parse_format()
484 dev->udev->devnum, alts->desc.bInterfaceNumber, in uvc_parse_format()
486 return -EINVAL; in uvc_parse_format()
489 uvc_dbg(dev, DESCR, "Found format %p4cc", &format->fcc); in uvc_parse_format()
491 buflen -= buffer[0]; in uvc_parse_format()
499 while (buflen > 2 && buffer[1] == USB_DT_CS_INTERFACE && in uvc_parse_format()
501 frame = &frames[format->nframes]; in uvc_parse_format()
507 format->nframes++; in uvc_parse_format()
508 buflen -= ret; in uvc_parse_format()
513 if (buflen > 2 && buffer[1] == USB_DT_CS_INTERFACE && in uvc_parse_format()
515 buflen -= buffer[0]; in uvc_parse_format()
519 if (buflen > 2 && buffer[1] == USB_DT_CS_INTERFACE && in uvc_parse_format()
524 dev->udev->devnum, in uvc_parse_format()
525 alts->desc.bInterfaceNumber); in uvc_parse_format()
526 return -EINVAL; in uvc_parse_format()
529 format->colorspace = uvc_colorspace(buffer[3]); in uvc_parse_format()
530 format->xfer_func = uvc_xfer_func(buffer[4]); in uvc_parse_format()
531 format->ycbcr_enc = uvc_ycbcr_enc(buffer[5]); in uvc_parse_format()
533 buflen -= buffer[0]; in uvc_parse_format()
536 format->colorspace = V4L2_COLORSPACE_SRGB; in uvc_parse_format()
539 return buffer - start; in uvc_parse_format()
548 struct usb_host_interface *alts = &intf->altsetting[0]; in uvc_parse_streaming()
549 const unsigned char *_buffer, *buffer = alts->extra; in uvc_parse_streaming()
550 int _buflen, buflen = alts->extralen; in uvc_parse_streaming()
555 int ret = -EINVAL; in uvc_parse_streaming()
557 if (intf->cur_altsetting->desc.bInterfaceSubClass in uvc_parse_streaming()
561 dev->udev->devnum, in uvc_parse_streaming()
562 intf->altsetting[0].desc.bInterfaceNumber); in uvc_parse_streaming()
563 return -EINVAL; in uvc_parse_streaming()
569 dev->udev->devnum, in uvc_parse_streaming()
570 intf->altsetting[0].desc.bInterfaceNumber); in uvc_parse_streaming()
571 return -EINVAL; in uvc_parse_streaming()
577 return -ENOMEM; in uvc_parse_streaming()
581 * The Pico iMage webcam has its class-specific interface descriptors in uvc_parse_streaming()
585 for (i = 0; i < alts->desc.bNumEndpoints; ++i) { in uvc_parse_streaming()
586 struct usb_host_endpoint *ep = &alts->endpoint[i]; in uvc_parse_streaming()
588 if (ep->extralen == 0) in uvc_parse_streaming()
591 if (ep->extralen > 2 && in uvc_parse_streaming()
592 ep->extra[1] == USB_DT_CS_INTERFACE) { in uvc_parse_streaming()
596 buffer = alts->endpoint[i].extra; in uvc_parse_streaming()
597 buflen = alts->endpoint[i].extralen; in uvc_parse_streaming()
604 while (buflen > 2 && buffer[1] != USB_DT_CS_INTERFACE) { in uvc_parse_streaming()
605 buflen -= buffer[0]; in uvc_parse_streaming()
611 "no class-specific streaming interface descriptors found\n"); in uvc_parse_streaming()
618 streaming->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; in uvc_parse_streaming()
623 streaming->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; in uvc_parse_streaming()
630 dev->udev->devnum, alts->desc.bInterfaceNumber); in uvc_parse_streaming()
635 n = buflen >= size ? buffer[size-1] : 0; in uvc_parse_streaming()
640 dev->udev->devnum, alts->desc.bInterfaceNumber); in uvc_parse_streaming()
644 streaming->header.bNumFormats = p; in uvc_parse_streaming()
645 streaming->header.bEndpointAddress = buffer[6]; in uvc_parse_streaming()
647 streaming->header.bmInfo = buffer[7]; in uvc_parse_streaming()
648 streaming->header.bTerminalLink = buffer[8]; in uvc_parse_streaming()
649 streaming->header.bStillCaptureMethod = buffer[9]; in uvc_parse_streaming()
650 streaming->header.bTriggerSupport = buffer[10]; in uvc_parse_streaming()
651 streaming->header.bTriggerUsage = buffer[11]; in uvc_parse_streaming()
653 streaming->header.bTerminalLink = buffer[7]; in uvc_parse_streaming()
655 streaming->header.bControlSize = n; in uvc_parse_streaming()
657 streaming->header.bmaControls = kmemdup(&buffer[size], p * n, in uvc_parse_streaming()
659 if (streaming->header.bmaControls == NULL) { in uvc_parse_streaming()
660 ret = -ENOMEM; in uvc_parse_streaming()
664 buflen -= buffer[0]; in uvc_parse_streaming()
671 while (_buflen > 2 && _buffer[1] == USB_DT_CS_INTERFACE) { in uvc_parse_streaming()
693 dev->udev->devnum, in uvc_parse_streaming()
694 alts->desc.bInterfaceNumber, _buffer[2]); in uvc_parse_streaming()
711 _buflen -= _buffer[0]; in uvc_parse_streaming()
718 dev->udev->devnum, alts->desc.bInterfaceNumber); in uvc_parse_streaming()
734 ret = -ENOMEM; in uvc_parse_streaming()
743 streaming->formats = format; in uvc_parse_streaming()
744 streaming->nformats = 0; in uvc_parse_streaming()
747 while (buflen > 2 && buffer[1] == USB_DT_CS_INTERFACE) { in uvc_parse_streaming()
760 streaming->nformats++; in uvc_parse_streaming()
761 frame += format->nframes; in uvc_parse_streaming()
764 buflen -= ret; in uvc_parse_streaming()
772 buflen -= buffer[0]; in uvc_parse_streaming()
779 dev->udev->devnum, alts->desc.bInterfaceNumber, buflen); in uvc_parse_streaming()
782 for (i = 0; i < intf->num_altsetting; ++i) { in uvc_parse_streaming()
785 alts = &intf->altsetting[i]; in uvc_parse_streaming()
787 streaming->header.bEndpointAddress); in uvc_parse_streaming()
790 psize = usb_endpoint_max_periodic_payload(dev->udev, ep); in uvc_parse_streaming()
791 if (psize > streaming->maxpsize) in uvc_parse_streaming()
792 streaming->maxpsize = psize; in uvc_parse_streaming()
795 list_add_tail(&streaming->list, &dev->streams); in uvc_parse_streaming()
819 /* Per UVC 1.1+ spec 3.7.2, the ID should be non-zero. */ in uvc_alloc_new_entity()
821 dev_err(&dev->intf->dev, "Found Unit with invalid ID 0\n"); in uvc_alloc_new_entity()
827 dev_err(&dev->intf->dev, "Found multiple Units with ID %u\n", id); in uvc_alloc_new_entity()
831 extra_size = roundup(extra_size, sizeof(*entity->pads)); in uvc_alloc_new_entity()
833 num_inputs = type & UVC_TERM_OUTPUT ? num_pads : num_pads - 1; in uvc_alloc_new_entity()
836 size = sizeof(*entity) + extra_size + sizeof(*entity->pads) * num_pads in uvc_alloc_new_entity()
840 return ERR_PTR(-ENOMEM); in uvc_alloc_new_entity()
842 entity->id = id; in uvc_alloc_new_entity()
843 entity->type = type; in uvc_alloc_new_entity()
851 memcpy(entity->guid, uvc_gpio_guid, 16); in uvc_alloc_new_entity()
854 memcpy(entity->guid, uvc_camera_guid, 16); in uvc_alloc_new_entity()
857 memcpy(entity->guid, uvc_media_transport_input_guid, 16); in uvc_alloc_new_entity()
860 memcpy(entity->guid, uvc_processing_guid, 16); in uvc_alloc_new_entity()
864 entity->num_links = 0; in uvc_alloc_new_entity()
865 entity->num_pads = num_pads; in uvc_alloc_new_entity()
866 entity->pads = ((void *)(entity + 1)) + extra_size; in uvc_alloc_new_entity()
869 entity->pads[i].flags = MEDIA_PAD_FL_SINK; in uvc_alloc_new_entity()
871 entity->pads[num_pads-1].flags = MEDIA_PAD_FL_SOURCE; in uvc_alloc_new_entity()
873 entity->bNrInPins = num_inputs; in uvc_alloc_new_entity()
874 entity->baSourceID = (u8 *)(&entity->pads[num_pads]); in uvc_alloc_new_entity()
891 ret = usb_string(dev->udev, string_id, entity->name, in uvc_entity_set_name()
892 sizeof(entity->name)); in uvc_entity_set_name()
897 sprintf(entity->name, "%s %u", type_name, entity->id); in uvc_entity_set_name()
900 /* Parse vendor-specific extensions. */
904 struct usb_device *udev = dev->udev; in uvc_parse_vendor_control()
905 struct usb_host_interface *alts = dev->intf->cur_altsetting; in uvc_parse_vendor_control()
910 switch (le16_to_cpu(udev->descriptor.idVendor)) { in uvc_parse_vendor_control()
912 if (buffer[1] != 0x41 || buffer[2] != 0x01) in uvc_parse_vendor_control()
924 * ---------------------------------------------------------- in uvc_parse_vendor_control()
925 * 0 bLength 1 Number in uvc_parse_vendor_control()
927 * ---------------------------------------------------------- in uvc_parse_vendor_control()
931 * 1: Relative in uvc_parse_vendor_control()
934 * ---------------------------------------------------------- in uvc_parse_vendor_control()
935 * 23+p+n*2 bReserved 1 Boolean in uvc_parse_vendor_control()
936 * ---------------------------------------------------------- in uvc_parse_vendor_control()
937 * 24+p+n*2 iExtension 1 Index in uvc_parse_vendor_control()
940 * ---------------------------------------------------------- in uvc_parse_vendor_control()
948 udev->devnum, alts->desc.bInterfaceNumber); in uvc_parse_vendor_control()
953 buffer[3], p + 1, 2 * n); in uvc_parse_vendor_control()
957 memcpy(unit->guid, &buffer[4], 16); in uvc_parse_vendor_control()
958 unit->extension.bNumControls = buffer[20]; in uvc_parse_vendor_control()
959 memcpy(unit->baSourceID, &buffer[22], p); in uvc_parse_vendor_control()
960 unit->extension.bControlSize = buffer[22+p]; in uvc_parse_vendor_control()
961 unit->extension.bmControls = (u8 *)unit + sizeof(*unit); in uvc_parse_vendor_control()
962 unit->extension.bmControlsType = (u8 *)unit + sizeof(*unit) in uvc_parse_vendor_control()
964 memcpy(unit->extension.bmControls, &buffer[23+p], 2*n); in uvc_parse_vendor_control()
968 list_add_tail(&unit->list, &dev->entities); in uvc_parse_vendor_control()
969 handled = 1; in uvc_parse_vendor_control()
979 struct usb_device *udev = dev->udev; in uvc_parse_standard_control()
982 struct usb_host_interface *alts = dev->intf->cur_altsetting; in uvc_parse_standard_control()
994 udev->devnum, alts->desc.bInterfaceNumber); in uvc_parse_standard_control()
995 return -EINVAL; in uvc_parse_standard_control()
998 dev->uvc_version = get_unaligned_le16(&buffer[3]); in uvc_parse_standard_control()
999 dev->clock_frequency = get_unaligned_le32(&buffer[7]); in uvc_parse_standard_control()
1007 udev->devnum, i); in uvc_parse_standard_control()
1019 udev->devnum, alts->desc.bInterfaceNumber); in uvc_parse_standard_control()
1020 return -EINVAL; in uvc_parse_standard_control()
1026 * - The high byte must be non-zero, otherwise it would be in uvc_parse_standard_control()
1029 * - Bit 15 must be 0, as we use it internally as a terminal in uvc_parse_standard_control()
1038 udev->devnum, alts->desc.bInterfaceNumber, in uvc_parse_standard_control()
1060 udev->devnum, alts->desc.bInterfaceNumber); in uvc_parse_standard_control()
1061 return -EINVAL; in uvc_parse_standard_control()
1065 buffer[3], 1, n + p); in uvc_parse_standard_control()
1070 term->camera.bControlSize = n; in uvc_parse_standard_control()
1071 term->camera.bmControls = (u8 *)term + sizeof(*term); in uvc_parse_standard_control()
1072 term->camera.wObjectiveFocalLengthMin = in uvc_parse_standard_control()
1074 term->camera.wObjectiveFocalLengthMax = in uvc_parse_standard_control()
1076 term->camera.wOcularFocalLength = in uvc_parse_standard_control()
1078 memcpy(term->camera.bmControls, &buffer[15], n); in uvc_parse_standard_control()
1081 term->media.bControlSize = n; in uvc_parse_standard_control()
1082 term->media.bmControls = (u8 *)term + sizeof(*term); in uvc_parse_standard_control()
1083 term->media.bTransportModeSize = p; in uvc_parse_standard_control()
1084 term->media.bmTransportModes = (u8 *)term in uvc_parse_standard_control()
1086 memcpy(term->media.bmControls, &buffer[9], n); in uvc_parse_standard_control()
1087 memcpy(term->media.bmTransportModes, &buffer[10+n], p); in uvc_parse_standard_control()
1099 list_add_tail(&term->list, &dev->entities); in uvc_parse_standard_control()
1106 udev->devnum, alts->desc.bInterfaceNumber); in uvc_parse_standard_control()
1107 return -EINVAL; in uvc_parse_standard_control()
1118 udev->devnum, alts->desc.bInterfaceNumber, in uvc_parse_standard_control()
1124 buffer[3], 1, 0); in uvc_parse_standard_control()
1128 memcpy(term->baSourceID, &buffer[7], 1); in uvc_parse_standard_control()
1132 list_add_tail(&term->list, &dev->entities); in uvc_parse_standard_control()
1141 udev->devnum, alts->desc.bInterfaceNumber); in uvc_parse_standard_control()
1142 return -EINVAL; in uvc_parse_standard_control()
1146 p + 1, 0); in uvc_parse_standard_control()
1150 memcpy(unit->baSourceID, &buffer[5], p); in uvc_parse_standard_control()
1154 list_add_tail(&unit->list, &dev->entities); in uvc_parse_standard_control()
1159 p = dev->uvc_version >= 0x0110 ? 10 : 9; in uvc_parse_standard_control()
1164 udev->devnum, alts->desc.bInterfaceNumber); in uvc_parse_standard_control()
1165 return -EINVAL; in uvc_parse_standard_control()
1172 memcpy(unit->baSourceID, &buffer[4], 1); in uvc_parse_standard_control()
1173 unit->processing.wMaxMultiplier = in uvc_parse_standard_control()
1175 unit->processing.bControlSize = buffer[7]; in uvc_parse_standard_control()
1176 unit->processing.bmControls = (u8 *)unit + sizeof(*unit); in uvc_parse_standard_control()
1177 memcpy(unit->processing.bmControls, &buffer[8], n); in uvc_parse_standard_control()
1178 if (dev->uvc_version >= 0x0110) in uvc_parse_standard_control()
1179 unit->processing.bmVideoStandards = buffer[9+n]; in uvc_parse_standard_control()
1183 list_add_tail(&unit->list, &dev->entities); in uvc_parse_standard_control()
1193 udev->devnum, alts->desc.bInterfaceNumber); in uvc_parse_standard_control()
1194 return -EINVAL; in uvc_parse_standard_control()
1198 p + 1, n); in uvc_parse_standard_control()
1202 memcpy(unit->guid, &buffer[4], 16); in uvc_parse_standard_control()
1203 unit->extension.bNumControls = buffer[20]; in uvc_parse_standard_control()
1204 memcpy(unit->baSourceID, &buffer[22], p); in uvc_parse_standard_control()
1205 unit->extension.bControlSize = buffer[22+p]; in uvc_parse_standard_control()
1206 unit->extension.bmControls = (u8 *)unit + sizeof(*unit); in uvc_parse_standard_control()
1207 memcpy(unit->extension.bmControls, &buffer[23+p], n); in uvc_parse_standard_control()
1211 list_add_tail(&unit->list, &dev->entities); in uvc_parse_standard_control()
1226 struct usb_host_interface *alts = dev->intf->cur_altsetting; in uvc_parse_control()
1227 const unsigned char *buffer = alts->extra; in uvc_parse_control()
1228 int buflen = alts->extralen; in uvc_parse_control()
1239 buffer[1] != USB_DT_CS_INTERFACE) in uvc_parse_control()
1247 buflen -= buffer[0]; in uvc_parse_control()
1252 * Check if the optional status endpoint is present. Built-in iSight in uvc_parse_control()
1257 if (alts->desc.bNumEndpoints == 1 && in uvc_parse_control()
1258 !(dev->quirks & UVC_QUIRK_BUILTIN_ISIGHT)) { in uvc_parse_control()
1259 struct usb_host_endpoint *ep = &alts->endpoint[0]; in uvc_parse_control()
1260 struct usb_endpoint_descriptor *desc = &ep->desc; in uvc_parse_control()
1263 le16_to_cpu(desc->wMaxPacketSize) >= 8 && in uvc_parse_control()
1264 desc->bInterval != 0) { in uvc_parse_control()
1267 desc->bEndpointAddress); in uvc_parse_control()
1268 dev->int_ep = ep; in uvc_parse_control()
1275 /* -----------------------------------------------------------------------------
1276 * Privacy GPIO
1281 struct uvc_entity *unit = dev->gpio_unit; in uvc_gpio_event()
1288 new_val = gpiod_get_value_cansleep(unit->gpio.gpio_privacy); in uvc_gpio_event()
1290 /* GPIO entities are always on the first chain. */ in uvc_gpio_event()
1291 chain = list_first_entry(&dev->chains, struct uvc_video_chain, list); in uvc_gpio_event()
1292 uvc_ctrl_status_event(chain, unit->controls, &new_val); in uvc_gpio_event()
1298 if (cs != UVC_CT_PRIVACY_CONTROL || size < 1) in uvc_gpio_get_cur()
1299 return -EINVAL; in uvc_gpio_get_cur()
1301 *(u8 *)data = gpiod_get_value_cansleep(entity->gpio.gpio_privacy); in uvc_gpio_get_cur()
1310 return -EINVAL; in uvc_gpio_get_info()
1330 gpio_privacy = devm_gpiod_get_optional(&dev->intf->dev, "privacy", in uvc_gpio_parse()
1336 return dev_err_probe(&dev->intf->dev, in uvc_gpio_parse()
1338 "Can't get privacy GPIO\n"); in uvc_gpio_parse()
1342 return dev_err_probe(&dev->intf->dev, irq, in uvc_gpio_parse()
1343 "No IRQ for privacy GPIO\n"); in uvc_gpio_parse()
1346 UVC_EXT_GPIO_UNIT_ID, 0, 1); in uvc_gpio_parse()
1350 unit->gpio.gpio_privacy = gpio_privacy; in uvc_gpio_parse()
1351 unit->gpio.irq = irq; in uvc_gpio_parse()
1352 unit->gpio.bControlSize = 1; in uvc_gpio_parse()
1353 unit->gpio.bmControls = (u8 *)unit + sizeof(*unit); in uvc_gpio_parse()
1354 unit->gpio.bmControls[0] = 1; in uvc_gpio_parse()
1355 unit->get_cur = uvc_gpio_get_cur; in uvc_gpio_parse()
1356 unit->get_info = uvc_gpio_get_info; in uvc_gpio_parse()
1357 strscpy(unit->name, "GPIO", sizeof(unit->name)); in uvc_gpio_parse()
1359 list_add_tail(&unit->list, &dev->entities); in uvc_gpio_parse()
1361 dev->gpio_unit = unit; in uvc_gpio_parse()
1368 struct uvc_entity *unit = dev->gpio_unit; in uvc_gpio_init_irq()
1371 if (!unit || unit->gpio.irq < 0) in uvc_gpio_init_irq()
1374 ret = request_threaded_irq(unit->gpio.irq, NULL, uvc_gpio_irq, in uvc_gpio_init_irq()
1379 unit->gpio.initialized = !ret; in uvc_gpio_init_irq()
1386 if (!dev->gpio_unit || !dev->gpio_unit->gpio.initialized) in uvc_gpio_deinit()
1389 free_irq(dev->gpio_unit->gpio.irq, dev); in uvc_gpio_deinit()
1392 /* ------------------------------------------------------------------------
1400 * - one or more Output Terminals (USB Streaming or Display)
1401 * - zero or one Processing Unit
1402 * - zero, one or more single-input Selector Units
1403 * - zero or one multiple-input Selector Units, provided all inputs are
1405 * - zero, one or mode single-input Extension Units
1406 * - one or more Input Terminals (Camera, External or USB Streaming)
1410 * ITT_*(0) -> +---------+ +---------+ +---------+ -> TT_STREAMING(0)
1411 * ... | SU{0,1} | -> | PU{0,1} | -> | XU{0,n} | ...
1412 * ITT_*(n) -> +---------+ +---------+ +---------+ -> TT_STREAMING(n)
1414 * +---------+ +---------+ -> OTT_*(0)
1415 * TT_STREAMING -> | PU{0,1} | -> | XU{0,n} | ...
1416 * +---------+ +---------+ -> OTT_*(n)
1419 * Extension Units connected to the main chain as single-unit branches are
1420 * also supported. Single-input Selector Units are ignored.
1427 uvc_dbg_cont(PROBE, " <- XU %d", entity->id); in uvc_scan_chain_entity()
1429 if (entity->bNrInPins != 1) { in uvc_scan_chain_entity()
1430 uvc_dbg(chain->dev, DESCR, in uvc_scan_chain_entity()
1431 "Extension unit %d has more than 1 input pin\n", in uvc_scan_chain_entity()
1432 entity->id); in uvc_scan_chain_entity()
1433 return -1; in uvc_scan_chain_entity()
1439 uvc_dbg_cont(PROBE, " <- PU %d", entity->id); in uvc_scan_chain_entity()
1441 if (chain->processing != NULL) { in uvc_scan_chain_entity()
1442 uvc_dbg(chain->dev, DESCR, in uvc_scan_chain_entity()
1444 return -1; in uvc_scan_chain_entity()
1447 chain->processing = entity; in uvc_scan_chain_entity()
1451 uvc_dbg_cont(PROBE, " <- SU %d", entity->id); in uvc_scan_chain_entity()
1453 /* Single-input selector units are ignored. */ in uvc_scan_chain_entity()
1454 if (entity->bNrInPins == 1) in uvc_scan_chain_entity()
1457 if (chain->selector != NULL) { in uvc_scan_chain_entity()
1458 uvc_dbg(chain->dev, DESCR, in uvc_scan_chain_entity()
1460 return -1; in uvc_scan_chain_entity()
1463 chain->selector = entity; in uvc_scan_chain_entity()
1469 uvc_dbg_cont(PROBE, " <- IT %d\n", entity->id); in uvc_scan_chain_entity()
1476 uvc_dbg_cont(PROBE, " OT %d", entity->id); in uvc_scan_chain_entity()
1482 uvc_dbg_cont(PROBE, " <- IT %d\n", entity->id); in uvc_scan_chain_entity()
1484 uvc_dbg_cont(PROBE, " OT %d", entity->id); in uvc_scan_chain_entity()
1489 uvc_dbg(chain->dev, DESCR, in uvc_scan_chain_entity()
1492 return -1; in uvc_scan_chain_entity()
1495 list_add_tail(&entity->chain, &chain->entities); in uvc_scan_chain_entity()
1509 while (1) { in uvc_scan_chain_forward()
1510 forward = uvc_entity_by_reference(chain->dev, entity->id, in uvc_scan_chain_forward()
1516 if (forward->chain.next || forward->chain.prev) { in uvc_scan_chain_forward()
1517 uvc_dbg(chain->dev, DESCR, in uvc_scan_chain_forward()
1519 forward->id); in uvc_scan_chain_forward()
1520 return -EINVAL; in uvc_scan_chain_forward()
1525 if (forward->bNrInPins != 1) { in uvc_scan_chain_forward()
1526 uvc_dbg(chain->dev, DESCR, in uvc_scan_chain_forward()
1527 "Extension unit %d has more than 1 input pin\n", in uvc_scan_chain_forward()
1528 forward->id); in uvc_scan_chain_forward()
1529 return -EINVAL; in uvc_scan_chain_forward()
1545 source = uvc_entity_by_id(chain->dev, in uvc_scan_chain_forward()
1546 entity->baSourceID[0]); in uvc_scan_chain_forward()
1548 uvc_dbg(chain->dev, DESCR, in uvc_scan_chain_forward()
1550 forward->id); in uvc_scan_chain_forward()
1554 forward->baSourceID[0] = source->id; in uvc_scan_chain_forward()
1557 list_add_tail(&forward->chain, &chain->entities); in uvc_scan_chain_forward()
1559 uvc_dbg_cont(PROBE, " (->"); in uvc_scan_chain_forward()
1561 uvc_dbg_cont(PROBE, " XU %d", forward->id); in uvc_scan_chain_forward()
1562 found = 1; in uvc_scan_chain_forward()
1570 uvc_dbg(chain->dev, DESCR, in uvc_scan_chain_forward()
1572 forward->id); in uvc_scan_chain_forward()
1573 return -EINVAL; in uvc_scan_chain_forward()
1577 uvc_dbg(chain->dev, DESCR, in uvc_scan_chain_forward()
1579 entity->id, forward->id); in uvc_scan_chain_forward()
1583 list_add_tail(&forward->chain, &chain->entities); in uvc_scan_chain_forward()
1585 uvc_dbg_cont(PROBE, " (->"); in uvc_scan_chain_forward()
1587 uvc_dbg_cont(PROBE, " OT %d", forward->id); in uvc_scan_chain_forward()
1588 found = 1; in uvc_scan_chain_forward()
1603 int id = -EINVAL, i; in uvc_scan_chain_backward()
1608 id = entity->baSourceID[0]; in uvc_scan_chain_backward()
1612 /* Single-input selector units are ignored. */ in uvc_scan_chain_backward()
1613 if (entity->bNrInPins == 1) { in uvc_scan_chain_backward()
1614 id = entity->baSourceID[0]; in uvc_scan_chain_backward()
1618 uvc_dbg_cont(PROBE, " <- IT"); in uvc_scan_chain_backward()
1620 chain->selector = entity; in uvc_scan_chain_backward()
1621 for (i = 0; i < entity->bNrInPins; ++i) { in uvc_scan_chain_backward()
1622 id = entity->baSourceID[i]; in uvc_scan_chain_backward()
1623 term = uvc_entity_by_id(chain->dev, id); in uvc_scan_chain_backward()
1625 uvc_dbg(chain->dev, DESCR, in uvc_scan_chain_backward()
1627 entity->id, i); in uvc_scan_chain_backward()
1628 return -1; in uvc_scan_chain_backward()
1631 if (term->chain.next || term->chain.prev) { in uvc_scan_chain_backward()
1632 uvc_dbg(chain->dev, DESCR, in uvc_scan_chain_backward()
1634 term->id); in uvc_scan_chain_backward()
1635 return -EINVAL; in uvc_scan_chain_backward()
1638 uvc_dbg_cont(PROBE, " %d", term->id); in uvc_scan_chain_backward()
1640 list_add_tail(&term->chain, &chain->entities); in uvc_scan_chain_backward()
1656 id = UVC_ENTITY_IS_OTERM(entity) ? entity->baSourceID[0] : 0; in uvc_scan_chain_backward()
1665 entity = uvc_entity_by_id(chain->dev, id); in uvc_scan_chain_backward()
1667 uvc_dbg(chain->dev, DESCR, in uvc_scan_chain_backward()
1669 return -EINVAL; in uvc_scan_chain_backward()
1681 uvc_dbg(chain->dev, PROBE, "Scanning UVC chain:"); in uvc_scan_chain()
1688 if (entity->chain.next || entity->chain.prev) { in uvc_scan_chain()
1689 uvc_dbg(chain->dev, DESCR, in uvc_scan_chain()
1691 entity->id); in uvc_scan_chain()
1692 return -EINVAL; in uvc_scan_chain()
1697 return -EINVAL; in uvc_scan_chain()
1701 return -EINVAL; in uvc_scan_chain()
1706 return -EINVAL; in uvc_scan_chain()
1730 p += sprintf(p, "%u", term->id); in uvc_print_terms()
1733 return p - buffer; in uvc_print_terms()
1741 p += uvc_print_terms(&chain->entities, UVC_TERM_INPUT, p); in uvc_print_chain()
1742 p += sprintf(p, " -> "); in uvc_print_chain()
1743 uvc_print_terms(&chain->entities, UVC_TERM_OUTPUT, p); in uvc_print_chain()
1756 INIT_LIST_HEAD(&chain->entities); in uvc_alloc_chain()
1757 mutex_init(&chain->ctrl_mutex); in uvc_alloc_chain()
1758 chain->dev = dev; in uvc_alloc_chain()
1759 v4l2_prio_init(&chain->prio); in uvc_alloc_chain()
1774 * - Acer Integrated Camera (5986:055a)
1775 * - Realtek rtl157a7 (0bda:57a7)
1789 list_for_each_entry(entity, &dev->entities, list) { in uvc_scan_fallback()
1792 return -EINVAL; in uvc_scan_fallback()
1798 return -EINVAL; in uvc_scan_fallback()
1804 return -EINVAL; in uvc_scan_fallback()
1809 return -ENOMEM; in uvc_scan_fallback()
1823 list_for_each_entry_reverse(entity, &dev->entities, list) { in uvc_scan_fallback()
1824 if (entity->type != UVC_VC_PROCESSING_UNIT && in uvc_scan_fallback()
1825 entity->type != UVC_VC_EXTENSION_UNIT) in uvc_scan_fallback()
1828 if (entity->num_pads != 2) in uvc_scan_fallback()
1834 prev->baSourceID[0] = entity->id; in uvc_scan_fallback()
1841 prev->baSourceID[0] = iterm->id; in uvc_scan_fallback()
1843 list_add_tail(&chain->list, &dev->chains); in uvc_scan_fallback()
1852 return -EINVAL; in uvc_scan_fallback()
1865 list_for_each_entry(term, &dev->entities, list) { in uvc_scan_device()
1875 if (term->chain.next || term->chain.prev) in uvc_scan_device()
1880 return -ENOMEM; in uvc_scan_device()
1882 term->flags |= UVC_ENTITY_FLAG_DEFAULT; in uvc_scan_device()
1892 list_add_tail(&chain->list, &dev->chains); in uvc_scan_device()
1895 if (list_empty(&dev->chains)) in uvc_scan_device()
1898 if (list_empty(&dev->chains)) { in uvc_scan_device()
1899 dev_info(&dev->intf->dev, "No valid video chain found.\n"); in uvc_scan_device()
1900 return -ENODEV; in uvc_scan_device()
1903 /* Add GPIO entity to the first chain. */ in uvc_scan_device()
1904 if (dev->gpio_unit) { in uvc_scan_device()
1905 chain = list_first_entry(&dev->chains, in uvc_scan_device()
1907 list_add_tail(&dev->gpio_unit->chain, &chain->entities); in uvc_scan_device()
1913 /* ------------------------------------------------------------------------
1935 usb_put_intf(dev->intf); in uvc_delete()
1936 usb_put_dev(dev->udev); in uvc_delete()
1939 media_device_cleanup(&dev->mdev); in uvc_delete()
1942 list_for_each_safe(p, n, &dev->chains) { in uvc_delete()
1949 list_for_each_safe(p, n, &dev->entities) { in uvc_delete()
1959 list_for_each_safe(p, n, &dev->streams) { in uvc_delete()
1963 usb_driver_release_interface(&uvc_driver, streaming->intf); in uvc_delete()
1973 struct uvc_device *dev = stream->dev; in uvc_release()
1975 kref_put(&dev->ref, uvc_delete); in uvc_release()
1987 list_for_each_entry(stream, &dev->streams, list) { in uvc_unregister_video()
1989 if (!video_is_registered(&stream->queue.vdev)) in uvc_unregister_video()
1992 vb2_video_unregister_device(&stream->queue.vdev); in uvc_unregister_video()
1993 vb2_video_unregister_device(&stream->meta.queue.vdev); in uvc_unregister_video()
1997 * return -ENODEV. in uvc_unregister_video()
2005 if (dev->vdev.dev) in uvc_unregister_video()
2006 v4l2_device_unregister(&dev->vdev); in uvc_unregister_video()
2008 if (media_devnode_is_registered(dev->mdev.devnode)) in uvc_unregister_video()
2009 media_device_unregister(&dev->mdev); in uvc_unregister_video()
2020 struct video_device *vdev = &queue->vdev; in uvc_register_video_device()
2031 * We already hold a reference to dev->udev. The video device will be in uvc_register_video_device()
2035 vdev->v4l2_dev = &dev->vdev; in uvc_register_video_device()
2036 vdev->fops = fops; in uvc_register_video_device()
2037 vdev->ioctl_ops = ioctl_ops; in uvc_register_video_device()
2038 vdev->release = uvc_release; in uvc_register_video_device()
2039 vdev->prio = &stream->chain->prio; in uvc_register_video_device()
2040 vdev->queue = &queue->queue; in uvc_register_video_device()
2041 vdev->lock = &queue->mutex; in uvc_register_video_device()
2043 vdev->vfl_dir = VFL_DIR_TX; in uvc_register_video_device()
2045 vdev->vfl_dir = VFL_DIR_RX; in uvc_register_video_device()
2050 vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; in uvc_register_video_device()
2053 vdev->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING; in uvc_register_video_device()
2056 vdev->device_caps = V4L2_CAP_META_CAPTURE | V4L2_CAP_STREAMING; in uvc_register_video_device()
2060 strscpy(vdev->name, dev->name, sizeof(vdev->name)); in uvc_register_video_device()
2068 ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1); in uvc_register_video_device()
2070 dev_err(&stream->intf->dev, in uvc_register_video_device()
2076 kref_get(&dev->ref); in uvc_register_video_device()
2088 dev_err(&stream->intf->dev, in uvc_register_video()
2093 if (stream->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) in uvc_register_video()
2094 stream->chain->caps |= V4L2_CAP_VIDEO_CAPTURE in uvc_register_video()
2097 stream->chain->caps |= V4L2_CAP_VIDEO_OUTPUT; in uvc_register_video()
2102 return uvc_register_video_device(dev, stream, &stream->queue, in uvc_register_video()
2103 stream->type, &uvc_fops, in uvc_register_video()
2117 list_for_each_entry(term, &chain->entities, chain) { in uvc_register_terms()
2121 stream = uvc_stream_by_id(dev, term->id); in uvc_register_terms()
2123 dev_info(&dev->intf->dev, in uvc_register_terms()
2125 term->id); in uvc_register_terms()
2129 stream->chain = chain; in uvc_register_terms()
2140 term->vdev = &stream->queue.vdev; in uvc_register_terms()
2151 list_for_each_entry(chain, &dev->chains, list) { in uvc_register_chains()
2159 dev_info(&dev->intf->dev, in uvc_register_chains()
2167 /* ------------------------------------------------------------------------
2179 (const struct uvc_device_info *)id->driver_info; in uvc_probe()
2186 return -ENOMEM; in uvc_probe()
2188 INIT_LIST_HEAD(&dev->entities); in uvc_probe()
2189 INIT_LIST_HEAD(&dev->chains); in uvc_probe()
2190 INIT_LIST_HEAD(&dev->streams); in uvc_probe()
2191 kref_init(&dev->ref); in uvc_probe()
2192 atomic_set(&dev->nmappings, 0); in uvc_probe()
2194 dev->udev = usb_get_dev(udev); in uvc_probe()
2195 dev->intf = usb_get_intf(intf); in uvc_probe()
2196 dev->intfnum = intf->cur_altsetting->desc.bInterfaceNumber; in uvc_probe()
2197 dev->info = info ? info : &uvc_quirk_none; in uvc_probe()
2198 dev->quirks = uvc_quirks_param == -1 in uvc_probe()
2199 ? dev->info->quirks : uvc_quirks_param; in uvc_probe()
2201 if (id->idVendor && id->idProduct) in uvc_probe()
2203 udev->devpath, id->idVendor, id->idProduct); in uvc_probe()
2206 udev->devpath); in uvc_probe()
2208 if (udev->product != NULL) in uvc_probe()
2209 strscpy(dev->name, udev->product, sizeof(dev->name)); in uvc_probe()
2211 snprintf(dev->name, sizeof(dev->name), in uvc_probe()
2213 le16_to_cpu(udev->descriptor.idVendor), in uvc_probe()
2214 le16_to_cpu(udev->descriptor.idProduct)); in uvc_probe()
2221 if (intf->intf_assoc && intf->intf_assoc->iFunction != 0) in uvc_probe()
2222 function = intf->intf_assoc->iFunction; in uvc_probe()
2224 function = intf->cur_altsetting->desc.iInterface; in uvc_probe()
2228 strlcat(dev->name, ": ", sizeof(dev->name)); in uvc_probe()
2229 len = strlen(dev->name); in uvc_probe()
2230 usb_string(udev, function, dev->name + len, in uvc_probe()
2231 sizeof(dev->name) - len); in uvc_probe()
2236 dev->mdev.dev = &intf->dev; in uvc_probe()
2237 strscpy(dev->mdev.model, dev->name, sizeof(dev->mdev.model)); in uvc_probe()
2238 if (udev->serial) in uvc_probe()
2239 strscpy(dev->mdev.serial, udev->serial, in uvc_probe()
2240 sizeof(dev->mdev.serial)); in uvc_probe()
2241 usb_make_path(udev, dev->mdev.bus_info, sizeof(dev->mdev.bus_info)); in uvc_probe()
2242 dev->mdev.hw_revision = le16_to_cpu(udev->descriptor.bcdDevice); in uvc_probe()
2243 media_device_init(&dev->mdev); in uvc_probe()
2245 dev->vdev.mdev = &dev->mdev; in uvc_probe()
2260 dev_info(&dev->intf->dev, "Found UVC %u.%02x device %s (%04x:%04x)\n", in uvc_probe()
2261 dev->uvc_version >> 8, dev->uvc_version & 0xff, in uvc_probe()
2262 udev->product ? udev->product : "<unnamed>", in uvc_probe()
2263 le16_to_cpu(udev->descriptor.idVendor), in uvc_probe()
2264 le16_to_cpu(udev->descriptor.idProduct)); in uvc_probe()
2266 if (dev->quirks != dev->info->quirks) { in uvc_probe()
2267 dev_info(&dev->intf->dev, in uvc_probe()
2269 dev->quirks); in uvc_probe()
2270 dev_info(&dev->intf->dev, in uvc_probe()
2271 "Please report required quirks to the linux-media mailing list.\n"); in uvc_probe()
2274 if (dev->info->uvc_version) { in uvc_probe()
2275 dev->uvc_version = dev->info->uvc_version; in uvc_probe()
2276 dev_info(&dev->intf->dev, "Forcing UVC version to %u.%02x\n", in uvc_probe()
2277 dev->uvc_version >> 8, dev->uvc_version & 0xff); in uvc_probe()
2281 ret = v4l2_device_register(&intf->dev, &dev->vdev); in uvc_probe()
2302 ret = media_device_register(&dev->mdev); in uvc_probe()
2312 dev_info(&dev->intf->dev, in uvc_probe()
2319 dev_err(&dev->intf->dev, in uvc_probe()
2320 "Unable to request privacy GPIO IRQ (%d)\n", ret); in uvc_probe()
2326 dev_err(&dev->intf->dev, in uvc_probe()
2331 if (dev->quirks & UVC_QUIRK_NO_RESET_RESUME) in uvc_probe()
2332 udev->quirks &= ~USB_QUIRK_RESET_RESUME; in uvc_probe()
2334 if (!(dev->quirks & UVC_QUIRK_DISABLE_AUTOSUSPEND)) in uvc_probe()
2343 kref_put(&dev->ref, uvc_delete); in uvc_probe()
2357 if (intf->cur_altsetting->desc.bInterfaceSubClass == in uvc_disconnect()
2362 kref_put(&dev->ref, uvc_delete); in uvc_disconnect()
2371 intf->cur_altsetting->desc.bInterfaceNumber); in uvc_suspend()
2374 if (intf->cur_altsetting->desc.bInterfaceSubClass == in uvc_suspend()
2380 list_for_each_entry(stream, &dev->streams, list) { in uvc_suspend()
2381 if (stream->intf == intf) in uvc_suspend()
2387 return -EINVAL; in uvc_suspend()
2397 intf->cur_altsetting->desc.bInterfaceNumber); in __uvc_resume()
2399 if (intf->cur_altsetting->desc.bInterfaceSubClass == in __uvc_resume()
2410 list_for_each_entry(stream, &dev->streams, list) { in __uvc_resume()
2411 if (stream->intf == intf) { in __uvc_resume()
2414 mutex_lock(&stream->queue.mutex); in __uvc_resume()
2415 vb2_streamoff(&stream->queue.queue, in __uvc_resume()
2416 stream->queue.queue.type); in __uvc_resume()
2417 mutex_unlock(&stream->queue.mutex); in __uvc_resume()
2425 return -EINVAL; in __uvc_resume()
2435 return __uvc_resume(intf, 1); in uvc_reset_resume()
2438 /* ------------------------------------------------------------------------
2460 return -EINVAL; in uvc_clock_param_set()
2496 /* ------------------------------------------------------------------------
2538 .bInterfaceSubClass = 1,
2547 .bInterfaceSubClass = 1,
2558 .bInterfaceSubClass = 1,
2569 .bInterfaceSubClass = 1,
2578 .bInterfaceSubClass = 1,
2581 /* Microsoft Lifecam NX-6000 */
2587 .bInterfaceSubClass = 1,
2590 /* Microsoft Lifecam NX-3000 */
2596 .bInterfaceSubClass = 1,
2599 /* Microsoft Lifecam VX-7000 */
2605 .bInterfaceSubClass = 1,
2614 .bInterfaceSubClass = 1,
2623 .bInterfaceSubClass = 1,
2632 .bInterfaceSubClass = 1,
2640 .bInterfaceSubClass = 1,
2648 .bInterfaceSubClass = 1,
2656 .bInterfaceSubClass = 1,
2664 .bInterfaceSubClass = 1,
2672 .bInterfaceSubClass = 1,
2680 .bInterfaceSubClass = 1,
2690 .bInterfaceSubClass = 1,
2699 .bInterfaceSubClass = 1,
2708 .bInterfaceSubClass = 1,
2717 .bInterfaceSubClass = 1,
2726 .bInterfaceSubClass = 1,
2735 .bInterfaceSubClass = 1,
2738 /* Dell XPS m1530 */
2744 .bInterfaceSubClass = 1,
2753 .bInterfaceSubClass = 1,
2762 .bInterfaceSubClass = 1,
2771 .bInterfaceSubClass = 1,
2774 /* Dell XPS M1330 (OmniVision OV7670 webcam) */
2780 .bInterfaceSubClass = 1,
2783 /* Apple Built-In iSight */
2789 .bInterfaceSubClass = 1,
2793 /* Apple FaceTime HD Camera (Built-In) */
2799 .bInterfaceSubClass = 1,
2802 /* Apple Built-In iSight via iBridge */
2808 .bInterfaceSubClass = 1,
2817 .bInterfaceSubClass = 1,
2826 .bInterfaceSubClass = 1,
2835 .bInterfaceSubClass = 1,
2844 .bInterfaceSubClass = 1,
2847 /* ViMicro - Minoru3D */
2853 .bInterfaceSubClass = 1,
2856 /* ViMicro Venus - Minoru3D */
2862 .bInterfaceSubClass = 1,
2865 /* Ophir Optronics - SPCAM 620U */
2871 .bInterfaceSubClass = 1,
2874 /* Sonix Technology Co. Ltd. - 292A IPC AR0330 */
2880 .bInterfaceSubClass = 1,
2889 .bInterfaceSubClass = 1,
2899 .bInterfaceSubClass = 1,
2908 .bInterfaceSubClass = 1,
2917 .bInterfaceSubClass = 1,
2926 .bInterfaceSubClass = 1,
2935 .bInterfaceSubClass = 1,
2944 .bInterfaceSubClass = 1,
2953 .bInterfaceSubClass = 1,
2962 .bInterfaceSubClass = 1,
2971 .bInterfaceSubClass = 1,
2980 .bInterfaceSubClass = 1,
2989 .bInterfaceSubClass = 1,
2998 .bInterfaceSubClass = 1,
3008 .bInterfaceSubClass = 1,
3016 .bInterfaceSubClass = 1,
3019 /* Manta MM-353 Plako */
3025 .bInterfaceSubClass = 1,
3034 .bInterfaceSubClass = 1,
3043 .bInterfaceSubClass = 1,
3052 .bInterfaceSubClass = 1,
3062 .bInterfaceSubClass = 1,
3071 .bInterfaceSubClass = 1,
3080 .bInterfaceSubClass = 1,
3089 .bInterfaceSubClass = 1,
3100 .bInterfaceSubClass = 1,
3104 /* Actions Microelectronics Co. Display capture-UVC05 */
3110 .bInterfaceSubClass = 1,
3119 .bInterfaceSubClass = 1,
3128 .bInterfaceSubClass = 1,
3137 .bInterfaceSubClass = 1,
3146 .bInterfaceSubClass = 1,
3155 .bInterfaceSubClass = 1,
3164 .bInterfaceSubClass = 1,
3173 .bInterfaceSubClass = 1,
3182 .bInterfaceSubClass = 1,
3191 .bInterfaceSubClass = 1,
3200 .bInterfaceSubClass = 1,
3209 .bInterfaceSubClass = 1,
3218 .bInterfaceSubClass = 1,
3227 .bInterfaceSubClass = 1,
3236 .bInterfaceSubClass = 1,
3240 { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, UVC_PC_PROTOCOL_UNDEFINED) },
3241 { USB_INTERFACE_INFO(USB_CLASS_VIDEO, 1, UVC_PC_PROTOCOL_15) },
3255 .supports_autosuspend = 1,