summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorFrank Chen <frankc@nvidia.com>2012-01-11 10:55:31 -0800
committerVarun Colbert <vcolbert@nvidia.com>2012-01-30 13:21:51 -0800
commitd484b0334ffaa8e7db5746f8c2713486bad2da1e (patch)
tree9f9d24a1e2e871c68f61168cf51a3b488e7e9f55 /drivers
parent133acfe3800e220048a9b568dd2bebcd5bd0b38b (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.c100
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(&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;
}