camera: fix camera open operation make a difference between O_RDONLY and O_RDWR for accerate open device

This commit is contained in:
ddl 2011-07-12 11:18:42 +08:00
parent c5200f65bd
commit ad78d87fad
3 changed files with 66 additions and 39 deletions

View File

@ -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,&reg_val);
sensor_write(client, 0x3000, reg_val&0xfc);
sensor_write(client, 0x3001, 0x00);
sensor_read(client,0x3002,&reg_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,&reg_val);
sensor_write(client, 0x3000, reg_val&0xfc);
sensor_write(client, 0x3001, 0x00);
sensor_read(client,0x3002,&reg_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;
}

View File

@ -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 @@ static int sensor_init(struct v4l2_subdev *sd, u32 val)
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[]=

View File

@ -373,27 +373,32 @@ static int soc_camera_open(struct file *file)
.colorspace = icd->current_fmt->colorspace,
},
};
/* 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;
}
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);
/* 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);