Merge tag 'upstream-3.7-rc1' of git://git.infradead.org/linux-ubifs
[cascardo/linux.git] / drivers / media / video / vivi.c
index 08c1024..a05494b 100644 (file)
@@ -188,6 +188,7 @@ struct vivi_dev {
        struct list_head           vivi_devlist;
        struct v4l2_device         v4l2_dev;
        struct v4l2_ctrl_handler   ctrl_handler;
+       struct video_device        vdev;
 
        /* controls */
        struct v4l2_ctrl           *brightness;
@@ -213,9 +214,6 @@ struct vivi_dev {
        spinlock_t                 slock;
        struct mutex               mutex;
 
-       /* various device info */
-       struct video_device        *vfd;
-
        struct vivi_dmaqueue       vidq;
 
        /* Several counters */
@@ -232,7 +230,6 @@ struct vivi_dev {
        struct vivi_fmt            *fmt;
        unsigned int               width, height;
        struct vb2_queue           vb_vidq;
-       enum v4l2_field            field;
        unsigned int               field_count;
 
        u8                         bars[9][3];
@@ -625,7 +622,7 @@ static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf)
 
        dev->mv_count += 2;
 
-       buf->vb.v4l2_buf.field = dev->field;
+       buf->vb.v4l2_buf.field = V4L2_FIELD_INTERLACED;
        dev->field_count++;
        buf->vb.v4l2_buf.sequence = dev->field_count >> 1;
        do_gettimeofday(&ts);
@@ -769,7 +766,13 @@ static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
        struct vivi_dev *dev = vb2_get_drv_priv(vq);
        unsigned long size;
 
-       size = dev->width * dev->height * dev->pixelsize;
+       if (fmt)
+               size = fmt->fmt.pix.sizeimage;
+       else
+               size = dev->width * dev->height * dev->pixelsize;
+
+       if (size == 0)
+               return -EINVAL;
 
        if (0 == *nbuffers)
                *nbuffers = 32;
@@ -792,27 +795,6 @@ static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
        return 0;
 }
 
-static int buffer_init(struct vb2_buffer *vb)
-{
-       struct vivi_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
-
-       BUG_ON(NULL == dev->fmt);
-
-       /*
-        * This callback is called once per buffer, after its allocation.
-        *
-        * Vivi does not allow changing format during streaming, but it is
-        * possible to do so when streaming is paused (i.e. in streamoff state).
-        * Buffers however are not freed when going into streamoff and so
-        * buffer size verification has to be done in buffer_prepare, on each
-        * qbuf.
-        * It would be best to move verification code here to buf_init and
-        * s_fmt though.
-        */
-
-       return 0;
-}
-
 static int buffer_prepare(struct vb2_buffer *vb)
 {
        struct vivi_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
@@ -850,20 +832,6 @@ static int buffer_prepare(struct vb2_buffer *vb)
        return 0;
 }
 
-static int buffer_finish(struct vb2_buffer *vb)
-{
-       struct vivi_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
-       dprintk(dev, 1, "%s\n", __func__);
-       return 0;
-}
-
-static void buffer_cleanup(struct vb2_buffer *vb)
-{
-       struct vivi_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
-       dprintk(dev, 1, "%s\n", __func__);
-
-}
-
 static void buffer_queue(struct vb2_buffer *vb)
 {
        struct vivi_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
@@ -909,10 +877,7 @@ static void vivi_unlock(struct vb2_queue *vq)
 
 static struct vb2_ops vivi_video_qops = {
        .queue_setup            = queue_setup,
-       .buf_init               = buffer_init,
        .buf_prepare            = buffer_prepare,
-       .buf_finish             = buffer_finish,
-       .buf_cleanup            = buffer_cleanup,
        .buf_queue              = buffer_queue,
        .start_streaming        = start_streaming,
        .stop_streaming         = stop_streaming,
@@ -959,7 +924,7 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
 
        f->fmt.pix.width        = dev->width;
        f->fmt.pix.height       = dev->height;
-       f->fmt.pix.field        = dev->field;
+       f->fmt.pix.field        = V4L2_FIELD_INTERLACED;
        f->fmt.pix.pixelformat  = dev->fmt->fourcc;
        f->fmt.pix.bytesperline =
                (f->fmt.pix.width * dev->fmt->depth) >> 3;
@@ -978,25 +943,16 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
 {
        struct vivi_dev *dev = video_drvdata(file);
        struct vivi_fmt *fmt;
-       enum v4l2_field field;
 
        fmt = get_format(f);
        if (!fmt) {
-               dprintk(dev, 1, "Fourcc format (0x%08x) invalid.\n",
+               dprintk(dev, 1, "Fourcc format (0x%08x) unknown.\n",
                        f->fmt.pix.pixelformat);
-               return -EINVAL;
-       }
-
-       field = f->fmt.pix.field;
-
-       if (field == V4L2_FIELD_ANY) {
-               field = V4L2_FIELD_INTERLACED;
-       } else if (V4L2_FIELD_INTERLACED != field) {
-               dprintk(dev, 1, "Field type invalid.\n");
-               return -EINVAL;
+               f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
+               fmt = get_format(f);
        }
 
-       f->fmt.pix.field = field;
+       f->fmt.pix.field = V4L2_FIELD_INTERLACED;
        v4l_bound_align_image(&f->fmt.pix.width, 48, MAX_WIDTH, 2,
                              &f->fmt.pix.height, 32, MAX_HEIGHT, 0, 0);
        f->fmt.pix.bytesperline =
@@ -1021,7 +977,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
        if (ret < 0)
                return ret;
 
-       if (vb2_is_streaming(q)) {
+       if (vb2_is_busy(q)) {
                dprintk(dev, 1, "%s device busy\n", __func__);
                return -EBUSY;
        }
@@ -1030,53 +986,10 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
        dev->pixelsize = dev->fmt->depth / 8;
        dev->width = f->fmt.pix.width;
        dev->height = f->fmt.pix.height;
-       dev->field = f->fmt.pix.field;
 
        return 0;
 }
 
-static int vidioc_reqbufs(struct file *file, void *priv,
-                         struct v4l2_requestbuffers *p)
-{
-       struct vivi_dev *dev = video_drvdata(file);
-       return vb2_reqbufs(&dev->vb_vidq, p);
-}
-
-static int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p)
-{
-       struct vivi_dev *dev = video_drvdata(file);
-       return vb2_querybuf(&dev->vb_vidq, p);
-}
-
-static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
-{
-       struct vivi_dev *dev = video_drvdata(file);
-       return vb2_qbuf(&dev->vb_vidq, p);
-}
-
-static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
-{
-       struct vivi_dev *dev = video_drvdata(file);
-       return vb2_dqbuf(&dev->vb_vidq, p, file->f_flags & O_NONBLOCK);
-}
-
-static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
-{
-       struct vivi_dev *dev = video_drvdata(file);
-       return vb2_streamon(&dev->vb_vidq, i);
-}
-
-static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
-{
-       struct vivi_dev *dev = video_drvdata(file);
-       return vb2_streamoff(&dev->vb_vidq, i);
-}
-
-static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *i)
-{
-       return 0;
-}
-
 /* only one input in this sample driver */
 static int vidioc_enum_input(struct file *file, void *priv,
                                struct v4l2_input *inp)
@@ -1085,7 +998,6 @@ static int vidioc_enum_input(struct file *file, void *priv,
                return -EINVAL;
 
        inp->type = V4L2_INPUT_TYPE_CAMERA;
-       inp->std = V4L2_STD_525_60;
        sprintf(inp->name, "Camera %u", inp->index);
        return 0;
 }
@@ -1145,58 +1057,6 @@ static int vivi_s_ctrl(struct v4l2_ctrl *ctrl)
        File operations for the device
    ------------------------------------------------------------------*/
 
-static ssize_t
-vivi_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
-{
-       struct vivi_dev *dev = video_drvdata(file);
-       int err;
-
-       dprintk(dev, 1, "read called\n");
-       mutex_lock(&dev->mutex);
-       err = vb2_read(&dev->vb_vidq, data, count, ppos,
-                      file->f_flags & O_NONBLOCK);
-       mutex_unlock(&dev->mutex);
-       return err;
-}
-
-static unsigned int
-vivi_poll(struct file *file, struct poll_table_struct *wait)
-{
-       struct vivi_dev *dev = video_drvdata(file);
-       struct vb2_queue *q = &dev->vb_vidq;
-
-       dprintk(dev, 1, "%s\n", __func__);
-       return vb2_poll(q, file, wait);
-}
-
-static int vivi_close(struct file *file)
-{
-       struct video_device  *vdev = video_devdata(file);
-       struct vivi_dev *dev = video_drvdata(file);
-
-       dprintk(dev, 1, "close called (dev=%s), file %p\n",
-               video_device_node_name(vdev), file);
-
-       if (v4l2_fh_is_singular_file(file))
-               vb2_queue_release(&dev->vb_vidq);
-       return v4l2_fh_release(file);
-}
-
-static int vivi_mmap(struct file *file, struct vm_area_struct *vma)
-{
-       struct vivi_dev *dev = video_drvdata(file);
-       int ret;
-
-       dprintk(dev, 1, "mmap called, vma=0x%08lx\n", (unsigned long)vma);
-
-       ret = vb2_mmap(&dev->vb_vidq, vma);
-       dprintk(dev, 1, "vma start=0x%08lx, size=%ld, ret=%d\n",
-               (unsigned long)vma->vm_start,
-               (unsigned long)vma->vm_end - (unsigned long)vma->vm_start,
-               ret);
-       return ret;
-}
-
 static const struct v4l2_ctrl_ops vivi_ctrl_ops = {
        .g_volatile_ctrl = vivi_g_volatile_ctrl,
        .s_ctrl = vivi_s_ctrl,
@@ -1301,11 +1161,11 @@ static const struct v4l2_ctrl_config vivi_ctrl_int_menu = {
 static const struct v4l2_file_operations vivi_fops = {
        .owner          = THIS_MODULE,
        .open           = v4l2_fh_open,
-       .release        = vivi_close,
-       .read           = vivi_read,
-       .poll           = vivi_poll,
+       .release        = vb2_fop_release,
+       .read           = vb2_fop_read,
+       .poll           = vb2_fop_poll,
        .unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */
-       .mmap           = vivi_mmap,
+       .mmap           = vb2_fop_mmap,
 };
 
 static const struct v4l2_ioctl_ops vivi_ioctl_ops = {
@@ -1314,16 +1174,17 @@ static const struct v4l2_ioctl_ops vivi_ioctl_ops = {
        .vidioc_g_fmt_vid_cap     = vidioc_g_fmt_vid_cap,
        .vidioc_try_fmt_vid_cap   = vidioc_try_fmt_vid_cap,
        .vidioc_s_fmt_vid_cap     = vidioc_s_fmt_vid_cap,
-       .vidioc_reqbufs       = vidioc_reqbufs,
-       .vidioc_querybuf      = vidioc_querybuf,
-       .vidioc_qbuf          = vidioc_qbuf,
-       .vidioc_dqbuf         = vidioc_dqbuf,
-       .vidioc_s_std         = vidioc_s_std,
+       .vidioc_reqbufs       = vb2_ioctl_reqbufs,
+       .vidioc_create_bufs   = vb2_ioctl_create_bufs,
+       .vidioc_prepare_buf   = vb2_ioctl_prepare_buf,
+       .vidioc_querybuf      = vb2_ioctl_querybuf,
+       .vidioc_qbuf          = vb2_ioctl_qbuf,
+       .vidioc_dqbuf         = vb2_ioctl_dqbuf,
        .vidioc_enum_input    = vidioc_enum_input,
        .vidioc_g_input       = vidioc_g_input,
        .vidioc_s_input       = vidioc_s_input,
-       .vidioc_streamon      = vidioc_streamon,
-       .vidioc_streamoff     = vidioc_streamoff,
+       .vidioc_streamon      = vb2_ioctl_streamon,
+       .vidioc_streamoff     = vb2_ioctl_streamoff,
        .vidioc_log_status    = v4l2_ctrl_log_status,
        .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
        .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
@@ -1333,10 +1194,7 @@ static struct video_device vivi_template = {
        .name           = "vivi",
        .fops           = &vivi_fops,
        .ioctl_ops      = &vivi_ioctl_ops,
-       .release        = video_device_release,
-
-       .tvnorms              = V4L2_STD_525_60,
-       .current_norm         = V4L2_STD_NTSC_M,
+       .release        = video_device_release_empty,
 };
 
 /* -----------------------------------------------------------------
@@ -1354,8 +1212,8 @@ static int vivi_release(void)
                dev = list_entry(list, struct vivi_dev, vivi_devlist);
 
                v4l2_info(&dev->v4l2_dev, "unregistering %s\n",
-                       video_device_node_name(dev->vfd));
-               video_unregister_device(dev->vfd);
+                       video_device_node_name(&dev->vdev));
+               video_unregister_device(&dev->vdev);
                v4l2_device_unregister(&dev->v4l2_dev);
                v4l2_ctrl_handler_free(&dev->ctrl_handler);
                kfree(dev);
@@ -1440,14 +1298,11 @@ static int __init vivi_create_instance(int inst)
        INIT_LIST_HEAD(&dev->vidq.active);
        init_waitqueue_head(&dev->vidq.wq);
 
-       ret = -ENOMEM;
-       vfd = video_device_alloc();
-       if (!vfd)
-               goto unreg_dev;
-
+       vfd = &dev->vdev;
        *vfd = vivi_template;
        vfd->debug = debug;
        vfd->v4l2_dev = &dev->v4l2_dev;
+       vfd->queue = q;
        set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags);
 
        /*
@@ -1455,26 +1310,19 @@ static int __init vivi_create_instance(int inst)
         * all fops and v4l2 ioctls.
         */
        vfd->lock = &dev->mutex;
+       video_set_drvdata(vfd, dev);
 
        ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr);
        if (ret < 0)
-               goto rel_vdev;
-
-       video_set_drvdata(vfd, dev);
+               goto unreg_dev;
 
        /* Now that everything is fine, let's add it to device list */
        list_add_tail(&dev->vivi_devlist, &vivi_devlist);
 
-       if (video_nr != -1)
-               video_nr++;
-
-       dev->vfd = vfd;
        v4l2_info(&dev->v4l2_dev, "V4L2 device registered as %s\n",
                  video_device_node_name(vfd));
        return 0;
 
-rel_vdev:
-       video_device_release(vfd);
 unreg_dev:
        v4l2_ctrl_handler_free(hdl);
        v4l2_device_unregister(&dev->v4l2_dev);