From 9d4fa15b74a697bf312620536470aaf82632f2af Mon Sep 17 00:00:00 2001 From: Hu Kejun Date: Wed, 26 Aug 2020 16:11:18 +0800 Subject: [PATCH] media: platform: rockchip: cif: fix fmt/crop for isp is not correct Signed-off-by: Hu Kejun Change-Id: I8ca4b38f6d857d82d77842989099a560e3f4212e --- drivers/media/platform/rockchip/cif/capture.c | 54 +++++++++---------- drivers/media/platform/rockchip/cif/dev.h | 1 + .../media/platform/rockchip/cif/subdev-itf.c | 43 ++++++++++----- 3 files changed, 57 insertions(+), 41 deletions(-) diff --git a/drivers/media/platform/rockchip/cif/capture.c b/drivers/media/platform/rockchip/cif/capture.c index 87c4946396d2..704c86f65ae0 100644 --- a/drivers/media/platform/rockchip/cif/capture.c +++ b/drivers/media/platform/rockchip/cif/capture.c @@ -478,33 +478,6 @@ static struct rkcif_sensor_info *sd_to_sensor(struct rkcif_device *dev, return NULL; } -static int rkcif_update_sensor_info(struct rkcif_stream *stream) -{ - struct rkcif_sensor_info *sensor, *terminal_sensor; - struct v4l2_subdev *sensor_sd; - int ret = 0; - - sensor_sd = get_remote_sensor(stream, NULL); - if (!sensor_sd) - return -ENODEV; - - sensor = sd_to_sensor(stream->cifdev, sensor_sd); - if (!sensor) { - v4l2_err(&stream->cifdev->v4l2_dev, "get sensor for updating failed!\n"); - return -ENODEV; - } - ret = v4l2_subdev_call(sensor->sd, video, g_mbus_config, - &sensor->mbus); - if (ret && ret != -ENOIOCTLCMD) - return ret; - stream->cifdev->active_sensor = sensor; - - terminal_sensor = &stream->cifdev->terminal_sensor; - get_remote_terminal_sensor(stream, &terminal_sensor->sd); - - return ret; -} - static unsigned char get_data_type(u32 pixelformat, u8 cmd_mode_en) { switch (pixelformat) { @@ -3248,6 +3221,33 @@ static u32 rkcif_lvds_get_sof(struct rkcif_device *dev) return 0; } +int rkcif_update_sensor_info(struct rkcif_stream *stream) +{ + struct rkcif_sensor_info *sensor, *terminal_sensor; + struct v4l2_subdev *sensor_sd; + int ret = 0; + + sensor_sd = get_remote_sensor(stream, NULL); + if (!sensor_sd) + return -ENODEV; + + sensor = sd_to_sensor(stream->cifdev, sensor_sd); + if (!sensor) { + v4l2_err(&stream->cifdev->v4l2_dev, "get sensor for updating failed!\n"); + return -ENODEV; + } + ret = v4l2_subdev_call(sensor->sd, video, g_mbus_config, + &sensor->mbus); + if (ret && ret != -ENOIOCTLCMD) + return ret; + stream->cifdev->active_sensor = sensor; + + terminal_sensor = &stream->cifdev->terminal_sensor; + get_remote_terminal_sensor(stream, &terminal_sensor->sd); + + return ret; +} + int rkcif_register_lvds_subdev(struct rkcif_device *dev) { struct v4l2_device *v4l2_dev = &dev->v4l2_dev; diff --git a/drivers/media/platform/rockchip/cif/dev.h b/drivers/media/platform/rockchip/cif/dev.h index 5ec53e5c04e7..e9594f344cb4 100644 --- a/drivers/media/platform/rockchip/cif/dev.h +++ b/drivers/media/platform/rockchip/cif/dev.h @@ -406,5 +406,6 @@ u32 rkcif_get_sof(struct rkcif_device *cif_dev); int rkcif_plat_init(struct rkcif_device *cif_dev, struct device_node *node, int inf_id); int rkcif_plat_uninit(struct rkcif_device *cif_dev); int rkcif_attach_hw(struct rkcif_device *cif_dev); +int rkcif_update_sensor_info(struct rkcif_stream *stream); #endif diff --git a/drivers/media/platform/rockchip/cif/subdev-itf.c b/drivers/media/platform/rockchip/cif/subdev-itf.c index 7689f3662065..7221a411e6db 100644 --- a/drivers/media/platform/rockchip/cif/subdev-itf.c +++ b/drivers/media/platform/rockchip/cif/subdev-itf.c @@ -33,6 +33,9 @@ static int sditf_g_frame_interval(struct v4l2_subdev *sd, struct rkcif_device *cif_dev = priv->cif_dev; struct v4l2_subdev *sensor_sd; + if (!cif_dev->active_sensor) + rkcif_update_sensor_info(&cif_dev->stream[0]); + if (cif_dev->active_sensor) { sensor_sd = cif_dev->active_sensor->sd; return v4l2_subdev_call(sensor_sd, video, g_frame_interval, fi); @@ -48,6 +51,9 @@ static int sditf_g_mbus_config(struct v4l2_subdev *sd, struct rkcif_device *cif_dev = priv->cif_dev; struct v4l2_subdev *sensor_sd; + if (!cif_dev->active_sensor) + rkcif_update_sensor_info(&cif_dev->stream[0]); + if (cif_dev->active_sensor) { sensor_sd = cif_dev->active_sensor->sd; return v4l2_subdev_call(sensor_sd, video, g_mbus_config, config); @@ -62,29 +68,32 @@ static int sditf_get_set_fmt(struct v4l2_subdev *sd, { struct sditf_priv *priv = to_sditf_priv(sd); struct rkcif_device *cif_dev = priv->cif_dev; - struct v4l2_subdev *sensor_sd; + struct v4l2_subdev_selection input_sel; + int ret = -EINVAL; - if (cif_dev->active_sensor) { - sensor_sd = cif_dev->active_sensor->sd; - return v4l2_subdev_call(sensor_sd, pad, get_fmt, NULL, fmt); + if (!cif_dev->terminal_sensor.sd) + rkcif_update_sensor_info(&cif_dev->stream[0]); + + if (cif_dev->terminal_sensor.sd) { + v4l2_subdev_call(cif_dev->terminal_sensor.sd, pad, get_fmt, NULL, fmt); + + input_sel.target = V4L2_SEL_TGT_CROP_BOUNDS; + ret = v4l2_subdev_call(cif_dev->terminal_sensor.sd, + pad, get_selection, NULL, + &input_sel); + if (!ret) { + fmt->format.width = input_sel.r.width; + fmt->format.height = input_sel.r.height; + } } - return -EINVAL; + return ret; } static int sditf_get_selection(struct v4l2_subdev *sd, struct v4l2_subdev_pad_config *cfg, struct v4l2_subdev_selection *sel) { - struct sditf_priv *priv = to_sditf_priv(sd); - struct rkcif_device *cif_dev = priv->cif_dev; - struct v4l2_subdev *sensor_sd; - - if (cif_dev->active_sensor) { - sensor_sd = cif_dev->active_sensor->sd; - return v4l2_subdev_call(sensor_sd, pad, get_selection, NULL, sel); - } - return -EINVAL; } @@ -94,6 +103,9 @@ static long sditf_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg) struct rkcif_device *cif_dev = priv->cif_dev; struct v4l2_subdev *sensor_sd; + if (!cif_dev->terminal_sensor.sd) + rkcif_update_sensor_info(&cif_dev->stream[0]); + if (cif_dev->terminal_sensor.sd) { sensor_sd = cif_dev->terminal_sensor.sd; return v4l2_subdev_call(sensor_sd, core, ioctl, cmd, arg); @@ -110,6 +122,9 @@ static long sditf_compat_ioctl32(struct v4l2_subdev *sd, struct rkcif_device *cif_dev = priv->cif_dev; struct v4l2_subdev *sensor_sd; + if (!cif_dev->terminal_sensor.sd) + rkcif_update_sensor_info(&cif_dev->stream[0]); + if (cif_dev->terminal_sensor.sd) { sensor_sd = cif_dev->terminal_sensor.sd; return v4l2_subdev_call(sensor_sd, core, compat_ioctl32, cmd, arg);