/* * sc2210_mipi.c * */ #include #include #include #include #include #include "isp_func_def.h" #include "isp_sensor_if.h" #include "sensor_ops.h" #include "clock_ops.h" #include "isp_enum.h" #include "mipi_api.h" #include "sc2210_mipi.h" #include "sensor.h" #ifndef OS_LINUX #include #endif static struct sns_cfg_s sns_cfg = { .inited = 0, .curr_exposure_ratio = 256, // 默认初始化为16倍 .MinRstLine = 5, .minAGain = 0x40, }; static int SetIntt(FH_UINT32 intt, FH_UINT8 fNo); static int GetIntt(); static int SetGain(FH_UINT32 again, FH_UINT8 fNo); static int GetGain(); static int SetExposureRatio(FH_UINT32 exposure_ratio); static int GetExposureRatio(FH_UINT32 *exposure_ratio); static int GetSensorViAttr(ISP_VI_ATTR_S *vi_attr) { if(vi_attr == NULL) return FH_ERR_NULL_POINTER; switch (sns_cfg.sensor_fmt) { case FORMAT_1080P25: vi_attr->u16WndWidth = FRAM_W_1080P25; vi_attr->u16WndHeight = FRAM_H_1080P25; vi_attr->u16InputWidth = ACTIVE_W_1080P25; vi_attr->u16InputHeight = ACTIVE_H_1080P25; vi_attr->u16PicWidth = PIC_IN_W_1080P25; vi_attr->u16PicHeight = PIC_IN_H_1080P25; vi_attr->u16OffsetX = OFFSET_X_1080P25; vi_attr->u16OffsetY = OFFSET_Y_1080P25; vi_attr->enBayerType = BAYER_BGGR; sns_cfg.curr_hsf = 25 * vi_attr->u16WndHeight; break; case FORMAT_1080P30: vi_attr->u16WndWidth = FRAM_W_1080P30; vi_attr->u16WndHeight = FRAM_H_1080P30; vi_attr->u16InputWidth = ACTIVE_W_1080P30; vi_attr->u16InputHeight = ACTIVE_H_1080P30; vi_attr->u16PicWidth = PIC_IN_W_1080P30; vi_attr->u16PicHeight = PIC_IN_H_1080P30; vi_attr->u16OffsetX = OFFSET_X_1080P30; vi_attr->u16OffsetY = OFFSET_Y_1080P30; vi_attr->enBayerType = BAYER_BGGR; sns_cfg.curr_hsf = 30 * vi_attr->u16WndHeight; break; case FORMAT_WDR_1080P25: vi_attr->u16WndWidth = FRAM_W_1080P25_WDR; vi_attr->u16WndHeight = FRAM_H_1080P25_WDR; vi_attr->u16InputWidth = ACTIVE_W_1080P25_WDR; vi_attr->u16InputHeight = ACTIVE_H_1080P25_WDR; vi_attr->u16PicWidth = PIC_IN_W_1080P25_WDR; vi_attr->u16PicHeight = PIC_IN_H_1080P25_WDR; vi_attr->u16OffsetX = OFFSET_X_1080P25_WDR; vi_attr->u16OffsetY = OFFSET_Y_1080P25_WDR; vi_attr->enBayerType = BAYER_BGGR; sns_cfg.curr_hsf = 25 * vi_attr->u16WndHeight; break; case FORMAT_WDR_1080P30: vi_attr->u16WndWidth = FRAM_W_1080P30_WDR; vi_attr->u16WndHeight = FRAM_H_1080P30_WDR; vi_attr->u16InputWidth = ACTIVE_W_1080P30_WDR; vi_attr->u16InputHeight = ACTIVE_H_1080P30_WDR; vi_attr->u16PicWidth = PIC_IN_W_1080P30_WDR; vi_attr->u16PicHeight = PIC_IN_H_1080P30_WDR; vi_attr->u16OffsetX = OFFSET_X_1080P30_WDR; vi_attr->u16OffsetY = OFFSET_Y_1080P30_WDR; vi_attr->enBayerType = BAYER_BGGR; sns_cfg.curr_hsf = 30 * vi_attr->u16WndHeight; break; default: break; } return 0; } static void SensorReset(void) { return; } static unsigned short sc2210_i2c_addr = 0x60; static int Sensor_Isconnect(void) { unsigned short pid1, pid2; unsigned short i2c_addr[4] = {0x60,0x62, 0x64,0x66}; int i; for(i = 0; i < 4; i ++) { SensorDevice_Init((i2c_addr[i] >> 1), 2); pid1 = Sensor_Read(0x3107); if(pid1!=0x22) { SensorDevice_Close(); continue; } pid2 = Sensor_Read(0x3108); SensorDevice_Close(); if (pid1 == 0x22 && pid2 == 0x10) { sc2210_i2c_addr = i2c_addr[i]; return 1; } else { continue; } } return 0; } static int Sensor_Init(void) { Sensor_Isconnect(); SensorDevice_Init((sc2210_i2c_addr>>1), 2); SensorReset(); sns_cfg.inited = 1; return 0; } static int Sensor_DeInit(void) { SensorReset(); return SensorDevice_Close(); } // GetGain仅在ae refresh时会重新获取,所以尽量直接从sensor端获取,保证intt的正确性 static int GetGain() { return sns_cfg.curr_sensor_gain; } // GetIntt仅在ae refresh时会重新获取,所以尽量直接从sensor端获取,保证intt的正确性 static int GetIntt(void) { return sns_cfg.curr_sensor_intt; } static int SetLaneNumMax(FH_UINT32 lane_num) { sns_cfg.maxLaneNum = lane_num; return 0; } static void SetSensorMipiCfg(void) { struct mipi_conf config; config.frq_range = R_750_799; config.sensor_mode = NOT_SONY_WDR_USE_WDR; config.raw_type = RAW10; // config.lf_vc_id = 0; // config.sf_vc_id = 1; // config.lane_num =2; if(!sns_cfg.wdr_flag) { config.lf_vc_id = 0xff;//0xff config.sf_vc_id = 0xff;//0xff config.lane_num =2; } else { config.lf_vc_id = 0; config.sf_vc_id = 2; config.lane_num =2; } mipi_init(&config); } static int SetSensorFmt(int format) { sns_cfg.sensor_fmt = format; sns_cfg.wdr_flag = (format >> 16)&1; SetSensorMipiCfg(); if(sns_cfg.inited) { int i; printf("sc2210 ver20210701\n"); switch(format) { case FORMAT_1080P25: printf("1080p25\n"); for(i=0; icurrIntt = GetIntt(); sensAEInfo->currAGain = GetGain(); sensAEInfo->currHsf = sns_cfg.curr_hsf; sensAEInfo->currFrameH = sns_cfg.v_cycle; return 0; } static int GetAEDefault(Sensor_AE_Default_S *sensAEDefault) { sensAEDefault->minIntt = 1; sensAEDefault->maxIntt = sns_cfg.max_intt; sensAEDefault->minAGain = sns_cfg.minAGain; sensAEDefault->maxAGain = 0x7fff; sensAEDefault->fullLineStd = sns_cfg.fullLineStd; sensAEDefault->MinRstLine = sns_cfg.MinRstLine; return 0; } static int CalcSnsValidGain(FH_UINT32 *u32Gain) { return 0; } static int SetGain(FH_UINT32 again, FH_UINT8 fNo) { sns_cfg.curr_sensor_gain = again; unsigned char gain_0x3e06 = 0x00; unsigned char gain_0x3e07 = 0x80; unsigned char gain_0x3e08 = 0x03; unsigned char gain_0x3e09 = 0x40; //UINT32 gainShift = 0; //printf("again: 0x%x, ", again); if (again < 64 * 2) //again 1x-2x { gain_0x3e08 = 0x03; gain_0x3e09 = again; gain_0x3e06 = 0x0; gain_0x3e07 = 0x80; } else if (again <= 64 * 3.375) //again 2x-3.375x { gain_0x3e08 = 0x07; gain_0x3e09 = again / 2; gain_0x3e06 = 0x0; gain_0x3e07 = 0x80; } else if (again <= 64 * 3.375 * 2) //again 3.375x-6.812x { gain_0x3e08 = 0x23; gain_0x3e09 = again / 3.375; gain_0x3e06 = 0x0; gain_0x3e07 = 0x80; } else if (again <= 64 * 3.375 * 4) //again 6.812x-13.624x { gain_0x3e08 = 0x27; gain_0x3e09 = again / 3.375 / 2; gain_0x3e06 = 0x0; gain_0x3e07 = 0x80; } else if (again <= 64 * 3.375 * 8) //again 13.624x-27.248x { gain_0x3e08 = 0x2f; gain_0x3e09 = again / 3.375 / 4; gain_0x3e06 = 0x0; gain_0x3e07 = 0x80; } else if (again <= 64 * 3.375 * 16) //again 27.248x-54.07x { gain_0x3e08 = 0x3f; gain_0x3e09 = again / 3.375 / 8; gain_0x3e06 = 0x0; gain_0x3e07 = 0x80; } #if 1 else if (again <= 64 * 3.375 * 16 * 2) //again 54.07x dgain 2x { gain_0x3e08 = 0x3f; gain_0x3e09 = 0x7f; gain_0x3e06 = 0x0; gain_0x3e07 = again / 3.375 / 8; } else if (again <= 64 * 3.375 * 16 * 4) //again 54.07x dgain 4x { gain_0x3e08 = 0x3f; gain_0x3e09 = 0x7f; gain_0x3e06 = 0x1; gain_0x3e07 = again / 3.375 / 16; } else if (again <= 64 * 3.375 * 16 * 8) //again 54.07x dgain 8x { gain_0x3e08 = 0x3f; gain_0x3e09 = 0x7f; gain_0x3e06 = 0x3; gain_0x3e07 = again / 3.375 / 32; } else if (again <= 64 * 3.375 * 16 * 16) //again 54.07x dgain 16x { gain_0x3e08 = 0x3f; gain_0x3e09 = 0x7f; gain_0x3e06 = 0x7; gain_0x3e07 = again / 3.375 / 64; } else if (again <= 64 * 3.375 * 16 * 32) //again 54.07x dgain 32x { gain_0x3e08 = 0x3f; gain_0x3e09 = 0x7f; gain_0x3e06 = 0xf; gain_0x3e07 = again / 3.375 / 128; } #endif // high frm GAIN Sensor_Write(0x3e06, gain_0x3e06); Sensor_Write(0x3e07, gain_0x3e07); Sensor_Write(0x3e08, gain_0x3e08); Sensor_Write(0x3e09, gain_0x3e09); // low frm GAIN Sensor_Write(0x3e10, gain_0x3e06); Sensor_Write(0x3e11, gain_0x3e07); Sensor_Write(0x3e12, gain_0x3e08); Sensor_Write(0x3e13, gain_0x3e09); return 0; } static int CalcSnsValidIntt(FH_UINT32 *u32Intt) { return 0; } static int SetIntt(FH_UINT32 intt, FH_UINT8 fNo) { //printf("intt=%d----",intt); if(intt<2) intt=2; sns_cfg.curr_sensor_intt = intt; //printf("curr_sensor_intt=%d\n",curr_sensor_intt); /* FH_SINT32 height1L,height1H,height1,height2L,height2H,height2; height1H = Sensor_Read(0x320e); height1L = Sensor_Read(0x320f); height1 = (height1H << 8) | height1L; height2H = Sensor_Read(0x3e23); height2L = Sensor_Read(0x3e24); height2 = (height2H << 8) | height2L; */ FH_UINT8 exposure_3e00 = 0x00; FH_UINT8 exposure_3e01 = 0x00; FH_UINT8 exposure_3e02 = 0x00; /* if(wdr_flag==0) { if(intt > height1-4 ) intt = height1-4; } else { if(intt > height1-height2-8 ) intt = height1-height2-8 ; } */ exposure_3e00 = (intt>>12) & 0x0f; exposure_3e01 = (intt &0xfff)>>4; exposure_3e02 = (intt&0xf)<<4; Sensor_Write(0x3e00, exposure_3e00); Sensor_Write(0x3e01, exposure_3e01); Sensor_Write(0x3e02, exposure_3e02); sns_cfg.curr_sensor_intt = intt; return 0; } static int SetSnsFrameH(FH_UINT32 frameH) { //if(sns_cfg.wdr_flag) // frame_height = (vi_attr.u16WndHeight )* multiple; // else // frame_height = (vi_attr.u16WndHeight/2 )* multiple; Sensor_Write(0x320e, (frameH>>8)&0xff); Sensor_Write(0x320f, frameH&0xff); sns_cfg.v_cycle = frameH; return 0; } static int SetExposureRatio(FH_UINT32 exposure_ratio) { FH_UINT32 s_intt; //FH_SINT32 s_3e23,s_3e24,sf_exp_limit; if(exposure_ratio == 0) return 0; //s_3e23=Sensor_Read(0x3e23); //s_3e24=Sensor_Read(0x3e24); //sf_exp_limit=(s_3e23<<8)|s_3e24; s_intt = MAX((((sns_cfg.curr_sensor_intt<<6)+(exposure_ratio>>1)) / exposure_ratio), 1); //printf("the s_intt =%d, %d\n",s_intt,s_intt%4); if(s_intt < 1) s_intt = 1; /* if(s_intt > (2 * sf_exp_limit -8)) s_intt = 2 * sf_exp_limit -8; */ Sensor_Write(0x3e04, (s_intt&0xfff)>>4); Sensor_Write(0x3e05, (s_intt&0xf)<<4); sns_cfg.curr_exposure_ratio = (sns_cfg.curr_sensor_intt<<4)/s_intt; return 0; } static int GetExposureRatio(FH_UINT32 *exposure_ratio) { *exposure_ratio = sns_cfg.curr_exposure_ratio; return 0; } /* static int Sensor_Kick() { if (sns_cfg.inited) { SensorDevice_Init((sc2210_i2c_addr>>1), 2); //0x64 SensorReset(); sns_cfg.inited = 1; } return 0; } */ static int SetSensorReg(unsigned short addr,unsigned short data) { Sensor_Write(addr,data); return 0; } static int GetSensorReg(unsigned short addr, unsigned short *data) { *data = Sensor_Read(addr); return 0; } static int SetSensorFlipMirror(FH_UINT32 sensor_en_stat) { FH_UINT32 mirror,flip; mirror = (sensor_en_stat >>1)&0x1; flip = sensor_en_stat & 0x1; Sensor_Write(0x3221, ((flip?0x3:0x00)<<5) | ((mirror?0x3:0x00) <<1) ); return 0; } static int GetSensorFlipMirror(FH_UINT32 *sensor_en_stat) { FH_UINT32 mirror,flip,tmp; tmp = Sensor_Read(0x3221); mirror = (tmp>>1) & 0x1; flip = (tmp>>5) &0x01 ; *sensor_en_stat = (mirror<<1)|flip; return 0; } static int GetSensorAttribute(char *name, FH_UINT32 *value) { #ifdef OS_LINUX if (strcmp(name, "WDR") == 0) { #else if (rt_strcmp(name, "WDR") == 0) { #endif *value = sns_cfg.wdr_flag; return 0; } return -1; } static int SensorCommonIf(FH_UINT32 cmd, ISP_SENSOR_COMMON_CMD_DATA0* data0, ISP_SENSOR_COMMON_CMD_DATA1* data1) { int ret = -1; return ret; } static FH_UINT32* GetMirrorFlipBayerFormat(void) { return NAME(MirrorFlipBayerFormat); } static FH_UINT32* GetUserSensorAwbGain(FH_UINT32 idx) {return 0;} static FH_UINT32* GetSensorLtmCurve(FH_UINT32 idx) { return 0; } /***********************adv api related end*************************************/ /***********************not used for now start**********************************/ static int SetSensorAwbGain(FH_UINT32 *awb_gain){return 0;} static int GetSensorAwbGain(FH_UINT32 *awb_gain){return 0;} static int SetSensorIris(FH_UINT32 iris){return 0;} #define SENSOR_SC2210_MIPI "sc2210_mipi" struct isp_sensor_if sc2210_mipi_sensor_if; /***********************not used for now end************************************/ #ifdef OS_RTT struct isp_sensor_if sc2210_mipi_sensor_if __attribute__((section(".sensor_drv"))) = { #else struct isp_sensor_if sc2210_mipi_sensor_if = { #endif .name = SENSOR_SC2210_MIPI, .get_vi_attr = GetSensorViAttr, .set_flipmirror = SetSensorFlipMirror, .get_flipmirror = GetSensorFlipMirror, .set_iris = SetSensorIris, .init = Sensor_Init, .reset = SensorReset, .deinit = Sensor_DeInit, .set_sns_fmt = SetSensorFmt, //.kick = Sensor_Kick, .set_sns_reg = SetSensorReg, .set_exposure_ratio = SetExposureRatio, .get_exposure_ratio = GetExposureRatio, .get_sensor_attribute = GetSensorAttribute, .set_lane_num_max = SetLaneNumMax, .get_sns_reg = GetSensorReg, .get_awb_gain = GetSensorAwbGain, .set_awb_gain = SetSensorAwbGain, .data = 0, .common_if = SensorCommonIf, .get_sns_ae_default = GetAEDefault, .get_sns_ae_info = GetAEInfo, .set_sns_intt = SetIntt, .calc_sns_valid_intt = CalcSnsValidIntt, .set_sns_gain = SetGain, .calc_sns_valid_gain = CalcSnsValidGain, .set_sns_frame_height = SetSnsFrameH, .get_sensor_mirror_flip_bayer_format = GetMirrorFlipBayerFormat, .get_user_awb_gain = GetUserSensorAwbGain, .get_user_ltm_curve = GetSensorLtmCurve, .is_sensor_connect = Sensor_Isconnect, }; #ifdef OS_RTT #else struct isp_sensor_if* NAME(Sensor_Create)() { return &sc2210_mipi_sensor_if; } void NAME(Sensor_Destroy)(struct isp_sensor_if* s_if){ memset(&sc2210_mipi_sensor_if, 0, sizeof(struct isp_sensor_if)); } #endif