[media] vivi: use vb2 helper functions
[linux-2.6-microblaze.git] / drivers / media / video / vivi.c
index 5e8b071..f6d7c6e 100644 (file)
@@ -94,6 +94,16 @@ static struct vivi_fmt formats[] = {
                .fourcc   = V4L2_PIX_FMT_UYVY,
                .depth    = 16,
        },
+       {
+               .name     = "4:2:2, packed, YVYU",
+               .fourcc   = V4L2_PIX_FMT_YVYU,
+               .depth    = 16,
+       },
+       {
+               .name     = "4:2:2, packed, VYUY",
+               .fourcc   = V4L2_PIX_FMT_VYUY,
+               .depth    = 16,
+       },
        {
                .name     = "RGB565 (LE)",
                .fourcc   = V4L2_PIX_FMT_RGB565, /* gggbbbbb rrrrrggg */
@@ -114,6 +124,26 @@ static struct vivi_fmt formats[] = {
                .fourcc   = V4L2_PIX_FMT_RGB555X, /* arrrrrgg gggbbbbb */
                .depth    = 16,
        },
+       {
+               .name     = "RGB24 (LE)",
+               .fourcc   = V4L2_PIX_FMT_RGB24, /* rgb */
+               .depth    = 24,
+       },
+       {
+               .name     = "RGB24 (BE)",
+               .fourcc   = V4L2_PIX_FMT_BGR24, /* bgr */
+               .depth    = 24,
+       },
+       {
+               .name     = "RGB32 (LE)",
+               .fourcc   = V4L2_PIX_FMT_RGB32, /* argb */
+               .depth    = 32,
+       },
+       {
+               .name     = "RGB32 (BE)",
+               .fourcc   = V4L2_PIX_FMT_BGR32, /* bgra */
+               .depth    = 32,
+       },
 };
 
 static struct vivi_fmt *get_format(struct v4l2_format *f)
@@ -158,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;
@@ -170,6 +201,7 @@ struct vivi_dev {
                struct v4l2_ctrl           *gain;
        };
        struct v4l2_ctrl           *volume;
+       struct v4l2_ctrl           *alpha;
        struct v4l2_ctrl           *button;
        struct v4l2_ctrl           *boolean;
        struct v4l2_ctrl           *int32;
