diff options
author | Qinggang Zhou <qzhou@nvidia.com> | 2011-09-20 16:37:00 -0700 |
---|---|---|
committer | Varun Colbert <vcolbert@nvidia.com> | 2011-11-04 11:09:47 -0700 |
commit | 8ae2be6646c83e206af4c046f397807030121ab3 (patch) | |
tree | 023e8e6dc5ab8238d361c29e4bfb541d3abecd1c | |
parent | 920eeed63d1f37b8ab6b60bbb98c58297174a442 (diff) |
ov5650: add fast set_mode
Resetting the mode does not need to reset all of the i2c
registers. This used to be called "fast set_mode". This
is added into the kernel driver in this change. This
change reduced 90ms from resetting the mode. It only
apply to still preview and capture resolutions
bug 816814
Reviewed-on: http://git-master/r/53587
(cherry picked from commit e0f1e9c61daa5faacb0e5cb404357f7e3284c8ae)
Change-Id: I5027bad3cd534e850791b26a118783db441c45ef
Reviewed-on: http://git-master/r/59660
Reviewed-by: Varun Colbert <vcolbert@nvidia.com>
Tested-by: Varun Colbert <vcolbert@nvidia.com>
-rw-r--r-- | drivers/media/video/tegra/ov5650.c | 31 |
1 files changed, 23 insertions, 8 deletions
diff --git a/drivers/media/video/tegra/ov5650.c b/drivers/media/video/tegra/ov5650.c index 6d28aa67d1d7..b9d86339f372 100644 --- a/drivers/media/video/tegra/ov5650.c +++ b/drivers/media/video/tegra/ov5650.c @@ -27,6 +27,8 @@ struct ov5650_reg { u16 val; }; +static struct ov5650_reg *last_mode; + struct ov5650_sensor { struct i2c_client *i2c_client; struct ov5650_platform_data *pdata; @@ -948,13 +950,24 @@ static int ov5650_set_mode(struct ov5650_info *info, struct ov5650_mode *mode) ov5650_get_coarse_time_regs(reg_list + 2, mode->coarse_time); ov5650_get_gain_reg(reg_list + 5, mode->gain); - err = ov5650_write_table(info, reset_seq, NULL, 0); - if (err) - return err; + /* Check what condition reset and mode start sequences are */ + /* needed. For switching between certain modes, these are */ + /* not required. Skipping them saves time for I2C access */ + if ((info->mode == OV5650_MODE_INVALID) || + ((last_mode != mode_2592x1944) && + (last_mode != mode_1296x972)) || + ((mode_table[sensor_mode] != mode_2592x1944) && + (mode_table[sensor_mode] != mode_1296x972))) { + err = ov5650_write_table(info, reset_seq, NULL, 0); + if (err) + return err; - err = ov5650_write_table(info, mode_start, NULL, 0); - if (err) - return err; + err = ov5650_write_table(info, mode_start, NULL, 0); + if (err) + return err; + } + + last_mode = mode_table[sensor_mode]; err = ov5650_write_table(info, mode_table[sensor_mode], reg_list, 6); @@ -1179,10 +1192,12 @@ static int set_power_helper(struct ov5650_platform_data *pdata, int powerLevel) { if (pdata) { - if (powerLevel && pdata->power_on) + if (powerLevel && pdata->power_on) { pdata->power_on(); - else if (pdata->power_off) + } else if (pdata->power_off) { pdata->power_off(); + stereo_ov5650_info->mode = OV5650_MODE_INVALID; + } } return 0; } |