You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1569 lines
50 KiB
C

/*****************************************************************************
*
* 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 <linux/videodev2.h>
#include <linux/i2c.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/cdev.h>
#include <linux/uaccess.h>
#include <linux/fs.h>
#include <linux/atomic.h>
#include <linux/types.h>
#include <linux/slab.h>
#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 = 8, //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 = 8,
.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 = 8,
.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 = 8,
.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 = 8,
.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 = 8,
.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);
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;
}