@@ -177,13 +209,11 @@ struct vivi_dev {
        struct v4l2_ctrl           *menu;
        struct v4l2_ctrl           *string;
        struct v4l2_ctrl           *bitmask;
+       struct v4l2_ctrl           *int_menu;
 
        spinlock_t                 slock;
        struct mutex               mutex;
 
-       /* various device info */
-       struct video_device        *vfd;
-
        struct vivi_dmaqueue       vidq;
 
        /* Several counters */
@@ -203,8 +233,10 @@ struct vivi_dev {
        enum v4l2_field            field;
        unsigned int               field_count;
 
-       u8                         bars[9][3];
-       u8                         line[MAX_WIDTH * 4];
+       u8                         bars[9][3];
+       u8                         line[MAX_WIDTH * 8];
+       unsigned int               pixelsize;
+       u8                         alpha_component;
 };
 
 /* ------------------------------------------------------------------
@@ -283,6 +315,8 @@ static void precalculate_bars(struct vivi_dev *dev)
                switch (dev->fmt->fourcc) {
                case V4L2_PIX_FMT_YUYV:
                case V4L2_PIX_FMT_UYVY:
+               case V4L2_PIX_FMT_YVYU:
+               case V4L2_PIX_FMT_VYUY:
                        is_yuv = 1;
                        break;
                case V4L2_PIX_FMT_RGB565:
@@ -297,6 +331,11 @@ static void precalculate_bars(struct vivi_dev *dev)
                        g >>= 3;
                        b >>= 3;
                        break;
+               case V4L2_PIX_FMT_RGB24:
+               case V4L2_PIX_FMT_BGR24:
+               case V4L2_PIX_FMT_RGB32:
+               case V4L2_PIX_FMT_BGR32:
+                       break;
                }
 
                if (is_yuv) {
@@ -316,9 +355,11 @@ static void precalculate_bars(struct vivi_dev *dev)
 #define TSTAMP_INPUT_X 10
 #define TSTAMP_MIN_X   (54 + TSTAMP_INPUT_X)
 
-static void gen_twopix(struct vivi_dev *dev, u8 *buf, int colorpos)
+/* 'odd' is true for pixels 1, 3, 5, etc. and false for pixels 0, 2, 4, etc. */
+static void gen_twopix(struct vivi_dev *dev, u8 *buf, int colorpos, bool odd)
 {
        u8 r_y, g_u, b_v;
+       u8 alpha = dev->alpha_component;
        int color;
        u8 *p;
 
@@ -326,46 +367,56 @@ static void gen_twopix(struct vivi_dev *dev, u8 *buf, int colorpos)
        g_u = dev->bars[colorpos][1]; /* G or precalculated U */
        b_v = dev->bars[colorpos][2]; /* B or precalculated V */
 
-       for (color = 0; color < 4; color++) {
+       for (color = 0; color < dev->pixelsize; color++) {
                p = buf + color;
 
                switch (dev->fmt->fourcc) {
                case V4L2_PIX_FMT_YUYV:
                        switch (color) {
                        case 0:
-                       case 2:
                                *p = r_y;
                                break;
                        case 1:
-                               *p = g_u;
-                               break;
-                       case 3:
-                               *p = b_v;
+                               *p = odd ? b_v : g_u;
                                break;
                        }
                        break;
                case V4L2_PIX_FMT_UYVY:
                        switch (color) {
+                       case 0:
+                               *p = odd ? b_v : g_u;
+                               break;
                        case 1:
-                       case 3:
                                *p = r_y;
                                break;
+                       }
+                       break;
+               case V4L2_PIX_FMT_YVYU:
+                       switch (color) {
                        case 0:
-                               *p = g_u;
+                               *p = r_y;
                                break;
-                       case 2:
-                               *p = b_v;
+                       case 1:
+                               *p = odd ? g_u : b_v;
+                               break;
+                       }
+                       break;
+               case V4L2_PIX_FMT_VYUY:
+                       switch (color) {
+                       case 0:
+                               *p = odd ? g_u : b_v;
+                               break;
+                       case 1:
+                               *p = r_y;
                                break;
                        }
                        break;
                case V4L2_PIX_FMT_RGB565:
                        switch (color) {
                        case 0:
-                       case 2:
                                *p = (g_u << 5) | b_v;
                                break;
                        case 1:
-                       case 3:
                                *p = (r_y << 3) | (g_u >> 3);
                                break;
                        }
@@ -373,11 +424,9 @@ static void gen_twopix(struct vivi_dev *dev, u8 *buf, int colorpos)
                case V4L2_PIX_FMT_RGB565X:
                        switch (color) {
                        case 0:
-                       case 2:
                                *p = (r_y << 3) | (g_u >> 3);
                                break;
                        case 1:
-                       case 3:
                                *p = (g_u << 5) | b_v;
                                break;
                        }
@@ -385,24 +434,78 @@ static void gen_twopix(struct vivi_dev *dev, u8 *buf, int colorpos)
                case V4L2_PIX_FMT_RGB555:
                        switch (color) {
                        case 0:
-                       case 2:
                                *p = (g_u << 5) | b_v;
                                break;
                        case 1:
-                       case 3:
-                               *p = (r_y << 2) | (g_u >> 3);
+                               *p = (alpha & 0x80) | (r_y << 2) | (g_u >> 3);
                                break;
                        }
                        break;
                case V4L2_PIX_FMT_RGB555X:
                        switch (color) {
                        case 0:
+                               *p = (alpha & 0x80) | (r_y << 2) | (g_u >> 3);
+                               break;
+                       case 1:
+                               *p = (g_u << 5) | b_v;
+                               break;
+                       }
+                       break;
+               case V4L2_PIX_FMT_RGB24:
+                       switch (color) {
+                       case 0:
+                               *p = r_y;
+                               break;
+                       case 1:
+                               *p = g_u;
+                               break;
+                       case 2:
+                               *p = b_v;
+                               break;
+                       }
+                       break;
+               case V4L2_PIX_FMT_BGR24:
+                       switch (color) {
+                       case 0:
+                               *p = b_v;
+                               break;
+                       case 1:
+                               *p = g_u;
+                               break;
                        case 2:
-                               *p = (r_y << 2) | (g_u >> 3);
+                               *p = r_y;
+                               break;
+                       }
+                       break;
+               case V4L2_PIX_FMT_RGB32:
+                       switch (color) {
+                       case 0:
+                               *p = alpha;
                                break;
                        case 1:
+                               *p = r_y;
+                               break;
+                       case 2:
+                               *p = g_u;
+                               break;
                        case 3:
-                               *p = (g_u << 5) | b_v;
+                               *p = b_v;
+                               break;
+                       }
+                       break;
+               case V4L2_PIX_FMT_BGR32:
+                       switch (color) {
+                       case 0:
+                               *p = b_v;
+                               break;
+                       case 1:
+                               *p = g_u;
+                               break;
+                       case 2:
+                               *p = r_y;
+                               break;
+                       case 3:
+                               *p = alpha;
                                break;
                        }
                        break;
@@ -414,10 +517,10 @@ static void precalculate_line(struct vivi_dev *dev)
 {
        int w;
 
-       for (w = 0; w < dev->width * 2; w += 2) {
-               int colorpos = (w / (dev->width / 8) % 8);
+       for (w = 0; w < dev->width * 2; w++) {
+               int colorpos = w / (dev->width / 8) % 8;
 
-               gen_twopix(dev, dev->line + w * 2, colorpos);
+               gen_twopix(dev, dev->line + w * dev->pixelsize, colorpos, w & 1);
        }
 }
 
@@ -433,7 +536,7 @@ static void gen_text(struct vivi_dev *dev, char *basep,
        /* Print stream time */
        for (line = y; line < y + 16; line++) {
                int j = 0;
-               char *pos = basep + line * dev->width * 2 + x * 2;
+               char *pos = basep + line * dev->width * dev->pixelsize + x * dev->pixelsize;
                char *s;
 
                for (s = text; *s; s++) {
@@ -443,9 +546,9 @@ static void gen_text(struct vivi_dev *dev, char *basep,
                        for (i = 0; i < 7; i++, j++) {
                                /* Draw white font on black background */
                                if (chr & (1 << (7 - i)))
-                                       gen_twopix(dev, pos + j * 2, WHITE);
+                                       gen_twopix(dev, pos + j * dev->pixelsize, WHITE, (x+y) & 1);
                                else
-                                       gen_twopix(dev, pos + j * 2, TEXT_BLACK);
+                                       gen_twopix(dev, pos + j * dev->pixelsize, TEXT_BLACK, (x+y) & 1);
                        }
                }
        }
@@ -466,7 +569,9 @@ static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf)
                return;
 
        for (h = 0; h < hmax; h++)
-               memcpy(vbuf + h * wmax * 2, dev->line + (dev->mv_count % wmax) * 2, wmax * 2);
+               memcpy(vbuf + h * wmax * dev->pixelsize,
+                      dev->line + (dev->mv_count % wmax) * dev->pixelsize,
+                      wmax * dev->pixelsize);
 
        /* Updates stream time */
 
@@ -484,15 +589,16 @@ static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf)
        gen_text(dev, vbuf, line++ * 16, 16, str);
 
        gain = v4l2_ctrl_g_ctrl(dev->gain);
-       mutex_lock(&dev->ctrl_handler.lock);
+       mutex_lock(dev->ctrl_handler.lock);
        snprintf(str, sizeof(str), " brightness %3d, contrast %3d, saturation %3d, hue %d ",
                        dev->brightness->cur.val,
                        dev->contrast->cur.val,
                        dev->saturation->cur.val,
                        dev->hue->cur.val);
        gen_text(dev, vbuf, line++ * 16, 16, str);
-       snprintf(str, sizeof(str), " autogain %d, gain %3d, volume %3d ",
-                       dev->autogain->cur.val, gain, dev->volume->cur.val);
+       snprintf(str, sizeof(str), " autogain %d, gain %3d, volume %3d, alpha 0x%02x ",
+                       dev->autogain->cur.val, gain, dev->volume->cur.val,
+                       dev->alpha->cur.val);
        gen_text(dev, vbuf, line++ * 16, 16, str);
        snprintf(str, sizeof(str), " int32 %d, int64 %lld, bitmask %08x ",
                        dev->int32->cur.val,
@@ -503,8 +609,12 @@ static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf)
                        dev->boolean->cur.val,
                        dev->menu->qmenu[dev->menu->cur.val],
                        dev->string->cur.string);
-       mutex_unlock(&dev->ctrl_handler.lock);
        gen_text(dev, vbuf, line++ * 16, 16, str);
+       snprintf(str, sizeof(str), " integer_menu %lld, value %d ",
+                       dev->int_menu->qmenu_int[dev->int_menu->cur.val],
+                       dev->int_menu->cur.val);
+       gen_text(dev, vbuf, line++ * 16, 16, str);
+       mutex_unlock(dev->ctrl_handler.lock);
        if (dev->button_pressed) {
                dev->button_pressed--;
                snprintf(str, sizeof(str), " button pressed!");
@@ -657,7 +767,7 @@ 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 * 2;
+       size = dev->width * dev->height * dev->pixelsize;
 
        if (0 == *nbuffers)
                *nbuffers = 32;
@@ -680,27 +790,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);
@@ -721,7 +810,7 @@ static int buffer_prepare(struct vb2_buffer *vb)
            dev->height < 32 || dev->height > MAX_HEIGHT)
                return -EINVAL;
 
-       size = dev->width * dev->height * 2;
+       size = dev->width * dev->height * dev->pixelsize;
        if (vb2_plane_size(vb, 0) < size) {
                dprintk(dev, 1, "%s data will not fit into plane (%lu < %lu)\n",
                                __func__, vb2_plane_size(vb, 0), size);
@@ -738,20 +827,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);
@@ -797,10 +872,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,
@@ -909,12 +981,13 @@ 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;
        }
 
        dev->fmt = get_format(f);
+       dev->pixelsize = dev->fmt->depth / 8;
        dev->width = f->fmt.pix.width;
        dev->height = f->fmt.pix.height;
        dev->field = f->fmt.pix.field;
@@ -922,48 +995,6 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
        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)
@@ -972,7 +1003,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;
 }
@@ -1016,8 +1046,15 @@ static int vivi_s_ctrl(struct v4l2_ctrl *ctrl)
 {
        struct vivi_dev *dev = container_of(ctrl->handler, struct vivi_dev, ctrl_handler);
 
-       if (ctrl == dev->button)
-               dev->button_pressed = 30;
+       switch (ctrl->id) {
+       case V4L2_CID_ALPHA_COMPONENT:
+               dev->alpha_component = ctrl->val;
+               break;
+       default:
+               if (ctrl == dev->button)
+                       dev->button_pressed = 30;
+               break;
+       }
        return 0;
 }
 
@@ -1025,61 +1062,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);
-
-       dprintk(dev, 1, "read called\n");
-       return vb2_read(&dev->vb_vidq, data, count, ppos,
-                      file->f_flags & O_NONBLOCK);
-}
-
-static unsigned int
-vivi_poll(struct file *file, struct poll_table_struct *wait)
-{
-       struct vivi_dev *dev = video_drvdata(file);
-       struct v4l2_fh *fh = file->private_data;
-       struct vb2_queue *q = &dev->vb_vidq;
-       unsigned int res;
-
-       dprintk(dev, 1, "%s\n", __func__);
-       res = vb2_poll(q, file, wait);
-       if (v4l2_event_pending(fh))
-               res |= POLLPRI;
-       else
-               poll_wait(file, &fh->wait, wait);
-       return res;
-}
-
-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,
@@ -1165,14 +1147,30 @@ static const struct v4l2_ctrl_config vivi_ctrl_bitmask = {
        .step = 0,
 };
 
