On Mon, Jan 23, 2023 at 01:51:40PM +0100, Hans de Goede wrote:
> Add exposure and gain controls. This allows controlling
> the exposure and gain through standard v4l2 IOCTLs.
>
> Note the register defines for the exposure and gain registers
> are renamed to match the datasheet.
Reviewed-by: Andy Shevchenko <andy@kernel.org>
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
> .../media/atomisp/i2c/atomisp-ov2680.c | 27 +++++++++++++++----
> drivers/staging/media/atomisp/i2c/ov2680.h | 9 +++----
> 2 files changed, 26 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> index d508c02444eb..14002a1c22d2 100644
> --- a/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> +++ b/drivers/staging/media/atomisp/i2c/atomisp-ov2680.c
> @@ -117,6 +117,16 @@ static int ov2680_set_hflip(struct ov2680_device *sensor, s32 val)
> return 0;
> }
>
> +static int ov2680_exposure_set(struct ov2680_device *sensor, u32 exp)
> +{
> + return ovxxxx_write_reg24(sensor->client, OV2680_REG_EXPOSURE_PK_HIGH, exp << 4);
> +}
> +
> +static int ov2680_gain_set(struct ov2680_device *sensor, u32 gain)
> +{
> + return ovxxxx_write_reg16(sensor->client, OV2680_REG_GAIN_PK, gain);
> +}
> +
> static int ov2680_s_ctrl(struct v4l2_ctrl *ctrl)
> {
> struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
> @@ -135,6 +145,12 @@ static int ov2680_s_ctrl(struct v4l2_ctrl *ctrl)
> case V4L2_CID_HFLIP:
> ret = ov2680_set_hflip(sensor, ctrl->val);
> break;
> + case V4L2_CID_EXPOSURE:
> + ret = ov2680_exposure_set(sensor, ctrl->val);
> + break;
> + case V4L2_CID_GAIN:
> + ret = ov2680_gain_set(sensor, ctrl->val);
> + break;
> default:
> ret = -EINVAL;
> }
> @@ -392,10 +408,7 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd,
> goto err;
> }
>
> - /*
> - * recall flip functions to avoid flip registers
> - * were overridden by default setting
> - */
> + /* Restore value of all ctrls */
> ret = __v4l2_ctrl_handler_setup(&dev->ctrls.handler);
> if (ret < 0)
> goto err;
> @@ -634,13 +647,17 @@ static int ov2680_init_controls(struct ov2680_device *sensor)
> const struct v4l2_ctrl_ops *ops = &ov2680_ctrl_ops;
> struct ov2680_ctrls *ctrls = &sensor->ctrls;
> struct v4l2_ctrl_handler *hdl = &ctrls->handler;
> + int exp_max = sensor->res->lines_per_frame - OV2680_INTEGRATION_TIME_MARGIN;
>
> - v4l2_ctrl_handler_init(hdl, 2);
> + v4l2_ctrl_handler_init(hdl, 4);
>
> hdl->lock = &sensor->input_lock;
>
> ctrls->hflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_HFLIP, 0, 1, 1, 0);
> ctrls->vflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_VFLIP, 0, 1, 1, 0);
> + ctrls->exposure = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_EXPOSURE,
> + 0, exp_max, 1, exp_max);
> + ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAIN, 0, 1023, 1, 250);
>
> ctrls->hflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
> ctrls->vflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
> diff --git a/drivers/staging/media/atomisp/i2c/ov2680.h b/drivers/staging/media/atomisp/i2c/ov2680.h
> index 45eb1f93b847..e3ad20a7ffd5 100644
> --- a/drivers/staging/media/atomisp/i2c/ov2680.h
> +++ b/drivers/staging/media/atomisp/i2c/ov2680.h
> @@ -90,11 +90,8 @@
>
> #define OV2680_GROUP_ACCESS 0x3208 /*Bit[7:4] Group control, Bit[3:0] Group ID*/
>
> -#define OV2680_EXPOSURE_H 0x3500 /*Bit[3:0] Bit[19:16] of exposure, remaining 16 bits lies in Reg0x3501&Reg0x3502*/
> -#define OV2680_EXPOSURE_M 0x3501
> -#define OV2680_EXPOSURE_L 0x3502
> -#define OV2680_AGC_H 0x350A /*Bit[1:0] means Bit[9:8] of gain*/
> -#define OV2680_AGC_L 0x350B /*Bit[7:0] of gain*/
> +#define OV2680_REG_EXPOSURE_PK_HIGH 0x3500
> +#define OV2680_REG_GAIN_PK 0x350a
>
> #define OV2680_HORIZONTAL_START_H 0x3800 /*Bit[11:8]*/
> #define OV2680_HORIZONTAL_START_L 0x3801 /*Bit[7:0]*/
> @@ -172,6 +169,8 @@ struct ov2680_device {
> struct v4l2_ctrl_handler handler;
> struct v4l2_ctrl *hflip;
> struct v4l2_ctrl *vflip;
> + struct v4l2_ctrl *exposure;
> + struct v4l2_ctrl *gain;
> } ctrls;
> };
>
> --
> 2.39.0
>
@@ -117,6 +117,16 @@ static int ov2680_set_hflip(struct ov2680_device *sensor, s32 val)
return 0;
}
+static int ov2680_exposure_set(struct ov2680_device *sensor, u32 exp)
+{
+ return ovxxxx_write_reg24(sensor->client, OV2680_REG_EXPOSURE_PK_HIGH, exp << 4);
+}
+
+static int ov2680_gain_set(struct ov2680_device *sensor, u32 gain)
+{
+ return ovxxxx_write_reg16(sensor->client, OV2680_REG_GAIN_PK, gain);
+}
+
static int ov2680_s_ctrl(struct v4l2_ctrl *ctrl)
{
struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
@@ -135,6 +145,12 @@ static int ov2680_s_ctrl(struct v4l2_ctrl *ctrl)
case V4L2_CID_HFLIP:
ret = ov2680_set_hflip(sensor, ctrl->val);
break;
+ case V4L2_CID_EXPOSURE:
+ ret = ov2680_exposure_set(sensor, ctrl->val);
+ break;
+ case V4L2_CID_GAIN:
+ ret = ov2680_gain_set(sensor, ctrl->val);
+ break;
default:
ret = -EINVAL;
}
@@ -392,10 +408,7 @@ static int ov2680_set_fmt(struct v4l2_subdev *sd,
goto err;
}
- /*
- * recall flip functions to avoid flip registers
- * were overridden by default setting
- */
+ /* Restore value of all ctrls */
ret = __v4l2_ctrl_handler_setup(&dev->ctrls.handler);
if (ret < 0)
goto err;
@@ -634,13 +647,17 @@ static int ov2680_init_controls(struct ov2680_device *sensor)
const struct v4l2_ctrl_ops *ops = &ov2680_ctrl_ops;
struct ov2680_ctrls *ctrls = &sensor->ctrls;
struct v4l2_ctrl_handler *hdl = &ctrls->handler;
+ int exp_max = sensor->res->lines_per_frame - OV2680_INTEGRATION_TIME_MARGIN;
- v4l2_ctrl_handler_init(hdl, 2);
+ v4l2_ctrl_handler_init(hdl, 4);
hdl->lock = &sensor->input_lock;
ctrls->hflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_HFLIP, 0, 1, 1, 0);
ctrls->vflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_VFLIP, 0, 1, 1, 0);
+ ctrls->exposure = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_EXPOSURE,
+ 0, exp_max, 1, exp_max);
+ ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAIN, 0, 1023, 1, 250);
ctrls->hflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
ctrls->vflip->flags |= V4L2_CTRL_FLAG_MODIFY_LAYOUT;
@@ -90,11 +90,8 @@
#define OV2680_GROUP_ACCESS 0x3208 /*Bit[7:4] Group control, Bit[3:0] Group ID*/
-#define OV2680_EXPOSURE_H 0x3500 /*Bit[3:0] Bit[19:16] of exposure, remaining 16 bits lies in Reg0x3501&Reg0x3502*/
-#define OV2680_EXPOSURE_M 0x3501
-#define OV2680_EXPOSURE_L 0x3502
-#define OV2680_AGC_H 0x350A /*Bit[1:0] means Bit[9:8] of gain*/
-#define OV2680_AGC_L 0x350B /*Bit[7:0] of gain*/
+#define OV2680_REG_EXPOSURE_PK_HIGH 0x3500
+#define OV2680_REG_GAIN_PK 0x350a
#define OV2680_HORIZONTAL_START_H 0x3800 /*Bit[11:8]*/
#define OV2680_HORIZONTAL_START_L 0x3801 /*Bit[7:0]*/
@@ -172,6 +169,8 @@ struct ov2680_device {
struct v4l2_ctrl_handler handler;
struct v4l2_ctrl *hflip;
struct v4l2_ctrl *vflip;
+ struct v4l2_ctrl *exposure;
+ struct v4l2_ctrl *gain;
} ctrls;
};