Lines Matching +full:spartan +full:- +full:6

1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * uvc_driver.c -- USB Video Class driver
5 * Copyright (C) 2005-2010
23 #include <media/v4l2-common.h>
24 #include <media/v4l2-ioctl.h>
35 static unsigned int uvc_quirks_param = -1;
39 /* ------------------------------------------------------------------------
49 for (i = 0; i < alts->desc.bNumEndpoints; ++i) { in uvc_find_endpoint()
50 ep = &alts->endpoint[i]; in uvc_find_endpoint()
51 if (ep->desc.bEndpointAddress == epaddr) in uvc_find_endpoint()
88 V4L2_XFER_FUNC_709, /* Substitution for BT.470-2 M */ in uvc_xfer_func()
89 V4L2_XFER_FUNC_709, /* Substitution for BT.470-2 B, G */ in uvc_xfer_func()
118 V4L2_YCBCR_ENC_601, /* Substitution for BT.470-2 B, G */ in uvc_ycbcr_enc()
129 /* ------------------------------------------------------------------------
137 list_for_each_entry(entity, &dev->entities, list) { in uvc_entity_by_id()
138 if (entity->id == id) in uvc_entity_by_id()
151 entity = list_entry(&dev->entities, struct uvc_entity, list); in uvc_entity_by_reference()
153 list_for_each_entry_continue(entity, &dev->entities, list) { in uvc_entity_by_reference()
154 for (i = 0; i < entity->bNrInPins; ++i) in uvc_entity_by_reference()
155 if (entity->baSourceID[i] == id) in uvc_entity_by_reference()
166 list_for_each_entry(stream, &dev->streams, list) { in uvc_stream_by_id()
167 if (stream->header.bTerminalLink == id) in uvc_stream_by_id()
174 /* ------------------------------------------------------------------------
180 if (stream->async_wq) in uvc_stream_delete()
181 destroy_workqueue(stream->async_wq); in uvc_stream_delete()
183 mutex_destroy(&stream->mutex); in uvc_stream_delete()
185 usb_put_intf(stream->intf); in uvc_stream_delete()
187 kfree(stream->formats); in uvc_stream_delete()
188 kfree(stream->header.bmaControls); in uvc_stream_delete()
201 mutex_init(&stream->mutex); in uvc_stream_new()
203 stream->dev = dev; in uvc_stream_new()
204 stream->intf = usb_get_intf(intf); in uvc_stream_new()
205 stream->intfnum = intf->cur_altsetting->desc.bInterfaceNumber; in uvc_stream_new()
208 stream->async_wq = alloc_workqueue("uvcvideo", WQ_UNBOUND | WQ_HIGHPRI, in uvc_stream_new()
210 if (!stream->async_wq) { in uvc_stream_new()
218 /* ------------------------------------------------------------------------
227 struct usb_interface *intf = streaming->intf; in uvc_parse_format()
228 struct usb_host_interface *alts = intf->cur_altsetting; in uvc_parse_format()
237 format->type = buffer[2]; in uvc_parse_format()
238 format->index = buffer[3]; in uvc_parse_format()
239 format->frames = frames; in uvc_parse_format()
248 dev->udev->devnum, in uvc_parse_format()
249 alts->desc.bInterfaceNumber); in uvc_parse_format()
250 return -EINVAL; in uvc_parse_format()
261 dev_info(&streaming->intf->dev, in uvc_parse_format()
266 format->fcc = fmtdesc->fcc; in uvc_parse_format()
267 format->bpp = buffer[21]; in uvc_parse_format()
273 if (dev->quirks & UVC_QUIRK_FORCE_Y8) { in uvc_parse_format()
274 if (format->fcc == V4L2_PIX_FMT_YUYV) { in uvc_parse_format()
275 format->fcc = V4L2_PIX_FMT_GREY; in uvc_parse_format()
276 format->bpp = 8; in uvc_parse_format()
282 if (dev->quirks & UVC_QUIRK_FORCE_BPP) { in uvc_parse_format()
284 v4l2_format_info(format->fcc); in uvc_parse_format()
287 unsigned int div = info->hdiv * info->vdiv; in uvc_parse_format()
289 n = info->bpp[0] * div; in uvc_parse_format()
290 for (i = 1; i < info->comp_planes; i++) in uvc_parse_format()
291 n += info->bpp[i]; in uvc_parse_format()
293 format->bpp = DIV_ROUND_UP(8 * n, div); in uvc_parse_format()
302 format->flags = UVC_FMT_FLAG_COMPRESSED; in uvc_parse_format()
310 dev->udev->devnum, in uvc_parse_format()
311 alts->desc.bInterfaceNumber); in uvc_parse_format()
312 return -EINVAL; in uvc_parse_format()
315 format->fcc = V4L2_PIX_FMT_MJPEG; in uvc_parse_format()
316 format->flags = UVC_FMT_FLAG_COMPRESSED; in uvc_parse_format()
317 format->bpp = 0; in uvc_parse_format()
325 dev->udev->devnum, in uvc_parse_format()
326 alts->desc.bInterfaceNumber); in uvc_parse_format()
327 return -EINVAL; in uvc_parse_format()
333 dev->udev->devnum, in uvc_parse_format()
334 alts->desc.bInterfaceNumber, buffer[8]); in uvc_parse_format()
335 return -EINVAL; in uvc_parse_format()
338 format->fcc = V4L2_PIX_FMT_DV; in uvc_parse_format()
339 format->flags = UVC_FMT_FLAG_COMPRESSED | UVC_FMT_FLAG_STREAM; in uvc_parse_format()
340 format->bpp = 0; in uvc_parse_format()
346 frame->bFrameIntervalType = 1; in uvc_parse_format()
347 frame->dwDefaultFrameInterval = 1; in uvc_parse_format()
348 frame->dwFrameInterval = *intervals; in uvc_parse_format()
350 format->nframes = 1; in uvc_parse_format()
359 dev->udev->devnum, alts->desc.bInterfaceNumber, in uvc_parse_format()
361 return -EINVAL; in uvc_parse_format()
364 uvc_dbg(dev, DESCR, "Found format %p4cc", &format->fcc); in uvc_parse_format()
366 buflen -= buffer[0]; in uvc_parse_format()
377 frame = &frames[format->nframes]; in uvc_parse_format()
388 dev->udev->devnum, in uvc_parse_format()
389 alts->desc.bInterfaceNumber); in uvc_parse_format()
390 return -EINVAL; in uvc_parse_format()
393 frame->bFrameIndex = buffer[3]; in uvc_parse_format()
394 frame->bmCapabilities = buffer[4]; in uvc_parse_format()
395 frame->wWidth = get_unaligned_le16(&buffer[5]) in uvc_parse_format()
397 frame->wHeight = get_unaligned_le16(&buffer[7]); in uvc_parse_format()
398 frame->dwMinBitRate = get_unaligned_le32(&buffer[9]); in uvc_parse_format()
399 frame->dwMaxBitRate = get_unaligned_le32(&buffer[13]); in uvc_parse_format()
401 frame->dwMaxVideoFrameBufferSize = in uvc_parse_format()
403 frame->dwDefaultFrameInterval = in uvc_parse_format()
405 frame->bFrameIntervalType = buffer[25]; in uvc_parse_format()
407 frame->dwMaxVideoFrameBufferSize = 0; in uvc_parse_format()
408 frame->dwDefaultFrameInterval = in uvc_parse_format()
410 frame->bFrameIntervalType = buffer[21]; in uvc_parse_format()
421 frame->dwFrameInterval = *intervals; in uvc_parse_format()
442 if (!(format->flags & UVC_FMT_FLAG_COMPRESSED)) in uvc_parse_format()
443 frame->dwMaxVideoFrameBufferSize = format->bpp in uvc_parse_format()
444 * frame->wWidth * frame->wHeight / 8; in uvc_parse_format()
452 maxIntervalIndex = frame->bFrameIntervalType ? n - 1 : 1; in uvc_parse_format()
453 frame->dwDefaultFrameInterval = in uvc_parse_format()
454 clamp(frame->dwDefaultFrameInterval, in uvc_parse_format()
455 frame->dwFrameInterval[0], in uvc_parse_format()
456 frame->dwFrameInterval[maxIntervalIndex]); in uvc_parse_format()
463 if (dev->quirks & UVC_QUIRK_RESTRICT_FRAME_RATE) { in uvc_parse_format()
464 frame->bFrameIntervalType = 1; in uvc_parse_format()
465 (*intervals)[0] = frame->dwDefaultFrameInterval; in uvc_parse_format()
468 uvc_dbg(dev, DESCR, "- %ux%u (%u.%u fps)\n", in uvc_parse_format()
469 frame->wWidth, frame->wHeight, in uvc_parse_format()
470 10000000 / frame->dwDefaultFrameInterval, in uvc_parse_format()
471 (100000000 / frame->dwDefaultFrameInterval) % 10); in uvc_parse_format()
473 format->nframes++; in uvc_parse_format()
476 buflen -= buffer[0]; in uvc_parse_format()
482 buflen -= buffer[0]; in uvc_parse_format()
488 if (buflen < 6) { in uvc_parse_format()
491 dev->udev->devnum, in uvc_parse_format()
492 alts->desc.bInterfaceNumber); in uvc_parse_format()
493 return -EINVAL; in uvc_parse_format()
496 format->colorspace = uvc_colorspace(buffer[3]); in uvc_parse_format()
497 format->xfer_func = uvc_xfer_func(buffer[4]); in uvc_parse_format()
498 format->ycbcr_enc = uvc_ycbcr_enc(buffer[5]); in uvc_parse_format()
500 buflen -= buffer[0]; in uvc_parse_format()
503 format->colorspace = V4L2_COLORSPACE_SRGB; in uvc_parse_format()
506 return buffer - start; in uvc_parse_format()
515 struct usb_host_interface *alts = &intf->altsetting[0]; in uvc_parse_streaming()
516 const unsigned char *_buffer, *buffer = alts->extra; in uvc_parse_streaming()
517 int _buflen, buflen = alts->extralen; in uvc_parse_streaming()
522 int ret = -EINVAL; in uvc_parse_streaming()
524 if (intf->cur_altsetting->desc.bInterfaceSubClass in uvc_parse_streaming()
528 dev->udev->devnum, in uvc_parse_streaming()
529 intf->altsetting[0].desc.bInterfaceNumber); in uvc_parse_streaming()
530 return -EINVAL; in uvc_parse_streaming()
536 dev->udev->devnum, in uvc_parse_streaming()
537 intf->altsetting[0].desc.bInterfaceNumber); in uvc_parse_streaming()
538 return -EINVAL; in uvc_parse_streaming()
544 return -ENOMEM; in uvc_parse_streaming()
548 * The Pico iMage webcam has its class-specific interface descriptors in uvc_parse_streaming()
552 for (i = 0; i < alts->desc.bNumEndpoints; ++i) { in uvc_parse_streaming()
553 struct usb_host_endpoint *ep = &alts->endpoint[i]; in uvc_parse_streaming()
555 if (ep->extralen == 0) in uvc_parse_streaming()
558 if (ep->extralen > 2 && in uvc_parse_streaming()
559 ep->extra[1] == USB_DT_CS_INTERFACE) { in uvc_parse_streaming()
563 buffer = alts->endpoint[i].extra; in uvc_parse_streaming()
564 buflen = alts->endpoint[i].extralen; in uvc_parse_streaming()
572 buflen -= buffer[0]; in uvc_parse_streaming()
578 "no class-specific streaming interface descriptors found\n"); in uvc_parse_streaming()
585 streaming->type = V4L2_BUF_TYPE_VIDEO_OUTPUT; in uvc_parse_streaming()
590 streaming->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; in uvc_parse_streaming()
597 dev->udev->devnum, alts->desc.bInterfaceNumber); in uvc_parse_streaming()
602 n = buflen >= size ? buffer[size-1] : 0; in uvc_parse_streaming()
607 dev->udev->devnum, alts->desc.bInterfaceNumber); in uvc_parse_streaming()
611 streaming->header.bNumFormats = p; in uvc_parse_streaming()
612 streaming->header.bEndpointAddress = buffer[6]; in uvc_parse_streaming()
614 streaming->header.bmInfo = buffer[7]; in uvc_parse_streaming()
615 streaming->header.bTerminalLink = buffer[8]; in uvc_parse_streaming()
616 streaming->header.bStillCaptureMethod = buffer[9]; in uvc_parse_streaming()
617 streaming->header.bTriggerSupport = buffer[10]; in uvc_parse_streaming()
618 streaming->header.bTriggerUsage = buffer[11]; in uvc_parse_streaming()
620 streaming->header.bTerminalLink = buffer[7]; in uvc_parse_streaming()
622 streaming->header.bControlSize = n; in uvc_parse_streaming()
624 streaming->header.bmaControls = kmemdup(&buffer[size], p * n, in uvc_parse_streaming()
626 if (streaming->header.bmaControls == NULL) { in uvc_parse_streaming()
627 ret = -ENOMEM; in uvc_parse_streaming()
631 buflen -= buffer[0]; in uvc_parse_streaming()
660 dev->udev->devnum, in uvc_parse_streaming()
661 alts->desc.bInterfaceNumber, _buffer[2]); in uvc_parse_streaming()
678 _buflen -= _buffer[0]; in uvc_parse_streaming()
685 dev->udev->devnum, alts->desc.bInterfaceNumber); in uvc_parse_streaming()
693 ret = -ENOMEM; in uvc_parse_streaming()
700 streaming->formats = format; in uvc_parse_streaming()
701 streaming->nformats = 0; in uvc_parse_streaming()
717 streaming->nformats++; in uvc_parse_streaming()
718 frame += format->nframes; in uvc_parse_streaming()
721 buflen -= ret; in uvc_parse_streaming()
729 buflen -= buffer[0]; in uvc_parse_streaming()
736 dev->udev->devnum, alts->desc.bInterfaceNumber, buflen); in uvc_parse_streaming()
739 for (i = 0; i < intf->num_altsetting; ++i) { in uvc_parse_streaming()
742 alts = &intf->altsetting[i]; in uvc_parse_streaming()
744 streaming->header.bEndpointAddress); in uvc_parse_streaming()
747 psize = uvc_endpoint_max_bpi(dev->udev, ep); in uvc_parse_streaming()
748 if (psize > streaming->maxpsize) in uvc_parse_streaming()
749 streaming->maxpsize = psize; in uvc_parse_streaming()
752 list_add_tail(&streaming->list, &dev->streams); in uvc_parse_streaming()
775 extra_size = roundup(extra_size, sizeof(*entity->pads)); in uvc_alloc_entity()
777 num_inputs = type & UVC_TERM_OUTPUT ? num_pads : num_pads - 1; in uvc_alloc_entity()
780 size = sizeof(*entity) + extra_size + sizeof(*entity->pads) * num_pads in uvc_alloc_entity()
786 entity->id = id; in uvc_alloc_entity()
787 entity->type = type; in uvc_alloc_entity()
795 memcpy(entity->guid, uvc_gpio_guid, 16); in uvc_alloc_entity()
798 memcpy(entity->guid, uvc_camera_guid, 16); in uvc_alloc_entity()
801 memcpy(entity->guid, uvc_media_transport_input_guid, 16); in uvc_alloc_entity()
804 memcpy(entity->guid, uvc_processing_guid, 16); in uvc_alloc_entity()
808 entity->num_links = 0; in uvc_alloc_entity()
809 entity->num_pads = num_pads; in uvc_alloc_entity()
810 entity->pads = ((void *)(entity + 1)) + extra_size; in uvc_alloc_entity()
813 entity->pads[i].flags = MEDIA_PAD_FL_SINK; in uvc_alloc_entity()
815 entity->pads[num_pads-1].flags = MEDIA_PAD_FL_SOURCE; in uvc_alloc_entity()
817 entity->bNrInPins = num_inputs; in uvc_alloc_entity()
818 entity->baSourceID = (u8 *)(&entity->pads[num_pads]); in uvc_alloc_entity()
835 ret = usb_string(dev->udev, string_id, entity->name, in uvc_entity_set_name()
836 sizeof(entity->name)); in uvc_entity_set_name()
841 sprintf(entity->name, "%s %u", type_name, entity->id); in uvc_entity_set_name()
844 /* Parse vendor-specific extensions. */
848 struct usb_device *udev = dev->udev; in uvc_parse_vendor_control()
849 struct usb_host_interface *alts = dev->intf->cur_altsetting; in uvc_parse_vendor_control()
854 switch (le16_to_cpu(dev->udev->descriptor.idVendor)) { in uvc_parse_vendor_control()
868 * ---------------------------------------------------------- in uvc_parse_vendor_control()
871 * ---------------------------------------------------------- in uvc_parse_vendor_control()
878 * ---------------------------------------------------------- in uvc_parse_vendor_control()
880 * ---------------------------------------------------------- in uvc_parse_vendor_control()
884 * ---------------------------------------------------------- in uvc_parse_vendor_control()
892 udev->devnum, alts->desc.bInterfaceNumber); in uvc_parse_vendor_control()
899 return -ENOMEM; in uvc_parse_vendor_control()
901 memcpy(unit->guid, &buffer[4], 16); in uvc_parse_vendor_control()
902 unit->extension.bNumControls = buffer[20]; in uvc_parse_vendor_control()
903 memcpy(unit->baSourceID, &buffer[22], p); in uvc_parse_vendor_control()
904 unit->extension.bControlSize = buffer[22+p]; in uvc_parse_vendor_control()
905 unit->extension.bmControls = (u8 *)unit + sizeof(*unit); in uvc_parse_vendor_control()
906 unit->extension.bmControlsType = (u8 *)unit + sizeof(*unit) in uvc_parse_vendor_control()
908 memcpy(unit->extension.bmControls, &buffer[23+p], 2*n); in uvc_parse_vendor_control()
912 list_add_tail(&unit->list, &dev->entities); in uvc_parse_vendor_control()
923 struct usb_device *udev = dev->udev; in uvc_parse_standard_control()
926 struct usb_host_interface *alts = dev->intf->cur_altsetting; in uvc_parse_standard_control()
938 udev->devnum, alts->desc.bInterfaceNumber); in uvc_parse_standard_control()
939 return -EINVAL; in uvc_parse_standard_control()
942 dev->uvc_version = get_unaligned_le16(&buffer[3]); in uvc_parse_standard_control()
943 dev->clock_frequency = get_unaligned_le32(&buffer[7]); in uvc_parse_standard_control()
951 udev->devnum, i); in uvc_parse_standard_control()
963 udev->devnum, alts->desc.bInterfaceNumber); in uvc_parse_standard_control()
964 return -EINVAL; in uvc_parse_standard_control()
970 * - The high byte must be non-zero, otherwise it would be in uvc_parse_standard_control()
973 * - Bit 15 must be 0, as we use it internally as a terminal in uvc_parse_standard_control()
982 udev->devnum, alts->desc.bInterfaceNumber, in uvc_parse_standard_control()
1004 udev->devnum, alts->desc.bInterfaceNumber); in uvc_parse_standard_control()
1005 return -EINVAL; in uvc_parse_standard_control()
1011 return -ENOMEM; in uvc_parse_standard_control()
1014 term->camera.bControlSize = n; in uvc_parse_standard_control()
1015 term->camera.bmControls = (u8 *)term + sizeof(*term); in uvc_parse_standard_control()
1016 term->camera.wObjectiveFocalLengthMin = in uvc_parse_standard_control()
1018 term->camera.wObjectiveFocalLengthMax = in uvc_parse_standard_control()
1020 term->camera.wOcularFocalLength = in uvc_parse_standard_control()
1022 memcpy(term->camera.bmControls, &buffer[15], n); in uvc_parse_standard_control()
1025 term->media.bControlSize = n; in uvc_parse_standard_control()
1026 term->media.bmControls = (u8 *)term + sizeof(*term); in uvc_parse_standard_control()
1027 term->media.bTransportModeSize = p; in uvc_parse_standard_control()
1028 term->media.bmTransportModes = (u8 *)term in uvc_parse_standard_control()
1030 memcpy(term->media.bmControls, &buffer[9], n); in uvc_parse_standard_control()
1031 memcpy(term->media.bmTransportModes, &buffer[10+n], p); in uvc_parse_standard_control()
1043 list_add_tail(&term->list, &dev->entities); in uvc_parse_standard_control()
1050 udev->devnum, alts->desc.bInterfaceNumber); in uvc_parse_standard_control()
1051 return -EINVAL; in uvc_parse_standard_control()
1062 udev->devnum, alts->desc.bInterfaceNumber, in uvc_parse_standard_control()
1070 return -ENOMEM; in uvc_parse_standard_control()
1072 memcpy(term->baSourceID, &buffer[7], 1); in uvc_parse_standard_control()
1076 list_add_tail(&term->list, &dev->entities); in uvc_parse_standard_control()
1082 if (buflen < 5 || buflen < 6 + p) { in uvc_parse_standard_control()
1085 udev->devnum, alts->desc.bInterfaceNumber); in uvc_parse_standard_control()
1086 return -EINVAL; in uvc_parse_standard_control()
1091 return -ENOMEM; in uvc_parse_standard_control()
1093 memcpy(unit->baSourceID, &buffer[5], p); in uvc_parse_standard_control()
1097 list_add_tail(&unit->list, &dev->entities); in uvc_parse_standard_control()
1102 p = dev->uvc_version >= 0x0110 ? 10 : 9; in uvc_parse_standard_control()
1107 udev->devnum, alts->desc.bInterfaceNumber); in uvc_parse_standard_control()
1108 return -EINVAL; in uvc_parse_standard_control()
1113 return -ENOMEM; in uvc_parse_standard_control()
1115 memcpy(unit->baSourceID, &buffer[4], 1); in uvc_parse_standard_control()
1116 unit->processing.wMaxMultiplier = in uvc_parse_standard_control()
1118 unit->processing.bControlSize = buffer[7]; in uvc_parse_standard_control()
1119 unit->processing.bmControls = (u8 *)unit + sizeof(*unit); in uvc_parse_standard_control()
1120 memcpy(unit->processing.bmControls, &buffer[8], n); in uvc_parse_standard_control()
1121 if (dev->uvc_version >= 0x0110) in uvc_parse_standard_control()
1122 unit->processing.bmVideoStandards = buffer[9+n]; in uvc_parse_standard_control()
1126 list_add_tail(&unit->list, &dev->entities); in uvc_parse_standard_control()
1136 udev->devnum, alts->desc.bInterfaceNumber); in uvc_parse_standard_control()
1137 return -EINVAL; in uvc_parse_standard_control()
1142 return -ENOMEM; in uvc_parse_standard_control()
1144 memcpy(unit->guid, &buffer[4], 16); in uvc_parse_standard_control()
1145 unit->extension.bNumControls = buffer[20]; in uvc_parse_standard_control()
1146 memcpy(unit->baSourceID, &buffer[22], p); in uvc_parse_standard_control()
1147 unit->extension.bControlSize = buffer[22+p]; in uvc_parse_standard_control()
1148 unit->extension.bmControls = (u8 *)unit + sizeof(*unit); in uvc_parse_standard_control()
1149 memcpy(unit->extension.bmControls, &buffer[23+p], n); in uvc_parse_standard_control()
1153 list_add_tail(&unit->list, &dev->entities); in uvc_parse_standard_control()
1168 struct usb_host_interface *alts = dev->intf->cur_altsetting; in uvc_parse_control()
1169 const unsigned char *buffer = alts->extra; in uvc_parse_control()
1170 int buflen = alts->extralen; in uvc_parse_control()
1189 buflen -= buffer[0]; in uvc_parse_control()
1194 * Check if the optional status endpoint is present. Built-in iSight in uvc_parse_control()
1199 if (alts->desc.bNumEndpoints == 1 && in uvc_parse_control()
1200 !(dev->quirks & UVC_QUIRK_BUILTIN_ISIGHT)) { in uvc_parse_control()
1201 struct usb_host_endpoint *ep = &alts->endpoint[0]; in uvc_parse_control()
1202 struct usb_endpoint_descriptor *desc = &ep->desc; in uvc_parse_control()
1205 le16_to_cpu(desc->wMaxPacketSize) >= 8 && in uvc_parse_control()
1206 desc->bInterval != 0) { in uvc_parse_control()
1209 desc->bEndpointAddress); in uvc_parse_control()
1210 dev->int_ep = ep; in uvc_parse_control()
1217 /* -----------------------------------------------------------------------------
1223 struct uvc_entity *unit = dev->gpio_unit; in uvc_gpio_event()
1230 new_val = gpiod_get_value_cansleep(unit->gpio.gpio_privacy); in uvc_gpio_event()
1233 chain = list_first_entry(&dev->chains, struct uvc_video_chain, list); in uvc_gpio_event()
1234 uvc_ctrl_status_event(chain, unit->controls, &new_val); in uvc_gpio_event()
1241 return -EINVAL; in uvc_gpio_get_cur()
1243 *(u8 *)data = gpiod_get_value_cansleep(entity->gpio.gpio_privacy); in uvc_gpio_get_cur()
1252 return -EINVAL; in uvc_gpio_get_info()
1272 gpio_privacy = devm_gpiod_get_optional(&dev->udev->dev, "privacy", in uvc_gpio_parse()
1279 return dev_err_probe(&dev->udev->dev, irq, in uvc_gpio_parse()
1284 return -ENOMEM; in uvc_gpio_parse()
1286 unit->gpio.gpio_privacy = gpio_privacy; in uvc_gpio_parse()
1287 unit->gpio.irq = irq; in uvc_gpio_parse()
1288 unit->gpio.bControlSize = 1; in uvc_gpio_parse()
1289 unit->gpio.bmControls = (u8 *)unit + sizeof(*unit); in uvc_gpio_parse()
1290 unit->gpio.bmControls[0] = 1; in uvc_gpio_parse()
1291 unit->get_cur = uvc_gpio_get_cur; in uvc_gpio_parse()
1292 unit->get_info = uvc_gpio_get_info; in uvc_gpio_parse()
1293 strscpy(unit->name, "GPIO", sizeof(unit->name)); in uvc_gpio_parse()
1295 list_add_tail(&unit->list, &dev->entities); in uvc_gpio_parse()
1297 dev->gpio_unit = unit; in uvc_gpio_parse()
1304 struct uvc_entity *unit = dev->gpio_unit; in uvc_gpio_init_irq()
1306 if (!unit || unit->gpio.irq < 0) in uvc_gpio_init_irq()
1309 return devm_request_threaded_irq(&dev->udev->dev, unit->gpio.irq, NULL, in uvc_gpio_init_irq()
1316 /* ------------------------------------------------------------------------
1324 * - one or more Output Terminals (USB Streaming or Display)
1325 * - zero or one Processing Unit
1326 * - zero, one or more single-input Selector Units
1327 * - zero or one multiple-input Selector Units, provided all inputs are
1329 * - zero, one or mode single-input Extension Units
1330 * - one or more Input Terminals (Camera, External or USB Streaming)
1334 * ITT_*(0) -> +---------+ +---------+ +---------+ -> TT_STREAMING(0)
1335 * ... | SU{0,1} | -> | PU{0,1} | -> | XU{0,n} | ...
1336 * ITT_*(n) -> +---------+ +---------+ +---------+ -> TT_STREAMING(n)
1338 * +---------+ +---------+ -> OTT_*(0)
1339 * TT_STREAMING -> | PU{0,1} | -> | XU{0,n} | ...
1340 * +---------+ +---------+ -> OTT_*(n)
1343 * Extension Units connected to the main chain as single-unit branches are
1344 * also supported. Single-input Selector Units are ignored.
1351 uvc_dbg_cont(PROBE, " <- XU %d", entity->id); in uvc_scan_chain_entity()
1353 if (entity->bNrInPins != 1) { in uvc_scan_chain_entity()
1354 uvc_dbg(chain->dev, DESCR, in uvc_scan_chain_entity()
1356 entity->id); in uvc_scan_chain_entity()
1357 return -1; in uvc_scan_chain_entity()
1363 uvc_dbg_cont(PROBE, " <- PU %d", entity->id); in uvc_scan_chain_entity()
1365 if (chain->processing != NULL) { in uvc_scan_chain_entity()
1366 uvc_dbg(chain->dev, DESCR, in uvc_scan_chain_entity()
1368 return -1; in uvc_scan_chain_entity()
1371 chain->processing = entity; in uvc_scan_chain_entity()
1375 uvc_dbg_cont(PROBE, " <- SU %d", entity->id); in uvc_scan_chain_entity()
1377 /* Single-input selector units are ignored. */ in uvc_scan_chain_entity()
1378 if (entity->bNrInPins == 1) in uvc_scan_chain_entity()
1381 if (chain->selector != NULL) { in uvc_scan_chain_entity()
1382 uvc_dbg(chain->dev, DESCR, in uvc_scan_chain_entity()
1384 return -1; in uvc_scan_chain_entity()
1387 chain->selector = entity; in uvc_scan_chain_entity()
1393 uvc_dbg_cont(PROBE, " <- IT %d\n", entity->id); in uvc_scan_chain_entity()
1400 uvc_dbg_cont(PROBE, " OT %d", entity->id); in uvc_scan_chain_entity()
1406 uvc_dbg_cont(PROBE, " <- IT %d\n", entity->id); in uvc_scan_chain_entity()
1408 uvc_dbg_cont(PROBE, " OT %d", entity->id); in uvc_scan_chain_entity()
1413 uvc_dbg(chain->dev, DESCR, in uvc_scan_chain_entity()
1416 return -1; in uvc_scan_chain_entity()
1419 list_add_tail(&entity->chain, &chain->entities); in uvc_scan_chain_entity()
1434 forward = uvc_entity_by_reference(chain->dev, entity->id, in uvc_scan_chain_forward()
1440 if (forward->chain.next || forward->chain.prev) { in uvc_scan_chain_forward()
1441 uvc_dbg(chain->dev, DESCR, in uvc_scan_chain_forward()
1443 forward->id); in uvc_scan_chain_forward()
1444 return -EINVAL; in uvc_scan_chain_forward()
1449 if (forward->bNrInPins != 1) { in uvc_scan_chain_forward()
1450 uvc_dbg(chain->dev, DESCR, in uvc_scan_chain_forward()
1452 forward->id); in uvc_scan_chain_forward()
1453 return -EINVAL; in uvc_scan_chain_forward()
1469 source = uvc_entity_by_id(chain->dev, in uvc_scan_chain_forward()
1470 entity->baSourceID[0]); in uvc_scan_chain_forward()
1472 uvc_dbg(chain->dev, DESCR, in uvc_scan_chain_forward()
1474 forward->id); in uvc_scan_chain_forward()
1478 forward->baSourceID[0] = source->id; in uvc_scan_chain_forward()
1481 list_add_tail(&forward->chain, &chain->entities); in uvc_scan_chain_forward()
1483 uvc_dbg_cont(PROBE, " (->"); in uvc_scan_chain_forward()
1485 uvc_dbg_cont(PROBE, " XU %d", forward->id); in uvc_scan_chain_forward()
1494 uvc_dbg(chain->dev, DESCR, in uvc_scan_chain_forward()
1496 forward->id); in uvc_scan_chain_forward()
1497 return -EINVAL; in uvc_scan_chain_forward()
1501 uvc_dbg(chain->dev, DESCR, in uvc_scan_chain_forward()
1503 entity->id, forward->id); in uvc_scan_chain_forward()
1507 list_add_tail(&forward->chain, &chain->entities); in uvc_scan_chain_forward()
1509 uvc_dbg_cont(PROBE, " (->"); in uvc_scan_chain_forward()
1511 uvc_dbg_cont(PROBE, " OT %d", forward->id); in uvc_scan_chain_forward()
1527 int id = -EINVAL, i; in uvc_scan_chain_backward()
1532 id = entity->baSourceID[0]; in uvc_scan_chain_backward()
1536 /* Single-input selector units are ignored. */ in uvc_scan_chain_backward()
1537 if (entity->bNrInPins == 1) { in uvc_scan_chain_backward()
1538 id = entity->baSourceID[0]; in uvc_scan_chain_backward()
1542 uvc_dbg_cont(PROBE, " <- IT"); in uvc_scan_chain_backward()
1544 chain->selector = entity; in uvc_scan_chain_backward()
1545 for (i = 0; i < entity->bNrInPins; ++i) { in uvc_scan_chain_backward()
1546 id = entity->baSourceID[i]; in uvc_scan_chain_backward()
1547 term = uvc_entity_by_id(chain->dev, id); in uvc_scan_chain_backward()
1549 uvc_dbg(chain->dev, DESCR, in uvc_scan_chain_backward()
1551 entity->id, i); in uvc_scan_chain_backward()
1552 return -1; in uvc_scan_chain_backward()
1555 if (term->chain.next || term->chain.prev) { in uvc_scan_chain_backward()
1556 uvc_dbg(chain->dev, DESCR, in uvc_scan_chain_backward()
1558 term->id); in uvc_scan_chain_backward()
1559 return -EINVAL; in uvc_scan_chain_backward()
1562 uvc_dbg_cont(PROBE, " %d", term->id); in uvc_scan_chain_backward()
1564 list_add_tail(&term->chain, &chain->entities); in uvc_scan_chain_backward()
1580 id = UVC_ENTITY_IS_OTERM(entity) ? entity->baSourceID[0] : 0; in uvc_scan_chain_backward()
1589 entity = uvc_entity_by_id(chain->dev, id); in uvc_scan_chain_backward()
1591 uvc_dbg(chain->dev, DESCR, in uvc_scan_chain_backward()
1593 return -EINVAL; in uvc_scan_chain_backward()
1605 uvc_dbg(chain->dev, PROBE, "Scanning UVC chain:"); in uvc_scan_chain()
1612 if (entity->chain.next || entity->chain.prev) { in uvc_scan_chain()
1613 uvc_dbg(chain->dev, DESCR, in uvc_scan_chain()
1615 entity->id); in uvc_scan_chain()
1616 return -EINVAL; in uvc_scan_chain()
1621 return -EINVAL; in uvc_scan_chain()
1625 return -EINVAL; in uvc_scan_chain()
1630 return -EINVAL; in uvc_scan_chain()
1654 p += sprintf(p, "%u", term->id); in uvc_print_terms()
1657 return p - buffer; in uvc_print_terms()
1665 p += uvc_print_terms(&chain->entities, UVC_TERM_INPUT, p); in uvc_print_chain()
1666 p += sprintf(p, " -> "); in uvc_print_chain()
1667 uvc_print_terms(&chain->entities, UVC_TERM_OUTPUT, p); in uvc_print_chain()
1680 INIT_LIST_HEAD(&chain->entities); in uvc_alloc_chain()
1681 mutex_init(&chain->ctrl_mutex); in uvc_alloc_chain()
1682 chain->dev = dev; in uvc_alloc_chain()
1683 v4l2_prio_init(&chain->prio); in uvc_alloc_chain()
1698 * - Acer Integrated Camera (5986:055a)
1699 * - Realtek rtl157a7 (0bda:57a7)
1713 list_for_each_entry(entity, &dev->entities, list) { in uvc_scan_fallback()
1716 return -EINVAL; in uvc_scan_fallback()
1722 return -EINVAL; in uvc_scan_fallback()
1728 return -EINVAL; in uvc_scan_fallback()
1733 return -ENOMEM; in uvc_scan_fallback()
1747 list_for_each_entry_reverse(entity, &dev->entities, list) { in uvc_scan_fallback()
1748 if (entity->type != UVC_VC_PROCESSING_UNIT && in uvc_scan_fallback()
1749 entity->type != UVC_VC_EXTENSION_UNIT) in uvc_scan_fallback()
1752 if (entity->num_pads != 2) in uvc_scan_fallback()
1758 prev->baSourceID[0] = entity->id; in uvc_scan_fallback()
1765 prev->baSourceID[0] = iterm->id; in uvc_scan_fallback()
1767 list_add_tail(&chain->list, &dev->chains); in uvc_scan_fallback()
1776 return -EINVAL; in uvc_scan_fallback()
1789 list_for_each_entry(term, &dev->entities, list) { in uvc_scan_device()
1799 if (term->chain.next || term->chain.prev) in uvc_scan_device()
1804 return -ENOMEM; in uvc_scan_device()
1806 term->flags |= UVC_ENTITY_FLAG_DEFAULT; in uvc_scan_device()
1816 list_add_tail(&chain->list, &dev->chains); in uvc_scan_device()
1819 if (list_empty(&dev->chains)) in uvc_scan_device()
1822 if (list_empty(&dev->chains)) { in uvc_scan_device()
1823 dev_info(&dev->udev->dev, "No valid video chain found.\n"); in uvc_scan_device()
1824 return -1; in uvc_scan_device()
1828 if (dev->gpio_unit) { in uvc_scan_device()
1829 chain = list_first_entry(&dev->chains, in uvc_scan_device()
1831 list_add_tail(&dev->gpio_unit->chain, &chain->entities); in uvc_scan_device()
1837 /* ------------------------------------------------------------------------
1859 usb_put_intf(dev->intf); in uvc_delete()
1860 usb_put_dev(dev->udev); in uvc_delete()
1863 media_device_cleanup(&dev->mdev); in uvc_delete()
1866 list_for_each_safe(p, n, &dev->chains) { in uvc_delete()
1873 list_for_each_safe(p, n, &dev->entities) { in uvc_delete()
1883 list_for_each_safe(p, n, &dev->streams) { in uvc_delete()
1888 streaming->intf); in uvc_delete()
1898 struct uvc_device *dev = stream->dev; in uvc_release()
1900 kref_put(&dev->ref, uvc_delete); in uvc_release()
1910 list_for_each_entry(stream, &dev->streams, list) { in uvc_unregister_video()
1911 if (!video_is_registered(&stream->vdev)) in uvc_unregister_video()
1914 video_unregister_device(&stream->vdev); in uvc_unregister_video()
1915 video_unregister_device(&stream->meta.vdev); in uvc_unregister_video()
1922 if (dev->vdev.dev) in uvc_unregister_video()
1923 v4l2_device_unregister(&dev->vdev); in uvc_unregister_video()
1925 if (media_devnode_is_registered(dev->mdev.devnode)) in uvc_unregister_video()
1926 media_device_unregister(&dev->mdev); in uvc_unregister_video()
1948 * We already hold a reference to dev->udev. The video device will be in uvc_register_video_device()
1952 vdev->v4l2_dev = &dev->vdev; in uvc_register_video_device()
1953 vdev->fops = fops; in uvc_register_video_device()
1954 vdev->ioctl_ops = ioctl_ops; in uvc_register_video_device()
1955 vdev->release = uvc_release; in uvc_register_video_device()
1956 vdev->prio = &stream->chain->prio; in uvc_register_video_device()
1958 vdev->vfl_dir = VFL_DIR_TX; in uvc_register_video_device()
1960 vdev->vfl_dir = VFL_DIR_RX; in uvc_register_video_device()
1965 vdev->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; in uvc_register_video_device()
1968 vdev->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING; in uvc_register_video_device()
1971 vdev->device_caps = V4L2_CAP_META_CAPTURE | V4L2_CAP_STREAMING; in uvc_register_video_device()
1975 strscpy(vdev->name, dev->name, sizeof(vdev->name)); in uvc_register_video_device()
1983 ret = video_register_device(vdev, VFL_TYPE_VIDEO, -1); in uvc_register_video_device()
1985 dev_err(&stream->intf->dev, in uvc_register_video_device()
1991 kref_get(&dev->ref); in uvc_register_video_device()
2003 dev_err(&stream->intf->dev, in uvc_register_video()
2008 if (stream->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) in uvc_register_video()
2009 stream->chain->caps |= V4L2_CAP_VIDEO_CAPTURE in uvc_register_video()
2012 stream->chain->caps |= V4L2_CAP_VIDEO_OUTPUT; in uvc_register_video()
2017 return uvc_register_video_device(dev, stream, &stream->vdev, in uvc_register_video()
2018 &stream->queue, stream->type, in uvc_register_video()
2032 list_for_each_entry(term, &chain->entities, chain) { in uvc_register_terms()
2036 stream = uvc_stream_by_id(dev, term->id); in uvc_register_terms()
2038 dev_info(&dev->udev->dev, in uvc_register_terms()
2040 term->id); in uvc_register_terms()
2044 stream->chain = chain; in uvc_register_terms()
2055 term->vdev = &stream->vdev; in uvc_register_terms()
2066 list_for_each_entry(chain, &dev->chains, list) { in uvc_register_chains()
2074 dev_info(&dev->udev->dev, in uvc_register_chains()
2082 /* ------------------------------------------------------------------------
2094 (const struct uvc_device_info *)id->driver_info; in uvc_probe()
2101 return -ENOMEM; in uvc_probe()
2103 INIT_LIST_HEAD(&dev->entities); in uvc_probe()
2104 INIT_LIST_HEAD(&dev->chains); in uvc_probe()
2105 INIT_LIST_HEAD(&dev->streams); in uvc_probe()
2106 kref_init(&dev->ref); in uvc_probe()
2107 atomic_set(&dev->nmappings, 0); in uvc_probe()
2108 mutex_init(&dev->lock); in uvc_probe()
2110 dev->udev = usb_get_dev(udev); in uvc_probe()
2111 dev->intf = usb_get_intf(intf); in uvc_probe()
2112 dev->intfnum = intf->cur_altsetting->desc.bInterfaceNumber; in uvc_probe()
2113 dev->info = info ? info : &uvc_quirk_none; in uvc_probe()
2114 dev->quirks = uvc_quirks_param == -1 in uvc_probe()
2115 ? dev->info->quirks : uvc_quirks_param; in uvc_probe()
2117 if (id->idVendor && id->idProduct) in uvc_probe()
2119 udev->devpath, id->idVendor, id->idProduct); in uvc_probe()
2122 udev->devpath); in uvc_probe()
2124 if (udev->product != NULL) in uvc_probe()
2125 strscpy(dev->name, udev->product, sizeof(dev->name)); in uvc_probe()
2127 snprintf(dev->name, sizeof(dev->name), in uvc_probe()
2129 le16_to_cpu(udev->descriptor.idVendor), in uvc_probe()
2130 le16_to_cpu(udev->descriptor.idProduct)); in uvc_probe()
2137 if (intf->intf_assoc && intf->intf_assoc->iFunction != 0) in uvc_probe()
2138 function = intf->intf_assoc->iFunction; in uvc_probe()
2140 function = intf->cur_altsetting->desc.iInterface; in uvc_probe()
2144 strlcat(dev->name, ": ", sizeof(dev->name)); in uvc_probe()
2145 len = strlen(dev->name); in uvc_probe()
2146 usb_string(udev, function, dev->name + len, in uvc_probe()
2147 sizeof(dev->name) - len); in uvc_probe()
2152 dev->mdev.dev = &intf->dev; in uvc_probe()
2153 strscpy(dev->mdev.model, dev->name, sizeof(dev->mdev.model)); in uvc_probe()
2154 if (udev->serial) in uvc_probe()
2155 strscpy(dev->mdev.serial, udev->serial, in uvc_probe()
2156 sizeof(dev->mdev.serial)); in uvc_probe()
2157 usb_make_path(udev, dev->mdev.bus_info, sizeof(dev->mdev.bus_info)); in uvc_probe()
2158 dev->mdev.hw_revision = le16_to_cpu(udev->descriptor.bcdDevice); in uvc_probe()
2159 media_device_init(&dev->mdev); in uvc_probe()
2161 dev->vdev.mdev = &dev->mdev; in uvc_probe()
2176 dev_info(&dev->udev->dev, "Found UVC %u.%02x device %s (%04x:%04x)\n", in uvc_probe()
2177 dev->uvc_version >> 8, dev->uvc_version & 0xff, in uvc_probe()
2178 udev->product ? udev->product : "<unnamed>", in uvc_probe()
2179 le16_to_cpu(udev->descriptor.idVendor), in uvc_probe()
2180 le16_to_cpu(udev->descriptor.idProduct)); in uvc_probe()
2182 if (dev->quirks != dev->info->quirks) { in uvc_probe()
2183 dev_info(&dev->udev->dev, in uvc_probe()
2185 dev->quirks); in uvc_probe()
2186 dev_info(&dev->udev->dev, in uvc_probe()
2187 "Please report required quirks to the linux-media mailing list.\n"); in uvc_probe()
2190 if (dev->info->uvc_version) { in uvc_probe()
2191 dev->uvc_version = dev->info->uvc_version; in uvc_probe()
2192 dev_info(&dev->udev->dev, "Forcing UVC version to %u.%02x\n", in uvc_probe()
2193 dev->uvc_version >> 8, dev->uvc_version & 0xff); in uvc_probe()
2197 if (v4l2_device_register(&intf->dev, &dev->vdev) < 0) in uvc_probe()
2214 if (media_device_register(&dev->mdev) < 0) in uvc_probe()
2223 dev_info(&dev->udev->dev, in uvc_probe()
2230 dev_err(&dev->udev->dev, in uvc_probe()
2241 kref_put(&dev->ref, uvc_delete); in uvc_probe()
2242 return -ENODEV; in uvc_probe()
2255 if (intf->cur_altsetting->desc.bInterfaceSubClass == in uvc_disconnect()
2260 kref_put(&dev->ref, uvc_delete); in uvc_disconnect()
2269 intf->cur_altsetting->desc.bInterfaceNumber); in uvc_suspend()
2272 if (intf->cur_altsetting->desc.bInterfaceSubClass == in uvc_suspend()
2274 mutex_lock(&dev->lock); in uvc_suspend()
2275 if (dev->users) in uvc_suspend()
2277 mutex_unlock(&dev->lock); in uvc_suspend()
2281 list_for_each_entry(stream, &dev->streams, list) { in uvc_suspend()
2282 if (stream->intf == intf) in uvc_suspend()
2288 return -EINVAL; in uvc_suspend()
2298 intf->cur_altsetting->desc.bInterfaceNumber); in __uvc_resume()
2300 if (intf->cur_altsetting->desc.bInterfaceSubClass == in __uvc_resume()
2308 mutex_lock(&dev->lock); in __uvc_resume()
2309 if (dev->users) in __uvc_resume()
2311 mutex_unlock(&dev->lock); in __uvc_resume()
2316 list_for_each_entry(stream, &dev->streams, list) { in __uvc_resume()
2317 if (stream->intf == intf) { in __uvc_resume()
2320 uvc_queue_streamoff(&stream->queue, in __uvc_resume()
2321 stream->queue.queue.type); in __uvc_resume()
2328 return -EINVAL; in __uvc_resume()
2341 /* ------------------------------------------------------------------------
2363 return -EINVAL; in uvc_clock_param_set()
2382 /* ------------------------------------------------------------------------
2475 /* Microsoft Lifecam NX-6000 */
2484 /* Microsoft Lifecam NX-3000 */
2493 /* Microsoft Lifecam VX-7000 */
2676 /* Apple Built-In iSight */
2686 /* Apple FaceTime HD Camera (Built-In) */
2695 /* Apple Built-In iSight via iBridge */
2740 /* ViMicro - Minoru3D */
2749 /* ViMicro Venus - Minoru3D */
2758 /* Ophir Optronics - SPCAM 620U */
2795 /* Syntek (HP Spartan) */
2894 /* Manta MM-353 Plako */