From ea771845119434207ae0905af33fa10b96dac18b Mon Sep 17 00:00:00 2001 From: Dongbo Yang Date: Fri, 30 Jul 2021 09:50:36 +0800 Subject: [PATCH] media: i2c: add strobe control & fix expsoure for ov9281. Signed-off-by: Dongbo Yang Change-Id: I12ba55000c1814b4aeedc414b9ce7f6ddfb8ed19 --- drivers/media/i2c/ov9281.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/drivers/media/i2c/ov9281.c b/drivers/media/i2c/ov9281.c index 484f0668991a..0897791e1f8d 100644 --- a/drivers/media/i2c/ov9281.c +++ b/drivers/media/i2c/ov9281.c @@ -66,6 +66,15 @@ #define OV9281_REG_VTS 0x380e +#define OV9281_AEC_STROBE_REG 0x3927 +#define OV9281_AEC_STROBE_REG_H 0x3927 +#define OV9281_AEC_STROBE_REG_L 0x3928 + +#define OV9282_AEC_GROUP_UPDATE_ADDRESS 0x3208 +#define OV9282_AEC_GROUP_UPDATE_START_DATA 0x00 +#define OV9282_AEC_GROUP_UPDATE_END_DATA 0x10 +#define OV9282_AEC_GROUP_UPDATE_END_LAUNCH 0xA0 + #define REG_NULL 0xFFFF #define OV9281_REG_VALUE_08BIT 1 @@ -149,6 +158,7 @@ struct ov9281 { struct v4l2_ctrl *hblank; struct v4l2_ctrl *vblank; struct v4l2_ctrl *test_pattern; + struct v4l2_ctrl *strobe; struct mutex mutex; bool streaming; bool power_on; @@ -1080,9 +1090,17 @@ static int ov9281_set_ctrl(struct v4l2_ctrl *ctrl) switch (ctrl->id) { case V4L2_CID_EXPOSURE: + ov9281_write_reg(ov9281->client, OV9282_AEC_GROUP_UPDATE_ADDRESS, + OV9281_REG_VALUE_08BIT, OV9282_AEC_GROUP_UPDATE_START_DATA); + /* 4 least significant bits of expsoure are fractional part */ ret = ov9281_write_reg(ov9281->client, OV9281_REG_EXPOSURE, OV9281_REG_VALUE_24BIT, ctrl->val << 4); + + ov9281_write_reg(ov9281->client, OV9282_AEC_GROUP_UPDATE_ADDRESS, + OV9281_REG_VALUE_08BIT, OV9282_AEC_GROUP_UPDATE_END_DATA); + ov9281_write_reg(ov9281->client, OV9282_AEC_GROUP_UPDATE_ADDRESS, + OV9281_REG_VALUE_08BIT, OV9282_AEC_GROUP_UPDATE_END_LAUNCH); break; case V4L2_CID_ANALOGUE_GAIN: ret = ov9281_write_reg(ov9281->client, OV9281_REG_GAIN_H, @@ -1097,6 +1115,14 @@ static int ov9281_set_ctrl(struct v4l2_ctrl *ctrl) OV9281_REG_VALUE_16BIT, ctrl->val + ov9281->cur_mode->height); break; + case V4L2_CID_BRIGHTNESS: + ret = ov9281_write_reg(ov9281->client, OV9281_AEC_STROBE_REG_H, + OV9281_REG_VALUE_08BIT, + (ctrl->val >> 8) & 0xff); + ret |= ov9281_write_reg(ov9281->client, OV9281_AEC_STROBE_REG_L, + OV9281_REG_VALUE_08BIT, + ctrl->val & 0xff); + break; case V4L2_CID_TEST_PATTERN: ret = ov9281_enable_test_pattern(ov9281, ctrl->val); break; @@ -1162,6 +1188,11 @@ static int ov9281_initialize_controls(struct ov9281 *ov9281) OV9281_GAIN_MAX, OV9281_GAIN_STEP, OV9281_GAIN_DEFAULT); + ov9281->strobe = v4l2_ctrl_new_std(handler, &ov9281_ctrl_ops, + V4L2_CID_BRIGHTNESS, 1, + exposure_max/16, 1, + 0xc8); + ov9281->test_pattern = v4l2_ctrl_new_std_menu_items(handler, &ov9281_ctrl_ops, V4L2_CID_TEST_PATTERN, ARRAY_SIZE(ov9281_test_pattern_menu) - 1,