From mboxrd@z Thu Jan 1 00:00:00 1970 Return-path: Received: from mx3.redhat.com (mx3.redhat.com [172.16.48.32]) by int-mx1.corp.redhat.com (8.13.1/8.13.1) with ESMTP id mBB0heRB021252 for ; Wed, 10 Dec 2008 19:43:40 -0500 Received: from mail06.idc.renesas.com (mail.renesas.com [202.234.163.13]) by mx3.redhat.com (8.13.8/8.13.8) with ESMTP id mBB0h5au018588 for ; Wed, 10 Dec 2008 19:43:06 -0500 Date: Thu, 11 Dec 2008 09:02:09 +0900 From: Kuninori Morimoto To: Guennadi Liakhovetski Message-id: MIME-version: 1.0 (generated by SEMI 1.14.6 - "Maruoka") Content-type: text/plain; charset=US-ASCII Cc: V4L-Linux Subject: [PATCH] Add interlace support to sh_mobile_ceu_camera.c List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: video4linux-list-bounces@redhat.com Errors-To: video4linux-list-bounces@redhat.com List-ID: Signed-off-by: Kuninori Morimoto --- This patch needs Magnus's "nv1x/nvx1 support for the sh_mobile_ceu driver" patch drivers/media/video/sh_mobile_ceu_camera.c | 47 ++++++++++++++++++++++------ 1 files changed, 37 insertions(+), 10 deletions(-) diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c index 5701363..13addd8 100644 --- a/drivers/media/video/sh_mobile_ceu_camera.c +++ b/drivers/media/video/sh_mobile_ceu_camera.c @@ -97,6 +97,7 @@ struct sh_mobile_ceu_dev { spinlock_t lock; struct list_head capture; struct videobuf_buffer *active; + int is_interlace; struct sh_mobile_ceu_info *pdata; @@ -161,7 +162,7 @@ static void free_buffer(struct videobuf_queue *vq, static void sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev) { struct soc_camera_device *icd = pcdev->icd; - unsigned long phys_addr; + unsigned long phys_addr_t, phys_addr_b = 0; ceu_write(pcdev, CEIER, ceu_read(pcdev, CEIER) & ~1); ceu_write(pcdev, CETCR, ~ceu_read(pcdev, CETCR) & 0x0317f313); @@ -174,16 +175,25 @@ static void sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev) if (!pcdev->active) return; - phys_addr = videobuf_to_dma_contig(pcdev->active); - ceu_write(pcdev, CDAYR, phys_addr); + phys_addr_t = videobuf_to_dma_contig(pcdev->active); + ceu_write(pcdev, CDAYR, phys_addr_t); + if (pcdev->is_interlace) { + phys_addr_b = phys_addr_t + icd->width; + ceu_write(pcdev, CDBYR, phys_addr_b); + } + switch (icd->current_fmt->fourcc) { case V4L2_PIX_FMT_NV12: case V4L2_PIX_FMT_NV21: case V4L2_PIX_FMT_NV16: case V4L2_PIX_FMT_NV61: - phys_addr += (icd->width * icd->height); - ceu_write(pcdev, CDACR, phys_addr); + phys_addr_t += (icd->width * icd->height); + ceu_write(pcdev, CDACR, phys_addr_t); + if (pcdev->is_interlace) { + phys_addr_b += (icd->width * icd->height); + ceu_write(pcdev, CDBCR, phys_addr_b); + } } pcdev->active->state = VIDEOBUF_ACTIVE; @@ -379,7 +389,7 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd, { struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); struct sh_mobile_ceu_dev *pcdev = ici->priv; - int ret, buswidth, width, cfszr_width, cdwdr_width; + int ret, buswidth, width, height, cfszr_width, cdwdr_width; unsigned long camera_flags, common_flags, value; int yuv_mode, yuv_lineskip; @@ -446,7 +456,7 @@ 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, 0); + ceu_write(pcdev, CAIFR, (pcdev->is_interlace) ? 0x101 : 0); mdelay(1); @@ -461,10 +471,16 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd, cdwdr_width = (buswidth == 16) ? width * 2 : width; } + height = icd->height; + if (pcdev->is_interlace) { + height /= 2; + cdwdr_width *= 2; + } + ceu_write(pcdev, CAMOR, 0); - ceu_write(pcdev, CAPWR, (icd->height << 16) | width); + ceu_write(pcdev, CAPWR, (height << 16) | width); ceu_write(pcdev, CFLCR, 0); /* no scaling */ - ceu_write(pcdev, CFSZR, (icd->height << 16) | cfszr_width); + ceu_write(pcdev, CFSZR, (height << 16) | cfszr_width); ceu_write(pcdev, CLFCR, 0); /* no lowpass filter */ /* A few words about byte order (observed in Big Endian mode) @@ -613,8 +629,10 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd, struct v4l2_format *f) { struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); + struct sh_mobile_ceu_dev *pcdev = ici->priv; const struct soc_camera_format_xlate *xlate; __u32 pixfmt = f->fmt.pix.pixelformat; + int ret; xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); if (!xlate) { @@ -640,8 +658,16 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd, f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; /* limit to sensor capabilities */ - return icd->ops->try_fmt(icd, f); + ret = icd->ops->try_fmt(icd, f); + + pcdev->is_interlace = 0; + if (V4L2_FIELD_INTERLACED == f->fmt.pix.field) { + pcdev->is_interlace = 1; + f->fmt.pix.field = V4L2_FIELD_NONE; + } + + return ret; + } static int sh_mobile_ceu_reqbufs(struct soc_camera_file *icf, -- 1.5.6.3 -- video4linux-list mailing list Unsubscribe mailto:video4linux-list-request@redhat.com?subject=unsubscribe https://www.redhat.com/mailman/listinfo/video4linux-list