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>
---
drivers/media/i2c/ov9282.c | 30 ++++++++++++++++++++++++++----
1 file changed, 26 insertions(+), 4 deletions(-)
diff --git a/drivers/media/i2c/ov9282.c b/drivers/media/i2c/ov9282.c
index b104ae77f00e9e7777342e48b7bf3caa6d297f69..3253d9f271cb3caef6d85837ebec4f5beb466a4d 100644
--- a/drivers/media/i2c/ov9282.c
+++ b/drivers/media/i2c/ov9282.c
@@ -198,6 +198,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
@@ -220,6 +221,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;
@@ -611,6 +613,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 * 1000000UL) / ov9282->pixel_rate->val;
+
+ return exposure * trow_us;
+}
+
/**
* ov9282_update_exp_gain() - Set updated exposure and gain
* @ov9282: pointer to ov9282 device
@@ -622,9 +633,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)
@@ -635,6 +647,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_FLASH_DURATION_DEFAULT);
error_release_group_hold:
ov9282_write_reg(ov9282, OV9282_REG_HOLD, 1, 0);
@@ -1420,6 +1438,7 @@ static int ov9282_init_controls(struct ov9282 *ov9282)
struct v4l2_fwnode_device_properties props;
struct v4l2_ctrl *ctrl;
u32 hblank_min;
+ u32 exposure_us;
u32 lpfr;
int ret;
@@ -1491,8 +1510,11 @@ static int ov9282_init_controls(struct ov9282 *ov9282)
/* Flash/Strobe controls */
v4l2_ctrl_new_std(ctrl_hdlr, &ov9282_ctrl_ops, V4L2_CID_FLASH_HW_STROBE_SIGNAL, 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_FLASH_DURATION_DEFAULT);
ctrl = v4l2_ctrl_new_std_menu(ctrl_hdlr, &ov9282_ctrl_ops,
V4L2_CID_FLASH_STROBE_SOURCE,
--
2.47.2
Hi Richard, On Mon, Sep 01, 2025 at 05:05:15PM +0200, Richard Leitner wrote: > 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> > --- > drivers/media/i2c/ov9282.c | 30 ++++++++++++++++++++++++++---- > 1 file changed, 26 insertions(+), 4 deletions(-) > > diff --git a/drivers/media/i2c/ov9282.c b/drivers/media/i2c/ov9282.c > index b104ae77f00e9e7777342e48b7bf3caa6d297f69..3253d9f271cb3caef6d85837ebec4f5beb466a4d 100644 > --- a/drivers/media/i2c/ov9282.c > +++ b/drivers/media/i2c/ov9282.c > @@ -198,6 +198,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 > @@ -220,6 +221,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; > @@ -611,6 +613,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 * 1000000UL) / ov9282->pixel_rate->val; Redundant parentheses. > + > + return exposure * trow_us; > +} > + > /** > * ov9282_update_exp_gain() - Set updated exposure and gain > * @ov9282: pointer to ov9282 device > @@ -622,9 +633,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) > @@ -635,6 +647,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_FLASH_DURATION_DEFAULT); > > error_release_group_hold: > ov9282_write_reg(ov9282, OV9282_REG_HOLD, 1, 0); > @@ -1420,6 +1438,7 @@ static int ov9282_init_controls(struct ov9282 *ov9282) > struct v4l2_fwnode_device_properties props; > struct v4l2_ctrl *ctrl; > u32 hblank_min; > + u32 exposure_us; > u32 lpfr; > int ret; > > @@ -1491,8 +1510,11 @@ static int ov9282_init_controls(struct ov9282 *ov9282) > /* Flash/Strobe controls */ > v4l2_ctrl_new_std(ctrl_hdlr, &ov9282_ctrl_ops, V4L2_CID_FLASH_HW_STROBE_SIGNAL, 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_FLASH_DURATION_DEFAULT); Wrap this differently, please, e.g. after '='. > > ctrl = v4l2_ctrl_new_std_menu(ctrl_hdlr, &ov9282_ctrl_ops, > V4L2_CID_FLASH_STROBE_SOURCE, > To me the set looks good but I wouldn't mind about having a bit more review. -- Kind regards, Sakari Ailus
Hi Sakari, On Tue, Sep 02, 2025 at 12:16:51AM +0300, Sakari Ailus wrote: > Hi Richard, > > On Mon, Sep 01, 2025 at 05:05:15PM +0200, Richard Leitner wrote: > > 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> > > --- > > drivers/media/i2c/ov9282.c | 30 ++++++++++++++++++++++++++---- > > 1 file changed, 26 insertions(+), 4 deletions(-) > > > > diff --git a/drivers/media/i2c/ov9282.c b/drivers/media/i2c/ov9282.c > > index b104ae77f00e9e7777342e48b7bf3caa6d297f69..3253d9f271cb3caef6d85837ebec4f5beb466a4d 100644 > > --- a/drivers/media/i2c/ov9282.c > > +++ b/drivers/media/i2c/ov9282.c > > @@ -198,6 +198,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 > > @@ -220,6 +221,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; > > @@ -611,6 +613,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 * 1000000UL) / ov9282->pixel_rate->val; > > Redundant parentheses. True. Will fix this. Thanks for the catch. > > > + > > + return exposure * trow_us; > > +} > > + > > /** > > * ov9282_update_exp_gain() - Set updated exposure and gain > > * @ov9282: pointer to ov9282 device > > @@ -622,9 +633,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) > > @@ -635,6 +647,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_FLASH_DURATION_DEFAULT); > > > > error_release_group_hold: > > ov9282_write_reg(ov9282, OV9282_REG_HOLD, 1, 0); > > @@ -1420,6 +1438,7 @@ static int ov9282_init_controls(struct ov9282 *ov9282) > > struct v4l2_fwnode_device_properties props; > > struct v4l2_ctrl *ctrl; > > u32 hblank_min; > > + u32 exposure_us; > > u32 lpfr; > > int ret; > > > > @@ -1491,8 +1510,11 @@ static int ov9282_init_controls(struct ov9282 *ov9282) > > /* Flash/Strobe controls */ > > v4l2_ctrl_new_std(ctrl_hdlr, &ov9282_ctrl_ops, V4L2_CID_FLASH_HW_STROBE_SIGNAL, 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_FLASH_DURATION_DEFAULT); > > Wrap this differently, please, e.g. after '='. This is wrapped the same way as all other v4l2_ctrl_new_X() calls in ov9282_init_controls(). Therefore I've chosen to do it this way here too. So if I'm going to change this one, IMHO all others should be changed too (exp_ctrl, again_ctrl, vblank_ctrl, pixel_rate, link_freq_ctrl, hblank_ctrl). Is this intended? If so I'm wondering if this would be a suiteable approach? ov9282->flash_duration = v4l2_ctrl_new_std(ctrl_hdlr, &ov9282_ctrl_ops, V4L2_CID_FLASH_DURATION, 0, exposure_us, 1, OV9282_FLASH_DURATION_DEFAULT); It is fine for checkpatch, but introduces a newline for every ctrl and tbh I'm not sure if it improves readability? > > > > > ctrl = v4l2_ctrl_new_std_menu(ctrl_hdlr, &ov9282_ctrl_ops, > > V4L2_CID_FLASH_STROBE_SOURCE, > > > > To me the set looks good but I wouldn't mind about having a bit more > review. Thanks for your continuous feedback! It improved the series a lot! Is there anyhthing I can assists/help? > > -- > Kind regards, > > Sakari Ailus regards;rl
Hi Richard, On Wed, Sep 03, 2025 at 09:13:35AM +0200, Richard Leitner wrote: > > > @@ -1491,8 +1510,11 @@ static int ov9282_init_controls(struct ov9282 *ov9282) > > > /* Flash/Strobe controls */ > > > v4l2_ctrl_new_std(ctrl_hdlr, &ov9282_ctrl_ops, V4L2_CID_FLASH_HW_STROBE_SIGNAL, 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_FLASH_DURATION_DEFAULT); > > > > Wrap this differently, please, e.g. after '='. > > This is wrapped the same way as all other v4l2_ctrl_new_X() calls in > ov9282_init_controls(). Therefore I've chosen to do it this way here > too. > > So if I'm going to change this one, IMHO all others should be changed > too (exp_ctrl, again_ctrl, vblank_ctrl, pixel_rate, link_freq_ctrl, > hblank_ctrl). Is this intended? > > If so I'm wondering if this would be a suiteable approach? > > ov9282->flash_duration = > v4l2_ctrl_new_std(ctrl_hdlr, > &ov9282_ctrl_ops, V4L2_CID_FLASH_DURATION, > 0, exposure_us, > 1, OV9282_FLASH_DURATION_DEFAULT); > > It is fine for checkpatch, but introduces a newline for every ctrl and > tbh I'm not sure if it improves readability? I don't think it's worse at least. You can also rewrap the rest of the lines: ov9282->flash_duration = v4l2_ctrl_new_std(ctrl_hdlr, &ov9282_ctrl_ops, V4L2_CID_FLASH_DURATION, 0, exposure_us, 1, OV9282_FLASH_DURATION_DEFAULT); > > > ctrl = v4l2_ctrl_new_std_menu(ctrl_hdlr, &ov9282_ctrl_ops, > > > V4L2_CID_FLASH_STROBE_SOURCE, > > > > > > > To me the set looks good but I wouldn't mind about having a bit more > > review. > > Thanks for your continuous feedback! It improved the series a lot! > > Is there anyhthing I can assists/help? I asked Laurent if he could check this out, it'd be nice to get these to 6.18. -- Kind regards, Sakari Ailus
Hi Sakari, On Wed, Sep 03, 2025 at 10:48:48AM +0300, Sakari Ailus wrote: > Hi Richard, > > On Wed, Sep 03, 2025 at 09:13:35AM +0200, Richard Leitner wrote: > > > > @@ -1491,8 +1510,11 @@ static int ov9282_init_controls(struct ov9282 *ov9282) > > > > /* Flash/Strobe controls */ > > > > v4l2_ctrl_new_std(ctrl_hdlr, &ov9282_ctrl_ops, V4L2_CID_FLASH_HW_STROBE_SIGNAL, 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_FLASH_DURATION_DEFAULT); > > > > > > Wrap this differently, please, e.g. after '='. > > > > This is wrapped the same way as all other v4l2_ctrl_new_X() calls in > > ov9282_init_controls(). Therefore I've chosen to do it this way here > > too. > > > > So if I'm going to change this one, IMHO all others should be changed > > too (exp_ctrl, again_ctrl, vblank_ctrl, pixel_rate, link_freq_ctrl, > > hblank_ctrl). Is this intended? > > > > If so I'm wondering if this would be a suiteable approach? > > > > ov9282->flash_duration = > > v4l2_ctrl_new_std(ctrl_hdlr, > > &ov9282_ctrl_ops, V4L2_CID_FLASH_DURATION, > > 0, exposure_us, > > 1, OV9282_FLASH_DURATION_DEFAULT); > > > > It is fine for checkpatch, but introduces a newline for every ctrl and > > tbh I'm not sure if it improves readability? > > I don't think it's worse at least. You can also rewrap the rest of the > lines: > > ov9282->flash_duration = > v4l2_ctrl_new_std(ctrl_hdlr, &ov9282_ctrl_ops, > V4L2_CID_FLASH_DURATION, 0, exposure_us, 1, > OV9282_FLASH_DURATION_DEFAULT); > Ok. Fine with me ;) So I will adapt this patch and add a new patch which changes the wrapping for all remaining v4l2_ctrl_new_X() calls in ov9282_init_controls() to the series and send a v8? Or should I wait for feedback from Laurent for v8? > > > > ctrl = v4l2_ctrl_new_std_menu(ctrl_hdlr, &ov9282_ctrl_ops, > > > > V4L2_CID_FLASH_STROBE_SOURCE, > > > > > > > > > > To me the set looks good but I wouldn't mind about having a bit more > > > review. > > > > Thanks for your continuous feedback! It improved the series a lot! > > > > Is there anyhthing I can assists/help? > > I asked Laurent if he could check this out, it'd be nice to get these to > 6.18. Nice. Thanks! Yeah, that would be nice, indeed :) > > -- > Kind regards, > > Sakari Ailus regards;rl
Hi Richard, On Wed, Sep 03, 2025 at 10:24:46AM +0200, Richard Leitner wrote: > Hi Sakari, > > On Wed, Sep 03, 2025 at 10:48:48AM +0300, Sakari Ailus wrote: > > Hi Richard, > > > > On Wed, Sep 03, 2025 at 09:13:35AM +0200, Richard Leitner wrote: > > > > > @@ -1491,8 +1510,11 @@ static int ov9282_init_controls(struct ov9282 *ov9282) > > > > > /* Flash/Strobe controls */ > > > > > v4l2_ctrl_new_std(ctrl_hdlr, &ov9282_ctrl_ops, V4L2_CID_FLASH_HW_STROBE_SIGNAL, 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_FLASH_DURATION_DEFAULT); > > > > > > > > Wrap this differently, please, e.g. after '='. > > > > > > This is wrapped the same way as all other v4l2_ctrl_new_X() calls in > > > ov9282_init_controls(). Therefore I've chosen to do it this way here > > > too. > > > > > > So if I'm going to change this one, IMHO all others should be changed > > > too (exp_ctrl, again_ctrl, vblank_ctrl, pixel_rate, link_freq_ctrl, > > > hblank_ctrl). Is this intended? > > > > > > If so I'm wondering if this would be a suiteable approach? > > > > > > ov9282->flash_duration = > > > v4l2_ctrl_new_std(ctrl_hdlr, > > > &ov9282_ctrl_ops, V4L2_CID_FLASH_DURATION, > > > 0, exposure_us, > > > 1, OV9282_FLASH_DURATION_DEFAULT); > > > > > > It is fine for checkpatch, but introduces a newline for every ctrl and > > > tbh I'm not sure if it improves readability? > > > > I don't think it's worse at least. You can also rewrap the rest of the > > lines: > > > > ov9282->flash_duration = > > v4l2_ctrl_new_std(ctrl_hdlr, &ov9282_ctrl_ops, > > V4L2_CID_FLASH_DURATION, 0, exposure_us, 1, > > OV9282_FLASH_DURATION_DEFAULT); > > > > Ok. Fine with me ;) > > So I will adapt this patch and add a new patch which changes the wrapping > for all remaining v4l2_ctrl_new_X() calls in ov9282_init_controls() to the > series and send a v8? Or should I wait for feedback from Laurent for v8? Let's wait for Laurent to review this first. The changes I asked for are minor. -- Sakari Ailus
© 2016 - 2025 Red Hat, Inc.