From: Yong He <yong.m...@intel.com>
Subject: [PATCH] MRST Tablet camera driver ver-0.964, fix 11173

Bug 11173 - [MM-camera] Camera has recorded a video with glitter at the 
beginning

In the snapshot mode, the AEC&AGC is turned off, so we can set a proper
Exposure & Gain value got from the preview mode.
However, in video mode, the AEC&AGC must be turned on for the changing of 
environment,
the sensor need some time (~0.5 sec) to stabilize the AEC&AGC after stream_on.
so the first several frames may be incorrect exposed.

Solution-1,
as the video recording setting is identical as the preview,
the application could keep the sensor streaming when switch from preview to 
video,
which will not cause the sensor to stop and start again.
(this will not need any change on driver)

Solution-2,
due to the middle-ware design limitations,
the application HAS to call sensor stop and start during the switch.
the driver will add an additional ioctl to let app set an additional delay 
after stream on,
this will provide the application a way to drop several incorrect frames
(this patch is adding this support)

Signed-off-by: Yong He <yong.m...@intel.com>
Index: linux-2.6.37/drivers/staging/mrstci/mrstov5640/mrstov5640.c
===================================================================
--- linux-2.6.37/drivers/staging/mrstci/mrstov5640/mrstov5640.c        
(revision 1295)
+++ linux-2.6.37/drivers/staging/mrstci/mrstov5640/mrstov5640.c     (revision 
1296)
@@ -50,7 +50,7 @@
#include "ci_sensor_common.h"
#include "ov5640.h"
-#define DRIVER_VERSION "0.963"
+#define DRIVER_VERSION "0.964"
 #define GPIO_FLASH 45
static int ov5640_flash;
@@ -222,6 +222,7 @@
       int scene_val;
       int spe_val;
       int exp_comp_val;
+       int stream_on_delay;
        struct ov5640_exp_info_1_t snapshot;
       struct ov5640_exp_info_1_t preview;
@@ -237,6 +238,7 @@
       .anti_banding = 0,
       .iso_mode = 0,
       .iso_val = 100,
