1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * uvc_v4l2.c -- USB Video Class Gadget driver
4 *
5 * Copyright (C) 2009-2010
6 * Laurent Pinchart (laurent.pinchart@ideasonboard.com)
7 */
8
9 #include <linux/device.h>
10 #include <linux/errno.h>
11 #include <linux/kernel.h>
12 #include <linux/list.h>
13 #include <linux/usb/g_uvc.h>
14 #include <linux/usb/uvc.h>
15 #include <linux/videodev2.h>
16 #include <linux/vmalloc.h>
17 #include <linux/wait.h>
18
19 #include <media/v4l2-dev.h>
20 #include <media/v4l2-event.h>
21 #include <media/v4l2-ioctl.h>
22
23 #include "f_uvc.h"
24 #include "uvc.h"
25 #include "uvc_queue.h"
26 #include "uvc_video.h"
27 #include "uvc_v4l2.h"
28 #include "uvc_configfs.h"
29
to_uvc_format(struct uvcg_format * uformat)30 static const struct uvc_format_desc *to_uvc_format(struct uvcg_format *uformat)
31 {
32 char guid[16] = UVC_GUID_FORMAT_MJPEG;
33 const struct uvc_format_desc *format;
34
35 if (uformat->type == UVCG_UNCOMPRESSED) {
36 struct uvcg_uncompressed *unc;
37
38 unc = to_uvcg_uncompressed(&uformat->group.cg_item);
39 if (!unc)
40 return ERR_PTR(-EINVAL);
41
42 memcpy(guid, unc->desc.guidFormat, sizeof(guid));
43 } else if (uformat->type == UVCG_FRAMEBASED) {
44 struct uvcg_framebased *unc;
45
46 unc = to_uvcg_framebased(&uformat->group.cg_item);
47 if (!unc)
48 return ERR_PTR(-EINVAL);
49
50 memcpy(guid, unc->desc.guidFormat, sizeof(guid));
51 }
52
53 format = uvc_format_by_guid(guid);
54 if (!format)
55 return ERR_PTR(-EINVAL);
56
57 return format;
58 }
59
uvc_v4l2_get_bytesperline(struct uvcg_format * uformat,struct uvcg_frame * uframe)60 static int uvc_v4l2_get_bytesperline(struct uvcg_format *uformat,
61 struct uvcg_frame *uframe)
62 {
63 struct uvcg_uncompressed *u;
64
65 if (uformat->type == UVCG_UNCOMPRESSED) {
66 u = to_uvcg_uncompressed(&uformat->group.cg_item);
67 if (!u)
68 return 0;
69
70 return u->desc.bBitsPerPixel * uframe->frame.w_width / 8;
71 }
72
73 return 0;
74 }
75
uvc_get_frame_size(struct uvcg_format * uformat,struct uvcg_frame * uframe)76 static int uvc_get_frame_size(struct uvcg_format *uformat,
77 struct uvcg_frame *uframe)
78 {
79 unsigned int bpl = uvc_v4l2_get_bytesperline(uformat, uframe);
80
81 return bpl ? bpl * uframe->frame.w_height :
82 uframe->frame.dw_max_video_frame_buffer_size;
83 }
84
find_format_by_index(struct uvc_device * uvc,int index)85 static struct uvcg_format *find_format_by_index(struct uvc_device *uvc, int index)
86 {
87 struct uvcg_format_ptr *format;
88 struct uvcg_format *uformat = NULL;
89 int i = 1;
90
91 list_for_each_entry(format, &uvc->header->formats, entry) {
92 if (index == i) {
93 uformat = format->fmt;
94 break;
95 }
96 i++;
97 }
98
99 return uformat;
100 }
101
find_frame_by_index(struct uvc_device * uvc,struct uvcg_format * uformat,int index)102 static struct uvcg_frame *find_frame_by_index(struct uvc_device *uvc,
103 struct uvcg_format *uformat,
104 int index)
105 {
106 struct uvcg_format_ptr *format;
107 struct uvcg_frame_ptr *frame;
108 struct uvcg_frame *uframe = NULL;
109
110 list_for_each_entry(format, &uvc->header->formats, entry) {
111 if (format->fmt->type != uformat->type)
112 continue;
113 list_for_each_entry(frame, &format->fmt->frames, entry) {
114 if (index == frame->frm->frame.b_frame_index) {
115 uframe = frame->frm;
116 break;
117 }
118 }
119 }
120
121 return uframe;
122 }
123
find_format_by_pix(struct uvc_device * uvc,u32 pixelformat)124 static struct uvcg_format *find_format_by_pix(struct uvc_device *uvc,
125 u32 pixelformat)
126 {
127 struct uvcg_format_ptr *format;
128 struct uvcg_format *uformat = NULL;
129
130 list_for_each_entry(format, &uvc->header->formats, entry) {
131 const struct uvc_format_desc *fmtdesc = to_uvc_format(format->fmt);
132
133 if (IS_ERR(fmtdesc))
134 continue;
135
136 if (fmtdesc->fcc == pixelformat) {
137 uformat = format->fmt;
138 break;
139 }
140 }
141
142 return uformat;
143 }
144
find_closest_frame_by_size(struct uvc_device * uvc,struct uvcg_format * uformat,u16 rw,u16 rh)145 static struct uvcg_frame *find_closest_frame_by_size(struct uvc_device *uvc,
146 struct uvcg_format *uformat,
147 u16 rw, u16 rh)
148 {
149 struct uvc_video *video = &uvc->video;
150 struct uvcg_format_ptr *format;
151 struct uvcg_frame_ptr *frame;
152 struct uvcg_frame *uframe = NULL;
153 unsigned int d, maxd;
154
155 /* Find the closest image size. The distance between image sizes is
156 * the size in pixels of the non-overlapping regions between the
157 * requested size and the frame-specified size.
158 */
159 maxd = (unsigned int)-1;
160
161 list_for_each_entry(format, &uvc->header->formats, entry) {
162 if (format->fmt->type != uformat->type)
163 continue;
164
165 list_for_each_entry(frame, &format->fmt->frames, entry) {
166 u16 w, h;
167
168 w = frame->frm->frame.w_width;
169 h = frame->frm->frame.w_height;
170
171 d = min(w, rw) * min(h, rh);
172 d = w*h + rw*rh - 2*d;
173 if (d < maxd) {
174 maxd = d;
175 uframe = frame->frm;
176 }
177
178 if (maxd == 0)
179 break;
180 }
181 }
182
183 if (!uframe)
184 uvcg_dbg(&video->uvc->func, "Unsupported size %ux%u\n", rw, rh);
185
186 return uframe;
187 }
188
189 /* --------------------------------------------------------------------------
190 * Requests handling
191 */
192
193 static int
uvc_send_response(struct uvc_device * uvc,struct uvc_request_data * data)194 uvc_send_response(struct uvc_device *uvc, struct uvc_request_data *data)
195 {
196 struct usb_composite_dev *cdev = uvc->func.config->cdev;
197 struct usb_request *req = uvc->control_req;
198
199 if (data->length < 0)
200 return usb_ep_set_halt(cdev->gadget->ep0);
201
202 req->length = min_t(unsigned int, uvc->event_length, data->length);
203 if (req->length > sizeof(data->data))
204 req->length = sizeof(data->data);
205 req->zero = data->length < uvc->event_length;
206
207 memcpy(req->buf, data->data, req->length);
208
209 return usb_ep_queue(cdev->gadget->ep0, req, GFP_KERNEL);
210 }
211
212 /* --------------------------------------------------------------------------
213 * V4L2 ioctls
214 */
215
216 static int
uvc_v4l2_querycap(struct file * file,void * fh,struct v4l2_capability * cap)217 uvc_v4l2_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
218 {
219 struct video_device *vdev = video_devdata(file);
220 struct uvc_device *uvc = video_get_drvdata(vdev);
221 struct usb_composite_dev *cdev = uvc->func.config->cdev;
222
223 strscpy(cap->driver, "g_uvc", sizeof(cap->driver));
224 strscpy(cap->card, cdev->gadget->name, sizeof(cap->card));
225 strscpy(cap->bus_info, dev_name(&cdev->gadget->dev),
226 sizeof(cap->bus_info));
227 return 0;
228 }
229
230 static int
uvc_v4l2_get_format(struct file * file,void * fh,struct v4l2_format * fmt)231 uvc_v4l2_get_format(struct file *file, void *fh, struct v4l2_format *fmt)
232 {
233 struct video_device *vdev = video_devdata(file);
234 struct uvc_device *uvc = video_get_drvdata(vdev);
235 struct uvc_video *video = &uvc->video;
236
237 fmt->fmt.pix.pixelformat = video->fcc;
238 fmt->fmt.pix.width = video->width;
239 fmt->fmt.pix.height = video->height;
240 fmt->fmt.pix.field = V4L2_FIELD_NONE;
241 fmt->fmt.pix.bytesperline = video->bpp * video->width / 8;
242 fmt->fmt.pix.sizeimage = video->imagesize;
243 fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB;
244 fmt->fmt.pix.priv = 0;
245
246 return 0;
247 }
248
249 static int
uvc_v4l2_try_format(struct file * file,void * fh,struct v4l2_format * fmt)250 uvc_v4l2_try_format(struct file *file, void *fh, struct v4l2_format *fmt)
251 {
252 struct video_device *vdev = video_devdata(file);
253 struct uvc_device *uvc = video_get_drvdata(vdev);
254 struct uvc_video *video = &uvc->video;
255 struct uvcg_format *uformat;
256 struct uvcg_frame *uframe;
257 const struct uvc_format_desc *fmtdesc;
258 u8 *fcc;
259
260 if (fmt->type != video->queue.queue.type)
261 return -EINVAL;
262
263 fcc = (u8 *)&fmt->fmt.pix.pixelformat;
264 uvcg_dbg(&uvc->func, "Trying format 0x%08x (%c%c%c%c): %ux%u\n",
265 fmt->fmt.pix.pixelformat,
266 fcc[0], fcc[1], fcc[2], fcc[3],
267 fmt->fmt.pix.width, fmt->fmt.pix.height);
268
269 uformat = find_format_by_pix(uvc, fmt->fmt.pix.pixelformat);
270 if (!uformat)
271 return -EINVAL;
272
273 uframe = find_closest_frame_by_size(uvc, uformat,
274 fmt->fmt.pix.width, fmt->fmt.pix.height);
275 if (!uframe)
276 return -EINVAL;
277
278 if (uformat->type == UVCG_UNCOMPRESSED) {
279 struct uvcg_uncompressed *u =
280 to_uvcg_uncompressed(&uformat->group.cg_item);
281 if (!u)
282 return 0;
283
284 v4l2_fill_pixfmt(&fmt->fmt.pix, fmt->fmt.pix.pixelformat,
285 uframe->frame.w_width, uframe->frame.w_height);
286
287 if (fmt->fmt.pix.sizeimage != (uvc_v4l2_get_bytesperline(uformat, uframe) *
288 uframe->frame.w_height))
289 return -EINVAL;
290 } else {
291 fmt->fmt.pix.width = uframe->frame.w_width;
292 fmt->fmt.pix.height = uframe->frame.w_height;
293 fmt->fmt.pix.bytesperline = uvc_v4l2_get_bytesperline(uformat, uframe);
294 fmt->fmt.pix.sizeimage = uvc_get_frame_size(uformat, uframe);
295 fmtdesc = to_uvc_format(uformat);
296 if (IS_ERR(fmtdesc))
297 return PTR_ERR(fmtdesc);
298 fmt->fmt.pix.pixelformat = fmtdesc->fcc;
299 }
300 fmt->fmt.pix.field = V4L2_FIELD_NONE;
301 fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB;
302 fmt->fmt.pix.priv = 0;
303
304 return 0;
305 }
306
307 static int
uvc_v4l2_set_format(struct file * file,void * fh,struct v4l2_format * fmt)308 uvc_v4l2_set_format(struct file *file, void *fh, struct v4l2_format *fmt)
309 {
310 struct video_device *vdev = video_devdata(file);
311 struct uvc_device *uvc = video_get_drvdata(vdev);
312 struct uvc_video *video = &uvc->video;
313 int ret;
314
315 ret = uvc_v4l2_try_format(file, fh, fmt);
316 if (ret)
317 return ret;
318
319 video->fcc = fmt->fmt.pix.pixelformat;
320 video->bpp = fmt->fmt.pix.bytesperline * 8 / video->width;
321 video->width = fmt->fmt.pix.width;
322 video->height = fmt->fmt.pix.height;
323 video->imagesize = fmt->fmt.pix.sizeimage;
324
325 return ret;
326 }
327
uvc_v4l2_g_parm(struct file * file,void * fh,struct v4l2_streamparm * parm)328 static int uvc_v4l2_g_parm(struct file *file, void *fh,
329 struct v4l2_streamparm *parm)
330 {
331 struct video_device *vdev = video_devdata(file);
332 struct uvc_device *uvc = video_get_drvdata(vdev);
333 struct uvc_video *video = &uvc->video;
334 struct v4l2_fract timeperframe;
335
336 if (!V4L2_TYPE_IS_OUTPUT(parm->type))
337 return -EINVAL;
338
339 /* Return the actual frame period. */
340 timeperframe.numerator = video->interval;
341 timeperframe.denominator = 10000000;
342 v4l2_simplify_fraction(&timeperframe.numerator,
343 &timeperframe.denominator, 8, 333);
344
345 uvcg_dbg(&uvc->func, "Getting frame interval of %u/%u (%u)\n",
346 timeperframe.numerator, timeperframe.denominator,
347 video->interval);
348
349 parm->parm.output.timeperframe = timeperframe;
350 parm->parm.output.capability = V4L2_CAP_TIMEPERFRAME;
351
352 return 0;
353 }
354
uvc_v4l2_s_parm(struct file * file,void * fh,struct v4l2_streamparm * parm)355 static int uvc_v4l2_s_parm(struct file *file, void *fh,
356 struct v4l2_streamparm *parm)
357 {
358 struct video_device *vdev = video_devdata(file);
359 struct uvc_device *uvc = video_get_drvdata(vdev);
360 struct uvc_video *video = &uvc->video;
361 struct v4l2_fract timeperframe;
362
363 if (!V4L2_TYPE_IS_OUTPUT(parm->type))
364 return -EINVAL;
365
366 timeperframe = parm->parm.output.timeperframe;
367
368 video->interval = v4l2_fraction_to_interval(timeperframe.numerator,
369 timeperframe.denominator);
370
371 uvcg_dbg(&uvc->func, "Setting frame interval to %u/%u (%u)\n",
372 timeperframe.numerator, timeperframe.denominator,
373 video->interval);
374
375 return 0;
376 }
377
378 static int
uvc_v4l2_enum_frameintervals(struct file * file,void * fh,struct v4l2_frmivalenum * fival)379 uvc_v4l2_enum_frameintervals(struct file *file, void *fh,
380 struct v4l2_frmivalenum *fival)
381 {
382 struct video_device *vdev = video_devdata(file);
383 struct uvc_device *uvc = video_get_drvdata(vdev);
384 struct uvcg_format *uformat = NULL;
385 struct uvcg_frame *uframe = NULL;
386 struct uvcg_frame_ptr *frame;
387
388 uformat = find_format_by_pix(uvc, fival->pixel_format);
389 if (!uformat)
390 return -EINVAL;
391
392 list_for_each_entry(frame, &uformat->frames, entry) {
393 if (frame->frm->frame.w_width == fival->width &&
394 frame->frm->frame.w_height == fival->height) {
395 uframe = frame->frm;
396 break;
397 }
398 }
399 if (!uframe)
400 return -EINVAL;
401
402 if (fival->index >= uframe->frame.b_frame_interval_type)
403 return -EINVAL;
404
405 fival->discrete.numerator =
406 uframe->dw_frame_interval[fival->index];
407
408 /* TODO: handle V4L2_FRMIVAL_TYPE_STEPWISE */
409 fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
410 fival->discrete.denominator = 10000000;
411 v4l2_simplify_fraction(&fival->discrete.numerator,
412 &fival->discrete.denominator, 8, 333);
413
414 return 0;
415 }
416
417 static int
uvc_v4l2_enum_framesizes(struct file * file,void * fh,struct v4l2_frmsizeenum * fsize)418 uvc_v4l2_enum_framesizes(struct file *file, void *fh,
419 struct v4l2_frmsizeenum *fsize)
420 {
421 struct video_device *vdev = video_devdata(file);
422 struct uvc_device *uvc = video_get_drvdata(vdev);
423 struct uvcg_format *uformat = NULL;
424 struct uvcg_frame *uframe = NULL;
425
426 uformat = find_format_by_pix(uvc, fsize->pixel_format);
427 if (!uformat)
428 return -EINVAL;
429
430 if (fsize->index >= uformat->num_frames)
431 return -EINVAL;
432
433 uframe = find_frame_by_index(uvc, uformat, fsize->index + 1);
434 if (!uframe)
435 return -EINVAL;
436
437 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
438 fsize->discrete.width = uframe->frame.w_width;
439 fsize->discrete.height = uframe->frame.w_height;
440
441 return 0;
442 }
443
444 static int
uvc_v4l2_enum_format(struct file * file,void * fh,struct v4l2_fmtdesc * f)445 uvc_v4l2_enum_format(struct file *file, void *fh, struct v4l2_fmtdesc *f)
446 {
447 struct video_device *vdev = video_devdata(file);
448 struct uvc_device *uvc = video_get_drvdata(vdev);
449 const struct uvc_format_desc *fmtdesc;
450 struct uvcg_format *uformat;
451
452 if (f->index >= uvc->header->num_fmt)
453 return -EINVAL;
454
455 uformat = find_format_by_index(uvc, f->index + 1);
456 if (!uformat)
457 return -EINVAL;
458
459 fmtdesc = to_uvc_format(uformat);
460 if (IS_ERR(fmtdesc))
461 return PTR_ERR(fmtdesc);
462
463 f->pixelformat = fmtdesc->fcc;
464
465 return 0;
466 }
467
468 static int
uvc_v4l2_reqbufs(struct file * file,void * fh,struct v4l2_requestbuffers * b)469 uvc_v4l2_reqbufs(struct file *file, void *fh, struct v4l2_requestbuffers *b)
470 {
471 struct video_device *vdev = video_devdata(file);
472 struct uvc_device *uvc = video_get_drvdata(vdev);
473 struct uvc_video *video = &uvc->video;
474
475 if (b->type != video->queue.queue.type)
476 return -EINVAL;
477
478 return uvcg_alloc_buffers(&video->queue, b);
479 }
480
481 static int
uvc_v4l2_querybuf(struct file * file,void * fh,struct v4l2_buffer * b)482 uvc_v4l2_querybuf(struct file *file, void *fh, struct v4l2_buffer *b)
483 {
484 struct video_device *vdev = video_devdata(file);
485 struct uvc_device *uvc = video_get_drvdata(vdev);
486 struct uvc_video *video = &uvc->video;
487
488 return uvcg_query_buffer(&video->queue, b);
489 }
490
491 static int
uvc_v4l2_qbuf(struct file * file,void * fh,struct v4l2_buffer * b)492 uvc_v4l2_qbuf(struct file *file, void *fh, struct v4l2_buffer *b)
493 {
494 struct video_device *vdev = video_devdata(file);
495 struct uvc_device *uvc = video_get_drvdata(vdev);
496 struct uvc_video *video = &uvc->video;
497 int ret;
498
499 ret = uvcg_queue_buffer(&video->queue, b);
500 if (ret < 0)
501 return ret;
502
503 if (uvc->state == UVC_STATE_STREAMING)
504 queue_work(video->async_wq, &video->pump);
505
506 return ret;
507 }
508
509 static int
uvc_v4l2_dqbuf(struct file * file,void * fh,struct v4l2_buffer * b)510 uvc_v4l2_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b)
511 {
512 struct video_device *vdev = video_devdata(file);
513 struct uvc_device *uvc = video_get_drvdata(vdev);
514 struct uvc_video *video = &uvc->video;
515
516 return uvcg_dequeue_buffer(&video->queue, b, file->f_flags & O_NONBLOCK);
517 }
518
519 static int
uvc_v4l2_streamon(struct file * file,void * fh,enum v4l2_buf_type type)520 uvc_v4l2_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
521 {
522 struct video_device *vdev = video_devdata(file);
523 struct uvc_device *uvc = video_get_drvdata(vdev);
524 struct uvc_video *video = &uvc->video;
525 int ret;
526
527 if (type != video->queue.queue.type)
528 return -EINVAL;
529
530 /* Enable UVC video. */
531 ret = uvcg_video_enable(video);
532 if (ret < 0)
533 return ret;
534
535 /*
536 * Complete the alternate setting selection setup phase now that
537 * userspace is ready to provide video frames.
538 */
539 uvc_function_setup_continue(uvc, 0);
540 uvc->state = UVC_STATE_STREAMING;
541
542 return 0;
543 }
544
545 static int
uvc_v4l2_streamoff(struct file * file,void * fh,enum v4l2_buf_type type)546 uvc_v4l2_streamoff(struct file *file, void *fh, enum v4l2_buf_type type)
547 {
548 struct video_device *vdev = video_devdata(file);
549 struct uvc_device *uvc = video_get_drvdata(vdev);
550 struct uvc_video *video = &uvc->video;
551 int ret = 0;
552
553 if (type != video->queue.queue.type)
554 return -EINVAL;
555
556 ret = uvcg_video_disable(video);
557 if (ret < 0)
558 return ret;
559
560 if (uvc->state != UVC_STATE_STREAMING)
561 return 0;
562
563 uvc->state = UVC_STATE_CONNECTED;
564 uvc_function_setup_continue(uvc, 1);
565 return 0;
566 }
567
568 static int
uvc_v4l2_subscribe_event(struct v4l2_fh * fh,const struct v4l2_event_subscription * sub)569 uvc_v4l2_subscribe_event(struct v4l2_fh *fh,
570 const struct v4l2_event_subscription *sub)
571 {
572 struct uvc_device *uvc = video_get_drvdata(fh->vdev);
573 struct uvc_file_handle *handle = to_uvc_file_handle(fh);
574 int ret;
575
576 if (sub->type < UVC_EVENT_FIRST || sub->type > UVC_EVENT_LAST)
577 return -EINVAL;
578
579 guard(mutex)(&uvc->lock);
580
581 if (sub->type == UVC_EVENT_SETUP && uvc->func_connected)
582 return -EBUSY;
583
584 ret = v4l2_event_subscribe(fh, sub, 2, NULL);
585 if (ret < 0)
586 return ret;
587
588 if (sub->type == UVC_EVENT_SETUP) {
589 uvc->func_connected = true;
590 handle->is_uvc_app_handle = true;
591 uvc_function_connect(uvc);
592 }
593
594 return 0;
595 }
596
uvc_v4l2_disable(struct uvc_device * uvc)597 static void uvc_v4l2_disable(struct uvc_device *uvc)
598 {
599 uvc_function_disconnect(uvc);
600 uvcg_video_disable(&uvc->video);
601 uvcg_free_buffers(&uvc->video.queue);
602 scoped_guard(mutex, &uvc->lock)
603 uvc->func_connected = false;
604 wake_up_interruptible(&uvc->func_connected_queue);
605 }
606
607 static int
uvc_v4l2_unsubscribe_event(struct v4l2_fh * fh,const struct v4l2_event_subscription * sub)608 uvc_v4l2_unsubscribe_event(struct v4l2_fh *fh,
609 const struct v4l2_event_subscription *sub)
610 {
611 struct uvc_device *uvc = video_get_drvdata(fh->vdev);
612 struct uvc_file_handle *handle = to_uvc_file_handle(fh);
613 int ret;
614
615 ret = v4l2_event_unsubscribe(fh, sub);
616 if (ret < 0)
617 return ret;
618
619 if (sub->type == UVC_EVENT_SETUP && handle->is_uvc_app_handle) {
620 uvc_v4l2_disable(uvc);
621 handle->is_uvc_app_handle = false;
622 }
623
624 return 0;
625 }
626
627 static long
uvc_v4l2_ioctl_default(struct file * file,void * fh,bool valid_prio,unsigned int cmd,void * arg)628 uvc_v4l2_ioctl_default(struct file *file, void *fh, bool valid_prio,
629 unsigned int cmd, void *arg)
630 {
631 struct video_device *vdev = video_devdata(file);
632 struct uvc_device *uvc = video_get_drvdata(vdev);
633
634 switch (cmd) {
635 case UVCIOC_SEND_RESPONSE:
636 return uvc_send_response(uvc, arg);
637
638 default:
639 return -ENOIOCTLCMD;
640 }
641 }
642
643 const struct v4l2_ioctl_ops uvc_v4l2_ioctl_ops = {
644 .vidioc_querycap = uvc_v4l2_querycap,
645 .vidioc_try_fmt_vid_out = uvc_v4l2_try_format,
646 .vidioc_g_fmt_vid_out = uvc_v4l2_get_format,
647 .vidioc_s_fmt_vid_out = uvc_v4l2_set_format,
648 .vidioc_enum_frameintervals = uvc_v4l2_enum_frameintervals,
649 .vidioc_enum_framesizes = uvc_v4l2_enum_framesizes,
650 .vidioc_enum_fmt_vid_out = uvc_v4l2_enum_format,
651 .vidioc_reqbufs = uvc_v4l2_reqbufs,
652 .vidioc_querybuf = uvc_v4l2_querybuf,
653 .vidioc_qbuf = uvc_v4l2_qbuf,
654 .vidioc_dqbuf = uvc_v4l2_dqbuf,
655 .vidioc_streamon = uvc_v4l2_streamon,
656 .vidioc_streamoff = uvc_v4l2_streamoff,
657 .vidioc_s_parm = uvc_v4l2_s_parm,
658 .vidioc_g_parm = uvc_v4l2_g_parm,
659 .vidioc_subscribe_event = uvc_v4l2_subscribe_event,
660 .vidioc_unsubscribe_event = uvc_v4l2_unsubscribe_event,
661 .vidioc_default = uvc_v4l2_ioctl_default,
662 };
663
664 /* --------------------------------------------------------------------------
665 * V4L2
666 */
667
668 static int
uvc_v4l2_open(struct file * file)669 uvc_v4l2_open(struct file *file)
670 {
671 struct video_device *vdev = video_devdata(file);
672 struct uvc_device *uvc = video_get_drvdata(vdev);
673 struct uvc_file_handle *handle;
674
675 handle = kzalloc_obj(*handle);
676 if (handle == NULL)
677 return -ENOMEM;
678
679 v4l2_fh_init(&handle->vfh, vdev);
680 v4l2_fh_add(&handle->vfh, file);
681
682 handle->device = &uvc->video;
683
684 return 0;
685 }
686
687 static int
uvc_v4l2_release(struct file * file)688 uvc_v4l2_release(struct file *file)
689 {
690 struct video_device *vdev = video_devdata(file);
691 struct uvc_device *uvc = video_get_drvdata(vdev);
692 struct uvc_file_handle *handle = file_to_uvc_file_handle(file);
693 struct uvc_video *video = handle->device;
694
695 mutex_lock(&video->mutex);
696 if (handle->is_uvc_app_handle)
697 uvc_v4l2_disable(uvc);
698 mutex_unlock(&video->mutex);
699
700 v4l2_fh_del(&handle->vfh, file);
701 v4l2_fh_exit(&handle->vfh);
702 kfree(handle);
703
704 return 0;
705 }
706
707 static int
uvc_v4l2_mmap(struct file * file,struct vm_area_struct * vma)708 uvc_v4l2_mmap(struct file *file, struct vm_area_struct *vma)
709 {
710 struct video_device *vdev = video_devdata(file);
711 struct uvc_device *uvc = video_get_drvdata(vdev);
712
713 return uvcg_queue_mmap(&uvc->video.queue, vma);
714 }
715
716 static __poll_t
uvc_v4l2_poll(struct file * file,poll_table * wait)717 uvc_v4l2_poll(struct file *file, poll_table *wait)
718 {
719 struct video_device *vdev = video_devdata(file);
720 struct uvc_device *uvc = video_get_drvdata(vdev);
721
722 return uvcg_queue_poll(&uvc->video.queue, file, wait);
723 }
724
725 #ifndef CONFIG_MMU
uvcg_v4l2_get_unmapped_area(struct file * file,unsigned long addr,unsigned long len,unsigned long pgoff,unsigned long flags)726 static unsigned long uvcg_v4l2_get_unmapped_area(struct file *file,
727 unsigned long addr, unsigned long len, unsigned long pgoff,
728 unsigned long flags)
729 {
730 struct video_device *vdev = video_devdata(file);
731 struct uvc_device *uvc = video_get_drvdata(vdev);
732
733 return uvcg_queue_get_unmapped_area(&uvc->video.queue, pgoff);
734 }
735 #endif
736
737 const struct v4l2_file_operations uvc_v4l2_fops = {
738 .owner = THIS_MODULE,
739 .open = uvc_v4l2_open,
740 .release = uvc_v4l2_release,
741 .unlocked_ioctl = video_ioctl2,
742 .mmap = uvc_v4l2_mmap,
743 .poll = uvc_v4l2_poll,
744 #ifndef CONFIG_MMU
745 .get_unmapped_area = uvcg_v4l2_get_unmapped_area,
746 #endif
747 };
748