diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2014-07-07 10:17:56 +0200 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2014-07-07 10:17:56 +0200 |
commit | f1615bbe9be4def59c3b3eaddb60722efeed16c2 (patch) | |
tree | ca3020e65447576fc1826e819651e6ba072030b5 /drivers/media/i2c/mt9p031.c | |
parent | cfb3c0ab0903abb6ea5215b37eebd9c2a1f057eb (diff) | |
parent | cd3de83f147601356395b57a8673e9c5ff1e59d1 (diff) |
Merge tag 'v3.16-rc4' into drm-intel-next-queued
Due to Dave's vacation drm-next hasn't opened yet for 3.17 so I
couldn't move my drm-intel-next queue forward yet like I usually do.
Just pull in the latest upstream -rc to unblock patch merging - I
don't want to needlessly rebase my current patch pile really and void
all the testing we've done already.
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/media/i2c/mt9p031.c')
-rw-r--r-- | drivers/media/i2c/mt9p031.c | 53 |
1 files changed, 39 insertions, 14 deletions
diff --git a/drivers/media/i2c/mt9p031.c b/drivers/media/i2c/mt9p031.c index 33daace8129..e18797ff7fa 100644 --- a/drivers/media/i2c/mt9p031.c +++ b/drivers/media/i2c/mt9p031.c @@ -647,6 +647,28 @@ static int mt9p031_set_crop(struct v4l2_subdev *subdev, #define V4L2_CID_BLC_ANALOG_OFFSET (V4L2_CID_USER_BASE | 0x1004) #define V4L2_CID_BLC_DIGITAL_OFFSET (V4L2_CID_USER_BASE | 0x1005) +static int mt9p031_restore_blc(struct mt9p031 *mt9p031) +{ + struct i2c_client *client = v4l2_get_subdevdata(&mt9p031->subdev); + int ret; + + if (mt9p031->blc_auto->cur.val != 0) { + ret = mt9p031_set_mode2(mt9p031, 0, + MT9P031_READ_MODE_2_ROW_BLC); + if (ret < 0) + return ret; + } + + if (mt9p031->blc_offset->cur.val != 0) { + ret = mt9p031_write(client, MT9P031_ROW_BLACK_TARGET, + mt9p031->blc_offset->cur.val); + if (ret < 0) + return ret; + } + + return 0; +} + static int mt9p031_s_ctrl(struct v4l2_ctrl *ctrl) { struct mt9p031 *mt9p031 = @@ -655,6 +677,9 @@ static int mt9p031_s_ctrl(struct v4l2_ctrl *ctrl) u16 data; int ret; + if (ctrl->flags & V4L2_CTRL_FLAG_INACTIVE) + return 0; + switch (ctrl->id) { case V4L2_CID_EXPOSURE: ret = mt9p031_write(client, MT9P031_SHUTTER_WIDTH_UPPER, @@ -709,18 +734,20 @@ static int mt9p031_s_ctrl(struct v4l2_ctrl *ctrl) MT9P031_READ_MODE_2_ROW_MIR, 0); case V4L2_CID_TEST_PATTERN: + /* The digital side of the Black Level Calibration function must + * be disabled when generating a test pattern to avoid artifacts + * in the image. Activate (deactivate) the BLC-related controls + * when the test pattern is enabled (disabled). + */ + v4l2_ctrl_activate(mt9p031->blc_auto, ctrl->val == 0); + v4l2_ctrl_activate(mt9p031->blc_offset, ctrl->val == 0); + if (!ctrl->val) { - /* Restore the black level compensation settings. */ - if (mt9p031->blc_auto->cur.val != 0) { - ret = mt9p031_s_ctrl(mt9p031->blc_auto); - if (ret < 0) - return ret; - } - if (mt9p031->blc_offset->cur.val != 0) { - ret = mt9p031_s_ctrl(mt9p031->blc_offset); - if (ret < 0) - return ret; - } + /* Restore the BLC settings. */ + ret = mt9p031_restore_blc(mt9p031); + if (ret < 0) + return ret; + return mt9p031_write(client, MT9P031_TEST_PATTERN, MT9P031_TEST_PATTERN_DISABLE); } @@ -735,9 +762,7 @@ static int mt9p031_s_ctrl(struct v4l2_ctrl *ctrl) if (ret < 0) return ret; - /* Disable digital black level compensation when using a test - * pattern. - */ + /* Disable digital BLC when generating a test pattern. */ ret = mt9p031_set_mode2(mt9p031, MT9P031_READ_MODE_2_ROW_BLC, 0); if (ret < 0) |