diff mbox series

[32/57] media: atomisp: ov2680: Add exposure and gain controls

Message ID 20230123125205.622152-33-hdegoede@redhat.com (mailing list archive)
State New, archived
Headers show
Series media: atomisp: Big power-management changes + lots of fixes | expand

Commit Message

Hans de Goede Jan. 23, 2023, 12:51 p.m. UTC
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.

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(-)

Comments

Andy Shevchenko Jan. 23, 2023, 6:43 p.m. UTC | #1
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
>
diff mbox series

Patch

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;
 };