]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/commitdiff
media: video: ov5650: add sensor group hold.
authorFrank Chen <frankc@nvidia.com>
Wed, 11 Jan 2012 18:55:31 +0000 (10:55 -0800)
committerDan Willemsen <dwillemsen@nvidia.com>
Sat, 14 Sep 2013 08:03:55 +0000 (01:03 -0700)
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
Rebase-Id: R10124b3d1bc3297da521d73e133ba23cb023f8e5

drivers/media/video/tegra/ov5650.c
include/media/ov5650.h

index e7ebbeb455481df9914a63b97b4ec4c28f62b701..e77ff7b1a74c3333d524890436337def775c3d24 100644 (file)
@@ -1035,51 +1035,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)
@@ -1088,12 +1074,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;
@@ -1308,6 +1335,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;
        }
index 00efcec61a5fd18d35bac88c9c8099dbc493797e..5c4a87cfbe8d377a0bfd2cf24d7c5c6f2f6079e1 100644 (file)
@@ -29,6 +29,7 @@
 #define OV5650_IOCTL_GET_STATUS                        _IOR('o', 5, __u8)
 #define OV5650_IOCTL_SET_BINNING       _IOW('o', 6, __u8)
 #define OV5650_IOCTL_TEST_PATTERN              _IOW('o', 7, enum ov5650_test_pattern)
+#define OV5650_IOCTL_SET_GROUP_HOLD        _IOW('o', 8, struct ov5650_ae)
 #define OV5650_IOCTL_SET_CAMERA_MODE   _IOW('o', 10, __u32)
 #define OV5650_IOCTL_SYNC_SENSORS              _IOW('o', 11, __u32)
 
@@ -71,6 +72,15 @@ struct ov5650_mode {
        __u16 gain;
 };
 
+struct ov5650_ae {
+       __u32 frame_length;
+       __u8 frame_length_enable;
+       __u32 coarse_time;
+       __u8 coarse_time_enable;
+       __s32 gain;
+       __u8 gain_enable;
+};
+
 #ifdef __KERNEL__
 struct ov5650_platform_data {
        int (*power_on)(void);