summaryrefslogtreecommitdiff
path: root/drivers/media/i2c
diff options
context:
space:
mode:
authorAkinobu Mita <akinobu.mita@gmail.com>2019-03-18 11:25:43 -0400
committerMauro Carvalho Chehab <mchehab+samsung@kernel.org>2019-03-29 10:44:47 -0400
commitc4b50cabd6a2c018c5b388392cce4d842d15ad86 (patch)
tree955083dbc92230c31d7efeee51804d3721d41467 /drivers/media/i2c
parent05fa38fd63e557d2681b063f053c5b94d9c442e3 (diff)
media: ov7740: enable to get exposure control in autoexposure mode
The exposure control is clustered with the autoexposure control and flagged as volatile, but the g_volatile_ctrl() doesn't handle V4L2_CID_EXPOSURE_AUTO. So, the value of the exposure control can't be read in autoexposure mode. This enables to get the exposure control in autoexposure mode by making ov7740_get_volatile_ctrl() deal with V4L2_CID_EXPOSURE_AUTO. This also sets the exposure control as volatile by specifying the argument to v4l2_ctrl_auto_cluster() instead of manually flagging it. Cc: Wenyou Yang <wenyou.yang@microchip.com> Cc: Eugen Hristev <eugen.hristev@microchip.com> Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
Diffstat (limited to 'drivers/media/i2c')
-rw-r--r--drivers/media/i2c/ov7740.c28
1 files changed, 25 insertions, 3 deletions
diff --git a/drivers/media/i2c/ov7740.c b/drivers/media/i2c/ov7740.c
index dfece91ce96b..54e80a60aa57 100644
--- a/drivers/media/i2c/ov7740.c
+++ b/drivers/media/i2c/ov7740.c
@@ -448,6 +448,27 @@ static int ov7740_get_gain(struct ov7740 *ov7740, struct v4l2_ctrl *ctrl)
return 0;
}
+static int ov7740_get_exp(struct ov7740 *ov7740, struct v4l2_ctrl *ctrl)
+{
+ struct regmap *regmap = ov7740->regmap;
+ unsigned int value0, value1;
+ int ret;
+
+ if (ctrl->val == V4L2_EXPOSURE_MANUAL)
+ return 0;
+
+ ret = regmap_read(regmap, REG_AEC, &value0);
+ if (ret)
+ return ret;
+ ret = regmap_read(regmap, REG_HAEC, &value1);
+ if (ret)
+ return ret;
+
+ ov7740->exposure->val = (value1 << 8) | (value0 & 0xff);
+
+ return 0;
+}
+
static int ov7740_set_exp(struct regmap *regmap, int value)
{
int ret;
@@ -494,6 +515,9 @@ static int ov7740_get_volatile_ctrl(struct v4l2_ctrl *ctrl)
case V4L2_CID_AUTOGAIN:
ret = ov7740_get_gain(ov7740, ctrl);
break;
+ case V4L2_CID_EXPOSURE_AUTO:
+ ret = ov7740_get_exp(ov7740, ctrl);
+ break;
default:
ret = -EINVAL;
break;
@@ -991,8 +1015,6 @@ static int ov7740_init_controls(struct ov7740 *ov7740)
ov7740->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &ov7740_ctrl_ops,
V4L2_CID_EXPOSURE, 0, 65535, 1, 500);
- if (ov7740->exposure)
- ov7740->exposure->flags |= V4L2_CTRL_FLAG_VOLATILE;
ov7740->auto_exposure = v4l2_ctrl_new_std_menu(ctrl_hdlr,
&ov7740_ctrl_ops,
@@ -1003,7 +1025,7 @@ static int ov7740_init_controls(struct ov7740 *ov7740)
v4l2_ctrl_auto_cluster(3, &ov7740->auto_wb, 0, false);
v4l2_ctrl_auto_cluster(2, &ov7740->auto_gain, 0, true);
v4l2_ctrl_auto_cluster(2, &ov7740->auto_exposure,
- V4L2_EXPOSURE_MANUAL, false);
+ V4L2_EXPOSURE_MANUAL, true);
v4l2_ctrl_cluster(2, &ov7740->hflip);
if (ctrl_hdlr->error) {