diff --git a/imx678mipi_Sensor.c b/imx678mipi_Sensor.c new file mode 100644 index 0000000..fc6b9b8 --- /dev/null +++ b/imx678mipi_Sensor.c @@ -0,0 +1,1568 @@ +/***************************************************************************** + * + * Filename: + * --------- + * imx678mipi_Sensor.c + * + * Project: + * -------- + * ALPS + * + * Description: + * ------------ + * Source code of Sensor driver + * + * + *------------------------------------------------------------------------------ + * Upper this line, this part is controlled by CC/CQ. DO NOT MODIFY!! + *============================================================================ + ****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kd_camera_typedef.h" +#include "kd_imgsensor.h" +#include "kd_imgsensor_define.h" +#include "kd_imgsensor_errcode.h" + +#include "imx678mipi_Sensor.h" + +/****************************Modify Following Strings for Debug****************************/ +#define PFX "IMX678_camera_sensor" + +/**************************** Modify end *******************************************/ + +//#define LOG_INF(format, args...) pr_debug(PFX "[%s] " format, __FUNCTION__, ##args) +#define LOG_INF printk +static DEFINE_SPINLOCK(imgsensor_drv_lock); + + + +static struct imgsensor_info_struct imgsensor_info = { + .sensor_id = IMX678MIPI_SENSOR_ID,//sensor id is 0x00c0 + .checksum_value = 0xf7375923, //checksum value for Camera Auto Test + .pre = { + .pclk = 74250000, + .linelength = 1100, //8800, //record different mode's linelength + .framelength = 2250, //2300, //record different mode's framelength + .startx = 0, //record different mode's startx of grabwindow + .starty = 0, //record different mode's starty of grabwindow + .grabwindow_width = 3840, //record different mode's width of grabwindow + .grabwindow_height = 2160, //record different mode's height of grabwindow + .mipi_data_lp2hs_settle_dc = 85, + .max_framerate = 300, + }, + .cap = { + .pclk = 74250000, + .linelength = 1100, + .framelength = 2250, + .startx = 0, + .starty = 0, + .grabwindow_width = 3840, + .grabwindow_height = 2160, + .mipi_data_lp2hs_settle_dc = 85, + .max_framerate = 300, + }, + .cap1 = { + .pclk = 74250000, + .linelength = 1100, + .framelength = 2250, + .startx = 0, + .starty = 0, + .grabwindow_width = 3840, + .grabwindow_height = 2160, + .mipi_data_lp2hs_settle_dc = 85, + .max_framerate = 300, + }, + .normal_video = { + .pclk = 74250000, + .linelength = 1100, + .framelength = 2250, + .startx = 0, + .starty = 0, + .grabwindow_width = 3840, + .grabwindow_height = 2160, + .mipi_data_lp2hs_settle_dc = 85, + .max_framerate = 300, + }, + + .hs_video = { + .pclk = 74250000, + .linelength = 1100, + .framelength = 2250, + .startx = 0, + .starty = 0, + .grabwindow_width = 3840, + .grabwindow_height = 2160, + .mipi_data_lp2hs_settle_dc = 85, + .max_framerate = 300, + }, + + .slim_video = { + .pclk = 74250000, + .linelength = 1100, + .framelength = 2250, + .startx = 0, + .starty = 0, + .grabwindow_width = 3840, + .grabwindow_height = 2160, + .mipi_data_lp2hs_settle_dc = 85, + .max_framerate = 300, + }, + .margin = 3, + .min_shutter = 3, + .max_frame_length = 0xffff, + .ae_shut_delay_frame = 0, + .ae_sensor_gain_delay_frame = 0, + .ae_ispGain_delay_frame = 2, + .ihdr_support = 0, //1, support; 0,not support + .ihdr_le_firstline = 0, //1,le first ; 0, se first + .sensor_mode_num = 5, //support sensor mode num + + .cap_delay_frame = 3, + .pre_delay_frame = 3, + .video_delay_frame = 3, + .hs_video_delay_frame = 3, + .slim_video_delay_frame = 3, + + .isp_driving_current = ISP_DRIVING_4MA, + .sensor_interface_type = SENSOR_INTERFACE_TYPE_MIPI, + .mipi_sensor_type = MIPI_OPHY_NCSI2, //0,MIPI_OPHY_NCSI2; 1,MIPI_OPHY_CSI2 + .mipi_settle_delay_mode = MIPI_SETTLEDELAY_AUTO,//0,MIPI_SETTLEDELAY_AUTO; 1,MIPI_SETTLEDELAY_MANNUAL + .sensor_output_dataformat = SENSOR_OUTPUT_FORMAT_RAW_Gb, + .mclk = 24,//.mclk = 37, + .mipi_lane_num = SENSOR_MIPI_4_LANE, + .i2c_addr_table = {0x34, 0xff}, + .i2c_speed = 200, +}; + + +static struct imgsensor_struct imgsensor = { + .mirror = IMAGE_H_MIRROR, //mirrorflip information + .sensor_mode = IMGSENSOR_MODE_INIT, //IMGSENSOR_MODE enum value,record current sensor mode,such as: INIT, Preview, Capture, Video,High Speed Video, Slim Video + .shutter = 0x3D0, //current shutter + .gain = 0x100, //current gain + .dummy_pixel = 0, //current dummypixel + .dummy_line = 0, //current dummyline + .current_fps = 30, //full size current fps : 24fps for PIP, 30fps for Normal or ZSD + .autoflicker_en = KAL_FALSE, //auto flicker enable: KAL_FALSE for disable auto flicker, KAL_TRUE for enable auto flicker + .test_pattern = KAL_FALSE, //test pattern mode or not. KAL_FALSE for in test pattern mode, KAL_TRUE for normal output + .current_scenario_id = MSDK_SCENARIO_ID_CAMERA_PREVIEW,//current scenario id + .ihdr_en = 0, //sensor need support LE, SE with HDR feature + .i2c_write_id = 0x34, +}; + + +/* Sensor output window information */ + +static struct SENSOR_WINSIZE_INFO_STRUCT imgsensor_winsize_info[5] = +{{ 3840, 2160, 0, 0, 3840, 2160, 3840, 2160, 0, 0, 3840, 2160, 0, 0, 3840, 2160}, // Preview + { 3840, 2160, 0, 0, 3840, 2160, 3840, 2160, 0, 0, 3840, 2160, 0, 0, 3840, 2160}, // capture + { 3840, 2160, 0, 0, 3840, 2160, 3840, 2160, 0, 0, 3840, 2160, 0, 0, 3840, 2160}, // video + { 3840, 2160, 0, 0, 3840, 2160, 3840, 2160, 0, 0, 3840, 2160, 0, 0, 3840, 2160}, //hight speed video + { 3840, 2160, 0, 0, 3840, 2160, 3840, 2160, 0, 0, 3840, 2160, 0, 0, 3840, 2160}}; // slim video + + + #define MaxGainIndex (103) +kal_uint16 sensorGainMapping[MaxGainIndex][2] ={ + {64 ,0 }, + {66 ,1 }, + {68 ,2 }, + {70 ,3 }, + {73 ,4 }, + {76 ,5 }, + {78 ,6 }, + {81 ,7 }, + {84 ,8 }, + {87 ,9 }, + {90 ,10 }, + {93 ,11 }, + {96 ,12 }, + {100 ,13 }, + {103 ,14 }, + {107 ,15 }, + {111 ,16}, + {115 ,17}, + {119 ,18}, + {123 ,19}, + {127 ,20}, + {132 ,21}, + {136 ,22}, + {141 ,23}, + {146 ,24}, + {151 ,25}, + {157 ,26}, + {162 ,27}, + {168 ,28}, + {174,29}, + {180,30}, + {186,31}, + {193,32}, + {200,33}, + {207,34}, + {214,35}, + {221,36}, + {229,37}, + {237,38}, + {246,39}, + {254,40}, + {263,41}, + {273,42}, + {282,43}, + {292,44}, + {302,45}, + {313,46}, + {324,47}, + {335,48}, + {347,49}, + {359,50}, + {372,51}, + {385,52}, + {399,53}, + {413,54}, + {427,55}, + {442,56}, + {458,57}, + {474,58}, + {491,59}, + {508,60}, + {526,61}, + {544,62}, + {563,63}, + {583,64}, + {604,65}, + {625,66}, + {647,67}, + {670,68}, + {693,69}, + {718,70}, + {743,71}, + {769,72}, + {796,73}, + {824,74}, + {853,75}, + {883,76}, + {914,77}, + {946,78}, + {979,79}, + {1014,80}, + {1049,81}, + {1086,82}, + {1125,83}, + {1164,84}, + {1205,86}, + {1247,88}, + {1291, 90}, + {1337, 92}, + {1384, 94}, + {1432, 96}, + {1483, 99}, + {1535, 102}, + {1587, 105}, + {1639, 108}, + {1691, 111}, + {1743, 114}, + {1795, 117}, + {1847, 120}, + {1899, 125}, + {1951, 131}, + {2003, 139}, + {2055, 148}, +}; + + + + +extern int iReadReg(u16 a_u2Addr , u8 * a_puBuff , u16 i2cId); +extern int iWriteReg(u16 a_u2Addr , u32 a_u4Data , u32 a_u4Bytes , u16 i2cId); +static kal_uint16 read_cmos_sensor(kal_uint32 addr) +{ + kal_uint16 get_byte=0; + char pu_send_cmd[2] = {(char)(addr >> 8), (char)(addr & 0xFF) }; + + + iReadRegI2C(pu_send_cmd, 2, (u8*)&get_byte, 1, imgsensor.i2c_write_id); + + return get_byte; +} + +//#define write_cmos_sensor(addr, para) iWriteReg((u16) addr , (u32) para , 1, imgsensor.i2c_write_id) +static void write_cmos_sensor(kal_uint32 addr, kal_uint32 para) +{ + char pu_send_cmd[3] = {(char)(addr >> 8), (char)(addr & 0xFF), (char)(para & 0xFF)}; + + iWriteRegI2C(pu_send_cmd, 3, imgsensor.i2c_write_id); +} + + +#if 1 +static void set_dummy(void) +{ + LOG_INF("dummyline = %d, dummypixels = %d ", imgsensor.dummy_line, imgsensor.dummy_pixel); + write_cmos_sensor(0x3001, 0x01); + write_cmos_sensor(0x3028, (imgsensor.frame_length&0x0000ff)); + write_cmos_sensor(0x3029, (imgsensor.frame_length&0x00ff00)>>8); + write_cmos_sensor(0x302a, (imgsensor.frame_length&0x0f0000)>>16); + write_cmos_sensor(0x3001, 0x00); +} +#endif + + +static kal_uint32 return_sensor_id(void) +{ printk("imx678 return_sensor_id=%x\n",(read_cmos_sensor(0x30DC) << 8) | read_cmos_sensor(0x30DD)); + return ((read_cmos_sensor(0x30DC) << 8) | read_cmos_sensor(0x30DD)); + //sensor id is 0x00c0 +} + + + +static void set_max_framerate(UINT16 framerate,kal_bool min_framelength_en) +{ + kal_uint32 frame_length = imgsensor.frame_length; + + LOG_INF("framerate = %d, min framelength should enable = %d\n", framerate,min_framelength_en); + + frame_length = imgsensor.pclk / framerate * 10 / imgsensor.line_length; + spin_lock(&imgsensor_drv_lock); + imgsensor.frame_length = (frame_length > imgsensor.min_frame_length) ? frame_length : imgsensor.min_frame_length; + imgsensor.dummy_line = imgsensor.frame_length - imgsensor.min_frame_length; + + if (imgsensor.frame_length > imgsensor_info.max_frame_length) + { + imgsensor.frame_length = imgsensor_info.max_frame_length; + imgsensor.dummy_line = imgsensor.frame_length - imgsensor.min_frame_length; + } + + if (min_framelength_en) + imgsensor.min_frame_length = imgsensor.frame_length; + spin_unlock(&imgsensor_drv_lock); + set_dummy(); +} /* set_max_framerate */ + + +static void write_shutter(kal_uint16 shutter) +{ + kal_uint16 realtime_fps = 0; + // kal_uint32 frame_length = 0; + + + // if shutter bigger than frame_length, should extend frame length first + spin_lock(&imgsensor_drv_lock); + if (shutter > imgsensor.min_frame_length - imgsensor_info.margin) + imgsensor.frame_length = shutter + imgsensor_info.margin; + else + imgsensor.frame_length = imgsensor.min_frame_length; + if (imgsensor.frame_length > imgsensor_info.max_frame_length) + imgsensor.frame_length = imgsensor_info.max_frame_length; + spin_unlock(&imgsensor_drv_lock); + shutter = (shutter < imgsensor_info.min_shutter) ? imgsensor_info.min_shutter : shutter; + shutter = (shutter > (imgsensor_info.max_frame_length - imgsensor_info.margin)) ? (imgsensor_info.max_frame_length - imgsensor_info.margin) : shutter; + + + printk("csh for at last write_shutter=%d\n",shutter); + + + // shutter =1012*3; + + if (imgsensor.autoflicker_en) { + realtime_fps = imgsensor.pclk / imgsensor.line_length * 10 / imgsensor.frame_length; + if(realtime_fps >= 297 && realtime_fps <= 305) + set_max_framerate(296,0); + else if(realtime_fps >= 147 && realtime_fps <= 150) + set_max_framerate(146,0); + else { + // Extend frame length + write_cmos_sensor(0x3001, 0x01); + write_cmos_sensor(0x3028, (imgsensor.frame_length&0x0000ff)); + write_cmos_sensor(0x3029, (imgsensor.frame_length&0x00ff00)>>8); + write_cmos_sensor(0x302a, (imgsensor.frame_length&0x0f0000)>>16); + write_cmos_sensor(0x3001, 0x00); + } + } else { + // Extend frame length + write_cmos_sensor(0x3001, 0x01); + write_cmos_sensor(0x3028, (imgsensor.frame_length&0x0000ff)); + write_cmos_sensor(0x3029, (imgsensor.frame_length&0x00ff00)>>8); + write_cmos_sensor(0x302a, (imgsensor.frame_length&0x0f0000)>>16); + write_cmos_sensor(0x3001, 0x00); + } + shutter = imgsensor.frame_length - shutter; + // Update Shutter + write_cmos_sensor(0x3001, 0x01); + write_cmos_sensor(0x3050, shutter & 0xFF); + write_cmos_sensor(0x3051, shutter >> 8); + write_cmos_sensor(0x3052, shutter >> 16); + write_cmos_sensor(0x3001, 0x00); + + + //LOG_INF("frame_length = %d ", frame_length); + + } + + + +static void set_shutter(kal_uint16 shutter) +{ + unsigned long flags; + spin_lock_irqsave(&imgsensor_drv_lock, flags); + imgsensor.shutter = shutter; + spin_unlock_irqrestore(&imgsensor_drv_lock, flags); + + write_shutter(shutter); + LOG_INF("Currently camera mode is %d,framerate is %d , framelength=%d,linelength=%d,shutter=%d\n",imgsensor.sensor_mode,imgsensor.current_fps,imgsensor.frame_length,imgsensor.line_length,shutter); +} + + + +static kal_uint16 gain2reg(const kal_uint16 gain) +{ + kal_uint8 iI; + + for (iI = 0; iI < MaxGainIndex; iI++) + { + if(gain < sensorGainMapping[iI][0]) + { + return sensorGainMapping[iI][1]; + } + + + } + if(iI != MaxGainIndex) + { + if(gain != sensorGainMapping[iI][0]) + { + LOG_INF("Gain mapping don't correctly:%d %d \n", gain, sensorGainMapping[iI][0]); + } + } + LOG_INF("Gain2Reg function\n"); + return sensorGainMapping[iI][1]; +} + + +static kal_uint16 set_gain(kal_uint16 gain) +{ + /******************************************************************* + *gain register: 0x3070 + ******************************************************************/ + + kal_uint16 reg_gain=0; + + if (gain < BASEGAIN || gain > 144 * BASEGAIN) { + LOG_INF("Error gain setting"); + + if (gain < BASEGAIN) + gain = BASEGAIN; + else if (gain > 144 * BASEGAIN) + gain = 144 * BASEGAIN; + } + + reg_gain = gain2reg(gain); + spin_lock(&imgsensor_drv_lock); + imgsensor.gain = reg_gain; + spin_unlock(&imgsensor_drv_lock); + LOG_INF("gain = %d , reg_gain = 0x%x\n ", gain, reg_gain); + + write_cmos_sensor(0x3001, 0x01); + write_cmos_sensor(0x3070, reg_gain); + write_cmos_sensor(0x3071, (reg_gain&0x03)>>8); + write_cmos_sensor(0x3001, 0x00); + return gain; +} /* set_gain */ + + + +static void set_mirror_flip(kal_uint8 image_mirror) +{ + + LOG_INF("image_mirror = %d", image_mirror); + + //spin_lock(&imgsensor_drv_lock); + // imgsensor.mirror= image_mirror; + //spin_unlock(&imgsensor_drv_lock); + switch (image_mirror) { + + case IMAGE_NORMAL: + write_cmos_sensor(0x3020,0x00); + write_cmos_sensor(0x3021,0x00); + break; + case IMAGE_H_MIRROR: + write_cmos_sensor(0x3020,0x01); + write_cmos_sensor(0x3021,0x00); + break; + case IMAGE_V_MIRROR: + write_cmos_sensor(0x3020,0x00); + write_cmos_sensor(0x3021,0x01); + break; + case IMAGE_HV_MIRROR: + write_cmos_sensor(0x3020,0x01); + write_cmos_sensor(0x3021,0x01); + break; + default: + LOG_INF("Error image_mirror setting\n"); + } + +} + + + +static void sensor_init(void) +{ + write_cmos_sensor(0x3000, 0x01); + write_cmos_sensor(0x3002, 0x01); + write_cmos_sensor(0x3014, 0x01); //0x01:37.125M,0x04:24M + write_cmos_sensor(0x3015, 0x05); //891Mbps + write_cmos_sensor(0x3020, 0x00); + write_cmos_sensor(0x3021, 0x00); + write_cmos_sensor(0x3022, 0x00); + write_cmos_sensor(0x3023, 0x00); //00: raw10 + write_cmos_sensor(0x3050, 0x03); + write_cmos_sensor(0x30A6, 0x00); + write_cmos_sensor(0x3460, 0x22); + write_cmos_sensor(0x355A, 0x64); + write_cmos_sensor(0x3A02, 0x7A); + write_cmos_sensor(0x3A10, 0xEC); + write_cmos_sensor(0x3A12, 0x71); + write_cmos_sensor(0x3A14, 0xDE); + write_cmos_sensor(0x3A20, 0x2B); + write_cmos_sensor(0x3A24, 0x22); + write_cmos_sensor(0x3A25, 0x25); + write_cmos_sensor(0x3A26, 0x2A); + write_cmos_sensor(0x3A27, 0x2C); + write_cmos_sensor(0x3A28, 0x39); + write_cmos_sensor(0x3A29, 0x38); + write_cmos_sensor(0x3A30, 0x04); + write_cmos_sensor(0x3A31, 0x04); + write_cmos_sensor(0x3A32, 0x03); + write_cmos_sensor(0x3A33, 0x03); + write_cmos_sensor(0x3A34, 0x09); + write_cmos_sensor(0x3A35, 0x06); + write_cmos_sensor(0x3A38, 0xCD); + write_cmos_sensor(0x3A3A, 0x4C); + write_cmos_sensor(0x3A3C, 0xB9); + write_cmos_sensor(0x3A3E, 0x30); + write_cmos_sensor(0x3A40, 0x2C); + write_cmos_sensor(0x3A42, 0x39); + write_cmos_sensor(0x3A4E, 0x00); + write_cmos_sensor(0x3A52, 0x00); + write_cmos_sensor(0x3A56, 0x00); + write_cmos_sensor(0x3A5A, 0x00); + write_cmos_sensor(0x3A5E, 0x00); + write_cmos_sensor(0x3A62, 0x00); + write_cmos_sensor(0x3A6E, 0xA0); + write_cmos_sensor(0x3A70, 0x50); + write_cmos_sensor(0x3A8C, 0x04); + write_cmos_sensor(0x3A8D, 0x03); + write_cmos_sensor(0x3A8E, 0x09); + write_cmos_sensor(0x3A90, 0x38); + write_cmos_sensor(0x3A91, 0x42); + write_cmos_sensor(0x3A92, 0x3C); + write_cmos_sensor(0x3B0E, 0xF3); + write_cmos_sensor(0x3B12, 0xE5); + write_cmos_sensor(0x3B27, 0xC0); + write_cmos_sensor(0x3B2E, 0xEF); + write_cmos_sensor(0x3B30, 0x6A); + write_cmos_sensor(0x3B32, 0xF6); + write_cmos_sensor(0x3B36, 0xE1); + write_cmos_sensor(0x3B3A, 0xE8); + write_cmos_sensor(0x3B5A, 0x17); + write_cmos_sensor(0x3B5E, 0xEF); + write_cmos_sensor(0x3B60, 0x6A); + write_cmos_sensor(0x3B62, 0xF6); + write_cmos_sensor(0x3B66, 0xE1); + write_cmos_sensor(0x3B6A, 0xE8); + write_cmos_sensor(0x3B88, 0xEC); + write_cmos_sensor(0x3B8A, 0xED); + write_cmos_sensor(0x3B94, 0x71); + write_cmos_sensor(0x3B96, 0x72); + write_cmos_sensor(0x3B98, 0xDE); + write_cmos_sensor(0x3B9A, 0xDF); + write_cmos_sensor(0x3C0F, 0x06); + write_cmos_sensor(0x3C10, 0x06); + write_cmos_sensor(0x3C11, 0x06); + write_cmos_sensor(0x3C12, 0x06); + write_cmos_sensor(0x3C13, 0x06); + write_cmos_sensor(0x3C18, 0x20); + write_cmos_sensor(0x3C3A, 0x7A); + write_cmos_sensor(0x3C40, 0xF4); + write_cmos_sensor(0x3C48, 0xE6); + write_cmos_sensor(0x3C54, 0xCE); + write_cmos_sensor(0x3C56, 0xD0); + write_cmos_sensor(0x3C6C, 0x53); + write_cmos_sensor(0x3C6E, 0x55); + write_cmos_sensor(0x3C70, 0xC0); + write_cmos_sensor(0x3C72, 0xC2); + write_cmos_sensor(0x3C7E, 0xCE); + write_cmos_sensor(0x3C8C, 0xCF); + write_cmos_sensor(0x3C8E, 0xEB); + write_cmos_sensor(0x3C98, 0x54); + write_cmos_sensor(0x3C9A, 0x70); + write_cmos_sensor(0x3C9C, 0xC1); + write_cmos_sensor(0x3C9E, 0xDD); + write_cmos_sensor(0x3CB0, 0x7A); + write_cmos_sensor(0x3CB2, 0xBA); + write_cmos_sensor(0x3CC8, 0xBC); + write_cmos_sensor(0x3CCA, 0x7C); + write_cmos_sensor(0x3CD4, 0xEA); + write_cmos_sensor(0x3CD5, 0x01); + write_cmos_sensor(0x3CD6, 0x4A); + write_cmos_sensor(0x3CD8, 0x00); + write_cmos_sensor(0x3CD9, 0x00); + write_cmos_sensor(0x3CDA, 0xFF); + write_cmos_sensor(0x3CDB, 0x03); + write_cmos_sensor(0x3CDC, 0x00); + write_cmos_sensor(0x3CDD, 0x00); + write_cmos_sensor(0x3CDE, 0xFF); + write_cmos_sensor(0x3CDF, 0x03); + write_cmos_sensor(0x3CE4, 0x4C); + write_cmos_sensor(0x3CE6, 0xEC); + write_cmos_sensor(0x3CE7, 0x01); + write_cmos_sensor(0x3CE8, 0xFF); + write_cmos_sensor(0x3CE9, 0x03); + write_cmos_sensor(0x3CEA, 0x00); + write_cmos_sensor(0x3CEB, 0x00); + write_cmos_sensor(0x3CEC, 0xFF); + write_cmos_sensor(0x3CED, 0x03); + write_cmos_sensor(0x3CEE, 0x00); + write_cmos_sensor(0x3CEF, 0x00); + write_cmos_sensor(0x3E28, 0x82); + write_cmos_sensor(0x3E2A, 0x80); + write_cmos_sensor(0x3E30, 0x85); + write_cmos_sensor(0x3E32, 0x7D); + write_cmos_sensor(0x3E5C, 0xCE); + write_cmos_sensor(0x3E5E, 0xD3); + write_cmos_sensor(0x3E70, 0x53); + write_cmos_sensor(0x3E72, 0x58); + write_cmos_sensor(0x3E74, 0xC0); + write_cmos_sensor(0x3E76, 0xC5); + write_cmos_sensor(0x3E78, 0xC0); + write_cmos_sensor(0x3E79, 0x01); + write_cmos_sensor(0x3E7A, 0xD4); + write_cmos_sensor(0x3E7B, 0x01); + write_cmos_sensor(0x3EB4, 0x0B); + write_cmos_sensor(0x3EB5, 0x02); + write_cmos_sensor(0x3EB6, 0x4D); + write_cmos_sensor(0x3EEC, 0xF3); + write_cmos_sensor(0x3EEE, 0xE7); + write_cmos_sensor(0x3F01, 0x01); + write_cmos_sensor(0x3F24, 0x10); + write_cmos_sensor(0x3F28, 0x2D); + write_cmos_sensor(0x3F2A, 0x2D); + write_cmos_sensor(0x3F2C, 0x2D); + write_cmos_sensor(0x3F2E, 0x2D); + write_cmos_sensor(0x3F30, 0x23); + write_cmos_sensor(0x3F38, 0x2D); + write_cmos_sensor(0x3F3A, 0x2D); + write_cmos_sensor(0x3F3C, 0x2D); + write_cmos_sensor(0x3F3E, 0x28); + write_cmos_sensor(0x3F40, 0x1E); + write_cmos_sensor(0x3F48, 0x2D); + write_cmos_sensor(0x3F4A, 0x2D); + write_cmos_sensor(0x4004, 0xE4); + write_cmos_sensor(0x4006, 0xFF); + write_cmos_sensor(0x4018, 0x69); + write_cmos_sensor(0x401A, 0x84); + write_cmos_sensor(0x401C, 0xD6); + write_cmos_sensor(0x401E, 0xF1); + write_cmos_sensor(0x4038, 0xDE); + write_cmos_sensor(0x403A, 0x00); + write_cmos_sensor(0x403B, 0x01); + write_cmos_sensor(0x404C, 0x63); + write_cmos_sensor(0x404E, 0x85); + write_cmos_sensor(0x4050, 0xD0); + write_cmos_sensor(0x4052, 0xF2); + write_cmos_sensor(0x4108, 0xDD); + write_cmos_sensor(0x410A, 0xF7); + write_cmos_sensor(0x411C, 0x62); + write_cmos_sensor(0x411E, 0x7C); + write_cmos_sensor(0x4120, 0xCF); + write_cmos_sensor(0x4122, 0xE9); + write_cmos_sensor(0x4138, 0xE6); + write_cmos_sensor(0x413A, 0xF1); + write_cmos_sensor(0x414C, 0x6B); + write_cmos_sensor(0x414E, 0x76); + write_cmos_sensor(0x4150, 0xD8); + write_cmos_sensor(0x4152, 0xE3); + write_cmos_sensor(0x417E, 0x03); + write_cmos_sensor(0x417F, 0x01); + write_cmos_sensor(0x4186, 0xE0); + write_cmos_sensor(0x4190, 0xF3); + write_cmos_sensor(0x4192, 0xF7); + write_cmos_sensor(0x419C, 0x78); + write_cmos_sensor(0x419E, 0x7C); + write_cmos_sensor(0x41A0, 0xE5); + write_cmos_sensor(0x41A2, 0xE9); + write_cmos_sensor(0x41C8, 0xE2); + write_cmos_sensor(0x41CA, 0xFD); + write_cmos_sensor(0x41DC, 0x67); + write_cmos_sensor(0x41DE, 0x82); + write_cmos_sensor(0x41E0, 0xD4); + write_cmos_sensor(0x41E2, 0xEF); + write_cmos_sensor(0x4200, 0xDE); + write_cmos_sensor(0x4202, 0xDA); + write_cmos_sensor(0x4218, 0x63); + write_cmos_sensor(0x421A, 0x5F); + write_cmos_sensor(0x421C, 0xD0); + write_cmos_sensor(0x421E, 0xCC); + write_cmos_sensor(0x425A, 0x82); + write_cmos_sensor(0x425C, 0xEF); + write_cmos_sensor(0x4348, 0xFE); + write_cmos_sensor(0x4349, 0x06); + write_cmos_sensor(0x4352, 0xCE); + write_cmos_sensor(0x4420, 0x0B); + write_cmos_sensor(0x4421, 0x02); + write_cmos_sensor(0x4422, 0x4D); + write_cmos_sensor(0x4426, 0xF5); + write_cmos_sensor(0x442A, 0xE7); + write_cmos_sensor(0x4432, 0xF5); + write_cmos_sensor(0x4436, 0xE7); + write_cmos_sensor(0x4466, 0xB4); + write_cmos_sensor(0x446E, 0x32); + write_cmos_sensor(0x449F, 0x1C); + write_cmos_sensor(0x44A4, 0x2C); + write_cmos_sensor(0x44A6, 0x2C); + write_cmos_sensor(0x44A8, 0x2C); + write_cmos_sensor(0x44AA, 0x2C); + write_cmos_sensor(0x44B4, 0x2C); + write_cmos_sensor(0x44B6, 0x2C); + write_cmos_sensor(0x44B8, 0x2C); + write_cmos_sensor(0x44BA, 0x2C); + write_cmos_sensor(0x44C4, 0x2C); + write_cmos_sensor(0x44C6, 0x2C); + write_cmos_sensor(0x44C8, 0x2C); + write_cmos_sensor(0x4506, 0xF3); + write_cmos_sensor(0x450E, 0xE5); + write_cmos_sensor(0x4516, 0xF3); + write_cmos_sensor(0x4522, 0xE5); + write_cmos_sensor(0x4524, 0xF3); + write_cmos_sensor(0x452C, 0xE5); + write_cmos_sensor(0x453C, 0x22); + write_cmos_sensor(0x453D, 0x1B); + write_cmos_sensor(0x453E, 0x1B); + write_cmos_sensor(0x453F, 0x15); + write_cmos_sensor(0x4540, 0x15); + write_cmos_sensor(0x4541, 0x15); + write_cmos_sensor(0x4542, 0x15); + write_cmos_sensor(0x4543, 0x15); + write_cmos_sensor(0x4544, 0x15); + write_cmos_sensor(0x4548, 0x00); + write_cmos_sensor(0x4549, 0x01); + write_cmos_sensor(0x454A, 0x01); + write_cmos_sensor(0x454B, 0x06); + write_cmos_sensor(0x454C, 0x06); + write_cmos_sensor(0x454D, 0x06); + write_cmos_sensor(0x454E, 0x06); + write_cmos_sensor(0x454F, 0x06); + write_cmos_sensor(0x4550, 0x06); + write_cmos_sensor(0x4554, 0x55); + write_cmos_sensor(0x4555, 0x02); + write_cmos_sensor(0x4556, 0x42); + write_cmos_sensor(0x4557, 0x05); + write_cmos_sensor(0x4558, 0xFD); + write_cmos_sensor(0x4559, 0x05); + write_cmos_sensor(0x455A, 0x94); + write_cmos_sensor(0x455B, 0x06); + write_cmos_sensor(0x455D, 0x06); + write_cmos_sensor(0x455E, 0x49); + write_cmos_sensor(0x455F, 0x07); + write_cmos_sensor(0x4560, 0x7F); + write_cmos_sensor(0x4561, 0x07); + write_cmos_sensor(0x4562, 0xA5); + write_cmos_sensor(0x4564, 0x55); + write_cmos_sensor(0x4565, 0x02); + write_cmos_sensor(0x4566, 0x42); + write_cmos_sensor(0x4567, 0x05); + write_cmos_sensor(0x4568, 0xFD); + write_cmos_sensor(0x4569, 0x05); + write_cmos_sensor(0x456A, 0x94); + write_cmos_sensor(0x456B, 0x06); + write_cmos_sensor(0x456D, 0x06); + write_cmos_sensor(0x456E, 0x49); + write_cmos_sensor(0x456F, 0x07); + write_cmos_sensor(0x4572, 0xA5); + write_cmos_sensor(0x460C, 0x7D); + write_cmos_sensor(0x460E, 0xB1); + write_cmos_sensor(0x4614, 0xA8); + write_cmos_sensor(0x4616, 0xB2); + write_cmos_sensor(0x461C, 0x7E); + write_cmos_sensor(0x461E, 0xA7); + write_cmos_sensor(0x4624, 0xA8); + write_cmos_sensor(0x4626, 0xB2); + write_cmos_sensor(0x462C, 0x7E); + write_cmos_sensor(0x462E, 0x8A); + write_cmos_sensor(0x4630, 0x94); + write_cmos_sensor(0x4632, 0xA7); + write_cmos_sensor(0x4634, 0xFB); + write_cmos_sensor(0x4636, 0x2F); + write_cmos_sensor(0x4638, 0x81); + write_cmos_sensor(0x4639, 0x01); + write_cmos_sensor(0x463A, 0xB5); + write_cmos_sensor(0x463B, 0x01); + write_cmos_sensor(0x463C, 0x26); + write_cmos_sensor(0x463E, 0x30); + write_cmos_sensor(0x4640, 0xAC); + write_cmos_sensor(0x4641, 0x01); + write_cmos_sensor(0x4642, 0xB6); + write_cmos_sensor(0x4643, 0x01); + write_cmos_sensor(0x4644, 0xFC); + write_cmos_sensor(0x4646, 0x25); + write_cmos_sensor(0x4648, 0x82); + write_cmos_sensor(0x4649, 0x01); + write_cmos_sensor(0x464A, 0xAB); + write_cmos_sensor(0x464B, 0x01); + write_cmos_sensor(0x464C, 0x26); + write_cmos_sensor(0x464E, 0x30); + write_cmos_sensor(0x4654, 0xFC); + write_cmos_sensor(0x4656, 0x08); + write_cmos_sensor(0x4658, 0x12); + write_cmos_sensor(0x465A, 0x25); + write_cmos_sensor(0x4662, 0xFC); + write_cmos_sensor(0x46A2, 0xFB); + write_cmos_sensor(0x46D6, 0xF3); + write_cmos_sensor(0x46E6, 0x00); + write_cmos_sensor(0x46E8, 0xFF); + write_cmos_sensor(0x46E9, 0x03); + write_cmos_sensor(0x46EC, 0x7A); + write_cmos_sensor(0x46EE, 0xE5); + write_cmos_sensor(0x46F4, 0xEE); + write_cmos_sensor(0x46F6, 0xF2); + write_cmos_sensor(0x470C, 0xFF); + write_cmos_sensor(0x470D, 0x03); + write_cmos_sensor(0x470E, 0x00); + write_cmos_sensor(0x4714, 0xE0); + write_cmos_sensor(0x4716, 0xE4); + write_cmos_sensor(0x471E, 0xED); + write_cmos_sensor(0x472E, 0x00); + write_cmos_sensor(0x4730, 0xFF); + write_cmos_sensor(0x4731, 0x03); + write_cmos_sensor(0x4734, 0x7B); + write_cmos_sensor(0x4736, 0xDF); + write_cmos_sensor(0x4754, 0x7D); + write_cmos_sensor(0x4756, 0x8B); + write_cmos_sensor(0x4758, 0x93); + write_cmos_sensor(0x475A, 0xB1); + write_cmos_sensor(0x475C, 0xFB); + write_cmos_sensor(0x475E, 0x09); + write_cmos_sensor(0x4760, 0x11); + write_cmos_sensor(0x4762, 0x2F); + write_cmos_sensor(0x4766, 0xCC); + write_cmos_sensor(0x4776, 0xCB); + write_cmos_sensor(0x477E, 0x4A); + write_cmos_sensor(0x478E, 0x49); + write_cmos_sensor(0x4794, 0x7C); + write_cmos_sensor(0x4796, 0x8F); + write_cmos_sensor(0x4798, 0xB3); + write_cmos_sensor(0x4799, 0x00); + write_cmos_sensor(0x479A, 0xCC); + write_cmos_sensor(0x479C, 0xC1); + write_cmos_sensor(0x479E, 0xCB); + write_cmos_sensor(0x47A4, 0x7D); + write_cmos_sensor(0x47A6, 0x8E); + write_cmos_sensor(0x47A8, 0xB4); + write_cmos_sensor(0x47A9, 0x00); + write_cmos_sensor(0x47AA, 0xC0); + write_cmos_sensor(0x47AC, 0xFA); + write_cmos_sensor(0x47AE, 0x0D); + write_cmos_sensor(0x47B0, 0x31); + write_cmos_sensor(0x47B1, 0x01); + write_cmos_sensor(0x47B2, 0x4A); + write_cmos_sensor(0x47B3, 0x01); + write_cmos_sensor(0x47B4, 0x3F); + write_cmos_sensor(0x47B6, 0x49); + write_cmos_sensor(0x47BC, 0xFB); + write_cmos_sensor(0x47BE, 0x0C); + write_cmos_sensor(0x47C0, 0x32); + write_cmos_sensor(0x47C1, 0x01); + write_cmos_sensor(0x47C2, 0x3E); + write_cmos_sensor(0x47C3, 0x01); + write_cmos_sensor(0x3000, 0x00); + write_cmos_sensor(0x3002, 0x00); +} /* sensor_init */ + + +extern int cur_senindex; + +static kal_uint32 get_imgsensor_id(UINT32 *sensor_id) +{ + kal_uint8 i = 0, retry = 2; + + if(cur_senindex != 1) + { + *sensor_id = 0xFFFFFFFF; + return ERROR_SENSOR_CONNECT_FAIL; + } + + while (imgsensor_info.i2c_addr_table[i] != 0xff) + { + spin_lock(&imgsensor_drv_lock); + imgsensor.i2c_write_id = imgsensor_info.i2c_addr_table[i]; + spin_unlock(&imgsensor_drv_lock); + + do { + + *sensor_id = return_sensor_id(); //0x0444 is IMX678 Sensor ID + printk("--tjj: imx678 get_imgsensor_id sensor id: 0x%x \n",*sensor_id); + if (*sensor_id == imgsensor_info.sensor_id) { + LOG_INF("i2c write id: 0x%x, sensor id: 0x%x\n", imgsensor.i2c_write_id,*sensor_id); + return ERROR_NONE; + } + LOG_INF("Read sensor id fail,i2c write id: 0x%x, id: 0x%x\n", imgsensor.i2c_write_id,*sensor_id); + retry--; + } while(retry > 0); + + i++; + retry = 2; + } + + if (*sensor_id != imgsensor_info.sensor_id) + { + *sensor_id = 0xFFFFFFFF; + return ERROR_SENSOR_CONNECT_FAIL; + } + return ERROR_NONE; +} + + + +static kal_uint32 open(void) +{ + kal_uint8 i = 0; + kal_uint8 retry = 2; + kal_uint16 sensor_id = 0; + + + while (imgsensor_info.i2c_addr_table[i] != 0xff) { + spin_lock(&imgsensor_drv_lock); + imgsensor.i2c_write_id = imgsensor_info.i2c_addr_table[i]; + spin_unlock(&imgsensor_drv_lock); + do { + sensor_id = return_sensor_id(); + if (sensor_id == imgsensor_info.sensor_id) { + printk("i2c write id: 0x%x, sensor id: 0x%x\n", imgsensor.i2c_write_id,sensor_id); + break; + } + printk("Read sensor id fail,i2c write id: 0x%x, id: 0x%x\n", imgsensor.i2c_write_id,sensor_id); + msleep(200); + retry--; + } while(retry > 0); + i++; + if (sensor_id == imgsensor_info.sensor_id) + break; + retry = 2; + } + printk("csh for imx678 open camera 2222 \n"); + + + if (imgsensor_info.sensor_id != sensor_id) + return ERROR_SENSOR_CONNECT_FAIL; + + + printk("csh for imx678 open camera ok\n"); + spin_lock(&imgsensor_drv_lock); + + imgsensor.autoflicker_en= KAL_FALSE; + imgsensor.sensor_mode = IMGSENSOR_MODE_INIT; + imgsensor.pclk = imgsensor_info.pre.pclk; + imgsensor.frame_length = imgsensor_info.pre.framelength; + imgsensor.line_length = imgsensor_info.pre.linelength; + imgsensor.min_frame_length = imgsensor_info.pre.framelength; + imgsensor.dummy_pixel = 0; + imgsensor.dummy_line = 0; + imgsensor.ihdr_en = 0; + imgsensor.test_pattern = KAL_FALSE; + imgsensor.current_fps = imgsensor_info.pre.max_framerate; + spin_unlock(&imgsensor_drv_lock); + + return ERROR_NONE; +} /* open */ + + + +static kal_uint32 close(void) +{ + LOG_INF("E\n"); + + return ERROR_NONE; +} /* close */ + + + +static kal_uint32 preview(MSDK_SENSOR_EXPOSURE_WINDOW_STRUCT *image_window, + MSDK_SENSOR_CONFIG_STRUCT *sensor_config_data) +{ + printk("csh002 preview E\n"); + + spin_lock(&imgsensor_drv_lock); + imgsensor.sensor_mode = IMGSENSOR_MODE_PREVIEW; + imgsensor.pclk = imgsensor_info.pre.pclk; + imgsensor.line_length = imgsensor_info.pre.linelength; + imgsensor.frame_length = imgsensor_info.pre.framelength; + imgsensor.min_frame_length = imgsensor_info.pre.framelength; + imgsensor.autoflicker_en = KAL_FALSE; + spin_unlock(&imgsensor_drv_lock); + //set_dummy(); + sensor_init(); + + set_mirror_flip(imgsensor.mirror); + printk("Currently camera mode is %d, framelength=%d,linelength=%d\n",imgsensor.sensor_mode,imgsensor.frame_length,imgsensor.line_length); + return ERROR_NONE; +} /* preview */ + + + +static kal_uint32 capture(MSDK_SENSOR_EXPOSURE_WINDOW_STRUCT *image_window, + MSDK_SENSOR_CONFIG_STRUCT *sensor_config_data) +{ + printk("csh002 capture E"); + spin_lock(&imgsensor_drv_lock); + imgsensor.sensor_mode = IMGSENSOR_MODE_CAPTURE; + + if (imgsensor.current_fps == imgsensor_info.cap.max_framerate) // 30fps + { + imgsensor.pclk = imgsensor_info.cap.pclk; + imgsensor.line_length = imgsensor_info.cap.linelength; + imgsensor.frame_length = imgsensor_info.cap.framelength; + imgsensor.min_frame_length = imgsensor_info.cap.framelength; + imgsensor.autoflicker_en = KAL_FALSE; + } + else //PIP capture: 24fps for less than 13M, 20fps for 16M,15fps for 20M + { + if (imgsensor.current_fps != imgsensor_info.cap1.max_framerate) + //LOG_INF("Warning: current_fps %d fps is not support, so use cap1's setting: %d fps!\n",imgsensor_info.cap1.max_framerate/10); + imgsensor.pclk = imgsensor_info.cap1.pclk; + imgsensor.line_length = imgsensor_info.cap1.linelength; + imgsensor.frame_length = imgsensor_info.cap1.framelength; + imgsensor.min_frame_length = imgsensor_info.cap1.framelength; + imgsensor.autoflicker_en = KAL_FALSE; + } + + spin_unlock(&imgsensor_drv_lock); + LOG_INF("Caputre fps:%d\n",imgsensor.current_fps); + //set_dummy(); + sensor_init(); + set_mirror_flip(imgsensor.mirror); + printk("Currently camera mode is %d, framelength=%d,linelength=%d\n",imgsensor.sensor_mode,imgsensor.frame_length,imgsensor.line_length); + return ERROR_NONE; +} /* capture() */ + + + +static kal_uint32 normal_video(MSDK_SENSOR_EXPOSURE_WINDOW_STRUCT *image_window, + MSDK_SENSOR_CONFIG_STRUCT *sensor_config_data) +{ + printk("csh002 normal_video E\n"); + + spin_lock(&imgsensor_drv_lock); + imgsensor.sensor_mode = IMGSENSOR_MODE_VIDEO; + imgsensor.pclk = imgsensor_info.normal_video.pclk; + imgsensor.line_length = imgsensor_info.normal_video.linelength; + imgsensor.frame_length = imgsensor_info.normal_video.framelength; + imgsensor.min_frame_length = imgsensor_info.normal_video.framelength; + //imgsensor.current_fps = 300; + imgsensor.autoflicker_en = KAL_FALSE; + spin_unlock(&imgsensor_drv_lock); + //set_dummy(); + sensor_init(); + set_mirror_flip(imgsensor.mirror); + LOG_INF("Currently camera mode is %d, framelength=%d,linelength=%d\n",imgsensor.sensor_mode,imgsensor.frame_length,imgsensor.line_length); + return ERROR_NONE; +} /* normal_video */ + + + +static kal_uint32 hs_video(MSDK_SENSOR_EXPOSURE_WINDOW_STRUCT *image_window, + MSDK_SENSOR_CONFIG_STRUCT *sensor_config_data) +{ + printk("csh002 hs_video E\n"); + + spin_lock(&imgsensor_drv_lock); + imgsensor.sensor_mode = IMGSENSOR_MODE_HIGH_SPEED_VIDEO; + imgsensor.pclk = imgsensor_info.hs_video.pclk; + //imgsensor.video_mode = KAL_TRUE; + imgsensor.line_length = imgsensor_info.hs_video.linelength; + + imgsensor.frame_length = imgsensor_info.hs_video.framelength; + imgsensor.min_frame_length = imgsensor_info.hs_video.framelength; + imgsensor.dummy_line = 0; + imgsensor.dummy_pixel = 0; + imgsensor.autoflicker_en = KAL_FALSE; + spin_unlock(&imgsensor_drv_lock); + //set_dummy(); + sensor_init(); + set_mirror_flip(imgsensor.mirror); + LOG_INF("Currently camera mode is %d,framerate is %d , framelength=%d,linelength=%d\n",imgsensor.sensor_mode,imgsensor.current_fps,imgsensor.frame_length,imgsensor.line_length); + return ERROR_NONE; +} /* hs_video */ + + + +static kal_uint32 slim_video(MSDK_SENSOR_EXPOSURE_WINDOW_STRUCT *image_window, + MSDK_SENSOR_CONFIG_STRUCT *sensor_config_data) +{ + printk("csh002 slim_video E\n"); + + spin_lock(&imgsensor_drv_lock); + imgsensor.sensor_mode = IMGSENSOR_MODE_SLIM_VIDEO; + imgsensor.pclk = imgsensor_info.slim_video.pclk; + imgsensor.line_length = imgsensor_info.slim_video.linelength; + imgsensor.frame_length = imgsensor_info.slim_video.framelength; + imgsensor.min_frame_length = imgsensor_info.slim_video.framelength; + imgsensor.dummy_line = 0; + imgsensor.dummy_pixel = 0; + imgsensor.autoflicker_en = KAL_FALSE; + spin_unlock(&imgsensor_drv_lock); + //set_dummy(); + sensor_init(); + set_mirror_flip(imgsensor.mirror); + LOG_INF("Currently camera mode is %d,framerate is %d , framelength=%d,linelength=%d\n",imgsensor.sensor_mode,imgsensor.current_fps,imgsensor.frame_length,imgsensor.line_length); + return ERROR_NONE; +} /* slim_video */ + + + + +static kal_uint32 get_resolution(MSDK_SENSOR_RESOLUTION_INFO_STRUCT *sensor_resolution) +{ + LOG_INF(" get resolution, now the mode is%d",imgsensor.sensor_mode); + sensor_resolution->SensorFullWidth = imgsensor_info.cap.grabwindow_width; + sensor_resolution->SensorFullHeight = imgsensor_info.cap.grabwindow_height; + + sensor_resolution->SensorPreviewWidth = imgsensor_info.pre.grabwindow_width; + sensor_resolution->SensorPreviewHeight = imgsensor_info.pre.grabwindow_height; + + sensor_resolution->SensorVideoWidth = imgsensor_info.normal_video.grabwindow_width; + sensor_resolution->SensorVideoHeight = imgsensor_info.normal_video.grabwindow_height; + + + sensor_resolution->SensorHighSpeedVideoWidth = imgsensor_info.hs_video.grabwindow_width; + sensor_resolution->SensorHighSpeedVideoHeight = imgsensor_info.hs_video.grabwindow_height; + + sensor_resolution->SensorSlimVideoWidth = imgsensor_info.slim_video.grabwindow_width; + sensor_resolution->SensorSlimVideoHeight = imgsensor_info.slim_video.grabwindow_height; + + return ERROR_NONE; +} /* get_resolution */ + + + +static kal_uint32 get_info(enum MSDK_SCENARIO_ID_ENUM scenario_id, + MSDK_SENSOR_INFO_STRUCT *sensor_info, + MSDK_SENSOR_CONFIG_STRUCT *sensor_config_data) +{ + LOG_INF("scenario_id = %d", scenario_id); + + sensor_info->SensorClockPolarity = SENSOR_CLOCK_POLARITY_LOW; + sensor_info->SensorClockFallingPolarity = SENSOR_CLOCK_POLARITY_LOW; /* not use */ + sensor_info->SensorHsyncPolarity = SENSOR_CLOCK_POLARITY_LOW; // inverse with datasheet + sensor_info->SensorVsyncPolarity = SENSOR_CLOCK_POLARITY_LOW; + sensor_info->SensorInterruptDelayLines = 4; /* not use */ + sensor_info->SensorResetActiveHigh = FALSE; /* not use */ + sensor_info->SensorResetDelayCount = 5; /* not use */ + + sensor_info->SensroInterfaceType = imgsensor_info.sensor_interface_type; + sensor_info->MIPIsensorType = imgsensor_info.mipi_sensor_type; + sensor_info->SettleDelayMode = imgsensor_info.mipi_settle_delay_mode; + sensor_info->SensorOutputDataFormat = imgsensor_info.sensor_output_dataformat; + + sensor_info->CaptureDelayFrame = imgsensor_info.cap_delay_frame; + sensor_info->PreviewDelayFrame = imgsensor_info.pre_delay_frame; + sensor_info->VideoDelayFrame = imgsensor_info.video_delay_frame; + sensor_info->HighSpeedVideoDelayFrame = imgsensor_info.hs_video_delay_frame; + sensor_info->SlimVideoDelayFrame = imgsensor_info.slim_video_delay_frame; + + sensor_info->SensorMasterClockSwitch = 0; /* not use */ + sensor_info->SensorDrivingCurrent = imgsensor_info.isp_driving_current; + + sensor_info->AEShutDelayFrame = imgsensor_info.ae_shut_delay_frame; /* The frame of setting shutter default 0 for TG int */ + sensor_info->AESensorGainDelayFrame = imgsensor_info.ae_sensor_gain_delay_frame; /* The frame of setting sensor gain */ + sensor_info->AEISPGainDelayFrame = imgsensor_info.ae_ispGain_delay_frame; + sensor_info->IHDR_Support = imgsensor_info.ihdr_support; + sensor_info->IHDR_LE_FirstLine = imgsensor_info.ihdr_le_firstline; + sensor_info->SensorModeNum = imgsensor_info.sensor_mode_num; + + sensor_info->SensorMIPILaneNumber = imgsensor_info.mipi_lane_num; + sensor_info->SensorClockFreq = imgsensor_info.mclk; + sensor_info->SensorClockDividCount = 3; /* not use */ + sensor_info->SensorClockRisingCount = 0; + sensor_info->SensorClockFallingCount = 2; /* not use */ + sensor_info->SensorPixelClockCount = 3; /* not use */ + sensor_info->SensorDataLatchCount = 2; /* not use */ + + sensor_info->MIPIDataLowPwr2HighSpeedTermDelayCount = 0; + sensor_info->MIPICLKLowPwr2HighSpeedTermDelayCount = 0; + sensor_info->SensorWidthSampling = 0; // 0 is default 1x + sensor_info->SensorHightSampling = 0; // 0 is default 1x + sensor_info->SensorPacketECCOrder = 1; + + switch (scenario_id) { + case MSDK_SCENARIO_ID_CAMERA_PREVIEW: + sensor_info->SensorGrabStartX = imgsensor_info.pre.startx; + sensor_info->SensorGrabStartY = imgsensor_info.pre.starty; + sensor_info->MIPIDataLowPwr2HighSpeedSettleDelayCount = imgsensor_info.pre.mipi_data_lp2hs_settle_dc; + break; + case MSDK_SCENARIO_ID_CAMERA_CAPTURE_JPEG: + sensor_info->SensorGrabStartX = imgsensor_info.cap.startx; + sensor_info->SensorGrabStartY = imgsensor_info.cap.starty; + sensor_info->MIPIDataLowPwr2HighSpeedSettleDelayCount = imgsensor_info.cap.mipi_data_lp2hs_settle_dc; + break; + case MSDK_SCENARIO_ID_VIDEO_PREVIEW: + sensor_info->SensorGrabStartX = imgsensor_info.normal_video.startx; + sensor_info->SensorGrabStartY = imgsensor_info.normal_video.starty; + sensor_info->MIPIDataLowPwr2HighSpeedSettleDelayCount = imgsensor_info.normal_video.mipi_data_lp2hs_settle_dc; + break; + case MSDK_SCENARIO_ID_HIGH_SPEED_VIDEO: + sensor_info->SensorGrabStartX = imgsensor_info.hs_video.startx; + sensor_info->SensorGrabStartY = imgsensor_info.hs_video.starty; + sensor_info->MIPIDataLowPwr2HighSpeedSettleDelayCount = imgsensor_info.hs_video.mipi_data_lp2hs_settle_dc; + break; + case MSDK_SCENARIO_ID_SLIM_VIDEO: + sensor_info->SensorGrabStartX = imgsensor_info.slim_video.startx; + sensor_info->SensorGrabStartY = imgsensor_info.slim_video.starty; + sensor_info->MIPIDataLowPwr2HighSpeedSettleDelayCount = imgsensor_info.slim_video.mipi_data_lp2hs_settle_dc; + break; + default: + sensor_info->SensorGrabStartX = imgsensor_info.pre.startx; + sensor_info->SensorGrabStartY = imgsensor_info.pre.starty; + sensor_info->MIPIDataLowPwr2HighSpeedSettleDelayCount = imgsensor_info.pre.mipi_data_lp2hs_settle_dc; + break; + } + + return ERROR_NONE; +} /* get_info */ + + + +static kal_uint32 control(enum MSDK_SCENARIO_ID_ENUM scenario_id, MSDK_SENSOR_EXPOSURE_WINDOW_STRUCT *image_window, + MSDK_SENSOR_CONFIG_STRUCT *sensor_config_data) +{ + LOG_INF("scenario_id = %d", scenario_id); + spin_lock(&imgsensor_drv_lock); + imgsensor.current_scenario_id = scenario_id; + spin_unlock(&imgsensor_drv_lock); + switch (scenario_id) { + case MSDK_SCENARIO_ID_CAMERA_PREVIEW: + preview(image_window, sensor_config_data); + break; + case MSDK_SCENARIO_ID_CAMERA_CAPTURE_JPEG: + capture(image_window, sensor_config_data); + break; + case MSDK_SCENARIO_ID_VIDEO_PREVIEW: + normal_video(image_window, sensor_config_data); + break; + case MSDK_SCENARIO_ID_HIGH_SPEED_VIDEO: + hs_video(image_window, sensor_config_data); + break; + case MSDK_SCENARIO_ID_SLIM_VIDEO: + slim_video(image_window, sensor_config_data); + break; + default: + LOG_INF("Error ScenarioId setting"); + preview(image_window, sensor_config_data); + return ERROR_INVALID_SCENARIO_ID; + } + return ERROR_NONE; +} /* control() */ + + + +static kal_uint32 set_video_mode(UINT16 framerate) +{ + + LOG_INF("framerate = %d\n ", framerate); + if (framerate == 0) + // Dynamic frame rate + return ERROR_NONE; + spin_lock(&imgsensor_drv_lock); + if ((framerate == 300) && (imgsensor.autoflicker_en == KAL_TRUE)) + imgsensor.current_fps = 296; + else if ((framerate == 150) && (imgsensor.autoflicker_en == KAL_TRUE)) + imgsensor.current_fps = 146; + else + imgsensor.current_fps = framerate; + spin_unlock(&imgsensor_drv_lock); + set_max_framerate(imgsensor.current_fps,1); + + return ERROR_NONE; + + +} + + +static kal_uint32 set_auto_flicker_mode(kal_bool enable, UINT16 framerate) +{ + LOG_INF("enable = %d, framerate = %d ", enable, framerate); + spin_lock(&imgsensor_drv_lock); + if (enable) + imgsensor.autoflicker_en = KAL_TRUE; + else //Cancel Auto flick + imgsensor.autoflicker_en = KAL_FALSE; + spin_unlock(&imgsensor_drv_lock); + return ERROR_NONE; +} + + +static kal_uint32 set_max_framerate_by_scenario(enum MSDK_SCENARIO_ID_ENUM scenario_id, MUINT32 framerate) +{ + kal_uint32 frame_length; + + LOG_INF("scenario_id = %d, framerate = %d\n", scenario_id, framerate); + + switch (scenario_id) { + case MSDK_SCENARIO_ID_CAMERA_PREVIEW: + frame_length = imgsensor_info.pre.pclk / framerate * 10 / imgsensor_info.pre.linelength; + spin_lock(&imgsensor_drv_lock); + imgsensor.dummy_line = (frame_length > imgsensor_info.pre.framelength) ? (frame_length - imgsensor_info.pre.framelength) : 0; + imgsensor.frame_length = imgsensor_info.pre.framelength + imgsensor.dummy_line; + imgsensor.min_frame_length = imgsensor.frame_length; + spin_unlock(&imgsensor_drv_lock); + break; + case MSDK_SCENARIO_ID_VIDEO_PREVIEW: + if(framerate == 0) + return ERROR_NONE; + frame_length = imgsensor_info.normal_video.pclk / framerate * 10 / imgsensor_info.normal_video.linelength; + spin_lock(&imgsensor_drv_lock); + imgsensor.dummy_line = (frame_length > imgsensor_info.normal_video.framelength) ? (frame_length - imgsensor_info.normal_video.framelength) : 0; + imgsensor.frame_length = imgsensor_info.normal_video.framelength + imgsensor.dummy_line; + imgsensor.min_frame_length = imgsensor.frame_length; + spin_unlock(&imgsensor_drv_lock); + break; + case MSDK_SCENARIO_ID_CAMERA_CAPTURE_JPEG: + if(framerate==300) + { + frame_length = imgsensor_info.cap.pclk / framerate * 10 / imgsensor_info.cap.linelength; + spin_lock(&imgsensor_drv_lock); + imgsensor.dummy_line = (frame_length > imgsensor_info.cap.framelength) ? (frame_length - imgsensor_info.cap.framelength) : 0; + imgsensor.frame_length = imgsensor_info.cap.framelength + imgsensor.dummy_line; + imgsensor.min_frame_length = imgsensor.frame_length; + spin_unlock(&imgsensor_drv_lock); + } + else + { + frame_length = imgsensor_info.cap1.pclk / framerate * 10 / imgsensor_info.cap1.linelength; + spin_lock(&imgsensor_drv_lock); + imgsensor.dummy_line = (frame_length > imgsensor_info.cap1.framelength) ? (frame_length - imgsensor_info.cap1.framelength) : 0; + imgsensor.frame_length = imgsensor_info.cap1.framelength + imgsensor.dummy_line; + imgsensor.min_frame_length = imgsensor.frame_length; + spin_unlock(&imgsensor_drv_lock); + } + break; + case MSDK_SCENARIO_ID_HIGH_SPEED_VIDEO: + frame_length = imgsensor_info.hs_video.pclk / framerate * 10 / imgsensor_info.hs_video.linelength; + spin_lock(&imgsensor_drv_lock); + imgsensor.dummy_line = (frame_length > imgsensor_info.hs_video.framelength) ? (frame_length - imgsensor_info.hs_video.framelength) : 0; + imgsensor.frame_length = imgsensor_info.hs_video.framelength + imgsensor.dummy_line; + imgsensor.min_frame_length = imgsensor.frame_length; + spin_unlock(&imgsensor_drv_lock); + LOG_INF("scenario hs_video:Currently camera mode is %d,framerate is %d , framelength=%d,linelength=%d\n",imgsensor.sensor_mode,imgsensor.current_fps,imgsensor.frame_length,imgsensor.line_length); + break; + case MSDK_SCENARIO_ID_SLIM_VIDEO: + frame_length = imgsensor_info.slim_video.pclk / framerate * 10 / imgsensor_info.slim_video.linelength; + spin_lock(&imgsensor_drv_lock); + imgsensor.dummy_line = (frame_length > imgsensor_info.slim_video.framelength) ? (frame_length - imgsensor_info.slim_video.framelength): 0; + imgsensor.frame_length = imgsensor_info.slim_video.framelength + imgsensor.dummy_line; + imgsensor.min_frame_length = imgsensor.frame_length; + spin_unlock(&imgsensor_drv_lock); + break; + default: //coding with preview scenario by default + frame_length = imgsensor_info.pre.pclk / framerate * 10 / imgsensor_info.pre.linelength; + spin_lock(&imgsensor_drv_lock); + imgsensor.dummy_line = (frame_length > imgsensor_info.pre.framelength) ? (frame_length - imgsensor_info.pre.framelength) : 0; + imgsensor.frame_length = imgsensor_info.pre.framelength + imgsensor.dummy_line; + imgsensor.min_frame_length = imgsensor.frame_length; + spin_unlock(&imgsensor_drv_lock); + LOG_INF("error scenario_id = %d, we use preview scenario \n", scenario_id); + break; + } + return ERROR_NONE; + +} + + +static kal_uint32 get_default_framerate_by_scenario(enum MSDK_SCENARIO_ID_ENUM scenario_id, MUINT32 *framerate) +{ + LOG_INF("scenario_id = %d\n", scenario_id); + + switch (scenario_id) { + case MSDK_SCENARIO_ID_CAMERA_PREVIEW: + *framerate = imgsensor_info.pre.max_framerate; + break; + case MSDK_SCENARIO_ID_VIDEO_PREVIEW: + *framerate = imgsensor_info.normal_video.max_framerate; + break; + case MSDK_SCENARIO_ID_CAMERA_CAPTURE_JPEG: + *framerate = imgsensor_info.cap.max_framerate; + break; + case MSDK_SCENARIO_ID_HIGH_SPEED_VIDEO: + *framerate = imgsensor_info.hs_video.max_framerate; + break; + case MSDK_SCENARIO_ID_SLIM_VIDEO: + *framerate = imgsensor_info.slim_video.max_framerate; + break; + default: + break; + } + + return ERROR_NONE; + + + +} + +static kal_uint32 set_test_pattern_mode(kal_bool enable) +{ +/* + LOG_INF("enable: %d\n", enable); + + if (enable) + { + write_cmos_sensor(0x0600, 0x0002); + } + else + { + write_cmos_sensor(0x0600, 0x0000); + } + + spin_lock(&imgsensor_drv_lock); + imgsensor.test_pattern = enable; + spin_unlock(&imgsensor_drv_lock);*/ + return ERROR_NONE; + +} + +static kal_uint32 feature_control(MSDK_SENSOR_FEATURE_ENUM feature_id, + UINT8 *feature_para,UINT32 *feature_para_len) +{ + UINT16 *feature_return_para_16=(UINT16 *) feature_para; + UINT16 *feature_data_16=(UINT16 *) feature_para; + UINT32 *feature_return_para_32=(UINT32 *) feature_para; + UINT32 *feature_data_32=(UINT32 *) feature_para; + + unsigned long long *feature_data=(unsigned long long *) feature_para; + + struct SENSOR_WINSIZE_INFO_STRUCT *wininfo; + MSDK_SENSOR_REG_INFO_STRUCT *sensor_reg_data=(MSDK_SENSOR_REG_INFO_STRUCT *) feature_para; + + LOG_INF("feature_id = %d", feature_id); + switch (feature_id) { + case SENSOR_FEATURE_GET_PERIOD: + *feature_return_para_16++ = imgsensor.line_length; + *feature_return_para_16 = imgsensor.frame_length; + *feature_para_len=4; + break; + case SENSOR_FEATURE_GET_PIXEL_CLOCK_FREQ: + *feature_return_para_32 = imgsensor.pclk; + *feature_para_len=4; + break; + case SENSOR_FEATURE_SET_ESHUTTER: + set_shutter(*feature_data); + break; + case SENSOR_FEATURE_SET_NIGHTMODE: + break; + case SENSOR_FEATURE_SET_GAIN: + set_gain((UINT16) *feature_data); + break; + case SENSOR_FEATURE_SET_FLASHLIGHT: + break; + case SENSOR_FEATURE_SET_ISP_MASTER_CLOCK_FREQ: + break; + case SENSOR_FEATURE_SET_REGISTER: + if((sensor_reg_data->RegData>>8)>0) + write_cmos_sensor(sensor_reg_data->RegAddr, sensor_reg_data->RegData); + break; + case SENSOR_FEATURE_GET_REGISTER: + sensor_reg_data->RegData = read_cmos_sensor(sensor_reg_data->RegAddr); + break; + case SENSOR_FEATURE_GET_LENS_DRIVER_ID: + *feature_return_para_32=LENS_DRIVER_ID_DO_NOT_CARE; + *feature_para_len=4; + break; + case SENSOR_FEATURE_SET_VIDEO_MODE: + set_video_mode(*feature_data); + break; + case SENSOR_FEATURE_CHECK_SENSOR_ID: + get_imgsensor_id(feature_return_para_32); + break; + case SENSOR_FEATURE_SET_AUTO_FLICKER_MODE: + set_auto_flicker_mode((kal_bool)*feature_data_16,*(feature_data_16+1)); + break; + case SENSOR_FEATURE_SET_MAX_FRAME_RATE_BY_SCENARIO: + set_max_framerate_by_scenario((enum MSDK_SCENARIO_ID_ENUM)*feature_data, *(feature_data+1)); + break; + case SENSOR_FEATURE_GET_DEFAULT_FRAME_RATE_BY_SCENARIO: + get_default_framerate_by_scenario((enum MSDK_SCENARIO_ID_ENUM)*feature_data, (MUINT32 *)(uintptr_t)(*(feature_data+1))); + break; + case SENSOR_FEATURE_SET_TEST_PATTERN: + set_test_pattern_mode((kal_bool)*feature_data); + break; + case SENSOR_FEATURE_GET_TEST_PATTERN_CHECKSUM_VALUE: //for factory mode auto testing + *feature_return_para_32 = imgsensor_info.checksum_value; + *feature_para_len=4; + break; + case SENSOR_FEATURE_SET_FRAMERATE: + LOG_INF("imx678 current fps :%d\n", (UINT32)*feature_data); + spin_lock(&imgsensor_drv_lock); + imgsensor.current_fps = *feature_data; + spin_unlock(&imgsensor_drv_lock); + break; + case SENSOR_FEATURE_SET_HDR: + LOG_INF("Warning! Not Support IHDR Feature"); + spin_lock(&imgsensor_drv_lock); + imgsensor.ihdr_en = KAL_FALSE; + spin_unlock(&imgsensor_drv_lock); + break; + case SENSOR_FEATURE_GET_CROP_INFO: + LOG_INF("imx678 SENSOR_FEATURE_GET_CROP_INFO scenarioId:%d\n", (UINT32)*feature_data_32); + wininfo = (struct SENSOR_WINSIZE_INFO_STRUCT *)(uintptr_t)(*(feature_data+1)); + + switch (*feature_data_32) { + case MSDK_SCENARIO_ID_CAMERA_CAPTURE_JPEG: + memcpy((void *)wininfo,(void *)&imgsensor_winsize_info[1],sizeof(struct SENSOR_WINSIZE_INFO_STRUCT)); + break; + case MSDK_SCENARIO_ID_VIDEO_PREVIEW: + memcpy((void *)wininfo,(void *)&imgsensor_winsize_info[2],sizeof(struct SENSOR_WINSIZE_INFO_STRUCT)); + break; + case MSDK_SCENARIO_ID_HIGH_SPEED_VIDEO: + memcpy((void *)wininfo,(void *)&imgsensor_winsize_info[3],sizeof(struct SENSOR_WINSIZE_INFO_STRUCT)); + break; + case MSDK_SCENARIO_ID_SLIM_VIDEO: + memcpy((void *)wininfo,(void *)&imgsensor_winsize_info[4],sizeof(struct SENSOR_WINSIZE_INFO_STRUCT)); + break; + case MSDK_SCENARIO_ID_CAMERA_PREVIEW: + default: + memcpy((void *)wininfo,(void *)&imgsensor_winsize_info[0],sizeof(struct SENSOR_WINSIZE_INFO_STRUCT)); + break; + } + break; + case SENSOR_FEATURE_SET_IHDR_SHUTTER_GAIN: + break; + default: + break; + } + + return ERROR_NONE; +} /* feature_control() */ + +static struct SENSOR_FUNCTION_STRUCT sensor_func = { + open, + get_info, + get_resolution, + feature_control, + control, + close +}; + +UINT32 IMX678MIPISensorInit( struct SENSOR_FUNCTION_STRUCT **pfFunc) +{ + if (pfFunc!=NULL) + *pfFunc=&sensor_func; + return ERROR_NONE; +} +