summaryrefslogtreecommitdiff
path: root/drivers/media/video
diff options
context:
space:
mode:
authorCharlie Huang <chahuang@nvidia.com>2013-04-16 18:51:23 -0700
committerMrutyunjay Sawant <msawant@nvidia.com>2013-04-23 04:33:38 -0700
commit414122e92ca5f11e371dbe274565532199a4c83f (patch)
treee2287831323e9cd0464533f0b5ab5e51f9e20052 /drivers/media/video
parent5b24181a1c90a7e3c33da00c35806396c01fa209 (diff)
media: video: tegra: ad5816: settle time not reach
In some systems with fast memory configuration, sometimes the settle time is not satisfied between two set positions, especially the first two after power on. Implement the time counter between two set positions to maintain the proper settle time. bug 1237579 Change-Id: I046cbb2c9d4f55d475fe30114a58b1e2316f4efe Signed-off-by: Charlie Huang <chahuang@nvidia.com> Reviewed-on: http://git-master/r/220019 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Thomas Cherry <tcherry@nvidia.com> GVS: Gerrit_Virtual_Submit
Diffstat (limited to 'drivers/media/video')
-rw-r--r--drivers/media/video/tegra/ad5816.c64
1 files changed, 40 insertions, 24 deletions
diff --git a/drivers/media/video/tegra/ad5816.c b/drivers/media/video/tegra/ad5816.c
index 9f1c060e1718..4741e1f2aaa4 100644
--- a/drivers/media/video/tegra/ad5816.c
+++ b/drivers/media/video/tegra/ad5816.c
@@ -1,22 +1,20 @@
-/* Copyright (C) 2011-2012 NVIDIA Corporation.
+/* ad5816.c - focuser device driver for AD5816
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
+ * Copyright (c) 2012-2013, NVIDIA Corporation. All Rights Reserved.
*
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- * 02111-1307, USA
- */
-/* This is a NVC kernel driver for a focuser device called
- * ad5816.
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+
/* Implementation
* --------------
* The board level details about the device need to be provided in the board
@@ -131,6 +129,7 @@ struct ad5816_info {
struct nvc_focus_cap cap;
struct nv_focuser_config nv_config;
struct ad5816_pdata_info config;
+ unsigned long ltv_ms;
};
/**
@@ -451,14 +450,33 @@ static int ad5816_position_rd(struct ad5816_info *info, unsigned *position)
static int ad5816_position_wr(struct ad5816_info *info, s32 position)
{
- s16 data;
+ struct timeval tv;
+ unsigned long tvl;
+ unsigned long dly;
+ int err;
if (position < info->config.pos_low || position > info->config.pos_high)
- return -EINVAL;
-
- data = position & AD5816_POS_CLAMP;
- return ad5816_i2c_wr16(info, VCM_CODE_MSB, data);
+ err = -EINVAL;
+ else {
+ do_gettimeofday(&tv);
+ tvl = ((unsigned long)tv.tv_sec * USEC_PER_SEC +
+ tv.tv_usec) / USEC_PER_MSEC;
+ if (tvl - info->ltv_ms < info->cap.settle_time) {
+ dly = (tvl - info->ltv_ms) * USEC_PER_MSEC;
+ dev_dbg(&info->i2c_client->dev,
+ "%s not settled(%lu uS).\n", __func__, dly);
+ usleep_range(dly, dly + 20);
+ }
+ err = ad5816_i2c_wr16(info, VCM_CODE_MSB,
+ position & AD5816_POS_CLAMP);
+ }
+ if (err)
+ dev_err(&info->i2c_client->dev, "%s ERROR: %d\n",
+ __func__, err);
+ else
+ info->ltv_ms = tvl;
+ return err;
}
static void ad5816_get_focuser_capabilities(struct ad5816_info *info)
@@ -660,8 +678,7 @@ static int ad5816_param_wr(struct ad5816_info *info, unsigned long arg)
if (!err) {
info->s_mode = u8val;
info->s_info->s_mode = u8val;
- }
- else {
+ } else {
if (info->s_mode != NVC_SYNC_STEREO)
ad5816_pm_wr(info->s_info,
NVC_PWR_OFF);
@@ -681,8 +698,7 @@ static int ad5816_param_wr(struct ad5816_info *info, unsigned long arg)
if (!err) {
info->s_mode = u8val;
info->s_info->s_mode = u8val;
- }
- else {
+ } else {
if (info->s_mode != NVC_SYNC_SLAVE)
ad5816_pm_wr(info->s_info,
NVC_PWR_OFF);
@@ -1055,4 +1071,4 @@ static void __exit ad5816_exit(void)
module_init(ad5816_init);
module_exit(ad5816_exit);
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");