[media] exynos4-is: Fix format propagation on FIMC-IS-ISP subdev
authorSylwester Nawrocki <s.nawrocki@samsung.com>
Tue, 18 Jun 2013 16:42:30 +0000 (13:42 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Fri, 28 Jun 2013 18:32:17 +0000 (15:32 -0300)
Ensure TRY formats are propagated from the sink pad to the source pads
of the FIMC-IS-ISP subdev and the TRY and ACTIVE formats are separated.

[mchehab@redhat.com: Whitespace cleanup]
Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Kyungmin Park <kyungin.park@samsung.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/platform/exynos4-is/fimc-isp.c
drivers/media/platform/exynos4-is/fimc-isp.h

index ecb82a9517f3cca2149d4f4eb5655d1752db34ca..f859b3cdd4093b8d0b13de2ed2defd4b78ba5388 100644 (file)
@@ -128,31 +128,28 @@ static int fimc_isp_subdev_get_fmt(struct v4l2_subdev *sd,
                                   struct v4l2_subdev_format *fmt)
 {
        struct fimc_isp *isp = v4l2_get_subdevdata(sd);
-       struct fimc_is *is = fimc_isp_to_is(isp);
        struct v4l2_mbus_framefmt *mf = &fmt->format;
-       struct v4l2_mbus_framefmt cur_fmt;
 
        if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
-               mf = v4l2_subdev_get_try_format(fh, fmt->pad);
-               fmt->format = *mf;
+               *mf = *v4l2_subdev_get_try_format(fh, fmt->pad);
                return 0;
        }
 
        mf->colorspace = V4L2_COLORSPACE_SRGB;
 
        mutex_lock(&isp->subdev_lock);
-       __is_get_frame_size(is, &cur_fmt);
 
        if (fmt->pad == FIMC_ISP_SD_PAD_SINK) {
-               /* full camera input frame size */
-               mf->width = cur_fmt.width + FIMC_ISP_CAC_MARGIN_WIDTH;
-               mf->height = cur_fmt.height + FIMC_ISP_CAC_MARGIN_HEIGHT;
-               mf->code = V4L2_MBUS_FMT_SGRBG10_1X10;
+               /* ISP OTF input image format */
+               *mf = isp->sink_fmt;
        } else {
-               /* crop size */
-               mf->width = cur_fmt.width;
-               mf->height = cur_fmt.height;
-               mf->code = V4L2_MBUS_FMT_YUV10_1X30;
+               /* ISP OTF output image format */
+               *mf = isp->src_fmt;
+
+               if (fmt->pad == FIMC_ISP_SD_PAD_SRC_FIFO) {
+                       mf->colorspace = V4L2_COLORSPACE_JPEG;
+                       mf->code = V4L2_MBUS_FMT_YUV10_1X30;
+               }
        }
 
        mutex_unlock(&isp->subdev_lock);
@@ -164,21 +161,37 @@ static int fimc_isp_subdev_get_fmt(struct v4l2_subdev *sd,
 }
 
 static void __isp_subdev_try_format(struct fimc_isp *isp,
-                                  struct v4l2_subdev_format *fmt)
+                                   struct v4l2_subdev_fh *fh,
+                                   struct v4l2_subdev_format *fmt)
 {
        struct v4l2_mbus_framefmt *mf = &fmt->format;
+       struct v4l2_mbus_framefmt *format;
+
+       mf->colorspace = V4L2_COLORSPACE_SRGB;
 
        if (fmt->pad == FIMC_ISP_SD_PAD_SINK) {
                v4l_bound_align_image(&mf->width, FIMC_ISP_SINK_WIDTH_MIN,
                                FIMC_ISP_SINK_WIDTH_MAX, 0,
                                &mf->height, FIMC_ISP_SINK_HEIGHT_MIN,
                                FIMC_ISP_SINK_HEIGHT_MAX, 0, 0);
-               isp->subdev_fmt = *mf;
+               mf->code = V4L2_MBUS_FMT_SGRBG10_1X10;
        } else {
+               if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
+                       format = v4l2_subdev_get_try_format(fh,
+                                               FIMC_ISP_SD_PAD_SINK);
+               else
+                       format = &isp->sink_fmt;
+
                /* Allow changing format only on sink pad */
-               mf->width = isp->subdev_fmt.width - FIMC_ISP_CAC_MARGIN_WIDTH;
-               mf->height = isp->subdev_fmt.height - FIMC_ISP_CAC_MARGIN_HEIGHT;
-               mf->code = isp->subdev_fmt.code;
+               mf->width = format->width - FIMC_ISP_CAC_MARGIN_WIDTH;
+               mf->height = format->height - FIMC_ISP_CAC_MARGIN_HEIGHT;
+
+               if (fmt->pad == FIMC_ISP_SD_PAD_SRC_FIFO) {
+                       mf->code = V4L2_MBUS_FMT_YUV10_1X30;
+                       mf->colorspace = V4L2_COLORSPACE_JPEG;
+               } else {
+                       mf->code = format->code;
+               }
        }
 }
 
