xref: /linux/drivers/usb/gadget/function/uvc_v4l2.c (revision 3932b9ca55b0be314a36d3e84faff3e823c081f5)
1 /*
2  *	uvc_v4l2.c  --  USB Video Class Gadget driver
3  *
4  *	Copyright (C) 2009-2010
5  *	    Laurent Pinchart (laurent.pinchart@ideasonboard.com)
6  *
7  *	This program is free software; you can redistribute it and/or modify
8  *	it under the terms of the GNU General Public License as published by
9  *	the Free Software Foundation; either version 2 of the License, or
10  *	(at your option) any later version.
11  */
12 
13 #include <linux/kernel.h>
14 #include <linux/device.h>
15 #include <linux/errno.h>
16 #include <linux/list.h>
17 #include <linux/mutex.h>
18 #include <linux/videodev2.h>
19 #include <linux/vmalloc.h>
20 #include <linux/wait.h>
21 
22 #include <media/v4l2-dev.h>
23 #include <media/v4l2-event.h>
24 #include <media/v4l2-ioctl.h>
25 
26 #include "uvc.h"
27 #include "uvc_queue.h"
28 
29 /* --------------------------------------------------------------------------
30  * Requests handling
31  */
32 
33 static int
34 uvc_send_response(struct uvc_device *uvc, struct uvc_request_data *data)
35 {
36 	struct usb_composite_dev *cdev = uvc->func.config->cdev;
37 	struct usb_request *req = uvc->control_req;
38 
39 	if (data->length < 0)
40 		return usb_ep_set_halt(cdev->gadget->ep0);
41 
42 	req->length = min_t(unsigned int, uvc->event_length, data->length);
43 	req->zero = data->length < uvc->event_length;
44 
45 	memcpy(req->buf, data->data, req->length);
46 
47 	return usb_ep_queue(cdev->gadget->ep0, req, GFP_KERNEL);
48 }
49 
50 /* --------------------------------------------------------------------------
51  * V4L2
52  */
53 
54 struct uvc_format
55 {
56 	u8 bpp;
57 	u32 fcc;
58 };
59 
60 static struct uvc_format uvc_formats[] = {
61 	{ 16, V4L2_PIX_FMT_YUYV  },
62 	{ 0,  V4L2_PIX_FMT_MJPEG },
63 };
64 
65 static int
66 uvc_v4l2_get_format(struct uvc_video *video, struct v4l2_format *fmt)
67 {
68 	fmt->fmt.pix.pixelformat = video->fcc;
69 	fmt->fmt.pix.width = video->width;
70 	fmt->fmt.pix.height = video->height;
71 	fmt->fmt.pix.field = V4L2_FIELD_NONE;
72 	fmt->fmt.pix.bytesperline = video->bpp * video->width / 8;
73 	fmt->fmt.pix.sizeimage = video->imagesize;
74 	fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB;
75 	fmt->fmt.pix.priv = 0;
76 
77 	return 0;
78 }
79 
80 static int
81 uvc_v4l2_set_format(struct uvc_video *video, struct v4l2_format *fmt)
82 {
83 	struct uvc_format *format;
84 	unsigned int imagesize;
85 	unsigned int bpl;
86 	unsigned int i;
87 
88 	for (i = 0; i < ARRAY_SIZE(uvc_formats); ++i) {
89 		format = &uvc_formats[i];
90 		if (format->fcc == fmt->fmt.pix.pixelformat)
91 			break;
92 	}
93 
94 	if (i == ARRAY_SIZE(uvc_formats)) {
95 		printk(KERN_INFO "Unsupported format 0x%08x.\n",
96 			fmt->fmt.pix.pixelformat);
97 		return -EINVAL;
98 	}
99 
100 	bpl = format->bpp * fmt->fmt.pix.width / 8;
101 	imagesize = bpl ? bpl * fmt->fmt.pix.height : fmt->fmt.pix.sizeimage;
102 
103 	video->fcc = format->fcc;
104 	video->bpp = format->bpp;
105 	video->width = fmt->fmt.pix.width;
106 	video->height = fmt->fmt.pix.height;
107 	video->imagesize = imagesize;
108 
109 	fmt->fmt.pix.field = V4L2_FIELD_NONE;
110 	fmt->fmt.pix.bytesperline = bpl;
111 	fmt->fmt.pix.sizeimage = imagesize;
112 	fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB;
113 	fmt->fmt.pix.priv = 0;
114 
115 	return 0;
116 }
117 
118 static int
119 uvc_v4l2_open(struct file *file)
120 {
121 	struct video_device *vdev = video_devdata(file);
122 	struct uvc_device *uvc = video_get_drvdata(vdev);
123 	struct uvc_file_handle *handle;
124 
125 	handle = kzalloc(sizeof(*handle), GFP_KERNEL);
126 	if (handle == NULL)
127 		return -ENOMEM;
128 
129 	v4l2_fh_init(&handle->vfh, vdev);
130 	v4l2_fh_add(&handle->vfh);
131 
132 	handle->device = &uvc->video;
133 	file->private_data = &handle->vfh;
134 
135 	uvc_function_connect(uvc);
136 	return 0;
137 }
138 
139 static int
140 uvc_v4l2_release(struct file *file)
141 {
142 	struct video_device *vdev = video_devdata(file);
143 	struct uvc_device *uvc = video_get_drvdata(vdev);
144 	struct uvc_file_handle *handle = to_uvc_file_handle(file->private_data);
145 	struct uvc_video *video = handle->device;
146 
147 	uvc_function_disconnect(uvc);
148 
149 	uvc_video_enable(video, 0);
150 	uvc_free_buffers(&video->queue);
151 
152 	file->private_data = NULL;
153 	v4l2_fh_del(&handle->vfh);
154 	v4l2_fh_exit(&handle->vfh);
155 	kfree(handle);
156 
157 	return 0;
158 }
159 
160 static long
161 uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
162 {
163 	struct video_device *vdev = video_devdata(file);
164 	struct uvc_device *uvc = video_get_drvdata(vdev);
165 	struct uvc_file_handle *handle = to_uvc_file_handle(file->private_data);
166 	struct usb_composite_dev *cdev = uvc->func.config->cdev;
167 	struct uvc_video *video = &uvc->video;
168 	int ret = 0;
169 
170 	switch (cmd) {
171 	/* Query capabilities */
172 	case VIDIOC_QUERYCAP:
173 	{
174 		struct v4l2_capability *cap = arg;
175 
176 		memset(cap, 0, sizeof *cap);
177 		strlcpy(cap->driver, "g_uvc", sizeof(cap->driver));
178 		strlcpy(cap->card, cdev->gadget->name, sizeof(cap->card));
179 		strlcpy(cap->bus_info, dev_name(&cdev->gadget->dev),
180 			sizeof cap->bus_info);
181 		cap->version = DRIVER_VERSION_NUMBER;
182 		cap->capabilities = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
183 		break;
184 	}
185 
186 	/* Get & Set format */
187 	case VIDIOC_G_FMT:
188 	{
189 		struct v4l2_format *fmt = arg;
190 
191 		if (fmt->type != video->queue.queue.type)
192 			return -EINVAL;
193 
194 		return uvc_v4l2_get_format(video, fmt);
195 	}
196 
197 	case VIDIOC_S_FMT:
198 	{
199 		struct v4l2_format *fmt = arg;
200 
201 		if (fmt->type != video->queue.queue.type)
202 			return -EINVAL;
203 
204 		return uvc_v4l2_set_format(video, fmt);
205 	}
206 
207 	/* Buffers & streaming */
208 	case VIDIOC_REQBUFS:
209 	{
210 		struct v4l2_requestbuffers *rb = arg;
211 
212 		if (rb->type != video->queue.queue.type)
213 			return -EINVAL;
214 
215 		ret = uvc_alloc_buffers(&video->queue, rb);
216 		if (ret < 0)
217 			return ret;
218 
219 		ret = 0;
220 		break;
221 	}
222 
223 	case VIDIOC_QUERYBUF:
224 	{
225 		struct v4l2_buffer *buf = arg;
226 
227 		return uvc_query_buffer(&video->queue, buf);
228 	}
229 
230 	case VIDIOC_QBUF:
231 		if ((ret = uvc_queue_buffer(&video->queue, arg)) < 0)
232 			return ret;
233 
234 		return uvc_video_pump(video);
235 
236 	case VIDIOC_DQBUF:
237 		return uvc_dequeue_buffer(&video->queue, arg,
238 			file->f_flags & O_NONBLOCK);
239 
240 	case VIDIOC_STREAMON:
241 	{
242 		int *type = arg;
243 
244 		if (*type != video->queue.queue.type)
245 			return -EINVAL;
246 
247 		/* Enable UVC video. */
248 		ret = uvc_video_enable(video, 1);
249 		if (ret < 0)
250 			return ret;
251 
252 		/*
253 		 * Complete the alternate setting selection setup phase now that
254 		 * userspace is ready to provide video frames.
255 		 */
256 		uvc_function_setup_continue(uvc);
257 		uvc->state = UVC_STATE_STREAMING;
258 
259 		return 0;
260 	}
261 
262 	case VIDIOC_STREAMOFF:
263 	{
264 		int *type = arg;
265 
266 		if (*type != video->queue.queue.type)
267 			return -EINVAL;
268 
269 		return uvc_video_enable(video, 0);
270 	}
271 
272 	/* Events */
273 	case VIDIOC_DQEVENT:
274 	{
275 		struct v4l2_event *event = arg;
276 
277 		ret = v4l2_event_dequeue(&handle->vfh, event,
278 					 file->f_flags & O_NONBLOCK);
279 		if (ret == 0 && event->type == UVC_EVENT_SETUP) {
280 			struct uvc_event *uvc_event = (void *)&event->u.data;
281 
282 			/* Tell the complete callback to generate an event for
283 			 * the next request that will be enqueued by
284 			 * uvc_event_write.
285 			 */
286 			uvc->event_setup_out =
287 				!(uvc_event->req.bRequestType & USB_DIR_IN);
288 			uvc->event_length = uvc_event->req.wLength;
289 		}
290 
291 		return ret;
292 	}
293 
294 	case VIDIOC_SUBSCRIBE_EVENT:
295 	{
296 		struct v4l2_event_subscription *sub = arg;
297 
298 		if (sub->type < UVC_EVENT_FIRST || sub->type > UVC_EVENT_LAST)
299 			return -EINVAL;
300 
301 		return v4l2_event_subscribe(&handle->vfh, arg, 2, NULL);
302 	}
303 
304 	case VIDIOC_UNSUBSCRIBE_EVENT:
305 		return v4l2_event_unsubscribe(&handle->vfh, arg);
306 
307 	case UVCIOC_SEND_RESPONSE:
308 		ret = uvc_send_response(uvc, arg);
309 		break;
310 
311 	default:
312 		return -ENOIOCTLCMD;
313 	}
314 
315 	return ret;
316 }
317 
318 static long
319 uvc_v4l2_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
320 {
321 	return video_usercopy(file, cmd, arg, uvc_v4l2_do_ioctl);
322 }
323 
324 static int
325 uvc_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
326 {
327 	struct video_device *vdev = video_devdata(file);
328 	struct uvc_device *uvc = video_get_drvdata(vdev);
329 
330 	return uvc_queue_mmap(&uvc->video.queue, vma);
331 }
332 
333 static unsigned int
334 uvc_v4l2_poll(struct file *file, poll_table *wait)
335 {
336 	struct video_device *vdev = video_devdata(file);
337 	struct uvc_device *uvc = video_get_drvdata(vdev);
338 
339 	return uvc_queue_poll(&uvc->video.queue, file, wait);
340 }
341 
342 #ifndef CONFIG_MMU
343 static unsigned long uvc_v4l2_get_unmapped_area(struct file *file,
344 		unsigned long addr, unsigned long len, unsigned long pgoff,
345 		unsigned long flags)
346 {
347 	struct video_device *vdev = video_devdata(file);
348 	struct uvc_device *uvc = video_get_drvdata(vdev);
349 
350 	return uvc_queue_get_unmapped_area(&uvc->video.queue, pgoff);
351 }
352 #endif
353 
354 static struct v4l2_file_operations uvc_v4l2_fops = {
355 	.owner		= THIS_MODULE,
356 	.open		= uvc_v4l2_open,
357 	.release	= uvc_v4l2_release,
358 	.ioctl		= uvc_v4l2_ioctl,
359 	.mmap		= uvc_v4l2_mmap,
360 	.poll		= uvc_v4l2_poll,
361 #ifndef CONFIG_MMU
362 	.get_unmapped_area = uvc_v4l2_get_unmapped_area,
363 #endif
364 };
365 
366