These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / media / platform / marvell-ccic / mcam-core.c
index 110fd70..aa2b440 100644 (file)
@@ -24,6 +24,7 @@
 #include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
 #include <media/v4l2-ctrls.h>
+#include <media/v4l2-event.h>
 #include <media/ov7670.h>
 #include <media/videobuf2-vmalloc.h>
 #include <media/videobuf2-dma-contig.h>
@@ -122,30 +123,23 @@ static struct mcam_format_struct {
                .bpp            = 2,
                .planar         = false,
        },
-       {
-               .desc           = "YUV 4:2:2 PLANAR",
-               .pixelformat    = V4L2_PIX_FMT_YUV422P,
-               .mbus_code      = MEDIA_BUS_FMT_YUYV8_2X8,
-               .bpp            = 2,
-               .planar         = true,
-       },
        {
                .desc           = "YUV 4:2:0 PLANAR",
                .pixelformat    = V4L2_PIX_FMT_YUV420,
                .mbus_code      = MEDIA_BUS_FMT_YUYV8_2X8,
-               .bpp            = 2,
+               .bpp            = 1,
                .planar         = true,
        },
        {
                .desc           = "YVU 4:2:0 PLANAR",
                .pixelformat    = V4L2_PIX_FMT_YVU420,
                .mbus_code      = MEDIA_BUS_FMT_YUYV8_2X8,
-               .bpp            = 2,
+               .bpp            = 1,
                .planar         = true,
        },
        {
-               .desc           = "RGB 444",
-               .pixelformat    = V4L2_PIX_FMT_RGB444,
+               .desc           = "XRGB 444",
+               .pixelformat    = V4L2_PIX_FMT_XRGB444,
                .mbus_code      = MEDIA_BUS_FMT_RGB444_2X8_PADHI_LE,
                .bpp            = 2,
                .planar         = false,
@@ -188,6 +182,7 @@ static const struct v4l2_pix_format mcam_def_pix_format = {
        .field          = V4L2_FIELD_NONE,
        .bytesperline   = VGA_WIDTH*2,
        .sizeimage      = VGA_WIDTH*VGA_HEIGHT*2,
+       .colorspace     = V4L2_COLORSPACE_SRGB,
 };
 
 static const u32 mcam_def_mbus_code = MEDIA_BUS_FMT_YUYV8_2X8;
@@ -204,27 +199,20 @@ struct mcam_dma_desc {
        u32 segment_len;
 };
 
-struct yuv_pointer_t {
-       dma_addr_t y;
-       dma_addr_t u;
-       dma_addr_t v;
-};
-
 /*
  * Our buffer type for working with videobuf2.  Note that the vb2
- * developers have decreed that struct vb2_buffer must be at the
+ * developers have decreed that struct vb2_v4l2_buffer must be at the
  * beginning of this structure.
  */
 struct mcam_vb_buffer {
-       struct vb2_buffer vb_buf;
+       struct vb2_v4l2_buffer vb_buf;
        struct list_head queue;
        struct mcam_dma_desc *dma_desc; /* Descriptor virtual address */
        dma_addr_t dma_desc_pa;         /* Descriptor physical address */
        int dma_desc_nent;              /* Number of mapped descriptors */
-       struct yuv_pointer_t yuv_p;
 };
 
-static inline struct mcam_vb_buffer *vb_to_mvb(struct vb2_buffer *vb)
+static inline struct mcam_vb_buffer *vb_to_mvb(struct vb2_v4l2_buffer *vb)
 {
        return container_of(vb, struct mcam_vb_buffer, vb_buf);
 }
@@ -233,12 +221,14 @@ static inline struct mcam_vb_buffer *vb_to_mvb(struct vb2_buffer *vb)
  * Hand a completed buffer back to user space.
  */
 static void mcam_buffer_done(struct mcam_camera *cam, int frame,
-               struct vb2_buffer *vbuf)
+               struct vb2_v4l2_buffer *vbuf)
 {
-       vbuf->v4l2_buf.bytesused = cam->pix_format.sizeimage;
-       vbuf->v4l2_buf.sequence = cam->buf_seq[frame];
-       vb2_set_plane_payload(vbuf, 0, cam->pix_format.sizeimage);
-       vb2_buffer_done(vbuf, VB2_BUF_STATE_DONE);
+       vbuf->vb2_buf.planes[0].bytesused = cam->pix_format.sizeimage;
+       vbuf->sequence = cam->buf_seq[frame];
+       vbuf->field = V4L2_FIELD_NONE;
+       v4l2_get_timestamp(&vbuf->timestamp);
+       vb2_set_plane_payload(&vbuf->vb2_buf, 0, cam->pix_format.sizeimage);
+       vb2_buffer_done(&vbuf->vb2_buf, VB2_BUF_STATE_DONE);
 }
 
 
@@ -337,6 +327,43 @@ static void mcam_disable_mipi(struct mcam_camera *mcam)
        mcam->mipi_enabled = false;
 }
 
+static bool mcam_fmt_is_planar(__u32 pfmt)
+{
+       struct mcam_format_struct *f;
+
+       f = mcam_find_format(pfmt);
+       return f->planar;
+}
+
+static void mcam_write_yuv_bases(struct mcam_camera *cam,
+                                unsigned frame, dma_addr_t base)
+{
+       struct v4l2_pix_format *fmt = &cam->pix_format;
+       u32 pixel_count = fmt->width * fmt->height;
+       dma_addr_t y, u = 0, v = 0;
+
+       y = base;
+
+       switch (fmt->pixelformat) {
+       case V4L2_PIX_FMT_YUV420:
+               u = y + pixel_count;
+               v = u + pixel_count / 4;
+               break;
+       case V4L2_PIX_FMT_YVU420:
+               v = y + pixel_count;
+               u = v + pixel_count / 4;
+               break;
+       default:
+               break;
+       }
+
+       mcam_reg_write(cam, REG_Y0BAR + frame * 4, y);
+       if (mcam_fmt_is_planar(fmt->pixelformat)) {
+               mcam_reg_write(cam, REG_U0BAR + frame * 4, u);
+               mcam_reg_write(cam, REG_V0BAR + frame * 4, v);
+       }
+}
+
 /* ------------------------------------------------------------------- */
 
 #ifdef MCAM_MODE_VMALLOC