@@ -194,24 +207,47 @@ static int fimc_isp_subdev_set_fmt(struct v4l2_subdev *sd,
        isp_dbg(1, sd, "%s: pad%d: code: 0x%x, %dx%d\n",
                 __func__, fmt->pad, mf->code, mf->width, mf->height);
 
-       mf->colorspace = V4L2_COLORSPACE_SRGB;
-
        mutex_lock(&isp->subdev_lock);
-       __isp_subdev_try_format(isp, fmt);
+       __isp_subdev_try_format(isp, fh, fmt);
 
        if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
                mf = v4l2_subdev_get_try_format(fh, fmt->pad);
                *mf = fmt->format;
-               mutex_unlock(&isp->subdev_lock);
-               return 0;
+
+               /* Propagate format to the source pads */
+               if (fmt->pad == FIMC_ISP_SD_PAD_SINK) {
+                       struct v4l2_subdev_format format = *fmt;
+                       unsigned int pad;
+
+                       for (pad = FIMC_ISP_SD_PAD_SRC_FIFO;
+                                       pad < FIMC_ISP_SD_PADS_NUM; pad++) {
+                               format.pad = pad;
+                               __isp_subdev_try_format(isp, fh, &format);
+                               mf = v4l2_subdev_get_try_format(fh, pad);
+                               *mf = format.format;
+                       }
+               }
+       } else {
+               if (sd->entity.stream_count == 0) {
+                       if (fmt->pad == FIMC_ISP_SD_PAD_SINK) {
+                               struct v4l2_subdev_format format = *fmt;
+
+                               isp->sink_fmt = *mf;
+
+                               format.pad = FIMC_ISP_SD_PAD_SRC_DMA;
+                               __isp_subdev_try_format(isp, fh, &format);
+
+                               isp->src_fmt = format.format;
+                               __is_set_frame_size(is, &isp->src_fmt);
+                       } else {
+                               isp->src_fmt = *mf;
+                       }
+               } else {
+                       ret = -EBUSY;
+               }
        }
 
-       if (sd->entity.stream_count == 0)
-               __is_set_frame_size(is, mf);
-       else
-               ret = -EBUSY;
        mutex_unlock(&isp->subdev_lock);
-
        return ret;
 }
 
index 756063e77fb8a8caf9705496249b76494d88469e..03bf95ab017bce6be66f07a98141e562f1b64abb 100644 (file)
@@ -145,7 +145,8 @@ struct fimc_isp {
        struct vb2_alloc_ctx            *alloc_ctx;
        struct v4l2_subdev              subdev;
        struct media_pad                subdev_pads[FIMC_ISP_SD_PADS_NUM];
-       struct v4l2_mbus_framefmt       subdev_fmt;
+       struct v4l2_mbus_framefmt       src_fmt;
+       struct v4l2_mbus_framefmt       sink_fmt;
        struct v4l2_ctrl                *test_pattern;
        struct fimc_isp_ctrls           ctrls;