diff --git a/drivers/media/i2c/soc_camera/rockchip/adv_camera_module.c b/drivers/media/i2c/soc_camera/rockchip/adv_camera_module.c index cbc9a7d4d3bd..034c12143015 100644 --- a/drivers/media/i2c/soc_camera/rockchip/adv_camera_module.c +++ b/drivers/media/i2c/soc_camera/rockchip/adv_camera_module.c @@ -740,6 +740,10 @@ int adv_camera_module_s_ext_ctrls( "V4L2_CID_EXPOSURE %d\n", ctrl->value); break; + case RK_V4L2_CID_VTS: + ctrl_updt = ADV_CAMERA_MODULE_CTRL_UPDT_VTS_VALUE; + cam_mod->exp_config.vts_value = ctrl->value; + break; case V4L2_CID_WHITE_BALANCE_TEMPERATURE: ctrl_updt = ADV_CAMERA_MODULE_CTRL_UPDT_WB_TEMPERATURE; cam_mod->wb_config.temperature = ctrl->value; diff --git a/drivers/media/i2c/soc_camera/rockchip/adv_camera_module.h b/drivers/media/i2c/soc_camera/rockchip/adv_camera_module.h index 5f505ee16379..85b7442ff224 100644 --- a/drivers/media/i2c/soc_camera/rockchip/adv_camera_module.h +++ b/drivers/media/i2c/soc_camera/rockchip/adv_camera_module.h @@ -41,6 +41,7 @@ #define ADV_CAMERA_MODULE_CTRL_UPDT_AUTO_EXP 0x20 #define ADV_CAMERA_MODULE_CTRL_UPDT_FOCUS_ABSOLUTE 0x40 #define ADV_CAMERA_MODULE_CTRL_UPDT_PRESET_WB 0x80 +#define ADV_CAMERA_MODULE_CTRL_UPDT_VTS_VALUE 0x100 enum adv_camera_module_state { ADV_CAMERA_MODULE_POWER_OFF = 0, @@ -100,6 +101,7 @@ struct adv_camera_module_exp_config { u16 gain_percent; bool auto_gain; enum v4l2_flash_led_mode flash_mode; + u32 vts_value; }; struct adv_camera_module_wb_config { diff --git a/drivers/media/i2c/soc_camera/rockchip/aptina_camera_module.c b/drivers/media/i2c/soc_camera/rockchip/aptina_camera_module.c index dd20bdf5d4c5..79a63caa7bbb 100644 --- a/drivers/media/i2c/soc_camera/rockchip/aptina_camera_module.c +++ b/drivers/media/i2c/soc_camera/rockchip/aptina_camera_module.c @@ -971,6 +971,10 @@ int aptina_camera_module_s_ext_ctrls( "V4L2_CID_EXPOSURE %d\n", ctrl->value); break; + case RK_V4L2_CID_VTS: + ctrl_updt = APTINA_CAMERA_MODULE_CTRL_UPDT_VTS_VALUE; + cam_mod->exp_config.vts_value = ctrl->value; + break; case V4L2_CID_WHITE_BALANCE_TEMPERATURE: ctrl_updt = APTINA_CAMERA_MODULE_CTRL_UPDT_WB_TEMPERATURE; diff --git a/drivers/media/i2c/soc_camera/rockchip/aptina_camera_module.h b/drivers/media/i2c/soc_camera/rockchip/aptina_camera_module.h index 5bd1b92e6c79..9f053051cb9c 100644 --- a/drivers/media/i2c/soc_camera/rockchip/aptina_camera_module.h +++ b/drivers/media/i2c/soc_camera/rockchip/aptina_camera_module.h @@ -42,6 +42,7 @@ #define APTINA_CAMERA_MODULE_CTRL_UPDT_AUTO_EXP 0x20 #define APTINA_CAMERA_MODULE_CTRL_UPDT_FOCUS_ABSOLUTE 0x40 #define APTINA_CAMERA_MODULE_CTRL_UPDT_PRESET_WB 0x80 +#define APTINA_CAMERA_MODULE_CTRL_UPDT_VTS_VALUE 0x100 enum aptina_camera_module_state { APTINA_CAMERA_MODULE_POWER_OFF = 0, @@ -97,6 +98,7 @@ struct aptina_camera_module_exp_config { u16 gain_percent; bool auto_gain; enum v4l2_flash_led_mode flash_mode; + u32 vts_value; }; struct aptina_camera_module_wb_config { diff --git a/drivers/media/i2c/soc_camera/rockchip/imx323_v4l2-i2c-subdev.c b/drivers/media/i2c/soc_camera/rockchip/imx323_v4l2-i2c-subdev.c index 4df5f00e34a3..b39afa63851b 100644 --- a/drivers/media/i2c/soc_camera/rockchip/imx323_v4l2-i2c-subdev.c +++ b/drivers/media/i2c/soc_camera/rockchip/imx323_v4l2-i2c-subdev.c @@ -191,6 +191,31 @@ static int imx323_auto_adjust_fps(struct imx_camera_module *cam_mod, return ret; } +static int imx323_set_vts(struct imx_camera_module *cam_mod, + u32 vts) +{ + int ret = 0; + + if (vts < cam_mod->vts_min) + return ret; + + if (vts > 0xfff) + vts = 0xfff; + + ret = imx_camera_module_write_reg(cam_mod, + IMX323_TIMING_VTS_LOW_REG, vts & 0xFF); + ret |= imx_camera_module_write_reg(cam_mod, + IMX323_TIMING_VTS_HIGH_REG, (vts >> 8) & 0xFF); + + if (IS_ERR_VALUE(ret)) { + imx_camera_module_pr_err(cam_mod, "failed with error (%d)\n", ret); + } else { + imx_camera_module_pr_info(cam_mod, "updated vts=%d,vts_min=%d\n", vts, cam_mod->vts_min); + cam_mod->vts_cur = vts; + } + return ret; +} + /*--------------------------------------------------------------------------*/ static int imx323_write_aec(struct imx_camera_module *cam_mod) @@ -230,6 +255,9 @@ static int imx323_write_aec(struct imx_camera_module *cam_mod) ret |= imx_camera_module_write_reg(cam_mod, IMX323_AEC_PK_EXPO_LOW_REG, IMX323_FETCH_LOW_BYTE_EXP(exp_time)); + + if (!cam_mod->auto_adjust_fps) + ret |= imx323_set_vts(cam_mod, cam_mod->exp_config.vts_value); } if (IS_ERR_VALUE(ret)) @@ -418,7 +446,7 @@ static int imx323_s_ext_ctrls(struct imx_camera_module *cam_mod, /* Handles only exposure and gain together special case. */ if (ctrls->count == 1) ret = imx323_s_ctrl(cam_mod, ctrls->ctrls[0].id); - else if ((ctrls->count == 3) && + else if ((ctrls->count >= 3) && ((ctrls->ctrls[0].id == V4L2_CID_GAIN && ctrls->ctrls[1].id == V4L2_CID_EXPOSURE) || (ctrls->ctrls[1].id == V4L2_CID_GAIN && diff --git a/drivers/media/i2c/soc_camera/rockchip/imx_camera_module.c b/drivers/media/i2c/soc_camera/rockchip/imx_camera_module.c index ad0ba0f1aa17..217151826903 100644 --- a/drivers/media/i2c/soc_camera/rockchip/imx_camera_module.c +++ b/drivers/media/i2c/soc_camera/rockchip/imx_camera_module.c @@ -714,6 +714,10 @@ int imx_camera_module_s_ext_ctrls( "V4L2_CID_EXPOSURE %d\n", ctrl->value); break; + case RK_V4L2_CID_VTS: + ctrl_updt = IMX_CAMERA_MODULE_CTRL_UPDT_VTS_VALUE; + cam_mod->exp_config.vts_value = ctrl->value; + break; case V4L2_CID_WHITE_BALANCE_TEMPERATURE: ctrl_updt = IMX_CAMERA_MODULE_CTRL_UPDT_WB_TEMPERATURE; cam_mod->wb_config.temperature = ctrl->value; @@ -913,7 +917,7 @@ long imx_camera_module_ioctl(struct v4l2_subdev *sd, imx_timings.fine_integration_time_min; if (cam_mod->custom.g_exposure_valid_frame) - timings->exposure_valid_frame = + timings->exposure_valid_frame[0] = cam_mod->custom.g_exposure_valid_frame(cam_mod); timings->exp_time = cam_mod->exp_config.exp_time; timings->gain = cam_mod->exp_config.gain; diff --git a/drivers/media/i2c/soc_camera/rockchip/imx_camera_module.h b/drivers/media/i2c/soc_camera/rockchip/imx_camera_module.h index 787beecd0a5d..ffd135ab672f 100644 --- a/drivers/media/i2c/soc_camera/rockchip/imx_camera_module.h +++ b/drivers/media/i2c/soc_camera/rockchip/imx_camera_module.h @@ -41,6 +41,7 @@ #define IMX_CAMERA_MODULE_CTRL_UPDT_AUTO_EXP 0x20 #define IMX_CAMERA_MODULE_CTRL_UPDT_FOCUS_ABSOLUTE 0x40 #define IMX_CAMERA_MODULE_CTRL_UPDT_PRESET_WB 0x80 +#define IMX_CAMERA_MODULE_CTRL_UPDT_VTS_VALUE 0x100 enum imx_camera_module_state { IMX_CAMERA_MODULE_POWER_OFF = 0, @@ -97,6 +98,7 @@ struct imx_camera_module_exp_config { u16 gain_percent; bool auto_gain; enum v4l2_flash_led_mode flash_mode; + u32 vts_value; }; struct imx_camera_module_wb_config { diff --git a/drivers/media/i2c/soc_camera/rockchip/ov13850_v4l2-i2c-subdev.c b/drivers/media/i2c/soc_camera/rockchip/ov13850_v4l2-i2c-subdev.c index b30c42ff5ece..a16a520fd993 100644 --- a/drivers/media/i2c/soc_camera/rockchip/ov13850_v4l2-i2c-subdev.c +++ b/drivers/media/i2c/soc_camera/rockchip/ov13850_v4l2-i2c-subdev.c @@ -1418,6 +1418,32 @@ static int ov13850_auto_adjust_fps(struct ov_camera_module *cam_mod, return ret; } +static int ov13850_set_vts(struct ov_camera_module *cam_mod, + u32 vts) +{ + int ret = 0; + + if (vts < cam_mod->vts_min) + return ret; + + if (vts > 0xfff) + vts = 0xfff; + + ret = ov_camera_module_write_reg(cam_mod, + ov13850_TIMING_VTS_LOW_REG, vts & 0xFF); + ret |= ov_camera_module_write_reg(cam_mod, + ov13850_TIMING_VTS_HIGH_REG, + (vts >> 8) & 0xFF); + + if (IS_ERR_VALUE(ret)) { + ov_camera_module_pr_err(cam_mod, "failed with error (%d)\n", ret); + } else { + ov_camera_module_pr_info(cam_mod, "updated vts=%d,vts_min=%d\n", vts, cam_mod->vts_min); + cam_mod->vts_cur = vts; + } + return ret; +} + static int ov13850_write_aec(struct ov_camera_module *cam_mod) { int ret = 0; @@ -1464,6 +1490,8 @@ static int ov13850_write_aec(struct ov_camera_module *cam_mod) ret |= ov_camera_module_write_reg(cam_mod, ov13850_AEC_PK_LONG_EXPO_1ST_REG, ov13850_FETCH_1ST_BYTE_EXP(exp_time)); + if (!cam_mod->auto_adjust_fps) + ret |= ov13850_set_vts(cam_mod, cam_mod->exp_config.vts_value); if (cam_mod->state == OV_CAMERA_MODULE_STREAMING) { ret = ov_camera_module_write_reg(cam_mod, ov13850_AEC_GROUP_UPDATE_ADDRESS, @@ -1745,7 +1773,7 @@ static int ov13850_s_ext_ctrls(struct ov_camera_module *cam_mod, /* Handles only exposure and gain together special case. */ if (ctrls->count == 1) ret = ov13850_s_ctrl(cam_mod, ctrls->ctrls[0].id); - else if ((ctrls->count == 3) && + else if ((ctrls->count >= 3) && ((ctrls->ctrls[0].id == V4L2_CID_GAIN && ctrls->ctrls[1].id == V4L2_CID_EXPOSURE) || (ctrls->ctrls[1].id == V4L2_CID_GAIN && diff --git a/drivers/media/i2c/soc_camera/rockchip/ov2710_v4l2-i2c-subdev.c b/drivers/media/i2c/soc_camera/rockchip/ov2710_v4l2-i2c-subdev.c index c749fceb5a62..3a1b7878885a 100644 --- a/drivers/media/i2c/soc_camera/rockchip/ov2710_v4l2-i2c-subdev.c +++ b/drivers/media/i2c/soc_camera/rockchip/ov2710_v4l2-i2c-subdev.c @@ -360,6 +360,33 @@ static int OV2710_auto_adjust_fps(struct ov_camera_module *cam_mod, return ret; } +static int ov2710_set_vts(struct ov_camera_module *cam_mod, + u32 vts) +{ + int ret = 0; + + if (vts < cam_mod->vts_min) + return ret; + + if (vts > 0xfff) + vts = 0xfff; + + ret = ov_camera_module_write_reg(cam_mod, + OV2710_TIMING_VTS_LOW_REG, + vts & 0xFF); + ret |= ov_camera_module_write_reg(cam_mod, + OV2710_TIMING_VTS_HIGH_REG, + (vts >> 8) & 0x0F); + + if (IS_ERR_VALUE(ret)) { + ov_camera_module_pr_err(cam_mod, "failed with error (%d)\n", ret); + } else { + ov_camera_module_pr_info(cam_mod, "updated vts=%d,vts_min=%d\n", vts, cam_mod->vts_min); + cam_mod->vts_cur = vts; + } + return ret; +} + static int ov2710_write_aec(struct ov_camera_module *cam_mod) { int ret = 0; @@ -404,6 +431,8 @@ static int ov2710_write_aec(struct ov_camera_module *cam_mod) ret |= ov_camera_module_write_reg(cam_mod, OV2710_AEC_PK_LONG_EXPO_1ST_REG, OV2710_FETCH_1ST_BYTE_EXP(exp_time)); + if (!cam_mod->auto_adjust_fps) + ret |= ov2710_set_vts(cam_mod, cam_mod->exp_config.vts_value); if (cam_mod->state == OV_CAMERA_MODULE_STREAMING) { ret = ov_camera_module_write_reg(cam_mod, OV2710_AEC_GROUP_UPDATE_ADDRESS, @@ -683,7 +712,7 @@ static int ov2710_s_ext_ctrls(struct ov_camera_module *cam_mod, /* Handles only exposure and gain together special case. */ if (ctrls->count == 1) ret = ov2710_s_ctrl(cam_mod, ctrls->ctrls[0].id); - else if ((ctrls->count == 3) && + else if ((ctrls->count >= 3) && (ctrls->ctrls[0].id == V4L2_CID_GAIN || ctrls->ctrls[0].id == V4L2_CID_EXPOSURE || ctrls->ctrls[1].id == V4L2_CID_GAIN || diff --git a/drivers/media/i2c/soc_camera/rockchip/ov4689_v4l2-i2c-subdev.c b/drivers/media/i2c/soc_camera/rockchip/ov4689_v4l2-i2c-subdev.c index 1d01997a4bec..12c554e6fb6a 100644 --- a/drivers/media/i2c/soc_camera/rockchip/ov4689_v4l2-i2c-subdev.c +++ b/drivers/media/i2c/soc_camera/rockchip/ov4689_v4l2-i2c-subdev.c @@ -426,6 +426,32 @@ static int ov4689_auto_adjust_fps(struct ov_camera_module *cam_mod, return ret; } +static int ov4689_set_vts(struct ov_camera_module *cam_mod, + u32 vts) +{ + int ret = 0; + + if (vts < cam_mod->vts_min) + return ret; + + if (vts > 0xfff) + vts = 0xfff; + + ret = ov_camera_module_write_reg(cam_mod, + ov4689_TIMING_VTS_LOW_REG, vts & 0xFF); + ret |= ov_camera_module_write_reg(cam_mod, + ov4689_TIMING_VTS_HIGH_REG, + (vts >> 8) & 0xFF); + + if (IS_ERR_VALUE(ret)) { + ov_camera_module_pr_err(cam_mod, "failed with error (%d)\n", ret); + } else { + ov_camera_module_pr_info(cam_mod, "updated vts=%d,vts_min=%d\n", vts, cam_mod->vts_min); + cam_mod->vts_cur = vts; + } + return ret; +} + static int ov4689_write_aec(struct ov_camera_module *cam_mod) { int ret = 0; @@ -470,6 +496,8 @@ static int ov4689_write_aec(struct ov_camera_module *cam_mod) ret |= ov_camera_module_write_reg(cam_mod, ov4689_AEC_PK_LONG_EXPO_1ST_REG, ov4689_FETCH_1ST_BYTE_EXP(exp_time)); + if (!cam_mod->auto_adjust_fps) + ret |= ov4689_set_vts(cam_mod, cam_mod->exp_config.vts_value); if (cam_mod->state == OV_CAMERA_MODULE_STREAMING) { ret = ov_camera_module_write_reg(cam_mod, ov4689_AEC_GROUP_UPDATE_ADDRESS, @@ -752,7 +780,7 @@ static int ov4689_s_ext_ctrls(struct ov_camera_module *cam_mod, /* Handles only exposure and gain together special case. */ if (ctrls->count == 1) ret = ov4689_s_ctrl(cam_mod, ctrls->ctrls[0].id); - else if ((ctrls->count == 3) && + else if ((ctrls->count >= 3) && ((ctrls->ctrls[0].id == V4L2_CID_GAIN && ctrls->ctrls[1].id == V4L2_CID_EXPOSURE) || (ctrls->ctrls[1].id == V4L2_CID_GAIN && diff --git a/drivers/media/i2c/soc_camera/rockchip/ov7675_v4l2-i2c-subdev.c b/drivers/media/i2c/soc_camera/rockchip/ov7675_v4l2-i2c-subdev.c index 6f9837f5d702..a3b0a12a7a1b 100644 --- a/drivers/media/i2c/soc_camera/rockchip/ov7675_v4l2-i2c-subdev.c +++ b/drivers/media/i2c/soc_camera/rockchip/ov7675_v4l2-i2c-subdev.c @@ -374,7 +374,7 @@ static int ov7675_s_ext_ctrls(struct ov_camera_module *cam_mod, /* Handles only exposure and gain together special case. */ if (ctrls->count == 1) ret = ov7675_s_ctrl(cam_mod, ctrls->ctrls[0].id); - else if ((ctrls->count == 3) && + else if ((ctrls->count >= 3) && ((ctrls->ctrls[0].id == V4L2_CID_GAIN && ctrls->ctrls[1].id == V4L2_CID_EXPOSURE) || (ctrls->ctrls[1].id == V4L2_CID_GAIN && diff --git a/drivers/media/i2c/soc_camera/rockchip/ov7750_v4l2-i2c-subdev.c b/drivers/media/i2c/soc_camera/rockchip/ov7750_v4l2-i2c-subdev.c index 22f3c33000c0..190df0f1792a 100644 --- a/drivers/media/i2c/soc_camera/rockchip/ov7750_v4l2-i2c-subdev.c +++ b/drivers/media/i2c/soc_camera/rockchip/ov7750_v4l2-i2c-subdev.c @@ -398,6 +398,33 @@ static int ov7750_auto_adjust_fps(struct ov_camera_module *cam_mod, return ret; } +static int ov7750_set_vts(struct ov_camera_module *cam_mod, + u32 vts) +{ + int ret = 0; + + if (vts < cam_mod->vts_min) + return ret; + + if (vts > 0xfff) + vts = 0xfff; + + ret = ov_camera_module_write_reg(cam_mod, + ov7750_TIMING_VTS_LOW_REG, + vts & 0xFF); + ret |= ov_camera_module_write_reg(cam_mod, + ov7750_TIMING_VTS_HIGH_REG, + (vts >> 8) & 0xFF); + + if (IS_ERR_VALUE(ret)) { + ov_camera_module_pr_err(cam_mod, "failed with error (%d)\n", ret); + } else { + ov_camera_module_pr_info(cam_mod, "updated vts=%d,vts_min=%d\n", vts, cam_mod->vts_min); + cam_mod->vts_cur = vts; + } + return ret; +} + static int ov7750_write_aec(struct ov_camera_module *cam_mod) { int ret = 0; @@ -443,6 +470,8 @@ static int ov7750_write_aec(struct ov_camera_module *cam_mod) ret |= ov_camera_module_write_reg(cam_mod, ov7750_AEC_PK_LONG_EXPO_1ST_REG, ov7750_FETCH_1ST_BYTE_EXP(exp_time)); + if (!cam_mod->auto_adjust_fps) + ret |= ov7750_set_vts(cam_mod, cam_mod->exp_config.vts_value); if (cam_mod->state == OV_CAMERA_MODULE_STREAMING) { ret = ov_camera_module_write_reg(cam_mod, ov7750_AEC_GROUP_UPDATE_ADDRESS, @@ -709,7 +738,7 @@ static int ov7750_s_ext_ctrls(struct ov_camera_module *cam_mod, /* Handles only exposure and gain together special case. */ if (ctrls->count == 1) ret = ov7750_s_ctrl(cam_mod, ctrls->ctrls[0].id); - else if ((ctrls->count == 3) && + else if ((ctrls->count >= 3) && ((ctrls->ctrls[0].id == V4L2_CID_GAIN && ctrls->ctrls[1].id == V4L2_CID_EXPOSURE) || (ctrls->ctrls[1].id == V4L2_CID_GAIN && diff --git a/drivers/media/i2c/soc_camera/rockchip/ov8858_v4l2-i2c-subdev.c b/drivers/media/i2c/soc_camera/rockchip/ov8858_v4l2-i2c-subdev.c index 51fee5e516d1..60bd0ea5e2f2 100644 --- a/drivers/media/i2c/soc_camera/rockchip/ov8858_v4l2-i2c-subdev.c +++ b/drivers/media/i2c/soc_camera/rockchip/ov8858_v4l2-i2c-subdev.c @@ -1239,6 +1239,33 @@ static int ov8858_auto_adjust_fps(struct ov_camera_module *cam_mod, return ret; } +static int ov8858_set_vts(struct ov_camera_module *cam_mod, + u32 vts) +{ + int ret = 0; + + if (vts < cam_mod->vts_min) + return ret; + + if (vts > 0xfff) + vts = 0xfff; + + ret = ov_camera_module_write_reg(cam_mod, + ov8858_TIMING_VTS_LOW_REG, + vts & 0xFF); + ret |= ov_camera_module_write_reg(cam_mod, + ov8858_TIMING_VTS_HIGH_REG, + (vts >> 8) & 0xFF); + + if (IS_ERR_VALUE(ret)) { + ov_camera_module_pr_err(cam_mod, "failed with error (%d)\n", ret); + } else { + ov_camera_module_pr_info(cam_mod, "updated vts=%d,vts_min=%d\n", vts, cam_mod->vts_min); + cam_mod->vts_cur = vts; + } + return ret; +} + /*--------------------------------------------------------------------------*/ static int ov8858_write_aec(struct ov_camera_module *cam_mod) { @@ -1285,6 +1312,8 @@ static int ov8858_write_aec(struct ov_camera_module *cam_mod) ret |= ov_camera_module_write_reg(cam_mod, ov8858_AEC_PK_LONG_EXPO_1ST_REG, ov8858_FETCH_1ST_BYTE_EXP(exp_time)); + if (!cam_mod->auto_adjust_fps) + ret |= ov8858_set_vts(cam_mod, cam_mod->exp_config.vts_value); if (cam_mod->state == OV_CAMERA_MODULE_STREAMING) { ret = ov_camera_module_write_reg(cam_mod, ov8858_AEC_GROUP_UPDATE_ADDRESS, @@ -1558,7 +1587,7 @@ static int ov8858_s_ext_ctrls(struct ov_camera_module *cam_mod, /* Handles only exposure and gain together special case. */ if (ctrls->count == 1) ret = ov8858_s_ctrl(cam_mod, ctrls->ctrls[0].id); - else if ((ctrls->count == 3) && + else if ((ctrls->count >= 3) && ((ctrls->ctrls[0].id == V4L2_CID_GAIN && ctrls->ctrls[1].id == V4L2_CID_EXPOSURE) || (ctrls->ctrls[1].id == V4L2_CID_GAIN && diff --git a/drivers/media/i2c/soc_camera/rockchip/ov_camera_module.c b/drivers/media/i2c/soc_camera/rockchip/ov_camera_module.c index 9e8110e5636c..f58c0a84b78c 100644 --- a/drivers/media/i2c/soc_camera/rockchip/ov_camera_module.c +++ b/drivers/media/i2c/soc_camera/rockchip/ov_camera_module.c @@ -738,6 +738,10 @@ int ov_camera_module_s_ext_ctrls( "V4L2_CID_EXPOSURE %d\n", ctrl->value); break; + case RK_V4L2_CID_VTS: + ctrl_updt = OV_CAMERA_MODULE_CTRL_UPDT_VTS_VALUE; + cam_mod->exp_config.vts_value = ctrl->value; + break; case V4L2_CID_WHITE_BALANCE_TEMPERATURE: ctrl_updt = OV_CAMERA_MODULE_CTRL_UPDT_WB_TEMPERATURE; cam_mod->wb_config.temperature = ctrl->value; diff --git a/drivers/media/i2c/soc_camera/rockchip/ov_camera_module.h b/drivers/media/i2c/soc_camera/rockchip/ov_camera_module.h index ffce8134fbb2..139406248cd5 100644 --- a/drivers/media/i2c/soc_camera/rockchip/ov_camera_module.h +++ b/drivers/media/i2c/soc_camera/rockchip/ov_camera_module.h @@ -41,6 +41,7 @@ #define OV_CAMERA_MODULE_CTRL_UPDT_AUTO_EXP 0x20 #define OV_CAMERA_MODULE_CTRL_UPDT_FOCUS_ABSOLUTE 0x40 #define OV_CAMERA_MODULE_CTRL_UPDT_PRESET_WB 0x80 +#define OV_CAMERA_MODULE_CTRL_UPDT_VTS_VALUE 0x100 enum ov_camera_module_state { OV_CAMERA_MODULE_POWER_OFF = 0, @@ -100,6 +101,7 @@ struct ov_camera_module_exp_config { u16 gain_percent; bool auto_gain; enum v4l2_flash_led_mode flash_mode; + u32 vts_value; }; struct ov_camera_module_wb_config { diff --git a/drivers/media/i2c/soc_camera/rockchip/tc358749xbg_v4l2-i2c-subdev.c b/drivers/media/i2c/soc_camera/rockchip/tc358749xbg_v4l2-i2c-subdev.c index f6408b8c753f..e93961638c61 100644 --- a/drivers/media/i2c/soc_camera/rockchip/tc358749xbg_v4l2-i2c-subdev.c +++ b/drivers/media/i2c/soc_camera/rockchip/tc358749xbg_v4l2-i2c-subdev.c @@ -707,7 +707,7 @@ static int tc358749xbg_s_ext_ctrls( /* Handles only exposure and gain together special case. */ if (ctrls->count == 1) ret = tc358749xbg_s_ctrl(cam_mod, ctrls->ctrls[0].id); - else if ((ctrls->count == 3) && + else if ((ctrls->count >= 3) && (ctrls->ctrls[0].id == V4L2_CID_GAIN || ctrls->ctrls[0].id == V4L2_CID_EXPOSURE || ctrls->ctrls[1].id == V4L2_CID_GAIN || diff --git a/drivers/media/i2c/soc_camera/rockchip/tc_camera_module.c b/drivers/media/i2c/soc_camera/rockchip/tc_camera_module.c index f862b6799591..229444c1eed5 100644 --- a/drivers/media/i2c/soc_camera/rockchip/tc_camera_module.c +++ b/drivers/media/i2c/soc_camera/rockchip/tc_camera_module.c @@ -755,6 +755,10 @@ int tc_camera_module_s_ext_ctrls( "V4L2_CID_EXPOSURE %d\n", ctrl->value); break; + case RK_V4L2_CID_VTS: + ctrl_updt = TC_CAMERA_MODULE_CTRL_UPDT_VTS_VALUE; + cam_mod->exp_config.vts_value = ctrl->value; + break; case V4L2_CID_WHITE_BALANCE_TEMPERATURE: ctrl_updt = TC_CAMERA_MODULE_CTRL_UPDT_WB_TEMPERATURE; cam_mod->wb_config.temperature = ctrl->value; diff --git a/drivers/media/i2c/soc_camera/rockchip/tc_camera_module.h b/drivers/media/i2c/soc_camera/rockchip/tc_camera_module.h index c4c1d25df250..2cb594df2cad 100644 --- a/drivers/media/i2c/soc_camera/rockchip/tc_camera_module.h +++ b/drivers/media/i2c/soc_camera/rockchip/tc_camera_module.h @@ -45,6 +45,7 @@ #define TC_CAMERA_MODULE_CTRL_UPDT_AUTO_EXP 0x20 #define TC_CAMERA_MODULE_CTRL_UPDT_FOCUS_ABSOLUTE 0x40 #define TC_CAMERA_MODULE_CTRL_UPDT_PRESET_WB 0x80 +#define TC_CAMERA_MODULE_CTRL_UPDT_VTS_VALUE 0x100 enum tc_camera_module_state { TC_CAMERA_MODULE_POWER_OFF = 0, @@ -111,6 +112,7 @@ struct tc_camera_module_exp_config { u16 gain_percent; bool auto_gain; enum v4l2_flash_led_mode flash_mode; + u32 vts_value; }; struct tc_camera_module_wb_config { diff --git a/include/media/v4l2-controls_rockchip.h b/include/media/v4l2-controls_rockchip.h index a30d1569d7bd..010ddf4696b4 100644 --- a/include/media/v4l2-controls_rockchip.h +++ b/include/media/v4l2-controls_rockchip.h @@ -29,4 +29,5 @@ #define RK_V4L2_CID_VBLANKING (V4L2_CID_USER_RK_BASE + 1) #define RK_V4L2_CID_GAIN_PERCENT (V4L2_CID_USER_RK_BASE + 2) #define RK_V4L2_CID_AUTO_FPS (V4L2_CID_USER_RK_BASE + 3) +#define RK_V4L2_CID_VTS (V4L2_CID_USER_RK_BASE + 4) #endif