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