#define CONFIG_SENSOR_Flip 0
#ifdef CONFIG_OV5640_AUTOFOCUS
#define CONFIG_SENSOR_Focus 1
+#define CONFIG_SENSOR_FocusCenterInCapture 0
#include "ov5640_af_firmware.c"
#else
#define CONFIG_SENSOR_Focus 0
#define STA_FOCUS_Reg 0x3029
/* ov5640 VCM Command */
-#define OverlayEn_Cmd 0x01
-#define OverlayDis_Cmd 0x02
-#define SingleFocus_Cmd 0x03
+
#define ConstFocus_Cmd 0x04
#define StepMode_Cmd 0x05
#define PauseFocus_Cmd 0x06
#define SetZone_Cmd 0x10
#define UpdateZone_Cmd 0x12
#define SetMotor_Cmd 0x20
+#define SingleFocus_Cmd 0x03
+#define GetFocusResult_Cmd 0x07
+#define ReleaseFocus_Cmd 0x08
+#define ZoneRelaunch_Cmd 0x12
+#define DefaultZoneConfig_Cmd 0x80
+#define TouchZoneConfig_Cmd 0x81
+#define CustomZoneConfig_Cmd 0x8f
-#define Zone_configuration_Cmd 0x12
-#define Trig_autofocus_Cmd 0x03
-#define Get_focus_result_Cmd 0x07
-
/* ov5640 Focus State */
//#define S_FIRWRE 0xFF /*Firmware is downloaded and not run*/
#define S_STARTUP 0x7e /*Firmware is initializing*/
.default_value = 125,
},*/
{
+ .id = V4L2_CID_FOCUSZONE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "FocusZone Control",
+ .minimum = -1,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },{
.id = V4L2_CID_FOCUS_AUTO,
.type = V4L2_CTRL_TYPE_BOOLEAN,
.name = "Focus Control",
enum sensor_wq_result result;
bool wait;
int var;
+ int zone_center_pos[2];
};
typedef struct sensor_info_priv_s
char read_tag=0xff,cnt;
if (cmdinfo) {
- if (cmdinfo->validate_bit & 0x80) {
- if (sensor_write(client, CMD_ACK_Reg, cmdinfo->cmd_tag)) {
- SENSOR_TR("%s write CMD_ACK_Reg(main:0x%x tag:0x%x) error!\n",SENSOR_NAME_STRING(),cmd_main,cmdinfo->cmd_tag);
- goto sensor_af_cmdset_err;
- }
- SENSOR_DG("%s write CMD_ACK_Reg(main:0x%x tag:0x%x) success!\n",SENSOR_NAME_STRING(),cmd_main,cmdinfo->cmd_tag);
- }
- for (i=0; i<4; i++) {
+ for (i=0; i<4; i++) {
if (cmdinfo->validate_bit & (1<<i)) {
- if (sensor_write(client, CMD_PARA0_Reg-i, cmdinfo->cmd_para[i])) {
+ if (sensor_write(client, CMD_PARA0_Reg+i, cmdinfo->cmd_para[i])) {
SENSOR_TR("%s write CMD_PARA_Reg(main:0x%x para%d:0x%x) error!\n",SENSOR_NAME_STRING(),cmd_main,i,cmdinfo->cmd_para[i]);
goto sensor_af_cmdset_err;
}
SENSOR_DG("%s write CMD_PARA_Reg(main:0x%x para%d:0x%x) success!\n",SENSOR_NAME_STRING(),cmd_main,i,cmdinfo->cmd_para[i]);
}
}
+
+ if (cmdinfo->validate_bit & 0x80) {
+ if (sensor_write(client, CMD_ACK_Reg, cmdinfo->cmd_tag)) {
+ SENSOR_TR("%s write CMD_ACK_Reg(main:0x%x tag:0x%x) error!\n",SENSOR_NAME_STRING(),cmd_main,cmdinfo->cmd_tag);
+ goto sensor_af_cmdset_err;
+ }
+ SENSOR_DG("%s write CMD_ACK_Reg(main:0x%x tag:0x%x) success!\n",SENSOR_NAME_STRING(),cmd_main,cmdinfo->cmd_tag);
+ }
+
} else {
if (sensor_write(client, CMD_ACK_Reg, 0xff)) {
SENSOR_TR("%s write CMD_ACK_Reg(main:0x%x no tag) error!\n",SENSOR_NAME_STRING(),cmd_main);
sensor_af_idlechk_end:
return ret;
}
+static int sensor_af_touch_zone(struct i2c_client *client, int *zone_center_pos)
+{
+ int ret = 0;
+ struct af_cmdinfo cmdinfo;
+ cmdinfo.cmd_tag = 0x01;
+ cmdinfo.validate_bit = 0x83;
+ if (zone_center_pos[0]<=8)
+ cmdinfo.cmd_para[0] = 0;
+ else if ((zone_center_pos[0]>8) && (zone_center_pos[0]<64))
+ cmdinfo.cmd_para[0] = zone_center_pos[0]-8;
+ else
+ cmdinfo.cmd_para[0] = 64;
+
+ if (zone_center_pos[1]<=6)
+ cmdinfo.cmd_para[1] = 0;
+ else if ((zone_center_pos[1]>6) && (zone_center_pos[1]<48))
+ cmdinfo.cmd_para[1] = zone_center_pos[1]-6;
+ else
+ cmdinfo.cmd_para[1] = 48;
+
+ ret = sensor_af_cmdset(client, TouchZoneConfig_Cmd, &cmdinfo);
+ if(0 != ret) {
+ SENSOR_TR("%s touch zone config error!\n",SENSOR_NAME_STRING());
+ ret = -1;
+ goto sensor_af_zone_end;
+ }
+sensor_af_zone_end:
+ return ret;
+}
static int sensor_af_single(struct i2c_client *client)
{
int ret = 0;
char state,cnt;
struct af_cmdinfo cmdinfo;
-
+
cmdinfo.cmd_tag = 0x01;
cmdinfo.validate_bit = 0x80;
ret = sensor_af_cmdset(client, SingleFocus_Cmd, &cmdinfo);
break;
}
case WqCmd_af_single:
- {
+ {
+ if ((sensor_work->zone_center_pos[0] >=0) && (sensor_work->zone_center_pos[1]>=0))
+ sensor_af_touch_zone(client,sensor_work->zone_center_pos);
+
if (sensor_af_single(client) < 0) {
SENSOR_TR("%s Sensor_af_single is failed in sensor_af_workqueue!\n",SENSOR_NAME_STRING());
sensor_work->result = WqRet_fail;
return;
}
-static int sensor_af_workqueue_set(struct soc_camera_device *icd, enum sensor_wq_cmd cmd, int var, bool wait)
+static int sensor_af_workqueue_set(struct soc_camera_device *icd, enum sensor_wq_cmd cmd, int var, bool wait, int *zone_pos)
{
struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
struct sensor *sensor = to_sensor(client);
wk->result = WqRet_inval;
wk->wait = wait;
wk->var = var;
+
+ if (zone_pos) {
+ if (*zone_pos || *(zone_pos+1) || *(zone_pos+2) || *(zone_pos+3)) {
+ *zone_pos += 1000;
+ *(zone_pos+1) += 1000;
+ *(zone_pos+2) += 1000;
+ *(zone_pos+3) += 1000;
+ wk->zone_center_pos[0] = ((*zone_pos + *(zone_pos+2))>>1)*80/2000;
+ wk->zone_center_pos[1] = ((*(zone_pos+1) + *(zone_pos+3))>>1)*60/2000;
+ } else {
+ #if CONFIG_SENSOR_FocusCenterInCapture
+ wk->zone_center_pos[0] = 32;
+ wk->zone_center_pos[1] = 24;
+ #else
+ wk->zone_center_pos[0] = -1;
+ wk->zone_center_pos[1] = -1;
+ #endif
+ }
+ }
+
init_waitqueue_head(&wk->done);
queue_delayed_work(sensor->sensor_wq,&(wk->dwork),0);
sensor->parameter.preview_exposure = ((tp_h<<12) & 0xF000) | ((tp_m<<4) & 0x0FF0) | ((tp_l>>4) & 0x0F);
//Read back AGC Gain for preview
- sensor_read(client,0x350b, &tp_l);
- sensor->parameter.preview_gain = tp_l;
+ sensor_read(client,0x350b, &ret_l);
+ sensor->parameter.preview_gain = ret_l;
SENSOR_DG(" %s Read 0x350b=0x%02x PreviewExposure:%d 0x3500=0x%02x 0x3501=0x%02x 0x3502=0x%02x \n",
- SENSOR_NAME_STRING(), tp_l,sensor->parameter.preview_exposure,ret_h, ret_m, ret_l);
+ SENSOR_NAME_STRING(), tp_l,sensor->parameter.preview_exposure,tp_h, tp_m, tp_l);
return 0;
}
#define OV5640_FULL_PERIOD_PIXEL_NUMS_HTS (2844)
u8 ExposureMid;
u8 ExposureHigh;
u16 ulCapture_Exposure;
- u32 ulCapture_Exposure_Gain;
- u16 iCapture_Gain;
- u8 Lines_10ms;
- bool m_60Hz = 0;
- u8 reg_l = 0,reg_h =0;
u16 Preview_Maxlines;
u8 Gain;
- u32 Capture_MaxLines;
u16 OV5640_g_iExtra_ExpLines;
struct sensor *sensor = to_sensor(client);
SENSOR_DG("cap shutter calutaed = %d, 0x%x\n", ulCapture_Exposure,ulCapture_Exposure);
// write the gain and exposure to 0x350* registers
- sensor_write(client,0x350b, Gain);
- //Gain = (Gain >> 8) & 0x01;
- //sensor_write(client,0x350a, Gain);
+ sensor_write(client,0x350b, Gain);
if (ulCapture_Exposure <= 1940) {
OV5640_g_iExtra_ExpLines = 0;
struct sensor *sensor = to_sensor(client);
const struct v4l2_queryctrl *qctrl;
const struct sensor_datafmt *fmt;
- char value,ret_h,ret_l;
+ char value;
int ret,pid = 0;
SENSOR_DG("\n%s..%s.. \n",SENSOR_NAME_STRING(),__FUNCTION__);
struct soc_camera_device *icd = client->dev.platform_data;
struct reginfo *winseqe_set_addr=NULL;
int ret = 0, set_w,set_h;
- char ret_h,ret_l;
fmt = sensor_find_datafmt(mf->code, sensor_colour_fmts,
ARRAY_SIZE(sensor_colour_fmts));
}
#if CONFIG_SENSOR_Focus
if (sensor->info_priv.auto_focus == SENSOR_AF_MODE_AUTO) {
- sensor_af_workqueue_set(icd,WqCmd_af_return_idle,0,true);
+ sensor_af_workqueue_set(icd,WqCmd_af_return_idle,0,true,NULL);
msleep(200);
} else {
msleep(500);
if ((sensor->info_priv.funmodule_state & SENSOR_AF_IS_OK) && (sensor->info_priv.affm_reinit == 0)) {
if ((value >= qctrl_info->minimum) && (value <= qctrl_info->maximum)) {
- ret = sensor_af_workqueue_set(icd, WqCmd_af_special_pos, value, true);
+ ret = sensor_af_workqueue_set(icd, WqCmd_af_special_pos, value, true,NULL);
SENSOR_DG("%s..%s : %d ret:0x%x\n",SENSOR_NAME_STRING(),__FUNCTION__, value,ret);
} else {
ret = -EINVAL;
if ((sensor->info_priv.funmodule_state & SENSOR_AF_IS_OK) && (sensor->info_priv.affm_reinit == 0)) {
if ((value >= qctrl_info->minimum) && (value <= qctrl_info->maximum)) {
if (value > 0) {
- ret = sensor_af_workqueue_set(icd, WqCmd_af_near_pos, 0, true);
+ ret = sensor_af_workqueue_set(icd, WqCmd_af_near_pos, 0, true,NULL);
} else {
- ret = sensor_af_workqueue_set(icd, WqCmd_af_far_pos, 0, true);
+ ret = sensor_af_workqueue_set(icd, WqCmd_af_far_pos, 0, true,NULL);
}
SENSOR_DG("%s..%s : %d ret:0x%x\n",SENSOR_NAME_STRING(),__FUNCTION__, value,ret);
} else {
return ret;
}
-static int sensor_set_focus_mode(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value)
+static int sensor_set_focus_mode(struct soc_camera_device *icd, const struct v4l2_queryctrl *qctrl, int value, int *zone_pos)
{
struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
struct sensor *sensor = to_sensor(client);
{
case SENSOR_AF_MODE_AUTO:
{
- ret = sensor_af_workqueue_set(icd, WqCmd_af_single, 0, true);
+ ret = sensor_af_workqueue_set(icd, WqCmd_af_single, 0, true, zone_pos);
break;
}
case SENSOR_AF_MODE_CONTINUOUS:
{
- ret = sensor_af_workqueue_set(icd, WqCmd_af_continues, 0, true);
+ ret = sensor_af_workqueue_set(icd, WqCmd_af_continues, 0, true,NULL);
break;
}*/
default:
const struct v4l2_queryctrl *qctrl;
struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
struct sensor *sensor = to_sensor(client);
- int val_offset,ret;
+ int val_offset;
qctrl = soc_camera_find_qctrl(&sensor_ops, ext_ctrl->id);
case V4L2_CID_FOCUS_AUTO:
{
if (ext_ctrl->value == 1) {
- if (sensor_set_focus_mode(icd, qctrl,SENSOR_AF_MODE_AUTO) != 0) {
+ if (sensor_set_focus_mode(icd, qctrl,SENSOR_AF_MODE_AUTO,ext_ctrl->rect) != 0) {
if(0 == (sensor->info_priv.funmodule_state & SENSOR_AF_IS_OK)) {
sensor->info_priv.auto_focus = SENSOR_AF_MODE_AUTO;
}
/* If auto focus firmware haven't download success, must download firmware again when in video or preview stream on */
if (sensor_fmt_capturechk(sd, &mf) == false) {
if ((sensor->info_priv.affm_reinit == 1) || ((sensor->info_priv.funmodule_state & SENSOR_AF_IS_OK)==0)) {
- sensor_af_workqueue_set(icd, WqCmd_af_init, 0, false);
+ sensor_af_workqueue_set(icd, WqCmd_af_init, 0, false,NULL);
sensor->info_priv.affm_reinit = 0;
}
}