On Thu, 23 Jun 2011 18:40:46 +0800
"He, Yong M" <yong.m...@intel.com> wrote:

> 
> Hi Kristen,
> 
> Please review the updates. Thanks a lot.
> 
> 1, removed the ioremapped memory operation, and leave it to firmware.

OK, so you decided not to set the alt function via a pci quirk
while you wait for fw?
 
> 2, added the gpio_request and free in the driver probe and remove function, 
> and also modified ov5640_t_flash(struct v4l2_subdev *sd, int value) using 
> gpio_set_value(GPIO_FLASH, value)

You needed to check return values for gpio_request and gpio_set_direction.
I modified your patch to do this.  Please review.

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

Bug 9960 - Back camera doesn't support auto-flash

Solution,
add Flash switch funtion (GPIO-45, Flash control), so that user app can sync 
the flash with the snapshot steps.
add 2 V4L2 CID controls to implement flash trigger function and environment 
detection

Signed-off-by: Yong He <yong.m...@intel.com>
Index: linux-2.6.37/drivers/staging/mrstci/mrstov5640/mrstov5640.c
===================================================================
--- linux-2.6.37.orig/drivers/staging/mrstci/mrstov5640/mrstov5640.c    
2011-06-22 11:19:57.449187360 -0700
+++ linux-2.6.37/drivers/staging/mrstci/mrstov5640/mrstov5640.c 2011-06-23 
10:11:45.025039205 -0700
@@ -50,7 +50,7 @@
 #include "ci_sensor_common.h"
 #include "ov5640.h"
 
-#define DRIVER_VERSION "0.95"
+#define DRIVER_VERSION "0.953"
 
 #define GPIO_FLASH 45
 static int ov5640_flash=0;
@@ -1231,26 +1231,21 @@
        return err;
 }
 
-static int ov5640_t_flash(struct i2c_client *c, int value)
+static int ov5640_t_flash(struct v4l2_subdev *sd, int value)
 {
        int ret;
-       if(value!=0&&value!=1)
+
+       if ((value != 0) && (value != 1))
                return -EINVAL;
-       if(ret == 0)
-       {
-               ret = gpio_direction_output(GPIO_FLASH,value);
-               if(ret == 0)
-                       ov5640_flash = value;
-               gpio_free(GPIO_FLASH);
-       }
-       return ret;
 
+       gpio_set_value(GPIO_FLASH, value);
+       ov5640_flash = value;
+
+       return ret;
 }
 
-static int ov5640_q_flash(struct i2c_client *c, int *value)
+static int ov5640_q_flash(struct v4l2_subdev *sd, int *value)
 {
-       if(!value)
-               return -EINVAL;
        *value=ov5640_flash;
        return 0;
 }
@@ -1327,6 +1322,37 @@
        return ret;
 }
 
+static int ov5640_t_exposure_level_detect(struct v4l2_subdev *sd, int value)
+{
+       int ret = 0;
+       /* this CID is Read Only */
+
+       return ret;
+}
+
+static int ov5640_q_exposure_level_detect(struct v4l2_subdev *sd, int *value)
+{
+       int ret = 0;
+       struct i2c_client *c = v4l2_get_subdevdata(sd);
+       int exposure, gain;
+       u8 v;
+
+       ret += ov5640_read(c, 0x3500, &v);
+       exposure = v;
+       ret += ov5640_read(c, 0x3501, &v);
+       exposure = (exposure<<8) | v;
+       ret += ov5640_read(c, 0x3502, &v);
+       exposure = (exposure<<8) | v;
+
+       ret += ov5640_read(c, 0x350a, &v);
+       gain = v;
+       ret += ov5640_read(c, 0x350b, &v);
+       gain = (gain<<8) | v;
+
+       *value = exposure*gain;
+       return ret;
+}
+
 #if 0
 static int ov5640_t_awb(struct i2c_client *c, int value)
 {
@@ -1455,7 +1481,9 @@
 #define CID_FOCUS_POSITION         (V4L2_CID_PRIVATE_BASE + 0)
 #define CID_FOCUS_MODE_STATUS      (V4L2_CID_PRIVATE_BASE + 1)
 #define CID_EXPOSURE_MODE_STATUS   (V4L2_CID_PRIVATE_BASE + 2)
-#define CID_AUTO_FLASH_DETECT      (V4L2_CID_PRIVATE_BASE + 3)
+#define CID_EXPOSURE_WINDOW        (V4L2_CID_PRIVATE_BASE + 3)
+#define CID_EXPOSURE_LEVEL_DETECT  (V4L2_CID_PRIVATE_BASE + 4)
+#define CID_FLASH_SWITCH           (V4L2_CID_PRIVATE_BASE + 5)
        {
                .qc = {
                        .id = CID_FOCUS_POSITION,
@@ -1482,12 +1510,24 @@
                .tweak = ov5640_t_focus,
                .query = ov5640_q_focus,
        },
-#if 0 //BUGBUG
        {
                .qc = {
-                       .id = V4L2_CID_FLASH_STROBE,
+                       .id = CID_EXPOSURE_LEVEL_DETECT,
+                       .type = V4L2_CTRL_TYPE_INTEGER,
+                       .name = "Exposure Level Detect",
+                       .minimum = 0,
+                       .maximum = 0x7fffffff,
+                       .step = 1,
+                       .default_value = 0,
+               },
+               .tweak = ov5640_t_exposure_level_detect,
+               .query = ov5640_q_exposure_level_detect,
+       },
+       {
+               .qc = {
+                       .id = CID_FLASH_SWITCH ,
                        .type = V4L2_CTRL_TYPE_BOOLEAN,
-                       .name = "LED flash control",
+                       .name = "Flash Switch",
                        .minimum = 0,
                        .maximum = 1,
                        .step = 1,
@@ -1496,7 +1536,6 @@
                .tweak = ov5640_t_flash,
                .query = ov5640_q_flash,
        },
-#endif
 #if 0
        {
                .parm = {
@@ -1863,6 +1902,7 @@
        struct ci_sensor_config *info;
        struct v4l2_subdev *sd;
        int ret = -1;
+       int err;
 
        DBG_entering;
 
@@ -1879,8 +1919,23 @@
 
        ret = ov5640_detect(client);
        if (ret) {
-               kfree(info);
-               return -ENODEV;
+               err = -ENODEV;
+               goto err_out;
+       }
+
+       /* Set Flash GPIO direction and init with OFF */
+       err = gpio_request(GPIO_FLASH, "Camera Flash");
+       if (err < 0) {
+               v4l_err(client, "%s: unable to request gpio for flash\n",
+                               client->adapter->name);
+               goto err_out;
+       }
+
+       err = gpio_direction_output(GPIO_FLASH, 0);
+       if (err < 0) {
+               v4l_err(client, "%s: unable to configure gpio for flash\n",
+                               client->adapter->name);
+               goto err_out1;
        }
 
        sd = &info->sd;
@@ -1898,12 +1953,19 @@
 
        DBG_leaving;
        return 0;
+
+err_out1:
+       gpio_free(GPIO_FLASH);
+err_out:
+       kfree(info);
+       return err;
 }
 
 static int ov5640_remove(struct i2c_client *client)
 {
        struct v4l2_subdev *sd = i2c_get_clientdata(client);
 
+       gpio_free(GPIO_FLASH);
        v4l2_device_unregister_subdev(sd);
        kfree(to_sensor_config(sd));
        return 0;
_______________________________________________
MeeGo-kernel mailing list
MeeGo-kernel@lists.meego.com
http://lists.meego.com/listinfo/meego-kernel

Reply via email to