+       .stream_on_delay = 0,
};
 /*
@@ -2120,6 +2122,27 @@
       return ret;
}
+#define STREAM_ON_DELAY_MAX_MS 5000
+static int ov5640_t_stream_on_delay(struct v4l2_subdev *sd, int value)
+{
+       int ret = 0;
+
+       dev_dbg(sd->v4l2_dev->dev, "%s (%d)", __func__, value);
+       if ((value >= 0) && (value <= STREAM_ON_DELAY_MAX_MS))
+                ov5640_status.stream_on_delay = value;
+       else
+                ov5640_status.stream_on_delay = 0;
+
+       return ret;
+}
+static int ov5640_q_stream_on_delay(struct v4l2_subdev *sd, int *value)
+{
+       int ret = 0;
+
+       *value = ov5640_status.stream_on_delay;
+       return ret;
+}
+
static struct ov5640_control {
       struct v4l2_queryctrl qc;
       int (*query)(struct v4l2_subdev *sd, __s32 *value);
@@ -2253,6 +2276,7 @@
#define CID_SCENE_MODE             (V4L2_CID_PRIVATE_BASE + 6)
#define CID_SPE_MODE               (V4L2_CID_PRIVATE_BASE + 7)
#define CID_EXPOSURE_COMPENSATION  (V4L2_CID_PRIVATE_BASE + 8)
+#define CID_STREAM_ON_DELAY        (V4L2_CID_PRIVATE_BASE + 9)
       {
                .qc = {
                          .id = CID_FOCUS_POSITION,
@@ -2372,6 +2396,19 @@
                .tweak = ov5640_t_exp_comp,
                .query = ov5640_q_exp_comp,
       },
+       {
+                .qc = {
+                          .id = CID_STREAM_ON_DELAY,
+                          .type = V4L2_CTRL_TYPE_INTEGER,
+                          .name = "Stream on delay",
+                          .minimum = 0,
+                          .maximum = 5000,
+                          .step = 1,
+                          .default_value = 0,
+                },
+                .tweak = ov5640_t_stream_on_delay,
+                .query = ov5640_q_stream_on_delay,
+       },
};
#define N_CONTROLS (ARRAY_SIZE(ov5640_controls))
@@ -2471,7 +2508,10 @@
                                                      af_fw_status);
                                   }
                          }
-                           msleep(50);
+                          msleep(50 + ov5640_status.stream_on_delay);
+                          /* clear the additional delay
+                          * user should set it by ioctl again if needed */
+                          ov5640_status.stream_on_delay = 0;
                }
       } else {
                ov5640_set_aec_agc(client, 0);
Index: linux-2.6.37/drivers/staging/mrstci/mrstov9740/mrstov9740.c
===================================================================
--- linux-2.6.37/drivers/staging/mrstci/mrstov9740/mrstov9740.c        
(revision 1295)
+++ linux-2.6.37/drivers/staging/mrstci/mrstov9740/mrstov9740.c     (revision 
1296)
@@ -47,7 +47,7 @@
#include "ci_sensor_common.h"
#include "ov9740.h"
-#define DRIVER_VERSION "0.963"
+#define DRIVER_VERSION "0.964"
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 #define DBG_entering  pr_debug("%s entering", __func__);
@@ -165,6 +165,7 @@
       int scene_val;
       int spe_val;
       int exp_comp_val;
+       int stream_on_delay;
        /* exposure status */
       struct ov9740_exp_info_1_t snapshot;
@@ -176,6 +177,7 @@
       .stream_on = OV9740_STREAM_OFF,
       .hflip = 0,
       .vflip = 0,
+       .stream_on_delay = 0,
};
 /*
@@ -1676,7 +1678,27 @@
       return ret;
}
+#define STREAM_ON_DELAY_MAX_MS 5000
+static int ov9740_t_stream_on_delay(struct v4l2_subdev *sd, int value)
+{
+       int ret = 0;
+       dev_dbg(sd->v4l2_dev->dev, "%s (%d)", __func__, value);
+       if ((value >= 0) && (value <= STREAM_ON_DELAY_MAX_MS))
+                ov9740_status.stream_on_delay = value;
+       else
+                ov9740_status.stream_on_delay = 0;
+
+       return ret;
+}
+static int ov9740_q_stream_on_delay(struct v4l2_subdev *sd, int *value)
+{
+       int ret = 0;
+
+       *value = ov9740_status.stream_on_delay;
+       return ret;
+}
+
static struct ov9740_control {
       struct v4l2_queryctrl qc;
       int (*query)(struct v4l2_subdev *sd, __s32 *value);
@@ -1806,6 +1828,7 @@
#define CID_EXPOSURE_MODE_STATUS   (V4L2_CID_PRIVATE_BASE + 2)
#define CID_EXPOSURE_WINDOW        (V4L2_CID_PRIVATE_BASE + 3)
#define CID_EXPOSURE_COMPENSATION  (V4L2_CID_PRIVATE_BASE + 4)
+#define CID_STREAM_ON_DELAY        (V4L2_CID_PRIVATE_BASE + 5)
       {
                .qc = {
                          .id =  CID_EXPOSURE_MODE_STATUS,
@@ -1873,6 +1896,19 @@
                .tweak = ov9740_t_exp_comp,
                .query = ov9740_q_exp_comp,
       },
+       {
+                .qc = {
+                          .id = CID_STREAM_ON_DELAY,
+                          .type = V4L2_CTRL_TYPE_INTEGER,
+                          .name = "Stream on delay",
+                          .minimum = 0,
+                          .maximum = 5000,
+                          .step = 1,
+                          .default_value = 0,
+                },
+                .tweak = ov9740_t_stream_on_delay,
+                .query = ov9740_q_stream_on_delay,
+       },
};
#define N_CONTROLS (ARRAY_SIZE(ov9740_controls))
@@ -1942,7 +1978,10 @@
                          "set stream on, sleep 300 ms for sensor 
adjusting...\n");
                ov9740_write(client, 0x0100, 0x01);
                ov9740_set_aec_agc(client, 1);
-                 msleep(50);
+                msleep(50 + ov9740_status.stream_on_delay);
+                /* clear the additional delay
+                * user should set it by ioctl again if needed */
+                ov9740_status.stream_on_delay = 0;
       } else if ((!enable) && (ov9740_status.stream_on == OV9740_STREAM_ON)) {
                /* Turn off streaming if current status is on */
                ov9740_status.stream_on = OV9740_STREAM_OFF;

Best Regards,

Yong He
Software Engineer, PCSD SW Solutions,
Intel Asia-Pacific R&D Ltd.
Phone (+86) 21-61166334
Lab (+86) 21-61167881

Attachment: linux-2.6.37-camera-ov5640-ov9740-version-0.963_to_0.964.patch
Description: linux-2.6.37-camera-ov5640-ov9740-version-0.963_to_0.964.patch

_______________________________________________
MeeGo-kernel mailing list
MeeGo-kernel@lists.meego.com
http://lists.meego.com/listinfo/meego-kernel

Reply via email to