From 2980395ff2dd9af45430e4c2cb9b3a67310c727b Mon Sep 17 00:00:00 2001 From: Jozef Kruger Date: Thu, 12 Jan 2012 15:31:38 -0800 Subject: [PATCH] [PORT FROM R2] mt9e013: Add runtime check for old vs new VCM BZ: 20773 ORIG_BZ: 11145 This patch adds a check that uses the IFWI (firmware) version to determine whether the VCM maintains focus position when the sensor module is put into standby mode or not. This is a temporary feature that is needed as long as prototype phones (earlier than PR3.3) are still being used. After those have been phased out completely, this check can be removed. Change-Id: I21b130e9a029d33f468a30f8f3f53b34c2cfc5b7 Orig-Change-Id: I5f2dd8545574f8e5d20c489fc3cfd357dc9611c1 Signed-off-by: Jozef Kruger Reviewed-on: http://android.intel.com:8080/31764 Reviewed-by: Jong-a-lock, Robert Reviewed-by: Samurov, Vitali Reviewed-by: Toivonen, Tuukka Reviewed-by: Wang, Wen W Tested-by: Lampila, KalleX Reviewed-by: buildbot Tested-by: buildbot Reviewed-on: http://android.intel.com:8080/32602 Reviewed-by: Lampila, KalleX --- drivers/media/video/mt9e013.c | 30 +++++++++++++++++++++++++----- drivers/media/video/mt9e013.h | 4 +++- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/drivers/media/video/mt9e013.c b/drivers/media/video/mt9e013.c index 013dc0f..d3da160 100644 --- a/drivers/media/video/mt9e013.c +++ b/drivers/media/video/mt9e013.c @@ -41,13 +41,15 @@ #include #include #include +#include #include "mt9e013.h" #define to_mt9e013_sensor(sd) container_of(sd, struct mt9e013_device, sd) #define HOME_POS 255 - +#define PR3_2_FW 0x0400 +#define PR3_3_FW 0x0500 /* divides a by b using half up rounding and div/0 prevention * (result is 0 if b == 0) */ @@ -904,6 +906,8 @@ static int mt9e013_init_registers(struct v4l2_subdev *sd) static int __mt9e013_init(struct v4l2_subdev *sd, u32 val) { int ret; + struct mt9e013_device *dev = to_mt9e013_sensor(sd); + u8 fw_rev[16]; /* set inital registers */ ret = mt9e013_init_registers(sd); @@ -915,6 +919,25 @@ static int __mt9e013_init(struct v4l2_subdev *sd, u32 val) mt9e013_res = mt9e013_res_preview; N_RES = N_RES_PREVIEW; + /* The only way to detect whether this VCM maintains focus after putting + * the sensor into standby mode is by looking at the SCU FW version. + * PR3.3 or higher runs on FW version 05.00 or higher. + * We cannot distinguish between PR3.2 and PR3.25, so we need to be + * conservative. PR3.25 owners can change the comparison to compare + * to PR3_2_FW instead of PR3_3_FW for testing purposes. + */ + dev->keeps_focus_pos = false; + ret |= intel_scu_ipc_command(IPCMSG_FW_REVISION, 0, NULL, 0, + (u32 *)fw_rev, 4); + if (ret == 0) { + u16 fw_version = (fw_rev[15] << 8) | fw_rev[14]; + dev->keeps_focus_pos = fw_version >= PR3_3_FW; + } + if (!dev->keeps_focus_pos) { + v4l2_warn(sd, "VCM does not maintain focus position in standby" + "mode, using software workaround\n"); + } + return ret; } @@ -1701,8 +1724,7 @@ static int mt9e013_s_stream(struct v4l2_subdev *sd, int enable) mutex_lock(&dev->input_lock); if (enable) { - if (dev->sensor_revision <= 0x0) { - /* begin: vcm hack, needs to be removed when new camera module is availible */ + if (!dev->keeps_focus_pos) { struct mt9e013_reg mt9e013_stream_enable[] = { mt9e013_streaming[0], {MT9E013_16BIT, {0x30F2}, 0x0000}, /* VCM_NEW_CODE */ @@ -1716,8 +1738,6 @@ static int mt9e013_s_stream(struct v4l2_subdev *sd, int enable) mt9e013_stream_enable[3].val = (MT9E013_MAX_FOCUS_POS - dev->focus); ret = mt9e013_write_reg_array(client, mt9e013_stream_enable); - - /* end: vcm hack, needs to be removed when new camera module is availible */ } else { ret = mt9e013_write_reg_array(client, mt9e013_streaming); } diff --git a/drivers/media/video/mt9e013.h b/drivers/media/video/mt9e013.h index 8e5c5bb..96a6812 100644 --- a/drivers/media/video/mt9e013.h +++ b/drivers/media/video/mt9e013.h @@ -386,6 +386,8 @@ struct mt9e013_device { s16 number_of_steps; struct mutex input_lock; /* serialize sensor's ioctl */ void *otp_data; + /* Older VCMs could not maintain the focus position in standby mode. */ + bool keeps_focus_pos; }; #define MT9E013_MAX_WRITE_BUF_SIZE 32 @@ -596,7 +598,7 @@ static const struct mt9e013_reg mt9e013_start_streaming[] = { #define GROUPED_PARAMETER_HOLD_DISABLE {MT9E013_8BIT, {0x0104}, 0x0} -#define INIT_VCM_CONTROL {MT9E013_16BIT, {0x30F0}, 0x8004} /* slew_rate[2:0] */ +#define INIT_VCM_CONTROL {MT9E013_16BIT, {0x30F0}, 0x800C} /* slew_rate[2:0] */ static const struct mt9e013_reg mt9e013_init_vcm[] = { INIT_VCM_CONTROL, /* VCM_CONTROL */ {MT9E013_16BIT, {0x30F2}, 0x0000}, /* VCM_NEW_CODE */ -- 2.7.4