linux/drivers/usb/gadget/function/uvc_video.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 *      uvc_video.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/usb/ch9.h>
  13#include <linux/usb/gadget.h>
  14#include <linux/usb/video.h>
  15
  16#include <media/v4l2-dev.h>
  17
  18#include "uvc.h"
  19#include "uvc_queue.h"
  20#include "uvc_video.h"
  21
  22/* --------------------------------------------------------------------------
  23 * Video codecs
  24 */
  25
  26static int
  27uvc_video_encode_header(struct uvc_video *video, struct uvc_buffer *buf,
  28                u8 *data, int len)
  29{
  30        data[0] = 2;
  31        data[1] = UVC_STREAM_EOH | video->fid;
  32
  33        if (buf->bytesused - video->queue.buf_used <= len - 2)
  34                data[1] |= UVC_STREAM_EOF;
  35
  36        return 2;
  37}
  38
  39static int
  40uvc_video_encode_data(struct uvc_video *video, struct uvc_buffer *buf,
  41                u8 *data, int len)
  42{
  43        struct uvc_video_queue *queue = &video->queue;
  44        unsigned int nbytes;
  45        void *mem;
  46
  47        /* Copy video data to the USB buffer. */
  48        mem = buf->mem + queue->buf_used;
  49        nbytes = min((unsigned int)len, buf->bytesused - queue->buf_used);
  50
  51        memcpy(data, mem, nbytes);
  52        queue->buf_used += nbytes;
  53
  54        return nbytes;
  55}
  56
  57static void
  58uvc_video_encode_bulk(struct usb_request *req, struct uvc_video *video,
  59                struct uvc_buffer *buf)
  60{
  61        void *mem = req->buf;
  62        int len = video->req_size;
  63        int ret;
  64
  65        /* Add a header at the beginning of the payload. */
  66        if (video->payload_size == 0) {
  67                ret = uvc_video_encode_header(video, buf, mem, len);
  68                video->payload_size += ret;
  69                mem += ret;
  70                len -= ret;
  71        }
  72
  73        /* Process video data. */
  74        len = min((int)(video->max_payload_size - video->payload_size), len);
  75        ret = uvc_video_encode_data(video, buf, mem, len);
  76
  77        video->payload_size += ret;
  78        len -= ret;
  79
  80        req->length = video->req_size - len;
  81        req->zero = video->payload_size == video->max_payload_size;
  82
  83        if (buf->bytesused == video->queue.buf_used) {
  84                video->queue.buf_used = 0;
  85                buf->state = UVC_BUF_STATE_DONE;
  86                uvcg_queue_next_buffer(&video->queue, buf);
  87                video->fid ^= UVC_STREAM_FID;
  88
  89                video->payload_size = 0;
  90        }
  91
  92        if (video->payload_size == video->max_payload_size ||
  93            buf->bytesused == video->queue.buf_used)
  94                video->payload_size = 0;
  95}
  96
  97static void
  98uvc_video_encode_isoc(struct usb_request *req, struct uvc_video *video,
  99                struct uvc_buffer *buf)
 100{
 101        void *mem = req->buf;
 102        int len = video->req_size;
 103        int ret;
 104
 105        /* Add the header. */
 106        ret = uvc_video_encode_header(video, buf, mem, len);
 107        mem += ret;
 108        len -= ret;
 109
 110        /* Process video data. */
 111        ret = uvc_video_encode_data(video, buf, mem, len);
 112        len -= ret;
 113
 114        req->length = video->req_size - len;
 115
 116        if (buf->bytesused == video->queue.buf_used) {
 117                video->queue.buf_used = 0;
 118                buf->state = UVC_BUF_STATE_DONE;
 119                uvcg_queue_next_buffer(&video->queue, buf);
 120                video->fid ^= UVC_STREAM_FID;
 121        }
 122}
 123
 124/* --------------------------------------------------------------------------
 125 * Request handling
 126 */
 127
 128static int uvcg_video_ep_queue(struct uvc_video *video, struct usb_request *req)
 129{
 130        int ret;
 131
 132        ret = usb_ep_queue(video->ep, req, GFP_ATOMIC);
 133        if (ret < 0) {
 134                uvcg_err(&video->uvc->func, "Failed to queue request (%d).\n",
 135                         ret);
 136
 137                /* Isochronous endpoints can't be halted. */
 138                if (usb_endpoint_xfer_bulk(video->ep->desc))
 139                        usb_ep_set_halt(video->ep);
 140        }
 141
 142        return ret;
 143}
 144
 145static void
 146uvc_video_complete(struct usb_ep *ep, struct usb_request *req)
 147{
 148        struct uvc_video *video = req->context;
 149        struct uvc_video_queue *queue = &video->queue;
 150        unsigned long flags;
 151
 152        switch (req->status) {
 153        case 0:
 154                break;
 155
 156        case -ESHUTDOWN:        /* disconnect from host. */
 157                uvcg_dbg(&video->uvc->func, "VS request cancelled.\n");
 158                uvcg_queue_cancel(queue, 1);
 159                break;
 160
 161        default:
 162                uvcg_info(&video->uvc->func,
 163                          "VS request completed with status %d.\n",
 164                          req->status);
 165                uvcg_queue_cancel(queue, 0);
 166        }
 167
 168        spin_lock_irqsave(&video->req_lock, flags);
 169        list_add_tail(&req->list, &video->req_free);
 170        spin_unlock_irqrestore(&video->req_lock, flags);
 171
 172        schedule_work(&video->pump);
 173}
 174
 175static int
 176uvc_video_free_requests(struct uvc_video *video)
 177{
 178        unsigned int i;
 179
 180        for (i = 0; i < UVC_NUM_REQUESTS; ++i) {
 181                if (video->req[i]) {
 182                        usb_ep_free_request(video->ep, video->req[i]);
 183                        video->req[i] = NULL;
 184                }
 185
 186                if (video->req_buffer[i]) {
 187                        kfree(video->req_buffer[i]);
 188                        video->req_buffer[i] = NULL;
 189                }
 190        }
 191
 192        INIT_LIST_HEAD(&video->req_free);
 193        video->req_size = 0;
 194        return 0;
 195}
 196
 197static int
 198uvc_video_alloc_requests(struct uvc_video *video)
 199{
 200        unsigned int req_size;
 201        unsigned int i;
 202        int ret = -ENOMEM;
 203
 204        BUG_ON(video->req_size);
 205
 206        req_size = video->ep->maxpacket
 207                 * max_t(unsigned int, video->ep->maxburst, 1)
 208                 * (video->ep->mult);
 209
 210        for (i = 0; i < UVC_NUM_REQUESTS; ++i) {
 211                video->req_buffer[i] = kmalloc(req_size, GFP_KERNEL);
 212                if (video->req_buffer[i] == NULL)
 213                        goto error;
 214
 215                video->req[i] = usb_ep_alloc_request(video->ep, GFP_KERNEL);
 216                if (video->req[i] == NULL)
 217                        goto error;
 218
 219                video->req[i]->buf = video->req_buffer[i];
 220                video->req[i]->length = 0;
 221                video->req[i]->complete = uvc_video_complete;
 222                video->req[i]->context = video;
 223
 224                list_add_tail(&video->req[i]->list, &video->req_free);
 225        }
 226
 227        video->req_size = req_size;
 228
 229        return 0;
 230
 231error:
 232        uvc_video_free_requests(video);
 233        return ret;
 234}
 235
 236/* --------------------------------------------------------------------------
 237 * Video streaming
 238 */
 239
 240/*
 241 * uvcg_video_pump - Pump video data into the USB requests
 242 *
 243 * This function fills the available USB requests (listed in req_free) with
 244 * video data from the queued buffers.
 245 */
 246static void uvcg_video_pump(struct work_struct *work)
 247{
 248        struct uvc_video *video = container_of(work, struct uvc_video, pump);
 249        struct uvc_video_queue *queue = &video->queue;
 250        struct usb_request *req;
 251        struct uvc_buffer *buf;
 252        unsigned long flags;
 253        int ret;
 254
 255        while (1) {
 256                /* Retrieve the first available USB request, protected by the
 257                 * request lock.
 258                 */
 259                spin_lock_irqsave(&video->req_lock, flags);
 260                if (list_empty(&video->req_free)) {
 261                        spin_unlock_irqrestore(&video->req_lock, flags);
 262                        return;
 263                }
 264                req = list_first_entry(&video->req_free, struct usb_request,
 265                                        list);
 266                list_del(&req->list);
 267                spin_unlock_irqrestore(&video->req_lock, flags);
 268
 269                /* Retrieve the first available video buffer and fill the
 270                 * request, protected by the video queue irqlock.
 271                 */
 272                spin_lock_irqsave(&queue->irqlock, flags);
 273                buf = uvcg_queue_head(queue);
 274                if (buf == NULL) {
 275                        spin_unlock_irqrestore(&queue->irqlock, flags);
 276                        break;
 277                }
 278
 279                video->encode(req, video, buf);
 280
 281                /* Queue the USB request */
 282                ret = uvcg_video_ep_queue(video, req);
 283                spin_unlock_irqrestore(&queue->irqlock, flags);
 284
 285                if (ret < 0) {
 286                        uvcg_queue_cancel(queue, 0);
 287                        break;
 288                }
 289        }
 290
 291        spin_lock_irqsave(&video->req_lock, flags);
 292        list_add_tail(&req->list, &video->req_free);
 293        spin_unlock_irqrestore(&video->req_lock, flags);
 294        return;
 295}
 296
 297/*
 298 * Enable or disable the video stream.
 299 */
 300int uvcg_video_enable(struct uvc_video *video, int enable)
 301{
 302        unsigned int i;
 303        int ret;
 304
 305        if (video->ep == NULL) {
 306                uvcg_info(&video->uvc->func,
 307                          "Video enable failed, device is uninitialized.\n");
 308                return -ENODEV;
 309        }
 310
 311        if (!enable) {
 312                cancel_work_sync(&video->pump);
 313                uvcg_queue_cancel(&video->queue, 0);
 314
 315                for (i = 0; i < UVC_NUM_REQUESTS; ++i)
 316                        if (video->req[i])
 317                                usb_ep_dequeue(video->ep, video->req[i]);
 318
 319                uvc_video_free_requests(video);
 320                uvcg_queue_enable(&video->queue, 0);
 321                return 0;
 322        }
 323
 324        if ((ret = uvcg_queue_enable(&video->queue, 1)) < 0)
 325                return ret;
 326
 327        if ((ret = uvc_video_alloc_requests(video)) < 0)
 328                return ret;
 329
 330        if (video->max_payload_size) {
 331                video->encode = uvc_video_encode_bulk;
 332                video->payload_size = 0;
 333        } else
 334                video->encode = uvc_video_encode_isoc;
 335
 336        schedule_work(&video->pump);
 337
 338        return ret;
 339}
 340
 341/*
 342 * Initialize the UVC video stream.
 343 */
 344int uvcg_video_init(struct uvc_video *video, struct uvc_device *uvc)
 345{
 346        INIT_LIST_HEAD(&video->req_free);
 347        spin_lock_init(&video->req_lock);
 348        INIT_WORK(&video->pump, uvcg_video_pump);
 349
 350        video->uvc = uvc;
 351        video->fcc = V4L2_PIX_FMT_YUYV;
 352        video->bpp = 16;
 353        video->width = 320;
 354        video->height = 240;
 355        video->imagesize = 320 * 240 * 2;
 356
 357        /* Initialize the video buffers queue. */
 358        uvcg_queue_init(&video->queue, V4L2_BUF_TYPE_VIDEO_OUTPUT,
 359                        &video->mutex);
 360        return 0;
 361}
 362
 363