drivers/usb/gadget/function/f_uvc.c

Source file repositories/reference/linux-study-clean/drivers/usb/gadget/function/f_uvc.c

File Facts

System
Linux kernel
Corpus path
drivers/usb/gadget/function/f_uvc.c
Extension
.c
Size
33778 bytes
Lines
1177
Domain
Driver Families
Bucket
drivers/usb
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (uvc->enable_interrupt_ep) {
			uvcg_info(f, "reset UVC interrupt endpoint\n");
			usb_ep_disable(uvc->interrupt_ep);

			if (!uvc->interrupt_ep->desc)
				if (config_ep_by_speed(cdev->gadget, f,
						       uvc->interrupt_ep))
					return -EINVAL;

			usb_ep_enable(uvc->interrupt_ep);
		}

		if (uvc->state == UVC_STATE_DISCONNECTED) {
			memset(&v4l2_event, 0, sizeof(v4l2_event));
			v4l2_event.type = UVC_EVENT_CONNECT;
			uvc_event->speed = cdev->gadget->speed;
			v4l2_event_queue(&uvc->vdev, &v4l2_event);

			uvc->state = UVC_STATE_CONNECTED;
		}

		return 0;
	}

	if (interface != uvc->streaming_intf)
		return -EINVAL;

	/* TODO
	if (usb_endpoint_xfer_bulk(&uvc->desc.vs_ep))
		return alt ? -EINVAL : 0;
	*/

	switch (alt) {
	case 0:
		if (uvc->state != UVC_STATE_STREAMING)
			return 0;

		memset(&v4l2_event, 0, sizeof(v4l2_event));
		v4l2_event.type = UVC_EVENT_STREAMOFF;
		v4l2_event_queue(&uvc->vdev, &v4l2_event);

		return USB_GADGET_DELAYED_STATUS;

	case 1:
		if (uvc->state != UVC_STATE_CONNECTED)
			return 0;

		if (!uvc->video.ep)
			return -EINVAL;

		uvcg_info(f, "reset UVC\n");
		usb_ep_disable(uvc->video.ep);

		ret = config_ep_by_speed(f->config->cdev->gadget,
				&(uvc->func), uvc->video.ep);
		if (ret)
			return ret;
		usb_ep_enable(uvc->video.ep);

		uvc->video.max_req_size = uvc->video.ep->maxpacket
			* max_t(unsigned int, uvc->video.ep->maxburst, 1)
			* (uvc->video.ep->mult);

		memset(&v4l2_event, 0, sizeof(v4l2_event));
		v4l2_event.type = UVC_EVENT_STREAMON;
		v4l2_event_queue(&uvc->vdev, &v4l2_event);
		return USB_GADGET_DELAYED_STATUS;

	default:
		return -EINVAL;
	}
}

static void
uvc_function_disable(struct usb_function *f)
{
	struct uvc_device *uvc = to_uvc(f);
	struct v4l2_event v4l2_event;

	uvcg_info(f, "%s()\n", __func__);

	memset(&v4l2_event, 0, sizeof(v4l2_event));
	v4l2_event.type = UVC_EVENT_DISCONNECT;
	v4l2_event_queue(&uvc->vdev, &v4l2_event);

	uvc->state = UVC_STATE_DISCONNECTED;

	usb_ep_disable(uvc->video.ep);
	if (uvc->enable_interrupt_ep)
		usb_ep_disable(uvc->interrupt_ep);

Annotation

Implementation Notes