/****************************************************************************** Function : ov5648_sunny_p5v18g_otp_read_module_info Description: read module info OTP. ******************************************************************************/ static int ov5648_sunny_p5v18g_otp_read_module_info(struct msm_sensor_ctrl_t *s_ctrl, struct ov5648_sunny_p5v18g_otp_struct * otp_ptr) { //module info from group2,bank1 first if (-1 == ov5648_sunny_p5v18g_select_bank(s_ctrl, OV5648_SUNNY_P5V18G_OTP_BANK1)) { return -1; } //Module info: Bank 1:0x3d02~0x3d06 ov5648_sunny_p5v18g_cci_i2c_read(s_ctrl, 0x3d02, &(otp_ptr->product_year)); ov5648_sunny_p5v18g_cci_i2c_read(s_ctrl, 0x3d03, &(otp_ptr->product_month)); ov5648_sunny_p5v18g_cci_i2c_read(s_ctrl, 0x3d04, &(otp_ptr->product_date)); ov5648_sunny_p5v18g_cci_i2c_read(s_ctrl, 0x3d05, &(otp_ptr->camera_id)); ov5648_sunny_p5v18g_cci_i2c_read(s_ctrl, 0x3d06, &(otp_ptr->supplier_version_id)); CMR_LOGD("%s,group 2 otp_ptr.product_year:%d\n",__func__,otp_ptr->product_year); CMR_LOGD("%s,group 2 otp_ptr.product_month:%d\n",__func__,otp_ptr->product_month); CMR_LOGD("%s,group 2 otp_ptr.product_date:%d\n",__func__,otp_ptr->product_date); CMR_LOGD("%s,group 2 otp_ptr.camera_id:%d\n",__func__,otp_ptr->camera_id); CMR_LOGD("%s,group 2 otp_ptr.supplier_version_id:%d\n",__func__,otp_ptr->supplier_version_id); ov5648_sunny_p5v18g_otp_clear(s_ctrl); if (0 != otp_ptr->product_year)// year is not zero, we assume module info is correct { CMR_LOGW("%s, Module info lays in group 2\n",__func__); return 0; } //group2 fail, check group1, bank0 if (-1 == ov5648_sunny_p5v18g_select_bank(s_ctrl, OV5648_SUNNY_P5V18G_OTP_BANK0)) { return -1; } //Module info: Bank 0:0x3d05~0x3d09 ov5648_sunny_p5v18g_cci_i2c_read(s_ctrl, 0x3d05, &(otp_ptr->product_year)); ov5648_sunny_p5v18g_cci_i2c_read(s_ctrl, 0x3d06, &(otp_ptr->product_month)); ov5648_sunny_p5v18g_cci_i2c_read(s_ctrl, 0x3d07, &(otp_ptr->product_date)); ov5648_sunny_p5v18g_cci_i2c_read(s_ctrl, 0x3d08, &(otp_ptr->camera_id)); ov5648_sunny_p5v18g_cci_i2c_read(s_ctrl, 0x3d09, &(otp_ptr->supplier_version_id)); CMR_LOGD("%s,group 2 otp_ptr.product_year:%d\n",__func__,otp_ptr->product_year); CMR_LOGD("%s,group 2 otp_ptr.product_month:%d\n",__func__,otp_ptr->product_month); CMR_LOGD("%s,group 2 otp_ptr.product_date:%d\n",__func__,otp_ptr->product_date); CMR_LOGD("%s,group 2 otp_ptr.camera_id:%d\n",__func__,otp_ptr->camera_id); CMR_LOGD("%s,group 2 otp_ptr.supplier_version_id:%d\n",__func__,otp_ptr->supplier_version_id); ov5648_sunny_p5v18g_otp_clear(s_ctrl); if (0 != otp_ptr->product_year) // year is not zero, we assume module info is correct { CMR_LOGW("%s, Module info lays in group 1\n",__func__); return 0;//otp read sucess } else { CMR_LOGE("%s, Error !No Module inf found in OTP\n",__func__); return -1;//otp read fail } return 0; }
/****************************************************************************** Function : ov5648_sunny_p5v18g_otp_read_vcm Description: read vcm info OTP. ******************************************************************************/ static int ov5648_sunny_p5v18g_otp_read_vcm(struct msm_sensor_ctrl_t *s_ctrl, struct ov5648_sunny_p5v18g_otp_struct * otp_ptr) { uint16_t vcm_start_value = 0; uint16_t vcm_end_value = 0; //vcm otp lays in bank1 if (0 != ov5648_sunny_p5v18g_select_bank(s_ctrl, OV5648_SUNNY_P5V18G_OTP_BANK1)) { return -1; } //VCM Start: Bank 1, 0x3d0d, 0x3d00 //group 2 ov5648_sunny_p5v18g_cci_i2c_read(s_ctrl, 0x3d0d, &vcm_start_value); CMR_LOGD("%s, VCM start group2 value:0x%x\n",__func__ , vcm_start_value); if (0 == vcm_start_value) { //group1 ov5648_sunny_p5v18g_cci_i2c_read( s_ctrl, 0x3d00, &vcm_start_value); CMR_LOGD("%s, VCM start group1 value:0x%x\n",__func__ , vcm_start_value); } //VCM:End, Bank 1,0x3d0e, 0x3d01 //group 2 ov5648_sunny_p5v18g_cci_i2c_read(s_ctrl, 0x3d0e, &vcm_end_value ); CMR_LOGD("%s, VCM end group2 value:0x%x\n",__func__ , vcm_end_value ); if (0 == vcm_end_value ) { //group 1 ov5648_sunny_p5v18g_cci_i2c_read(s_ctrl, 0x3d01, &vcm_end_value ); CMR_LOGD("%s, VCM end group1 value:0x%x\n",__func__ , vcm_end_value ); } //clear the buffer ov5648_sunny_p5v18g_otp_clear(s_ctrl); if ((0 != vcm_start_value) && (0 != vcm_end_value)) { otp_ptr->vcm_start = vcm_start_value; otp_ptr->vcm_end = vcm_end_value; CMR_LOGD("%s, VCM info read sucess!\n\n",__func__); //otp read success return 0; } else { CMR_LOGE("%s, Error VCM info is not correct!\n",__func__); //otp read fail return -1; } }
/****************************************************************************** Function : ov5648_sunny_p5v18g_otp_debug Description: Only for debug use ******************************************************************************/ void ov5648_sunny_p5v18g_otp_debug(struct ov5648_sunny_p5v18g_otp_struct otp_ptr) { CMR_LOGD("%s,otp_ptr.product_year:%d\n",__func__,otp_ptr.product_year); CMR_LOGD("%s,otp_ptr.product_month:%d\n",__func__,otp_ptr.product_month); CMR_LOGD("%s,otp_ptr.product_date:%d\n",__func__,otp_ptr.product_date); CMR_LOGD("%s,otp_ptr.camera_id:0x%x\n",__func__,otp_ptr.camera_id); CMR_LOGD("%s,otp_ptr.supplier_version_id:0x%x\n",__func__,otp_ptr.supplier_version_id); CMR_LOGD("%s,otp_ptr.wb_rg:0x%x\n",__func__, (otp_ptr.wb_rg_h << 8) + otp_ptr.wb_rg_l); CMR_LOGD("%s,otp_ptr.wb_bg:0x%x\n",__func__, (otp_ptr.wb_bg_h << 8) + otp_ptr.wb_bg_l); CMR_LOGD("%s,otp_ptr.wb_gbgr:0x%x\n",__func__,(otp_ptr.wb_gbgr_h << 8) + otp_ptr.wb_gbgr_l); CMR_LOGD("%s,otp_ptr.vcm_start:0x%x\n",__func__,otp_ptr.vcm_start); CMR_LOGD("%s,otp_ptr.vcm_end:0x%x\n",__func__,otp_ptr.vcm_end); }
/****************************************************************************** Function : ov5648_sunny_p5v18g_select_bank Description: Select the specific bankNum. OTP will be read into IC's internel men. ******************************************************************************/ static int ov5648_sunny_p5v18g_select_bank(struct msm_sensor_ctrl_t *s_ctrl, int bankNum) { CMR_LOGD("%s, select bank num :%d\n",__func__, bankNum); if (OV5648_SUNNY_P5V18G_OTP_BANK0 == bankNum) { ov5648_sunny_p5v18g_cci_i2c_write(s_ctrl, 0x3d84, 0xc0); ov5648_sunny_p5v18g_cci_i2c_write(s_ctrl, 0x3d85, 0x00);//bank0 ov5648_sunny_p5v18g_cci_i2c_write(s_ctrl, 0x3d86, 0x0f); ov5648_sunny_p5v18g_cci_i2c_write(s_ctrl, 0x3d81, 0x01);//start read mdelay(3);//must delay 3ms return 0; } else if (OV5648_SUNNY_P5V18G_OTP_BANK1 == bankNum) { ov5648_sunny_p5v18g_cci_i2c_write(s_ctrl, 0x3d84, 0xc0); ov5648_sunny_p5v18g_cci_i2c_write(s_ctrl, 0x3d85, 0x10);//bank1 ov5648_sunny_p5v18g_cci_i2c_write(s_ctrl, 0x3d86, 0x1f); ov5648_sunny_p5v18g_cci_i2c_write(s_ctrl, 0x3d81, 0x01);//start read mdelay(3);//must delay 3ms return 0; } else { CMR_LOGE("%s, Error bank number!\n",__func__); return -1; } return 0; }
/****************************************************************************** Function : ov5648_foxconn_132_otp_debug Description: Only for debug use ******************************************************************************/ void ov5648_foxconn_132_otp_debug(struct ov5648_foxconn_132_otp_struct otp_ptr) { CMR_LOGD("%s,otp_ptr.product_year:%d\n",__func__,otp_ptr.product_year); CMR_LOGD("%s,otp_ptr.product_month:%d\n",__func__,otp_ptr.product_month); CMR_LOGD("%s,otp_ptr.product_date:%d\n",__func__,otp_ptr.product_date); CMR_LOGD("%s,otp_ptr.camera_id:0x%x\n",__func__,otp_ptr.camera_id); CMR_LOGD("%s,otp_ptr.supplier_version_id:0x%x\n",__func__,otp_ptr.supplier_version_id); CMR_LOGD("%s,otp_ptr.wb_rg:0x%x\n",__func__, (otp_ptr.wb_rg_h << 8) + otp_ptr.wb_rg_l); CMR_LOGD("%s,otp_ptr.wb_bg:0x%x\n",__func__, (otp_ptr.wb_bg_h << 8) + otp_ptr.wb_bg_l); CMR_LOGD("%s,otp_ptr.wb_gbgr:0x%x\n",__func__,(otp_ptr.wb_gbgr_h << 8) + otp_ptr.wb_gbgr_l); }
/****************************************************************************** Function : ov5648_sunny_p5v18g_update_awb_gain Description: Update the RGB AWB gain to sensor ******************************************************************************/ void ov5648_sunny_p5v18g_update_awb_gain(struct msm_sensor_ctrl_t *s_ctrl, uint32_t r_gain, uint32_t g_gain, uint32_t b_gain) { CMR_LOGD("%s, R_gain:0x%x,G_gain:0x%x,B_gain:0x%x\n",__func__, r_gain, g_gain, b_gain); if (r_gain > 0x400) { ov5648_sunny_p5v18g_cci_i2c_write(s_ctrl, 0x5186, r_gain >> 8); ov5648_sunny_p5v18g_cci_i2c_write(s_ctrl, 0x5187, r_gain & 0x00ff); }
/****************************************************************************** Function : s5k4e1_update_awb_gain Description: Update the RGB AWB gain to sensor ******************************************************************************/ void s5k4e1_update_awb_gain(struct msm_sensor_ctrl_t *s_ctrl, uint32_t r_gain, uint32_t g_gain, uint32_t b_gain) { CMR_LOGD("%s, R_gain:0x%x,G_gain:0x%x,B_gain:0x%x\n",__func__, r_gain, g_gain, b_gain); if (r_gain >= 0x100) { s5k4e1_cci_i2c_write(s_ctrl, 0x0210, r_gain >> 8); s5k4e1_cci_i2c_write(s_ctrl, 0x0211, r_gain & 0x00ff); }
/****************************************************************************** Function : s5k4e1_otp_debug Description: Only for debug use ******************************************************************************/ void s5k4e1_otp_debug(struct s5k4e1_otp_struct otp_ptr) { CMR_LOGD("%s,otp_ptr.product_year:0x%x",__func__,otp_ptr.product_year); CMR_LOGD("%s,otp_ptr.product_month:0x%x",__func__,otp_ptr.product_month); CMR_LOGD("%s,otp_ptr.product_date:0x%x",__func__,otp_ptr.product_date); CMR_LOGD("%s,otp_ptr.camera_id:0x%x",__func__,otp_ptr.camera_id); CMR_LOGD("%s,otp_ptr.supplier_version_id:0x%x",__func__,otp_ptr.supplier_version_id); CMR_LOGD("%s,otp_ptr.version:0x%x\n",__func__,otp_ptr.version); CMR_LOGD("%s,otp_ptr.wb_rg:0x%x",__func__,otp_ptr.wb_rg); CMR_LOGD("%s,otp_ptr.wb_bg:0x%x",__func__,otp_ptr.wb_bg); return; }
static uint32_t _DC_GetExifPrimaryPriDescInfo(uint32_t param) { EXIF_PRI_DESC_T *exif_ptr = &s_dc_exif_pri_desc_info; time_t timep; struct tm *p; time(&timep); p = gmtime(&timep); sprintf((char *)exif_ptr->DateTime, "%4d:%2d:%2d %2d:%2d:%2d", (1900+p->tm_year), (1+p->tm_mon), p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec); #ifdef KERNEL_TIME SCI_DATE_T cur_date = { 0 }; SCI_TIME_T cur_time = { 0 }; *(uint32_t *) & s_dc_exif_pri_desc_info.valid = (uint32_t) 0x7F; TM_GetSysDate(&cur_date); TM_GetSysTime(&cur_time); sprintf((int8 *)exif_ptr->DateTime, "%04d:%02d:%02d %02d:%02d:%02d", cur_date.year, cur_date.mon, cur_date.mday, cur_time.hour, cur_time.min, cur_time.sec); #endif *(uint32_t *) & s_dc_exif_pri_desc_info.valid = (uint32_t) 0x7F; sprintf((char *) exif_ptr->DateTime, "%04d:%02d:%02d %02d:%02d:%02d", (1900+p->tm_year), (1+p->tm_mon),p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec); /*sprintf((int8*)s_dc_exif_pri_desc_info.Copyright, "%s", "CopyRight");*/ /*sprintf((int8*)s_dc_exif_pri_desc_info.ImageDescription, "%s", "ImageDescription");*/ sprintf((char *) s_dc_exif_pri_desc_info.Make, "%s", "Spreadtrum"); sprintf((char *) s_dc_exif_pri_desc_info.Model, "%s", "SP8810ga"); /*sprintf((int8*)s_dc_exif_pri_desc_info.Software, "%s", "Test Version v0.0.0.1");*/ /*sprintf((int8*)s_dc_exif_pri_desc_info.Artist, "%s", "Artist");*/ sprintf((char *) s_dc_exif_pri_desc_info.Copyright, "%s","CopyRight, Spreadtrum, 2012"); CMR_LOGD("return 0x%x.",(uint32_t)exif_ptr); return (uint32_t) exif_ptr; }
/****************************************************************************** Function : ov5648_ofilm_ohw5f03_read_otp Description: read module info , awb otp separeately, and set coressponding bits ******************************************************************************/ void ov5648_ofilm_ohw5f03_read_otp(struct msm_sensor_ctrl_t *s_ctrl, struct ov5648_ofilm_ohw5f03_otp_struct * current_otp) { if (0 == ov5648_ofilm_ohw5f03_otp_read_module_info(s_ctrl, current_otp)) { ov5648_ofilm_ohw5f03_otp_read_flag |= OV5648_OFILM_OHW5F03_OTP_MODULE_INFO; } if (0 == ov5648_ofilm_ohw5f03_otp_read_awb(s_ctrl, current_otp)) { ov5648_ofilm_ohw5f03_otp_read_flag |= OV5648_OFILM_OHW5F03_OTP_AWB; } CMR_LOGD("%s, ov5648_ofilm_ohw5f03_otp_read_flag:0x%x\n",__func__, ov5648_ofilm_ohw5f03_otp_read_flag); return; }
/****************************************************************************** Function : ov5648_foxconn_132_read_otp Description: read module info , awb otp separeately, and set coressponding bits ******************************************************************************/ void ov5648_foxconn_132_read_otp(struct msm_sensor_ctrl_t *s_ctrl, struct ov5648_foxconn_132_otp_struct * current_otp) { if (0 == ov5648_foxconn_132_otp_read_module_info(s_ctrl, current_otp)) { ov5648_foxconn_132_otp_read_flag |= OV5648_FOXCONN_132_OTP_MODULE_INFO; } if (0 == ov5648_foxconn_132_otp_read_awb(s_ctrl, current_otp)) { ov5648_foxconn_132_otp_read_flag |= OV5648_FOXCONN_132_OTP_AWB; } CMR_LOGD("%s, ov5648_foxconn_132_otp_read_flag:0x%x\n",__func__, ov5648_foxconn_132_otp_read_flag); return; }
/**---------------------------------------------------------------------------* ** External Functions * **---------------------------------------------------------------------------*/ cmr_int cmr_sensor_init(struct sensor_init_param *init_param_ptr, cmr_handle *sensor_handle) { cmr_int ret = CMR_CAMERA_SUCCESS; struct cmr_sensor_handle *handle = NULL; CMR_LOGI("E"); if (!init_param_ptr) { CMR_LOGE("Invalid param!"); return CMR_CAMERA_INVALID_PARAM; } handle = (struct cmr_sensor_handle *)malloc(sizeof(struct cmr_sensor_handle)); if (!handle) { CMR_LOGE("No mem!"); return CMR_CAMERA_NO_MEM; } cmr_bzero(handle, sizeof(struct cmr_sensor_handle)); /*save init param*/ handle->oem_handle = init_param_ptr->oem_handle; handle->sensor_bits = init_param_ptr->sensor_bits; handle->private_data = init_param_ptr->private_data; handle->is_autotest = init_param_ptr->is_autotest; CMR_LOGD("oem_handle: 0x%lx, sensor_bits: %ld, private_data: 0x%lx autotest %ld", (cmr_uint)handle->oem_handle, handle->sensor_bits, (cmr_uint)handle->private_data, handle->is_autotest); /*create thread*/ ret = cmr_sns_create_thread(handle); if (ret) { CMR_LOGE("create thread failed!"); ret = CMR_CAMERA_FAIL; goto init_end; } /*return handle*/ *sensor_handle = (cmr_handle)handle; CMR_LOGI("handle 0x%lx created!", (cmr_uint)handle); init_end: if (ret) { if (handle) { free(handle); handle = NULL; } } CMR_LOGV("X ret %ld", ret); return ret; }
static uint32_t _DC_GetExifSpecUserInfo(uint32_t param) { EXIF_SPEC_USER_T *exif_ptr = &s_dc_exif_spec_user_info; /*s_dc_exif_spec_user_info.valid.MakerNote = 0; s_dc_exif_spec_user_info.valid.UserComment = 0; s_dc_exif_spec_user_info.UserComment.count = 1; s_dc_exif_spec_user_info.UserComment.count = strlen((char*)exif_user_comments); s_dc_exif_spec_user_info.UserComment.ptr = (void*)exif_user_comments; s_dc_exif_spec_user_info.UserComment.type = EXIF_ASCII; s_dc_exif_spec_user_info.UserComment.size = 1;*/ CMR_LOGD(" valid.UserComment %d \n",s_dc_exif_spec_user_info.valid.UserComment); return (uint32_t) exif_ptr; }
uint32_t getOrientationFromRotationDegrees(int degrees) { uint32_t orientation = 1;/*ExifInterface.ORIENTATION_NORMAL;*/ degrees %= 360; if (degrees < 0) degrees += 360; if (degrees < 45) { orientation = 1;/*ExifInterface.ORIENTATION_NORMAL;*/ } else if (degrees < 135) { orientation = 6;/*ExifInterface.ORIENTATION_ROTATE_90;*/ } else if (degrees < 225) { orientation = 3;/*ExifInterface.ORIENTATION_ROTATE_180;*/ } else { orientation = 8;/*ExifInterface.ORIENTATION_ROTATE_270;*/ } CMR_LOGD("rotation degrees: %d, orientation: %d.", degrees, orientation); return orientation; }
/****************************************************************************** Function : ov5648_sunny_p5v18g_read_otp Description: read module info , awb, vcm otp separeately, and set coressponding bits ******************************************************************************/ void ov5648_sunny_p5v18g_read_otp(struct msm_sensor_ctrl_t *s_ctrl, struct ov5648_sunny_p5v18g_otp_struct * current_otp) { if (0 == ov5648_sunny_p5v18g_otp_read_module_info(s_ctrl, current_otp)) { ov5648_sunny_p5v18g_otp_read_flag |= OV5648_SUNNY_P5V18G_OTP_MODULE_INFO; } if (0 == ov5648_sunny_p5v18g_otp_read_awb(s_ctrl, current_otp)) { ov5648_sunny_p5v18g_otp_read_flag |= OV5648_SUNNY_P5V18G_OTP_AWB; } if (0 == ov5648_sunny_p5v18g_otp_read_vcm(s_ctrl, current_otp)) { ov5648_sunny_p5v18g_otp_read_flag |= OV5648_SUNNY_P5V18G_OTP_VCM; } CMR_LOGD("%s, ov5648_sunny_p5v18g_otp_read_flag:0x%x\n",__func__, ov5648_sunny_p5v18g_otp_read_flag); return; }
/****************************************************************************** Function : ov5648_sunny_p5v18g_update_otp Description: Check, read OTP ******************************************************************************/ static int ov5648_sunny_p5v18g_update_otp(struct msm_sensor_ctrl_t *s_ctrl) { struct ov5648_sunny_p5v18g_otp_struct current_otp; uint32_t r_gain = 0; uint32_t g_gain = 0; uint32_t b_gain = 0; uint32_t g_gain_r = 0; uint32_t g_gain_b = 0; uint32_t rg = 0; uint32_t bg = 0; memset(¤t_otp, 0, sizeof(struct ov5648_sunny_p5v18g_otp_struct)); // R/G and B/G of current camera module is read out from sensor OTP ov5648_sunny_p5v18g_read_otp(s_ctrl, ¤t_otp); ov5648_sunny_p5v18g_otp_debug(current_otp); rg = (current_otp.wb_rg_h << 8) + current_otp.wb_rg_l; bg = (current_otp.wb_bg_h << 8) + current_otp.wb_bg_l; //check if AWB OTP is read correctly if (0 ==(ov5648_sunny_p5v18g_otp_read_flag & OV5648_SUNNY_P5V18G_OTP_AWB)) { CMR_LOGE("%s Error!no AWB data in OTP!\n", __func__); return -1; } if ((0 == rg) || (0 == bg))//make sure rg and bg are not zero { CMR_LOGE("%s, Error Zero rg or bg, rg:%d, bg:%d\n", __func__, rg, bg); return -1; } CMR_LOGD("%s, r/g:0x%x, b/g:0x%x\n", __func__, rg, bg); //calculate G gain //0x400 = 1x gain if(bg < bg_ratio_typical) { if (rg < rg_ratio_typical) { // current_otp.bg_ratio < BG_Ratio_typical && // current_otp.rg_ratio < RG_Ratio_typical g_gain = 0x400; b_gain = (0x400 * bg_ratio_typical) / bg; r_gain = (0x400 * rg_ratio_typical) / rg; } else { // current_otp.bg_ratio < BG_Ratio_typical && // current_otp.rg_ratio >= RG_Ratio_typical r_gain = 0x400; g_gain = (0x400 * rg) / rg_ratio_typical; b_gain = (g_gain * bg_ratio_typical) / bg; } } else { if (rg < rg_ratio_typical) { // current_otp.bg_ratio >= BG_Ratio_typical && // current_otp.rg_ratio < RG_Ratio_typical b_gain = 0x400; g_gain = (0x400 * bg) / bg_ratio_typical; r_gain = (g_gain * rg_ratio_typical) / rg; } else { // current_otp.bg_ratio >= BG_Ratio_typical && // current_otp.rg_ratio >= RG_Ratio_typical g_gain_b = (0x400 * bg) / bg_ratio_typical; g_gain_r = (0x400 * rg) / rg_ratio_typical; if(g_gain_b > g_gain_r ) { b_gain = 0x400; g_gain = g_gain_b; r_gain = (g_gain * rg_ratio_typical) /rg; } else { r_gain = 0x400; g_gain = g_gain_r; b_gain = (g_gain * bg_ratio_typical) / bg; } } } CMR_LOGD("%s, R_gain:0x%x,G_gain:0x%x,B_gain:0x%x\n", __func__, r_gain, g_gain, b_gain); gr_gain = r_gain; gg_gain = g_gain; gb_gain = b_gain; return 0; }
cmr_int cmr_sns_ioctl(struct sensor_drv_context *sensor_cxt, cmr_uint cmd, cmr_uint arg) { SENSOR_IOCTL_FUNC_PTR func_ptr; SENSOR_IOCTL_FUNC_TAB_T *func_tab_ptr; cmr_uint temp; cmr_u32 ret = CMR_CAMERA_SUCCESS; cmr_u32 sns_cmd = SENSOR_IOCTL_GET_STATUS; ret = cmr_sns_get_ioctl_cmd(&sns_cmd, cmd); if (ret) { CMR_LOGE("can't get correct command !\n"); return CMR_CAMERA_INVALID_PARAM; } if (SENSOR_IOCTL_GET_STATUS != sns_cmd) { CMR_LOGI("cmd = %d, arg = 0x%lx.\n", sns_cmd, arg); } SENSOR_DRV_CHECK_ZERO(sensor_cxt); if (!sensor_is_init_common(sensor_cxt)) { CMR_LOGE("sensor has not init.\n"); return SENSOR_OP_STATUS_ERR; } if (SENSOR_IOCTL_CUS_FUNC_1 > sns_cmd) { CMR_LOGW("can't access internal command !\n"); return SENSOR_SUCCESS; } if (PNULL == sensor_cxt->sensor_info_ptr) { CMR_LOGE("No sensor info!"); return -1; } func_tab_ptr = sensor_cxt->sensor_info_ptr->ioctl_func_tab_ptr; #ifdef __LP64__ temp = *(cmr_uint *) ((cmr_uint) func_tab_ptr + sns_cmd * S_BIT_3); #else temp = *(cmr_uint *) ((cmr_uint) func_tab_ptr + sns_cmd * S_BIT_2); #endif func_ptr = (SENSOR_IOCTL_FUNC_PTR) temp; #if (CONFIG_READOTP_METHOD != 0) if( SENSOR_ACCESS_VAL == cmd) { SENSOR_VAL_T *val = (SENSOR_VAL_T *)arg; if(val->type == SENSOR_VAL_TYPE_READ_OTP) { SENSOR_OTP_PARAM_T *param_ptr = (SENSOR_OTP_PARAM_T *)val->pval; CMR_LOGD("SENSOR_IO_READ_OTPDATA %p, %d", param_ptr, param_ptr->type); ret = ioctl(sensor_cxt->fd_sensor, SENSOR_IO_READ_OTPDATA, param_ptr); if(!ret && param_ptr->type == SENSOR_OTP_PARAM_NORMAL) { val->type = SENSOR_VAL_TYPE_PARSE_OTP; ret = func_ptr(arg); } return ret; } } #endif if (PNULL != func_ptr) { ret = func_ptr(arg); } return ret; }
JINF_EXIF_INFO_T* camera_get_exif(struct camera_context *p_cxt) { JINF_EXIF_INFO_T *p_exif_info = DC_GetExifParameter(); uint32_t latitude_dd_numerator = getDataFromDouble(s_position.latitude, 0); uint32_t latitude_dd_denominator = 1; uint32_t latitude_mm_numerator = getDataFromDouble(s_position.latitude, 1); uint32_t latitude_mm_denominator = 1; uint32_t latitude_ss_numerator = 0; uint32_t latitude_ss_denominator = 0; uint32_t latitude_ref = 0; uint32_t longitude_ref = 0; uint32_t longitude_dd_numerator = 0; uint32_t longitude_dd_denominator = 0; uint32_t longitude_mm_numerator = 0; uint32_t longitude_mm_denominator = 0; uint32_t longitude_ss_numerator = 0; uint32_t longitude_ss_denominator = 0; char datetime_buf[20]; char gps_date_buf[12]; time_t timep; struct tm *p; char *datetime; char *gps_date; const char *gps_process_method; uint32_t gps_hour; uint32_t gps_minuter; uint32_t gps_second; uint32_t focal_length_numerator; uint32_t focal_length_denominator; char property[PROPERTY_VALUE_MAX]; getSecondsFromDouble(s_position.latitude, &latitude_ss_numerator, &latitude_ss_denominator); if (s_position.latitude < 0.0) { latitude_ref = 1; } else { latitude_ref = 0; } longitude_dd_numerator = getDataFromDouble(s_position.longitude, 0); longitude_dd_denominator = 1; longitude_mm_numerator = getDataFromDouble(s_position.longitude, 1); longitude_mm_denominator = 1; getSecondsFromDouble(s_position.longitude, &longitude_ss_numerator, &longitude_ss_denominator); if (s_position.longitude < 0.0) { longitude_ref = 1; } else { longitude_ref = 0; } time(&timep); p = localtime(&timep); sprintf(datetime_buf, "%4d:%02d:%02d %02d:%02d:%02d", (1900+p->tm_year), (1+p->tm_mon), p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec); datetime_buf[19] = '\0'; datetime = datetime_buf; CMR_LOGD("datetime %s",datetime); if (0 == s_position.timestamp) time(&s_position.timestamp); p = gmtime(&s_position.timestamp); sprintf(gps_date_buf, "%4d:%02d:%02d", (1900+p->tm_year), (1+p->tm_mon),p->tm_mday); gps_date_buf[10] = '\0'; gps_date = gps_date_buf; gps_hour = p->tm_hour; gps_minuter = p->tm_min; gps_second = p->tm_sec; CMR_LOGD("gps_data 2 = %s, %d:%d:%d \n", gps_date, gps_hour, gps_minuter, gps_second); gps_process_method = s_position.process_method; focal_length_numerator = p_cxt->cmr_set.focal_len; focal_length_denominator = 1000; /* Some info is not get from the kernel */ if (NULL != p_exif_info->spec_ptr) { p_exif_info->spec_ptr->basic.PixelXDimension = p_cxt->picture_size.width; p_exif_info->spec_ptr->basic.PixelYDimension = p_cxt->picture_size.height; } p_exif_info->primary.basic.ImageWidth = p_cxt->actual_picture_size.width; p_exif_info->primary.basic.ImageLength = p_cxt->actual_picture_size.height; CMR_LOGD("EXIF width=%d, height=%d \n", p_exif_info->primary.basic.ImageWidth, p_exif_info->primary.basic.ImageLength); if (NULL != p_exif_info->primary.data_struct_ptr) { p_exif_info->primary.data_struct_ptr->valid.Orientation = 1; p_exif_info->primary.data_struct_ptr->Orientation = getOrientationFromRotationDegrees(p_cxt->jpeg_cxt.set_encode_rotation); } if (NULL != p_exif_info->primary.img_desc_ptr) { strcpy((char *)p_exif_info->primary.img_desc_ptr->ImageDescription, (char *)image_desc); memset(property,'\0',sizeof(property)); property_get("ro.product.manufacturer", property, EXIF_DEF_MAKER); strcpy((char *)p_exif_info->primary.img_desc_ptr->Make, (char *)property); memset(property,'\0',sizeof(property)); property_get("ro.product.model", property, EXIF_DEF_MODEL); strcpy((char *)p_exif_info->primary.img_desc_ptr->Model, (char *)property); strcpy((char *)p_exif_info->primary.img_desc_ptr->Copyright, (char *)copyright); } if (NULL != p_exif_info->gps_ptr) { if ((0 == latitude_dd_numerator) && (0 == latitude_mm_numerator) && (0 == latitude_ss_numerator) && (0 == longitude_dd_numerator) && (0 == longitude_mm_numerator) && (0 == longitude_ss_numerator)) { /* if no Latitude and Longitude, do not write GPS to EXIF */ CMR_LOGD("GPS: Latitude and Longitude is 0, do not write to EXIF: valid=%d \n", *(uint32_t*)&p_exif_info->gps_ptr->valid); memset(&p_exif_info->gps_ptr->valid,0,sizeof(EXIF_GPS_VALID_T)); } else { p_exif_info->gps_ptr->valid.GPSLatitudeRef = 1; p_exif_info->gps_ptr->GPSLatitudeRef[0] = (0 == latitude_ref) ? 'N' : 'S'; p_exif_info->gps_ptr->valid.GPSLongitudeRef = 1; p_exif_info->gps_ptr->GPSLongitudeRef[0] = (0 == longitude_ref) ? 'E' : 'W'; p_exif_info->gps_ptr->valid.GPSLatitude = 1; p_exif_info->gps_ptr->GPSLatitude[0].numerator = latitude_dd_numerator; p_exif_info->gps_ptr->GPSLatitude[0].denominator = latitude_dd_denominator; p_exif_info->gps_ptr->GPSLatitude[1].numerator = latitude_mm_numerator; p_exif_info->gps_ptr->GPSLatitude[1].denominator = latitude_mm_denominator; p_exif_info->gps_ptr->GPSLatitude[2].numerator = latitude_ss_numerator; p_exif_info->gps_ptr->GPSLatitude[2].denominator = latitude_ss_denominator; p_exif_info->gps_ptr->valid.GPSLongitude = 1; p_exif_info->gps_ptr->GPSLongitude[0].numerator = longitude_dd_numerator; p_exif_info->gps_ptr->GPSLongitude[0].denominator = longitude_dd_denominator; p_exif_info->gps_ptr->GPSLongitude[1].numerator = longitude_mm_numerator; p_exif_info->gps_ptr->GPSLongitude[1].denominator = longitude_mm_denominator; p_exif_info->gps_ptr->GPSLongitude[2].numerator = longitude_ss_numerator; p_exif_info->gps_ptr->GPSLongitude[2].denominator = longitude_ss_denominator; p_exif_info->gps_ptr->valid.GPSAltitude = 1; p_exif_info->gps_ptr->GPSAltitude.numerator = s_position.altitude; CMR_LOGD("gps_ptr->GPSAltitude.numerator: %d.", p_exif_info->gps_ptr->GPSAltitude.numerator); p_exif_info->gps_ptr->GPSAltitude.denominator = 1; p_exif_info->gps_ptr->valid.GPSAltitudeRef = 1; if(NULL != gps_process_method) { const char ascii[] = {0x41, 0x53, 0x43, 0x49, 0x49, 0, 0, 0}; p_exif_info->gps_ptr->valid.GPSProcessingMethod = 1; p_exif_info->gps_ptr->GPSProcessingMethod.count = strlen(gps_process_method)+sizeof(ascii) + 1; memcpy((char *)p_exif_info->gps_ptr->GPSProcessingMethod.ptr, ascii, sizeof(ascii)); strcpy((char *)p_exif_info->gps_ptr->GPSProcessingMethod.ptr+sizeof(ascii), (char *)gps_process_method); /*add "ASCII\0\0\0" for cts test by lyh*/ } p_exif_info->gps_ptr->valid.GPSTimeStamp = 1; p_exif_info->gps_ptr->GPSTimeStamp[0].numerator = gps_hour; p_exif_info->gps_ptr->GPSTimeStamp[1].numerator = gps_minuter; p_exif_info->gps_ptr->GPSTimeStamp[2].numerator = gps_second; p_exif_info->gps_ptr->GPSTimeStamp[0].denominator = 1; p_exif_info->gps_ptr->GPSTimeStamp[1].denominator = 1; p_exif_info->gps_ptr->GPSTimeStamp[2].denominator = 1; p_exif_info->gps_ptr->valid.GPSDateStamp = 1; strcpy((char *)p_exif_info->gps_ptr->GPSDateStamp, (char *)gps_date); CMR_LOGD("GPS: valid=%d \n", *(uint32_t*)&p_exif_info->gps_ptr->valid); } } if ((NULL != p_exif_info->spec_ptr) && (NULL != p_exif_info->spec_ptr->pic_taking_cond_ptr)) { p_exif_info->spec_ptr->pic_taking_cond_ptr->valid.FocalLength = 1; p_exif_info->spec_ptr->pic_taking_cond_ptr->FocalLength.numerator = focal_length_numerator; p_exif_info->spec_ptr->pic_taking_cond_ptr->FocalLength.denominator = focal_length_denominator; } /* TODO: data time is get from user space now */ if (NULL != p_exif_info->primary.img_desc_ptr) { CMR_LOGD("set DateTime."); strcpy((char *)p_exif_info->primary.img_desc_ptr->DateTime, (char *)datetime); } if (NULL != p_exif_info->spec_ptr) { if(NULL != p_exif_info->spec_ptr->other_ptr) { CMR_LOGD("set ImageUniqueID."); memset(p_exif_info->spec_ptr->other_ptr->ImageUniqueID, 0, sizeof(p_exif_info->spec_ptr->other_ptr->ImageUniqueID)); sprintf((char *)p_exif_info->spec_ptr->other_ptr->ImageUniqueID,"IMAGE %s", datetime); } if(NULL != p_exif_info->spec_ptr->date_time_ptr) { strcpy((char *)p_exif_info->spec_ptr->date_time_ptr->DateTimeOriginal, (char *)datetime); strcpy((char *)p_exif_info->spec_ptr->date_time_ptr->DateTimeDigitized, (char *)datetime); CMR_LOGD("set DateTimeOriginal."); } } memset(&s_position, 0, sizeof(camera_position_type)); return p_exif_info; }