mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-16 14:51:51 -04:00
media: i2c: ov9282: dynamic flash_duration maximum
This patch sets the current exposure time as maximum for the flash_duration control. As Flash/Strobes which are longer than the exposure time have no effect. Signed-off-by: Richard Leitner <richard.leitner@linux.dev> [Sakari Ailus: Some lines rewrapped.] Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
This commit is contained in:
committed by
Hans Verkuil
parent
b95d8058a2
commit
df60764ea5
@@ -199,6 +199,7 @@ struct ov9282_mode {
|
||||
* @exp_ctrl: Pointer to exposure control
|
||||
* @again_ctrl: Pointer to analog gain control
|
||||
* @pixel_rate: Pointer to pixel rate control
|
||||
* @flash_duration: Pointer to flash duration control
|
||||
* @vblank: Vertical blanking in lines
|
||||
* @noncontinuous_clock: Selection of CSI2 noncontinuous clock mode
|
||||
* @cur_mode: Pointer to current selected sensor mode
|
||||
@@ -221,6 +222,7 @@ struct ov9282 {
|
||||
struct v4l2_ctrl *again_ctrl;
|
||||
};
|
||||
struct v4l2_ctrl *pixel_rate;
|
||||
struct v4l2_ctrl *flash_duration;
|
||||
u32 vblank;
|
||||
bool noncontinuous_clock;
|
||||
const struct ov9282_mode *cur_mode;
|
||||
@@ -612,6 +614,15 @@ static int ov9282_update_controls(struct ov9282 *ov9282,
|
||||
mode->vblank_max, 1, mode->vblank);
|
||||
}
|
||||
|
||||
static u32 ov9282_exposure_to_us(struct ov9282 *ov9282, u32 exposure)
|
||||
{
|
||||
/* calculate exposure time in µs */
|
||||
u32 frame_width = ov9282->cur_mode->width + ov9282->hblank_ctrl->val;
|
||||
u32 trow_us = frame_width / (ov9282->pixel_rate->val / 1000000UL);
|
||||
|
||||
return exposure * trow_us;
|
||||
}
|
||||
|
||||
/**
|
||||
* ov9282_update_exp_gain() - Set updated exposure and gain
|
||||
* @ov9282: pointer to ov9282 device
|
||||
@@ -623,9 +634,10 @@ static int ov9282_update_controls(struct ov9282 *ov9282,
|
||||
static int ov9282_update_exp_gain(struct ov9282 *ov9282, u32 exposure, u32 gain)
|
||||
{
|
||||
int ret;
|
||||
u32 exposure_us = ov9282_exposure_to_us(ov9282, exposure);
|
||||
|
||||
dev_dbg(ov9282->dev, "Set exp %u, analog gain %u",
|
||||
exposure, gain);
|
||||
dev_dbg(ov9282->dev, "Set exp %u (~%u us), analog gain %u",
|
||||
exposure, exposure_us, gain);
|
||||
|
||||
ret = ov9282_write_reg(ov9282, OV9282_REG_HOLD, 1, 1);
|
||||
if (ret)
|
||||
@@ -636,6 +648,12 @@ static int ov9282_update_exp_gain(struct ov9282 *ov9282, u32 exposure, u32 gain)
|
||||
goto error_release_group_hold;
|
||||
|
||||
ret = ov9282_write_reg(ov9282, OV9282_REG_AGAIN, 1, gain);
|
||||
if (ret)
|
||||
goto error_release_group_hold;
|
||||
|
||||
ret = __v4l2_ctrl_modify_range(ov9282->flash_duration,
|
||||
0, exposure_us, 1,
|
||||
OV9282_STROBE_FRAME_SPAN_DEFAULT);
|
||||
|
||||
error_release_group_hold:
|
||||
ov9282_write_reg(ov9282, OV9282_REG_HOLD, 1, 0);
|
||||
@@ -1431,6 +1449,7 @@ static int ov9282_init_controls(struct ov9282 *ov9282)
|
||||
const struct ov9282_mode *mode = ov9282->cur_mode;
|
||||
struct v4l2_fwnode_device_properties props;
|
||||
u32 hblank_min;
|
||||
u32 exposure_us;
|
||||
u32 lpfr;
|
||||
int ret;
|
||||
|
||||
@@ -1503,8 +1522,11 @@ static int ov9282_init_controls(struct ov9282 *ov9282)
|
||||
v4l2_ctrl_new_std(ctrl_hdlr, &ov9282_ctrl_ops,
|
||||
V4L2_CID_FLASH_STROBE_OE, 0, 1, 1, 0);
|
||||
|
||||
v4l2_ctrl_new_std(ctrl_hdlr, &ov9282_ctrl_ops, V4L2_CID_FLASH_DURATION,
|
||||
0, 13900, 1, 8);
|
||||
exposure_us = ov9282_exposure_to_us(ov9282, OV9282_EXPOSURE_DEFAULT);
|
||||
ov9282->flash_duration =
|
||||
v4l2_ctrl_new_std(ctrl_hdlr, &ov9282_ctrl_ops,
|
||||
V4L2_CID_FLASH_DURATION, 0, exposure_us, 1,
|
||||
OV9282_STROBE_FRAME_SPAN_DEFAULT);
|
||||
|
||||
ret = v4l2_fwnode_device_parse(ov9282->dev, &props);
|
||||
if (!ret) {
|
||||
|
||||
Reference in New Issue
Block a user