/*
* Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* V1.0
*/
/*History
*Date Modification Reason
*
*/
#define LOG_TAG "9850ka_s5k5e3yx"
#include "sensor_s5k5e3yx_mipi_raw.h"
#define MIPI_RAW_INFO g_s5k5e3yx_mipi_raw_info
/*==============================================================================
* Description:
* write register value to sensor
* please modify this function acording your spec
*============================================================================*/
static void s5k5e3yx_drv_write_reg2sensor(cmr_handle handle, struct sensor_i2c_reg_tab *reg_info)
{
SENSOR_IC_CHECK_PTR_VOID(reg_info);
SENSOR_IC_CHECK_HANDLE_VOID(handle);
struct sensor_ic_drv_cxt * sns_drv_cxt = (struct sensor_ic_drv_cxt *)handle;
cmr_int i=0;
for(i=0;i<reg_info->size;i++){
hw_sensor_write_reg(sns_drv_cxt->hw_handle, reg_info->settings[i].reg_addr, reg_info->settings[i].reg_value);
}
}
/*==============================================================================
* Description:
* write gain to sensor registers buffer
* please modify this function acording your spec
*============================================================================*/
static void s5k5e3yx_drv_write_gain(cmr_handle handle, struct sensor_aec_i2c_tag *aec_info, cmr_u32 gain)
{
SENSOR_IC_CHECK_PTR_VOID(aec_info);
SENSOR_IC_CHECK_HANDLE_VOID(handle);
struct sensor_ic_drv_cxt * sns_drv_cxt = (struct sensor_ic_drv_cxt *)handle;
if (SENSOR_MAX_GAIN < gain)
gain = SENSOR_MAX_GAIN;
if(aec_info->again->size)
{
/*TODO*/
aec_info->again->settings[0].reg_value = (gain >> 8) & 0x3;
aec_info->again->settings[1].reg_value = gain & 0xff;
/*END*/
}
if(aec_info->dgain->size){
/*TODO*/
/*END*/
}
}
/*==============================================================================
* Description:
* write frame length to sensor registers buffer
* please modify this function acording your spec
*============================================================================*/
static void s5k5e3yx_drv_write_frame_length(cmr_handle handle, struct sensor_aec_i2c_tag *aec_info, cmr_u32 frame_len)
{
SENSOR_IC_CHECK_PTR_VOID(aec_info);
SENSOR_IC_CHECK_HANDLE_VOID(handle);
struct sensor_ic_drv_cxt * sns_drv_cxt = (struct sensor_ic_drv_cxt *)handle;
if(aec_info->frame_length->size){
/*TODO*/
aec_info->frame_length->settings[0].reg_value = (frame_len >> 8) & 0xff;
aec_info->frame_length->settings[1].reg_value = frame_len & 0xff;
/*END*/
}
}
/*==============================================================================
* Description:
* write shutter to sensor registers buffer
* please pay attention to the frame length
* please modify this function acording your spec
*============================================================================*/
static void s5k5e3yx_drv_write_shutter(cmr_handle handle, struct sensor_aec_i2c_tag *aec_info , cmr_u32 shutter)
{
SENSOR_IC_CHECK_PTR_VOID(aec_info);
SENSOR_IC_CHECK_HANDLE_VOID(handle);
struct sensor_ic_drv_cxt * sns_drv_cxt = (struct sensor_ic_drv_cxt *)handle;
cmr_u16 value = (shutter >> 1);
if(aec_info->shutter->size){
/*TODO*/
aec_info->shutter->settings[0].reg_value = (value >> 8) & 0xff;
aec_info->shutter->settings[1].reg_value = value & 0xff;
/*END*/
}
}
/*==============================================================================
* Description:
* write exposure to sensor registers and get current shutter
* please pay attention to the frame length
* please don't change this function if it's necessary
*============================================================================*/
static void s5k5e3yx_drv_calc_exposure(cmr_handle handle, cmr_u32 shutter, cmr_u32 dummy_line,
cmr_u16 mode, struct sensor_aec_i2c_tag *aec_info)
{
cmr_u32 dest_fr_len = 0;
cmr_u32 cur_fr_len = 0;
cmr_u32 fr_len = 0;
float fps = 0.0;
cmr_u16 frame_interval = 0x00;
SENSOR_IC_CHECK_PTR_VOID(aec_info);
SENSOR_IC_CHECK_HANDLE_VOID(handle);
struct sensor_ic_drv_cxt * sns_drv_cxt = (struct sensor_ic_drv_cxt *)handle;
sns_drv_cxt->frame_length_def = sns_drv_cxt->trim_tab_info[mode].frame_line;
sns_drv_cxt->line_time_def = sns_drv_cxt->trim_tab_info[mode].line_time;
cur_fr_len = sns_drv_cxt->sensor_ev_info.preview_framelength;
fr_len = sns_drv_cxt->frame_length_def;
dummy_line = dummy_line > FRAME_OFFSET ? dummy_line : FRAME_OFFSET;
dest_fr_len = ((shutter + dummy_line) > fr_len) ? (shutter +dummy_line) : fr_len;
sns_drv_cxt->frame_length = dest_fr_len;
if (shutter < SENSOR_MIN_SHUTTER)
shutter = SENSOR_MIN_SHUTTER;
if (cur_fr_len > shutter) {
fps = 1000000000.0 / (cur_fr_len * sns_drv_cxt->trim_tab_info[mode].line_time);
} else {
fps = 1000000000.0 / ((shutter + dummy_line) * sns_drv_cxt->trim_tab_info[mode].line_time);
}
SENSOR_LOGI("fps = %f", fps);
frame_interval = (cmr_u16)(((shutter + dummy_line) *
sns_drv_cxt->line_time_def) / 1000000);
SENSOR_LOGI("mode = %d, exposure_line = %d, dummy_line= %d, dest_fr_len= %d, cur_fr_len= %d, frame_interval= %d ms",
mode, shutter, dummy_line, dest_fr_len, cur_fr_len, frame_interval);
// if (dest_fr_len != cur_fr_len){
sns_drv_cxt->sensor_ev_info.preview_framelength = dest_fr_len;
s5k5e3yx_drv_write_frame_length(handle, aec_info, dest_fr_len);
// }
sns_drv_cxt->sensor_ev_info.preview_shutter = shutter;
s5k5e3yx_drv_write_shutter(handle, aec_info, shutter);
if(sns_drv_cxt->ops_cb.set_exif_info) {
sns_drv_cxt->ops_cb.set_exif_info(sns_drv_cxt->caller_handle,
SENSOR_EXIF_CTRL_EXPOSURETIME, shutter);
}
}
static void s5k5e3yx_drv_calc_gain(cmr_handle handle,cmr_uint isp_gain, struct sensor_aec_i2c_tag *aec_info)
{
SENSOR_IC_CHECK_HANDLE_VOID(handle);
struct sensor_ic_drv_cxt * sns_drv_cxt = (struct sensor_ic_drv_cxt *)handle;
cmr_u32 sensor_gain = 0;
sensor_gain = isp_gain < ISP_BASE_GAIN ? ISP_BASE_GAIN : isp_gain;
sensor_gain = sensor_gain * SENSOR_BASE_GAIN / ISP_BASE_GAIN;
if (SENSOR_MAX_GAIN < sensor_gain)
sensor_gain = SENSOR_MAX_GAIN;
SENSOR_LOGI("isp_gain = 0x%x,sensor_gain=0x%x", (unsigned int)isp_gain,sensor_gain);
sns_drv_cxt->sensor_ev_info.preview_gain = sensor_gain;
s5k5e3yx_drv_write_gain(handle, aec_info, sensor_gain);
}
/*==============================================================================
* Description:
* sensor power on
* please modify this function acording your spec
*============================================================================*/
static cmr_int s5k5e3yx_drv_power_on(cmr_handle handle, cmr_uint power_on)
{
SENSOR_IC_CHECK_HANDLE(handle);
struct sensor_ic_drv_cxt * sns_drv_cxt = (struct sensor_ic_drv_cxt *)handle;
struct module_cfg_info *module_info = sns_drv_cxt->module_info;
SENSOR_AVDD_VAL_E dvdd_val = module_info->dvdd_val;
SENSOR_AVDD_VAL_E avdd_val = module_info->avdd_val;
SENSOR_AVDD_VAL_E iovdd_val = module_info->iovdd_val;
BOOLEAN power_down = MIPI_RAW_INFO.power_down_level;
BOOLEAN reset_level = MIPI_RAW