[v2,13/20] media: i2c: ov4689: Implement digital gain control
Commit Message
The OV4689 sensor supports digital gain up to 16x. Implement
corresponding control in the driver. Default digital gain value is not
modified by this patch.
Signed-off-by: Mikhail Rudenko <mike.rudenko@gmail.com>
---
drivers/media/i2c/ov4689.c | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
Comments
Hi Mikhail,
Thank you for the patch.
On Mon, Dec 18, 2023 at 08:40:34PM +0300, Mikhail Rudenko wrote:
> The OV4689 sensor supports digital gain up to 16x. Implement
> corresponding control in the driver. Default digital gain value is not
> modified by this patch.
>
> Signed-off-by: Mikhail Rudenko <mike.rudenko@gmail.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> ---
> drivers/media/i2c/ov4689.c | 16 ++++++++++++++--
> 1 file changed, 14 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/media/i2c/ov4689.c b/drivers/media/i2c/ov4689.c
> index 6cf986bf305d..579362570ba4 100644
> --- a/drivers/media/i2c/ov4689.c
> +++ b/drivers/media/i2c/ov4689.c
> @@ -35,6 +35,12 @@
> #define OV4689_GAIN_STEP 1
> #define OV4689_GAIN_DEFAULT 0x80
>
> +#define OV4689_REG_DIG_GAIN CCI_REG16(0x352a)
> +#define OV4689_DIG_GAIN_MIN 1
> +#define OV4689_DIG_GAIN_MAX 0x7fff
> +#define OV4689_DIG_GAIN_STEP 1
> +#define OV4689_DIG_GAIN_DEFAULT 0x800
> +
> #define OV4689_REG_HTS CCI_REG16(0x380c)
> #define OV4689_HTS_DIVIDER 4
> #define OV4689_HTS_MAX 0x7fff
> @@ -131,7 +137,6 @@ static const struct cci_reg_sequence ov4689_2688x1520_regs[] = {
>
> /* AEC PK */
> {CCI_REG8(0x3503), 0x04}, /* AEC_MANUAL gain_input_as_sensor_gain_format = 1 */
> - {CCI_REG8(0x352a), 0x08}, /* DIG_GAIN_FRAC_LONG dig_gain_long[14:8] = 0x08 (2x) */
>
> /* ADC and analog control*/
> {CCI_REG8(0x3603), 0x40},
> @@ -624,6 +629,9 @@ static int ov4689_set_ctrl(struct v4l2_ctrl *ctrl)
> OV4689_TIMING_FLIP_MASK,
> ctrl->val ? 0 : OV4689_TIMING_FLIP_BOTH, &ret);
> break;
> + case V4L2_CID_DIGITAL_GAIN:
> + cci_write(regmap, OV4689_REG_DIG_GAIN, ctrl->val, &ret);
> + break;
> default:
> dev_warn(dev, "%s Unhandled id:0x%x, val:0x%x\n",
> __func__, ctrl->id, ctrl->val);
> @@ -654,7 +662,7 @@ static int ov4689_initialize_controls(struct ov4689 *ov4689)
>
> handler = &ov4689->ctrl_handler;
> mode = ov4689->cur_mode;
> - ret = v4l2_ctrl_handler_init(handler, 12);
> + ret = v4l2_ctrl_handler_init(handler, 13);
> if (ret)
> return ret;
>
> @@ -697,6 +705,10 @@ static int ov4689_initialize_controls(struct ov4689 *ov4689)
> v4l2_ctrl_new_std(handler, &ov4689_ctrl_ops, V4L2_CID_VFLIP, 0, 1, 1, 0);
> v4l2_ctrl_new_std(handler, &ov4689_ctrl_ops, V4L2_CID_HFLIP, 0, 1, 1, 0);
>
> + v4l2_ctrl_new_std(handler, &ov4689_ctrl_ops, V4L2_CID_DIGITAL_GAIN,
> + OV4689_DIG_GAIN_MIN, OV4689_DIG_GAIN_MAX,
> + OV4689_DIG_GAIN_STEP, OV4689_DIG_GAIN_DEFAULT);
> +
> if (handler->error) {
> ret = handler->error;
> dev_err(ov4689->dev, "Failed to init controls(%d)\n", ret);
@@ -35,6 +35,12 @@
#define OV4689_GAIN_STEP 1
#define OV4689_GAIN_DEFAULT 0x80
+#define OV4689_REG_DIG_GAIN CCI_REG16(0x352a)
+#define OV4689_DIG_GAIN_MIN 1
+#define OV4689_DIG_GAIN_MAX 0x7fff
+#define OV4689_DIG_GAIN_STEP 1
+#define OV4689_DIG_GAIN_DEFAULT 0x800
+
#define OV4689_REG_HTS CCI_REG16(0x380c)
#define OV4689_HTS_DIVIDER 4
#define OV4689_HTS_MAX 0x7fff
@@ -131,7 +137,6 @@ static const struct cci_reg_sequence ov4689_2688x1520_regs[] = {
/* AEC PK */
{CCI_REG8(0x3503), 0x04}, /* AEC_MANUAL gain_input_as_sensor_gain_format = 1 */
- {CCI_REG8(0x352a), 0x08}, /* DIG_GAIN_FRAC_LONG dig_gain_long[14:8] = 0x08 (2x) */
/* ADC and analog control*/
{CCI_REG8(0x3603), 0x40},
@@ -624,6 +629,9 @@ static int ov4689_set_ctrl(struct v4l2_ctrl *ctrl)
OV4689_TIMING_FLIP_MASK,
ctrl->val ? 0 : OV4689_TIMING_FLIP_BOTH, &ret);
break;
+ case V4L2_CID_DIGITAL_GAIN:
+ cci_write(regmap, OV4689_REG_DIG_GAIN, ctrl->val, &ret);
+ break;
default:
dev_warn(dev, "%s Unhandled id:0x%x, val:0x%x\n",
__func__, ctrl->id, ctrl->val);
@@ -654,7 +662,7 @@ static int ov4689_initialize_controls(struct ov4689 *ov4689)
handler = &ov4689->ctrl_handler;
mode = ov4689->cur_mode;
- ret = v4l2_ctrl_handler_init(handler, 12);
+ ret = v4l2_ctrl_handler_init(handler, 13);
if (ret)
return ret;
@@ -697,6 +705,10 @@ static int ov4689_initialize_controls(struct ov4689 *ov4689)
v4l2_ctrl_new_std(handler, &ov4689_ctrl_ops, V4L2_CID_VFLIP, 0, 1, 1, 0);
v4l2_ctrl_new_std(handler, &ov4689_ctrl_ops, V4L2_CID_HFLIP, 0, 1, 1, 0);
+ v4l2_ctrl_new_std(handler, &ov4689_ctrl_ops, V4L2_CID_DIGITAL_GAIN,
+ OV4689_DIG_GAIN_MIN, OV4689_DIG_GAIN_MAX,
+ OV4689_DIG_GAIN_STEP, OV4689_DIG_GAIN_DEFAULT);
+
if (handler->error) {
ret = handler->error;
dev_err(ov4689->dev, "Failed to init controls(%d)\n", ret);