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