Commit bad1774e authored by Jacopo Mondi's avatar Jacopo Mondi Committed by Mauro Carvalho Chehab

media: ov5640: Fix timings setup code

As of: commit 476dec01 ("media: ov5640: Add horizontal and vertical
totals") the timings parameters gets programmed separately from the
static register values array.

When changing capture mode, the vertical and horizontal totals gets
inspected by the set_mode_exposure_calc() functions, and only later
programmed with the new values. This means exposure, light banding
filter and shutter gain are calculated using the previous timings, and
are thus not correct.

Fix this by programming timings right after the static register value
table has been sent to the sensor in the ov5640_load_regs() function.

Fixes: 476dec01 ("media: ov5640: Add horizontal and vertical totals")

Tested-by: Steve Longerbeam <slongerbeam@gmail.com> # i.MX6q SabreSD, CSI-2
Tested-by: Loic Poulain <loic.poulain@linaro.org> # Dragonboard-410c, CSI-2
Signed-off-by: default avatarSamuel Bobrowicz <sam@elite-embedded.com>
Signed-off-by: default avatarMaxime Ripard <maxime.ripard@bootlin.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+samsung@kernel.org>
parent aa4bb8b8
...@@ -909,6 +909,26 @@ static int ov5640_mod_reg(struct ov5640_dev *sensor, u16 reg, ...@@ -909,6 +909,26 @@ static int ov5640_mod_reg(struct ov5640_dev *sensor, u16 reg,
} }
/* download ov5640 settings to sensor through i2c */ /* download ov5640 settings to sensor through i2c */
static int ov5640_set_timings(struct ov5640_dev *sensor,
const struct ov5640_mode_info *mode)
{
int ret;
ret = ov5640_write_reg16(sensor, OV5640_REG_TIMING_DVPHO, mode->hact);
if (ret < 0)
return ret;
ret = ov5640_write_reg16(sensor, OV5640_REG_TIMING_DVPVO, mode->vact);
if (ret < 0)
return ret;
ret = ov5640_write_reg16(sensor, OV5640_REG_TIMING_HTS, mode->htot);
if (ret < 0)
return ret;
return ov5640_write_reg16(sensor, OV5640_REG_TIMING_VTS, mode->vtot);
}
static int ov5640_load_regs(struct ov5640_dev *sensor, static int ov5640_load_regs(struct ov5640_dev *sensor,
const struct ov5640_mode_info *mode) const struct ov5640_mode_info *mode)
{ {
...@@ -936,7 +956,7 @@ static int ov5640_load_regs(struct ov5640_dev *sensor, ...@@ -936,7 +956,7 @@ static int ov5640_load_regs(struct ov5640_dev *sensor,
usleep_range(1000 * delay_ms, 1000 * delay_ms + 100); usleep_range(1000 * delay_ms, 1000 * delay_ms + 100);
} }
return ret; return ov5640_set_timings(sensor, mode);
} }
/* read exposure, in number of line periods */ /* read exposure, in number of line periods */
...@@ -1399,30 +1419,6 @@ static int ov5640_set_virtual_channel(struct ov5640_dev *sensor) ...@@ -1399,30 +1419,6 @@ static int ov5640_set_virtual_channel(struct ov5640_dev *sensor)
return ov5640_write_reg(sensor, OV5640_REG_DEBUG_MODE, temp); return ov5640_write_reg(sensor, OV5640_REG_DEBUG_MODE, temp);
} }
static int ov5640_set_timings(struct ov5640_dev *sensor,
const struct ov5640_mode_info *mode)
{
int ret;
ret = ov5640_write_reg16(sensor, OV5640_REG_TIMING_DVPHO, mode->hact);
if (ret < 0)
return ret;
ret = ov5640_write_reg16(sensor, OV5640_REG_TIMING_DVPVO, mode->vact);
if (ret < 0)
return ret;
ret = ov5640_write_reg16(sensor, OV5640_REG_TIMING_HTS, mode->htot);
if (ret < 0)
return ret;
ret = ov5640_write_reg16(sensor, OV5640_REG_TIMING_VTS, mode->vtot);
if (ret < 0)
return ret;
return 0;
}
static const struct ov5640_mode_info * static const struct ov5640_mode_info *
ov5640_find_mode(struct ov5640_dev *sensor, enum ov5640_frame_rate fr, ov5640_find_mode(struct ov5640_dev *sensor, enum ov5640_frame_rate fr,
int width, int height, bool nearest) int width, int height, bool nearest)
...@@ -1663,10 +1659,6 @@ static int ov5640_set_mode(struct ov5640_dev *sensor, ...@@ -1663,10 +1659,6 @@ static int ov5640_set_mode(struct ov5640_dev *sensor,
ret = ov5640_set_mode_direct(sensor, mode, exposure); ret = ov5640_set_mode_direct(sensor, mode, exposure);
} }
if (ret < 0)
return ret;
ret = ov5640_set_timings(sensor, mode);
if (ret < 0) if (ret < 0)
return ret; return ret;
......
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