+static const s64 vivi_ctrl_int_menu_values[] = {
+       1, 1, 2, 3, 5, 8, 13, 21, 42,
+};
+
+static const struct v4l2_ctrl_config vivi_ctrl_int_menu = {
+       .ops = &vivi_ctrl_ops,
+       .id = VIVI_CID_CUSTOM_BASE + 7,
+       .name = "Integer menu",
+       .type = V4L2_CTRL_TYPE_INTEGER_MENU,
+       .min = 1,
+       .max = 8,
+       .def = 4,
+       .menu_skip_mask = 0x02,
+       .qmenu_int = vivi_ctrl_int_menu_values,
+};
+
 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 = {
@@ -1181,16 +1179,15 @@ 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_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,
@@ -1200,10 +1197,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,
 };
 
 /* -----------------------------------------------------------------
@@ -1221,8 +1215,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);
@@ -1252,6 +1246,7 @@ static int __init vivi_create_instance(int inst)
        dev->fmt = &formats[0];
        dev->width = 640;
        dev->height = 480;
+       dev->pixelsize = dev->fmt->depth / 8;
        hdl = &dev->ctrl_handler;
        v4l2_ctrl_handler_init(hdl, 11);
        dev->volume = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
@@ -1268,6 +1263,8 @@ static int __init vivi_create_instance(int inst)
                        V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
        dev->gain = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
                        V4L2_CID_GAIN, 0, 255, 1, 100);
+       dev->alpha = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
+                       V4L2_CID_ALPHA_COMPONENT, 0, 255, 1, 0);
        dev->button = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_button, NULL);
        dev->int32 = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_int32, NULL);
        dev->int64 = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_int64, NULL);
@@ -1275,6 +1272,7 @@ static int __init vivi_create_instance(int inst)
        dev->menu = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_menu, NULL);
        dev->string = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_string, NULL);
        dev->bitmask = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_bitmask, NULL);
+       dev->int_menu = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_int_menu, NULL);
        if (hdl->error) {
                ret = hdl->error;
                goto unreg_dev;
@@ -1303,14 +1301,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);
 
        /*
@@ -1318,12 +1313,11 @@ 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);
@@ -1331,13 +1325,10 @@ static int __init vivi_create_instance(int inst)
        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);