[media] exynos4-is: Fix format propagation on FIMC-IS-ISP subdev
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>
This commit is contained in:
parent
a055d97037
commit
5cfaad64d8
2 changed files with 66 additions and 29 deletions
|
@ -128,31 +128,28 @@ static int fimc_isp_subdev_get_fmt(struct v4l2_subdev *sd,
|
||||||
struct v4l2_subdev_format *fmt)
|
struct v4l2_subdev_format *fmt)
|
||||||
{
|
{
|
||||||
struct fimc_isp *isp = v4l2_get_subdevdata(sd);
|
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 *mf = &fmt->format;
|
||||||
struct v4l2_mbus_framefmt cur_fmt;
|
|
||||||
|
|
||||||
if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
|
if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
|
||||||
mf = v4l2_subdev_get_try_format(fh, fmt->pad);
|
*mf = *v4l2_subdev_get_try_format(fh, fmt->pad);
|
||||||
fmt->format = *mf;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
mf->colorspace = V4L2_COLORSPACE_SRGB;
|
mf->colorspace = V4L2_COLORSPACE_SRGB;
|
||||||
|
|
||||||
mutex_lock(&isp->subdev_lock);
|
mutex_lock(&isp->subdev_lock);
|
||||||
__is_get_frame_size(is, &cur_fmt);
|
|
||||||
|
|
||||||
if (fmt->pad == FIMC_ISP_SD_PAD_SINK) {
|
if (fmt->pad == FIMC_ISP_SD_PAD_SINK) {
|
||||||
/* full camera input frame size */
|
/* ISP OTF input image format */
|
||||||
mf->width = cur_fmt.width + FIMC_ISP_CAC_MARGIN_WIDTH;
|
*mf = isp->sink_fmt;
|
||||||
mf->height = cur_fmt.height + FIMC_ISP_CAC_MARGIN_HEIGHT;
|
|
||||||
mf->code = V4L2_MBUS_FMT_SGRBG10_1X10;
|
|
||||||
} else {
|
} else {
|
||||||
/* crop size */
|
/* ISP OTF output image format */
|
||||||
mf->width = cur_fmt.width;
|
*mf = isp->src_fmt;
|
||||||
mf->height = cur_fmt.height;
|
|
||||||
mf->code = V4L2_MBUS_FMT_YUV10_1X30;
|
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);
|
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,
|
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 *mf = &fmt->format;
|
||||||
|
struct v4l2_mbus_framefmt *format;
|
||||||
|
|
||||||
|
mf->colorspace = V4L2_COLORSPACE_SRGB;
|
||||||
|
|
||||||
if (fmt->pad == FIMC_ISP_SD_PAD_SINK) {
|
if (fmt->pad == FIMC_ISP_SD_PAD_SINK) {
|
||||||
v4l_bound_align_image(&mf->width, FIMC_ISP_SINK_WIDTH_MIN,
|
v4l_bound_align_image(&mf->width, FIMC_ISP_SINK_WIDTH_MIN,
|
||||||
FIMC_ISP_SINK_WIDTH_MAX, 0,
|
FIMC_ISP_SINK_WIDTH_MAX, 0,
|
||||||
&mf->height, FIMC_ISP_SINK_HEIGHT_MIN,
|
&mf->height, FIMC_ISP_SINK_HEIGHT_MIN,
|
||||||
FIMC_ISP_SINK_HEIGHT_MAX, 0, 0);
|
FIMC_ISP_SINK_HEIGHT_MAX, 0, 0);
|
||||||
isp->subdev_fmt = *mf;
|
mf->code = V4L2_MBUS_FMT_SGRBG10_1X10;
|
||||||
} else {
|
} 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 */
|
/* Allow changing format only on sink pad */
|
||||||
mf->width = isp->subdev_fmt.width - FIMC_ISP_CAC_MARGIN_WIDTH;
|
mf->width = format->width - FIMC_ISP_CAC_MARGIN_WIDTH;
|
||||||
mf->height = isp->subdev_fmt.height - FIMC_ISP_CAC_MARGIN_HEIGHT;
|
mf->height = format->height - FIMC_ISP_CAC_MARGIN_HEIGHT;
|
||||||
mf->code = isp->subdev_fmt.code;
|
|
||||||
|
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",
|
isp_dbg(1, sd, "%s: pad%d: code: 0x%x, %dx%d\n",
|
||||||
__func__, fmt->pad, mf->code, mf->width, mf->height);
|
__func__, fmt->pad, mf->code, mf->width, mf->height);
|
||||||
|
|
||||||
mf->colorspace = V4L2_COLORSPACE_SRGB;
|
|
||||||
|
|
||||||
mutex_lock(&isp->subdev_lock);
|
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) {
|
if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
|
||||||
mf = v4l2_subdev_get_try_format(fh, fmt->pad);
|
mf = v4l2_subdev_get_try_format(fh, fmt->pad);
|
||||||
*mf = fmt->format;
|
*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);
|
mutex_unlock(&isp->subdev_lock);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -145,7 +145,8 @@ struct fimc_isp {
|
||||||
struct vb2_alloc_ctx *alloc_ctx;
|
struct vb2_alloc_ctx *alloc_ctx;
|
||||||
struct v4l2_subdev subdev;
|
struct v4l2_subdev subdev;
|
||||||
struct media_pad subdev_pads[FIMC_ISP_SD_PADS_NUM];
|
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 v4l2_ctrl *test_pattern;
|
||||||
struct fimc_isp_ctrls ctrls;
|
struct fimc_isp_ctrls ctrls;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue