[media] davinci: vpif capture: migrate driver to videobuf2
authorLad, Prabhakar <prabhakar.lad@ti.com>
Thu, 28 Jun 2012 12:28:05 +0000 (09:28 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Mon, 30 Jul 2012 22:05:29 +0000 (19:05 -0300)
This patch migrates VPIF capture driver to videobuf2 framework.

Signed-off-by: Lad, Prabhakar <prabhakar.lad@ti.com>
Signed-off-by: Manjunath Hadli <manjunath.hadli@ti.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/video/davinci/Kconfig
drivers/media/video/davinci/vpif_capture.c
drivers/media/video/davinci/vpif_capture.h

index 9337b56..c45739d 100644 (file)
@@ -14,7 +14,7 @@ config DISPLAY_DAVINCI_DM646X_EVM
 config CAPTURE_DAVINCI_DM646X_EVM
        tristate "DM646x EVM Video Capture"
        depends on VIDEO_DEV && MACH_DAVINCI_DM6467_EVM
-       select VIDEOBUF_DMA_CONTIG
+       select VIDEOBUF2_DMA_CONTIG
        select VIDEO_DAVINCI_VPIF
        help
          Support for DM6467 based capture device.
index d126fb6..1d4427a 100644 (file)
@@ -80,108 +80,45 @@ static struct vpif_config_params config_params = {
 /* global variables */
 static struct vpif_device vpif_obj = { {NULL} };
 static struct device *vpif_dev;
-
-/**
- * vpif_uservirt_to_phys : translate user/virtual address to phy address
- * @virtp: user/virtual address
- *
- * This inline function is used to convert user space virtual address to
- * physical address.
- */
-static inline u32 vpif_uservirt_to_phys(u32 virtp)
-{
-       unsigned long physp = 0;
-       struct mm_struct *mm = current->mm;
-       struct vm_area_struct *vma;
-
-       vma = find_vma(mm, virtp);
-
-       /* For kernel direct-mapped memory, take the easy way */
-       if (virtp >= PAGE_OFFSET)
-               physp = virt_to_phys((void *)virtp);
-       else if (vma && (vma->vm_flags & VM_IO) && (vma->vm_pgoff))
-               /**
-                * this will catch, kernel-allocated, mmaped-to-usermode
-                * addresses
-                */
-               physp = (vma->vm_pgoff << PAGE_SHIFT) + (virtp - vma->vm_start);
-       else {
-               /* otherwise, use get_user_pages() for general userland pages */
-               int res, nr_pages = 1;
-                       struct page *pages;
-
-               down_read(&current->mm->mmap_sem);
-
-               res = get_user_pages(current, current->mm,
-                                    virtp, nr_pages, 1, 0, &pages, NULL);
-               up_read(&current->mm->mmap_sem);
-
-               if (res == nr_pages)
-                       physp = __pa(page_address(&pages[0]) +
-                                    (virtp & ~PAGE_MASK));
-               else {
-                       vpif_err("get_user_pages failed\n");
-                       return 0;
-               }
-       }
-       return physp;
-}
+static void vpif_calculate_offsets(struct channel_obj *ch);
+static void vpif_config_addr(struct channel_obj *ch, int muxmode);
 
 /**
  * buffer_prepare :  callback function for buffer prepare
- * @q : buffer queue ptr
- * @vb: ptr to video buffer
- * @field: field info
+ * @vb: ptr to vb2_buffer
  *
- * This is the callback function for buffer prepare when videobuf_qbuf()
+ * This is the callback function for buffer prepare when vb2_qbuf()
  * function is called. The buffer is prepared and user space virtual address
  * or user address is converted into  physical address
  */
-static int vpif_buffer_prepare(struct videobuf_queue *q,
-                              struct videobuf_buffer *vb,
-                              enum v4l2_field field)
+static int vpif_buffer_prepare(struct vb2_buffer *vb)
 {
        /* Get the file handle object and channel object */
-       struct vpif_fh *fh = q->priv_data;
+       struct vpif_fh *fh = vb2_get_drv_priv(vb->vb2_queue);
+       struct vb2_queue *q = vb->vb2_queue;
        struct channel_obj *ch = fh->channel;
        struct common_obj *common;
        unsigned long addr;
 
-
        vpif_dbg(2, debug, "vpif_buffer_prepare\n");
 
        common = &ch->common[VPIF_VIDEO_INDEX];
 
-       /* If buffer is not initialized, initialize it */
-       if (VIDEOBUF_NEEDS_INIT == vb->state) {
-               vb->width = common->width;
-               vb->height = common->height;
-               vb->size = vb->width * vb->height;
-               vb->field = field;
-       }
-       vb->state = VIDEOBUF_PREPARED;
-       /**
-        * if user pointer memory mechanism is used, get the physical
-        * address of the buffer
-        */
-       if (V4L2_MEMORY_USERPTR == common->memory) {
-               if (0 == vb->baddr) {
-                       vpif_dbg(1, debug, "buffer address is 0\n");
-                       return -EINVAL;
-
-               }
-               vb->boff = vpif_uservirt_to_phys(vb->baddr);
-               if (!IS_ALIGNED(vb->boff, 8))
+       if (vb->state != VB2_BUF_STATE_ACTIVE &&
+               vb->state != VB2_BUF_STATE_PREPARED) {
+               vb2_set_plane_payload(vb, 0, common->fmt.fmt.pix.sizeimage);
+               if (vb2_plane_vaddr(vb, 0) &&
+               vb2_get_plane_payload(vb, 0) > vb2_plane_size(vb, 0))
                        goto exit;
-       }
+               addr = vb2_dma_contig_plane_dma_addr(vb, 0);
 
-       addr = vb->boff;
-       if (q->streaming) {
-               if (!IS_ALIGNED((addr + common->ytop_off), 8) ||
-                   !IS_ALIGNED((addr + common->ybtm_off), 8) ||
-                   !IS_ALIGNED((addr + common->ctop_off), 8) ||
-                   !IS_ALIGNED((addr + common->cbtm_off), 8))
-                       goto exit;
+               if (q->streaming) {
+                       if (!IS_ALIGNED((addr + common->ytop_off), 8) ||
+                               !IS_ALIGNED((addr + common->ybtm_off), 8) ||
+                               !IS_ALIGNED((addr + common->ctop_off), 8) ||
+                               !IS_ALIGNED((addr + common->cbtm_off), 8))
+                               goto exit;
+               }
        }
        return 0;
 exit:
@@ -190,66 +127,79 @@ exit:
 }
 
 /**
- * vpif_buffer_setup : Callback function for buffer setup.
- * @q: buffer queue ptr
- * @count: number of buffers
- * @size: size of the buffer
+ * vpif_buffer_queue_setup : Callback function for buffer setup.
+ * @vq: vb2_queue ptr
+ * @fmt: v4l2 format
+ * @nbuffers: ptr to number of buffers requested by application
+ * @nplanes:: contains number of distinct video planes needed to hold a frame
+ * @sizes[]: contains the size (in bytes) of each plane.
+ * @alloc_ctxs: ptr to allocation context
  *
  * This callback function is called when reqbuf() is called to adjust
  * the buffer count and buffer size
  */
-static int vpif_buffer_setup(struct videobuf_queue *q, unsigned int *count,
-                            unsigned int *size)
+static int vpif_buffer_queue_setup(struct vb2_queue *vq,
+                               const struct v4l2_format *fmt,
+                               unsigned int *nbuffers, unsigned int *nplanes,
+                               unsigned int sizes[], void *alloc_ctxs[])
 {
        /* Get the file handle object and channel object */
-       struct vpif_fh *fh = q->priv_data;
+       struct vpif_fh *fh = vb2_get_drv_priv(vq);
        struct channel_obj *ch = fh->channel;
        struct common_obj *common;
+       unsigned long size;
 
        common = &ch->common[VPIF_VIDEO_INDEX];
 
        vpif_dbg(2, debug, "vpif_buffer_setup\n");
 
        /* If memory type is not mmap, return */
-       if (V4L2_MEMORY_MMAP != common->memory)
-               return 0;
-
-       /* Calculate the size of the buffer */
-       *size = config_params.channel_bufsize[ch->channel_id];
-
-       /*
-        * Checking if the buffer size exceeds the available buffer
-        * ycmux_mode = 0 means 1 channel mode HD and
-        * ycmux_mode = 1 means 2 channels mode SD
-        */
-       if (ch->vpifparams.std_info.ycmux_mode == 0) {
-               if (config_params.video_limit[ch->channel_id])
-                       while (*size * *count > (config_params.video_limit[0]
+       if (V4L2_MEMORY_MMAP == common->memory) {
+               /* Calculate the size of the buffer */
+               size = config_params.channel_bufsize[ch->channel_id];
+               /*
+                * Checking if the buffer size exceeds the available buffer
+                * ycmux_mode = 0 means 1 channel mode HD and
+                * ycmux_mode = 1 means 2 channels mode SD
+                */
+               if (ch->vpifparams.std_info.ycmux_mode == 0) {
+                       if (config_params.video_limit[ch->channel_id])
+                               while (size * *nbuffers >
+                                       (config_params.video_limit[0]
                                                + config_params.video_limit[1]))
-                               (*count)--;
-       } else {
-               if (config_params.video_limit[ch->channel_id])
-                       while (*size * *count >
+                                       (*nbuffers)--;
+               } else {
+                       if (config_params.video_limit[ch->channel_id])
+                               while (size * *nbuffers >
                                config_params.video_limit[ch->channel_id])
-                               (*count)--;
+                                       (*nbuffers)--;
+               }
+
+       } else {
+               size = common->fmt.fmt.pix.sizeimage;
        }
 
-       if (*count < config_params.min_numbuffers)
-               *count = config_params.min_numbuffers;
+       if (*nbuffers < config_params.min_numbuffers)
+               *nbuffers = config_params.min_numbuffers;
+
+       *nplanes = 1;
+       sizes[0] = size;
+       alloc_ctxs[0] = common->alloc_ctx;
+
        return 0;
 }
 
 /**
  * vpif_buffer_queue : Callback function to add buffer to DMA queue
- * @q: ptr to videobuf_queue
- * @vb: ptr to videobuf_buffer
+ * @vb: ptr to vb2_buffer
  */
-static void vpif_buffer_queue(struct videobuf_queue *q,
-                             struct videobuf_buffer *vb)
+static void vpif_buffer_queue(struct vb2_buffer *vb)
 {
        /* Get the file handle object and channel object */
-       struct vpif_fh *fh = q->priv_data;
+       struct vpif_fh *fh = vb2_get_drv_priv(vb->vb2_queue);
        struct channel_obj *ch = fh->channel;
+       struct vpif_cap_buffer *buf = container_of(vb,
+                               struct vpif_cap_buffer, vb);
        struct common_obj *common;
 
        common = &ch->common[VPIF_VIDEO_INDEX];
@@ -257,43 +207,189 @@ static void vpif_buffer_queue(struct videobuf_queue *q,
        vpif_dbg(2, debug, "vpif_buffer_queue\n");
 
        /* add the buffer to the DMA queue */
-       list_add_tail(&vb->queue, &common->dma_queue);
-       /* Change state of the buffer */
-       vb->state = VIDEOBUF_QUEUED;
+       list_add_tail(&buf->list, &common->dma_queue);
 }
 
 /**
- * vpif_buffer_release : Callback function to free buffer
- * @q: buffer queue ptr
- * @vb: ptr to video buffer
+ * vpif_buf_cleanup : Callback function to free buffer
+ * @vb: ptr to vb2_buffer
  *
- * This function is called from the videobuf layer to free memory
+ * This function is called from the videobuf2 layer to free memory
  * allocated to  the buffers
  */
-static void vpif_buffer_release(struct videobuf_queue *q,
-                               struct videobuf_buffer *vb)
+static void vpif_buf_cleanup(struct vb2_buffer *vb)
 {
        /* Get the file handle object and channel object */
-       struct vpif_fh *fh = q->priv_data;
+       struct vpif_fh *fh = vb2_get_drv_priv(vb->vb2_queue);
+       struct vpif_cap_buffer *buf = container_of(vb,
+                                       struct vpif_cap_buffer, vb);
        struct channel_obj *ch = fh->channel;
        struct common_obj *common;
+       unsigned long flags;
 
        common = &ch->common[VPIF_VIDEO_INDEX];
 
-       videobuf_dma_contig_free(q, vb);
-       vb->state = VIDEOBUF_NEEDS_INIT;
+       spin_lock_irqsave(&common->irqlock, flags);
+       if (vb->state == VB2_BUF_STATE_ACTIVE)
+               list_del_init(&buf->list);
+       spin_unlock_irqrestore(&common->irqlock, flags);
+
 }
 
-static struct videobuf_queue_ops video_qops = {
-       .buf_setup = vpif_buffer_setup,
-       .buf_prepare = vpif_buffer_prepare,
-       .buf_queue = vpif_buffer_queue,
-       .buf_release = vpif_buffer_release,
-};
+static void vpif_wait_prepare(struct vb2_queue *vq)
+{
+       struct vpif_fh *fh = vb2_get_drv_priv(vq);
+       struct channel_obj *ch = fh->channel;
+       struct common_obj *common;
+
+       common = &ch->common[VPIF_VIDEO_INDEX];
+       mutex_unlock(&common->lock);
+}
+
+static void vpif_wait_finish(struct vb2_queue *vq)
+{
+       struct vpif_fh *fh = vb2_get_drv_priv(vq);
+       struct channel_obj *ch = fh->channel;
+       struct common_obj *common;
+
+       common = &ch->common[VPIF_VIDEO_INDEX];
+       mutex_lock(&common->lock);
+}
+
+static int vpif_buffer_init(struct vb2_buffer *vb)
+{
+       struct vpif_cap_buffer *buf = container_of(vb,
+                                       struct vpif_cap_buffer, vb);
+
+       INIT_LIST_HEAD(&buf->list);
+
+       return 0;
+}
 
 static u8 channel_first_int[VPIF_NUMBER_OF_OBJECTS][2] =
        { {1, 1} };
 
+static int vpif_start_streaming(struct vb2_queue *vq, unsigned int count)
+{
+       struct vpif_capture_config *vpif_config_data =
+                                       vpif_dev->platform_data;
+       struct vpif_fh *fh = vb2_get_drv_priv(vq);
+       struct channel_obj *ch = fh->channel;
+       struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
+       struct vpif_params *vpif = &ch->vpifparams;
+       unsigned long addr = 0;
+       int ret;
+
+               /* If buffer queue is empty, return error */
+       if (list_empty(&common->dma_queue)) {
+               vpif_dbg(1, debug, "buffer queue is empty\n");
+               return -EIO;
+       }
+
+       /* Get the next frame from the buffer queue */
+       common->cur_frm = common->next_frm = list_entry(common->dma_queue.next,
+                                   struct vpif_cap_buffer, list);
+       /* Remove buffer from the buffer queue */
+       list_del(&common->cur_frm->list);
+       /* Mark state of the current frame to active */
+       common->cur_frm->vb.state = VB2_BUF_STATE_ACTIVE;
+       /* Initialize field_id and started member */
+       ch->field_id = 0;
+       common->started = 1;
+       addr = vb2_dma_contig_plane_dma_addr(&common->cur_frm->vb, 0);
+
+       /* Calculate the offset for Y and C data in the buffer */
+       vpif_calculate_offsets(ch);
+
+       if ((vpif->std_info.frm_fmt &&
+           ((common->fmt.fmt.pix.field != V4L2_FIELD_NONE) &&
+            (common->fmt.fmt.pix.field != V4L2_FIELD_ANY))) ||
+           (!vpif->std_info.frm_fmt &&
+            (common->fmt.fmt.pix.field == V4L2_FIELD_NONE))) {
+               vpif_dbg(1, debug, "conflict in field format and std format\n");
+               return -EINVAL;
+       }
+
+       /* configure 1 or 2 channel mode */
+       ret = vpif_config_data->setup_input_channel_mode
+                                       (vpif->std_info.ycmux_mode);
+
+       if (ret < 0) {
+               vpif_dbg(1, debug, "can't set vpif channel mode\n");
+               return ret;
+       }
+
+       /* Call vpif_set_params function to set the parameters and addresses */
+       ret = vpif_set_video_params(vpif, ch->channel_id);
+
+       if (ret < 0) {
+               vpif_dbg(1, debug, "can't set video params\n");
+               return ret;
+       }
+
+       common->started = ret;
+       vpif_config_addr(ch, ret);
+
+       common->set_addr(addr + common->ytop_off,
+                        addr + common->ybtm_off,
+                        addr + common->ctop_off,
+                        addr + common->cbtm_off);
+
+       /**
+        * Set interrupt for both the fields in VPIF Register enable channel in
+        * VPIF register
+        */
+       if ((VPIF_CHANNEL0_VIDEO == ch->channel_id)) {
+               channel0_intr_assert();
+               channel0_intr_enable(1);
+               enable_channel0(1);
+       }
+       if ((VPIF_CHANNEL1_VIDEO == ch->channel_id) ||
+           (common->started == 2)) {
+               channel1_intr_assert();
+               channel1_intr_enable(1);
+               enable_channel1(1);
+       }
+       channel_first_int[VPIF_VIDEO_INDEX][ch->channel_id] = 1;
+
+       return 0;
+}
+
+/* abort streaming and wait for last buffer */
+static int vpif_stop_streaming(struct vb2_queue *vq)
+{
+       struct vpif_fh *fh = vb2_get_drv_priv(vq);
+       struct channel_obj *ch = fh->channel;
+       struct common_obj *common;
+
+       if (!vb2_is_streaming(vq))
+               return 0;
+
+       common = &ch->common[VPIF_VIDEO_INDEX];
+
+       /* release all active buffers */
+       while (!list_empty(&common->dma_queue)) {
+               common->next_frm = list_entry(common->dma_queue.next,
+                                               struct vpif_cap_buffer, list);
+               list_del(&common->next_frm->list);
+               vb2_buffer_done(&common->next_frm->vb, VB2_BUF_STATE_ERROR);
+       }
+
+       return 0;
+}
+
+static struct vb2_ops video_qops = {
+       .queue_setup            = vpif_buffer_queue_setup,
+       .wait_prepare           = vpif_wait_prepare,
+       .wait_finish            = vpif_wait_finish,
+       .buf_init               = vpif_buffer_init,
+       .buf_prepare            = vpif_buffer_prepare,
+       .start_streaming        = vpif_start_streaming,
+       .stop_streaming         = vpif_stop_streaming,
+       .buf_cleanup            = vpif_buf_cleanup,
+       .buf_queue              = vpif_buffer_queue,
+};
+
 /**
  * vpif_process_buffer_complete: process a completed buffer
  * @common: ptr to common channel object
@@ -304,9 +400,9 @@ static u8 channel_first_int[VPIF_NUMBER_OF_OBJECTS][2] =
  */
 static void vpif_process_buffer_complete(struct common_obj *common)
 {
-       do_gettimeofday(&common->cur_frm->ts);
-       common->cur_frm->state = VIDEOBUF_DONE;
-       wake_up_interruptible(&common->cur_frm->done);
+       do_gettimeofday(&common->cur_frm->vb.v4l2_buf.timestamp);
+       vb2_buffer_done(&common->cur_frm->vb,
+                                           VB2_BUF_STATE_DONE);
        /* Make curFrm pointing to nextFrm */
        common->cur_frm = common->next_frm;
 }
@@ -324,14 +420,11 @@ static void vpif_schedule_next_buffer(struct common_obj *common)
        unsigned long addr = 0;
 
        common->next_frm = list_entry(common->dma_queue.next,
-                                    struct videobuf_buffer, queue);
+                                    struct vpif_cap_buffer, list);
        /* Remove that buffer from the buffer queue */
-       list_del(&common->next_frm->queue);
-       common->next_frm->state = VIDEOBUF_ACTIVE;
-       if (V4L2_MEMORY_USERPTR == common->memory)
-               addr = common->next_frm->boff;
-       else
-               addr = videobuf_to_dma_contig(common->next_frm);
+       list_del(&common->next_frm->list);
+       common->next_frm->vb.state = VB2_BUF_STATE_ACTIVE;
+       addr = vb2_dma_contig_plane_dma_addr(&common->next_frm->vb, 0);
 
        /* Set top and bottom field addresses in VPIF registers */
        common->set_addr(addr + common->ytop_off,
@@ -505,10 +598,7 @@ static void vpif_calculate_offsets(struct channel_obj *ch)
        } else
                vid_ch->buf_field = common->fmt.fmt.pix.field;
 
-       if (V4L2_MEMORY_USERPTR == common->memory)
-               sizeimage = common->fmt.fmt.pix.sizeimage;
-       else
-               sizeimage = config_params.channel_bufsize[ch->channel_id];
+       sizeimage = common->fmt.fmt.pix.sizeimage;
 
        hpitch = common->fmt.fmt.pix.bytesperline;
        vpitch = sizeimage / (hpitch * 2);
@@ -660,10 +750,7 @@ static int vpif_check_format(struct channel_obj *ch,
                hpitch = vpif_params->std_info.width;
        }
 
-       if (V4L2_MEMORY_USERPTR == common->memory)
-               sizeimage = pixfmt->sizeimage;
-       else
-               sizeimage = config_params.channel_bufsize[ch->channel_id];
+       sizeimage = pixfmt->sizeimage;
 
        vpitch = sizeimage / (hpitch * 2);
 
@@ -736,7 +823,7 @@ static int vpif_mmap(struct file *filep, struct vm_area_struct *vma)
 
        vpif_dbg(2, debug, "vpif_mmap\n");
 
-       return videobuf_mmap_mapper(&common->buffer_queue, vma);
+       return vb2_mmap(&common->buffer_queue, vma);
 }
 
 /**
@@ -753,7 +840,7 @@ static unsigned int vpif_poll(struct file *filep, poll_table * wait)
        vpif_dbg(2, debug, "vpif_poll\n");
 
        if (common->started)
-               return videobuf_poll_stream(filep, &common->buffer_queue, wait);
+               return vb2_poll(&common->buffer_queue, filep, wait);
        return 0;
 }
 
@@ -861,8 +948,8 @@ static int vpif_release(struct file *filep)
                }
                common->started = 0;
                /* Free buffers allocated */
-               videobuf_queue_cancel(&common->buffer_queue);
-               videobuf_mmap_free(&common->buffer_queue);
+               vb2_queue_release(&common->buffer_queue);
+               vb2_dma_contig_cleanup_ctx(common->alloc_ctx);
        }
 
        /* Decrement channel usrs counter */
@@ -892,6 +979,7 @@ static int vpif_reqbufs(struct file *file, void *priv,
        struct channel_obj *ch = fh->channel;
        struct common_obj *common;
        u8 index = 0;
+       struct vb2_queue *q;
 
        vpif_dbg(2, debug, "vpif_reqbufs\n");
 
@@ -917,14 +1005,21 @@ static int vpif_reqbufs(struct file *file, void *priv,
        if (0 != common->io_usrs)
                return -EBUSY;
 
-       /* Initialize videobuf queue as per the buffer type */
-       videobuf_queue_dma_contig_init(&common->buffer_queue,
-                                           &video_qops, vpif_dev,
-                                           &common->irqlock,
-                                           reqbuf->type,
-                                           common->fmt.fmt.pix.field,
-                                           sizeof(struct videobuf_buffer), fh,
-                                           &common->lock);
+       /* Initialize videobuf2 queue as per the buffer type */
+       common->alloc_ctx = vb2_dma_contig_init_ctx(vpif_dev);
+       if (!common->alloc_ctx) {
+               vpif_err("Failed to get the context\n");
+               return -EINVAL;
+       }
+       q = &common->buffer_queue;
+       q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+       q->io_modes = VB2_MMAP | VB2_USERPTR;
+       q->drv_priv = fh;
+       q->ops = &video_qops;
+       q->mem_ops = &vb2_dma_contig_memops;
+       q->buf_struct_size = sizeof(struct vpif_cap_buffer);
+
+       vb2_queue_init(q);
 
        /* Set io allowed member of file handle to TRUE */
        fh->io_allowed[index] = 1;
@@ -935,7 +1030,7 @@ static int vpif_reqbufs(struct file *file, void *priv,
        INIT_LIST_HEAD(&common->dma_queue);
 
        /* Allocate buffers */
-       return videobuf_reqbufs(&common->buffer_queue, reqbuf);
+       return vb2_reqbufs(&common->buffer_queue, reqbuf);
 }
 
 /**
@@ -961,7 +1056,7 @@ static int vpif_querybuf(struct file *file, void *priv,
                return -EINVAL;
        }
 
-       return videobuf_querybuf(&common->buffer_queue, buf);
+       return vb2_querybuf(&common->buffer_queue, buf);
 }
 
 /**
@@ -977,10 +1072,6 @@ static int vpif_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
        struct channel_obj *ch = fh->channel;
        struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
        struct v4l2_buffer tbuf = *buf;
-       struct videobuf_buffer *buf1;
-       unsigned long addr = 0;
-       unsigned long flags;
-       int ret = 0;
 
        vpif_dbg(2, debug, "vpif_qbuf\n");
 
@@ -990,76 +1081,11 @@ static int vpif_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
        }
 
        if (!fh->io_allowed[VPIF_VIDEO_INDEX]) {
-               vpif_err("fh io not allowed \n");
+               vpif_err("fh io not allowed\n");
                return -EACCES;
        }
 
-       if (!(list_empty(&common->dma_queue)) ||
-           (common->cur_frm != common->next_frm) ||
-           !common->started ||
-           (common->started && (0 == ch->field_id)))
-               return videobuf_qbuf(&common->buffer_queue, buf);
-
-       /* bufferqueue is empty store buffer address in VPIF registers */
-       mutex_lock(&common->buffer_queue.vb_lock);
-       buf1 = common->buffer_queue.bufs[tbuf.index];
-
-       if ((buf1->state == VIDEOBUF_QUEUED) ||
-           (buf1->state == VIDEOBUF_ACTIVE)) {
-               vpif_err("invalid state\n");
-               goto qbuf_exit;
-       }
-
-       switch (buf1->memory) {
-       case V4L2_MEMORY_MMAP:
-               if (buf1->baddr == 0)
-                       goto qbuf_exit;
-               break;
-
-       case V4L2_MEMORY_USERPTR:
-               if (tbuf.length < buf1->bsize)
-                       goto qbuf_exit;
-
-               if ((VIDEOBUF_NEEDS_INIT != buf1->state)
-                           && (buf1->baddr != tbuf.m.userptr)) {
-                       vpif_buffer_release(&common->buffer_queue, buf1);
-                       buf1->baddr = tbuf.m.userptr;
-               }
-               break;
-
-       default:
-               goto qbuf_exit;
-       }
-
-       local_irq_save(flags);
-       ret = vpif_buffer_prepare(&common->buffer_queue, buf1,
-                                       common->buffer_queue.field);
-       if (ret < 0) {
-               local_irq_restore(flags);
-               goto qbuf_exit;
-       }
-
-       buf1->state = VIDEOBUF_ACTIVE;
-
-       if (V4L2_MEMORY_USERPTR == common->memory)
-               addr = buf1->boff;
-       else
-               addr = videobuf_to_dma_contig(buf1);
-
-       common->next_frm = buf1;
-       common->set_addr(addr + common->ytop_off,
-                        addr + common->ybtm_off,
-                        addr + common->ctop_off,
-                        addr + common->cbtm_off);
-
-       local_irq_restore(flags);
-       list_add_tail(&buf1->stream, &common->buffer_queue.stream);
-       mutex_unlock(&common->buffer_queue.vb_lock);
-       return 0;
-
-qbuf_exit:
-       mutex_unlock(&common->buffer_queue.vb_lock);
-       return -EINVAL;
+       return vb2_qbuf(&common->buffer_queue, buf);
 }
 
 /**
@@ -1076,8 +1102,8 @@ static int vpif_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
 
        vpif_dbg(2, debug, "vpif_dqbuf\n");
 
-       return videobuf_dqbuf(&common->buffer_queue, buf,
-                                       file->f_flags & O_NONBLOCK);
+       return vb2_dqbuf(&common->buffer_queue, buf,
+                        (file->f_flags & O_NONBLOCK));
 }
 
 /**
@@ -1090,13 +1116,11 @@ static int vpif_streamon(struct file *file, void *priv,
                                enum v4l2_buf_type buftype)
 {
 
-       struct vpif_capture_config *config = vpif_dev->platform_data;
        struct vpif_fh *fh = priv;
        struct channel_obj *ch = fh->channel;
        struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
        struct channel_obj *oth_ch = vpif_obj.dev[!ch->channel_id];
        struct vpif_params *vpif;
-       unsigned long addr = 0;
        int ret = 0;
 
        vpif_dbg(2, debug, "vpif_streamon\n");
@@ -1142,95 +1166,13 @@ static int vpif_streamon(struct file *file, void *priv,
                return ret;
        }
 
-       /* Call videobuf_streamon to start streaming in videobuf */
-       ret = videobuf_streamon(&common->buffer_queue);
+       /* Call vb2_streamon to start streaming in videobuf2 */
+       ret = vb2_streamon(&common->buffer_queue, buftype);
        if (ret) {
-               vpif_dbg(1, debug, "videobuf_streamon\n");
+               vpif_dbg(1, debug, "vb2_streamon\n");
                return ret;
        }
 
-       /* If buffer queue is empty, return error */
-       if (list_empty(&common->dma_queue)) {
-               vpif_dbg(1, debug, "buffer queue is empty\n");
-               ret = -EIO;
-               goto exit;
-       }
-
-       /* Get the next frame from the buffer queue */
-       common->cur_frm = list_entry(common->dma_queue.next,
-                                   struct videobuf_buffer, queue);
-       common->next_frm = common->cur_frm;
-
-       /* Remove buffer from the buffer queue */
-       list_del(&common->cur_frm->queue);
-       /* Mark state of the current frame to active */
-       common->cur_frm->state = VIDEOBUF_ACTIVE;
-       /* Initialize field_id and started member */
-       ch->field_id = 0;
-       common->started = 1;
-
-       if (V4L2_MEMORY_USERPTR == common->memory)
-               addr = common->cur_frm->boff;
-       else
-               addr = videobuf_to_dma_contig(common->cur_frm);
-
-       /* Calculate the offset for Y and C data in the buffer */
-       vpif_calculate_offsets(ch);
-
-       if ((vpif->std_info.frm_fmt &&
-           ((common->fmt.fmt.pix.field != V4L2_FIELD_NONE) &&
-            (common->fmt.fmt.pix.field != V4L2_FIELD_ANY))) ||
-           (!vpif->std_info.frm_fmt &&
-            (common->fmt.fmt.pix.field == V4L2_FIELD_NONE))) {
-               vpif_dbg(1, debug, "conflict in field format and std format\n");
-               ret = -EINVAL;
-               goto exit;
-       }
-
-       /* configure 1 or 2 channel mode */
-       ret = config->setup_input_channel_mode(vpif->std_info.ycmux_mode);
-
-       if (ret < 0) {
-               vpif_dbg(1, debug, "can't set vpif channel mode\n");
-               goto exit;
-       }
-
-       /* Call vpif_set_params function to set the parameters and addresses */
-       ret = vpif_set_video_params(vpif, ch->channel_id);
-
-       if (ret < 0) {
-               vpif_dbg(1, debug, "can't set video params\n");
-               goto exit;
-       }
-
-       common->started = ret;
-       vpif_config_addr(ch, ret);
-
-       common->set_addr(addr + common->ytop_off,
-                        addr + common->ybtm_off,
-                        addr + common->ctop_off,
-                        addr + common->cbtm_off);
-
-       /**
-        * Set interrupt for both the fields in VPIF Register enable channel in
-        * VPIF register
-        */
-       if ((VPIF_CHANNEL0_VIDEO == ch->channel_id)) {
-               channel0_intr_assert();
-               channel0_intr_enable(1);
-               enable_channel0(1);
-       }
-       if ((VPIF_CHANNEL1_VIDEO == ch->channel_id) ||
-           (common->started == 2)) {
-               channel1_intr_assert();
-               channel1_intr_enable(1);
-               enable_channel1(1);
-       }
-       channel_first_int[VPIF_VIDEO_INDEX][ch->channel_id] = 1;
-       return ret;
-
-exit:
-       videobuf_streamoff(&common->buffer_queue);
        return ret;
 }
 
@@ -1285,7 +1227,7 @@ static int vpif_streamoff(struct file *file, void *priv,
        if (ret && (ret != -ENOIOCTLCMD))
                vpif_dbg(1, debug, "stream off failed in subdev\n");
 
-       return videobuf_streamoff(&common->buffer_queue);
+       return vb2_streamoff(&common->buffer_queue, buftype);
 }
 
 /**
index 8095910..3511510 100644 (file)
@@ -26,7 +26,7 @@
 #include <media/v4l2-common.h>
 #include <media/v4l2-device.h>
 #include <media/videobuf-core.h>
-#include <media/videobuf-dma-contig.h>
+#include <media/videobuf2-dma-contig.h>
 #include <media/davinci/vpif_types.h>
 
 #include "vpif.h"
@@ -60,11 +60,16 @@ struct video_obj {
        u32 input_idx;
 };
 
+struct vpif_cap_buffer {
+       struct vb2_buffer vb;
+       struct list_head list;
+};
+
 struct common_obj {
        /* Pointer pointing to current v4l2_buffer */
-       struct videobuf_buffer *cur_frm;
+       struct vpif_cap_buffer *cur_frm;
        /* Pointer pointing to current v4l2_buffer */
-       struct videobuf_buffer *next_frm;
+       struct vpif_cap_buffer *next_frm;
        /*
         * This field keeps track of type of buffer exchange mechanism
         * user has selected
@@ -73,7 +78,9 @@ struct common_obj {
        /* Used to store pixel format */
        struct v4l2_format fmt;
        /* Buffer queue used in video-buf */
-       struct videobuf_queue buffer_queue;
+       struct vb2_queue buffer_queue;
+       /* allocator-specific contexts for each plane */
+       struct vb2_alloc_ctx *alloc_ctx;
        /* Queue of filled frames */
        struct list_head dma_queue;
        /* Used in video-buf */