diff --git a/build/boards/cv181x/cv1812cp_milkv_duo256m_sd/cv1812cp_milkv_duo256m_sd_defconfig b/build/boards/cv181x/cv1812cp_milkv_duo256m_sd/cv1812cp_milkv_duo256m_sd_defconfig index 55e3485a3..2f50b6c20 100644 --- a/build/boards/cv181x/cv1812cp_milkv_duo256m_sd/cv1812cp_milkv_duo256m_sd_defconfig +++ b/build/boards/cv181x/cv1812cp_milkv_duo256m_sd/cv1812cp_milkv_duo256m_sd_defconfig @@ -11,6 +11,7 @@ CONFIG_FLASH_SIZE_SHRINK=y CONFIG_BOOT_IMAGE_SINGLE_DTB=y CONFIG_STORAGE_TYPE_sd=y CONFIG_SENSOR_SONY_IMX327=y +CONFIG_SENSOR_GCORE_GC2083=y CONFIG_SENSOR_SMS_SC035HGS=y CONFIG_UBOOT_2021_10=y CONFIG_KERNEL_SRC_5.10=y diff --git a/build/boards/cv181x/cv1812cp_milkv_duo256m_sd/u-boot/cvi_board_init.c b/build/boards/cv181x/cv1812cp_milkv_duo256m_sd/u-boot/cvi_board_init.c index 2938a3ec9..257612ec7 100644 --- a/build/boards/cv181x/cv1812cp_milkv_duo256m_sd/u-boot/cvi_board_init.c +++ b/build/boards/cv181x/cv1812cp_milkv_duo256m_sd/u-boot/cvi_board_init.c @@ -2,7 +2,8 @@ int cvi_board_init(void) { PINMUX_CONFIG(PAD_MIPI_TXM1, IIC2_SDA); PINMUX_CONFIG(PAD_MIPI_TXP1, IIC2_SCL); - PINMUX_CONFIG(PAD_MIPI_TXM0, CAM_MCLK1); + PINMUX_CONFIG(PAD_MIPI_TXP0, CAM_MCLK0); + PINMUX_CONFIG(PAD_MIPI_TXP2, XGPIOC_17); return 0; } diff --git a/middleware/v2/component/isp/sensor/cv181x/Makefile b/middleware/v2/component/isp/sensor/cv181x/Makefile index 6706e8cfc..b93866941 100644 --- a/middleware/v2/component/isp/sensor/cv181x/Makefile +++ b/middleware/v2/component/isp/sensor/cv181x/Makefile @@ -46,6 +46,9 @@ gcore_gc2053_slave: gcore_gc2053_1L: $(call MAKE_SENSOR, ${@}) +gcore_gc2083: + $(call MAKE_SENSOR, ${@}) + gcore_gc2093: $(call MAKE_SENSOR, ${@}) diff --git a/middleware/v2/component/isp/sensor/cv181x/gcore_gc2083/Makefile b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2083/Makefile new file mode 100644 index 000000000..25ce84b58 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2083/Makefile @@ -0,0 +1,36 @@ +SHELL = /bin/bash +ifeq ($(PARAM_FILE), ) + PARAM_FILE=../../../../../../$(shell echo $(MW_VER))/Makefile.param + include $(PARAM_FILE) +endif + +SDIR = $(PWD) +SRCS = $(wildcard $(SDIR)/*.c) +INCS = -I$(MW_INC) -I$(ISP_INC) -I$(KERNEL_INC) -I./include +OBJS = $(SRCS:.c=.o) +DEPS = $(SRCS:.c=.d) +TARGET_A = $(MW_LIB)/libsns_gc2083.a +TARGET_SO = $(MW_LIB)/libsns_gc2083.so + +EXTRA_CFLAGS = $(INCS) +EXTRA_LDFLAGS = + +.PHONY : clean all +all : $(TARGET_A) $(TARGET_SO) + +$(SDIR)/%.o: $(SDIR)/%.c + @$(CC) $(DEPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@ + @echo [$(notdir $(CC))] $(notdir $@) + +$(TARGET_A): $(OBJS) + @$(AR) $(ARFLAGS) $@ $(OBJS) + @echo -e $(YELLOW)[LINK]$(END)[$(notdir $(AR))] $(notdir $(TARGET_A)) + +$(TARGET_SO): $(OBJS) + @$(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -o $@ --start-group $(OBJS) --end-group + @echo -e $(GREEN)[LINK]$(END)[$(notdir $(LD))] $(notdir $(TARGET_SO)) + +clean: + @rm -f $(OBJS) $(DEPS) $(TARGET_A) $(TARGET_SO) + +-include $(DEPS) diff --git a/middleware/v2/component/isp/sensor/cv181x/gcore_gc2083/gc2083_cmos.c b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2083/gc2083_cmos.c new file mode 100644 index 000000000..0e9323bf1 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2083/gc2083_cmos.c @@ -0,0 +1,976 @@ +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include "cvi_type.h" +#include "cvi_comm_video.h" +#include +#else +#include +#include +#include +#endif +#include "cvi_debug.h" +#include "cvi_comm_sns.h" +#include "cvi_sns_ctrl.h" +#include "cvi_ae_comm.h" +#include "cvi_awb_comm.h" +#include "cvi_ae.h" +#include "cvi_awb.h" +#include "cvi_isp.h" + +#include "gc2083_cmos_ex.h" +#include "gc2083_cmos_param.h" + +#define DIV_0_TO_1(a) ((0 == (a)) ? 1 : (a)) +#define DIV_0_TO_1_FLOAT(a) ((((a) < 1E-10) && ((a) > -1E-10)) ? 1 : (a)) +#define GC2083_ID 2083 +#define GC2083_I2C_ADDR_1 0x3f +#define GC2083_I2C_ADDR_2 0x37 +#define GC2083_I2C_ADDR_IS_VALID(addr) ((addr) == GC2083_I2C_ADDR_1 || (addr) == GC2083_I2C_ADDR_2) + +/**************************************************************************** + * global variables * + ****************************************************************************/ + +ISP_SNS_STATE_S *g_pastGc2083[VI_MAX_PIPE_NUM] = {CVI_NULL}; + +#define GC2083_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastGc2083[dev]) +#define GC2083_SENSOR_SET_CTX(dev, pstCtx) (g_pastGc2083[dev] = pstCtx) +#define GC2083_SENSOR_RESET_CTX(dev) (g_pastGc2083[dev] = CVI_NULL) + +ISP_SNS_COMMBUS_U g_aunGc2083_BusInfo[VI_MAX_PIPE_NUM] = { + [0] = { .s8I2cDev = 0}, + [1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1} +}; + +GC2083_STATE_S g_astGc2083_State[VI_MAX_PIPE_NUM] = { {0} }; +ISP_SNS_MIRRORFLIP_TYPE_E g_aeGc2083_MirrorFip[VI_MAX_PIPE_NUM] = {0}; + +CVI_U16 g_au16Gc2083_GainMode[VI_MAX_PIPE_NUM] = {0}; +CVI_U16 g_au16Gc2083_L2SMode[VI_MAX_PIPE_NUM] = {0}; + +/**************************************************************************** + * local variables and functions * + ****************************************************************************/ +static CVI_U32 g_au32InitExposure[VI_MAX_PIPE_NUM] = {0}; +static CVI_U32 g_au32LinesPer500ms[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16InitWBGain[VI_MAX_PIPE_NUM][3] = {{0} }; +static CVI_U16 g_au16SampleRgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_U16 g_au16SampleBgain[VI_MAX_PIPE_NUM] = {0}; +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg); +/*****Gc2083 Lines Range*****/ +#define GC2083_FULL_LINES_MAX (0x3fff) // 0x3FFF(Max VB) + 1080 + 16 + +/*****Gc2083 Register Address*****/ +#define GC2083_EXP_H_ADDR 0x0d03 +#define GC2083_EXP_L_ADDR 0x0d04 +#define GC2083_AGAIN_H_ADDR 0x0dc1 +#define GC2083_AGAIN_L_ADDR 0x00d0 +#define GC2083_COL_AGAIN_H_ADDR 0x00b8 +#define GC2083_COL_AGAIN_L_ADDR 0x00b9 +#define GC2083_DGAIN_H_ADDR 0x00b1 +#define GC2083_DGAIN_L_ADDR 0x00b2 +#define GC2083_VTS_H_ADDR 0x0d41 //(frame length) +#define GC2083_VTS_L_ADDR 0x0d42 +#define GC2083_AGAIN_HOLD 0x031d +#define GC2083_AGAIN_MAG1 0x0155 +#define GC2083_AGAIN_MAG2 0x0410 +#define GC2083_AGAIN_MAG3 0x0411 +#define GC2083_AGAIN_MAG4 0x0412 +#define GC2083_AGAIN_MAG5 0x0413 +#define GC2083_AGAIN_MAG6 0x0414 +#define GC2083_AGAIN_MAG7 0x0415 +#define GC2083_AGAIN_MAG8 0x0416 +#define GC2083_AGAIN_MAG9 0x0417 + +#define GC2083_RES_IS_1080P(w, h) ((w) == 1920 && (h) == 1080) + +static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + GC2083_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32FlickerFreq = 50 * 256; + pstAeSnsDft->u32FullLinesMax = GC2083_FULL_LINES_MAX; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 30); + + pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR; + pstAeSnsDft->stIntTimeAccu.f32Accuracy = 1; + pstAeSnsDft->stIntTimeAccu.f32Offset = 0; + pstAeSnsDft->stAgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stAgainAccu.f32Accuracy = 1; + pstAeSnsDft->stDgainAccu.enAccuType = AE_ACCURACY_TABLE; + pstAeSnsDft->stDgainAccu.f32Accuracy = 1; + + pstAeSnsDft->u32ISPDgainShift = 8; + pstAeSnsDft->u32MinISPDgainTarget = 1 << pstAeSnsDft->u32ISPDgainShift; + pstAeSnsDft->u32MaxISPDgainTarget = 2 << pstAeSnsDft->u32ISPDgainShift; + + if (g_au32LinesPer500ms[ViPipe] == 0) + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * 30 / 2; + else + pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe]; + + switch (pstSnsState->enWDRMode) { + default: + case WDR_MODE_NONE: /*linear mode*/ + pstAeSnsDft->f32Fps = g_stGc2083_mode[GC2083_MODE_1920X1080P30].f32MaxFps; + pstAeSnsDft->f32MinFps = g_stGc2083_mode[GC2083_MODE_1920X1080P30].f32MinFps; + pstAeSnsDft->au8HistThresh[0] = 0xd; + pstAeSnsDft->au8HistThresh[1] = 0x28; + pstAeSnsDft->au8HistThresh[2] = 0x60; + pstAeSnsDft->au8HistThresh[3] = 0x80; + + pstAeSnsDft->u32MaxAgain = 8028*16; + pstAeSnsDft->u32MinAgain = 1024; + pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain; + pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain; + + pstAeSnsDft->u32MaxDgain = 10240; + pstAeSnsDft->u32MinDgain = 1024; + pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain; + pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain; + + pstAeSnsDft->u8AeCompensation = 40; + pstAeSnsDft->u32InitAESpeed = 64; + pstAeSnsDft->u32InitAETolerance = 5; + pstAeSnsDft->u32AEResponseFrame = 4; + pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR; + pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? + g_au32InitExposure[ViPipe] : g_stGc2083_mode[GC2083_MODE_1920X1080P30].stExp[0].u16Def; + + pstAeSnsDft->u32MaxIntTime = g_stGc2083_mode[GC2083_MODE_1920X1080P30].stExp[0].u16Max; + pstAeSnsDft->u32MinIntTime = g_stGc2083_mode[GC2083_MODE_1920X1080P30].stExp[0].u16Min; + pstAeSnsDft->u32MaxIntTimeTarget = 65535; + pstAeSnsDft->u32MinIntTimeTarget = 1; + break; + } + + + return CVI_SUCCESS; +} + +/* the function of sensor set fps */ +static CVI_S32 cmos_fps_set(VI_PIPE ViPipe, CVI_FLOAT f32Fps, AE_SENSOR_DEFAULT_S *pstAeSnsDft) +{ + + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + CVI_U32 u32VMAX; + CVI_FLOAT f32MaxFps = 0; + CVI_FLOAT f32MinFps = 0; + CVI_U32 u32Vts = 0; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + CMOS_CHECK_POINTER(pstAeSnsDft); + GC2083_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u32Vts = g_stGc2083_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + f32MaxFps = g_stGc2083_mode[pstSnsState->u8ImgMode].f32MaxFps; + f32MinFps = g_stGc2083_mode[pstSnsState->u8ImgMode].f32MinFps; + + if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) { + u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps); + CVI_TRACE_SNS(CVI_DBG_ERR, "u32VMAX: %d, Fps: %f\n", u32VMAX, f32Fps); + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps); + return CVI_FAILURE; + } + + u32VMAX = (u32VMAX > GC2083_FULL_LINES_MAX) ? GC2083_FULL_LINES_MAX : u32VMAX; + pstSnsRegsInfo->astI2cData[LINEAR_VTS_H].u32Data = ((u32VMAX & 0xFF00) >> 8); + pstSnsRegsInfo->astI2cData[LINEAR_VTS_L].u32Data = (u32VMAX & 0xFF); + + + pstSnsState->u32FLStd = u32VMAX; + + pstAeSnsDft->f32Fps = f32Fps; + pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2; + pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd; + pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 8; + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstAeSnsDft->u32FullLines = pstSnsState->au32FL[0]; + pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * DIV_0_TO_1_FLOAT(f32Fps)); + + return CVI_SUCCESS; +} + +/* while isp notify ae to update sensor regs, ae call these funcs. */ +static CVI_S32 cmos_inttime_update(VI_PIPE ViPipe, CVI_U32 *u32IntTime) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + + GC2083_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(u32IntTime); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + pstSnsRegsInfo->astI2cData[LINEAR_EXP_H].u32Data = ((u32IntTime[0] >> 8) & 0x3F); + pstSnsRegsInfo->astI2cData[LINEAR_EXP_L].u32Data = (u32IntTime[0] & 0xFF); + + return CVI_SUCCESS; +} + +static CVI_U32 regValTable[29][13] = { + //0x00d0 0x0155 0x0410 0x0411 0x0412 0x0413 0x0414 0x0415 0x0416 0x0417 0x00b8 0x00b9 0x0dc1 + {0x00, 0x03, 0x11, 0x11, 0x11, 0x11, 0x6f, 0x6f, 0x6f, 0x6f, 0x01, 0x00, 0x00}, + {0x10, 0x03, 0x11, 0x11, 0x11, 0x11, 0x6f, 0x6f, 0x6f, 0x6f, 0x01, 0x0c, 0x00}, + {0x01, 0x03, 0x11, 0x11, 0x11, 0x11, 0x6f, 0x6f, 0x6f, 0x6f, 0x01, 0x1a, 0x00}, + {0x11, 0x03, 0x11, 0x11, 0x11, 0x11, 0x6f, 0x6f, 0x6f, 0x6f, 0x01, 0x2b, 0x00}, + {0x02, 0x03, 0x11, 0x11, 0x11, 0x11, 0x6f, 0x6f, 0x6f, 0x6f, 0x02, 0x00, 0x00}, + {0x12, 0x03, 0x11, 0x11, 0x11, 0x11, 0x6f, 0x6f, 0x6f, 0x6f, 0x02, 0x18, 0x00}, + {0x03, 0x03, 0x11, 0x11, 0x11, 0x11, 0x6f, 0x6f, 0x6f, 0x6f, 0x02, 0x33, 0x00}, + {0x13, 0x03, 0x11, 0x11, 0x11, 0x11, 0x6f, 0x6f, 0x6f, 0x6f, 0x03, 0x15, 0x00}, + {0x04, 0x03, 0x11, 0x11, 0x11, 0x11, 0x6f, 0x6f, 0x6f, 0x6f, 0x04, 0x00, 0x00}, + {0x14, 0x03, 0x11, 0x11, 0x11, 0x11, 0x6f, 0x6f, 0x6f, 0x6f, 0x04, 0xe0, 0x00}, + {0x05, 0x03, 0x11, 0x11, 0x11, 0x11, 0x6f, 0x6f, 0x6f, 0x6f, 0x05, 0x26, 0x00}, + {0x15, 0x03, 0x11, 0x11, 0x11, 0x11, 0x6f, 0x6f, 0x6f, 0x6f, 0x06, 0x2b, 0x00}, + {0x44, 0x03, 0x11, 0x11, 0x11, 0x11, 0x6f, 0x6f, 0x6f, 0x6f, 0x08, 0x00, 0x00}, + {0x54, 0x03, 0x11, 0x11, 0x11, 0x11, 0x6f, 0x6f, 0x6f, 0x6f, 0x09, 0x22, 0x00}, + {0x45, 0x03, 0x11, 0x11, 0x11, 0x11, 0x6f, 0x6f, 0x6f, 0x6f, 0x0b, 0x0d, 0x00}, + {0x55, 0x03, 0x11, 0x11, 0x11, 0x11, 0x6f, 0x6f, 0x6f, 0x6f, 0x0d, 0x16, 0x00}, + {0x04, 0x19, 0x16, 0x16, 0x16, 0x16, 0x6f, 0x6f, 0x6f, 0x6f, 0x10, 0x00, 0x01}, + {0x14, 0x19, 0x16, 0x16, 0x16, 0x16, 0x6f, 0x6f, 0x6f, 0x6f, 0x13, 0x04, 0x01}, + {0x24, 0x19, 0x16, 0x16, 0x16, 0x16, 0x6f, 0x6f, 0x6f, 0x6f, 0x16, 0x1a, 0x01}, + {0x34, 0x19, 0x16, 0x16, 0x16, 0x16, 0x6f, 0x6f, 0x6f, 0x6f, 0x1a, 0x2b, 0x01}, + {0x44, 0x36, 0x18, 0x18, 0x18, 0x18, 0x6f, 0x6f, 0x6f, 0x6f, 0x20, 0x00, 0x01}, + {0x54, 0x36, 0x18, 0x18, 0x18, 0x18, 0x6f, 0x6f, 0x6f, 0x6f, 0x26, 0x07, 0x01}, + {0x64, 0x36, 0x18, 0x18, 0x18, 0x18, 0x6f, 0x6f, 0x6f, 0x6f, 0x2c, 0x33, 0x01}, + {0x74, 0x36, 0x18, 0x18, 0x18, 0x18, 0x6f, 0x6f, 0x6f, 0x6f, 0x35, 0x17, 0x01}, + {0x84, 0x64, 0x16, 0x16, 0x16, 0x16, 0x72, 0x72, 0x72, 0x72, 0x35, 0x17, 0x01}, + {0x94, 0x64, 0x16, 0x16, 0x16, 0x16, 0x72, 0x72, 0x72, 0x72, 0x35, 0x17, 0x01}, + {0x85, 0x64, 0x16, 0x16, 0x16, 0x16, 0x72, 0x72, 0x72, 0x72, 0x35, 0x17, 0x01}, + {0x95, 0x64, 0x16, 0x16, 0x16, 0x16, 0x72, 0x72, 0x72, 0x72, 0x35, 0x17, 0x01}, + {0xa5, 0x64, 0x16, 0x16, 0x16, 0x16, 0x72, 0x72, 0x72, 0x72, 0x35, 0x17, 0x01}, +}; + +static CVI_U32 gain_table[29] = { + 64*16, + 76*16, + 90*16, + 107*16, + 128*16, + 152*16, + 179*16, + 213*16, + 256*16, + 305*16, + 358*16, + 427*16, + 512*16, + 610*16, + 717*16, + 854*16, + 1024*16, + 1220*16, + 1434*16, + 1707*16, + 2048*16, + 2439*16, + 2867*16, + 3415*16, + 4096*16, + 4878*16, + 5734*16, + 6830*16, + 8028*16, +}; + +static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb) +{ + int i, total; + CVI_U32 pregain; + + UNUSED(ViPipe); + CMOS_CHECK_POINTER(pu32AgainLin); + CMOS_CHECK_POINTER(pu32AgainDb); + + total = sizeof(gain_table) / sizeof(CVI_U32); + + if (*pu32AgainLin >= gain_table[total - 1]) { + *pu32AgainLin = *pu32AgainDb = gain_table[total - 1]; + return CVI_SUCCESS; + } + + for (i = 1; i < total; i++) { + if (*pu32AgainLin < gain_table[i]) + break; + } + i--; + // find the pregain + pregain = *pu32AgainLin * 64 / gain_table[i]; + // set the Db as the AE algo gain, we need this to do gain update + *pu32AgainDb = *pu32AgainLin; + // set the Lin as the closest sensor gain for AE algo reference + *pu32AgainLin = pregain * gain_table[i] / 64; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb) +{ + CVI_U32 pregain; + + UNUSED(ViPipe); + CMOS_CHECK_POINTER(pu32DgainLin); + CMOS_CHECK_POINTER(pu32DgainDb); + + // find the pregain + pregain = *pu32DgainLin * 64 / 1024; + // set the Db as the AE algo gain, we need this to do gain update + *pu32DgainDb = *pu32DgainLin; + // set the Lin as the closest sensor gain for AE algo reference + *pu32DgainLin = pregain * 16; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_gains_update(VI_PIPE ViPipe, CVI_U32 *pu32Again, CVI_U32 *pu32Dgain) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + CVI_U32 u32Again; + CVI_U32 u32Dgain; + int i, total; + + total = sizeof(gain_table) / sizeof(CVI_U32); + + GC2083_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pu32Again); + CMOS_CHECK_POINTER(pu32Dgain); + pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg; + + /* only surpport linear mode */ + u32Again = pu32Again[0]; + /* To kepp the linearity. we assume AE algo adjusts the dgain only when the again reachs the maximum value */ + if (u32Again < (8028*16)) { + for (i = 1; i < total; i++) { + if (*pu32Again < gain_table[i]) + break; + } + i--; + // find the pregain + u32Dgain = u32Again * 64 / gain_table[i]; + u32Again = i; + } else { + u32Again = total - 1; + // find the pregain + u32Dgain = pu32Dgain[0] * 64 / 1024; + } + + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_L].u32Data = regValTable[u32Again][0]; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_MAG1].u32Data = regValTable[u32Again][1]; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_MAG2].u32Data = regValTable[u32Again][2]; + + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_MAG3].u32Data = regValTable[u32Again][3]; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_MAG4].u32Data = regValTable[u32Again][4]; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_MAG5].u32Data = regValTable[u32Again][5]; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_MAG6].u32Data = regValTable[u32Again][6]; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_MAG7].u32Data = regValTable[u32Again][7]; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_MAG8].u32Data = regValTable[u32Again][8]; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_MAG9].u32Data = regValTable[u32Again][9]; + + pstSnsRegsInfo->astI2cData[LINEAR_COL_AGAIN_H].u32Data = regValTable[u32Again][10]; + pstSnsRegsInfo->astI2cData[LINEAR_COL_AGAIN_L].u32Data = regValTable[u32Again][11]; + + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_HOLD_2E].u32Data = 0x2e; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_H].u32Data = regValTable[u32Again][12]; + pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_HOLD_28].u32Data = 0x28; + + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_H].u32Data = (u32Dgain >> 6); + pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_L].u32Data = (u32Dgain & 0x3F) << 2; + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_ae_exp_function(AE_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AE_SENSOR_EXP_FUNC_S)); + pstExpFuncs->pfn_cmos_get_ae_default = cmos_get_ae_default; + pstExpFuncs->pfn_cmos_fps_set = cmos_fps_set; + pstExpFuncs->pfn_cmos_inttime_update = cmos_inttime_update; + pstExpFuncs->pfn_cmos_gains_update = cmos_gains_update; + pstExpFuncs->pfn_cmos_again_calc_table = cmos_again_calc_table; + pstExpFuncs->pfn_cmos_dgain_calc_table = cmos_dgain_calc_table; + //pstExpFuncs->pfn_cmos_get_inttime_max = cmos_get_inttime_max; + //pstExpFuncs->pfn_cmos_ae_fswdr_attr_set = cmos_ae_fswdr_attr_set; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_awb_default(VI_PIPE ViPipe, AWB_SENSOR_DEFAULT_S *pstAwbSnsDft) +{ + CMOS_CHECK_POINTER(pstAwbSnsDft); + UNUSED(ViPipe); + + memset(pstAwbSnsDft, 0, sizeof(AWB_SENSOR_DEFAULT_S)); + + pstAwbSnsDft->u16InitGgain = 1024; + pstAwbSnsDft->u8AWBRunInterval = 1; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_awb_exp_function(AWB_SENSOR_EXP_FUNC_S *pstExpFuncs) +{ + CMOS_CHECK_POINTER(pstExpFuncs); + + memset(pstExpFuncs, 0, sizeof(AWB_SENSOR_EXP_FUNC_S)); + + pstExpFuncs->pfn_cmos_get_awb_default = cmos_get_awb_default; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_isp_default(VI_PIPE ViPipe, ISP_CMOS_DEFAULT_S *pstDef) +{ + UNUSED(ViPipe); + memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S)); + + memcpy(pstDef->stNoiseCalibration.CalibrationCoef, + &g_stIspNoiseCalibratio, sizeof(ISP_CMOS_NOISE_CALIBRATION_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc) +{ + CMOS_CHECK_POINTER(pstBlc); + UNUSED(ViPipe); + + memset(pstBlc, 0, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + + memcpy(pstBlc, + &g_stIspBlcCalibratio, sizeof(ISP_CMOS_BLACK_LEVEL_S)); + return CVI_SUCCESS; +} + +static CVI_S32 cmos_get_wdr_size(VI_PIPE ViPipe, ISP_SNS_ISP_INFO_S *pstIspCfg) +{ + const GC2083_MODE_S *pstMode = CVI_NULL; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC2083_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstMode = &g_stGc2083_mode[pstSnsState->u8ImgMode]; + pstIspCfg->frm_num = 1; + memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S)); + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC2083_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + pstSnsState->bSyncInit = CVI_FALSE; + + switch (u8Mode) { + case WDR_MODE_NONE: + pstSnsState->u8ImgMode = GC2083_MODE_1920X1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_stGc2083_mode[pstSnsState->u8ImgMode].u32VtsDef; + syslog(LOG_INFO, "WDR_MODE_NONE\n"); + break; + + case WDR_MODE_2To1_LINE: + default: + CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport sensor mode!\n"); + return CVI_FAILURE; + } + + pstSnsState->au32FL[0] = pstSnsState->u32FLStd; + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + memset(pstSnsState->au32WDRIntTime, 0, sizeof(pstSnsState->au32WDRIntTime)); + + return CVI_SUCCESS; +} + +static CVI_U32 sensor_cmp_wdr_size(ISP_SNS_ISP_INFO_S *pstWdr1, ISP_SNS_ISP_INFO_S *pstWdr2) +{ + CVI_U32 i; + + if (pstWdr1->frm_num != pstWdr2->frm_num) + goto _mismatch; + for (i = 0; i < 2; i++) { + if (pstWdr1->img_size[i].stSnsSize.u32Width != pstWdr2->img_size[i].stSnsSize.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stSnsSize.u32Height != pstWdr2->img_size[i].stSnsSize.u32Height) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32X != pstWdr2->img_size[i].stWndRect.s32X) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.s32Y != pstWdr2->img_size[i].stWndRect.s32Y) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Width != pstWdr2->img_size[i].stWndRect.u32Width) + goto _mismatch; + if (pstWdr1->img_size[i].stWndRect.u32Height != pstWdr2->img_size[i].stWndRect.u32Height) + goto _mismatch; + } + + return 0; +_mismatch: + return 1; +} + +static CVI_S32 cmos_get_sns_regs_info(VI_PIPE ViPipe, ISP_SNS_SYNC_INFO_S *pstSnsSyncInfo) +{ + CVI_U32 i; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg0 = CVI_NULL; + ISP_SNS_SYNC_INFO_S *pstCfg1 = CVI_NULL; + ISP_I2C_DATA_S *pstI2c_data = CVI_NULL; + + CMOS_CHECK_POINTER(pstSnsSyncInfo); + GC2083_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + pstSnsRegsInfo = &pstSnsSyncInfo->snsCfg; + pstCfg0 = &pstSnsState->astSyncInfo[0]; + pstCfg1 = &pstSnsState->astSyncInfo[1]; + pstI2c_data = pstCfg0->snsCfg.astI2cData; + + if ((pstSnsState->bSyncInit == CVI_FALSE) || (pstSnsRegsInfo->bConfig == CVI_FALSE)) { + pstCfg0->snsCfg.enSnsType = SNS_I2C_TYPE; + pstCfg0->snsCfg.unComBus.s8I2cDev = g_aunGc2083_BusInfo[ViPipe].s8I2cDev; + pstCfg0->snsCfg.u8Cfg2ValidDelayMax = 0; + pstCfg0->snsCfg.use_snsr_sram = CVI_TRUE; + pstCfg0->snsCfg.u32RegNum = LINEAR_REGS_NUM; + + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + pstI2c_data[i].bUpdate = CVI_TRUE; + pstI2c_data[i].u8DevAddr = gc2083_i2c_addr; + pstI2c_data[i].u32AddrByteNum = gc2083_addr_byte; + pstI2c_data[i].u32DataByteNum = gc2083_data_byte; + } + + pstI2c_data[LINEAR_EXP_H].u32RegAddr = GC2083_EXP_H_ADDR; + pstI2c_data[LINEAR_EXP_L].u32RegAddr = GC2083_EXP_L_ADDR; + + pstI2c_data[LINEAR_AGAIN_L].u32RegAddr = GC2083_AGAIN_L_ADDR; + + pstI2c_data[LINEAR_AGAIN_MAG1].u32RegAddr = GC2083_AGAIN_MAG1; + pstI2c_data[LINEAR_AGAIN_MAG2].u32RegAddr = GC2083_AGAIN_MAG2; + pstI2c_data[LINEAR_AGAIN_MAG3].u32RegAddr = GC2083_AGAIN_MAG3; + pstI2c_data[LINEAR_AGAIN_MAG4].u32RegAddr = GC2083_AGAIN_MAG4; + pstI2c_data[LINEAR_AGAIN_MAG5].u32RegAddr = GC2083_AGAIN_MAG5; + pstI2c_data[LINEAR_AGAIN_MAG6].u32RegAddr = GC2083_AGAIN_MAG6; + pstI2c_data[LINEAR_AGAIN_MAG7].u32RegAddr = GC2083_AGAIN_MAG7; + pstI2c_data[LINEAR_AGAIN_MAG8].u32RegAddr = GC2083_AGAIN_MAG8; + pstI2c_data[LINEAR_AGAIN_MAG9].u32RegAddr = GC2083_AGAIN_MAG9; + + pstI2c_data[LINEAR_COL_AGAIN_H].u32RegAddr = GC2083_COL_AGAIN_H_ADDR; + pstI2c_data[LINEAR_COL_AGAIN_L].u32RegAddr = GC2083_COL_AGAIN_L_ADDR; + + pstI2c_data[LINEAR_AGAIN_HOLD_2E].u32RegAddr = GC2083_AGAIN_HOLD; + pstI2c_data[LINEAR_AGAIN_H].u32RegAddr = GC2083_AGAIN_H_ADDR; + pstI2c_data[LINEAR_AGAIN_HOLD_28].u32RegAddr = GC2083_AGAIN_HOLD; + + pstI2c_data[LINEAR_DGAIN_H].u32RegAddr = GC2083_DGAIN_H_ADDR; + pstI2c_data[LINEAR_DGAIN_L].u32RegAddr = GC2083_DGAIN_L_ADDR; + + pstI2c_data[LINEAR_VTS_H].u32RegAddr = GC2083_VTS_H_ADDR; + pstI2c_data[LINEAR_VTS_L].u32RegAddr = GC2083_VTS_L_ADDR; + + pstSnsState->bSyncInit = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + /* recalcualte WDR size */ + cmos_get_wdr_size(ViPipe, &pstCfg0->ispCfg); + pstCfg0->ispCfg.need_update = CVI_TRUE; + } else { + + CVI_U32 gainsUpdate = 0, shutterUpdate = 0, vtsUpdate = 0; + + pstCfg0->snsCfg.need_update = CVI_FALSE; + for (i = 0; i < pstCfg0->snsCfg.u32RegNum; i++) { + if (pstCfg0->snsCfg.astI2cData[i].u32Data == pstCfg1->snsCfg.astI2cData[i].u32Data) { + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_FALSE; + } else { + + if ((i >= LINEAR_AGAIN_H) && (i <= LINEAR_DGAIN_L)) + gainsUpdate = 1; + + if (i <= LINEAR_EXP_L) + shutterUpdate = 1; + + if ((i >= LINEAR_VTS_H) && (i <= LINEAR_VTS_L)) + vtsUpdate = 1; + + pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.need_update = CVI_TRUE; + } + } + + if (gainsUpdate) { + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_L].bUpdate = CVI_TRUE; + + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_MAG1].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_MAG2].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_MAG3].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_MAG4].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_MAG5].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_MAG6].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_MAG7].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_MAG8].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_MAG9].bUpdate = CVI_TRUE; + + pstCfg0->snsCfg.astI2cData[LINEAR_COL_AGAIN_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_COL_AGAIN_L].bUpdate = CVI_TRUE; + + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_HOLD_2E].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_HOLD_28].bUpdate = CVI_TRUE; + + pstCfg0->snsCfg.astI2cData[LINEAR_DGAIN_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_DGAIN_L].bUpdate = CVI_TRUE; + } + + if (shutterUpdate) { + pstCfg0->snsCfg.astI2cData[LINEAR_EXP_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_EXP_L].bUpdate = CVI_TRUE; + } + + if (vtsUpdate) { + pstCfg0->snsCfg.astI2cData[LINEAR_VTS_H].bUpdate = CVI_TRUE; + pstCfg0->snsCfg.astI2cData[LINEAR_VTS_L].bUpdate = CVI_TRUE; + } + + pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ? + CVI_TRUE : CVI_FALSE); + // pstCfg0->ispCfg.u8DelayFrmNum = 1; + } + + pstSnsRegsInfo->bConfig = CVI_FALSE; + + memcpy(pstSnsSyncInfo, &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + memcpy(&pstSnsState->astSyncInfo[1], &pstSnsState->astSyncInfo[0], sizeof(ISP_SNS_SYNC_INFO_S)); + pstSnsState->au32FL[1] = pstSnsState->au32FL[0]; + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_set_image_mode(VI_PIPE ViPipe, ISP_CMOS_SENSOR_IMAGE_MODE_S *pstSensorImageMode) +{ + CVI_U8 u8SensorImageMode = 0; + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + CMOS_CHECK_POINTER(pstSensorImageMode); + GC2083_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + + u8SensorImageMode = pstSnsState->u8ImgMode; + pstSnsState->bSyncInit = CVI_FALSE; + + if (pstSensorImageMode->f32Fps <= 30) { + if (pstSnsState->enWDRMode == WDR_MODE_NONE) { + if (GC2083_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) + u8SensorImageMode = GC2083_MODE_1920X1080P30; + else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support! Width:%d, Height:%d, Fps:%f, WDRMode:%d\n", + pstSensorImageMode->u16Width, + pstSensorImageMode->u16Height, + pstSensorImageMode->f32Fps, + pstSnsState->enWDRMode); + return CVI_FAILURE; + } + } else { + CVI_TRACE_SNS(CVI_DBG_ERR, "Not support this Fps:%f\n", pstSensorImageMode->f32Fps); + return CVI_FAILURE; + } + + if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) { + /* Don't need to switch SensorImageMode */ + return CVI_FAILURE; + } + + pstSnsState->u8ImgMode = u8SensorImageMode; + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC2083_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + /* Apply the setting on the fly */ + if (pstSnsState->bInit == CVI_TRUE && g_aeGc2083_MirrorFip[ViPipe] != eSnsMirrorFlip) { + gc2083_mirror_flip(ViPipe, eSnsMirrorFlip); + g_aeGc2083_MirrorFip[ViPipe] = eSnsMirrorFlip; + } +} + +static CVI_VOID sensor_global_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC2083_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER_VOID(pstSnsState); + + pstSnsState->bInit = CVI_FALSE; + pstSnsState->bSyncInit = CVI_FALSE; + pstSnsState->u8ImgMode = GC2083_MODE_1920X1080P30; + pstSnsState->enWDRMode = WDR_MODE_NONE; + pstSnsState->u32FLStd = g_stGc2083_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsState->au32FL[0] = g_stGc2083_mode[pstSnsState->u8ImgMode].u32VtsDef; + pstSnsState->au32FL[1] = g_stGc2083_mode[pstSnsState->u8ImgMode].u32VtsDef; + + memset(&pstSnsState->astSyncInfo[0], 0, sizeof(ISP_SNS_SYNC_INFO_S)); + memset(&pstSnsState->astSyncInfo[1], 0, sizeof(ISP_SNS_SYNC_INFO_S)); +} + +static CVI_S32 sensor_rx_attr(VI_PIPE ViPipe, SNS_COMBO_DEV_ATTR_S *pstRxAttr) +{ + ISP_SNS_STATE_S *pstSnsState = CVI_NULL; + + GC2083_SENSOR_GET_CTX(ViPipe, pstSnsState); + CMOS_CHECK_POINTER(pstSnsState); + CMOS_CHECK_POINTER(pstRxAttr); + + memcpy(pstRxAttr, &gc2083_rx_attr, sizeof(*pstRxAttr)); + + pstRxAttr->img_size.width = g_stGc2083_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width; + pstRxAttr->img_size.height = g_stGc2083_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Height; + if (pstSnsState->enWDRMode == WDR_MODE_NONE) + pstRxAttr->mipi_attr.wdr_mode = CVI_MIPI_WDR_MODE_NONE; + + return CVI_SUCCESS; + +} + +static CVI_S32 sensor_patch_rx_attr(RX_INIT_ATTR_S *pstRxInitAttr) +{ + SNS_COMBO_DEV_ATTR_S *pstRxAttr = &gc2083_rx_attr; + int i; + + CMOS_CHECK_POINTER(pstRxInitAttr); + + if (pstRxInitAttr->stMclkAttr.bMclkEn) + pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk; + + if (pstRxInitAttr->MipiDev >= VI_MAX_DEV_NUM) + return CVI_SUCCESS; + + pstRxAttr->devno = pstRxInitAttr->MipiDev; + + if (pstRxAttr->input_mode == INPUT_MODE_MIPI) { + struct mipi_dev_attr_s *attr = &pstRxAttr->mipi_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } else { + struct lvds_dev_attr_s *attr = &pstRxAttr->lvds_attr; + + for (i = 0; i < MIPI_LANE_NUM + 1; i++) { + attr->lane_id[i] = pstRxInitAttr->as16LaneId[i]; + attr->pn_swap[i] = pstRxInitAttr->as8PNSwap[i]; + } + } + + return CVI_SUCCESS; +} + +static CVI_S32 cmos_init_sensor_exp_function(ISP_SENSOR_EXP_FUNC_S *pstSensorExpFunc) +{ + CMOS_CHECK_POINTER(pstSensorExpFunc); + + memset(pstSensorExpFunc, 0, sizeof(ISP_SENSOR_EXP_FUNC_S)); + + pstSensorExpFunc->pfn_cmos_sensor_init = gc2083_init; + pstSensorExpFunc->pfn_cmos_sensor_exit = gc2083_exit; + pstSensorExpFunc->pfn_cmos_sensor_global_init = sensor_global_init; + pstSensorExpFunc->pfn_cmos_set_image_mode = cmos_set_image_mode; + pstSensorExpFunc->pfn_cmos_set_wdr_mode = cmos_set_wdr_mode; + pstSensorExpFunc->pfn_cmos_get_isp_default = cmos_get_isp_default; + pstSensorExpFunc->pfn_cmos_get_isp_black_level = cmos_get_blc_default; + pstSensorExpFunc->pfn_cmos_get_sns_reg_info = cmos_get_sns_regs_info; + + return CVI_SUCCESS; +} + +/**************************************************************************** + * callback structure * + ****************************************************************************/ +static CVI_VOID sensor_patch_i2c_addr(CVI_S32 s32I2cAddr) +{ + if (GC2083_I2C_ADDR_IS_VALID(s32I2cAddr)) + gc2083_i2c_addr = s32I2cAddr; +} + +static CVI_S32 gc2083_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo) +{ + g_aunGc2083_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + GC2083_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + + if (pastSnsStateCtx == CVI_NULL) { + pastSnsStateCtx = (ISP_SNS_STATE_S *)malloc(sizeof(ISP_SNS_STATE_S)); + if (pastSnsStateCtx == CVI_NULL) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Isp[%d] SnsCtx malloc memory failed!\n", ViPipe); + return -ENOMEM; + } + } + + memset(pastSnsStateCtx, 0, sizeof(ISP_SNS_STATE_S)); + + GC2083_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx); + + return CVI_SUCCESS; +} + +static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe) +{ + ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL; + + GC2083_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx); + SENSOR_FREE(pastSnsStateCtx); + GC2083_SENSOR_RESET_CTX(ViPipe); +} + +static CVI_S32 sensor_register_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + ISP_SENSOR_REGISTER_S stIspRegister; + AE_SENSOR_REGISTER_S stAeRegister; + AWB_SENSOR_REGISTER_S stAwbRegister; + ISP_SNS_ATTR_INFO_S stSnsAttrInfo; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = sensor_ctx_init(ViPipe); + + if (s32Ret != CVI_SUCCESS) + return CVI_FAILURE; + + stSnsAttrInfo.eSensorId = GC2083_ID; + + s32Ret = cmos_init_sensor_exp_function(&stIspRegister.stSnsExp); + s32Ret |= CVI_ISP_SensorRegCallBack(ViPipe, &stSnsAttrInfo, &stIspRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_ae_exp_function(&stAeRegister.stAeExp); + s32Ret |= CVI_AE_SensorRegCallBack(ViPipe, pstAeLib, &stSnsAttrInfo, &stAeRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = cmos_init_awb_exp_function(&stAwbRegister.stAwbExp); + s32Ret |= CVI_AWB_SensorRegCallBack(ViPipe, pstAwbLib, &stSnsAttrInfo, &stAwbRegister); + + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor register callback function to awb lib failed!\n"); + return s32Ret; + } + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_unregister_callback(VI_PIPE ViPipe, ALG_LIB_S *pstAeLib, ALG_LIB_S *pstAwbLib) +{ + CVI_S32 s32Ret; + + CMOS_CHECK_POINTER(pstAeLib); + CMOS_CHECK_POINTER(pstAwbLib); + + s32Ret = CVI_ISP_SensorUnRegCallBack(ViPipe, GC2083_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AE_SensorUnRegCallBack(ViPipe, pstAeLib, GC2083_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to ae lib failed!\n"); + return s32Ret; + } + + s32Ret = CVI_AWB_SensorUnRegCallBack(ViPipe, pstAwbLib, GC2083_ID); + if (s32Ret != CVI_SUCCESS) { + CVI_TRACE_SNS(CVI_DBG_ERR, "sensor unregister callback function to awb lib failed!\n"); + return s32Ret; + } + + sensor_ctx_exit(ViPipe); + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_set_init(VI_PIPE ViPipe, ISP_INIT_ATTR_S *pstInitAttr) +{ + CMOS_CHECK_POINTER(pstInitAttr); + + g_au32InitExposure[ViPipe] = pstInitAttr->u32Exposure; + g_au32LinesPer500ms[ViPipe] = pstInitAttr->u32LinesPer500ms; + g_au16InitWBGain[ViPipe][0] = pstInitAttr->u16WBRgain; + g_au16InitWBGain[ViPipe][1] = pstInitAttr->u16WBGgain; + g_au16InitWBGain[ViPipe][2] = pstInitAttr->u16WBBgain; + g_au16SampleRgain[ViPipe] = pstInitAttr->u16SampleRgain; + g_au16SampleBgain[ViPipe] = pstInitAttr->u16SampleBgain; + g_au16Gc2083_GainMode[ViPipe] = pstInitAttr->enGainMode; + g_au16Gc2083_L2SMode[ViPipe] = pstInitAttr->enL2SMode; + + return CVI_SUCCESS; +} + +static CVI_S32 sensor_probe(VI_PIPE ViPipe) +{ + return gc2083_probe(ViPipe); +} + +ISP_SNS_OBJ_S stSnsGc2083_Obj = { + .pfnRegisterCallback = sensor_register_callback, + .pfnUnRegisterCallback = sensor_unregister_callback, + .pfnStandby = gc2083_standby, + .pfnRestart = gc2083_restart, + .pfnWriteReg = gc2083_write_register, + .pfnReadReg = gc2083_read_register, + .pfnSetBusInfo = gc2083_set_bus_info, + .pfnSetInit = sensor_set_init, + .pfnMirrorFlip = sensor_mirror_flip, + .pfnPatchRxAttr = sensor_patch_rx_attr, + .pfnPatchI2cAddr = sensor_patch_i2c_addr, + .pfnGetRxAttr = sensor_rx_attr, + .pfnExpSensorCb = cmos_init_sensor_exp_function, + .pfnExpAeCb = cmos_init_ae_exp_function, + .pfnSnsProbe = sensor_probe, +}; \ No newline at end of file diff --git a/middleware/v2/component/isp/sensor/cv181x/gcore_gc2083/gc2083_cmos_ex.h b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2083/gc2083_cmos_ex.h new file mode 100644 index 000000000..ad3205b82 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2083/gc2083_cmos_ex.h @@ -0,0 +1,107 @@ +#ifndef __GC2083_CMOS_EX_H_ +#define __GC2083_CMOS_EX_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" + +#ifndef UNUSED +#define UNUSED(x) ((void)(x)) +#endif + +enum gc2083_linear_regs_e { + LINEAR_EXP_H, //0x0d03 + LINEAR_EXP_L, //0x0d04 + + LINEAR_AGAIN_L, //0x00d0 + LINEAR_AGAIN_MAG1, //0x0155 + LINEAR_AGAIN_MAG2, //0x0410 + LINEAR_AGAIN_MAG3, //0x0411 + LINEAR_AGAIN_MAG4, //0x0412 + LINEAR_AGAIN_MAG5, //0x0413 + LINEAR_AGAIN_MAG6, //0x0414 + LINEAR_AGAIN_MAG7, //0x0415 + LINEAR_AGAIN_MAG8, //0x0416 + LINEAR_AGAIN_MAG9, //0x0417 + + LINEAR_COL_AGAIN_H, //0x00b8 + LINEAR_COL_AGAIN_L, //0x00b9 + + + LINEAR_AGAIN_HOLD_2E, // 0x031d + LINEAR_AGAIN_H, //0x0dc1 + LINEAR_AGAIN_HOLD_28, // 0x031d + + LINEAR_DGAIN_H, //0x00b1 + LINEAR_DGAIN_L, //0x00b2 + + LINEAR_VTS_H, //0x0d41 (frame length) + LINEAR_VTS_L, //0x0d42 + + LINEAR_REGS_NUM + +}; + + +typedef enum _GC2083_MODE_E { + GC2083_MODE_1920X1080P30 = 0, + GC2083_MODE_NUM +} GC2083_SLAVE_MODE_E; + +typedef struct _GC2083_STATE_S { + CVI_U32 u32Sexp_MAX; +} GC2083_STATE_S; + +typedef struct _GC2083_MODE_S { + ISP_WDR_SIZE_S astImg[2]; + CVI_FLOAT f32MaxFps; + CVI_FLOAT f32MinFps; + CVI_U32 u32HtsDef; + CVI_U32 u32VtsDef; + SNS_ATTR_S stExp[2]; + SNS_ATTR_LARGE_S stAgain[2]; + SNS_ATTR_LARGE_S stDgain[2]; + char name[64]; +} GC2083_MODE_S; + +/**************************************************************************** + * external variables and functions * + ****************************************************************************/ + +extern ISP_SNS_STATE_S *g_pastGc2083[VI_MAX_PIPE_NUM]; +extern ISP_SNS_COMMBUS_U g_aunGc2083_BusInfo[]; +extern ISP_SNS_MIRRORFLIP_TYPE_E g_aeGc2083_MirrorFip[VI_MAX_PIPE_NUM]; +extern CVI_U8 gc2083_i2c_addr; +extern const CVI_U32 gc2083_addr_byte; +extern const CVI_U32 gc2083_data_byte; +extern void gc2083_init(VI_PIPE ViPipe); +extern void gc2083_exit(VI_PIPE ViPipe); +extern void gc2083_standby(VI_PIPE ViPipe); +extern void gc2083_restart(VI_PIPE ViPipe); +extern int gc2083_write_register(VI_PIPE ViPipe, int addr, int data); +extern int gc2083_read_register(VI_PIPE ViPipe, int addr); +extern void gc2083_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip); +extern int gc2083_probe(VI_PIPE ViPipe); + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __GC2083_CMOS_EX_H_ */ + diff --git a/middleware/v2/component/isp/sensor/cv181x/gcore_gc2083/gc2083_cmos_param.h b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2083/gc2083_cmos_param.h new file mode 100644 index 000000000..f0fb67262 --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2083/gc2083_cmos_param.h @@ -0,0 +1,222 @@ +#ifndef __GC2083_CMOS_PARAM_H_ +#define __GC2083_CMOS_PARAM_H_ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif + +#ifdef ARCH_CV182X +#include +#include +#include "cvi_type.h" +#else +#include +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "gc2083_cmos_ex.h" + +static const GC2083_MODE_S g_stGc2083_mode[GC2083_MODE_NUM] = { + [GC2083_MODE_1920X1080P30] = { + .name = "1920X1080P30", + .astImg[0] = { + .stSnsSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + .stWndRect = { + .s32X = 0, + .s32Y = 0, + .u32Width = 1920, + .u32Height = 1080, + }, + .stMaxSize = { + .u32Width = 1920, + .u32Height = 1080, + }, + }, + .f32MaxFps = 30, + .f32MinFps = 2.07, /* 1125 * 30 / 0x3FFF */ + .u32HtsDef = 2200, + .u32VtsDef = 1125, + .stExp[0] = { + .u16Min = 1, + .u16Max = 1125 - 8, + .u16Def = 400, + .u16Step = 1, + }, + .stAgain[0] = { + .u32Min = 64, + .u32Max = 62977, + .u32Def = 64, + .u32Step = 1, + }, + .stDgain[0] = { + .u32Min = 64*16, + .u32Max = 7073*16, + .u32Def = 581*16, + .u32Step = 10*16, + }, + }, +}; + +static ISP_CMOS_NOISE_CALIBRATION_S g_stIspNoiseCalibratio = {.CalibrationCoef = { + { //iso 100 + {0.05999477580189704895, 0.13019448518753051758}, //B: slope, intercept + {0.06732148677110671997, -1.36387133598327636719}, //Gb: slope, intercept + {0.06651904433965682983, -1.10093510150909423828}, //Gr: slope, intercept + {0.06406146287918090820, 0.33316791057586669922}, //R: slope, intercept + }, + { //iso 200 + {0.06256803125143051147, 4.54908418655395507813}, //B: slope, intercept + {0.06911934912204742432, 2.79023528099060058594}, //Gb: slope, intercept + {0.06846688687801361084, 2.88726186752319335938}, //Gr: slope, intercept + {0.06652788817882537842, 4.40276956558227539063}, //R: slope, intercept + }, + { //iso 400 + {0.06841833144426345825, 11.72280883789062500000}, //B: slope, intercept + {0.07257881015539169312, 10.86985683441162109375}, //Gb: slope, intercept + {0.07174283266067504883, 11.20646286010742187500}, //Gr: slope, intercept + {0.07294593751430511475, 11.17350578308105468750}, //R: slope, intercept + }, + { //iso 800 + {0.07805790752172470093, 20.62956619262695312500}, //B: slope, intercept + {0.07694032043218612671, 22.20356750488281250000}, //Gb: slope, intercept + {0.07647507637739181519, 22.50957298278808593750}, //Gr: slope, intercept + {0.08402533829212188721, 19.11953735351562500000}, //R: slope, intercept + }, + { //iso 1600 + {0.09468275308609008789, 34.07563018798828125000}, //B: slope, intercept + {0.08710632473230361938, 39.15500259399414062500}, //Gb: slope, intercept + {0.08662072569131851196, 39.37175750732421875000}, //Gr: slope, intercept + {0.10222808271646499634, 31.34789276123046875000}, //R: slope, intercept + }, + { //iso 3200 + {0.12651191651821136475, 49.56183242797851562500}, //B: slope, intercept + {0.10816962271928787231, 59.42719650268554687500}, //Gb: slope, intercept + {0.10751257836818695068, 59.90552902221679687500}, //Gr: slope, intercept + {0.13802853226661682129, 45.09576034545898437500}, //R: slope, intercept + }, + { //iso 6400 + {0.17422541975975036621, 70.04063415527343750000}, //B: slope, intercept + {0.14234761893749237061, 85.51583862304687500000}, //Gb: slope, intercept + {0.14159946143627166748, 86.23278045654296875000}, //Gr: slope, intercept + {0.19450971484184265137, 62.65447235107421875000}, //R: slope, intercept + }, + { //iso 12800 + {0.24947367608547210693, 108.30633544921875000000}, //B: slope, intercept + {0.19751225411891937256, 130.88159179687500000000}, //Gb: slope, intercept + {0.19614629447460174561, 132.49082946777343750000}, //Gr: slope, intercept + {0.28106108307838439941, 97.15969085693359375000}, //R: slope, intercept + }, + { //iso 25600 + {0.35420843958854675293, 137.06745910644531250000}, //B: slope, intercept + {0.27778801321983337402, 168.72366333007812500000}, //Gb: slope, intercept + {0.27540388703346252441, 170.54939270019531250000}, //Gr: slope, intercept + {0.39949953556060791016, 123.29409790039062500000}, //R: slope, intercept + }, + { //iso 51200 + {0.45704349875450134277, 179.20147705078125000000}, //B: slope, intercept + {0.32142028212547302246, 246.71363830566406250000}, //Gb: slope, intercept + {0.31958609819412231445, 246.82630920410156250000}, //Gr: slope, intercept + {0.51058447360992431641, 161.86299133300781250000}, //R: slope, intercept + }, + { //iso 102400 + {0.61760461330413818359, 222.90534973144531250000}, //B: slope, intercept + {0.42568457126617431641, 319.29257202148437500000}, //Gb: slope, intercept + {0.41750904917716979980, 324.93432617187500000000}, //Gr: slope, intercept + {0.67956107854843139648, 203.78948974609375000000}, //R: slope, intercept + }, + { //iso 204800 + {0.63289469480514526367, 216.99952697753906250000}, //B: slope, intercept + {0.44890350103378295898, 306.80810546875000000000}, //Gb: slope, intercept + {0.44229975342750549316, 310.13763427734375000000}, //Gr: slope, intercept + {0.69596910476684570313, 196.70443725585937500000}, //R: slope, intercept + }, + { //iso 409600 + {0.71106964349746704102, 187.98352050781250000000}, //B: slope, intercept + {0.55859673023223876953, 246.22378540039062500000}, //Gb: slope, intercept + {0.55284017324447631836, 249.86463928222656250000}, //Gr: slope, intercept + {0.77318203449249267578, 168.85035705566406250000}, //R: slope, intercept + }, + { //iso 819200 + {0.70888006687164306641, 188.44216918945312500000}, //B: slope, intercept + {0.56110274791717529297, 245.46603393554687500000}, //Gb: slope, intercept + {0.55100852251052856445, 250.33049011230468750000}, //Gr: slope, intercept + {0.76897650957107543945, 169.31251525878906250000}, //R: slope, intercept + }, + { //iso 1638400 + {0.70520979166030883789, 188.93899536132812500000}, //B: slope, intercept + {0.56178557872772216797, 245.21235656738281250000}, //Gb: slope, intercept + {0.55338454246520996094, 249.57423400878906250000}, //Gr: slope, intercept + {0.77306479215621948242, 168.86497497558593750000}, //R: slope, intercept + }, + { //iso 3276800 + {0.71255809068679809570, 187.86839294433593750000}, //B: slope, intercept + {0.56056070327758789063, 245.57748413085937500000}, //Gb: slope, intercept + {0.55358195304870605469, 249.62020874023437500000}, //Gr: slope, intercept + {0.77431541681289672852, 168.74313354492187500000}, //R: slope, intercept + }, +} }; + +static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = { + .bUpdate = CVI_TRUE, + .blcAttr = { + .Enable = 1, + .enOpType = OP_TYPE_AUTO, + .stManual = {252, 252, 252, 252, 0, 0, 0, 0 +#ifdef ARCH_CV182X + , 1093, 1093, 1093, 1093 +#endif + }, + .stAuto = { + {252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252 }, + {252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252 }, + {252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252 }, + {252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252 }, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, +#ifdef ARCH_CV182X + {1093, 1093, 1093, 1093, 1093, 1093, 1093, 1095, + 1099, 1104, 1125, 1130, 1125, 1127, 1126, 1126}, + {1093, 1093, 1093, 1093, 1093, 1093, 1094, 1095, + 1097, 1104, 1128, 1128, 1126, 1124, 1127, 1127}, + {1093, 1093, 1093, 1093, 1093, 1093, 1094, 1095, + 1098, 1104, 1128, 1131, 1125, 1127, 1128, 1126}, + {1093, 1093, 1093, 1093, 1093, 1093, 1093, 1095, + 1097, 1103, 1123, 1124, 1124, 1123, 1121, 1125}, +#endif + }, + }, +}; + +struct combo_dev_attr_s gc2083_rx_attr = { + .input_mode = INPUT_MODE_MIPI, + .mac_clk = RX_MAC_CLK_200M, + .mipi_attr = { + .raw_data_type = RAW_DATA_10BIT, + .lane_id = {3, 2, 4, -1, -1}, + .pn_swap = {0, 0, 0, 0, 0}, + .wdr_mode = CVI_MIPI_WDR_MODE_NONE, + }, + .mclk = { + .cam = 0, + .freq = CAMPLL_FREQ_24M, + }, + .devno = 0, +}; + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* End of #ifdef __cplusplus */ + + +#endif /* __GC2083_CMOS_PARAM_H_ */ + diff --git a/middleware/v2/component/isp/sensor/cv181x/gcore_gc2083/gc2083_sensor_ctl.c b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2083/gc2083_sensor_ctl.c new file mode 100644 index 000000000..c075dc23e --- /dev/null +++ b/middleware/v2/component/isp/sensor/cv181x/gcore_gc2083/gc2083_sensor_ctl.c @@ -0,0 +1,387 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef ARCH_CV182X +#include +#include "cvi_comm_video.h" +#else +#include +#include +#endif +#include "cvi_sns_ctrl.h" +#include "gc2083_cmos_ex.h" + +static void gc2083_linear_1080p30_init(VI_PIPE ViPipe); + +CVI_U8 gc2083_i2c_addr = 0x37;//0x6e +const CVI_U32 gc2083_addr_byte = 2; +const CVI_U32 gc2083_data_byte = 1; +static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1}; + +int gc2083_i2c_init(VI_PIPE ViPipe) +{ + char acDevFile[16] = {0}; + CVI_U8 u8DevNum; + + if (g_fd[ViPipe] >= 0) + return CVI_SUCCESS; + int ret; + + u8DevNum = g_aunGc2083_BusInfo[ViPipe].s8I2cDev; + snprintf(acDevFile, sizeof(acDevFile), "/dev/i2c-%u", u8DevNum); + + g_fd[ViPipe] = open(acDevFile, O_RDWR, 0600); + + if (g_fd[ViPipe] < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Open /dev/i2c-%u error!\n", u8DevNum); + return CVI_FAILURE; + } + + ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, gc2083_i2c_addr); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_SLAVE_FORCE error!\n"); + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return ret; + } + + return CVI_SUCCESS; +} + +int gc2083_i2c_exit(VI_PIPE ViPipe) +{ + if (g_fd[ViPipe] >= 0) { + close(g_fd[ViPipe]); + g_fd[ViPipe] = -1; + return CVI_SUCCESS; + } + return CVI_FAILURE; +} + +int gc2083_read_register(VI_PIPE ViPipe, int addr) +{ + int ret, data; + CVI_U8 buf[8]; + CVI_U8 idx = 0; + + if (g_fd[ViPipe] < 0) + return CVI_FAILURE; + + if (gc2083_addr_byte == 2) + buf[idx++] = (addr >> 8) & 0xff; + + // add address byte 0 + buf[idx++] = addr & 0xff; + + ret = write(g_fd[ViPipe], buf, gc2083_addr_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return ret; + } + + buf[0] = 0; + buf[1] = 0; + ret = read(g_fd[ViPipe], buf, gc2083_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n"); + return ret; + } + + // pack read back data + data = 0; + if (gc2083_data_byte == 2) { + data = buf[0] << 8; + data += buf[1]; + } else { + data = buf[0]; + } + + syslog(LOG_DEBUG, "i2c r 0x%x = 0x%x\n", addr, data); + return data; +} + +int gc2083_write_register(VI_PIPE ViPipe, int addr, int data) +{ + CVI_U8 idx = 0; + int ret; + CVI_U8 buf[8]; + + if (g_fd[ViPipe] < 0) + return CVI_SUCCESS; + + if (gc2083_addr_byte == 2) { + buf[idx] = (addr >> 8) & 0xff; + idx++; + buf[idx] = addr & 0xff; + idx++; + } + if (gc2083_data_byte == 1) { + buf[idx] = data & 0xff; + idx++; + } + + ret = write(g_fd[ViPipe], buf, gc2083_addr_byte + gc2083_data_byte); + if (ret < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n"); + return CVI_FAILURE; + } + ret = read(g_fd[ViPipe], buf, gc2083_addr_byte + gc2083_data_byte); + //syslog(LOG_DEBUG, "i2c w 0x%x 0x%x\n", addr, data); + return CVI_SUCCESS; +} + +static void delay_ms(int ms) +{ + usleep(ms * 1000); +} + +void gc2083_standby(VI_PIPE ViPipe) +{ + gc2083_write_register(ViPipe, 0x003e, 0x00); + gc2083_write_register(ViPipe, 0x03f7, 0x00); + gc2083_write_register(ViPipe, 0x03fc, 0x01); + gc2083_write_register(ViPipe, 0x03f9, 0x41); + + printf("gc2083_standby\n"); +} + +void gc2083_restart(VI_PIPE ViPipe) +{ + gc2083_write_register(ViPipe, 0x03f9, 0x42); + usleep(1); + gc2083_write_register(ViPipe, 0x03f7, 0x11); + gc2083_write_register(ViPipe, 0x03fc, 0x8e); + gc2083_write_register(ViPipe, 0x003e, 0x91); + + printf("gc2083_restart\n"); +} + +void gc2083_default_reg_init(VI_PIPE ViPipe) +{ + CVI_U32 i; + + for (i = 0; i < g_pastGc2083[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) { + gc2083_write_register(ViPipe, + g_pastGc2083[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr, + g_pastGc2083[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data); + } +} + +#define GC2083_CHIP_ID_ADDR_H 0x03f0 +#define GC2083_CHIP_ID_ADDR_L 0x03f1 +#define GC2083_CHIP_ID 0x2083 + +void gc2083_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip) +{ + CVI_U8 value = 0; + + switch (eSnsMirrorFlip) { + case ISP_SNS_NORMAL: + break; + case ISP_SNS_MIRROR: + value = 0x01; + break; + case ISP_SNS_FLIP: + value = 0x02; + break; + case ISP_SNS_MIRROR_FLIP: + value = 0x03; + break; + default: + return; + } + gc2083_write_register(ViPipe, 0x0015, value); + gc2083_write_register(ViPipe, 0x0d15, value); +} + +int gc2083_probe(VI_PIPE ViPipe) +{ + int nVal; + int nVal2; + + usleep(50); + if (gc2083_i2c_init(ViPipe) != CVI_SUCCESS) + return CVI_FAILURE; + + nVal = gc2083_read_register(ViPipe, GC2083_CHIP_ID_ADDR_H); + nVal2 = gc2083_read_register(ViPipe, GC2083_CHIP_ID_ADDR_L); + if (nVal < 0 || nVal2 < 0) { + CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n"); + return nVal; + } + + if ((((nVal & 0xFF) << 8) | (nVal2 & 0xFF)) != GC2083_CHIP_ID) { + CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n"); + return CVI_FAILURE; + } + + return CVI_SUCCESS; +} + +void gc2083_init(VI_PIPE ViPipe) +{ + + gc2083_i2c_init(ViPipe); + + gc2083_linear_1080p30_init(ViPipe); + + + g_pastGc2083[ViPipe]->bInit = CVI_TRUE; +} + +void gc2083_exit(VI_PIPE ViPipe) +{ + gc2083_i2c_exit(ViPipe); +} + +static void gc2083_linear_1080p30_init(VI_PIPE ViPipe) +{ + delay_ms(10); + /****system****/ + gc2083_write_register(ViPipe, 0x03fe, 0xf0); + gc2083_write_register(ViPipe, 0x03fe, 0xf0); + gc2083_write_register(ViPipe, 0x03fe, 0xf0); + gc2083_write_register(ViPipe, 0x03fe, 0x00); + gc2083_write_register(ViPipe, 0x03f2, 0x00); + gc2083_write_register(ViPipe, 0x03f3, 0x00); + gc2083_write_register(ViPipe, 0x03f4, 0x36); + gc2083_write_register(ViPipe, 0x03f5, 0xc0); + gc2083_write_register(ViPipe, 0x03f6, 0x24); + gc2083_write_register(ViPipe, 0x03f7, 0x01); + gc2083_write_register(ViPipe, 0x03f8, 0x32); + gc2083_write_register(ViPipe, 0x03f9, 0x43); + gc2083_write_register(ViPipe, 0x03fc, 0x8e); + gc2083_write_register(ViPipe, 0x0381, 0x07); + gc2083_write_register(ViPipe, 0x00d7, 0x29); + gc2083_write_register(ViPipe, 0x0d6d, 0x18); + gc2083_write_register(ViPipe, 0x00d5, 0x03); + gc2083_write_register(ViPipe, 0x0082, 0x01); + gc2083_write_register(ViPipe, 0x0db3, 0xd4); + gc2083_write_register(ViPipe, 0x0db0, 0x0d); + gc2083_write_register(ViPipe, 0x0db5, 0x96); + gc2083_write_register(ViPipe, 0x0d03, 0x02); + gc2083_write_register(ViPipe, 0x0d04, 0x02); + gc2083_write_register(ViPipe, 0x0d05, 0x05); + gc2083_write_register(ViPipe, 0x0d06, 0xc9); + gc2083_write_register(ViPipe, 0x0d07, 0x00); + gc2083_write_register(ViPipe, 0x0d08, 0x11); + gc2083_write_register(ViPipe, 0x0d09, 0x00); + gc2083_write_register(ViPipe, 0x0d0a, 0x02); + gc2083_write_register(ViPipe, 0x000b, 0x00); + gc2083_write_register(ViPipe, 0x000c, 0x02); + gc2083_write_register(ViPipe, 0x0d0d, 0x04); + gc2083_write_register(ViPipe, 0x0d0e, 0x40); + gc2083_write_register(ViPipe, 0x000f, 0x07); + gc2083_write_register(ViPipe, 0x0010, 0x90); + gc2083_write_register(ViPipe, 0x0017, 0x0c); + gc2083_write_register(ViPipe, 0x0d73, 0x92); + gc2083_write_register(ViPipe, 0x0d76, 0x00); + gc2083_write_register(ViPipe, 0x0076, 0x00); + gc2083_write_register(ViPipe, 0x0d41, 0x04); + gc2083_write_register(ViPipe, 0x0d42, 0x65); + gc2083_write_register(ViPipe, 0x0d7a, 0x10); + gc2083_write_register(ViPipe, 0x0d19, 0x31); + gc2083_write_register(ViPipe, 0x0d25, 0xcb); + gc2083_write_register(ViPipe, 0x0d20, 0x60); + gc2083_write_register(ViPipe, 0x0d27, 0x03); + gc2083_write_register(ViPipe, 0x0d29, 0x60); + gc2083_write_register(ViPipe, 0x0d43, 0x10); + gc2083_write_register(ViPipe, 0x0d49, 0x10); + gc2083_write_register(ViPipe, 0x0d55, 0x18); + gc2083_write_register(ViPipe, 0x0dc2, 0x44); + gc2083_write_register(ViPipe, 0x0058, 0x3c); + gc2083_write_register(ViPipe, 0x00d8, 0x68); + gc2083_write_register(ViPipe, 0x00d9, 0x14); + gc2083_write_register(ViPipe, 0x00da, 0xc1); + gc2083_write_register(ViPipe, 0x0050, 0x18); + gc2083_write_register(ViPipe, 0x0db6, 0x3d); + gc2083_write_register(ViPipe, 0x00d2, 0xbc); + gc2083_write_register(ViPipe, 0x0d66, 0x42); + gc2083_write_register(ViPipe, 0x008c, 0x07); + gc2083_write_register(ViPipe, 0x008d, 0xff); + gc2083_write_register(ViPipe, 0x007a, 0x50); + gc2083_write_register(ViPipe, 0x00d0, 0x00); + gc2083_write_register(ViPipe, 0x0dc1, 0x00); + gc2083_write_register(ViPipe, 0x0102, 0xa9); + gc2083_write_register(ViPipe, 0x0158, 0x00); + gc2083_write_register(ViPipe, 0x0107, 0xa6); + gc2083_write_register(ViPipe, 0x0108, 0xa9); + gc2083_write_register(ViPipe, 0x0109, 0xa8); + gc2083_write_register(ViPipe, 0x010a, 0xa7); + gc2083_write_register(ViPipe, 0x010b, 0xff); + gc2083_write_register(ViPipe, 0x010c, 0xff); + gc2083_write_register(ViPipe, 0x0428, 0x86); + gc2083_write_register(ViPipe, 0x0429, 0x86); + gc2083_write_register(ViPipe, 0x042a, 0x86); + gc2083_write_register(ViPipe, 0x042b, 0x68); + gc2083_write_register(ViPipe, 0x042c, 0x68); + gc2083_write_register(ViPipe, 0x042d, 0x68); + gc2083_write_register(ViPipe, 0x042e, 0x68); + gc2083_write_register(ViPipe, 0x042f, 0x68); + gc2083_write_register(ViPipe, 0x0430, 0x4f); + gc2083_write_register(ViPipe, 0x0431, 0x68); + gc2083_write_register(ViPipe, 0x0432, 0x67); + gc2083_write_register(ViPipe, 0x0433, 0x66); + gc2083_write_register(ViPipe, 0x0434, 0x66); + gc2083_write_register(ViPipe, 0x0435, 0x66); + gc2083_write_register(ViPipe, 0x0436, 0x66); + gc2083_write_register(ViPipe, 0x0437, 0x66); + gc2083_write_register(ViPipe, 0x0438, 0x62); + gc2083_write_register(ViPipe, 0x0439, 0x62); + gc2083_write_register(ViPipe, 0x043a, 0x62); + gc2083_write_register(ViPipe, 0x043b, 0x62); + gc2083_write_register(ViPipe, 0x043c, 0x62); + gc2083_write_register(ViPipe, 0x043d, 0x62); + gc2083_write_register(ViPipe, 0x043e, 0x62); + gc2083_write_register(ViPipe, 0x043f, 0x62); + gc2083_write_register(ViPipe, 0x0077, 0x01); + gc2083_write_register(ViPipe, 0x0078, 0x65); + gc2083_write_register(ViPipe, 0x0079, 0x04); + gc2083_write_register(ViPipe, 0x0067, 0xa0); + gc2083_write_register(ViPipe, 0x0054, 0xff); + gc2083_write_register(ViPipe, 0x0055, 0x02); + gc2083_write_register(ViPipe, 0x0056, 0x00); + gc2083_write_register(ViPipe, 0x0057, 0x04); + gc2083_write_register(ViPipe, 0x005a, 0xff); + gc2083_write_register(ViPipe, 0x005b, 0x07); + gc2083_write_register(ViPipe, 0x0026, 0x01); + gc2083_write_register(ViPipe, 0x0152, 0x02); + gc2083_write_register(ViPipe, 0x0153, 0x50); + gc2083_write_register(ViPipe, 0x0155, 0x93); + gc2083_write_register(ViPipe, 0x0410, 0x16); + gc2083_write_register(ViPipe, 0x0411, 0x16); + gc2083_write_register(ViPipe, 0x0412, 0x16); + gc2083_write_register(ViPipe, 0x0413, 0x16); + gc2083_write_register(ViPipe, 0x0414, 0x6f); + gc2083_write_register(ViPipe, 0x0415, 0x6f); + gc2083_write_register(ViPipe, 0x0416, 0x6f); + gc2083_write_register(ViPipe, 0x0417, 0x6f); + gc2083_write_register(ViPipe, 0x04e0, 0x18); + gc2083_write_register(ViPipe, 0x0192, 0x04); + gc2083_write_register(ViPipe, 0x0194, 0x04); + gc2083_write_register(ViPipe, 0x0195, 0x04); + gc2083_write_register(ViPipe, 0x0196, 0x38); + gc2083_write_register(ViPipe, 0x0197, 0x07); + gc2083_write_register(ViPipe, 0x0198, 0x80); + gc2083_write_register(ViPipe, 0x0201, 0x27); + gc2083_write_register(ViPipe, 0x0202, 0x53); + gc2083_write_register(ViPipe, 0x0203, 0xce); + gc2083_write_register(ViPipe, 0x0204, 0x40); + gc2083_write_register(ViPipe, 0x0212, 0x07); + gc2083_write_register(ViPipe, 0x0213, 0x80); + gc2083_write_register(ViPipe, 0x0215, 0x12); + gc2083_write_register(ViPipe, 0x0229, 0x05); + gc2083_write_register(ViPipe, 0x0237, 0x03); + gc2083_write_register(ViPipe, 0x023e, 0x99); + + gc2083_default_reg_init(ViPipe); + delay_ms(80); + + printf("ViPipe:%d,===GC2083 1080P 30fps 10bit LINE Init OK!===\n", ViPipe); +} \ No newline at end of file