media: i2c: ov9282: Action CID_VBLANK when set.
Programming the sensor with TIMING_VTS (aka LPFR) was done when triggered by a change in exposure or gain, but not when V4L2_CID_VBLANK was changed. Dynamic frame rate changes could therefore not be achieved. Separate out programming TIMING_VTS so that it is triggered by set_ctrl(V4L2_CID_VBLANK) Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
This commit is contained in:
committed by
Mauro Carvalho Chehab
parent
f6a8808200
commit
ed80071b95
@@ -417,22 +417,15 @@ static int ov9282_update_controls(struct ov9282 *ov9282,
|
|||||||
*/
|
*/
|
||||||
static int ov9282_update_exp_gain(struct ov9282 *ov9282, u32 exposure, u32 gain)
|
static int ov9282_update_exp_gain(struct ov9282 *ov9282, u32 exposure, u32 gain)
|
||||||
{
|
{
|
||||||
u32 lpfr;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
lpfr = ov9282->vblank + ov9282->cur_mode->height;
|
dev_dbg(ov9282->dev, "Set exp %u, analog gain %u",
|
||||||
|
exposure, gain);
|
||||||
dev_dbg(ov9282->dev, "Set exp %u, analog gain %u, lpfr %u",
|
|
||||||
exposure, gain, lpfr);
|
|
||||||
|
|
||||||
ret = ov9282_write_reg(ov9282, OV9282_REG_HOLD, 1, 1);
|
ret = ov9282_write_reg(ov9282, OV9282_REG_HOLD, 1, 1);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ret = ov9282_write_reg(ov9282, OV9282_REG_LPFR, 2, lpfr);
|
|
||||||
if (ret)
|
|
||||||
goto error_release_group_hold;
|
|
||||||
|
|
||||||
ret = ov9282_write_reg(ov9282, OV9282_REG_EXPOSURE, 3, exposure << 4);
|
ret = ov9282_write_reg(ov9282, OV9282_REG_EXPOSURE, 3, exposure << 4);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_release_group_hold;
|
goto error_release_group_hold;
|
||||||
@@ -463,6 +456,7 @@ static int ov9282_set_ctrl(struct v4l2_ctrl *ctrl)
|
|||||||
container_of(ctrl->handler, struct ov9282, ctrl_handler);
|
container_of(ctrl->handler, struct ov9282, ctrl_handler);
|
||||||
u32 analog_gain;
|
u32 analog_gain;
|
||||||
u32 exposure;
|
u32 exposure;
|
||||||
|
u32 lpfr;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
switch (ctrl->id) {
|
switch (ctrl->id) {
|
||||||
@@ -480,11 +474,14 @@ static int ov9282_set_ctrl(struct v4l2_ctrl *ctrl)
|
|||||||
OV9282_EXPOSURE_OFFSET,
|
OV9282_EXPOSURE_OFFSET,
|
||||||
1, OV9282_EXPOSURE_DEFAULT);
|
1, OV9282_EXPOSURE_DEFAULT);
|
||||||
break;
|
break;
|
||||||
case V4L2_CID_EXPOSURE:
|
}
|
||||||
/* Set controls only if sensor is in power on state */
|
|
||||||
if (!pm_runtime_get_if_in_use(ov9282->dev))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
|
/* Set controls only if sensor is in power on state */
|
||||||
|
if (!pm_runtime_get_if_in_use(ov9282->dev))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
switch (ctrl->id) {
|
||||||
|
case V4L2_CID_EXPOSURE:
|
||||||
exposure = ctrl->val;
|
exposure = ctrl->val;
|
||||||
analog_gain = ov9282->again_ctrl->val;
|
analog_gain = ov9282->again_ctrl->val;
|
||||||
|
|
||||||
@@ -492,15 +489,18 @@ static int ov9282_set_ctrl(struct v4l2_ctrl *ctrl)
|
|||||||
exposure, analog_gain);
|
exposure, analog_gain);
|
||||||
|
|
||||||
ret = ov9282_update_exp_gain(ov9282, exposure, analog_gain);
|
ret = ov9282_update_exp_gain(ov9282, exposure, analog_gain);
|
||||||
|
break;
|
||||||
pm_runtime_put(ov9282->dev);
|
case V4L2_CID_VBLANK:
|
||||||
|
lpfr = ov9282->vblank + ov9282->cur_mode->height;
|
||||||
|
ret = ov9282_write_reg(ov9282, OV9282_REG_LPFR, 2, lpfr);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
dev_err(ov9282->dev, "Invalid control %d", ctrl->id);
|
dev_err(ov9282->dev, "Invalid control %d", ctrl->id);
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pm_runtime_put(ov9282->dev);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user