@@ -407,15 +434,14 @@ static void mcam_free_dma_bufs(struct mcam_camera *cam)
 static void mcam_ctlr_dma_vmalloc(struct mcam_camera *cam)
 {
        /*
-        * Store the first two Y buffers (we aren't supporting
-        * planar formats for now, so no UV bufs).  Then either
+        * Store the first two YUV buffers. Then either
         * set the third if it exists, or tell the controller
         * to just use two.
         */
-       mcam_reg_write(cam, REG_Y0BAR, cam->dma_handles[0]);
-       mcam_reg_write(cam, REG_Y1BAR, cam->dma_handles[1]);
+       mcam_write_yuv_bases(cam, 0, cam->dma_handles[0]);
+       mcam_write_yuv_bases(cam, 1, cam->dma_handles[1]);
        if (cam->nbufs > 2) {
-               mcam_reg_write(cam, REG_Y2BAR, cam->dma_handles[2]);
+               mcam_write_yuv_bases(cam, 2, cam->dma_handles[2]);
                mcam_reg_clear_bit(cam, REG_CTRL1, C1_TWOBUFS);
        } else
                mcam_reg_set_bit(cam, REG_CTRL1, C1_TWOBUFS);
@@ -456,7 +482,8 @@ static void mcam_frame_tasklet(unsigned long data)
                 * Drop the lock during the big copy.  This *should* be safe...
                 */
                spin_unlock_irqrestore(&cam->dev_lock, flags);
-               memcpy(vb2_plane_vaddr(&buf->vb_buf, 0), cam->dma_bufs[bufno],
+               memcpy(vb2_plane_vaddr(&buf->vb_buf.vb2_buf, 0),
+                               cam->dma_bufs[bufno],
                                cam->pix_format.sizeimage);
                mcam_buffer_done(cam, bufno, &buf->vb_buf);
                spin_lock_irqsave(&cam->dev_lock, flags);
@@ -510,14 +537,6 @@ static inline int mcam_check_dma_buffers(struct mcam_camera *cam)
  * DMA-contiguous code.
  */
 
-static bool mcam_fmt_is_planar(__u32 pfmt)
-{
-       struct mcam_format_struct *f;
-
-       f = mcam_find_format(pfmt);
-       return f->planar;
-}
-
 /*
  * Set up a contiguous buffer for the given frame.  Here also is where
  * the underrun strategy is set: if there is no buffer available, reuse
@@ -529,10 +548,8 @@ static bool mcam_fmt_is_planar(__u32 pfmt)
 static void mcam_set_contig_buffer(struct mcam_camera *cam, int frame)
 {
        struct mcam_vb_buffer *buf;
-       struct v4l2_pix_format *fmt = &cam->pix_format;
        dma_addr_t dma_handle;
-       u32 pixel_count = fmt->width * fmt->height;
-       struct vb2_buffer *vb;
+       struct vb2_v4l2_buffer *vb;
 
        /*
         * If there are no available buffers, go into single mode
@@ -554,33 +571,8 @@ static void mcam_set_contig_buffer(struct mcam_camera *cam, int frame)
        cam->vb_bufs[frame] = buf;
        vb = &buf->vb_buf;
 
-       dma_handle = vb2_dma_contig_plane_dma_addr(vb, 0);
-       buf->yuv_p.y = dma_handle;
-
-       switch (cam->pix_format.pixelformat) {
-       case V4L2_PIX_FMT_YUV422P:
-               buf->yuv_p.u = buf->yuv_p.y + pixel_count;
-               buf->yuv_p.v = buf->yuv_p.u + pixel_count / 2;
-               break;
-       case V4L2_PIX_FMT_YUV420:
-               buf->yuv_p.u = buf->yuv_p.y + pixel_count;
-               buf->yuv_p.v = buf->yuv_p.u + pixel_count / 4;
-               break;
-       case V4L2_PIX_FMT_YVU420:
-               buf->yuv_p.v = buf->yuv_p.y + pixel_count;
-               buf->yuv_p.u = buf->yuv_p.v + pixel_count / 4;
-               break;
-       default:
-               break;
-       }
-
-       mcam_reg_write(cam, frame == 0 ? REG_Y0BAR : REG_Y1BAR, buf->yuv_p.y);
-       if (mcam_fmt_is_planar(fmt->pixelformat)) {
-               mcam_reg_write(cam, frame == 0 ?
-                                       REG_U0BAR : REG_U1BAR, buf->yuv_p.u);
-               mcam_reg_write(cam, frame == 0 ?
-                                       REG_V0BAR : REG_V1BAR, buf->yuv_p.v);
-       }
+       dma_handle = vb2_dma_contig_plane_dma_addr(&vb->vb2_buf, 0);
+       mcam_write_yuv_bases(cam, frame, dma_handle);
 }
 
 /*
@@ -603,6 +595,7 @@ static void mcam_dma_contig_done(struct mcam_camera *cam, int frame)
 
        if (!test_bit(CF_SINGLE_BUFFER, &cam->flags)) {
                cam->frame_state.delivered++;
+               cam->vb_bufs[frame] = NULL;
                mcam_buffer_done(cam, frame, &buf->vb_buf);
        }
        mcam_set_contig_buffer(cam, frame);
@@ -752,12 +745,6 @@ static void mcam_ctlr_image(struct mcam_camera *cam)
                widthy = fmt->width * 2;
                widthuv = 0;
                break;
-       case V4L2_PIX_FMT_JPEG:
-               imgsz_h = (fmt->sizeimage / fmt->bytesperline) << IMGSZ_V_SHIFT;
-               widthy = fmt->bytesperline;
-               widthuv = 0;
-               break;
-       case V4L2_PIX_FMT_YUV422P:
        case V4L2_PIX_FMT_YUV420:
        case V4L2_PIX_FMT_YVU420:
                widthy = fmt->width;
@@ -766,6 +753,7 @@ static void mcam_ctlr_image(struct mcam_camera *cam)
        default:
                widthy = fmt->bytesperline;
                widthuv = 0;
+               break;
        }
 
        mcam_reg_write_mask(cam, REG_IMGPITCH, widthuv << 16 | widthy,
@@ -777,10 +765,6 @@ static void mcam_ctlr_image(struct mcam_camera *cam)
         * Tell the controller about the image format we are using.
         */
        switch (fmt->pixelformat) {
-       case V4L2_PIX_FMT_YUV422P:
-               mcam_reg_write_mask(cam, REG_CTRL0,
-                       C0_DF_YUV | C0_YUV_PLANAR | C0_YUVE_YVYU, C0_DF_MASK);
-               break;
        case V4L2_PIX_FMT_YUV420:
        case V4L2_PIX_FMT_YVU420:
                mcam_reg_write_mask(cam, REG_CTRL0,
@@ -794,19 +778,18 @@ static void mcam_ctlr_image(struct mcam_camera *cam)
                mcam_reg_write_mask(cam, REG_CTRL0,
                        C0_DF_YUV | C0_YUV_PACKED | C0_YUVE_SWAP24, C0_DF_MASK);
                break;
-       case V4L2_PIX_FMT_JPEG:
-               mcam_reg_write_mask(cam, REG_CTRL0,
-                       C0_DF_YUV | C0_YUV_PACKED | C0_YUVE_YUYV, C0_DF_MASK);
-               break;
-       case V4L2_PIX_FMT_RGB444:
+       case V4L2_PIX_FMT_XRGB444:
                mcam_reg_write_mask(cam, REG_CTRL0,
-                       C0_DF_RGB | C0_RGBF_444 | C0_RGB4_XRGB, C0_DF_MASK);
-               /* Alpha value? */
+                       C0_DF_RGB | C0_RGBF_444 | C0_RGB4_XBGR, C0_DF_MASK);
                break;
        case V4L2_PIX_FMT_RGB565:
                mcam_reg_write_mask(cam, REG_CTRL0,
                        C0_DF_RGB | C0_RGBF_565 | C0_RGB5_BGGR, C0_DF_MASK);
                break;
+       case V4L2_PIX_FMT_SBGGR8:
+               mcam_reg_write_mask(cam, REG_CTRL0,
+                       C0_DF_RGB | C0_RGB5_GRBG, C0_DF_MASK);
+               break;
        default:
                cam_err(cam, "camera: unknown format: %#x\n", fmt->pixelformat);
                break;
@@ -969,7 +952,6 @@ static int mcam_cam_init(struct mcam_camera *cam)
 {
        int ret;
 
-       mutex_lock(&cam->s_mutex);
        if (cam->state != S_NOTREADY)
                cam_warn(cam, "Cam init with device in funky state %d",
                                cam->state);
@@ -977,7 +959,6 @@ static int mcam_cam_init(struct mcam_camera *cam)
        /* Get/set parameters? */
        cam->state = S_IDLE;
        mcam_ctlr_power_down(cam);
-       mutex_unlock(&cam->s_mutex);
        return ret;
 }
 
@@ -998,13 +979,15 @@ static int mcam_cam_set_flip(struct mcam_camera *cam)
 
 static int mcam_cam_configure(struct mcam_camera *cam)
 {
-       struct v4l2_mbus_framefmt mbus_fmt;
+       struct v4l2_subdev_format format = {
+               .which = V4L2_SUBDEV_FORMAT_ACTIVE,
+       };
        int ret;
 
-       v4l2_fill_mbus_format(&mbus_fmt, &cam->pix_format, cam->mbus_code);
+       v4l2_fill_mbus_format(&format.format, &cam->pix_format, cam->mbus_code);
        ret = sensor_call(cam, core, init, 0);
        if (ret == 0)
-               ret = sensor_call(cam, video, s_mbus_fmt, &mbus_fmt);
+               ret = sensor_call(cam, pad, set_fmt, NULL, &format);
        /*
         * OV7670 does weird things if flip is set *before* format...
         */
@@ -1066,14 +1049,17 @@ static int mcam_read_setup(struct mcam_camera *cam)
  */
 
 static int mcam_vb_queue_setup(struct vb2_queue *vq,
-               const struct v4l2_format *fmt, unsigned int *nbufs,
+               const void *parg, unsigned int *nbufs,
                unsigned int *num_planes, unsigned int sizes[],
                void *alloc_ctxs[])
 {
+       const struct v4l2_format *fmt = parg;
        struct mcam_camera *cam = vb2_get_drv_priv(vq);
        int minbufs = (cam->buffer_mode == B_DMA_contig) ? 3 : 2;
 
-       sizes[0] = cam->pix_format.sizeimage;
+       if (fmt && fmt->fmt.pix.sizeimage < cam->pix_format.sizeimage)
+               return -EINVAL;
+       sizes[0] = fmt ? fmt->fmt.pix.sizeimage : cam->pix_format.sizeimage;
        *num_planes = 1; /* Someday we have to support planar formats... */
        if (*nbufs < minbufs)
                *nbufs = minbufs;
@@ -1087,7 +1073,8 @@ static int mcam_vb_queue_setup(struct vb2_queue *vq,
 
 static void mcam_vb_buf_queue(struct vb2_buffer *vb)
 {
-       struct mcam_vb_buffer *mvb = vb_to_mvb(vb);
+       struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+       struct mcam_vb_buffer *mvb = vb_to_mvb(vbuf);
        struct mcam_camera *cam = vb2_get_drv_priv(vb->vb2_queue);
        unsigned long flags;
        int start;
@@ -1102,6 +1089,30 @@ static void mcam_vb_buf_queue(struct vb2_buffer *vb)
                mcam_read_setup(cam);
 }
 
+static void mcam_vb_requeue_bufs(struct vb2_queue *vq,
+                                enum vb2_buffer_state state)
+{
+       struct mcam_camera *cam = vb2_get_drv_priv(vq);
+       struct mcam_vb_buffer *buf, *node;
+       unsigned long flags;
+       unsigned i;
+
+       spin_lock_irqsave(&cam->dev_lock, flags);
+       list_for_each_entry_safe(buf, node, &cam->buffers, queue) {
+               vb2_buffer_done(&buf->vb_buf.vb2_buf, state);
+               list_del(&buf->queue);
+       }
+       for (i = 0; i < MAX_DMA_BUFS; i++) {
+               buf = cam->vb_bufs[i];
+
+               if (buf) {
+                       vb2_buffer_done(&buf->vb_buf.vb2_buf, state);
+                       cam->vb_bufs[i] = NULL;
+               }
+       }
+       spin_unlock_irqrestore(&cam->dev_lock, flags);
+}
+
 /*
  * These need to be called with the mutex held from vb2
  */
@@ -1109,11 +1120,15 @@ static int mcam_vb_start_streaming(struct vb2_queue *vq, unsigned int count)
 {
        struct mcam_camera *cam = vb2_get_drv_priv(vq);
        unsigned int frame;
+       int ret;
 
        if (cam->state != S_IDLE) {
-               INIT_LIST_HEAD(&cam->buffers);
+               mcam_vb_requeue_bufs(vq, VB2_BUF_STATE_QUEUED);
                return -EINVAL;
        }
+       cam->frame_state.frames = 0;
+       cam->frame_state.singles = 0;
+       cam->frame_state.delivered = 0;
        cam->sequence = 0;
        /*
         * Videobuf2 sneakily hoards all the buffers and won't
@@ -1134,14 +1149,19 @@ static int mcam_vb_start_streaming(struct vb2_queue *vq, unsigned int count)
        for (frame = 0; frame < cam->nbufs; frame++)
                clear_bit(CF_FRAME_SOF0 + frame, &cam->flags);
 
-       return mcam_read_setup(cam);
+       ret = mcam_read_setup(cam);
+       if (ret)
+               mcam_vb_requeue_bufs(vq, VB2_BUF_STATE_QUEUED);
+       return ret;
 }
 
 static void mcam_vb_stop_streaming(struct vb2_queue *vq)
 {
        struct mcam_camera *cam = vb2_get_drv_priv(vq);
-       unsigned long flags;
 
+       cam_dbg(cam, "stop_streaming: %d frames, %d singles, %d delivered\n",
+                       cam->frame_state.frames, cam->frame_state.singles,
+                       cam->frame_state.delivered);
        if (cam->state == S_BUFWAIT) {
                /* They never gave us buffers */
                cam->state = S_IDLE;
@@ -1160,9 +1180,7 @@ static void mcam_vb_stop_streaming(struct vb2_queue *vq)
         * VB2 reclaims the buffers, so we need to forget
         * about them.
         */
-       spin_lock_irqsave(&cam->dev_lock, flags);
-       INIT_LIST_HEAD(&cam->buffers);
-       spin_unlock_irqrestore(&cam->dev_lock, flags);
+       mcam_vb_requeue_bufs(vq, VB2_BUF_STATE_ERROR);
 }
 
 
@@ -1183,7 +1201,8 @@ static const struct vb2_ops mcam_vb2_ops = {
  */
 static int mcam_vb_sg_buf_init(struct vb2_buffer *vb)
 {
-       struct mcam_vb_buffer *mvb = vb_to_mvb(vb);
+       struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+       struct mcam_vb_buffer *mvb = vb_to_mvb(vbuf);
        struct mcam_camera *cam = vb2_get_drv_priv(vb->vb2_queue);
        int ndesc = cam->pix_format.sizeimage/PAGE_SIZE + 1;
 
@@ -1199,7 +1218,8 @@ static int mcam_vb_sg_buf_init(struct vb2_buffer *vb)
 
 static int mcam_vb_sg_buf_prepare(struct vb2_buffer *vb)
 {
-       struct mcam_vb_buffer *mvb = vb_to_mvb(vb);
+       struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
+       struct mcam_vb_buffer *mvb = vb_to_mvb(vbuf);
        struct sg_table *sg_table = vb2_dma_sg_plane_desc(vb, 0);
        struct mcam_dma_desc *desc = mvb->dma_desc;
        struct scatterlist *sg;
@@ -1215,8 +1235,9 @@ static int mcam_vb_sg_buf_prepare(struct vb2_buffer *vb)
 
 static void mcam_vb_sg_buf_cleanup(struct vb2_buffer *vb)
 {
+       struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
        struct mcam_camera *cam = vb2_get_drv_priv(vb->vb2_queue);
-       struct mcam_vb_buffer *mvb = vb_to_mvb(vb);
+       struct mcam_vb_buffer *mvb = vb_to_mvb(vbuf);
        int ndesc = cam->pix_format.sizeimage/PAGE_SIZE + 1;
 
        dma_free_coherent(cam->dev, ndesc * sizeof(struct mcam_dma_desc),
@@ -1246,14 +1267,15 @@ static int mcam_setup_vb2(struct mcam_camera *cam)
        vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
        vq->drv_priv = cam;
        vq->lock = &cam->s_mutex;
+       vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
+       vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF | VB2_READ;
+       vq->buf_struct_size = sizeof(struct mcam_vb_buffer);
        INIT_LIST_HEAD(&cam->buffers);
        switch (cam->buffer_mode) {
        case B_DMA_contig:
 #ifdef MCAM_MODE_DMA_CONTIG
                vq->ops = &mcam_vb2_ops;
                vq->mem_ops = &vb2_dma_contig_memops;
-               vq->buf_struct_size = sizeof(struct mcam_vb_buffer);
-               vq->io_modes = VB2_MMAP | VB2_USERPTR;
                cam->dma_setup = mcam_ctlr_dma_contig;
                cam->frame_complete = mcam_dma_contig_done;
                cam->vb_alloc_ctx = vb2_dma_contig_init_ctx(cam->dev);
@@ -1265,8 +1287,6 @@ static int mcam_setup_vb2(struct mcam_camera *cam)
 #ifdef MCAM_MODE_DMA_SG
                vq->ops = &mcam_vb2_sg_ops;
                vq->mem_ops = &vb2_dma_sg_memops;
-               vq->buf_struct_size = sizeof(struct mcam_vb_buffer);
-               vq->io_modes = VB2_MMAP | VB2_USERPTR;
                cam->dma_setup = mcam_ctlr_dma_sg;
                cam->frame_complete = mcam_dma_sg_done;
                cam->vb_alloc_ctx_sg = vb2_dma_sg_init_ctx(cam->dev);
@@ -1280,8 +1300,6 @@ static int mcam_setup_vb2(struct mcam_camera *cam)
                                (unsigned long) cam);
                vq->ops = &mcam_vb2_ops;
                vq->mem_ops = &vb2_vmalloc_memops;
-               vq->buf_struct_size = sizeof(struct mcam_vb_buffer);
-               vq->io_modes = VB2_MMAP;
                cam->dma_setup = mcam_ctlr_dma_vmalloc;
                cam->frame_complete = mcam_vmalloc_done;
 #endif
@@ -1292,7 +1310,6 @@ static int mcam_setup_vb2(struct mcam_camera *cam)
 
 static void mcam_cleanup_vb2(struct mcam_camera *cam)
 {
-       vb2_queue_release(&cam->vb_queue);
 #ifdef MCAM_MODE_DMA_CONTIG
        if (cam->buffer_mode == B_DMA_contig)
                vb2_dma_contig_cleanup_ctx(cam->vb_alloc_ctx);
@@ -1309,86 +1326,14 @@ static void mcam_cleanup_vb2(struct mcam_camera *cam)
  * The long list of V4L2 ioctl() operations.
  */
 
-static int mcam_vidioc_streamon(struct file *filp, void *priv,
-               enum v4l2_buf_type type)
-{
-       struct mcam_camera *cam = filp->private_data;
-       int ret;
-
-       mutex_lock(&cam->s_mutex);
-       ret = vb2_streamon(&cam->vb_queue, type);
-       mutex_unlock(&cam->s_mutex);
-       return ret;
-}
-
-
-static int mcam_vidioc_streamoff(struct file *filp, void *priv,
-               enum v4l2_buf_type type)
-{
-       struct mcam_camera *cam = filp->private_data;
-       int ret;
-
-       mutex_lock(&cam->s_mutex);
-       ret = vb2_streamoff(&cam->vb_queue, type);
-       mutex_unlock(&cam->s_mutex);
-       return ret;
-}
-
-
-static int mcam_vidioc_reqbufs(struct file *filp, void *priv,
-               struct v4l2_requestbuffers *req)
-{
-       struct mcam_camera *cam = filp->private_data;
-       int ret;
-
-       mutex_lock(&cam->s_mutex);
-       ret = vb2_reqbufs(&cam->vb_queue, req);
-       mutex_unlock(&cam->s_mutex);
-       return ret;
-}
-
-
-static int mcam_vidioc_querybuf(struct file *filp, void *priv,
-               struct v4l2_buffer *buf)
-{
-       struct mcam_camera *cam = filp->private_data;
-       int ret;
-
-       mutex_lock(&cam->s_mutex);
-       ret = vb2_querybuf(&cam->vb_queue, buf);
-       mutex_unlock(&cam->s_mutex);
-       return ret;
-}
-
-static int mcam_vidioc_qbuf(struct file *filp, void *priv,
-               struct v4l2_buffer *buf)
-{
-       struct mcam_camera *cam = filp->private_data;
-       int ret;
-
-       mutex_lock(&cam->s_mutex);
-       ret = vb2_qbuf(&cam->vb_queue, buf);
-       mutex_unlock(&cam->s_mutex);
-       return ret;
-}
-
-static int mcam_vidioc_dqbuf(struct file *filp, void *priv,
-               struct v4l2_buffer *buf)
-{
-       struct mcam_camera *cam = filp->private_data;
-       int ret;
-
-       mutex_lock(&cam->s_mutex);
-       ret = vb2_dqbuf(&cam->vb_queue, buf, filp->f_flags & O_NONBLOCK);
-       mutex_unlock(&cam->s_mutex);
-       return ret;
-}
-
 static int mcam_vidioc_querycap(struct file *file, void *priv,
                struct v4l2_capability *cap)
 {
+       struct mcam_camera *cam = video_drvdata(file);
+
        strcpy(cap->driver, "marvell_ccic");
        strcpy(cap->card, "marvell_ccic");
+       strlcpy(cap->bus_info, cam->bus_info, sizeof(cap->bus_info));
        cap->device_caps = V4L2_CAP_VIDEO_CAPTURE |
                V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
        cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
@@ -1410,36 +1355,38 @@ static int mcam_vidioc_enum_fmt_vid_cap(struct file *filp,
 static int mcam_vidioc_try_fmt_vid_cap(struct file *filp, void *priv,
                struct v4l2_format *fmt)
 {
-       struct mcam_camera *cam = priv;
+       struct mcam_camera *cam = video_drvdata(filp);
        struct mcam_format_struct *f;
        struct v4l2_pix_format *pix = &fmt->fmt.pix;
-       struct v4l2_mbus_framefmt mbus_fmt;
+       struct v4l2_subdev_pad_config pad_cfg;
+       struct v4l2_subdev_format format = {
+               .which = V4L2_SUBDEV_FORMAT_TRY,
+       };
        int ret;
 
        f = mcam_find_format(pix->pixelformat);
        pix->pixelformat = f->pixelformat;
-       v4l2_fill_mbus_format(&mbus_fmt, pix, f->mbus_code);
-       mutex_lock(&cam->s_mutex);
-       ret = sensor_call(cam, video, try_mbus_fmt, &mbus_fmt);
-       mutex_unlock(&cam->s_mutex);
-       v4l2_fill_pix_format(pix, &mbus_fmt);
+       v4l2_fill_mbus_format(&format.format, pix, f->mbus_code);
+       ret = sensor_call(cam, pad, set_fmt, &pad_cfg, &format);
+       v4l2_fill_pix_format(pix, &format.format);
+       pix->bytesperline = pix->width * f->bpp;
        switch (f->pixelformat) {
        case V4L2_PIX_FMT_YUV420:
        case V4L2_PIX_FMT_YVU420:
-               pix->bytesperline = pix->width * 3 / 2;
+               pix->sizeimage = pix->height * pix->bytesperline * 3 / 2;
                break;
        default:
-               pix->bytesperline = pix->width * f->bpp;
+               pix->sizeimage = pix->height * pix->bytesperline;
                break;
        }
-       pix->sizeimage = pix->height * pix->bytesperline;
+       pix->colorspace = V4L2_COLORSPACE_SRGB;
        return ret;
 }
 
 static int mcam_vidioc_s_fmt_vid_cap(struct file *filp, void *priv,
                struct v4l2_format *fmt)
 {
-       struct mcam_camera *cam = priv;
+       struct mcam_camera *cam = video_drvdata(filp);
        struct mcam_format_struct *f;
        int ret;
 
@@ -1447,7 +1394,7 @@ static int mcam_vidioc_s_fmt_vid_cap(struct file *filp, void *priv,
         * Can't do anything if the device is not idle
         * Also can't if there are streaming buffers in place.
         */
-       if (cam->state != S_IDLE || cam->vb_queue.num_buffers > 0)
+       if (cam->state != S_IDLE || vb2_is_busy(&cam->vb_queue))
                return -EBUSY;
 
        f = mcam_find_format(fmt->fmt.pix.pixelformat);
@@ -1462,7 +1409,6 @@ static int mcam_vidioc_s_fmt_vid_cap(struct file *filp, void *priv,
         * Now we start to change things for real, so let's do it
         * under lock.
         */
-       mutex_lock(&cam->s_mutex);
        cam->pix_format = fmt->fmt.pix;
        cam->mbus_code = f->mbus_code;
 
@@ -1476,7 +1422,6 @@ static int mcam_vidioc_s_fmt_vid_cap(struct file *filp, void *priv,
        }
        mcam_set_config_needed(cam, 1);
 out:
-       mutex_unlock(&cam->s_mutex);
        return ret;
 }
 
@@ -1488,7 +1433,7 @@ out:
 static int mcam_vidioc_g_fmt_vid_cap(struct file *filp, void *priv,
                struct v4l2_format *f)
 {
-       struct mcam_camera *cam = priv;
+       struct mcam_camera *cam = video_drvdata(filp);
 
        f->fmt.pix = cam->pix_format;
        return 0;
@@ -1504,7 +1449,6 @@ static int mcam_vidioc_enum_input(struct file *filp, void *priv,
                return -EINVAL;
 
        input->type = V4L2_INPUT_TYPE_CAMERA;
-       input->std = V4L2_STD_ALL; /* Not sure what should go here */
        strcpy(input->name, "Camera");
        return 0;
 }
@@ -1522,18 +1466,6 @@ static int mcam_vidioc_s_input(struct file *filp, void *priv, unsigned int i)
        return 0;
 }
 
-/* from vivi.c */
-static int mcam_vidioc_s_std(struct file *filp, void *priv, v4l2_std_id a)
-{
-       return 0;
-}
-
-static int mcam_vidioc_g_std(struct file *filp, void *priv, v4l2_std_id *a)
-{
-       *a = V4L2_STD_NTSC_M;
-       return 0;
-}
-
 /*
  * G/S_PARM.  Most of this is done by the sensor, but we are
  * the level which controls the number of read buffers.
@@ -1541,12 +1473,10 @@ static int mcam_vidioc_g_std(struct file *filp, void *priv, v4l2_std_id *a)
 static int mcam_vidioc_g_parm(struct file *filp, void *priv,
                struct v4l2_streamparm *parms)
 {
-       struct mcam_camera *cam = priv;
+       struct mcam_camera *cam = video_drvdata(filp);
        int ret;
 
-       mutex_lock(&cam->s_mutex);
        ret = sensor_call(cam, video, g_parm, parms);
-       mutex_unlock(&cam->s_mutex);
        parms->parm.capture.readbuffers = n_dma_bufs;
        return ret;
 }
@@ -1554,12 +1484,10 @@ static int mcam_vidioc_g_parm(struct file *filp, void *priv,
 static int mcam_vidioc_s_parm(struct file *filp, void *priv,
                struct v4l2_streamparm *parms)
 {
-       struct mcam_camera *cam = priv;
+       struct mcam_camera *cam = video_drvdata(filp);
        int ret;
 
-       mutex_lock(&cam->s_mutex);
        ret = sensor_call(cam, video, s_parm, parms);
-       mutex_unlock(&cam->s_mutex);
        parms->parm.capture.readbuffers = n_dma_bufs;
        return ret;
 }
@@ -1567,7 +1495,7 @@ static int mcam_vidioc_s_parm(struct file *filp, void *priv,
 static int mcam_vidioc_enum_framesizes(struct file *filp, void *priv,
                struct v4l2_frmsizeenum *sizes)
 {
-       struct mcam_camera *cam = priv;
+       struct mcam_camera *cam = video_drvdata(filp);
        struct mcam_format_struct *f;
        struct v4l2_subdev_frame_size_enum fse = {
                .index = sizes->index,
@@ -1579,9 +1507,7 @@ static int mcam_vidioc_enum_framesizes(struct file *filp, void *priv,
        if (f->pixelformat != sizes->pixel_format)
                return -EINVAL;
        fse.code = f->mbus_code;
-       mutex_lock(&cam->s_mutex);
        ret = sensor_call(cam, pad, enum_frame_size, NULL, &fse);
-       mutex_unlock(&cam->s_mutex);
        if (ret)
                return ret;
        if (fse.min_width == fse.max_width &&
@@ -1604,7 +1530,7 @@ static int mcam_vidioc_enum_framesizes(struct file *filp, void *priv,
 static int mcam_vidioc_enum_frameintervals(struct file *filp, void *priv,
                struct v4l2_frmivalenum *interval)
 {
-       struct mcam_camera *cam = priv;
+       struct mcam_camera *cam = video_drvdata(filp);
        struct mcam_format_struct *f;
        struct v4l2_subdev_frame_interval_enum fie = {
                .index = interval->index,
@@ -1618,9 +1544,7 @@ static int mcam_vidioc_enum_frameintervals(struct file *filp, void *priv,
        if (f->pixelformat != interval->pixel_format)
                return -EINVAL;
        fie.code = f->mbus_code;
-       mutex_lock(&cam->s_mutex);
        ret = sensor_call(cam, pad, enum_frame_interval, NULL, &fie);
-       mutex_unlock(&cam->s_mutex);
        if (ret)
                return ret;
        interval->type = V4L2_FRMIVAL_TYPE_DISCRETE;
@@ -1632,7 +1556,7 @@ static int mcam_vidioc_enum_frameintervals(struct file *filp, void *priv,
 static int mcam_vidioc_g_register(struct file *file, void *priv,
                struct v4l2_dbg_register *reg)
 {
-       struct mcam_camera *cam = priv;
+       struct mcam_camera *cam = video_drvdata(file);
 
        if (reg->reg > cam->regs_size - 4)
                return -EINVAL;
@@ -1644,7 +1568,7 @@ static int mcam_vidioc_g_register(struct file *file, void *priv,
 static int mcam_vidioc_s_register(struct file *file, void *priv,
                const struct v4l2_dbg_register *reg)
 {
-       struct mcam_camera *cam = priv;
+       struct mcam_camera *cam = video_drvdata(file);
 
        if (reg->reg > cam->regs_size - 4)
                return -EINVAL;
@@ -1662,18 +1586,20 @@ static const struct v4l2_ioctl_ops mcam_v4l_ioctl_ops = {
        .vidioc_enum_input      = mcam_vidioc_enum_input,
        .vidioc_g_input         = mcam_vidioc_g_input,
        .vidioc_s_input         = mcam_vidioc_s_input,
-       .vidioc_s_std           = mcam_vidioc_s_std,
-       .vidioc_g_std           = mcam_vidioc_g_std,
-       .vidioc_reqbufs         = mcam_vidioc_reqbufs,
-       .vidioc_querybuf        = mcam_vidioc_querybuf,
-       .vidioc_qbuf            = mcam_vidioc_qbuf,
-       .vidioc_dqbuf           = mcam_vidioc_dqbuf,
-       .vidioc_streamon        = mcam_vidioc_streamon,
-       .vidioc_streamoff       = mcam_vidioc_streamoff,
+       .vidioc_reqbufs         = vb2_ioctl_reqbufs,
+       .vidioc_create_bufs     = vb2_ioctl_create_bufs,
+       .vidioc_querybuf        = vb2_ioctl_querybuf,
+       .vidioc_qbuf            = vb2_ioctl_qbuf,
+       .vidioc_dqbuf           = vb2_ioctl_dqbuf,
+       .vidioc_expbuf          = vb2_ioctl_expbuf,
+       .vidioc_streamon        = vb2_ioctl_streamon,
+       .vidioc_streamoff       = vb2_ioctl_streamoff,
        .vidioc_g_parm          = mcam_vidioc_g_parm,
        .vidioc_s_parm          = mcam_vidioc_s_parm,
        .vidioc_enum_framesizes = mcam_vidioc_enum_framesizes,
        .vidioc_enum_frameintervals = mcam_vidioc_enum_frameintervals,
+       .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
+       .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
 #ifdef CONFIG_VIDEO_ADV_DEBUG
        .vidioc_g_register      = mcam_vidioc_g_register,
        .vidioc_s_register      = mcam_vidioc_s_register,
@@ -1687,43 +1613,36 @@ static const struct v4l2_ioctl_ops mcam_v4l_ioctl_ops = {
 static int mcam_v4l_open(struct file *filp)
 {
        struct mcam_camera *cam = video_drvdata(filp);
-       int ret = 0;
-
-       filp->private_data = cam;
+       int ret;
 
-       cam->frame_state.frames = 0;
-       cam->frame_state.singles = 0;
-       cam->frame_state.delivered = 0;
        mutex_lock(&cam->s_mutex);
-       if (cam->users == 0) {
-               ret = mcam_setup_vb2(cam);
-               if (ret)
-                       goto out;
+       ret = v4l2_fh_open(filp);
+       if (ret)
+               goto out;
+       if (v4l2_fh_is_singular_file(filp)) {
                ret = mcam_ctlr_power_up(cam);
                if (ret)
                        goto out;
                __mcam_cam_reset(cam);
                mcam_set_config_needed(cam, 1);
        }
-       (cam->users)++;
 out:
        mutex_unlock(&cam->s_mutex);
+       if (ret)
+               v4l2_fh_release(filp);
        return ret;
 }
 
 
 static int mcam_v4l_release(struct file *filp)
 {
-       struct mcam_camera *cam = filp->private_data;
+       struct mcam_camera *cam = video_drvdata(filp);
+       bool last_open;
 
-       cam_dbg(cam, "Release, %d frames, %d singles, %d delivered\n",
-                       cam->frame_state.frames, cam->frame_state.singles,
-                       cam->frame_state.delivered);
        mutex_lock(&cam->s_mutex);
-       (cam->users)--;
-       if (cam->users == 0) {
-               mcam_ctlr_stop_dma(cam);
-               mcam_cleanup_vb2(cam);
+       last_open = v4l2_fh_is_singular_file(filp);
+       _vb2_fop_release(filp, NULL);
+       if (last_open) {
                mcam_disable_mipi(cam);
                mcam_ctlr_power_down(cam);
                if (cam->buffer_mode == B_vmalloc && alloc_bufs_at_read)
@@ -1734,54 +1653,13 @@ static int mcam_v4l_release(struct file *filp)
        return 0;
 }
 
-static ssize_t mcam_v4l_read(struct file *filp,
-               char __user *buffer, size_t len, loff_t *pos)
-{
-       struct mcam_camera *cam = filp->private_data;
-       int ret;
-
-       mutex_lock(&cam->s_mutex);
-       ret = vb2_read(&cam->vb_queue, buffer, len, pos,
-                       filp->f_flags & O_NONBLOCK);
-       mutex_unlock(&cam->s_mutex);
-       return ret;
-}
-
-
-
-static unsigned int mcam_v4l_poll(struct file *filp,
-               struct poll_table_struct *pt)
-{
-       struct mcam_camera *cam = filp->private_data;
-       int ret;
-
-       mutex_lock(&cam->s_mutex);
-       ret = vb2_poll(&cam->vb_queue, filp, pt);
-       mutex_unlock(&cam->s_mutex);
-       return ret;
-}
-
-
-static int mcam_v4l_mmap(struct file *filp, struct vm_area_struct *vma)
-{
-       struct mcam_camera *cam = filp->private_data;
-       int ret;
-
-       mutex_lock(&cam->s_mutex);
-       ret = vb2_mmap(&cam->vb_queue, vma);
-       mutex_unlock(&cam->s_mutex);
-       return ret;
-}
-
-
-
 static const struct v4l2_file_operations mcam_v4l_fops = {
        .owner = THIS_MODULE,
        .open = mcam_v4l_open,
        .release = mcam_v4l_release,
-       .read = mcam_v4l_read,
-       .poll = mcam_v4l_poll,
-       .mmap = mcam_v4l_mmap,
+       .read = vb2_fop_read,
+       .poll = vb2_fop_poll,
+       .mmap = vb2_fop_mmap,
        .unlocked_ioctl = video_ioctl2,
 };
 
@@ -1792,8 +1670,6 @@ static const struct v4l2_file_operations mcam_v4l_fops = {
  */
 static struct video_device mcam_v4l_template = {
        .name = "mcam",
-       .tvnorms = V4L2_STD_NTSC_M,
-
        .fops = &mcam_v4l_fops,
        .ioctl_ops = &mcam_v4l_ioctl_ops,
        .release = video_device_release_empty,
@@ -1811,7 +1687,7 @@ static void mcam_frame_complete(struct mcam_camera *cam, int frame)
        set_bit(frame, &cam->flags);
        clear_bit(CF_DMA_ACTIVE, &cam->flags);
        cam->next_buf = frame;
-       cam->buf_seq[frame] = ++(cam->sequence);
+       cam->buf_seq[frame] = cam->sequence++;
        cam->frame_state.frames++;
        /*
         * "This should never happen"
@@ -1924,9 +1800,16 @@ int mccic_register(struct mcam_camera *cam)
        mcam_set_config_needed(cam, 1);
        cam->pix_format = mcam_def_pix_format;
        cam->mbus_code = mcam_def_mbus_code;
-       INIT_LIST_HEAD(&cam->buffers);
        mcam_ctlr_init(cam);
 
+       /*
+        * Get the v4l2 setup done.
+        */
+       ret = v4l2_ctrl_handler_init(&cam->ctrl_handler, 10);
+       if (ret)
+               goto out_unregister;
+       cam->v4l2_dev.ctrl_handler = &cam->ctrl_handler;
+
        /*
         * Try to find the sensor.
         */
@@ -1943,21 +1826,22 @@ int mccic_register(struct mcam_camera *cam)
        ret = mcam_cam_init(cam);
        if (ret)
                goto out_unregister;
-       /*
-        * Get the v4l2 setup done.
-        */
-       ret = v4l2_ctrl_handler_init(&cam->ctrl_handler, 10);
+
+       ret = mcam_setup_vb2(cam);
        if (ret)
                goto out_unregister;
-       cam->v4l2_dev.ctrl_handler = &cam->ctrl_handler;
 
        mutex_lock(&cam->s_mutex);
        cam->vdev = mcam_v4l_template;
        cam->vdev.v4l2_dev = &cam->v4l2_dev;
+       cam->vdev.lock = &cam->s_mutex;
+       cam->vdev.queue = &cam->vb_queue;
        video_set_drvdata(&cam->vdev, cam);
        ret = video_register_device(&cam->vdev, VFL_TYPE_GRABBER, -1);
-       if (ret)
-               goto out;
+       if (ret) {
+               mutex_unlock(&cam->s_mutex);
+               goto out_unregister;
+       }
 
        /*
         * If so requested, try to get our DMA buffers now.
@@ -1968,11 +1852,11 @@ int mccic_register(struct mcam_camera *cam)
                                        " will try again later.");
        }
 
-out:
-       v4l2_ctrl_handler_free(&cam->ctrl_handler);
        mutex_unlock(&cam->s_mutex);
-       return ret;
+       return 0;
+
 out_unregister:
+       v4l2_ctrl_handler_free(&cam->ctrl_handler);
        v4l2_device_unregister(&cam->v4l2_dev);
        return ret;
 }
@@ -1986,11 +1870,11 @@ void mccic_shutdown(struct mcam_camera *cam)
         * take it down again will wedge the machine, which is frowned
         * upon.
         */
-       if (cam->users > 0) {
+       if (!list_empty(&cam->vdev.fh_list)) {
                cam_warn(cam, "Removing a device with users!\n");
                mcam_ctlr_power_down(cam);
        }
-       vb2_queue_release(&cam->vb_queue);
+       mcam_cleanup_vb2(cam);
        if (cam->buffer_mode == B_vmalloc)
                mcam_free_dma_bufs(cam);
        video_unregister_device(&cam->vdev);
@@ -2006,7 +1890,7 @@ void mccic_shutdown(struct mcam_camera *cam)
 void mccic_suspend(struct mcam_camera *cam)
 {
        mutex_lock(&cam->s_mutex);
-       if (cam->users > 0) {
+       if (!list_empty(&cam->vdev.fh_list)) {
                enum mcam_state cstate = cam->state;
 
                mcam_ctlr_stop_dma(cam);
@@ -2021,7 +1905,7 @@ int mccic_resume(struct mcam_camera *cam)
        int ret = 0;
 
        mutex_lock(&cam->s_mutex);
-       if (cam->users > 0) {
+       if (!list_empty(&cam->vdev.fh_list)) {
                ret = mcam_ctlr_power_up(cam);
                if (ret) {
                        mutex_unlock(&cam->s_mutex);