From 306c705feaa88879f73db0e9c5562248649ce674 Mon Sep 17 00:00:00 2001 From: ddl Date: Wed, 24 Apr 2013 16:18:04 +0800 Subject: [PATCH] camera(rk_cam_sensor:v0.1.3): add support flash control --- drivers/media/video/generic_sensor.c | 62 +++++++++------------------- drivers/media/video/generic_sensor.h | 27 ++++++++++-- 2 files changed, 43 insertions(+), 46 deletions(-) diff --git a/drivers/media/video/generic_sensor.c b/drivers/media/video/generic_sensor.c index a68393bcfa99..832e561541c4 100755 --- a/drivers/media/video/generic_sensor.c +++ b/drivers/media/video/generic_sensor.c @@ -18,8 +18,10 @@ *v0.0.1: this driver is compatible with generic_sensor *v0.1.1: * add WqCmd_af_continues_pause; +*v0.1.3: +* add support flash control; */ -static int version = KERNEL_VERSION(0,1,1); +static int version = KERNEL_VERSION(0,1,3); module_param(version, int, S_IRUGO); @@ -610,7 +612,6 @@ static const struct rk_sensor_datafmt *generic_sensor_find_datafmt( return NULL; } - int generic_sensor_softreset(struct i2c_client *client, struct rk_sensor_reg *series) { int ret = 0; struct generic_sensor *sensor = to_generic_sensor(client); @@ -715,9 +716,10 @@ int generic_sensor_ioctrl(struct soc_camera_device *icd,enum rk29sensor_power_cm if (pdata && pdata->sensor_ioctrl) { pdata->sensor_ioctrl(icd->pdev,Cam_Flash, on); if(on==Flash_On){ - //flash off after 1.5 secs + mdelay(5); + //flash off after 2 secs hrtimer_cancel(&(sensor->flash_off_timer.timer)); - hrtimer_start(&(sensor->flash_off_timer.timer),ktime_set(0, 1500*1000*1000),HRTIMER_MODE_REL); + hrtimer_start(&(sensor->flash_off_timer.timer),ktime_set(0, 2000*1000*1000),HRTIMER_MODE_REL); } } break; @@ -845,9 +847,11 @@ int generic_sensor_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) int generic_sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) { struct i2c_client *client = v4l2_get_subdevdata(sd); + struct soc_camera_device *icd = client->dev.platform_data; const struct rk_sensor_datafmt *fmt; struct generic_sensor *sensor = to_generic_sensor(client); struct rk_sensor_sequence *winseqe_set_addr=NULL; + struct sensor_v4l2ctrl_info_s *v4l2ctrl_info; bool is_capture=(mf->reserved[7]==0xfefe5a5a)?true:false; int ret=0; @@ -868,6 +872,17 @@ int generic_sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) if (sensor->sensor_cb.sensor_s_fmt_cb_th) ret |= sensor->sensor_cb.sensor_s_fmt_cb_th(client, mf, is_capture); + v4l2ctrl_info = sensor_find_ctrl(sensor->ctrls,V4L2_CID_FLASH); /* ddl@rock-chips.com: v0.1.3 */ + if (v4l2ctrl_info) { + if (is_capture) { + if ((v4l2ctrl_info->cur_value == 2) || (v4l2ctrl_info->cur_value == 1)) { + generic_sensor_ioctrl(icd, Sensor_Flash, 1); + } + } else { + generic_sensor_ioctrl(icd, Sensor_Flash, 0); + } + } + ret |= generic_sensor_write_array(client, winseqe_set_addr->data); if (ret != 0) { SENSOR_TR("set format capability failed"); @@ -902,45 +917,6 @@ sensor_s_fmt_end: return 0; } -int generic_sensor_set_flash(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct generic_sensor *sensor = to_generic_sensor(client); - - if ((value >= qctrl->minimum) && (value <= qctrl->maximum)) { - if (value == 3) { /* ddl@rock-chips.com: torch */ - generic_sensor_ioctrl(icd, Sensor_Flash, Flash_Torch); /* Flash On */ - } else { - generic_sensor_ioctrl(icd, Sensor_Flash, Flash_Off); - } - SENSOR_DG("%s : %x",__FUNCTION__, value); - return 0; - } - - SENSOR_TR("%s valure = %d is invalidate",__FUNCTION__,value); - return -EINVAL; -} -int sensor_v4l2ctrl_flash_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, - struct v4l2_ext_control *ext_ctrl) -{ - struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); - struct generic_sensor *sensor = to_generic_sensor(client); - int value = ext_ctrl->value; - - if ((value < ctrl_info->qctrl->minimum) || (value > ctrl_info->qctrl->maximum)) { - printk(KERN_ERR "%s(%d): value(0x%x) isn't between in (0x%x,0x%x)\n",__FUNCTION__,__LINE__,value, - ctrl_info->qctrl->minimum,ctrl_info->qctrl->maximum); - return -EINVAL; - } - - if (value == 3) { /* ddl@rock-chips.com: torch */ - generic_sensor_ioctrl(icd, Sensor_Flash, Flash_Torch); /* Flash On */ - } else { - generic_sensor_ioctrl(icd, Sensor_Flash, Flash_Off); - } - SENSOR_DG("%s : %x",__FUNCTION__, value); - return 0; -} int generic_sensor_g_control(struct v4l2_subdev *sd, struct v4l2_control *ctrl) { diff --git a/drivers/media/video/generic_sensor.h b/drivers/media/video/generic_sensor.h index c6129e0d3b94..e4277e9e83a2 100755 --- a/drivers/media/video/generic_sensor.h +++ b/drivers/media/video/generic_sensor.h @@ -289,12 +289,9 @@ extern int generic_sensor_s_ext_control(struct soc_camera_device *icd, struct v4 extern int generic_sensor_g_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl); extern int generic_sensor_s_ext_controls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ext_ctrl); extern long generic_sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg); -extern long generic_sensor_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg); extern int generic_sensor_enum_fmt(struct v4l2_subdev *sd, unsigned int index,enum v4l2_mbus_pixelcode *code); extern int generic_sensor_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf); extern int generic_sensor_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *id); -extern int sensor_v4l2ctrl_flash_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, - struct v4l2_ext_control *ext_ctrl); extern int generic_sensor_af_workqueue_set(struct soc_camera_device *icd, enum rk_sensor_focus_wq_cmd cmd, int var, bool wait); extern int generic_sensor_s_stream(struct v4l2_subdev *sd, int enable); extern int generic_sensor_writebuf(struct i2c_client *client, char *buf, int buf_size); @@ -493,6 +490,29 @@ static inline int sensor_v4l2ctrl_default_cb(struct soc_camera_device *icd, stru return -EINVAL; } } +static inline int sensor_v4l2ctrl_flash_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, + struct v4l2_ext_control *ext_ctrl) +{ + struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); + struct generic_sensor *sensor = to_generic_sensor(client); + int value = ext_ctrl->value; + + if ((value < ctrl_info->qctrl->minimum) || (value > ctrl_info->qctrl->maximum)) { + printk(KERN_ERR "%s(%d): value(0x%x) isn't between in (0x%x,0x%x)\n",__FUNCTION__,__LINE__,value, + ctrl_info->qctrl->minimum,ctrl_info->qctrl->maximum); + return -EINVAL; + } + + if (value == 3) { /* ddl@rock-chips.com: torch */ + generic_sensor_ioctrl(icd, Sensor_Flash, Flash_Torch); /* Flash On */ + } else { + generic_sensor_ioctrl(icd, Sensor_Flash, Flash_Off); + } + + ctrl_info->cur_value = value; /* ddl@rock-chips.com : v0.1.3 */ + + return 0; +} static inline int sensor_focus_default_cb(struct soc_camera_device *icd, struct sensor_v4l2ctrl_info_s *ctrl_info, struct v4l2_ext_control *ext_ctrl) { @@ -888,6 +908,7 @@ static inline int sensor_face_detect_default_cb(struct soc_camera_device *icd, s if (SensorConfiguration & (1<