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/kernel.h> 10 #include <linux/device.h> 11 #include <linux/errno.h> 12 #include <linux/list.h> 13 #include <linux/videodev2.h> 14 #include <linux/vmalloc.h> 15 #include <linux/wait.h> 16 17 #include <media/v4l2-dev.h> 18 #include <media/v4l2-event.h> 19 #include <media/v4l2-ioctl.h> 20 21 #include "f_uvc.h" 22 #include "uvc.h" 23 #include "uvc_queue.h" 24 #include "uvc_video.h" 25 #include "uvc_v4l2.h" 26 27 /* -------------------------------------------------------------------------- 28 * Requests handling 29 */ 30 31 static int 32 uvc_send_response(struct uvc_device *uvc, struct uvc_request_data *data) 33 { 34 struct usb_composite_dev *cdev = uvc->func.config->cdev; 35 struct usb_request *req = uvc->control_req; 36 37 if (data->length < 0) 38 return usb_ep_set_halt(cdev->gadget->ep0); 39 40 req->length = min_t(unsigned int, uvc->event_length, data->length); 41 req->zero = data->length < uvc->event_length; 42 43 memcpy(req->buf, data->data, req->length); 44 45 return usb_ep_queue(cdev->gadget->ep0, req, GFP_KERNEL); 46 } 47 48 /* -------------------------------------------------------------------------- 49 * V4L2 ioctls 50 */ 51 52 struct uvc_format { 53 u8 bpp; 54 u32 fcc; 55 }; 56 57 static struct uvc_format uvc_formats[] = { 58 { 16, V4L2_PIX_FMT_YUYV }, 59 { 0, V4L2_PIX_FMT_MJPEG }, 60 }; 61 62 static int 63 uvc_v4l2_querycap(struct file *file, void *fh, struct v4l2_capability *cap) 64 { 65 struct video_device *vdev = video_devdata(file); 66 struct uvc_device *uvc = video_get_drvdata(vdev); 67 struct usb_composite_dev *cdev = uvc->func.config->cdev; 68 69 strlcpy(cap->driver, "g_uvc", sizeof(cap->driver)); 70 strlcpy(cap->card, cdev->gadget->name, sizeof(cap->card)); 71 strlcpy(cap->bus_info, dev_name(&cdev->gadget->dev), 72 sizeof(cap->bus_info)); 73 74 cap->device_caps = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING; 75 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; 76 77 return 0; 78 } 79 80 static int 81 uvc_v4l2_get_format(struct file *file, void *fh, struct v4l2_format *fmt) 82 { 83 struct video_device *vdev = video_devdata(file); 84 struct uvc_device *uvc = video_get_drvdata(vdev); 85 struct uvc_video *video = &uvc->video; 86 87 fmt->fmt.pix.pixelformat = video->fcc; 88 fmt->fmt.pix.width = video->width; 89 fmt->fmt.pix.height = video->height; 90 fmt->fmt.pix.field = V4L2_FIELD_NONE; 91 fmt->fmt.pix.bytesperline = video->bpp * video->width / 8; 92 fmt->fmt.pix.sizeimage = video->imagesize; 93 fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB; 94 fmt->fmt.pix.priv = 0; 95 96 return 0; 97 } 98 99 static int 100 uvc_v4l2_set_format(struct file *file, void *fh, struct v4l2_format *fmt) 101 { 102 struct video_device *vdev = video_devdata(file); 103 struct uvc_device *uvc = video_get_drvdata(vdev); 104 struct uvc_video *video = &uvc->video; 105 struct uvc_format *format; 106 unsigned int imagesize; 107 unsigned int bpl; 108 unsigned int i; 109 110 for (i = 0; i < ARRAY_SIZE(uvc_formats); ++i) { 111 format = &uvc_formats[i]; 112 if (format->fcc == fmt->fmt.pix.pixelformat) 113 break; 114 } 115 116 if (i == ARRAY_SIZE(uvc_formats)) { 117 printk(KERN_INFO "Unsupported format 0x%08x.\n", 118 fmt->fmt.pix.pixelformat); 119 return -EINVAL; 120 } 121 122 bpl = format->bpp * fmt->fmt.pix.width / 8; 123 imagesize = bpl ? bpl * fmt->fmt.pix.height : fmt->fmt.pix.sizeimage; 124 125 video->fcc = format->fcc; 126 video->bpp = format->bpp; 127 video->width = fmt->fmt.pix.width; 128 video->height = fmt->fmt.pix.height; 129 video->imagesize = imagesize; 130 131 fmt->fmt.pix.field = V4L2_FIELD_NONE; 132 fmt->fmt.pix.bytesperline = bpl; 133 fmt->fmt.pix.sizeimage = imagesize; 134 fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SRGB; 135 fmt->fmt.pix.priv = 0; 136 137 return 0; 138 } 139 140 static int 141 uvc_v4l2_reqbufs(struct file *file, void *fh, struct v4l2_requestbuffers *b) 142 { 143 struct video_device *vdev = video_devdata(file); 144 struct uvc_device *uvc = video_get_drvdata(vdev); 145 struct uvc_video *video = &uvc->video; 146 147 if (b->type != video->queue.queue.type) 148 return -EINVAL; 149 150 return uvcg_alloc_buffers(&video->queue, b); 151 } 152 153 static int 154 uvc_v4l2_querybuf(struct file *file, void *fh, struct v4l2_buffer *b) 155 { 156 struct video_device *vdev = video_devdata(file); 157 struct uvc_device *uvc = video_get_drvdata(vdev); 158 struct uvc_video *video = &uvc->video; 159 160 return uvcg_query_buffer(&video->queue, b); 161 } 162 163 static int 164 uvc_v4l2_qbuf(struct file *file, void *fh, struct v4l2_buffer *b) 165 { 166 struct video_device *vdev = video_devdata(file); 167 struct uvc_device *uvc = video_get_drvdata(vdev); 168 struct uvc_video *video = &uvc->video; 169 int ret; 170 171 ret = uvcg_queue_buffer(&video->queue, b); 172 if (ret < 0) 173 return ret; 174 175 return uvcg_video_pump(video); 176 } 177 178 static int 179 uvc_v4l2_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b) 180 { 181 struct video_device *vdev = video_devdata(file); 182 struct uvc_device *uvc = video_get_drvdata(vdev); 183 struct uvc_video *video = &uvc->video; 184 185 return uvcg_dequeue_buffer(&video->queue, b, file->f_flags & O_NONBLOCK); 186 } 187 188 static int 189 uvc_v4l2_streamon(struct file *file, void *fh, enum v4l2_buf_type type) 190 { 191 struct video_device *vdev = video_devdata(file); 192 struct uvc_device *uvc = video_get_drvdata(vdev); 193 struct uvc_video *video = &uvc->video; 194 int ret; 195 196 if (type != video->queue.queue.type) 197 return -EINVAL; 198 199 /* Enable UVC video. */ 200 ret = uvcg_video_enable(video, 1); 201 if (ret < 0) 202 return ret; 203 204 /* 205 * Complete the alternate setting selection setup phase now that 206 * userspace is ready to provide video frames. 207 */ 208 uvc_function_setup_continue(uvc); 209 uvc->state = UVC_STATE_STREAMING; 210 211 return 0; 212 } 213 214 static int 215 uvc_v4l2_streamoff(struct file *file, void *fh, enum v4l2_buf_type type) 216 { 217 struct video_device *vdev = video_devdata(file); 218 struct uvc_device *uvc = video_get_drvdata(vdev); 219 struct uvc_video *video = &uvc->video; 220 221 if (type != video->queue.queue.type) 222 return -EINVAL; 223 224 return uvcg_video_enable(video, 0); 225 } 226 227 static int 228 uvc_v4l2_subscribe_event(struct v4l2_fh *fh, 229 const struct v4l2_event_subscription *sub) 230 { 231 if (sub->type < UVC_EVENT_FIRST || sub->type > UVC_EVENT_LAST) 232 return -EINVAL; 233 234 return v4l2_event_subscribe(fh, sub, 2, NULL); 235 } 236 237 static int 238 uvc_v4l2_unsubscribe_event(struct v4l2_fh *fh, 239 const struct v4l2_event_subscription *sub) 240 { 241 return v4l2_event_unsubscribe(fh, sub); 242 } 243 244 static long 245 uvc_v4l2_ioctl_default(struct file *file, void *fh, bool valid_prio, 246 unsigned int cmd, void *arg) 247 { 248 struct video_device *vdev = video_devdata(file); 249 struct uvc_device *uvc = video_get_drvdata(vdev); 250 251 switch (cmd) { 252 case UVCIOC_SEND_RESPONSE: 253 return uvc_send_response(uvc, arg); 254 255 default: 256 return -ENOIOCTLCMD; 257 } 258 } 259 260 const struct v4l2_ioctl_ops uvc_v4l2_ioctl_ops = { 261 .vidioc_querycap = uvc_v4l2_querycap, 262 .vidioc_g_fmt_vid_out = uvc_v4l2_get_format, 263 .vidioc_s_fmt_vid_out = uvc_v4l2_set_format, 264 .vidioc_reqbufs = uvc_v4l2_reqbufs, 265 .vidioc_querybuf = uvc_v4l2_querybuf, 266 .vidioc_qbuf = uvc_v4l2_qbuf, 267 .vidioc_dqbuf = uvc_v4l2_dqbuf, 268 .vidioc_streamon = uvc_v4l2_streamon, 269 .vidioc_streamoff = uvc_v4l2_streamoff, 270 .vidioc_subscribe_event = uvc_v4l2_subscribe_event, 271 .vidioc_unsubscribe_event = uvc_v4l2_unsubscribe_event, 272 .vidioc_default = uvc_v4l2_ioctl_default, 273 }; 274 275 /* -------------------------------------------------------------------------- 276 * V4L2 277 */ 278 279 static int 280 uvc_v4l2_open(struct file *file) 281 { 282 struct video_device *vdev = video_devdata(file); 283 struct uvc_device *uvc = video_get_drvdata(vdev); 284 struct uvc_file_handle *handle; 285 286 handle = kzalloc(sizeof(*handle), GFP_KERNEL); 287 if (handle == NULL) 288 return -ENOMEM; 289 290 v4l2_fh_init(&handle->vfh, vdev); 291 v4l2_fh_add(&handle->vfh); 292 293 handle->device = &uvc->video; 294 file->private_data = &handle->vfh; 295 296 uvc_function_connect(uvc); 297 return 0; 298 } 299 300 static int 301 uvc_v4l2_release(struct file *file) 302 { 303 struct video_device *vdev = video_devdata(file); 304 struct uvc_device *uvc = video_get_drvdata(vdev); 305 struct uvc_file_handle *handle = to_uvc_file_handle(file->private_data); 306 struct uvc_video *video = handle->device; 307 308 uvc_function_disconnect(uvc); 309 310 mutex_lock(&video->mutex); 311 uvcg_video_enable(video, 0); 312 uvcg_free_buffers(&video->queue); 313 mutex_unlock(&video->mutex); 314 315 file->private_data = NULL; 316 v4l2_fh_del(&handle->vfh); 317 v4l2_fh_exit(&handle->vfh); 318 kfree(handle); 319 320 return 0; 321 } 322 323 static int 324 uvc_v4l2_mmap(struct file *file, struct vm_area_struct *vma) 325 { 326 struct video_device *vdev = video_devdata(file); 327 struct uvc_device *uvc = video_get_drvdata(vdev); 328 329 return uvcg_queue_mmap(&uvc->video.queue, vma); 330 } 331 332 static __poll_t 333 uvc_v4l2_poll(struct file *file, poll_table *wait) 334 { 335 struct video_device *vdev = video_devdata(file); 336 struct uvc_device *uvc = video_get_drvdata(vdev); 337 338 return uvcg_queue_poll(&uvc->video.queue, file, wait); 339 } 340 341 #ifndef CONFIG_MMU 342 static unsigned long uvcg_v4l2_get_unmapped_area(struct file *file, 343 unsigned long addr, unsigned long len, unsigned long pgoff, 344 unsigned long flags) 345 { 346 struct video_device *vdev = video_devdata(file); 347 struct uvc_device *uvc = video_get_drvdata(vdev); 348 349 return uvcg_queue_get_unmapped_area(&uvc->video.queue, pgoff); 350 } 351 #endif 352 353 const struct v4l2_file_operations uvc_v4l2_fops = { 354 .owner = THIS_MODULE, 355 .open = uvc_v4l2_open, 356 .release = uvc_v4l2_release, 357 .unlocked_ioctl = video_ioctl2, 358 .mmap = uvc_v4l2_mmap, 359 .poll = uvc_v4l2_poll, 360 #ifndef CONFIG_MMU 361 .get_unmapped_area = uvcg_v4l2_get_unmapped_area, 362 #endif 363 }; 364 365