Web lists-archives.com

[PATCH 3/4] soc-camera: sh_mobile_ceu: Add V4L2_FIELD_INTERLACED_BT/TB support




Signed-off-by: Kuninori Morimoto <morimoto.kuninori@xxxxxxxxxxx>
---
 drivers/media/video/sh_mobile_ceu_camera.c |   52 ++++++++++++++++++++++-----
 1 files changed, 42 insertions(+), 10 deletions(-)

diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c
index 3e7a148..92812e5 100644
--- a/drivers/media/video/sh_mobile_ceu_camera.c
+++ b/drivers/media/video/sh_mobile_ceu_camera.c
@@ -104,7 +104,10 @@ struct sh_mobile_ceu_dev {
 
 	u32 cflcr;
 
-	unsigned int is_interlaced:1;
+	unsigned int is_interlaced;
+#define TOP_ITL 1	/* 1: interlace top field start */
+#define BTM_ITL 2	/* 2: interlace bottom field start */
+
 	unsigned int image_mode:1;
 	unsigned int is_16bit:1;
 };
@@ -247,6 +250,8 @@ static int sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
 {
 	struct soc_camera_device *icd = pcdev->icd;
 	dma_addr_t phys_addr_top, phys_addr_bottom;
+	unsigned long top1, top2;
+	unsigned long bottom1, bottom2;
 	u32 status;
 	int ret = 0;
 
@@ -275,11 +280,23 @@ static int sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
 	if (!pcdev->active)
 		return ret;
 
+	if (BTM_ITL == pcdev->is_interlaced) {
+		top1	= CDBYR;
+		top2	= CDBCR;
+		bottom1	= CDAYR;
+		bottom2	= CDACR;
+	} else {
+		top1	= CDAYR;
+		top2	= CDACR;
+		bottom1	= CDBYR;
+		bottom2	= CDBCR;
+	}
+
 	phys_addr_top = videobuf_to_dma_contig(pcdev->active);
-	ceu_write(pcdev, CDAYR, phys_addr_top);
+	ceu_write(pcdev, top1, phys_addr_top);
 	if (pcdev->is_interlaced) {
 		phys_addr_bottom = phys_addr_top + icd->user_width;
-		ceu_write(pcdev, CDBYR, phys_addr_bottom);
+		ceu_write(pcdev, bottom1, phys_addr_bottom);
 	}
 
 	switch (icd->current_fmt->fourcc) {
@@ -289,11 +306,10 @@ static int sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
 	case V4L2_PIX_FMT_NV61:
 		phys_addr_top += icd->user_width *
 			icd->user_height;
-		ceu_write(pcdev, CDACR, phys_addr_top);
+		ceu_write(pcdev, top2, phys_addr_top);
 		if (pcdev->is_interlaced) {
-			phys_addr_bottom = phys_addr_top +
-				icd->user_width;
-			ceu_write(pcdev, CDBCR, phys_addr_bottom);
+			phys_addr_bottom = phys_addr_top + icd->user_width;
+			ceu_write(pcdev, bottom2, phys_addr_bottom);
 		}
 	}
 
@@ -706,7 +722,19 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
 	ceu_write(pcdev, CAMCR, value);
 
 	ceu_write(pcdev, CAPCR, 0x00300000);
-	ceu_write(pcdev, CAIFR, pcdev->is_interlaced ? 0x101 : 0);
+
+	switch (pcdev->is_interlaced) {
+	case TOP_ITL:
+		value = 0x101;
+		break;
+	case BTM_ITL:
+		value = 0x102;
+		break;
+	default:
+		value = 0;
+		break;
+	}
+	ceu_write(pcdev, CAIFR, value);
 
 	sh_mobile_ceu_set_rect(icd, icd->user_width, icd->user_height);
 	mdelay(1);
@@ -1388,14 +1416,18 @@ static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd,
 
 	switch (pix->field) {
 	case V4L2_FIELD_INTERLACED:
-		is_interlaced = true;
+	case V4L2_FIELD_INTERLACED_TB:
+		is_interlaced = TOP_ITL;
+		break;
+	case V4L2_FIELD_INTERLACED_BT:
+		is_interlaced = BTM_ITL;
 		break;
 	case V4L2_FIELD_ANY:
 	default:
 		pix->field = V4L2_FIELD_NONE;
 		/* fall-through */
 	case V4L2_FIELD_NONE:
-		is_interlaced = false;
+		is_interlaced = 0;
 		break;
 	}
 
-- 
1.6.0.4

--
video4linux-list mailing list
Unsubscribe mailto:video4linux-list-request@xxxxxxxxxx?subject=unsubscribe
https://www.redhat.com/mailman/listinfo/video4linux-list