Lines Matching +full:trace +full:- +full:buffer +full:- +full:extension
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * uvc_driver.c -- USB Video Class driver
5 * Copyright (C) 2005-2010
22 #include <media/v4l2-common.h>
23 #include <media/v4l2-ioctl.h>
34 static unsigned int uvc_quirks_param = -1;
38 /* ------------------------------------------------------------------------
84 .name = "Greyscale 8-bit (Y800)",
89 .name = "Greyscale 8-bit (Y8 )",
94 .name = "Greyscale 8-bit (D3DFMT_L8)",
99 .name = "IR 8-bit (L8_IR)",
104 .name = "Greyscale 10-bit (Y10 )",
109 .name = "Greyscale 12-bit (Y12 )",
114 .name = "Greyscale 16-bit (Y16 )",
169 .name = "Depth data 16-bit (Z16)",
174 .name = "Bayer 10-bit (SRGGB10P)",
179 .name = "Bayer 16-bit (SBGGR16)",
184 .name = "Bayer 16-bit (SGBRG16)",
189 .name = "Bayer 16-bit (SRGGB16)",
194 .name = "Bayer 16-bit (SGRBG16)",
199 .name = "Depth data 16-bit (Z16)",
204 .name = "Greyscale 10-bit (Y10 )",
209 .name = "IR:Depth 26-bit (INZI)",
214 .name = "4-bit Depth Confidence (Packed)",
225 /* ------------------------------------------------------------------------
235 for (i = 0; i < alts->desc.bNumEndpoints; ++i) { in uvc_find_endpoint()
236 ep = &alts->endpoint[i]; in uvc_find_endpoint()
237 if (ep->desc.bEndpointAddress == epaddr) in uvc_find_endpoint()
287 V4L2_XFER_FUNC_709, /* Substitution for BT.470-2 M */ in uvc_xfer_func()
288 V4L2_XFER_FUNC_709, /* Substitution for BT.470-2 B, G */ in uvc_xfer_func()
317 V4L2_YCBCR_ENC_601, /* Substitution for BT.470-2 B, G */ in uvc_ycbcr_enc()
331 * arbitrary parameters to remove non-significative terms from the simple
362 r = x - an[n] * y; in uvc_simplify_fraction()
371 for (i = n; i > 0; --i) { in uvc_simplify_fraction()
373 y = an[i-1] * y + x; in uvc_simplify_fraction()
392 numerator/denominator >= ((u32)-1)/10000000) in uvc_fraction_to_interval()
393 return (u32)-1; in uvc_fraction_to_interval()
400 while (numerator > ((u32)-1)/multiplier) { in uvc_fraction_to_interval()
408 /* ------------------------------------------------------------------------
416 list_for_each_entry(entity, &dev->entities, list) { in uvc_entity_by_id()
417 if (entity->id == id) in uvc_entity_by_id()
430 entity = list_entry(&dev->entities, struct uvc_entity, list); in uvc_entity_by_reference()
432 list_for_each_entry_continue(entity, &dev->entities, list) { in uvc_entity_by_reference()
433 for (i = 0; i < entity->bNrInPins; ++i) in uvc_entity_by_reference()
434 if (entity->baSourceID[i] == id) in uvc_entity_by_reference()
445 list_for_each_entry(stream, &dev->streams, list) { in uvc_stream_by_id()
446 if (stream->header.bTerminalLink == id) in uvc_stream_by_id()
453 /* ------------------------------------------------------------------------
459 if (stream->async_wq) in uvc_stream_delete()
460 destroy_workqueue(stream->async_wq); in uvc_stream_delete()
462 mutex_destroy(&stream->mutex); in uvc_stream_delete()
464 usb_put_intf(stream->intf); in uvc_stream_delete()
466 kfree(stream->format); in uvc_stream_delete()
467 kfree(stream->header.bmaControls); in uvc_stream_delete()
480 mutex_init(&stream->mutex); in uvc_stream_new()
482 stream->dev = dev; in uvc_stream_new()
483 stream->intf = usb_get_intf(intf); in uvc_stream_new()
484 stream->intfnum = intf->cur_altsetting->desc.bInterfaceNumber; in uvc_stream_new()
487 stream->async_wq = alloc_workqueue("uvcvideo", WQ_UNBOUND | WQ_HIGHPRI, in uvc_stream_new()
489 if (!stream->async_wq) { in uvc_stream_new()
497 /* ------------------------------------------------------------------------
503 u32 **intervals, unsigned char *buffer, int buflen) in uvc_parse_format() argument
505 struct usb_interface *intf = streaming->intf; in uvc_parse_format()
506 struct usb_host_interface *alts = intf->cur_altsetting; in uvc_parse_format()
509 const unsigned char *start = buffer; in uvc_parse_format()
515 format->type = buffer[2]; in uvc_parse_format()
516 format->index = buffer[3]; in uvc_parse_format()
518 switch (buffer[2]) { in uvc_parse_format()
521 n = buffer[2] == UVC_VS_FORMAT_UNCOMPRESSED ? 27 : 28; in uvc_parse_format()
525 dev->udev->devnum, in uvc_parse_format()
526 alts->desc.bInterfaceNumber); in uvc_parse_format()
527 return -EINVAL; in uvc_parse_format()
531 fmtdesc = uvc_format_by_guid(&buffer[5]); in uvc_parse_format()
534 strscpy(format->name, fmtdesc->name, in uvc_parse_format()
535 sizeof(format->name)); in uvc_parse_format()
536 format->fcc = fmtdesc->fcc; in uvc_parse_format()
538 dev_info(&streaming->intf->dev, in uvc_parse_format()
539 "Unknown video format %pUl\n", &buffer[5]); in uvc_parse_format()
540 snprintf(format->name, sizeof(format->name), "%pUl\n", in uvc_parse_format()
541 &buffer[5]); in uvc_parse_format()
542 format->fcc = 0; in uvc_parse_format()
545 format->bpp = buffer[21]; in uvc_parse_format()
550 if (dev->quirks & UVC_QUIRK_FORCE_Y8) { in uvc_parse_format()
551 if (format->fcc == V4L2_PIX_FMT_YUYV) { in uvc_parse_format()
552 strscpy(format->name, "Greyscale 8-bit (Y8 )", in uvc_parse_format()
553 sizeof(format->name)); in uvc_parse_format()
554 format->fcc = V4L2_PIX_FMT_GREY; in uvc_parse_format()
555 format->bpp = 8; in uvc_parse_format()
561 if (dev->quirks & UVC_QUIRK_FORCE_BPP) { in uvc_parse_format()
563 v4l2_format_info(format->fcc); in uvc_parse_format()
566 unsigned int div = info->hdiv * info->vdiv; in uvc_parse_format()
568 n = info->bpp[0] * div; in uvc_parse_format()
569 for (i = 1; i < info->comp_planes; i++) in uvc_parse_format()
570 n += info->bpp[i]; in uvc_parse_format()
572 format->bpp = DIV_ROUND_UP(8 * n, div); in uvc_parse_format()
576 if (buffer[2] == UVC_VS_FORMAT_UNCOMPRESSED) { in uvc_parse_format()
580 if (buffer[27]) in uvc_parse_format()
581 format->flags = UVC_FMT_FLAG_COMPRESSED; in uvc_parse_format()
589 dev->udev->devnum, in uvc_parse_format()
590 alts->desc.bInterfaceNumber); in uvc_parse_format()
591 return -EINVAL; in uvc_parse_format()
594 strscpy(format->name, "MJPEG", sizeof(format->name)); in uvc_parse_format()
595 format->fcc = V4L2_PIX_FMT_MJPEG; in uvc_parse_format()
596 format->flags = UVC_FMT_FLAG_COMPRESSED; in uvc_parse_format()
597 format->bpp = 0; in uvc_parse_format()
605 dev->udev->devnum, in uvc_parse_format()
606 alts->desc.bInterfaceNumber); in uvc_parse_format()
607 return -EINVAL; in uvc_parse_format()
610 switch (buffer[8] & 0x7f) { in uvc_parse_format()
612 strscpy(format->name, "SD-DV", sizeof(format->name)); in uvc_parse_format()
615 strscpy(format->name, "SDL-DV", sizeof(format->name)); in uvc_parse_format()
618 strscpy(format->name, "HD-DV", sizeof(format->name)); in uvc_parse_format()
623 dev->udev->devnum, in uvc_parse_format()
624 alts->desc.bInterfaceNumber, buffer[8]); in uvc_parse_format()
625 return -EINVAL; in uvc_parse_format()
628 strlcat(format->name, buffer[8] & (1 << 7) ? " 60Hz" : " 50Hz", in uvc_parse_format()
629 sizeof(format->name)); in uvc_parse_format()
631 format->fcc = V4L2_PIX_FMT_DV; in uvc_parse_format()
632 format->flags = UVC_FMT_FLAG_COMPRESSED | UVC_FMT_FLAG_STREAM; in uvc_parse_format()
633 format->bpp = 0; in uvc_parse_format()
637 frame = &format->frame[0]; in uvc_parse_format()
638 memset(&format->frame[0], 0, sizeof(format->frame[0])); in uvc_parse_format()
639 frame->bFrameIntervalType = 1; in uvc_parse_format()
640 frame->dwDefaultFrameInterval = 1; in uvc_parse_format()
641 frame->dwFrameInterval = *intervals; in uvc_parse_format()
643 format->nframes = 1; in uvc_parse_format()
652 dev->udev->devnum, alts->desc.bInterfaceNumber, in uvc_parse_format()
653 buffer[2]); in uvc_parse_format()
654 return -EINVAL; in uvc_parse_format()
657 uvc_dbg(dev, DESCR, "Found format %s\n", format->name); in uvc_parse_format()
659 buflen -= buffer[0]; in uvc_parse_format()
660 buffer += buffer[0]; in uvc_parse_format()
665 while (buflen > 2 && buffer[1] == USB_DT_CS_INTERFACE && in uvc_parse_format()
666 buffer[2] == ftype) { in uvc_parse_format()
667 frame = &format->frame[format->nframes]; in uvc_parse_format()
669 n = buflen > 25 ? buffer[25] : 0; in uvc_parse_format()
671 n = buflen > 21 ? buffer[21] : 0; in uvc_parse_format()
678 dev->udev->devnum, in uvc_parse_format()
679 alts->desc.bInterfaceNumber); in uvc_parse_format()
680 return -EINVAL; in uvc_parse_format()
683 frame->bFrameIndex = buffer[3]; in uvc_parse_format()
684 frame->bmCapabilities = buffer[4]; in uvc_parse_format()
685 frame->wWidth = get_unaligned_le16(&buffer[5]) in uvc_parse_format()
687 frame->wHeight = get_unaligned_le16(&buffer[7]); in uvc_parse_format()
688 frame->dwMinBitRate = get_unaligned_le32(&buffer[9]); in uvc_parse_format()
689 frame->dwMaxBitRate = get_unaligned_le32(&buffer[13]); in uvc_parse_format()
691 frame->dwMaxVideoFrameBufferSize = in uvc_parse_format()
692 get_unaligned_le32(&buffer[17]); in uvc_parse_format()
693 frame->dwDefaultFrameInterval = in uvc_parse_format()
694 get_unaligned_le32(&buffer[21]); in uvc_parse_format()
695 frame->bFrameIntervalType = buffer[25]; in uvc_parse_format()
697 frame->dwMaxVideoFrameBufferSize = 0; in uvc_parse_format()
698 frame->dwDefaultFrameInterval = in uvc_parse_format()
699 get_unaligned_le32(&buffer[17]); in uvc_parse_format()
700 frame->bFrameIntervalType = buffer[21]; in uvc_parse_format()
702 frame->dwFrameInterval = *intervals; in uvc_parse_format()
712 if (!(format->flags & UVC_FMT_FLAG_COMPRESSED)) in uvc_parse_format()
713 frame->dwMaxVideoFrameBufferSize = format->bpp in uvc_parse_format()
714 * frame->wWidth * frame->wHeight / 8; in uvc_parse_format()
722 interval = get_unaligned_le32(&buffer[26+4*i]); in uvc_parse_format()
729 n -= frame->bFrameIntervalType ? 1 : 2; in uvc_parse_format()
730 frame->dwDefaultFrameInterval = in uvc_parse_format()
731 min(frame->dwFrameInterval[n], in uvc_parse_format()
732 max(frame->dwFrameInterval[0], in uvc_parse_format()
733 frame->dwDefaultFrameInterval)); in uvc_parse_format()
735 if (dev->quirks & UVC_QUIRK_RESTRICT_FRAME_RATE) { in uvc_parse_format()
736 frame->bFrameIntervalType = 1; in uvc_parse_format()
737 frame->dwFrameInterval[0] = in uvc_parse_format()
738 frame->dwDefaultFrameInterval; in uvc_parse_format()
741 uvc_dbg(dev, DESCR, "- %ux%u (%u.%u fps)\n", in uvc_parse_format()
742 frame->wWidth, frame->wHeight, in uvc_parse_format()
743 10000000 / frame->dwDefaultFrameInterval, in uvc_parse_format()
744 (100000000 / frame->dwDefaultFrameInterval) % 10); in uvc_parse_format()
746 format->nframes++; in uvc_parse_format()
747 buflen -= buffer[0]; in uvc_parse_format()
748 buffer += buffer[0]; in uvc_parse_format()
751 if (buflen > 2 && buffer[1] == USB_DT_CS_INTERFACE && in uvc_parse_format()
752 buffer[2] == UVC_VS_STILL_IMAGE_FRAME) { in uvc_parse_format()
753 buflen -= buffer[0]; in uvc_parse_format()
754 buffer += buffer[0]; in uvc_parse_format()
757 if (buflen > 2 && buffer[1] == USB_DT_CS_INTERFACE && in uvc_parse_format()
758 buffer[2] == UVC_VS_COLORFORMAT) { in uvc_parse_format()
762 dev->udev->devnum, in uvc_parse_format()
763 alts->desc.bInterfaceNumber); in uvc_parse_format()
764 return -EINVAL; in uvc_parse_format()
767 format->colorspace = uvc_colorspace(buffer[3]); in uvc_parse_format()
768 format->xfer_func = uvc_xfer_func(buffer[4]); in uvc_parse_format()
769 format->ycbcr_enc = uvc_ycbcr_enc(buffer[5]); in uvc_parse_format()
771 buflen -= buffer[0]; in uvc_parse_format()
772 buffer += buffer[0]; in uvc_parse_format()
775 return buffer - start; in uvc_parse_format()
784 struct usb_host_interface *alts = &intf->altsetting[0]; in uvc_parse_streaming()
785 unsigned char *_buffer, *buffer = alts->extra; in uvc_parse_streaming() local
786 int _buflen, buflen = alts->extralen; in uvc_parse_streaming()
791 int ret = -EINVAL; in uvc_parse_streaming()
793 if (intf->cur_altsetting->desc.bInterfaceSubClass in uvc_parse_streaming()
797 dev->udev->devnum, in uvc_parse_streaming()
798 intf->altsetting[0].desc.bInterfaceNumber); in uvc_parse_streaming()
799 return -EINVAL; in uvc_parse_streaming()
805 dev->udev->devnum, in uvc_parse_streaming()
806 intf->altsetting[0].desc.bInterfaceNumber); in uvc_parse_streaming()
807 return -EINVAL; in uvc_parse_streaming()
813 return -ENOMEM; in uvc_parse_streaming()
816 /* The Pico iMage webcam has its class-specific interface descriptors in uvc_parse_streaming()
820 for (i = 0; i < alts->desc.bNumEndpoints; ++i) { in uvc_parse_streaming()
821 struct usb_host_endpoint *ep = &alts->endpoint[i]; in uvc_parse_streaming()
823 if (ep->extralen == 0) in uvc_parse_streaming()
826 if (ep->extralen > 2 && in uvc_parse_streaming()
827 ep->extra[1] == USB_DT_CS_INTERFACE) { in uvc_parse_streaming()
831 buffer = alts->endpoint[i].extra; in uvc_parse_streaming()
832 buflen = alts->endpoint[i].extralen; in uvc_parse_streaming()
839 while (buflen > 2 && buffer[1] != USB_DT_CS_INTERFACE) { in uvc_parse_streaming()
840 buflen -= buffer[0]; in uvc_parse_streaming()
841 buffer += buffer[0]; in uvc_parse_streaming()
846 "no class-specific streaming interface descriptors found\n"); in uvc_parse_streaming()
851 switch (buffer[2]) { in uvc_parse_streaming()
853 streaming->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; in uvc_parse_streaming()
858 streaming->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; in uvc_parse_streaming()
865 dev->udev->devnum, alts->desc.bInterfaceNumber); in uvc_parse_streaming()
869 p = buflen >= 4 ? buffer[3] : 0; in uvc_parse_streaming()
870 n = buflen >= size ? buffer[size-1] : 0; in uvc_parse_streaming()
875 dev->udev->devnum, alts->desc.bInterfaceNumber); in uvc_parse_streaming()
879 streaming->header.bNumFormats = p; in uvc_parse_streaming()
880 streaming->header.bEndpointAddress = buffer[6]; in uvc_parse_streaming()
881 if (buffer[2] == UVC_VS_INPUT_HEADER) { in uvc_parse_streaming()
882 streaming->header.bmInfo = buffer[7]; in uvc_parse_streaming()
883 streaming->header.bTerminalLink = buffer[8]; in uvc_parse_streaming()
884 streaming->header.bStillCaptureMethod = buffer[9]; in uvc_parse_streaming()
885 streaming->header.bTriggerSupport = buffer[10]; in uvc_parse_streaming()
886 streaming->header.bTriggerUsage = buffer[11]; in uvc_parse_streaming()
888 streaming->header.bTerminalLink = buffer[7]; in uvc_parse_streaming()
890 streaming->header.bControlSize = n; in uvc_parse_streaming()
892 streaming->header.bmaControls = kmemdup(&buffer[size], p * n, in uvc_parse_streaming()
894 if (streaming->header.bmaControls == NULL) { in uvc_parse_streaming()
895 ret = -ENOMEM; in uvc_parse_streaming()
899 buflen -= buffer[0]; in uvc_parse_streaming()
900 buffer += buffer[0]; in uvc_parse_streaming()
902 _buffer = buffer; in uvc_parse_streaming()
927 dev->udev->devnum, in uvc_parse_streaming()
928 alts->desc.bInterfaceNumber, _buffer[2]); in uvc_parse_streaming()
945 _buflen -= _buffer[0]; in uvc_parse_streaming()
952 dev->udev->devnum, alts->desc.bInterfaceNumber); in uvc_parse_streaming()
960 ret = -ENOMEM; in uvc_parse_streaming()
967 streaming->format = format; in uvc_parse_streaming()
968 streaming->nformats = nformats; in uvc_parse_streaming()
971 while (buflen > 2 && buffer[1] == USB_DT_CS_INTERFACE) { in uvc_parse_streaming()
972 switch (buffer[2]) { in uvc_parse_streaming()
977 format->frame = frame; in uvc_parse_streaming()
979 &interval, buffer, buflen); in uvc_parse_streaming()
983 frame += format->nframes; in uvc_parse_streaming()
986 buflen -= ret; in uvc_parse_streaming()
987 buffer += ret; in uvc_parse_streaming()
994 buflen -= buffer[0]; in uvc_parse_streaming()
995 buffer += buffer[0]; in uvc_parse_streaming()
1001 dev->udev->devnum, alts->desc.bInterfaceNumber, buflen); in uvc_parse_streaming()
1004 for (i = 0; i < intf->num_altsetting; ++i) { in uvc_parse_streaming()
1006 alts = &intf->altsetting[i]; in uvc_parse_streaming()
1008 streaming->header.bEndpointAddress); in uvc_parse_streaming()
1012 psize = le16_to_cpu(ep->desc.wMaxPacketSize); in uvc_parse_streaming()
1014 if (psize > streaming->maxpsize) in uvc_parse_streaming()
1015 streaming->maxpsize = psize; in uvc_parse_streaming()
1018 list_add_tail(&streaming->list, &dev->streams); in uvc_parse_streaming()
1041 extra_size = roundup(extra_size, sizeof(*entity->pads)); in uvc_alloc_entity()
1043 num_inputs = type & UVC_TERM_OUTPUT ? num_pads : num_pads - 1; in uvc_alloc_entity()
1046 size = sizeof(*entity) + extra_size + sizeof(*entity->pads) * num_pads in uvc_alloc_entity()
1052 entity->id = id; in uvc_alloc_entity()
1053 entity->type = type; in uvc_alloc_entity()
1056 * Set the GUID for standard entity types. For extension units, the GUID in uvc_alloc_entity()
1061 memcpy(entity->guid, uvc_gpio_guid, 16); in uvc_alloc_entity()
1064 memcpy(entity->guid, uvc_camera_guid, 16); in uvc_alloc_entity()
1067 memcpy(entity->guid, uvc_media_transport_input_guid, 16); in uvc_alloc_entity()
1070 memcpy(entity->guid, uvc_processing_guid, 16); in uvc_alloc_entity()
1074 entity->num_links = 0; in uvc_alloc_entity()
1075 entity->num_pads = num_pads; in uvc_alloc_entity()
1076 entity->pads = ((void *)(entity + 1)) + extra_size; in uvc_alloc_entity()
1079 entity->pads[i].flags = MEDIA_PAD_FL_SINK; in uvc_alloc_entity()
1081 entity->pads[num_pads-1].flags = MEDIA_PAD_FL_SOURCE; in uvc_alloc_entity()
1083 entity->bNrInPins = num_inputs; in uvc_alloc_entity()
1084 entity->baSourceID = (u8 *)(&entity->pads[num_pads]); in uvc_alloc_entity()
1089 /* Parse vendor-specific extensions. */
1091 const unsigned char *buffer, int buflen) in uvc_parse_vendor_control() argument
1093 struct usb_device *udev = dev->udev; in uvc_parse_vendor_control()
1094 struct usb_host_interface *alts = dev->intf->cur_altsetting; in uvc_parse_vendor_control()
1099 switch (le16_to_cpu(dev->udev->descriptor.idVendor)) { in uvc_parse_vendor_control()
1101 if (buffer[1] != 0x41 || buffer[2] != 0x01) in uvc_parse_vendor_control()
1105 * through vendor specific extension units (LXU). in uvc_parse_vendor_control()
1109 * 3.7.2.6 "Extension Unit Descriptor") with the following in uvc_parse_vendor_control()
1112 * ---------------------------------------------------------- in uvc_parse_vendor_control()
1115 * ---------------------------------------------------------- in uvc_parse_vendor_control()
1122 * ---------------------------------------------------------- in uvc_parse_vendor_control()
1124 * ---------------------------------------------------------- in uvc_parse_vendor_control()
1127 * extension unit. in uvc_parse_vendor_control()
1128 * ---------------------------------------------------------- in uvc_parse_vendor_control()
1130 p = buflen >= 22 ? buffer[21] : 0; in uvc_parse_vendor_control()
1131 n = buflen >= 25 + p ? buffer[22+p] : 0; in uvc_parse_vendor_control()
1136 udev->devnum, alts->desc.bInterfaceNumber); in uvc_parse_vendor_control()
1140 unit = uvc_alloc_entity(UVC_VC_EXTENSION_UNIT, buffer[3], in uvc_parse_vendor_control()
1143 return -ENOMEM; in uvc_parse_vendor_control()
1145 memcpy(unit->guid, &buffer[4], 16); in uvc_parse_vendor_control()
1146 unit->extension.bNumControls = buffer[20]; in uvc_parse_vendor_control()
1147 memcpy(unit->baSourceID, &buffer[22], p); in uvc_parse_vendor_control()
1148 unit->extension.bControlSize = buffer[22+p]; in uvc_parse_vendor_control()
1149 unit->extension.bmControls = (u8 *)unit + sizeof(*unit); in uvc_parse_vendor_control()
1150 unit->extension.bmControlsType = (u8 *)unit + sizeof(*unit) in uvc_parse_vendor_control()
1152 memcpy(unit->extension.bmControls, &buffer[23+p], 2*n); in uvc_parse_vendor_control()
1154 if (buffer[24+p+2*n] != 0) in uvc_parse_vendor_control()
1155 usb_string(udev, buffer[24+p+2*n], unit->name, in uvc_parse_vendor_control()
1156 sizeof(unit->name)); in uvc_parse_vendor_control()
1158 sprintf(unit->name, "Extension %u", buffer[3]); in uvc_parse_vendor_control()
1160 list_add_tail(&unit->list, &dev->entities); in uvc_parse_vendor_control()
1169 const unsigned char *buffer, int buflen) in uvc_parse_standard_control() argument
1171 struct usb_device *udev = dev->udev; in uvc_parse_standard_control()
1174 struct usb_host_interface *alts = dev->intf->cur_altsetting; in uvc_parse_standard_control()
1178 switch (buffer[2]) { in uvc_parse_standard_control()
1180 n = buflen >= 12 ? buffer[11] : 0; in uvc_parse_standard_control()
1185 udev->devnum, alts->desc.bInterfaceNumber); in uvc_parse_standard_control()
1186 return -EINVAL; in uvc_parse_standard_control()
1189 dev->uvc_version = get_unaligned_le16(&buffer[3]); in uvc_parse_standard_control()
1190 dev->clock_frequency = get_unaligned_le32(&buffer[7]); in uvc_parse_standard_control()
1194 intf = usb_ifnum_to_if(udev, buffer[12+i]); in uvc_parse_standard_control()
1198 udev->devnum, i); in uvc_parse_standard_control()
1210 udev->devnum, alts->desc.bInterfaceNumber); in uvc_parse_standard_control()
1211 return -EINVAL; in uvc_parse_standard_control()
1217 * - The high byte must be non-zero, otherwise it would be in uvc_parse_standard_control()
1220 * - Bit 15 must be 0, as we use it internally as a terminal in uvc_parse_standard_control()
1225 type = get_unaligned_le16(&buffer[4]); in uvc_parse_standard_control()
1229 udev->devnum, alts->desc.bInterfaceNumber, in uvc_parse_standard_control()
1230 buffer[3], type); in uvc_parse_standard_control()
1239 n = buflen >= 15 ? buffer[14] : 0; in uvc_parse_standard_control()
1243 n = buflen >= 9 ? buffer[8] : 0; in uvc_parse_standard_control()
1244 p = buflen >= 10 + n ? buffer[9+n] : 0; in uvc_parse_standard_control()
1251 udev->devnum, alts->desc.bInterfaceNumber); in uvc_parse_standard_control()
1252 return -EINVAL; in uvc_parse_standard_control()
1255 term = uvc_alloc_entity(type | UVC_TERM_INPUT, buffer[3], in uvc_parse_standard_control()
1258 return -ENOMEM; in uvc_parse_standard_control()
1261 term->camera.bControlSize = n; in uvc_parse_standard_control()
1262 term->camera.bmControls = (u8 *)term + sizeof(*term); in uvc_parse_standard_control()
1263 term->camera.wObjectiveFocalLengthMin = in uvc_parse_standard_control()
1264 get_unaligned_le16(&buffer[8]); in uvc_parse_standard_control()
1265 term->camera.wObjectiveFocalLengthMax = in uvc_parse_standard_control()
1266 get_unaligned_le16(&buffer[10]); in uvc_parse_standard_control()
1267 term->camera.wOcularFocalLength = in uvc_parse_standard_control()
1268 get_unaligned_le16(&buffer[12]); in uvc_parse_standard_control()
1269 memcpy(term->camera.bmControls, &buffer[15], n); in uvc_parse_standard_control()
1272 term->media.bControlSize = n; in uvc_parse_standard_control()
1273 term->media.bmControls = (u8 *)term + sizeof(*term); in uvc_parse_standard_control()
1274 term->media.bTransportModeSize = p; in uvc_parse_standard_control()
1275 term->media.bmTransportModes = (u8 *)term in uvc_parse_standard_control()
1277 memcpy(term->media.bmControls, &buffer[9], n); in uvc_parse_standard_control()
1278 memcpy(term->media.bmTransportModes, &buffer[10+n], p); in uvc_parse_standard_control()
1281 if (buffer[7] != 0) in uvc_parse_standard_control()
1282 usb_string(udev, buffer[7], term->name, in uvc_parse_standard_control()
1283 sizeof(term->name)); in uvc_parse_standard_control()
1285 sprintf(term->name, "Camera %u", buffer[3]); in uvc_parse_standard_control()
1287 sprintf(term->name, "Media %u", buffer[3]); in uvc_parse_standard_control()
1289 sprintf(term->name, "Input %u", buffer[3]); in uvc_parse_standard_control()
1291 list_add_tail(&term->list, &dev->entities); in uvc_parse_standard_control()
1298 udev->devnum, alts->desc.bInterfaceNumber); in uvc_parse_standard_control()
1299 return -EINVAL; in uvc_parse_standard_control()
1305 type = get_unaligned_le16(&buffer[4]); in uvc_parse_standard_control()
1309 udev->devnum, alts->desc.bInterfaceNumber, in uvc_parse_standard_control()
1310 buffer[3], type); in uvc_parse_standard_control()
1314 term = uvc_alloc_entity(type | UVC_TERM_OUTPUT, buffer[3], in uvc_parse_standard_control()
1317 return -ENOMEM; in uvc_parse_standard_control()
1319 memcpy(term->baSourceID, &buffer[7], 1); in uvc_parse_standard_control()
1321 if (buffer[8] != 0) in uvc_parse_standard_control()
1322 usb_string(udev, buffer[8], term->name, in uvc_parse_standard_control()
1323 sizeof(term->name)); in uvc_parse_standard_control()
1325 sprintf(term->name, "Output %u", buffer[3]); in uvc_parse_standard_control()
1327 list_add_tail(&term->list, &dev->entities); in uvc_parse_standard_control()
1331 p = buflen >= 5 ? buffer[4] : 0; in uvc_parse_standard_control()
1336 udev->devnum, alts->desc.bInterfaceNumber); in uvc_parse_standard_control()
1337 return -EINVAL; in uvc_parse_standard_control()
1340 unit = uvc_alloc_entity(buffer[2], buffer[3], p + 1, 0); in uvc_parse_standard_control()
1342 return -ENOMEM; in uvc_parse_standard_control()
1344 memcpy(unit->baSourceID, &buffer[5], p); in uvc_parse_standard_control()
1346 if (buffer[5+p] != 0) in uvc_parse_standard_control()
1347 usb_string(udev, buffer[5+p], unit->name, in uvc_parse_standard_control()
1348 sizeof(unit->name)); in uvc_parse_standard_control()
1350 sprintf(unit->name, "Selector %u", buffer[3]); in uvc_parse_standard_control()
1352 list_add_tail(&unit->list, &dev->entities); in uvc_parse_standard_control()
1356 n = buflen >= 8 ? buffer[7] : 0; in uvc_parse_standard_control()
1357 p = dev->uvc_version >= 0x0110 ? 10 : 9; in uvc_parse_standard_control()
1362 udev->devnum, alts->desc.bInterfaceNumber); in uvc_parse_standard_control()
1363 return -EINVAL; in uvc_parse_standard_control()
1366 unit = uvc_alloc_entity(buffer[2], buffer[3], 2, n); in uvc_parse_standard_control()
1368 return -ENOMEM; in uvc_parse_standard_control()
1370 memcpy(unit->baSourceID, &buffer[4], 1); in uvc_parse_standard_control()
1371 unit->processing.wMaxMultiplier = in uvc_parse_standard_control()
1372 get_unaligned_le16(&buffer[5]); in uvc_parse_standard_control()
1373 unit->processing.bControlSize = buffer[7]; in uvc_parse_standard_control()
1374 unit->processing.bmControls = (u8 *)unit + sizeof(*unit); in uvc_parse_standard_control()
1375 memcpy(unit->processing.bmControls, &buffer[8], n); in uvc_parse_standard_control()
1376 if (dev->uvc_version >= 0x0110) in uvc_parse_standard_control()
1377 unit->processing.bmVideoStandards = buffer[9+n]; in uvc_parse_standard_control()
1379 if (buffer[8+n] != 0) in uvc_parse_standard_control()
1380 usb_string(udev, buffer[8+n], unit->name, in uvc_parse_standard_control()
1381 sizeof(unit->name)); in uvc_parse_standard_control()
1383 sprintf(unit->name, "Processing %u", buffer[3]); in uvc_parse_standard_control()
1385 list_add_tail(&unit->list, &dev->entities); in uvc_parse_standard_control()
1389 p = buflen >= 22 ? buffer[21] : 0; in uvc_parse_standard_control()
1390 n = buflen >= 24 + p ? buffer[22+p] : 0; in uvc_parse_standard_control()
1395 udev->devnum, alts->desc.bInterfaceNumber); in uvc_parse_standard_control()
1396 return -EINVAL; in uvc_parse_standard_control()
1399 unit = uvc_alloc_entity(buffer[2], buffer[3], p + 1, n); in uvc_parse_standard_control()
1401 return -ENOMEM; in uvc_parse_standard_control()
1403 memcpy(unit->guid, &buffer[4], 16); in uvc_parse_standard_control()
1404 unit->extension.bNumControls = buffer[20]; in uvc_parse_standard_control()
1405 memcpy(unit->baSourceID, &buffer[22], p); in uvc_parse_standard_control()
1406 unit->extension.bControlSize = buffer[22+p]; in uvc_parse_standard_control()
1407 unit->extension.bmControls = (u8 *)unit + sizeof(*unit); in uvc_parse_standard_control()
1408 memcpy(unit->extension.bmControls, &buffer[23+p], n); in uvc_parse_standard_control()
1410 if (buffer[23+p+n] != 0) in uvc_parse_standard_control()
1411 usb_string(udev, buffer[23+p+n], unit->name, in uvc_parse_standard_control()
1412 sizeof(unit->name)); in uvc_parse_standard_control()
1414 sprintf(unit->name, "Extension %u", buffer[3]); in uvc_parse_standard_control()
1416 list_add_tail(&unit->list, &dev->entities); in uvc_parse_standard_control()
1422 buffer[2]); in uvc_parse_standard_control()
1431 struct usb_host_interface *alts = dev->intf->cur_altsetting; in uvc_parse_control()
1432 unsigned char *buffer = alts->extra; in uvc_parse_control() local
1433 int buflen = alts->extralen; in uvc_parse_control()
1442 if (uvc_parse_vendor_control(dev, buffer, buflen) || in uvc_parse_control()
1443 buffer[1] != USB_DT_CS_INTERFACE) in uvc_parse_control()
1446 if ((ret = uvc_parse_standard_control(dev, buffer, buflen)) < 0) in uvc_parse_control()
1450 buflen -= buffer[0]; in uvc_parse_control()
1451 buffer += buffer[0]; in uvc_parse_control()
1454 /* Check if the optional status endpoint is present. Built-in iSight in uvc_parse_control()
1459 if (alts->desc.bNumEndpoints == 1 && in uvc_parse_control()
1460 !(dev->quirks & UVC_QUIRK_BUILTIN_ISIGHT)) { in uvc_parse_control()
1461 struct usb_host_endpoint *ep = &alts->endpoint[0]; in uvc_parse_control()
1462 struct usb_endpoint_descriptor *desc = &ep->desc; in uvc_parse_control()
1465 le16_to_cpu(desc->wMaxPacketSize) >= 8 && in uvc_parse_control()
1466 desc->bInterval != 0) { in uvc_parse_control()
1469 desc->bEndpointAddress); in uvc_parse_control()
1470 dev->int_ep = ep; in uvc_parse_control()
1477 /* -----------------------------------------------------------------------------
1483 struct uvc_entity *unit = dev->gpio_unit; in uvc_gpio_event()
1490 new_val = gpiod_get_value_cansleep(unit->gpio.gpio_privacy); in uvc_gpio_event()
1493 chain = list_first_entry(&dev->chains, struct uvc_video_chain, list); in uvc_gpio_event()
1494 uvc_ctrl_status_event(chain, unit->controls, &new_val); in uvc_gpio_event()
1501 return -EINVAL; in uvc_gpio_get_cur()
1503 *(u8 *)data = gpiod_get_value_cansleep(entity->gpio.gpio_privacy); in uvc_gpio_get_cur()
1512 return -EINVAL; in uvc_gpio_get_info()
1532 gpio_privacy = devm_gpiod_get_optional(&dev->udev->dev, "privacy", in uvc_gpio_parse()
1539 return -ENOMEM; in uvc_gpio_parse()
1544 dev_err(&dev->udev->dev, in uvc_gpio_parse()
1549 unit->gpio.gpio_privacy = gpio_privacy; in uvc_gpio_parse()
1550 unit->gpio.irq = irq; in uvc_gpio_parse()
1551 unit->gpio.bControlSize = 1; in uvc_gpio_parse()
1552 unit->gpio.bmControls = (u8 *)unit + sizeof(*unit); in uvc_gpio_parse()
1553 unit->gpio.bmControls[0] = 1; in uvc_gpio_parse()
1554 unit->get_cur = uvc_gpio_get_cur; in uvc_gpio_parse()
1555 unit->get_info = uvc_gpio_get_info; in uvc_gpio_parse()
1556 strscpy(unit->name, "GPIO", sizeof(unit->name)); in uvc_gpio_parse()
1558 list_add_tail(&unit->list, &dev->entities); in uvc_gpio_parse()
1560 dev->gpio_unit = unit; in uvc_gpio_parse()
1567 struct uvc_entity *unit = dev->gpio_unit; in uvc_gpio_init_irq()
1569 if (!unit || unit->gpio.irq < 0) in uvc_gpio_init_irq()
1572 return devm_request_threaded_irq(&dev->udev->dev, unit->gpio.irq, NULL, in uvc_gpio_init_irq()
1579 /* ------------------------------------------------------------------------
1587 * - one or more Output Terminals (USB Streaming or Display)
1588 * - zero or one Processing Unit
1589 * - zero, one or more single-input Selector Units
1590 * - zero or one multiple-input Selector Units, provided all inputs are
1592 * - zero, one or mode single-input Extension Units
1593 * - one or more Input Terminals (Camera, External or USB Streaming)
1597 * ITT_*(0) -> +---------+ +---------+ +---------+ -> TT_STREAMING(0)
1598 * ... | SU{0,1} | -> | PU{0,1} | -> | XU{0,n} | ...
1599 * ITT_*(n) -> +---------+ +---------+ +---------+ -> TT_STREAMING(n)
1601 * +---------+ +---------+ -> OTT_*(0)
1602 * TT_STREAMING -> | PU{0,1} | -> | XU{0,n} | ...
1603 * +---------+ +---------+ -> OTT_*(n)
1605 * The Processing Unit and Extension Units can be in any order. Additional
1606 * Extension Units connected to the main chain as single-unit branches are
1607 * also supported. Single-input Selector Units are ignored.
1614 uvc_dbg_cont(PROBE, " <- XU %d", entity->id); in uvc_scan_chain_entity()
1616 if (entity->bNrInPins != 1) { in uvc_scan_chain_entity()
1617 uvc_dbg(chain->dev, DESCR, in uvc_scan_chain_entity()
1618 "Extension unit %d has more than 1 input pin\n", in uvc_scan_chain_entity()
1619 entity->id); in uvc_scan_chain_entity()
1620 return -1; in uvc_scan_chain_entity()
1626 uvc_dbg_cont(PROBE, " <- PU %d", entity->id); in uvc_scan_chain_entity()
1628 if (chain->processing != NULL) { in uvc_scan_chain_entity()
1629 uvc_dbg(chain->dev, DESCR, in uvc_scan_chain_entity()
1631 return -1; in uvc_scan_chain_entity()
1634 chain->processing = entity; in uvc_scan_chain_entity()
1638 uvc_dbg_cont(PROBE, " <- SU %d", entity->id); in uvc_scan_chain_entity()
1640 /* Single-input selector units are ignored. */ in uvc_scan_chain_entity()
1641 if (entity->bNrInPins == 1) in uvc_scan_chain_entity()
1644 if (chain->selector != NULL) { in uvc_scan_chain_entity()
1645 uvc_dbg(chain->dev, DESCR, in uvc_scan_chain_entity()
1647 return -1; in uvc_scan_chain_entity()
1650 chain->selector = entity; in uvc_scan_chain_entity()
1656 uvc_dbg_cont(PROBE, " <- IT %d\n", entity->id); in uvc_scan_chain_entity()
1663 uvc_dbg_cont(PROBE, " OT %d", entity->id); in uvc_scan_chain_entity()
1669 uvc_dbg_cont(PROBE, " <- IT %d\n", entity->id); in uvc_scan_chain_entity()
1671 uvc_dbg_cont(PROBE, " OT %d", entity->id); in uvc_scan_chain_entity()
1676 uvc_dbg(chain->dev, DESCR, in uvc_scan_chain_entity()
1679 return -1; in uvc_scan_chain_entity()
1682 list_add_tail(&entity->chain, &chain->entities); in uvc_scan_chain_entity()
1697 forward = uvc_entity_by_reference(chain->dev, entity->id, in uvc_scan_chain_forward()
1703 if (forward->chain.next || forward->chain.prev) { in uvc_scan_chain_forward()
1704 uvc_dbg(chain->dev, DESCR, in uvc_scan_chain_forward()
1706 forward->id); in uvc_scan_chain_forward()
1707 return -EINVAL; in uvc_scan_chain_forward()
1712 if (forward->bNrInPins != 1) { in uvc_scan_chain_forward()
1713 uvc_dbg(chain->dev, DESCR, in uvc_scan_chain_forward()
1714 "Extension unit %d has more than 1 input pin\n", in uvc_scan_chain_forward()
1715 forward->id); in uvc_scan_chain_forward()
1716 return -EINVAL; in uvc_scan_chain_forward()
1721 * source of extension units. This is incorrect, as in uvc_scan_chain_forward()
1726 * avoid this problem, connect the extension unit to in uvc_scan_chain_forward()
1732 source = uvc_entity_by_id(chain->dev, in uvc_scan_chain_forward()
1733 entity->baSourceID[0]); in uvc_scan_chain_forward()
1735 uvc_dbg(chain->dev, DESCR, in uvc_scan_chain_forward()
1736 "Can't connect extension unit %u in chain\n", in uvc_scan_chain_forward()
1737 forward->id); in uvc_scan_chain_forward()
1741 forward->baSourceID[0] = source->id; in uvc_scan_chain_forward()
1744 list_add_tail(&forward->chain, &chain->entities); in uvc_scan_chain_forward()
1746 uvc_dbg_cont(PROBE, " (->"); in uvc_scan_chain_forward()
1748 uvc_dbg_cont(PROBE, " XU %d", forward->id); in uvc_scan_chain_forward()
1757 uvc_dbg(chain->dev, DESCR, in uvc_scan_chain_forward()
1759 forward->id); in uvc_scan_chain_forward()
1760 return -EINVAL; in uvc_scan_chain_forward()
1764 uvc_dbg(chain->dev, DESCR, in uvc_scan_chain_forward()
1766 entity->id, forward->id); in uvc_scan_chain_forward()
1770 list_add_tail(&forward->chain, &chain->entities); in uvc_scan_chain_forward()
1772 uvc_dbg_cont(PROBE, " (->"); in uvc_scan_chain_forward()
1774 uvc_dbg_cont(PROBE, " OT %d", forward->id); in uvc_scan_chain_forward()
1790 int id = -EINVAL, i; in uvc_scan_chain_backward()
1795 id = entity->baSourceID[0]; in uvc_scan_chain_backward()
1799 /* Single-input selector units are ignored. */ in uvc_scan_chain_backward()
1800 if (entity->bNrInPins == 1) { in uvc_scan_chain_backward()
1801 id = entity->baSourceID[0]; in uvc_scan_chain_backward()
1805 uvc_dbg_cont(PROBE, " <- IT"); in uvc_scan_chain_backward()
1807 chain->selector = entity; in uvc_scan_chain_backward()
1808 for (i = 0; i < entity->bNrInPins; ++i) { in uvc_scan_chain_backward()
1809 id = entity->baSourceID[i]; in uvc_scan_chain_backward()
1810 term = uvc_entity_by_id(chain->dev, id); in uvc_scan_chain_backward()
1812 uvc_dbg(chain->dev, DESCR, in uvc_scan_chain_backward()
1814 entity->id, i); in uvc_scan_chain_backward()
1815 return -1; in uvc_scan_chain_backward()
1818 if (term->chain.next || term->chain.prev) { in uvc_scan_chain_backward()
1819 uvc_dbg(chain->dev, DESCR, in uvc_scan_chain_backward()
1821 term->id); in uvc_scan_chain_backward()
1822 return -EINVAL; in uvc_scan_chain_backward()
1825 uvc_dbg_cont(PROBE, " %d", term->id); in uvc_scan_chain_backward()
1827 list_add_tail(&term->chain, &chain->entities); in uvc_scan_chain_backward()
1843 id = UVC_ENTITY_IS_OTERM(entity) ? entity->baSourceID[0] : 0; in uvc_scan_chain_backward()
1852 entity = uvc_entity_by_id(chain->dev, id); in uvc_scan_chain_backward()
1854 uvc_dbg(chain->dev, DESCR, in uvc_scan_chain_backward()
1856 return -EINVAL; in uvc_scan_chain_backward()
1868 uvc_dbg(chain->dev, PROBE, "Scanning UVC chain:"); in uvc_scan_chain()
1875 if (entity->chain.next || entity->chain.prev) { in uvc_scan_chain()
1876 uvc_dbg(chain->dev, DESCR, in uvc_scan_chain()
1878 entity->id); in uvc_scan_chain()
1879 return -EINVAL; in uvc_scan_chain()
1884 return -EINVAL; in uvc_scan_chain()
1888 return -EINVAL; in uvc_scan_chain()
1893 return -EINVAL; in uvc_scan_chain()
1900 char *buffer) in uvc_print_terms() argument
1904 char *p = buffer; in uvc_print_terms()
1917 p += sprintf(p, "%u", term->id); in uvc_print_terms()
1920 return p - buffer; in uvc_print_terms()
1925 static char buffer[43]; in uvc_print_chain() local
1926 char *p = buffer; in uvc_print_chain()
1928 p += uvc_print_terms(&chain->entities, UVC_TERM_INPUT, p); in uvc_print_chain()
1929 p += sprintf(p, " -> "); in uvc_print_chain()
1930 uvc_print_terms(&chain->entities, UVC_TERM_OUTPUT, p); in uvc_print_chain()
1932 return buffer; in uvc_print_chain()
1943 INIT_LIST_HEAD(&chain->entities); in uvc_alloc_chain()
1944 mutex_init(&chain->ctrl_mutex); in uvc_alloc_chain()
1945 chain->dev = dev; in uvc_alloc_chain()
1946 v4l2_prio_init(&chain->prio); in uvc_alloc_chain()
1961 * - Acer Integrated Camera (5986:055a)
1962 * - Realtek rtl157a7 (0bda:57a7)
1976 list_for_each_entry(entity, &dev->entities, list) { in uvc_scan_fallback()
1979 return -EINVAL; in uvc_scan_fallback()
1985 return -EINVAL; in uvc_scan_fallback()
1991 return -EINVAL; in uvc_scan_fallback()
1996 return -ENOMEM; in uvc_scan_fallback()
2004 * Add all Processing and Extension Units with two pads. The order in uvc_scan_fallback()
2010 list_for_each_entry_reverse(entity, &dev->entities, list) { in uvc_scan_fallback()
2011 if (entity->type != UVC_VC_PROCESSING_UNIT && in uvc_scan_fallback()
2012 entity->type != UVC_VC_EXTENSION_UNIT) in uvc_scan_fallback()
2015 if (entity->num_pads != 2) in uvc_scan_fallback()
2021 prev->baSourceID[0] = entity->id; in uvc_scan_fallback()
2028 prev->baSourceID[0] = iterm->id; in uvc_scan_fallback()
2030 list_add_tail(&chain->list, &dev->chains); in uvc_scan_fallback()
2039 return -EINVAL; in uvc_scan_fallback()
2052 list_for_each_entry(term, &dev->entities, list) { in uvc_scan_device()
2061 if (term->chain.next || term->chain.prev) in uvc_scan_device()
2066 return -ENOMEM; in uvc_scan_device()
2068 term->flags |= UVC_ENTITY_FLAG_DEFAULT; in uvc_scan_device()
2078 list_add_tail(&chain->list, &dev->chains); in uvc_scan_device()
2081 if (list_empty(&dev->chains)) in uvc_scan_device()
2084 if (list_empty(&dev->chains)) { in uvc_scan_device()
2085 dev_info(&dev->udev->dev, "No valid video chain found.\n"); in uvc_scan_device()
2086 return -1; in uvc_scan_device()
2090 if (dev->gpio_unit) { in uvc_scan_device()
2091 chain = list_first_entry(&dev->chains, in uvc_scan_device()
2093 list_add_tail(&dev->gpio_unit->chain, &chain->entities); in uvc_scan_device()
2099 /* ------------------------------------------------------------------------
2121 usb_put_intf(dev->intf); in uvc_delete()
2122 usb_put_dev(dev->udev); in uvc_delete()
2125 media_device_cleanup(&dev->mdev); in uvc_delete()
2128 list_for_each_safe(p, n, &dev->chains) { in uvc_delete()
2134 list_for_each_safe(p, n, &dev->entities) { in uvc_delete()
2143 list_for_each_safe(p, n, &dev->streams) { in uvc_delete()
2147 streaming->intf); in uvc_delete()
2157 struct uvc_device *dev = stream->dev; in uvc_release()
2159 kref_put(&dev->ref, uvc_delete); in uvc_release()
2169 list_for_each_entry(stream, &dev->streams, list) { in uvc_unregister_video()
2170 if (!video_is_registered(&stream->vdev)) in uvc_unregister_video()
2173 video_unregister_device(&stream->vdev); in uvc_unregister_video()
2174 video_unregister_device(&stream->meta.vdev); in uvc_unregister_video()
2181 if (dev->vdev.dev) in uvc_unregister_video()
2182 v4l2_device_unregister(&dev->vdev); in uvc_unregister_video()
2184 if (media_devnode_is_registered(dev->mdev.devnode)) in uvc_unregister_video()
2185 media_device_unregister(&dev->mdev); in uvc_unregister_video()
2207 * We already hold a reference to dev->udev. The video device will be in uvc_register_video_device()
2211 vdev->v4l2_dev = &dev->vdev; in uvc_register_video_device()
2212 vdev->fops = fops; in uvc_register_video_device()
2213 vdev->ioctl_ops = ioctl_ops; in uvc_register_video_device()
2214 vdev->release = uvc_release; in uvc_register_video_device()
2215 vdev->prio = &stream->chain->prio; in uvc_register_video_device()
2217 vdev->vfl_dir = VFL_DIR_TX; in uvc_register_video_device()
2219 vdev->vfl_dir = VFL_DIR_RX; in uvc_register_video_device()
2224 vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; in uvc_register_video_device()
2227 vdev->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING; in uvc_register_video_device()
2230 vdev->device_caps = V4L2_CAP_META_CAPTURE | V4L2_CAP_STREAMING; in uvc_register_video_device()
2234 strscpy(vdev->name, dev->name, sizeof(vdev->name)); in uvc_register_video_device()
2242 ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1); in uvc_register_video_device()
2244 dev_err(&stream->intf->dev, in uvc_register_video_device()
2250 kref_get(&dev->ref); in uvc_register_video_device()
2262 dev_err(&stream->intf->dev, in uvc_register_video()
2267 if (stream->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) in uvc_register_video()
2268 stream->chain->caps |= V4L2_CAP_VIDEO_CAPTURE in uvc_register_video()
2271 stream->chain->caps |= V4L2_CAP_VIDEO_OUTPUT; in uvc_register_video()
2276 return uvc_register_video_device(dev, stream, &stream->vdev, in uvc_register_video()
2277 &stream->queue, stream->type, in uvc_register_video()
2291 list_for_each_entry(term, &chain->entities, chain) { in uvc_register_terms()
2295 stream = uvc_stream_by_id(dev, term->id); in uvc_register_terms()
2297 dev_info(&dev->udev->dev, in uvc_register_terms()
2299 term->id); in uvc_register_terms()
2303 stream->chain = chain; in uvc_register_terms()
2313 term->vdev = &stream->vdev; in uvc_register_terms()
2324 list_for_each_entry(chain, &dev->chains, list) { in uvc_register_chains()
2332 dev_info(&dev->udev->dev, in uvc_register_chains()
2340 /* ------------------------------------------------------------------------
2352 (const struct uvc_device_info *)id->driver_info; in uvc_probe()
2359 return -ENOMEM; in uvc_probe()
2361 INIT_LIST_HEAD(&dev->entities); in uvc_probe()
2362 INIT_LIST_HEAD(&dev->chains); in uvc_probe()
2363 INIT_LIST_HEAD(&dev->streams); in uvc_probe()
2364 kref_init(&dev->ref); in uvc_probe()
2365 atomic_set(&dev->nmappings, 0); in uvc_probe()
2366 mutex_init(&dev->lock); in uvc_probe()
2368 dev->udev = usb_get_dev(udev); in uvc_probe()
2369 dev->intf = usb_get_intf(intf); in uvc_probe()
2370 dev->intfnum = intf->cur_altsetting->desc.bInterfaceNumber; in uvc_probe()
2371 dev->info = info ? info : &uvc_quirk_none; in uvc_probe()
2372 dev->quirks = uvc_quirks_param == -1 in uvc_probe()
2373 ? dev->info->quirks : uvc_quirks_param; in uvc_probe()
2375 if (id->idVendor && id->idProduct) in uvc_probe()
2377 udev->devpath, id->idVendor, id->idProduct); in uvc_probe()
2380 udev->devpath); in uvc_probe()
2382 if (udev->product != NULL) in uvc_probe()
2383 strscpy(dev->name, udev->product, sizeof(dev->name)); in uvc_probe()
2385 snprintf(dev->name, sizeof(dev->name), in uvc_probe()
2387 le16_to_cpu(udev->descriptor.idVendor), in uvc_probe()
2388 le16_to_cpu(udev->descriptor.idProduct)); in uvc_probe()
2395 if (intf->intf_assoc && intf->intf_assoc->iFunction != 0) in uvc_probe()
2396 function = intf->intf_assoc->iFunction; in uvc_probe()
2398 function = intf->cur_altsetting->desc.iInterface; in uvc_probe()
2402 strlcat(dev->name, ": ", sizeof(dev->name)); in uvc_probe()
2403 len = strlen(dev->name); in uvc_probe()
2404 usb_string(udev, function, dev->name + len, in uvc_probe()
2405 sizeof(dev->name) - len); in uvc_probe()
2410 dev->mdev.dev = &intf->dev; in uvc_probe()
2411 strscpy(dev->mdev.model, dev->name, sizeof(dev->mdev.model)); in uvc_probe()
2412 if (udev->serial) in uvc_probe()
2413 strscpy(dev->mdev.serial, udev->serial, in uvc_probe()
2414 sizeof(dev->mdev.serial)); in uvc_probe()
2415 usb_make_path(udev, dev->mdev.bus_info, sizeof(dev->mdev.bus_info)); in uvc_probe()
2416 dev->mdev.hw_revision = le16_to_cpu(udev->descriptor.bcdDevice); in uvc_probe()
2417 media_device_init(&dev->mdev); in uvc_probe()
2419 dev->vdev.mdev = &dev->mdev; in uvc_probe()
2434 dev_info(&dev->udev->dev, "Found UVC %u.%02x device %s (%04x:%04x)\n", in uvc_probe()
2435 dev->uvc_version >> 8, dev->uvc_version & 0xff, in uvc_probe()
2436 udev->product ? udev->product : "<unnamed>", in uvc_probe()
2437 le16_to_cpu(udev->descriptor.idVendor), in uvc_probe()
2438 le16_to_cpu(udev->descriptor.idProduct)); in uvc_probe()
2440 if (dev->quirks != dev->info->quirks) { in uvc_probe()
2441 dev_info(&dev->udev->dev, in uvc_probe()
2443 dev->quirks); in uvc_probe()
2444 dev_info(&dev->udev->dev, in uvc_probe()
2445 "Please report required quirks to the linux-uvc-devel mailing list.\n"); in uvc_probe()
2448 if (dev->info->uvc_version) { in uvc_probe()
2449 dev->uvc_version = dev->info->uvc_version; in uvc_probe()
2450 dev_info(&dev->udev->dev, "Forcing UVC version to %u.%02x\n", in uvc_probe()
2451 dev->uvc_version >> 8, dev->uvc_version & 0xff); in uvc_probe()
2455 if (v4l2_device_register(&intf->dev, &dev->vdev) < 0) in uvc_probe()
2472 if (media_device_register(&dev->mdev) < 0) in uvc_probe()
2480 dev_info(&dev->udev->dev, in uvc_probe()
2487 dev_err(&dev->udev->dev, in uvc_probe()
2498 kref_put(&dev->ref, uvc_delete); in uvc_probe()
2499 return -ENODEV; in uvc_probe()
2511 if (intf->cur_altsetting->desc.bInterfaceSubClass == in uvc_disconnect()
2516 kref_put(&dev->ref, uvc_delete); in uvc_disconnect()
2525 intf->cur_altsetting->desc.bInterfaceNumber); in uvc_suspend()
2528 if (intf->cur_altsetting->desc.bInterfaceSubClass == in uvc_suspend()
2530 mutex_lock(&dev->lock); in uvc_suspend()
2531 if (dev->users) in uvc_suspend()
2533 mutex_unlock(&dev->lock); in uvc_suspend()
2537 list_for_each_entry(stream, &dev->streams, list) { in uvc_suspend()
2538 if (stream->intf == intf) in uvc_suspend()
2544 return -EINVAL; in uvc_suspend()
2554 intf->cur_altsetting->desc.bInterfaceNumber); in __uvc_resume()
2556 if (intf->cur_altsetting->desc.bInterfaceSubClass == in __uvc_resume()
2564 mutex_lock(&dev->lock); in __uvc_resume()
2565 if (dev->users) in __uvc_resume()
2567 mutex_unlock(&dev->lock); in __uvc_resume()
2572 list_for_each_entry(stream, &dev->streams, list) { in __uvc_resume()
2573 if (stream->intf == intf) { in __uvc_resume()
2576 uvc_queue_streamoff(&stream->queue, in __uvc_resume()
2577 stream->queue.queue.type); in __uvc_resume()
2584 return -EINVAL; in __uvc_resume()
2597 /* ------------------------------------------------------------------------
2601 static int uvc_clock_param_get(char *buffer, const struct kernel_param *kp) in uvc_clock_param_get() argument
2604 return sprintf(buffer, "CLOCK_MONOTONIC"); in uvc_clock_param_get()
2606 return sprintf(buffer, "CLOCK_REALTIME"); in uvc_clock_param_get()
2619 return -EINVAL; in uvc_clock_param_set()
2633 module_param_named(trace, uvc_dbg_param, uint, S_IRUGO|S_IWUSR);
2634 MODULE_PARM_DESC(trace, "Trace level bitmask");
2638 /* ------------------------------------------------------------------------
2690 /* Microsoft Lifecam NX-6000 */
2699 /* Microsoft Lifecam NX-3000 */
2708 /* Microsoft Lifecam VX-7000 */
2837 /* Apple Built-In iSight */
2847 /* Apple Built-In iSight via iBridge */
2892 /* ViMicro - Minoru3D */
2901 /* ViMicro Venus - Minoru3D */
2910 /* Ophir Optronics - SPCAM 620U */
3046 /* Manta MM-353 Plako */