From ad78d87fadb3328c0ef294b1afb634c2e28a382e Mon Sep 17 00:00:00 2001 From: ddl Date: Tue, 12 Jul 2011 11:18:42 +0800 Subject: [PATCH] camera: fix camera open operation make a difference between O_RDONLY and O_RDWR for accerate open device --- drivers/media/video/ov2659.c | 38 +++++++++++++++++++------------ drivers/media/video/ov5642.c | 30 ++++++++++++++++-------- drivers/media/video/soc_camera.c | 39 +++++++++++++++++++------------- 3 files changed, 67 insertions(+), 40 deletions(-) diff --git a/drivers/media/video/ov2659.c b/drivers/media/video/ov2659.c index c17e4cfbb4f8..30fc9c7b58df 100755 --- a/drivers/media/video/ov2659.c +++ b/drivers/media/video/ov2659.c @@ -68,7 +68,7 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define CONFIG_SENSOR_Mirror 0 #define CONFIG_SENSOR_Flip 0 -#define CONFIG_SENSOR_I2C_SPEED 250000 /* Hz */ +#define CONFIG_SENSOR_I2C_SPEED 350000 /* Hz */ /* Sensor write register continues by preempt_disable/preempt_enable for current process not be scheduled */ #define CONFIG_SENSOR_I2C_NOSCHED 0 #define CONFIG_SENSOR_I2C_RDWRCHK 0 @@ -89,6 +89,11 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define SENSOR_NAME_STRING(a) STR(CONS(SENSOR_NAME, a)) #define SENSOR_NAME_VARFUN(a) CONS(SENSOR_NAME, a) +#define SENSOR_AF_IS_ERR (0x00<<0) +#define SENSOR_AF_IS_OK (0x01<<0) +#define SENSOR_INIT_IS_ERR (0x00<<28) +#define SENSOR_INIT_IS_OK (0x01<<28) + struct reginfo { u16 reg; @@ -1239,7 +1244,7 @@ typedef struct sensor_info_priv_s unsigned char flip; /* VFLIP */ unsigned int winseqe_cur_addr; unsigned int pixfmt; - + unsigned int funmodule_state; } sensor_info_priv_t; struct sensor @@ -1596,9 +1601,10 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) #endif SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),((val == 0)?__FUNCTION__:"sensor_reinit"),icd->user_width,icd->user_height); - + sensor->info_priv.funmodule_state |= SENSOR_INIT_IS_OK; return 0; sensor_INIT_ERR: + sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; sensor_task_lock(client,0); sensor_deactivate(client); return ret; @@ -1608,23 +1614,27 @@ static int sensor_deactivate(struct i2c_client *client) { struct soc_camera_device *icd = client->dev.platform_data; u8 reg_val; - + struct sensor *sensor = to_sensor(client); SENSOR_DG("\n%s..%s.. Enter\n",SENSOR_NAME_STRING(),__FUNCTION__); - + /* ddl@rock-chips.com : all sensor output pin must change to input for other sensor */ - sensor_task_lock(client, 1); - sensor_read(client,0x3000,®_val); - sensor_write(client, 0x3000, reg_val&0xfc); - sensor_write(client, 0x3001, 0x00); - sensor_read(client,0x3002,®_val); - sensor_write(client, 0x3002, reg_val&0x1f); - sensor_task_lock(client, 0); - sensor_ioctrl(icd, Sensor_PowerDown, 1); + if (sensor->info_priv.funmodule_state & SENSOR_INIT_IS_OK) { + sensor_task_lock(client, 1); + sensor_read(client,0x3000,®_val); + sensor_write(client, 0x3000, reg_val&0xfc); + sensor_write(client, 0x3001, 0x00); + sensor_read(client,0x3002,®_val); + sensor_write(client, 0x3002, reg_val&0x1f); + sensor_task_lock(client, 0); + } + sensor_ioctrl(icd, Sensor_PowerDown, 1); + msleep(100); /* ddl@rock-chips.com : sensor config init width , because next open sensor quickly(soc_camera_open -> Try to configure with default parameters) */ icd->user_width = SENSOR_INIT_WIDTH; icd->user_height = SENSOR_INIT_HEIGHT; - msleep(100); + sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; + return 0; } diff --git a/drivers/media/video/ov5642.c b/drivers/media/video/ov5642.c index e7f26170aaa1..77d86fd6bb31 100755 --- a/drivers/media/video/ov5642.c +++ b/drivers/media/video/ov5642.c @@ -97,6 +97,8 @@ module_param(debug, int, S_IRUGO|S_IWUSR); #define SENSOR_AF_IS_ERR (0x00<<0) #define SENSOR_AF_IS_OK (0x01<<0) +#define SENSOR_INIT_IS_ERR (0x00<<28) +#define SENSOR_INIT_IS_OK (0x01<<28) #if CONFIG_SENSOR_Focus #define SENSOR_AF_MODE_INFINITY 0 @@ -4195,8 +4197,11 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val) #endif SENSOR_DG("\n%s..%s.. icd->width = %d.. icd->height %d\n",SENSOR_NAME_STRING(),((val == 0)?__FUNCTION__:"sensor_reinit"),icd->user_width,icd->user_height); + sensor->info_priv.funmodule_state |= SENSOR_INIT_IS_OK; + return 0; sensor_INIT_ERR: + sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; sensor_task_lock(client,0); sensor_deactivate(client); return ret; @@ -4204,20 +4209,25 @@ sensor_INIT_ERR: static int sensor_deactivate(struct i2c_client *client) { struct soc_camera_device *icd = client->dev.platform_data; - - SENSOR_DG("\n%s..%s.. Enter\n",SENSOR_NAME_STRING(),__FUNCTION__); - + struct sensor *sensor = to_sensor(client); + + SENSOR_DG("\n%s..%s.. Enter\n",SENSOR_NAME_STRING(),__FUNCTION__); + /* ddl@rock-chips.com : all sensor output pin must change to input for other sensor */ - sensor_task_lock(client, 1); - sensor_write(client, 0x3017, 0x00); // FREX,VSYNC,HREF,PCLK,D9-D6 - sensor_write(client, 0x3018, 0x03); // D5-D0 - sensor_write(client,0x3019,0X00); // STROBE,SDA - sensor_task_lock(client, 0); - sensor_ioctrl(icd, Sensor_PowerDown, 1); + if (sensor->info_priv.funmodule_state & SENSOR_INIT_IS_OK) { + sensor_task_lock(client, 1); + sensor_write(client, 0x3017, 0x00); // FREX,VSYNC,HREF,PCLK,D9-D6 + sensor_write(client, 0x3018, 0x03); // D5-D0 + sensor_write(client,0x3019,0X00); // STROBE,SDA + sensor_task_lock(client, 0); + } + sensor_ioctrl(icd, Sensor_PowerDown, 1); + msleep(100); + /* ddl@rock-chips.com : sensor config init width , because next open sensor quickly(soc_camera_open -> Try to configure with default parameters) */ icd->user_width = SENSOR_INIT_WIDTH; icd->user_height = SENSOR_INIT_HEIGHT; - msleep(100); + sensor->info_priv.funmodule_state &= ~SENSOR_INIT_IS_OK; return 0; } static struct reginfo sensor_power_down_sequence[]= diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c index 9c174400285a..db07d81cfe55 100644 --- a/drivers/media/video/soc_camera.c +++ b/drivers/media/video/soc_camera.c @@ -373,27 +373,32 @@ static int soc_camera_open(struct file *file) .colorspace = icd->current_fmt->colorspace, }, }; - - if (icl->power) { - ret = icl->power(icd->pdev, 1); - if (ret < 0) - goto epower; - } - - /* The camera could have been already on, try to reset */ - if (icl->reset) - icl->reset(icd->pdev); + /* ddl@rock-chips.com : accelerate device open */ + if ((file->f_flags & O_ACCMODE) == O_RDWR) { + if (icl->power) { + ret = icl->power(icd->pdev, 1); + if (ret < 0) + goto epower; + } + + /* The camera could have been already on, try to reset */ + if (icl->reset) + icl->reset(icd->pdev); + } ret = ici->ops->add(icd); if (ret < 0) { dev_err(&icd->dev, "Couldn't activate the camera: %d\n", ret); goto eiciadd; } - + /* Try to configure with default parameters */ - ret = soc_camera_set_fmt(icf, &f); - if (ret < 0) - goto esfmt; + if ((file->f_flags & O_ACCMODE) == O_RDWR) { + ret = soc_camera_set_fmt(icf, &f); + if (ret < 0) + goto esfmt; + } + } file->private_data = icf; @@ -435,8 +440,10 @@ static int soc_camera_close(struct file *file) struct soc_camera_link *icl = to_soc_camera_link(icd); ici->ops->remove(icd); - if (icl->power) - icl->power(icd->pdev, 0); + if ((file->f_flags & O_ACCMODE) == O_RDWR) { + if (icl->power) + icl->power(icd->pdev, 0); + } } mutex_unlock(&icd->video_lock); -- 2.34.1