2 * uvc_v4l2.c -- USB Video Class Gadget driver
4 * Copyright (C) 2009-2010
5 * Laurent Pinchart (laurent.pinchart@ideasonboard.com)
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.
14 #include <linux/kernel.h>
15 #include <linux/device.h>
16 #include <linux/errno.h>
17 #include <linux/list.h>
18 #include <linux/mutex.h>
19 #include <linux/version.h>
20 #include <linux/videodev2.h>
21 #include <linux/vmalloc.h>
22 #include <linux/wait.h>
24 #include <media/v4l2-dev.h>
25 #include <media/v4l2-event.h>
26 #include <media/v4l2-ioctl.h>
29 #include "uvc_queue.h"
31 /* --------------------------------------------------------------------------
36 uvc_send_response(struct uvc_device
*uvc
, struct uvc_request_data
*data
)
38 struct usb_composite_dev
*cdev
= uvc
->func
.config
->cdev
;
39 struct usb_request
*req
= uvc
->control_req
;
42 return usb_ep_set_halt(cdev
->gadget
->ep0
);
44 req
->length
= min(uvc
->event_length
, data
->length
);
45 req
->zero
= data
->length
< uvc
->event_length
;
46 req
->dma
= DMA_ADDR_INVALID
;
48 memcpy(req
->buf
, data
->data
, data
->length
);
50 return usb_ep_queue(cdev
->gadget
->ep0
, req
, GFP_KERNEL
);
53 /* --------------------------------------------------------------------------
63 static struct uvc_format uvc_formats
[] = {
64 { 16, V4L2_PIX_FMT_YUYV
},
65 { 0, V4L2_PIX_FMT_MJPEG
},
69 uvc_v4l2_get_format(struct uvc_video
*video
, struct v4l2_format
*fmt
)
71 fmt
->fmt
.pix
.pixelformat
= video
->fcc
;
72 fmt
->fmt
.pix
.width
= video
->width
;
73 fmt
->fmt
.pix
.height
= video
->height
;
74 fmt
->fmt
.pix
.field
= V4L2_FIELD_NONE
;
75 fmt
->fmt
.pix
.bytesperline
= video
->bpp
* video
->width
/ 8;
76 fmt
->fmt
.pix
.sizeimage
= video
->imagesize
;
77 fmt
->fmt
.pix
.colorspace
= V4L2_COLORSPACE_SRGB
;
78 fmt
->fmt
.pix
.priv
= 0;
84 uvc_v4l2_set_format(struct uvc_video
*video
, struct v4l2_format
*fmt
)
86 struct uvc_format
*format
;
87 unsigned int imagesize
;
91 for (i
= 0; i
< ARRAY_SIZE(uvc_formats
); ++i
) {
92 format
= &uvc_formats
[i
];
93 if (format
->fcc
== fmt
->fmt
.pix
.pixelformat
)
97 if (i
== ARRAY_SIZE(uvc_formats
)) {
98 printk(KERN_INFO
"Unsupported format 0x%08x.\n",
99 fmt
->fmt
.pix
.pixelformat
);
103 bpl
= format
->bpp
* fmt
->fmt
.pix
.width
/ 8;
104 imagesize
= bpl
? bpl
* fmt
->fmt
.pix
.height
: fmt
->fmt
.pix
.sizeimage
;
106 video
->fcc
= format
->fcc
;
107 video
->bpp
= format
->bpp
;
108 video
->width
= fmt
->fmt
.pix
.width
;
109 video
->height
= fmt
->fmt
.pix
.height
;
110 video
->imagesize
= imagesize
;
112 fmt
->fmt
.pix
.field
= V4L2_FIELD_NONE
;
113 fmt
->fmt
.pix
.bytesperline
= bpl
;
114 fmt
->fmt
.pix
.sizeimage
= imagesize
;
115 fmt
->fmt
.pix
.colorspace
= V4L2_COLORSPACE_SRGB
;
116 fmt
->fmt
.pix
.priv
= 0;
122 uvc_v4l2_open(struct file
*file
)
124 struct video_device
*vdev
= video_devdata(file
);
125 struct uvc_device
*uvc
= video_get_drvdata(vdev
);
126 struct uvc_file_handle
*handle
;
129 handle
= kzalloc(sizeof(*handle
), GFP_KERNEL
);
133 ret
= v4l2_fh_init(&handle
->vfh
, vdev
);
137 ret
= v4l2_event_init(&handle
->vfh
);
141 ret
= v4l2_event_alloc(&handle
->vfh
, 8);
145 v4l2_fh_add(&handle
->vfh
);
147 handle
->device
= &uvc
->video
;
148 file
->private_data
= &handle
->vfh
;
150 uvc_function_connect(uvc
);
154 v4l2_fh_exit(&handle
->vfh
);
159 uvc_v4l2_release(struct file
*file
)
161 struct video_device
*vdev
= video_devdata(file
);
162 struct uvc_device
*uvc
= video_get_drvdata(vdev
);
163 struct uvc_file_handle
*handle
= to_uvc_file_handle(file
->private_data
);
164 struct uvc_video
*video
= handle
->device
;
166 uvc_function_disconnect(uvc
);
168 uvc_video_enable(video
, 0);
169 mutex_lock(&video
->queue
.mutex
);
170 if (uvc_free_buffers(&video
->queue
) < 0)
171 printk(KERN_ERR
"uvc_v4l2_release: Unable to free "
173 mutex_unlock(&video
->queue
.mutex
);
175 file
->private_data
= NULL
;
176 v4l2_fh_del(&handle
->vfh
);
177 v4l2_fh_exit(&handle
->vfh
);
183 uvc_v4l2_do_ioctl(struct file
*file
, unsigned int cmd
, void *arg
)
185 struct video_device
*vdev
= video_devdata(file
);
186 struct uvc_device
*uvc
= video_get_drvdata(vdev
);
187 struct uvc_file_handle
*handle
= to_uvc_file_handle(file
->private_data
);
188 struct usb_composite_dev
*cdev
= uvc
->func
.config
->cdev
;
189 struct uvc_video
*video
= &uvc
->video
;
193 /* Query capabilities */
194 case VIDIOC_QUERYCAP
:
196 struct v4l2_capability
*cap
= arg
;
198 memset(cap
, 0, sizeof *cap
);
199 strncpy(cap
->driver
, "g_uvc", sizeof(cap
->driver
));
200 strncpy(cap
->card
, cdev
->gadget
->name
, sizeof(cap
->card
));
201 strncpy(cap
->bus_info
, dev_name(&cdev
->gadget
->dev
),
202 sizeof cap
->bus_info
);
203 cap
->version
= DRIVER_VERSION_NUMBER
;
204 cap
->capabilities
= V4L2_CAP_VIDEO_OUTPUT
| V4L2_CAP_STREAMING
;
208 /* Get & Set format */
211 struct v4l2_format
*fmt
= arg
;
213 if (fmt
->type
!= video
->queue
.type
)
216 return uvc_v4l2_get_format(video
, fmt
);
221 struct v4l2_format
*fmt
= arg
;
223 if (fmt
->type
!= video
->queue
.type
)
226 return uvc_v4l2_set_format(video
, fmt
);
229 /* Buffers & streaming */
232 struct v4l2_requestbuffers
*rb
= arg
;
234 if (rb
->type
!= video
->queue
.type
||
235 rb
->memory
!= V4L2_MEMORY_MMAP
)
238 ret
= uvc_alloc_buffers(&video
->queue
, rb
->count
,
248 case VIDIOC_QUERYBUF
:
250 struct v4l2_buffer
*buf
= arg
;
252 if (buf
->type
!= video
->queue
.type
)
255 return uvc_query_buffer(&video
->queue
, buf
);
259 if ((ret
= uvc_queue_buffer(&video
->queue
, arg
)) < 0)
262 return uvc_video_pump(video
);
265 return uvc_dequeue_buffer(&video
->queue
, arg
,
266 file
->f_flags
& O_NONBLOCK
);
268 case VIDIOC_STREAMON
:
272 if (*type
!= video
->queue
.type
)
275 return uvc_video_enable(video
, 1);
278 case VIDIOC_STREAMOFF
:
282 if (*type
!= video
->queue
.type
)
285 return uvc_video_enable(video
, 0);
291 struct v4l2_event
*event
= arg
;
293 ret
= v4l2_event_dequeue(&handle
->vfh
, event
,
294 file
->f_flags
& O_NONBLOCK
);
295 if (ret
== 0 && event
->type
== UVC_EVENT_SETUP
) {
296 struct uvc_event
*uvc_event
= (void *)&event
->u
.data
;
298 /* Tell the complete callback to generate an event for
299 * the next request that will be enqueued by
302 uvc
->event_setup_out
=
303 !(uvc_event
->req
.bRequestType
& USB_DIR_IN
);
304 uvc
->event_length
= uvc_event
->req
.wLength
;
310 case VIDIOC_SUBSCRIBE_EVENT
:
312 struct v4l2_event_subscription
*sub
= arg
;
314 if (sub
->type
< UVC_EVENT_FIRST
|| sub
->type
> UVC_EVENT_LAST
)
317 return v4l2_event_subscribe(&handle
->vfh
, arg
);
320 case VIDIOC_UNSUBSCRIBE_EVENT
:
321 return v4l2_event_unsubscribe(&handle
->vfh
, arg
);
323 case UVCIOC_SEND_RESPONSE
:
324 ret
= uvc_send_response(uvc
, arg
);
335 uvc_v4l2_ioctl(struct file
*file
, unsigned int cmd
, unsigned long arg
)
337 return video_usercopy(file
, cmd
, arg
, uvc_v4l2_do_ioctl
);
341 uvc_v4l2_mmap(struct file
*file
, struct vm_area_struct
*vma
)
343 struct video_device
*vdev
= video_devdata(file
);
344 struct uvc_device
*uvc
= video_get_drvdata(vdev
);
346 return uvc_queue_mmap(&uvc
->video
.queue
, vma
);
350 uvc_v4l2_poll(struct file
*file
, poll_table
*wait
)
352 struct video_device
*vdev
= video_devdata(file
);
353 struct uvc_device
*uvc
= video_get_drvdata(vdev
);
354 struct uvc_file_handle
*handle
= to_uvc_file_handle(file
->private_data
);
355 unsigned int mask
= 0;
357 poll_wait(file
, &handle
->vfh
.events
->wait
, wait
);
358 if (v4l2_event_pending(&handle
->vfh
))
361 mask
|= uvc_queue_poll(&uvc
->video
.queue
, file
, wait
);
366 static struct v4l2_file_operations uvc_v4l2_fops
= {
367 .owner
= THIS_MODULE
,
368 .open
= uvc_v4l2_open
,
369 .release
= uvc_v4l2_release
,
370 .ioctl
= uvc_v4l2_ioctl
,
371 .mmap
= uvc_v4l2_mmap
,
372 .poll
= uvc_v4l2_poll
,