/***************************************************************************** * * 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 = 67500, //2250, //2300, //record different mode's framelength .startx = 0, //record different mode's startx of grabwindow .starty = 24, //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 = 10, }, .cap = { .pclk = 74250000, .linelength = 1100, .framelength = 67500, //2250, .startx = 0, .starty = 24, .grabwindow_width = 3840, .grabwindow_height = 2160, .mipi_data_lp2hs_settle_dc = 85, .max_framerate = 10, }, .cap1 = { .pclk = 74250000, .linelength = 1100, .framelength = 67500, //2250, .startx = 0, .starty = 24, .grabwindow_width = 3840, .grabwindow_height = 2160, .mipi_data_lp2hs_settle_dc = 85, .max_framerate = 10, }, .normal_video = { .pclk = 74250000, .linelength = 1100, .framelength = 2250, .startx = 0, .starty = 24, .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 = 24, .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 = 24, .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_R, .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); // 处理低帧率情况 if (framerate < 5) { // 非常低的帧率 frame_length = imgsensor.pclk / framerate * 10 / imgsensor.line_length; } else { // 原有计算方式 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; if (shutter > (imgsensor.frame_length - imgsensor_info.margin)) imgsensor.frame_length = shutter + imgsensor_info.margin; 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; }