Commit 19f2e3e6 authored by Hugues Fruchet's avatar Hugues Fruchet Committed by Mauro Carvalho Chehab

media: ov5640: Adjust vblank with s_frame_interval

Adjust the vertical blanking when s_frame_interval is used.

s_frame_interval allows to set a fixed frame rate, which gets stored as
the sensor's current one. When a new mode is applied, the current frame
rate is reset to the mode's default one. In order to correctly report
the currently configured vertical blanking for s_frame_interval users,
verify that the desired frame rate has not been changed. If that's the
case, compute the correct blanking value and reflect it through the
corresponding v4l2 control.
Signed-off-by: default avatarHugues Fruchet <hugues.fruchet@st.com>
Signed-off-by: default avatarJacopo Mondi <jacopo@jmondi.org>
Signed-off-by: default avatarSakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@kernel.org>
parent bce93b82
...@@ -319,6 +319,7 @@ struct ov5640_mode_info { ...@@ -319,6 +319,7 @@ struct ov5640_mode_info {
/* Used by s_frame_interval only. */ /* Used by s_frame_interval only. */
u32 max_fps; u32 max_fps;
u32 def_fps;
}; };
struct ov5640_ctrls { struct ov5640_ctrls {
...@@ -602,7 +603,8 @@ static const struct ov5640_mode_info ov5640_mode_data[OV5640_NUM_MODES] = { ...@@ -602,7 +603,8 @@ static const struct ov5640_mode_info ov5640_mode_data[OV5640_NUM_MODES] = {
}, },
.reg_data = ov5640_setting_low_res, .reg_data = ov5640_setting_low_res,
.reg_data_size = ARRAY_SIZE(ov5640_setting_low_res), .reg_data_size = ARRAY_SIZE(ov5640_setting_low_res),
.max_fps = OV5640_30_FPS .max_fps = OV5640_30_FPS,
.def_fps = OV5640_30_FPS
}, { }, {
/* 176x144 */ /* 176x144 */
.id = OV5640_MODE_QCIF_176_144, .id = OV5640_MODE_QCIF_176_144,
...@@ -646,7 +648,8 @@ static const struct ov5640_mode_info ov5640_mode_data[OV5640_NUM_MODES] = { ...@@ -646,7 +648,8 @@ static const struct ov5640_mode_info ov5640_mode_data[OV5640_NUM_MODES] = {
}, },
.reg_data = ov5640_setting_low_res, .reg_data = ov5640_setting_low_res,
.reg_data_size = ARRAY_SIZE(ov5640_setting_low_res), .reg_data_size = ARRAY_SIZE(ov5640_setting_low_res),
.max_fps = OV5640_30_FPS .max_fps = OV5640_30_FPS,
.def_fps = OV5640_30_FPS
}, { }, {
/* 320x240 */ /* 320x240 */
.id = OV5640_MODE_QVGA_320_240, .id = OV5640_MODE_QVGA_320_240,
...@@ -690,7 +693,8 @@ static const struct ov5640_mode_info ov5640_mode_data[OV5640_NUM_MODES] = { ...@@ -690,7 +693,8 @@ static const struct ov5640_mode_info ov5640_mode_data[OV5640_NUM_MODES] = {
}, },
.reg_data = ov5640_setting_low_res, .reg_data = ov5640_setting_low_res,
.reg_data_size = ARRAY_SIZE(ov5640_setting_low_res), .reg_data_size = ARRAY_SIZE(ov5640_setting_low_res),
.max_fps = OV5640_30_FPS .max_fps = OV5640_30_FPS,
.def_fps = OV5640_30_FPS
}, { }, {
/* 640x480 */ /* 640x480 */
.id = OV5640_MODE_VGA_640_480, .id = OV5640_MODE_VGA_640_480,
...@@ -734,7 +738,8 @@ static const struct ov5640_mode_info ov5640_mode_data[OV5640_NUM_MODES] = { ...@@ -734,7 +738,8 @@ static const struct ov5640_mode_info ov5640_mode_data[OV5640_NUM_MODES] = {
}, },
.reg_data = ov5640_setting_low_res, .reg_data = ov5640_setting_low_res,
.reg_data_size = ARRAY_SIZE(ov5640_setting_low_res), .reg_data_size = ARRAY_SIZE(ov5640_setting_low_res),
.max_fps = OV5640_60_FPS .max_fps = OV5640_60_FPS,
.def_fps = OV5640_30_FPS
}, { }, {
/* 720x480 */ /* 720x480 */
.id = OV5640_MODE_NTSC_720_480, .id = OV5640_MODE_NTSC_720_480,
...@@ -777,7 +782,8 @@ static const struct ov5640_mode_info ov5640_mode_data[OV5640_NUM_MODES] = { ...@@ -777,7 +782,8 @@ static const struct ov5640_mode_info ov5640_mode_data[OV5640_NUM_MODES] = {
}, },
.reg_data = ov5640_setting_low_res, .reg_data = ov5640_setting_low_res,
.reg_data_size = ARRAY_SIZE(ov5640_setting_low_res), .reg_data_size = ARRAY_SIZE(ov5640_setting_low_res),
.max_fps = OV5640_30_FPS .max_fps = OV5640_30_FPS,
.def_fps = OV5640_30_FPS
}, { }, {
/* 720x576 */ /* 720x576 */
.id = OV5640_MODE_PAL_720_576, .id = OV5640_MODE_PAL_720_576,
...@@ -820,7 +826,8 @@ static const struct ov5640_mode_info ov5640_mode_data[OV5640_NUM_MODES] = { ...@@ -820,7 +826,8 @@ static const struct ov5640_mode_info ov5640_mode_data[OV5640_NUM_MODES] = {
}, },
.reg_data = ov5640_setting_low_res, .reg_data = ov5640_setting_low_res,
.reg_data_size = ARRAY_SIZE(ov5640_setting_low_res), .reg_data_size = ARRAY_SIZE(ov5640_setting_low_res),
.max_fps = OV5640_30_FPS .max_fps = OV5640_30_FPS,
.def_fps = OV5640_30_FPS
}, { }, {
/* 1024x768 */ /* 1024x768 */
.id = OV5640_MODE_XGA_1024_768, .id = OV5640_MODE_XGA_1024_768,
...@@ -862,7 +869,8 @@ static const struct ov5640_mode_info ov5640_mode_data[OV5640_NUM_MODES] = { ...@@ -862,7 +869,8 @@ static const struct ov5640_mode_info ov5640_mode_data[OV5640_NUM_MODES] = {
}, },
.reg_data = ov5640_setting_low_res, .reg_data = ov5640_setting_low_res,
.reg_data_size = ARRAY_SIZE(ov5640_setting_low_res), .reg_data_size = ARRAY_SIZE(ov5640_setting_low_res),
.max_fps = OV5640_30_FPS .max_fps = OV5640_30_FPS,
.def_fps = OV5640_30_FPS
}, { }, {
/* 1280x720 */ /* 1280x720 */
.id = OV5640_MODE_720P_1280_720, .id = OV5640_MODE_720P_1280_720,
...@@ -904,7 +912,8 @@ static const struct ov5640_mode_info ov5640_mode_data[OV5640_NUM_MODES] = { ...@@ -904,7 +912,8 @@ static const struct ov5640_mode_info ov5640_mode_data[OV5640_NUM_MODES] = {
}, },
.reg_data = ov5640_setting_720P_1280_720, .reg_data = ov5640_setting_720P_1280_720,
.reg_data_size = ARRAY_SIZE(ov5640_setting_720P_1280_720), .reg_data_size = ARRAY_SIZE(ov5640_setting_720P_1280_720),
.max_fps = OV5640_30_FPS .max_fps = OV5640_30_FPS,
.def_fps = OV5640_30_FPS
}, { }, {
/* 1920x1080 */ /* 1920x1080 */
.id = OV5640_MODE_1080P_1920_1080, .id = OV5640_MODE_1080P_1920_1080,
...@@ -948,7 +957,8 @@ static const struct ov5640_mode_info ov5640_mode_data[OV5640_NUM_MODES] = { ...@@ -948,7 +957,8 @@ static const struct ov5640_mode_info ov5640_mode_data[OV5640_NUM_MODES] = {
}, },
.reg_data = ov5640_setting_1080P_1920_1080, .reg_data = ov5640_setting_1080P_1920_1080,
.reg_data_size = ARRAY_SIZE(ov5640_setting_1080P_1920_1080), .reg_data_size = ARRAY_SIZE(ov5640_setting_1080P_1920_1080),
.max_fps = OV5640_30_FPS .max_fps = OV5640_30_FPS,
.def_fps = OV5640_30_FPS
}, { }, {
/* 2592x1944 */ /* 2592x1944 */
.id = OV5640_MODE_QSXGA_2592_1944, .id = OV5640_MODE_QSXGA_2592_1944,
...@@ -991,7 +1001,8 @@ static const struct ov5640_mode_info ov5640_mode_data[OV5640_NUM_MODES] = { ...@@ -991,7 +1001,8 @@ static const struct ov5640_mode_info ov5640_mode_data[OV5640_NUM_MODES] = {
}, },
.reg_data = ov5640_setting_QSXGA_2592_1944, .reg_data = ov5640_setting_QSXGA_2592_1944,
.reg_data_size = ARRAY_SIZE(ov5640_setting_QSXGA_2592_1944), .reg_data_size = ARRAY_SIZE(ov5640_setting_QSXGA_2592_1944),
.max_fps = OV5640_15_FPS .max_fps = OV5640_15_FPS,
.def_fps = OV5640_15_FPS
}, },
}; };
...@@ -2712,6 +2723,7 @@ static int ov5640_update_pixel_rate(struct ov5640_dev *sensor) ...@@ -2712,6 +2723,7 @@ static int ov5640_update_pixel_rate(struct ov5640_dev *sensor)
u32 pixel_rate; u32 pixel_rate;
s64 link_freq; s64 link_freq;
u32 num_lanes; u32 num_lanes;
u32 vblank;
u32 bpp; u32 bpp;
/* /*
...@@ -2770,15 +2782,29 @@ static int ov5640_update_pixel_rate(struct ov5640_dev *sensor) ...@@ -2770,15 +2782,29 @@ static int ov5640_update_pixel_rate(struct ov5640_dev *sensor)
__v4l2_ctrl_modify_range(sensor->ctrls.hblank, __v4l2_ctrl_modify_range(sensor->ctrls.hblank,
hblank, hblank, 1, hblank); hblank, hblank, 1, hblank);
vblank = timings->vblank_def;
if (sensor->current_fr != mode->def_fps) {
/*
* Compute the vertical blanking according to the framerate
* configured with s_frame_interval.
*/
int fie_num = sensor->frame_interval.numerator;
int fie_denom = sensor->frame_interval.denominator;
vblank = ((fie_num * pixel_rate / fie_denom) / timings->htot) -
mode->height;
}
__v4l2_ctrl_modify_range(sensor->ctrls.vblank, OV5640_MIN_VBLANK, __v4l2_ctrl_modify_range(sensor->ctrls.vblank, OV5640_MIN_VBLANK,
OV5640_MAX_VTS - mode->height, 1, OV5640_MAX_VTS - mode->height, 1, vblank);
timings->vblank_def); __v4l2_ctrl_s_ctrl(sensor->ctrls.vblank, vblank);
__v4l2_ctrl_s_ctrl(sensor->ctrls.vblank, timings->vblank_def);
exposure_max = timings->crop.height + timings->vblank_def - 4; exposure_max = timings->crop.height + vblank - 4;
exposure_val = clamp_t(s32, sensor->ctrls.exposure->val, exposure_val = clamp_t(s32, sensor->ctrls.exposure->val,
sensor->ctrls.exposure->minimum, sensor->ctrls.exposure->minimum,
exposure_max); exposure_max);
__v4l2_ctrl_modify_range(sensor->ctrls.exposure, __v4l2_ctrl_modify_range(sensor->ctrls.exposure,
sensor->ctrls.exposure->minimum, sensor->ctrls.exposure->minimum,
exposure_max, 1, exposure_val); exposure_max, 1, exposure_val);
...@@ -2816,6 +2842,7 @@ static int ov5640_set_fmt(struct v4l2_subdev *sd, ...@@ -2816,6 +2842,7 @@ static int ov5640_set_fmt(struct v4l2_subdev *sd,
} }
if (new_mode != sensor->current_mode) { if (new_mode != sensor->current_mode) {
sensor->current_fr = new_mode->def_fps;
sensor->current_mode = new_mode; sensor->current_mode = new_mode;
sensor->pending_mode_change = true; sensor->pending_mode_change = true;
} }
...@@ -3468,8 +3495,7 @@ static int ov5640_s_frame_interval(struct v4l2_subdev *sd, ...@@ -3468,8 +3495,7 @@ static int ov5640_s_frame_interval(struct v4l2_subdev *sd,
sensor->current_mode = mode; sensor->current_mode = mode;
sensor->pending_mode_change = true; sensor->pending_mode_change = true;
__v4l2_ctrl_s_ctrl_int64(sensor->ctrls.pixel_rate, ov5640_update_pixel_rate(sensor);
ov5640_calc_pixel_rate(sensor));
} }
out: out:
mutex_unlock(&sensor->lock); mutex_unlock(&sensor->lock);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment