diff options
author | Frank Chen <frankc@nvidia.com> | 2012-01-11 10:55:31 -0800 |
---|---|---|
committer | Varun Colbert <vcolbert@nvidia.com> | 2012-01-30 13:21:51 -0800 |
commit | d484b0334ffaa8e7db5746f8c2713486bad2da1e (patch) | |
tree | 9f9d24a1e2e871c68f61168cf51a3b488e7e9f55 /drivers | |
parent | 133acfe3800e220048a9b568dd2bebcd5bd0b38b (diff) |
media: video: ov5650: add sensor group hold.
Grouphold gain and coarse_time register writes.
Make gain and coarse_time set in one ioctl call.
Bug 924213
Reviewed-on: http://git-master/r/74622
Change-Id: I648e4c24c1a048629757abc21afba092d1484d04
Signed-off-by: Yining Deng <ydeng@nvidia.com>
Signed-off-by: Varun Wadekar <vwadekar@nvidia.com>
Reviewed-on: http://git-master/r/77762
Reviewed-by: Automatic_Commit_Validation_User
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/media/video/tegra/ov5650.c | 100 |
1 files changed, 69 insertions, 31 deletions
diff --git a/drivers/media/video/tegra/ov5650.c b/drivers/media/video/tegra/ov5650.c index cc50e9141e66..3adb46a3bb80 100644 --- a/drivers/media/video/tegra/ov5650.c +++ b/drivers/media/video/tegra/ov5650.c @@ -1033,51 +1033,37 @@ static int ov5650_set_mode(struct ov5650_info *info, struct ov5650_mode *mode) static int ov5650_set_frame_length(struct ov5650_info *info, u32 frame_length) { - struct ov5650_reg reg_list[2]; - int i = 0; int ret; + struct ov5650_reg reg_list[2]; + u8 *b_ptr = info->i2c_trans_buf; ov5650_get_frame_length_regs(reg_list, frame_length); - for (i = 0; i < 2; i++) { - ret = ov5650_write_reg_helper(info, reg_list[i].addr, - reg_list[i].val); - if (ret) - return ret; - } + *b_ptr++ = reg_list[0].addr >> 8; + *b_ptr++ = reg_list[0].addr & 0xff; + *b_ptr++ = reg_list[0].val & 0xff; + *b_ptr++ = reg_list[1].val & 0xff; + ret = ov5650_write_bulk_reg_helper(info, 4); - return 0; + return ret; } static int ov5650_set_coarse_time(struct ov5650_info *info, u32 coarse_time) { int ret; - struct ov5650_reg reg_list[3]; - int i = 0; + u8 *b_ptr = info->i2c_trans_buf; ov5650_get_coarse_time_regs(reg_list, coarse_time); - ret = ov5650_write_reg_helper(info, 0x3212, 0x01); - if (ret) - return ret; - - for (i = 0; i < 3; i++) { - ret = ov5650_write_reg_helper(info, reg_list[i].addr, - reg_list[i].val); - if (ret) - return ret; - } - - ret = ov5650_write_reg_helper(info, 0x3212, 0x11); - if (ret) - return ret; - - ret = ov5650_write_reg_helper(info, 0x3212, 0xa1); - if (ret) - return ret; + *b_ptr++ = reg_list[0].addr >> 8; + *b_ptr++ = reg_list[0].addr & 0xff; + *b_ptr++ = reg_list[0].val & 0xff; + *b_ptr++ = reg_list[1].val & 0xff; + *b_ptr++ = reg_list[2].val & 0xff; + ret = ov5650_write_bulk_reg_helper(info, 5); - return 0; + return ret; } static int ov5650_set_gain(struct ov5650_info *info, u16 gain) @@ -1086,12 +1072,53 @@ static int ov5650_set_gain(struct ov5650_info *info, u16 gain) struct ov5650_reg reg_list; ov5650_get_gain_reg(®_list, gain); - ret = ov5650_write_reg_helper(info, reg_list.addr, reg_list.val); return ret; } +static int ov5650_set_group_hold(struct ov5650_info *info, struct ov5650_ae *ae) +{ + int ret; + int count = 0; + bool groupHoldEnabled = false; + + if (ae->gain_enable) + count++; + if (ae->coarse_time_enable) + count++; + if (ae->frame_length_enable) + count++; + if (count >= 2) + groupHoldEnabled = true; + + if (groupHoldEnabled) { + ret = ov5650_write_reg_helper(info, 0x3212, 0x01); + if (ret) + return ret; + } + + if (ae->gain_enable) + ov5650_set_gain(info, ae->gain); + if (ae->coarse_time_enable) + ov5650_set_coarse_time(info, ae->coarse_time); + if (ae->frame_length_enable) + ov5650_set_frame_length(info, ae->frame_length); + + if (groupHoldEnabled) { + ret = ov5650_write_reg_helper(info, 0x3212, 0x11); + if (ret) + return ret; + + ret = ov5650_write_reg_helper(info, 0x3212, 0xa1); + if (ret) + return ret; + } + + return 0; +} + + static int ov5650_set_binning(struct ov5650_info *info, u8 enable) { s32 ret; @@ -1306,6 +1333,17 @@ static long ov5650_ioctl(struct file *file, pr_err("%s %d %d\n", __func__, __LINE__, err); return err; } + case OV5650_IOCTL_SET_GROUP_HOLD: + { + struct ov5650_ae ae; + if (copy_from_user(&ae, + (const void __user *)arg, + sizeof(struct ov5650_ae))) { + pr_info("%s %d\n", __func__, __LINE__); + return -EFAULT; + } + return ov5650_set_group_hold(info, &ae); + } default: return -EINVAL; } |