[media] V4L: sh_mobile_ceu_camera: fix field addresses in interleaved mode
authorGuennadi Liakhovetski <g.liakhovetski@gmx.de>
Tue, 26 Jul 2011 14:03:37 +0000 (11:03 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Thu, 3 Nov 2011 20:27:10 +0000 (18:27 -0200)
In interlaced interleaved mode field offset for deinterlacing depends
on the pixel format.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/video/sh_mobile_ceu_camera.c

index b44f318..7841fde 100644 (file)
@@ -267,6 +267,7 @@ static int sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
        unsigned long top1, top2;
        unsigned long bottom1, bottom2;
        u32 status;
+       bool planar;
        int ret = 0;
 
        /*
@@ -314,17 +315,29 @@ static int sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
 
        phys_addr_top = vb2_dma_contig_plane_dma_addr(pcdev->active, 0);
 
-       ceu_write(pcdev, top1, phys_addr_top);
-       if (V4L2_FIELD_NONE != pcdev->field) {
-               phys_addr_bottom = phys_addr_top + icd->user_width;
-               ceu_write(pcdev, bottom1, phys_addr_bottom);
-       }
-
        switch (icd->current_fmt->host_fmt->fourcc) {
        case V4L2_PIX_FMT_NV12:
        case V4L2_PIX_FMT_NV21:
        case V4L2_PIX_FMT_NV16:
        case V4L2_PIX_FMT_NV61:
+               planar = true;
+               break;
+       default:
+               planar = false;
+       }
+
+       ceu_write(pcdev, top1, phys_addr_top);
+       if (V4L2_FIELD_NONE != pcdev->field) {
+               if (planar)
+                       phys_addr_bottom = phys_addr_top + icd->user_width;
+               else
+                       phys_addr_bottom = phys_addr_top +
+                               soc_mbus_bytes_per_line(icd->user_width,
+                                                       icd->current_fmt->host_fmt);
+               ceu_write(pcdev, bottom1, phys_addr_bottom);
+       }
+
+       if (planar) {
                phys_addr_top += icd->user_width *
                        icd->user_height;
                ceu_write(pcdev, top2, phys_addr_top);