[Meego-kernel] [PATCH] MRST Tablet camera driver ver-0.953, fix 9960

Kristen Carlson Accardi kristen at linux.intel.com
Thu Jun 23 11:16:21 PDT 2011


On Thu, 23 Jun 2011 18:40:46 +0800
"He, Yong M" <yong.m.he at 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.he at 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.he at 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;


More information about the MeeGo-kernel mailing list