V4L/DVB (10079): sh_mobile_ceu: use new pixel format translation code
authorMagnus Damm <damm@igel.co.jp>
Thu, 18 Dec 2008 14:49:06 +0000 (11:49 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Tue, 30 Dec 2008 11:40:21 +0000 (09:40 -0200)
This patch converts the sh_mobile_ceu driver to make use
of the new pixel format translation code. Only pass-though
mode at this point.

Signed-off-by: Magnus Damm <damm@igel.co.jp>
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 c25ea0047e0487e698d113e1819e41e709c8bf4f..a49bec1509f4eba97616ef7ff44e196f34707392 100644 (file)
@@ -434,8 +434,7 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
        return 0;
 }
 
-static int sh_mobile_ceu_try_bus_param(struct soc_camera_device *icd,
-                                      __u32 pixfmt)
+static int sh_mobile_ceu_try_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;
@@ -450,25 +449,60 @@ static int sh_mobile_ceu_try_bus_param(struct soc_camera_device *icd,
        return 0;
 }
 
+static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, int idx,
+                                    struct soc_camera_format_xlate *xlate)
+{
+       struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+       int ret;
+       int formats = 0;
+
+       ret = sh_mobile_ceu_try_bus_param(icd);
+       if (ret < 0)
+               return 0;
+
+       switch (icd->formats[idx].fourcc) {
+       default:
+               /* Generic pass-through */
+               formats++;
+               if (xlate) {
+                       xlate->host_fmt = icd->formats + idx;
+                       xlate->cam_fmt = icd->formats + idx;
+                       xlate->buswidth = icd->formats[idx].depth;
+                       xlate++;
+                       dev_dbg(&ici->dev,
+                               "Providing format %s in pass-through mode\n",
+                               icd->formats[idx].name);
+               }
+       }
+
+       return formats;
+}
+
 static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd,
                                 __u32 pixfmt, struct v4l2_rect *rect)
 {
-       const struct soc_camera_data_format *cam_fmt = NULL;
+       struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+       const struct soc_camera_format_xlate *xlate;
        int ret;
 
-       /*
-        * TODO: find a suitable supported by the SoC output format, check
-        * whether the sensor supports one of acceptable input formats.
-        */
-       if (pixfmt) {
-               cam_fmt = soc_camera_format_by_fourcc(icd, pixfmt);
-               if (!cam_fmt)
-                       return -EINVAL;
+       xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
+       if (!xlate) {
+               dev_warn(&ici->dev, "Format %x not found\n", pixfmt);
+               return -EINVAL;
        }
 
-       ret = icd->ops->set_fmt(icd, pixfmt, rect);
-       if (pixfmt && !ret)
-               icd->current_fmt = cam_fmt;
+       switch (pixfmt) {
+       case 0:                         /* Only geometry change */
+               ret = icd->ops->set_fmt(icd, pixfmt, rect);
+               break;
+       default:
+               ret = icd->ops->set_fmt(icd, xlate->cam_fmt->fourcc, rect);
+       }
+
+       if (pixfmt && !ret) {
+               icd->buswidth = xlate->buswidth;
+               icd->current_fmt = xlate->host_fmt;
+       }
 
        return ret;
 }
@@ -476,19 +510,15 @@ static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd,
 static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd,
                                 struct v4l2_format *f)
 {
-       const struct soc_camera_data_format *cam_fmt;
-       int ret = sh_mobile_ceu_try_bus_param(icd, f->fmt.pix.pixelformat);
-
-       if (ret < 0)
-               return ret;
+       struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+       const struct soc_camera_format_xlate *xlate;
+       __u32 pixfmt = f->fmt.pix.pixelformat;
 
-       /*
-        * TODO: find a suitable supported by the SoC output format, check
-        * whether the sensor supports one of acceptable input formats.
-        */
-       cam_fmt = soc_camera_format_by_fourcc(icd, f->fmt.pix.pixelformat);
-       if (!cam_fmt)
+       xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
+       if (!xlate) {
+               dev_warn(&ici->dev, "Format %x not found\n", pixfmt);
                return -EINVAL;
+       }
 
        /* FIXME: calculate using depth and bus width */
 
@@ -504,7 +534,7 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd,
        f->fmt.pix.height &= ~0x03;
 
        f->fmt.pix.bytesperline = f->fmt.pix.width *
-               DIV_ROUND_UP(cam_fmt->depth, 8);
+               DIV_ROUND_UP(xlate->host_fmt->depth, 8);
        f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
 
        /* limit to sensor capabilities */
@@ -576,6 +606,7 @@ static struct soc_camera_host_ops sh_mobile_ceu_host_ops = {
        .owner          = THIS_MODULE,
        .add            = sh_mobile_ceu_add_device,
        .remove         = sh_mobile_ceu_remove_device,
+       .get_formats    = sh_mobile_ceu_get_formats,
        .set_fmt        = sh_mobile_ceu_set_fmt,
        .try_fmt        = sh_mobile_ceu_try_fmt,
        .reqbufs        = sh_mobile_ceu_reqbufs,