middleware: version release v4.1.0.3

4849be0d9 add gc1084 dual sensor
1d6272046 [sensor] add new sensor cv4001
4a1fbbfb9 [sensor] add new sensor gc1084
bc594bd06 [audio] add 32bit width AUD_USE_32BIT_WIDTH = yes in audio.mk
0321a3d55 [vb] Add CVI_VB_CreateExPool API
d5888892d [mars][ldc] add ldc sample by user cfg
c139b74c7 [sensor] add ov5647 missed configuration in mw/v1
c7342fb4f [sensor] modify sc2331_1l vts and hts
9eda43160 [sensor] add sensor mis2008_1l
3accef3a8 [sensor] add sc2336_1L
update isp and osdrv.

Change-Id: I62cc8b9c75484b6dd5c249fe1983e03a84812c71
This commit is contained in:
forum_service
2023-08-28 20:05:10 +08:00
committed by carbon
parent 077fb488fa
commit 01e4576313
423 changed files with 16132 additions and 59 deletions

View File

@ -53,10 +53,13 @@ sensor-$(CONFIG_SENSOR_VIVO_MM308M2) += vivo_mm308m2
sensor-$(CONFIG_SENSOR_TECHPOINT_TP2825) += techpoint_tp2825
else ifeq ($(CHIP_ARCH), $(filter $(CHIP_ARCH), CV180X CV181X CV182X))
sensor-$(CONFIG_SENSOR_BRIGATES_BG0808) += brigates_bg0808
sensor-$(CONFIG_SENSOR_CVSENS_CV4001) += cvsens_cv4001
sensor-$(CONFIG_SENSOR_GCORE_GC02M1) += gcore_gc02m1
sensor-$(CONFIG_SENSOR_GCORE_GC0312) += gcore_gc0312
sensor-$(CONFIG_SENSOR_GCORE_GC0329) += gcore_gc0329
sensor-$(CONFIG_SENSOR_GCORE_GC1054) += gcore_gc1054
sensor-$(CONFIG_SENSOR_GCORE_GC1084) += gcore_gc1084
sensor-$(CONFIG_SENSOR_GCORE_GC1084_SLAVE) += gcore_gc1084_slave
sensor-$(CONFIG_SENSOR_GCORE_GC2053) += gcore_gc2053
sensor-$(CONFIG_SENSOR_GCORE_GC2053_SLAVE) += gcore_gc2053_slave
sensor-$(CONFIG_SENSOR_GCORE_GC2053_1L) += gcore_gc2053_1L
@ -93,6 +96,7 @@ sensor-$(CONFIG_SENSOR_SMS_SC3336) += sms_sc3336
sensor-$(CONFIG_SENSOR_SMS_SC2331_1L) += sms_sc2331_1L
sensor-$(CONFIG_SENSOR_SMS_SC2335) += sms_sc2335
sensor-$(CONFIG_SENSOR_SMS_SC2336) += sms_sc2336
sensor-$(CONFIG_SENSOR_SMS_SC2336_1L) += sms_sc2336_1L
sensor-$(CONFIG_SENSOR_SMS_SC2336P) += sms_sc2336p
sensor-$(CONFIG_SENSOR_SMS_SC4336) += sms_sc4336
sensor-$(CONFIG_SENSOR_SMS_SC4336P) += sms_sc4336p

View File

@ -26,8 +26,12 @@ prepare:
brigates_bg0808:
$(call MAKE_SENSOR, ${@})
cvsens_cv4001:
$(call MAKE_SENSOR, ${@})
gcore_gc02m1:
$(call MAKE_SENSOR, ${@})
gcore_gc0312:
$(call MAKE_SENSOR, ${@})
@ -37,6 +41,12 @@ gcore_gc0329:
gcore_gc1054:
$(call MAKE_SENSOR, ${@})
gcore_gc1084:
$(call MAKE_SENSOR, ${@})
gcore_gc1084_slave:
$(call MAKE_SENSOR, ${@})
gcore_gc2053:
$(call MAKE_SENSOR, ${@})
@ -61,6 +71,9 @@ gcore_gc4653:
imgds_mis2008:
$(call MAKE_SENSOR, ${@})
imgds_mis2008_1L:
$(call MAKE_SENSOR, ${@})
nextchip_n5:
$(call MAKE_SENSOR, ${@})
@ -145,6 +158,9 @@ sms_sc2335:
sms_sc2336:
$(call MAKE_SENSOR, ${@})
sms_sc2336_1L:
$(call MAKE_SENSOR, ${@})
sms_sc2336p:
$(call MAKE_SENSOR, ${@})

View File

@ -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_cv4001.a
TARGET_SO = $(MW_LIB)/libsns_cv4001.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)

View File

@ -0,0 +1,939 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <syslog.h>
#include <errno.h>
#ifdef ARCH_CV182X
#include "cvi_type.h"
#include "cvi_comm_video.h"
#include <linux/cvi_vip_snsr.h>
#else
#include <linux/cvi_type.h>
#include <linux/cvi_comm_video.h>
#include <linux/vi_snsr.h>
#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 "cv4001_cmos_ex.h"
#include "cv4001_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 CV4001_ID 4001
#define CV4001_I2C_ADDR_1 0x35
#define CV4001_I2C_ADDR_2 0x36
#define CV4001_I2C_ADDR_IS_VALID(addr) ((addr) == CV4001_I2C_ADDR_1 || (addr) == CV4001_I2C_ADDR_2)
/****************************************************************************
* global variables *
***************************************************************************/
ISP_SNS_STATE_S *g_pastCV4001[VI_MAX_PIPE_NUM] = {CVI_NULL};
#define CV4001_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastCV4001[dev])
#define CV4001_SENSOR_SET_CTX(dev, pstCtx) (g_pastCV4001[dev] = pstCtx)
#define CV4001_SENSOR_RESET_CTX(dev) (g_pastCV4001[dev] = CVI_NULL)
ISP_SNS_COMMBUS_U g_aunCV4001_BusInfo[VI_MAX_PIPE_NUM] = {
[0] = { .s8I2cDev = 3},
[1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1}
};
ISP_SNS_MIRRORFLIP_TYPE_E g_aeCV4001_MirrorFip[VI_MAX_PIPE_NUM] = {0};
CVI_U16 g_au16CV4001_GainMode[VI_MAX_PIPE_NUM] = {0};
/****************************************************************************
* local variables and functions *
***************************************************************************/
static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = {
[0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE
};
static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0};
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);
/*****CV4001 Lines Range*****/
#define CV4001_FULL_LINES_MAX (0xfffff)
/*****CV4001 Register Address*****/
#define CV4001_EXP_ADDR0 0x3062 //bit[19:16]
#define CV4001_EXP_ADDR1 0x3061
#define CV4001_EXP_ADDR2 0x3060
#define CV4001_AGAIN_ADDR 0x3180 //bit[7:0]
#define CV4001_DGAIN_H_ADDR 0x3179 //bit[15:8]
#define CV4001_DGAIN_L_ADDR 0x3178 //bit[7:0]
#define CV4001_VTS_ADDR0 0x302A //bit[19:16]
#define CV4001_VTS_ADDR1 0x3029
#define CV4001_VTS_ADDR2 0x3028
#define CV4001_FLIP_MIRROR_ADDR 0x3034
#define CV4001_RES_IS_1440P(w, h) ((w) <= 2560 && (h) <= 1440)
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);
CV4001_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER(pstSnsState);
pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd;
pstAeSnsDft->u32FlickerFreq = 50 * 256;
pstAeSnsDft->u32FullLinesMax = CV4001_FULL_LINES_MAX;
pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 25);
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 * 25 / 2;
else
pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe];
switch (pstSnsState->enWDRMode) {
default:
case WDR_MODE_NONE: /*linear mode*/
pstAeSnsDft->f32Fps = g_astCV4001_mode[CV4001_MODE_2560X1440P25].f32MaxFps;
pstAeSnsDft->f32MinFps = g_astCV4001_mode[CV4001_MODE_2560X1440P25].f32MinFps;
pstAeSnsDft->au8HistThresh[0] = 0xd;
pstAeSnsDft->au8HistThresh[1] = 0x28;
pstAeSnsDft->au8HistThresh[2] = 0x60;
pstAeSnsDft->au8HistThresh[3] = 0x80;
pstAeSnsDft->u32MaxAgain = 16384;
pstAeSnsDft->u32MinAgain = 1024;
pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain;
pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain;
pstAeSnsDft->u32MaxDgain = 16384;
pstAeSnsDft->u32MinDgain = 1024;
pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain;
pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain;
pstAeSnsDft->u8AeCompensation = 40;
pstAeSnsDft->u32InitAESpeed = 64;
pstAeSnsDft->u32InitAETolerance = 2;
pstAeSnsDft->u32AEResponseFrame = 4;
pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR;
pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ?
g_au32InitExposure[ViPipe] : g_astCV4001_mode[CV4001_MODE_2560X1440P25].stExp[0].u16Def;
pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 8;
pstAeSnsDft->u32MinIntTime = g_astCV4001_mode[CV4001_MODE_2560X1440P25].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);
CV4001_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER(pstSnsState);
u32Vts = g_astCV4001_mode[pstSnsState->u8ImgMode].u32VtsDef;
pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg;
f32MaxFps = g_astCV4001_mode[pstSnsState->u8ImgMode].f32MaxFps;
f32MinFps = g_astCV4001_mode[pstSnsState->u8ImgMode].f32MinFps;
if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) {
u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps);
} else {
CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps);
return CVI_FAILURE;
}
u32VMAX = (u32VMAX > CV4001_FULL_LINES_MAX) ? CV4001_FULL_LINES_MAX : u32VMAX;
if (pstSnsState->enWDRMode == WDR_MODE_NONE) {
pstSnsRegsInfo->astI2cData[LINEAR_VTS_0].u32Data = ((u32VMAX & 0xFF0000) >> 16);
pstSnsRegsInfo->astI2cData[LINEAR_VTS_1].u32Data = ((u32VMAX & 0xFF00) >> 8);
pstSnsRegsInfo->astI2cData[LINEAR_VTS_2].u32Data = (u32VMAX & 0xFF);
} else {
CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport WDRMode: %d\n", pstSnsState->enWDRMode);
return CVI_FAILURE;
}
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;
CVI_S32 Cur_Vts;
CVI_S32 Reg_IntTime;
CV4001_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER(pstSnsState);
CMOS_CHECK_POINTER(u32IntTime);
Cur_Vts = pstSnsState->u32FLStd;
Reg_IntTime = ((Cur_Vts / 2) - u32IntTime[0]) * 2;
pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg;
pstSnsRegsInfo->astI2cData[LINEAR_EXP_0].u32Data = ((Reg_IntTime >> 16) & 0x0F);
pstSnsRegsInfo->astI2cData[LINEAR_EXP_1].u32Data = ((Reg_IntTime >> 8) & 0xFF);
pstSnsRegsInfo->astI2cData[LINEAR_EXP_2].u32Data = (Reg_IntTime & 0xFF);
return CVI_SUCCESS;
}
static CVI_U32 gain_table[242] = {
1024, 1024, 1024, 1024, 1040, 1040, 1040, 1040, 1056, 1056,
1056, 1056, 1072, 1072, 1072, 1072, 1088, 1088, 1088, 1104,
1104, 1104, 1120, 1120, 1120, 1120, 1136, 1136, 1136, 1152,
1152, 1152, 1168, 1168, 1168, 1184, 1184, 1184, 1200, 1200,
1200, 1216, 1216, 1216, 1232, 1232, 1248, 1248, 1248, 1264,
1264, 1264, 1280, 1280, 1296, 1296, 1296, 1312, 1312, 1328,
1328, 1344, 1344, 1344, 1360, 1360, 1376, 1376, 1392, 1392,
1408, 1408, 1424, 1424, 1440, 1440, 1456, 1456, 1472, 1472,
1488, 1488, 1504, 1504, 1520, 1520, 1536, 1536, 1552, 1568,
1568, 1584, 1584, 1600, 1616, 1616, 1632, 1648, 1648, 1664,
1680, 1680, 1696, 1712, 1712, 1728, 1744, 1744, 1760, 1776,
1792, 1808, 1808, 1824, 1840, 1856, 1872, 1872, 1888, 1904,
1920, 1936, 1952, 1968, 1984, 2000, 2016, 2016, 2048, 2064,
2080, 2096, 2112, 2128, 2144, 2160, 2176, 2192, 2208, 2240,
2256, 2272, 2288, 2304, 2336, 2352, 2368, 2400, 2416, 2448,
2464, 2496, 2512, 2544, 2560, 2592, 2608, 2640, 2672, 2688,
2720, 2752, 2784, 2816, 2848, 2880, 2912, 2944, 2976, 3008,
3040, 3072, 3120, 3152, 3184, 3232, 3264, 3312, 3360, 3392,
3440, 3488, 3536, 3584, 3632, 3680, 3744, 3792, 3840, 3904,
3968, 4032, 4096, 4160, 4224, 4288, 4368, 4432, 4512, 4592,
4672, 4752, 4848, 4944, 5040, 5136, 5232, 5344, 5456, 5568,
5696, 5824, 5952, 6080, 6240, 6384, 6544, 6720, 6896, 7072,
7280, 7488, 7696, 7936, 8192, 8448, 8736, 9024, 9360, 9696,
10080, 10480, 10912, 11392, 11904, 12480, 13104, 13792, 14560, 15408,
16384, 0x3FFFF,
};
static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb)
{
int i, total;
CVI_U32 pregain;
CMOS_CHECK_POINTER(pu32AgainLin);
CMOS_CHECK_POINTER(pu32AgainDb);
UNUSED(ViPipe);
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;
CMOS_CHECK_POINTER(pu32DgainLin);
CMOS_CHECK_POINTER(pu32DgainDb);
UNUSED(ViPipe);
// 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);
CV4001_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 */
for (i = 0; i < total; i++) {
if ((gain_table[i] <= pu32Again[0]) && (gain_table[i+1] >= pu32Again[0])) {
break;
}
}
u32Again = i;
u32Dgain = pu32Dgain[0] / 16;
if (u32Dgain < 64) {
u32Dgain = 64;
}
if (u32Dgain > 1024) {
u32Dgain = 1024;
}
if (pstSnsState->enWDRMode == WDR_MODE_NONE) {
pstSnsRegsInfo->astI2cData[LINEAR_AGAIN].u32Data = u32Again;
pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_H].u32Data = (u32Dgain >> 8);
pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_L].u32Data = (u32Dgain & 0xFF);
} else {
CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport WDRMode: %d\n", pstSnsState->enWDRMode);
return CVI_FAILURE;
}
return CVI_SUCCESS;
}
static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio,
CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime)
{
UNUSED(ViPipe);
UNUSED(u16ManRatioEnable);
UNUSED(au32Ratio);
UNUSED(au32IntTimeMax);
UNUSED(au32IntTimeMin);
UNUSED(pu32LFMaxIntTime);
CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport WDRMode\n");
return CVI_SUCCESS;
}
/* Only used in LINE_WDR mode */
static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr)
{
CMOS_CHECK_POINTER(pstAeFSWDRAttr);
genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode;
gu32MaxTimeGetCnt[ViPipe] = 0;
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));
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 CV4001_MODE_S *pstMode = CVI_NULL;
ISP_SNS_STATE_S *pstSnsState = CVI_NULL;
CV4001_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER(pstSnsState);
pstMode = &g_astCV4001_mode[pstSnsState->u8ImgMode];
if (pstSnsState->enWDRMode != WDR_MODE_NONE) {
CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport WDRMode: %d\n", pstSnsState->enWDRMode);
} else {
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)
{
UNUSED(ViPipe);
UNUSED(u8Mode);
CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport sensor mode!\n");
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);
CV4001_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_aunCV4001_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 = cv4001_i2c_addr;
pstI2c_data[i].u32AddrByteNum = cv4001_addr_byte;
pstI2c_data[i].u32DataByteNum = cv4001_data_byte;
}
pstI2c_data[LINEAR_EXP_0].u32RegAddr = CV4001_EXP_ADDR0;
pstI2c_data[LINEAR_EXP_1].u32RegAddr = CV4001_EXP_ADDR1;
pstI2c_data[LINEAR_EXP_2].u32RegAddr = CV4001_EXP_ADDR2;
pstI2c_data[LINEAR_AGAIN].u32RegAddr = CV4001_AGAIN_ADDR;
pstI2c_data[LINEAR_DGAIN_H].u32RegAddr = CV4001_DGAIN_H_ADDR;
pstI2c_data[LINEAR_DGAIN_L].u32RegAddr = CV4001_DGAIN_L_ADDR;
pstI2c_data[LINEAR_VTS_0].u32RegAddr = CV4001_VTS_ADDR0;
pstI2c_data[LINEAR_VTS_1].u32RegAddr = CV4001_VTS_ADDR1;
pstI2c_data[LINEAR_VTS_2].u32RegAddr = CV4001_VTS_ADDR2;
pstI2c_data[LINEAR_FLIP_MIRROR].u32RegAddr = CV4001_FLIP_MIRROR_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) && (i <= LINEAR_DGAIN_L)) {
gainsUpdate = 1;
}
if (i <= LINEAR_EXP_2) {
shutterUpdate = 1;
}
if ((i >= LINEAR_VTS_0) && (i <= LINEAR_VTS_2)) {
vtsUpdate = 1;
}
pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE;
pstCfg0->snsCfg.need_update = CVI_TRUE;
}
}
if (gainsUpdate) {
pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN].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_0].bUpdate = CVI_TRUE;
pstCfg0->snsCfg.astI2cData[LINEAR_EXP_1].bUpdate = CVI_TRUE;
pstCfg0->snsCfg.astI2cData[LINEAR_EXP_2].bUpdate = CVI_TRUE;
}
if (vtsUpdate) {
pstCfg0->snsCfg.astI2cData[LINEAR_VTS_0].bUpdate = CVI_TRUE;
pstCfg0->snsCfg.astI2cData[LINEAR_VTS_1].bUpdate = CVI_TRUE;
pstCfg0->snsCfg.astI2cData[LINEAR_VTS_2].bUpdate = CVI_TRUE;
}
/* check update isp crop or not */
pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ?
CVI_TRUE : CVI_FALSE);
}
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];
pstCfg0->snsCfg.astI2cData[LINEAR_FLIP_MIRROR].bDropFrm = CVI_FALSE;
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);
CV4001_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 (CV4001_RES_IS_1440P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height))
u8SensorImageMode = CV4001_MODE_2560X1440P25;
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)
{
CVI_U8 value = 0x0;
CVI_U8 start_x = 4;
CVI_U8 start_y = 4;
ISP_SNS_STATE_S *pstSnsState = CVI_NULL;
ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL;
ISP_SNS_ISP_INFO_S *pstIspCfg0 = CVI_NULL;
CV4001_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER_VOID(pstSnsState);
pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg;
pstIspCfg0 = &pstSnsState->astSyncInfo[0].ispCfg;
/* Apply the setting on the fly */
if (pstSnsState->bInit == CVI_TRUE && g_aeCV4001_MirrorFip[ViPipe] != eSnsMirrorFlip) {
switch (eSnsMirrorFlip) {
case ISP_SNS_NORMAL:
value = 0x0;
start_x = 4;
start_y = 4;
break;
case ISP_SNS_MIRROR:
value = 0x1;
start_x = 5;
start_y = 4;
break;
case ISP_SNS_FLIP:
value = 0x2;
start_x = 4;
start_y = 5;
break;
case ISP_SNS_MIRROR_FLIP:
value = 0x3;
start_x = 5;
start_y = 5;
break;
default:
return;
}
pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR].u32Data = value;
pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR].bDropFrm = 1;
pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR].u8DropFrmNum = 2;
g_aeCV4001_MirrorFip[ViPipe] = eSnsMirrorFlip;
pstIspCfg0->img_size[0].stWndRect.s32X = start_x;
pstIspCfg0->img_size[0].stWndRect.s32Y = start_y;
}
}
static CVI_VOID sensor_global_init(VI_PIPE ViPipe)
{
ISP_SNS_STATE_S *pstSnsState = CVI_NULL;
CV4001_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER_VOID(pstSnsState);
pstSnsState->bInit = CVI_FALSE;
pstSnsState->bSyncInit = CVI_FALSE;
pstSnsState->u8ImgMode = CV4001_MODE_2560X1440P25;
pstSnsState->enWDRMode = WDR_MODE_NONE;
pstSnsState->u32FLStd = g_astCV4001_mode[pstSnsState->u8ImgMode].u32VtsDef;
pstSnsState->au32FL[0] = g_astCV4001_mode[pstSnsState->u8ImgMode].u32VtsDef;
pstSnsState->au32FL[1] = g_astCV4001_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;
CV4001_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER(pstSnsState);
CMOS_CHECK_POINTER(pstRxAttr);
memcpy(pstRxAttr, &cv4001_rx_attr, sizeof(*pstRxAttr));
pstRxAttr->img_size.width = g_astCV4001_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width;
pstRxAttr->img_size.height = g_astCV4001_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 = &cv4001_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 = cv4001_init;
pstSensorExpFunc->pfn_cmos_sensor_exit = cv4001_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 (CV4001_I2C_ADDR_IS_VALID(s32I2cAddr))
cv4001_i2c_addr = s32I2cAddr;
}
static CVI_S32 cv4001_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo)
{
g_aunCV4001_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev;
return CVI_SUCCESS;
}
static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe)
{
ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL;
CV4001_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));
CV4001_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx);
return CVI_SUCCESS;
}
static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe)
{
ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL;
CV4001_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx);
SENSOR_FREE(pastSnsStateCtx);
CV4001_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 = CV4001_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, CV4001_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, CV4001_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, CV4001_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_au16CV4001_GainMode[ViPipe] = pstInitAttr->enGainMode;
return CVI_SUCCESS;
}
static CVI_S32 sensor_probe(VI_PIPE ViPipe)
{
return cv4001_probe(ViPipe);
}
ISP_SNS_OBJ_S stSnsCV4001_Obj = {
.pfnRegisterCallback = sensor_register_callback,
.pfnUnRegisterCallback = sensor_unregister_callback,
.pfnStandby = cv4001_standby,
.pfnRestart = cv4001_restart,
.pfnWriteReg = cv4001_write_register,
.pfnReadReg = cv4001_read_register,
.pfnSetBusInfo = cv4001_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,
};

View File

@ -0,0 +1,86 @@
#ifndef __CV4001_CMOS_EX_H_
#define __CV4001_CMOS_EX_H_
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
#ifdef ARCH_CV182X
#include <linux/cvi_vip_cif.h>
#include <linux/cvi_vip_snsr.h>
#include "cvi_type.h"
#else
#include <linux/cif_uapi.h>
#include <linux/vi_snsr.h>
#include <linux/cvi_type.h>
#endif
#include "cvi_sns_ctrl.h"
#ifndef UNUSED
#define UNUSED(x) ((void)(x))
#endif
enum cv4001_linear_regs_e {
LINEAR_EXP_0, //0x3062 bit[19:16]
LINEAR_EXP_1, //0x3061
LINEAR_EXP_2, //0x3060
LINEAR_AGAIN, //0x3180 bit[7:0]
LINEAR_DGAIN_H, //0x3179 bit[15:8]
LINEAR_DGAIN_L, //0x3178 bit[7:0]
LINEAR_VTS_0, //0x302A bit[19:16]
LINEAR_VTS_1, //0x3029
LINEAR_VTS_2, //0x3028
LINEAR_FLIP_MIRROR, //0x3034
LINEAR_REGS_NUM
};
typedef enum _CV4001_MODE_E {
CV4001_MODE_2560X1440P25 = 0,
CV4001_MODE_NUM
} CV4001_MODE_E;
typedef struct _CV4001_STATE_S {
CVI_U32 u32Sexp_MAX;
} CV4001_STATE_S;
typedef struct _CV4001_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];
} CV4001_MODE_S;
/****************************************************************************
* external variables and functions *
****************************************************************************/
extern ISP_SNS_STATE_S *g_pastCV4001[VI_MAX_PIPE_NUM];
extern ISP_SNS_COMMBUS_U g_aunCV4001_BusInfo[];
extern ISP_SNS_MIRRORFLIP_TYPE_E g_aeCV4001_MirrorFip[VI_MAX_PIPE_NUM];
extern CVI_U8 cv4001_i2c_addr;
extern const CVI_U32 cv4001_addr_byte;
extern const CVI_U32 cv4001_data_byte;
extern void cv4001_init(VI_PIPE ViPipe);
extern void cv4001_exit(VI_PIPE ViPipe);
extern void cv4001_standby(VI_PIPE ViPipe);
extern void cv4001_restart(VI_PIPE ViPipe);
extern int cv4001_write_register(VI_PIPE ViPipe, int addr, int data);
extern int cv4001_read_register(VI_PIPE ViPipe, int addr);
extern int cv4001_probe(VI_PIPE ViPipe);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* End of #ifdef __cplusplus */
#endif /* __CV4001_CMOS_EX_H_ */

View File

@ -0,0 +1,124 @@
#ifndef __CV4001_CMOS_PARAM_H_
#define __CV4001_CMOS_PARAM_H_
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
#ifdef ARCH_CV182X
#include <linux/cvi_vip_cif.h>
#include <linux/cvi_vip_snsr.h>
#include "cvi_type.h"
#else
#include <linux/cif_uapi.h>
#include <linux/vi_snsr.h>
#include <linux/cvi_type.h>
#endif
#include "cvi_sns_ctrl.h"
#include "cv4001_cmos_ex.h"
static const CV4001_MODE_S g_astCV4001_mode[CV4001_MODE_NUM] = {
[CV4001_MODE_2560X1440P25] = {
.name = "2560X1440P25",
.astImg[0] = {
.stSnsSize = {
.u32Width = 2568,
.u32Height = 1448,
},
.stWndRect = {
.s32X = 4,
.s32Y = 4,
.u32Width = 2560,
.u32Height = 1440,
},
.stMaxSize = {
.u32Width = 2568,
.u32Height = 1448,
},
},
.f32MaxFps = 25,
.f32MinFps = 0.076, /* 3200 * 25 / 0x0FFFFF */
.u32HtsDef = 743,
.u32VtsDef = 3200,
.stExp[0] = {
.u16Min = 8,
.u16Max = 3200-4,
.u16Def = 8,
.u16Step = 1,
},
.stAgain[0] = {
.u32Min = 1024,
.u32Max = 16384,
.u32Def = 1024,
.u32Step = 1,
},
.stDgain[0] = {
.u32Min = 1024,
.u32Max = 16384,
.u32Def = 1024,
.u32Step = 64,
},
},
};
static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = {
.bUpdate = CVI_TRUE,
.blcAttr = {
.Enable = 1,
.enOpType = OP_TYPE_AUTO,
.stManual = {196, 196, 196, 196, 0, 0, 0, 0
#ifdef ARCH_CV182X
, 1075, 1075, 1075, 1075
#endif
},
.stAuto = {
{196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196 },
{196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196 },
{196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196 },
{196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196 },
{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
{1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075,
1075, 1075},
{1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075,
1075, 1075},
{1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075,
1075, 1075},
{1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075,
1075, 1075},
#endif
},
},
};
struct combo_dev_attr_s cv4001_rx_attr = {
.input_mode = INPUT_MODE_MIPI,
.mac_clk = RX_MAC_CLK_200M,
.mipi_attr = {
.raw_data_type = RAW_DATA_12BIT,
.lane_id = {1, 2, 0, -1, -1},
.pn_swap = {1, 1, 1, 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 /* __CV4001_CMOS_PARAM_H_ */

View File

@ -0,0 +1,294 @@
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <syslog.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#ifdef ARCH_CV182X
#include <linux/cvi_vip_snsr.h>
#include "cvi_comm_video.h"
#else
#include <linux/vi_snsr.h>
#include <linux/cvi_comm_video.h>
#endif
#include "cvi_sns_ctrl.h"
#include "cv4001_cmos_ex.h"
#define CV4001_CHIP_ID_ADDR_H 0x3003
#define CV4001_CHIP_ID_ADDR_L 0x3002
#define CV4001_CHIP_ID 0x4001
static void cv4001_linear_1440p25_init(VI_PIPE ViPipe);
CVI_U8 cv4001_i2c_addr = 0x35;
const CVI_U32 cv4001_addr_byte = 2;
const CVI_U32 cv4001_data_byte = 1;
static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1};
int cv4001_i2c_init(VI_PIPE ViPipe)
{
char acDevFile[16] = {0};
CVI_U8 u8DevNum;
if (g_fd[ViPipe] >= 0)
return CVI_SUCCESS;
int ret;
u8DevNum = g_aunCV4001_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, cv4001_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 cv4001_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 cv4001_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 (cv4001_addr_byte == 2)
buf[idx++] = (addr >> 8) & 0xff;
// add address byte 0
buf[idx++] = addr & 0xff;
ret = write(g_fd[ViPipe], buf, cv4001_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, cv4001_data_byte);
if (ret < 0) {
CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n");
return ret;
}
// pack read back data
data = 0;
if (cv4001_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 cv4001_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 (cv4001_addr_byte == 2) {
buf[idx] = (addr >> 8) & 0xff;
idx++;
buf[idx] = addr & 0xff;
idx++;
}
if (cv4001_data_byte == 1) {
buf[idx] = data & 0xff;
idx++;
}
ret = write(g_fd[ViPipe], buf, cv4001_addr_byte + cv4001_data_byte);
if (ret < 0) {
CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n");
return CVI_FAILURE;
}
ret = read(g_fd[ViPipe], buf, cv4001_addr_byte + cv4001_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 cv4001_standby(VI_PIPE ViPipe)
{
cv4001_write_register(ViPipe, 0x3000, 0x1);
printf("%s\n", __func__);
}
void cv4001_restart(VI_PIPE ViPipe)
{
cv4001_write_register(ViPipe, 0x3000, 0x01);
delay_ms(20);
cv4001_write_register(ViPipe, 0x3000, 0x00);
printf("%s\n", __func__);
}
void cv4001_default_reg_init(VI_PIPE ViPipe)
{
CVI_U32 i;
for (i = 0; i < g_pastCV4001[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) {
cv4001_write_register(ViPipe,
g_pastCV4001[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr,
g_pastCV4001[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data);
}
}
int cv4001_probe(VI_PIPE ViPipe)
{
int nVal;
int nVal2;
usleep(50);
if (cv4001_i2c_init(ViPipe) != CVI_SUCCESS)
return CVI_FAILURE;
nVal = cv4001_read_register(ViPipe, CV4001_CHIP_ID_ADDR_H);
nVal2 = cv4001_read_register(ViPipe, CV4001_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)) != CV4001_CHIP_ID) {
CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n");
return CVI_FAILURE;
}
return CVI_SUCCESS;
}
void cv4001_init(VI_PIPE ViPipe)
{
cv4001_i2c_init(ViPipe);
cv4001_linear_1440p25_init(ViPipe);
g_pastCV4001[ViPipe]->bInit = CVI_TRUE;
}
void cv4001_exit(VI_PIPE ViPipe)
{
cv4001_i2c_exit(ViPipe);
}
static void cv4001_linear_1440p25_init(VI_PIPE ViPipe)
{
delay_ms(10);
//25fps 2lane
cv4001_write_register(ViPipe, 0x3028, 0xB8);
cv4001_write_register(ViPipe, 0x3029, 0x0B);
cv4001_write_register(ViPipe, 0x302C, 0xE4);
cv4001_write_register(ViPipe, 0x302D, 0x02);
cv4001_write_register(ViPipe, 0x3048, 0x40);
cv4001_write_register(ViPipe, 0x3049, 0x00);
cv4001_write_register(ViPipe, 0x304A, 0x08);
cv4001_write_register(ViPipe, 0x304B, 0x0A);
cv4001_write_register(ViPipe, 0x3054, 0x28);
cv4001_write_register(ViPipe, 0x3055, 0x00);
cv4001_write_register(ViPipe, 0x3056, 0xA8);
cv4001_write_register(ViPipe, 0x3057, 0x05);
cv4001_write_register(ViPipe, 0x3020, 0x04);
cv4001_write_register(ViPipe, 0x3908, 0x4A);
cv4001_write_register(ViPipe, 0x3306, 0x03);
cv4001_write_register(ViPipe, 0x343E, 0x00);
cv4001_write_register(ViPipe, 0x3401, 0x01);
cv4001_write_register(ViPipe, 0x3035, 0x01);
cv4001_write_register(ViPipe, 0x3036, 0x01);
cv4001_write_register(ViPipe, 0x343C, 0x01);
cv4001_write_register(ViPipe, 0x362A, 0x00);
cv4001_write_register(ViPipe, 0x3625, 0x01);
cv4001_write_register(ViPipe, 0x35A4, 0x09);
cv4001_write_register(ViPipe, 0x35A8, 0x09);
cv4001_write_register(ViPipe, 0x35AE, 0x07);
cv4001_write_register(ViPipe, 0x35AF, 0x07);
cv4001_write_register(ViPipe, 0x34A2, 0x2C);
cv4001_write_register(ViPipe, 0x3418, 0x9F);
cv4001_write_register(ViPipe, 0x341A, 0x57);
cv4001_write_register(ViPipe, 0x341C, 0x57);
cv4001_write_register(ViPipe, 0x341E, 0x6F);
cv4001_write_register(ViPipe, 0x341F, 0x01);
cv4001_write_register(ViPipe, 0x3420, 0x57);
cv4001_write_register(ViPipe, 0x3422, 0x9F);
cv4001_write_register(ViPipe, 0x3424, 0x57);
cv4001_write_register(ViPipe, 0x3426, 0x8F);
cv4001_write_register(ViPipe, 0x3428, 0x47);
cv4001_write_register(ViPipe, 0x3348, 0x00);
cv4001_write_register(ViPipe, 0x3000, 0x00);
cv4001_write_register(ViPipe, 0x3576, 0x06);
cv4001_write_register(ViPipe, 0x350F, 0x18);
cv4001_write_register(ViPipe, 0x3513, 0x07);
cv4001_write_register(ViPipe, 0x3517, 0x07);
cv4001_write_register(ViPipe, 0x351A, 0x05);
cv4001_write_register(ViPipe, 0x351E, 0x0B);
cv4001_write_register(ViPipe, 0x357A, 0x0B);
cv4001_write_register(ViPipe, 0x3348, 0x00);
cv4001_write_register(ViPipe, 0x316C, 0x64);
cv4001_write_register(ViPipe, 0x3258, 0x02);
cv4001_write_register(ViPipe, 0x3162, 0x01);
cv4001_write_register(ViPipe, 0x3347, 0x01);
cv4001_write_register(ViPipe, 0x3804, 0x0F);
cv4001_write_register(ViPipe, 0x3871, 0x00);
cv4001_write_register(ViPipe, 0x3244, 0x08);
cv4001_write_register(ViPipe, 0x3270, 0x60);
cv4001_write_register(ViPipe, 0x3271, 0x00);
cv4001_write_register(ViPipe, 0x3272, 0x00);
cv4001_write_register(ViPipe, 0x31AC, 0xC8);
cv4001_write_register(ViPipe, 0x3890, 0x00);
cv4001_write_register(ViPipe, 0x3894, 0x05);
cv4001_write_register(ViPipe, 0x3690, 0x00);
cv4001_write_register(ViPipe, 0x3898, 0x20);
cv4001_write_register(ViPipe, 0x3899, 0x20);
cv4001_write_register(ViPipe, 0x3583, 0x2f);
cv4001_write_register(ViPipe, 0x3b75, 0x00);
cv4001_write_register(ViPipe, 0x3b5E, 0x01);
cv4001_write_register(ViPipe, 0x3a10, 0x06);
cv4001_write_register(ViPipe, 0x3a11, 0x06);
cv4001_write_register(ViPipe, 0x316C, 0x64);
cv4001_write_register(ViPipe, 0x3000, 0x00);
cv4001_default_reg_init(ViPipe);
delay_ms(100);
printf("ViPipe:%d,===CV4001 1440P 25fps 12bit LINEAR Init OK!===\n", ViPipe);
}

View File

@ -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_gc1084.a
TARGET_SO = $(MW_LIB)/libsns_gc1084.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)

View File

@ -0,0 +1,971 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <syslog.h>
#include <errno.h>
#ifdef ARCH_CV182X
#include "cvi_type.h"
#include "cvi_comm_video.h"
#include <linux/cvi_vip_snsr.h>
#else
#include <linux/cvi_type.h>
#include <linux/cvi_comm_video.h>
#include <linux/vi_snsr.h>
#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 "gc1084_cmos_ex.h"
#include "gc1084_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 GC1084_ID 1084
/****************************************************************************
* global variables *
****************************************************************************/
ISP_SNS_STATE_S *g_pastGc1084[VI_MAX_PIPE_NUM] = {CVI_NULL};
#define GC1084_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastGc1084[dev])
#define GC1084_SENSOR_SET_CTX(dev, pstCtx) (g_pastGc1084[dev] = pstCtx)
#define GC1084_SENSOR_RESET_CTX(dev) (g_pastGc1084[dev] = CVI_NULL)
ISP_SNS_COMMBUS_U g_aunGc1084_BusInfo[VI_MAX_PIPE_NUM] = {
[0] = { .s8I2cDev = 0},
[1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1}
};
GC1084_STATE_S g_astGc1084_State[VI_MAX_PIPE_NUM] = { {0} };
ISP_SNS_MIRRORFLIP_TYPE_E g_aeGc1084_MirrorFip[VI_MAX_PIPE_NUM] = {0};
CVI_U16 g_au16Gc1084_GainMode[VI_MAX_PIPE_NUM] = {0};
CVI_U16 g_au16Gc1084_L2SMode[VI_MAX_PIPE_NUM] = {0};
/****************************************************************************
* local variables and functions *
****************************************************************************/
static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = {
[0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE
};
static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0};
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);
/*****Gc1084 Lines Range*****/
#define GC1084_FULL_LINES_MAX (17119) // 0x3FFF(Max VB) + 720 + 16
/*****Gc1084 Register Address*****/
#define GC1084_EXP_H_ADDR 0x0d03
#define GC1084_EXP_L_ADDR 0x0d04
#define GC1084_AGAIN_M_ADDR 0x00d1
#define GC1084_AGAIN_L_ADDR 0x00d0
#define GC1084_AGAIN_REG_0x031D 0x031d
#define GC1084_AGAIN_H_ADDR 0x0dc1
#define GC1084_COL_AGAIN_H_ADDR 0x00b8
#define GC1084_COL_AGAIN_L_ADDR 0x00b9
#define GC1084_AGAIN_REG_0x0155 0x0155
#define GC1084_DGAIN_H_ADDR 0x00b1
#define GC1084_DGAIN_L_ADDR 0x00b2
#define GC1084_VTS_H_ADDR 0x0d41
#define GC1084_VTS_L_ADDR 0x0d42
#define GC1084_FLIP_MIRROR_ADDR1 0x0015
#define GC1084_FLIP_MIRROR_ADDR2 0x0d15
#define GC1084_RES_IS_720P(w, h) ((w) <= 1280 && (h) <= 720)
static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft)
{
const GC1084_MODE_S *pstMode;
ISP_SNS_STATE_S *pstSnsState = CVI_NULL;
CMOS_CHECK_POINTER(pstAeSnsDft);
GC1084_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER(pstSnsState);
pstMode = &g_stGc1084_mode;
pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd;
pstAeSnsDft->u32FlickerFreq = 50 * 256;
pstAeSnsDft->u32FullLinesMax = GC1084_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 = pstMode->f32MaxFps;
pstAeSnsDft->f32MinFps = pstMode->f32MinFps;
pstAeSnsDft->au8HistThresh[0] = 0xd;
pstAeSnsDft->au8HistThresh[1] = 0x28;
pstAeSnsDft->au8HistThresh[2] = 0x60;
pstAeSnsDft->au8HistThresh[3] = 0x80;
pstAeSnsDft->u32MaxAgain = pstMode->stAgain.u32Max;
pstAeSnsDft->u32MinAgain = pstMode->stAgain.u32Min;
pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain;
pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain;
pstAeSnsDft->u32MaxDgain = pstMode->stDgain.u32Max;
pstAeSnsDft->u32MinDgain = pstMode->stDgain.u32Min;
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] :
pstMode->stExp.u16Def;
pstAeSnsDft->u32MaxIntTime = pstMode->stExp.u16Max;
pstAeSnsDft->u32MinIntTime = pstMode->stExp.u16Min;
pstAeSnsDft->u32MaxIntTimeTarget = 65535;
pstAeSnsDft->u32MinIntTimeTarget = 1;
break;
case WDR_MODE_2To1_LINE:
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 = 0;
CVI_FLOAT f32MaxFps = 0;
CVI_FLOAT f32MinFps = 0;
CVI_U32 u32Vts = 0;
ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL;
CMOS_CHECK_POINTER(pstAeSnsDft);
GC1084_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER(pstSnsState);
u32Vts = g_stGc1084_mode.u32VtsDef;
pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg;
f32MaxFps = g_stGc1084_mode.f32MaxFps;
f32MinFps = g_stGc1084_mode.f32MinFps;
if (pstSnsState->enWDRMode == WDR_MODE_NONE) {
if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) {
u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps);
} else {
CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps);
return CVI_FAILURE;
}
u32VMAX = (u32VMAX > GC1084_FULL_LINES_MAX) ? GC1084_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;
GC1084_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] & 0xFF00) >> 8);
pstSnsRegsInfo->astI2cData[LINEAR_EXP_L].u32Data = (u32IntTime[0] & 0xFF);
return CVI_SUCCESS;
}
static CVI_U32 regValTable[25][6] = {
/* [reg] 0x00d1, 0x00d0, 0x0dc1, 0x00b8, 0x00b9, 0x155
* [name] AGAIN_M, AGAIN_L, AGAIN_H, COLGA_H, COLGA_L, REG_0x0155
*/
{0x00, 0x00, 0x00, 0x01, 0x00, 0x00},
{0x0A, 0x00, 0x00, 0x01, 0x0c, 0x00},
{0x00, 0x01, 0x00, 0x01, 0x1a, 0x00},
{0x0A, 0x01, 0x00, 0x01, 0x2a, 0x00},
{0x00, 0x02, 0x00, 0x02, 0x00, 0x00},
{0x0A, 0x02, 0x00, 0x02, 0x18, 0x00},
{0x00, 0x03, 0x00, 0x02, 0x33, 0x00},
{0x0A, 0x03, 0x00, 0x03, 0x14, 0x00},
{0x00, 0x04, 0x00, 0x04, 0x00, 0x02},
{0x0A, 0x04, 0x00, 0x04, 0x2f, 0x02},
{0x00, 0x05, 0x00, 0x05, 0x26, 0x02},
{0x0A, 0x05, 0x00, 0x06, 0x29, 0x02},
{0x00, 0x06, 0x00, 0x08, 0x00, 0x02},
{0x0A, 0x06, 0x00, 0x09, 0x1f, 0x04},
{0x12, 0x46, 0x00, 0x0b, 0x0d, 0x04},
{0x19, 0x66, 0x00, 0x0d, 0x12, 0x06},
{0x00, 0x04, 0x01, 0x10, 0x00, 0x06},
{0x0A, 0x04, 0x01, 0x12, 0x3e, 0x08},
{0x00, 0x05, 0x01, 0x16, 0x1a, 0x0a},
{0x0A, 0x05, 0x01, 0x1a, 0x23, 0x0c},
{0x00, 0x06, 0x01, 0x20, 0x00, 0x0c},
{0x0A, 0x06, 0x01, 0x25, 0x3b, 0x0f},
{0x12, 0x46, 0x01, 0x2c, 0x33, 0x12},
{0x19, 0x66, 0x01, 0x35, 0x06, 0x14},
{0x20, 0x06, 0x01, 0x3f, 0x3f, 0x15},
};
static CVI_U32 gain_table[25] = {
1024, 1216, 1440, 1696, 2048, 2432, 2864, 3392,
4096, 4848, 5728, 6800, 8192, 9712, 11472, 13584,
16384, 19408, 22944, 27184, 32768, 38832, 45872, 54368,
65536
};
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)
{
UNUSED(ViPipe);
CMOS_CHECK_POINTER(pu32DgainLin);
CMOS_CHECK_POINTER(pu32DgainDb);
*pu32DgainLin = 1024;
*pu32DgainDb = 0;
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);
GC1084_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 */
/* To kepp the linearity. we assume AE algo adjusts the dgain only when the again reachs the maximum value */
if (pu32Again[0] < gain_table[total - 1]) {
for (i = 1; i < total; i++) {
if (*pu32Again < gain_table[i])
break;
}
i--;
// find the pregain
u32Dgain = pu32Again[0] * 64 / gain_table[i];
u32Again = i;
} else {
// find the pregain
u32Dgain = pu32Again[0] * 64 / gain_table[total - 1];
u32Again = total - 1;
}
if (pstSnsState->enWDRMode == WDR_MODE_NONE) {
pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_M].u32Data = regValTable[u32Again][0];
pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_L].u32Data = regValTable[u32Again][1];
pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_REG_0x031D_0x2E].u32Data = 0x2e;
pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_H].u32Data = regValTable[u32Again][2];
pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_REG_0x031D_0x28].u32Data = 0x28;
pstSnsRegsInfo->astI2cData[LINEAR_COL_AGAIN_H].u32Data = regValTable[u32Again][3];
pstSnsRegsInfo->astI2cData[LINEAR_COL_AGAIN_L].u32Data = regValTable[u32Again][4];
pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_REG_0x0155].u32Data = regValTable[u32Again][5];
pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_H].u32Data = (u32Dgain >> 6);
pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_L].u32Data = (u32Dgain & 0x3F) << 2;
} else {
CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport WDRMode: %d\n", pstSnsState->enWDRMode);
return CVI_FAILURE;
}
return CVI_SUCCESS;
}
static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio,
CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime)
{
UNUSED(ViPipe);
UNUSED(u16ManRatioEnable);
UNUSED(au32Ratio);
UNUSED(au32IntTimeMax);
UNUSED(au32IntTimeMin);
UNUSED(pu32LFMaxIntTime);
return CVI_SUCCESS;
}
/* Only used in LINE_WDR mode */
static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr)
{
CMOS_CHECK_POINTER(pstAeFSWDRAttr);
genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode;
gu32MaxTimeGetCnt[ViPipe] = 0;
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 GC1084_MODE_S *pstMode = CVI_NULL;
ISP_SNS_STATE_S *pstSnsState = CVI_NULL;
GC1084_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER(pstSnsState);
pstMode = &g_stGc1084_mode;
pstIspCfg->frm_num = 1;
memcpy(&pstIspCfg->img_size[0], &pstMode->stImg, 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;
GC1084_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER(pstSnsState);
pstSnsState->bSyncInit = CVI_FALSE;
switch (u8Mode) {
case WDR_MODE_NONE:
pstSnsState->u8ImgMode = GC1084_MODE_1280X720P30;
pstSnsState->enWDRMode = WDR_MODE_NONE;
pstSnsState->u32FLStd = g_stGc1084_mode.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);
GC1084_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_aunGc1084_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 = gc1084_i2c_addr;
pstI2c_data[i].u32AddrByteNum = gc1084_addr_byte;
pstI2c_data[i].u32DataByteNum = gc1084_data_byte;
}
pstI2c_data[LINEAR_EXP_H].u32RegAddr = GC1084_EXP_H_ADDR;
pstI2c_data[LINEAR_EXP_L].u32RegAddr = GC1084_EXP_L_ADDR;
pstI2c_data[LINEAR_AGAIN_M].u32RegAddr = GC1084_AGAIN_M_ADDR;
pstI2c_data[LINEAR_AGAIN_L].u32RegAddr = GC1084_AGAIN_L_ADDR;
pstI2c_data[LINEAR_AGAIN_REG_0x031D_0x2E].u32RegAddr = GC1084_AGAIN_REG_0x031D;
pstI2c_data[LINEAR_AGAIN_H].u32RegAddr = GC1084_AGAIN_H_ADDR;
pstI2c_data[LINEAR_AGAIN_REG_0x031D_0x28].u32RegAddr = GC1084_AGAIN_REG_0x031D;
pstI2c_data[LINEAR_COL_AGAIN_H].u32RegAddr = GC1084_COL_AGAIN_H_ADDR;
pstI2c_data[LINEAR_COL_AGAIN_L].u32RegAddr = GC1084_COL_AGAIN_L_ADDR;
pstI2c_data[LINEAR_AGAIN_REG_0x0155].u32RegAddr = GC1084_AGAIN_REG_0x0155;
pstI2c_data[LINEAR_DGAIN_H].u32RegAddr = GC1084_DGAIN_H_ADDR;
pstI2c_data[LINEAR_DGAIN_L].u32RegAddr = GC1084_DGAIN_L_ADDR;
pstI2c_data[LINEAR_VTS_H].u32RegAddr = GC1084_VTS_H_ADDR;
pstI2c_data[LINEAR_VTS_L].u32RegAddr = GC1084_VTS_L_ADDR;
pstI2c_data[LINEAR_FLIP_MIRROR1].u32RegAddr = GC1084_FLIP_MIRROR_ADDR1;
pstI2c_data[LINEAR_FLIP_MIRROR2].u32RegAddr = GC1084_FLIP_MIRROR_ADDR2;
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, expUpdate = 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_M) && (i <= LINEAR_DGAIN_L))
gainsUpdate = 1;
if (i <= LINEAR_EXP_L)
expUpdate = 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_M].bUpdate = CVI_TRUE;
pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_L].bUpdate = CVI_TRUE;
pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_REG_0x031D_0x2E].bUpdate = CVI_TRUE;
pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_H].bUpdate = CVI_TRUE;
pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_REG_0x031D_0x28].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_REG_0x0155].bUpdate = CVI_TRUE;
pstCfg0->snsCfg.astI2cData[LINEAR_DGAIN_H].bUpdate = CVI_TRUE;
pstCfg0->snsCfg.astI2cData[LINEAR_DGAIN_L].bUpdate = CVI_TRUE;
}
if (expUpdate) {
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];
pstCfg0->snsCfg.astI2cData[LINEAR_FLIP_MIRROR1].bDropFrm = CVI_FALSE;
pstCfg0->snsCfg.astI2cData[LINEAR_FLIP_MIRROR2].bDropFrm = CVI_FALSE;
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);
GC1084_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 (GC1084_RES_IS_720P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height))
u8SensorImageMode = GC1084_MODE_1280X720P30;
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)
{
CVI_U8 value = 0;
ISP_SNS_STATE_S *pstSnsState = CVI_NULL;
ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL;
GC1084_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER_VOID(pstSnsState);
pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg;
/* Apply the setting on the fly */
if (pstSnsState->bInit == CVI_TRUE && g_aeGc1084_MirrorFip[ViPipe] != eSnsMirrorFlip) {
switch (eSnsMirrorFlip) {
case ISP_SNS_NORMAL:
value = 0;
break;
case ISP_SNS_MIRROR:
value = 2;
break;
case ISP_SNS_FLIP:
value = 1;
break;
case ISP_SNS_MIRROR_FLIP:
value = 3;
break;
default:
return;
}
pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR1].u32Data = value;
pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR2].u32Data = value;
pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR1].bDropFrm = 1;
pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR2].bDropFrm = 1;
pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR1].u8DropFrmNum = 1;
pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR2].u8DropFrmNum = 1;
g_aeGc1084_MirrorFip[ViPipe] = eSnsMirrorFlip;
}
}
static CVI_VOID sensor_global_init(VI_PIPE ViPipe)
{
ISP_SNS_STATE_S *pstSnsState = CVI_NULL;
GC1084_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER_VOID(pstSnsState);
pstSnsState->bInit = CVI_FALSE;
pstSnsState->bSyncInit = CVI_FALSE;
pstSnsState->u8ImgMode = GC1084_MODE_1280X720P30;
pstSnsState->enWDRMode = WDR_MODE_NONE;
pstSnsState->u32FLStd = g_stGc1084_mode.u32VtsDef;
pstSnsState->au32FL[0] = g_stGc1084_mode.u32VtsDef;
pstSnsState->au32FL[1] = g_stGc1084_mode.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;
GC1084_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER(pstSnsState);
CMOS_CHECK_POINTER(pstRxAttr);
memcpy(pstRxAttr, &gc1084_rx_attr, sizeof(*pstRxAttr));
pstRxAttr->img_size.width = g_stGc1084_mode.stImg.stSnsSize.u32Width;
pstRxAttr->img_size.height = g_stGc1084_mode.stImg.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 = &gc1084_rx_attr;
int i;
CMOS_CHECK_POINTER(pstRxInitAttr);
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 = gc1084_init;
pstSensorExpFunc->pfn_cmos_sensor_exit = gc1084_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_S32 gc1084_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo)
{
g_aunGc1084_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev;
return CVI_SUCCESS;
}
static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe)
{
ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL;
GC1084_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));
GC1084_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx);
return CVI_SUCCESS;
}
static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe)
{
ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL;
GC1084_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx);
SENSOR_FREE(pastSnsStateCtx);
GC1084_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 = GC1084_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, GC1084_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, GC1084_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, GC1084_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_au16Gc1084_GainMode[ViPipe] = pstInitAttr->enGainMode;
g_au16Gc1084_L2SMode[ViPipe] = pstInitAttr->enL2SMode;
return CVI_SUCCESS;
}
static CVI_S32 sensor_probe(VI_PIPE ViPipe)
{
return gc1084_probe(ViPipe);
}
ISP_SNS_OBJ_S stSnsGc1084_Obj = {
.pfnRegisterCallback = sensor_register_callback,
.pfnUnRegisterCallback = sensor_unregister_callback,
.pfnStandby = gc1084_standby,
.pfnRestart = gc1084_restart,
.pfnWriteReg = gc1084_write_register,
.pfnReadReg = gc1084_read_register,
.pfnSetBusInfo = gc1084_set_bus_info,
.pfnSetInit = sensor_set_init,
.pfnMirrorFlip = sensor_mirror_flip,
.pfnPatchRxAttr = sensor_patch_rx_attr,
.pfnPatchI2cAddr = CVI_NULL,
.pfnGetRxAttr = sensor_rx_attr,
.pfnExpSensorCb = cmos_init_sensor_exp_function,
.pfnExpAeCb = cmos_init_ae_exp_function,
.pfnSnsProbe = sensor_probe,
};

View File

@ -0,0 +1,98 @@
#ifndef __GC1084_CMOS_EX_H_
#define __GC1084_CMOS_EX_H_
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
#ifdef ARCH_CV182X
#include <linux/cvi_vip_cif.h>
#include <linux/cvi_vip_snsr.h>
#include "cvi_type.h"
#else
#include <linux/cif_uapi.h>
#include <linux/vi_snsr.h>
#include <linux/cvi_type.h>
#endif
#include "cvi_sns_ctrl.h"
#ifndef UNUSED
#define UNUSED(x) ((void)(x))
#endif
enum gc1084_linear_regs_e {
LINEAR_EXP_H,
LINEAR_EXP_L,
LINEAR_AGAIN_M,
LINEAR_AGAIN_L,
LINEAR_AGAIN_REG_0x031D_0x2E,
LINEAR_AGAIN_H,
LINEAR_AGAIN_REG_0x031D_0x28,
LINEAR_COL_AGAIN_H,
LINEAR_COL_AGAIN_L,
LINEAR_AGAIN_REG_0x0155,
LINEAR_DGAIN_H,
LINEAR_DGAIN_L,
LINEAR_VTS_H,
LINEAR_VTS_L,
LINEAR_FLIP_MIRROR1,
LINEAR_FLIP_MIRROR2,
LINEAR_REGS_NUM
};
typedef enum _GC1084_MODE_E {
GC1084_MODE_1280X720P30 = 0,
GC1084_MODE_NUM
} GC1084_SLAVE_MODE_E;
typedef struct _GC1084_STATE_S {
CVI_U32 u32Sexp_MAX;
} GC1084_STATE_S;
typedef struct _GC1084_MODE_S {
ISP_WDR_SIZE_S stImg;
CVI_FLOAT f32MaxFps;
CVI_FLOAT f32MinFps;
CVI_U32 u32HtsDef;
CVI_U32 u32VtsDef;
SNS_ATTR_S stExp;
SNS_ATTR_LARGE_S stAgain;
SNS_ATTR_LARGE_S stDgain;
char name[64];
} GC1084_MODE_S;
/****************************************************************************
* external variables and functions *
****************************************************************************/
extern ISP_SNS_STATE_S *g_pastGc1084[VI_MAX_PIPE_NUM];
extern ISP_SNS_COMMBUS_U g_aunGc1084_BusInfo[];
extern ISP_SNS_MIRRORFLIP_TYPE_E g_aeGc1084_MirrorFip[VI_MAX_PIPE_NUM];
extern const CVI_U8 gc1084_i2c_addr;
extern const CVI_U32 gc1084_addr_byte;
extern const CVI_U32 gc1084_data_byte;
extern void gc1084_init(VI_PIPE ViPipe);
extern void gc1084_exit(VI_PIPE ViPipe);
extern void gc1084_standby(VI_PIPE ViPipe);
extern void gc1084_restart(VI_PIPE ViPipe);
extern int gc1084_write_register(VI_PIPE ViPipe, int addr, int data);
extern int gc1084_read_register(VI_PIPE ViPipe, int addr);
extern int gc1084_probe(VI_PIPE ViPipe);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* End of #ifdef __cplusplus */
#endif /* __GC1084_CMOS_EX_H_ */

View File

@ -0,0 +1,219 @@
#ifndef __GC1084_CMOS_PARAM_H_
#define __GC1084_CMOS_PARAM_H_
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
#ifdef ARCH_CV182X
#include <linux/cvi_vip_cif.h>
#include <linux/cvi_vip_snsr.h>
#include "cvi_type.h"
#else
#include <linux/cif_uapi.h>
#include <linux/vi_snsr.h>
#include <linux/cvi_type.h>
#endif
#include "cvi_sns_ctrl.h"
#include "gc1084_cmos_ex.h"
static const GC1084_MODE_S g_stGc1084_mode = {
.name = "1280X720P30",
.stImg = {
.stSnsSize = {
.u32Width = 1280,
.u32Height = 720,
},
.stWndRect = {
.s32X = 0,
.s32Y = 0,
.u32Width = 1280,
.u32Height = 720,
},
.stMaxSize = {
.u32Width = 1280,
.u32Height = 720,
},
},
.f32MaxFps = 30,
.f32MinFps = 1.31, /* 750 * 30 / 0xFFFF */
.u32HtsDef = 2200,
.u32VtsDef = 746, /* WIN_H + VB + 16 */
.stExp = {
.u16Min = 1,
.u16Max = 746 - 1, /* VtsDef - 1*/
.u16Def = 100,
.u16Step = 1,
},
.stAgain = {
.u32Min = 1024,
.u32Max = 64 * 1024,
.u32Def = 1024,
.u32Step = 1,
},
.stDgain = {
.u32Min = 1024,
.u32Max = 1024,
.u32Def = 1024,
.u32Step = 1,
},
};
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
, 1092, 1092, 1092, 1092
#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
{1092, 1092, 1093, 1093, 1093, 1093, 1093, 1095,
1099, 1104, 1125, 1130, 1125, 1127, 1126, 1126},
{1092, 1092, 1093, 1093, 1093, 1093, 1094, 1095,
1097, 1104, 1128, 1128, 1126, 1124, 1127, 1127},
{1092, 1092, 1093, 1093, 1093, 1093, 1094, 1095,
1098, 1104, 1128, 1131, 1125, 1127, 1128, 1126},
{1092, 1092, 1093, 1093, 1093, 1093, 1093, 1095,
1097, 1103, 1123, 1124, 1124, 1123, 1121, 1125},
#endif
},
},
};
struct combo_dev_attr_s gc1084_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, -1, -1, -1},
.wdr_mode = CVI_MIPI_WDR_MODE_NONE,
},
.mclk = {
.cam = 0,
.freq = CAMPLL_FREQ_27M,
},
.devno = 0,
};
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* End of #ifdef __cplusplus */
#endif /* __GC1084_CMOS_PARAM_H_ */

View File

@ -0,0 +1,332 @@
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <syslog.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#ifdef ARCH_CV182X
#include <linux/cvi_vip_snsr.h>
#include "cvi_comm_video.h"
#else
#include <linux/vi_snsr.h>
#include <linux/cvi_comm_video.h>
#endif
#include "cvi_sns_ctrl.h"
#include "gc1084_cmos_ex.h"
#define GC1084_CHIP_ID_ADDR_H 0x03f0
#define GC1084_CHIP_ID_ADDR_L 0x03f1
#define GC1084_CHIP_ID 0x1084
static void gc1084_linear_720p30_init(VI_PIPE ViPipe);
const CVI_U8 gc1084_i2c_addr = 0x37;//0x42
const CVI_U32 gc1084_addr_byte = 2;
const CVI_U32 gc1084_data_byte = 1;
static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1};
int gc1084_i2c_init(VI_PIPE ViPipe)
{
char acDevFile[16] = {0};
CVI_U8 u8DevNum;
if (g_fd[ViPipe] >= 0)
return CVI_SUCCESS;
int ret;
u8DevNum = g_aunGc1084_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, gc1084_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 gc1084_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 gc1084_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 (gc1084_addr_byte == 2)
buf[idx++] = (addr >> 8) & 0xff;
// add address byte 0
buf[idx++] = addr & 0xff;
ret = write(g_fd[ViPipe], buf, gc1084_addr_byte);
if (ret < 0) {
CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n");
return 0;
}
buf[0] = 0;
buf[1] = 0;
ret = read(g_fd[ViPipe], buf, gc1084_data_byte);
if (ret < 0) {
CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n");
return 0;
}
// pack read back data
data = 0;
if (gc1084_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 gc1084_write_register(VI_PIPE ViPipe, int addr, int data)
{
CVI_U8 idx = 0;
int ret;
CVI_U8 buf[8];
if (gc1084_addr_byte == 2) {
buf[idx] = (addr >> 8) & 0xff;
idx++;
buf[idx] = addr & 0xff;
idx++;
}
if (gc1084_data_byte == 1) {
buf[idx] = data & 0xff;
idx++;
}
ret = write(g_fd[ViPipe], buf, gc1084_addr_byte + gc1084_data_byte);
if (ret < 0) {
CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n");
return CVI_FAILURE;
}
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 gc1084_standby(VI_PIPE ViPipe)
{
UNUSED(ViPipe);
printf("%s\n", __func__);
}
void gc1084_restart(VI_PIPE ViPipe)
{
UNUSED(ViPipe);
printf("%s\n", __func__);
}
int gc1084_probe(VI_PIPE ViPipe)
{
int nVal;
int nVal2;
usleep(50);
if (gc1084_i2c_init(ViPipe) != CVI_SUCCESS)
return CVI_FAILURE;
nVal = gc1084_read_register(ViPipe, GC1084_CHIP_ID_ADDR_H);
nVal2 = gc1084_read_register(ViPipe, GC1084_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)) != GC1084_CHIP_ID) {
CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n");
return CVI_FAILURE;
}
return CVI_SUCCESS;
}
void gc1084_default_reg_init(VI_PIPE ViPipe)
{
CVI_U32 i;
for (i = 0; i < g_pastGc1084[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) {
gc1084_write_register(ViPipe,
g_pastGc1084[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr,
g_pastGc1084[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data);
}
}
void gc1084_init(VI_PIPE ViPipe)
{
WDR_MODE_E enWDRMode = g_pastGc1084[ViPipe]->enWDRMode;
gc1084_i2c_init(ViPipe);
if (enWDRMode == WDR_MODE_2To1_LINE) {
CVI_TRACE_SNS(CVI_DBG_ERR, "not surpport this WDR_MODE_E!\n");
} else {
gc1084_linear_720p30_init(ViPipe);
}
g_pastGc1084[ViPipe]->bInit = CVI_TRUE;
}
void gc1084_exit(VI_PIPE ViPipe)
{
gc1084_i2c_exit(ViPipe);
}
static void gc1084_linear_720p30_init(VI_PIPE ViPipe)
{
gc1084_write_register(ViPipe, 0x03fe, 0xf0);
gc1084_write_register(ViPipe, 0x03fe, 0xf0);
gc1084_write_register(ViPipe, 0x03fe, 0xf0);
gc1084_write_register(ViPipe, 0x03fe, 0x00);
gc1084_write_register(ViPipe, 0x03f2, 0x00);
gc1084_write_register(ViPipe, 0x03f3, 0x00);
gc1084_write_register(ViPipe, 0x03f4, 0x36);
gc1084_write_register(ViPipe, 0x03f5, 0xc0);
gc1084_write_register(ViPipe, 0x03f6, 0x13);
gc1084_write_register(ViPipe, 0x03f7, 0x01);
gc1084_write_register(ViPipe, 0x03f8, 0x2c);
gc1084_write_register(ViPipe, 0x03f9, 0x21);
gc1084_write_register(ViPipe, 0x03fc, 0xae);
gc1084_write_register(ViPipe, 0x0d05, 0x08);
gc1084_write_register(ViPipe, 0x0d06, 0x98);
gc1084_write_register(ViPipe, 0x0d08, 0x10);
gc1084_write_register(ViPipe, 0x0d0a, 0x02);
gc1084_write_register(ViPipe, 0x000c, 0x03);
gc1084_write_register(ViPipe, 0x0d0d, 0x02);
gc1084_write_register(ViPipe, 0x0d0e, 0xd4);
gc1084_write_register(ViPipe, 0x000f, 0x05);
gc1084_write_register(ViPipe, 0x0010, 0x08);
gc1084_write_register(ViPipe, 0x0017, 0x08);
gc1084_write_register(ViPipe, 0x0d73, 0x92);
gc1084_write_register(ViPipe, 0x0076, 0x00);
gc1084_write_register(ViPipe, 0x0d76, 0x00);
gc1084_write_register(ViPipe, 0x0d41, 0x02);
gc1084_write_register(ViPipe, 0x0d42, 0xee);
gc1084_write_register(ViPipe, 0x0d7a, 0x0a);
gc1084_write_register(ViPipe, 0x006b, 0x18);
gc1084_write_register(ViPipe, 0x0db0, 0x9d);
gc1084_write_register(ViPipe, 0x0db1, 0x00);
gc1084_write_register(ViPipe, 0x0db2, 0xac);
gc1084_write_register(ViPipe, 0x0db3, 0xd5);
gc1084_write_register(ViPipe, 0x0db4, 0x00);
gc1084_write_register(ViPipe, 0x0db5, 0x97);
gc1084_write_register(ViPipe, 0x0db6, 0x09);
gc1084_write_register(ViPipe, 0x00d2, 0xfc);
gc1084_write_register(ViPipe, 0x0d19, 0x31);
gc1084_write_register(ViPipe, 0x0d20, 0x40);
gc1084_write_register(ViPipe, 0x0d25, 0xcb);
gc1084_write_register(ViPipe, 0x0d27, 0x03);
gc1084_write_register(ViPipe, 0x0d29, 0x40);
gc1084_write_register(ViPipe, 0x0d43, 0x20);
gc1084_write_register(ViPipe, 0x0058, 0x60);
gc1084_write_register(ViPipe, 0x00d6, 0x66);
gc1084_write_register(ViPipe, 0x00d7, 0x19);
gc1084_write_register(ViPipe, 0x0093, 0x02);
gc1084_write_register(ViPipe, 0x00d9, 0x14);
gc1084_write_register(ViPipe, 0x00da, 0xc1);
gc1084_write_register(ViPipe, 0x0d2a, 0x00);
gc1084_write_register(ViPipe, 0x0d28, 0x04);
gc1084_write_register(ViPipe, 0x0dc2, 0x84);
gc1084_write_register(ViPipe, 0x0050, 0x30);
gc1084_write_register(ViPipe, 0x0080, 0x07);
gc1084_write_register(ViPipe, 0x008c, 0x05);
gc1084_write_register(ViPipe, 0x008d, 0xa8);
gc1084_write_register(ViPipe, 0x0077, 0x01);
gc1084_write_register(ViPipe, 0x0078, 0xee);
gc1084_write_register(ViPipe, 0x0079, 0x02);
gc1084_write_register(ViPipe, 0x0067, 0xc0);
gc1084_write_register(ViPipe, 0x0054, 0xff);
gc1084_write_register(ViPipe, 0x0055, 0x02);
gc1084_write_register(ViPipe, 0x0056, 0x00);
gc1084_write_register(ViPipe, 0x0057, 0x04);
gc1084_write_register(ViPipe, 0x005a, 0xff);
gc1084_write_register(ViPipe, 0x005b, 0x07);
gc1084_write_register(ViPipe, 0x00d5, 0x03);
gc1084_write_register(ViPipe, 0x0102, 0xa9);
gc1084_write_register(ViPipe, 0x0d03, 0x02);
gc1084_write_register(ViPipe, 0x0d04, 0xd0);
gc1084_write_register(ViPipe, 0x007a, 0x60);
gc1084_write_register(ViPipe, 0x04e0, 0xff);
gc1084_write_register(ViPipe, 0x0414, 0x75);
gc1084_write_register(ViPipe, 0x0415, 0x75);
gc1084_write_register(ViPipe, 0x0416, 0x75);
gc1084_write_register(ViPipe, 0x0417, 0x75);
gc1084_write_register(ViPipe, 0x0122, 0x00);
gc1084_write_register(ViPipe, 0x0121, 0x80);
gc1084_write_register(ViPipe, 0x0428, 0x10);
gc1084_write_register(ViPipe, 0x0429, 0x10);
gc1084_write_register(ViPipe, 0x042a, 0x10);
gc1084_write_register(ViPipe, 0x042b, 0x10);
gc1084_write_register(ViPipe, 0x042c, 0x14);
gc1084_write_register(ViPipe, 0x042d, 0x14);
gc1084_write_register(ViPipe, 0x042e, 0x18);
gc1084_write_register(ViPipe, 0x042f, 0x18);
gc1084_write_register(ViPipe, 0x0430, 0x05);
gc1084_write_register(ViPipe, 0x0431, 0x05);
gc1084_write_register(ViPipe, 0x0432, 0x05);
gc1084_write_register(ViPipe, 0x0433, 0x05);
gc1084_write_register(ViPipe, 0x0434, 0x05);
gc1084_write_register(ViPipe, 0x0435, 0x05);
gc1084_write_register(ViPipe, 0x0436, 0x05);
gc1084_write_register(ViPipe, 0x0437, 0x05);
gc1084_write_register(ViPipe, 0x0153, 0x00);
gc1084_write_register(ViPipe, 0x0190, 0x01);
gc1084_write_register(ViPipe, 0x0192, 0x02);
gc1084_write_register(ViPipe, 0x0194, 0x04);
gc1084_write_register(ViPipe, 0x0195, 0x02);
gc1084_write_register(ViPipe, 0x0196, 0xd0);
gc1084_write_register(ViPipe, 0x0197, 0x05);
gc1084_write_register(ViPipe, 0x0198, 0x00);
gc1084_write_register(ViPipe, 0x0201, 0x23);
gc1084_write_register(ViPipe, 0x0202, 0x53);
gc1084_write_register(ViPipe, 0x0203, 0xce);
gc1084_write_register(ViPipe, 0x0208, 0x39);
gc1084_write_register(ViPipe, 0x0212, 0x06);
gc1084_write_register(ViPipe, 0x0213, 0x40);
gc1084_write_register(ViPipe, 0x0215, 0x12);
gc1084_write_register(ViPipe, 0x0229, 0x05);
gc1084_write_register(ViPipe, 0x023e, 0x98);
gc1084_write_register(ViPipe, 0x031e, 0x3e);
gc1084_default_reg_init(ViPipe);
delay_ms(40);
printf("ViPipe:%d,===GC1084 720P 30fps 10bit LINE Init OK!===\n", ViPipe);
}

View File

@ -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_gc1084_slave.a
TARGET_SO = $(MW_LIB)/libsns_gc1084_slave.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)

View File

@ -0,0 +1,985 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <syslog.h>
#include <errno.h>
#ifdef ARCH_CV182X
#include "cvi_type.h"
#include "cvi_comm_video.h"
#include <linux/cvi_vip_snsr.h>
#else
#include <linux/cvi_type.h>
#include <linux/cvi_comm_video.h>
#include <linux/vi_snsr.h>
#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 "gc1084_slave_cmos_ex.h"
#include "gc1084_slave_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 GC1084_SLAVE_ID 1084
/****************************************************************************
* global variables *
****************************************************************************/
ISP_SNS_STATE_S *g_pastGc1084_Slave[VI_MAX_PIPE_NUM] = {CVI_NULL};
#define GC1084_SLAVE_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastGc1084_Slave[dev])
#define GC1084_SLAVE_SENSOR_SET_CTX(dev, pstCtx) (g_pastGc1084_Slave[dev] = pstCtx)
#define GC1084_SLAVE_SENSOR_RESET_CTX(dev) (g_pastGc1084_Slave[dev] = CVI_NULL)
ISP_SNS_COMMBUS_U g_aunGc1084_Slave_BusInfo[VI_MAX_PIPE_NUM] = {
[0] = { .s8I2cDev = 0},
[1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1}
};
GC1084_SLAVE_STATE_S g_astGc1084_Slave_State[VI_MAX_PIPE_NUM] = { {0} };
ISP_SNS_MIRRORFLIP_TYPE_E g_aeGc1084_Slave_MirrorFip[VI_MAX_PIPE_NUM] = {0};
CVI_U16 g_au16Gc1084_Slave_GainMode[VI_MAX_PIPE_NUM] = {0};
CVI_U16 g_au16Gc1084_Slave_L2SMode[VI_MAX_PIPE_NUM] = {0};
/****************************************************************************
* local variables and functions *
****************************************************************************/
static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = {
[0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE
};
static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0};
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);
/*****Gc1084 Lines Range*****/
#define GC1084_SLAVE_FULL_LINES_MAX (17119) // 0x3FFF(Max VB) + 720 + 16
/*****Gc1084 Register Address*****/
#define GC1084_SLAVE_EXP_H_ADDR 0x0d03
#define GC1084_SLAVE_EXP_L_ADDR 0x0d04
#define GC1084_SLAVE_AGAIN_M_ADDR 0x00d1
#define GC1084_SLAVE_AGAIN_L_ADDR 0x00d0
#define GC1084_SLAVE_AGAIN_REG_0x031D 0x031d
#define GC1084_SLAVE_AGAIN_H_ADDR 0x0dc1
#define GC1084_SLAVE_COL_AGAIN_H_ADDR 0x00b8
#define GC1084_SLAVE_COL_AGAIN_L_ADDR 0x00b9
#define GC1084_SLAVE_AGAIN_REG_0x0155 0x0155
#define GC1084_SLAVE_DGAIN_H_ADDR 0x00b1
#define GC1084_SLAVE_DGAIN_L_ADDR 0x00b2
#define GC1084_SLAVE_VTS_H_ADDR 0x0d41
#define GC1084_SLAVE_VTS_L_ADDR 0x0042
#define GC1084_SLAVE_VB_H_ADDR 0x0d79
#define GC1084_SLAVE_VB_L_ADDR 0x0d7a
#define GC1084_SLAVE_FLIP_MIRROR_ADDR1 0x0015
#define GC1084_SLAVE_FLIP_MIRROR_ADDR2 0x0d15
#define GC1084_SLAVE_RES_IS_720P(w, h) ((w) <= 1280 && (h) <= 720)
static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft)
{
const GC1084_SLAVE_MODE_S *pstMode;
ISP_SNS_STATE_S *pstSnsState = CVI_NULL;
CMOS_CHECK_POINTER(pstAeSnsDft);
GC1084_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER(pstSnsState);
pstMode = &g_stGc1084_Slave_mode;
pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd;
pstAeSnsDft->u32FlickerFreq = 50 * 256;
pstAeSnsDft->u32FullLinesMax = GC1084_SLAVE_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];
#if 0
pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0;
pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0;
pstAeSnsDft->bAERouteExValid = CVI_FALSE;
pstAeSnsDft->stAERouteAttr.u32TotalNum = 0;
pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0;
#endif
switch (pstSnsState->enWDRMode) {
default:
case WDR_MODE_NONE: /*linear mode*/
pstAeSnsDft->f32Fps = pstMode->f32MaxFps;
pstAeSnsDft->f32MinFps = pstMode->f32MinFps;
pstAeSnsDft->au8HistThresh[0] = 0xd;
pstAeSnsDft->au8HistThresh[1] = 0x28;
pstAeSnsDft->au8HistThresh[2] = 0x60;
pstAeSnsDft->au8HistThresh[3] = 0x80;
pstAeSnsDft->u32MaxAgain = pstMode->stAgain.u32Max;
pstAeSnsDft->u32MinAgain = pstMode->stAgain.u32Min;
pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain;
pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain;
pstAeSnsDft->u32MaxDgain = pstMode->stDgain.u32Max;
pstAeSnsDft->u32MinDgain = pstMode->stDgain.u32Min;
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] :
pstMode->stExp.u16Def;
pstAeSnsDft->u32MaxIntTime = pstMode->stExp.u16Max;
pstAeSnsDft->u32MinIntTime = pstMode->stExp.u16Min;
pstAeSnsDft->u32MaxIntTimeTarget = 65535;
pstAeSnsDft->u32MinIntTimeTarget = 1;
break;
case WDR_MODE_2To1_LINE:
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 = 0, u32VB = 0;
CVI_FLOAT f32MaxFps = 0;
CVI_FLOAT f32MinFps = 0;
CVI_U32 u32Vts = 0;
ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL;
CMOS_CHECK_POINTER(pstAeSnsDft);
GC1084_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER(pstSnsState);
u32Vts = g_stGc1084_Slave_mode.u32VtsDef;
pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg;
f32MaxFps = g_stGc1084_Slave_mode.f32MaxFps;
f32MinFps = g_stGc1084_Slave_mode.f32MinFps;
if (pstSnsState->enWDRMode == WDR_MODE_NONE) {
if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) {
u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps);
} else {
CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps);
return CVI_FAILURE;
}
u32VMAX = (u32VMAX > GC1084_SLAVE_FULL_LINES_MAX) ? GC1084_SLAVE_FULL_LINES_MAX : u32VMAX;
u32VB = u32VMAX - 720 - 16;//vts - win_h -16
pstSnsRegsInfo->astI2cData[LINEAR_VTS_H].u32Data = ((u32VMAX & 0xFF00) >> 8);
pstSnsRegsInfo->astI2cData[LINEAR_VTS_L].u32Data = (u32VMAX & 0xFF);
pstSnsRegsInfo->astI2cData[LINEAR_VB_H].u32Data = ((u32VB & 0xFF00) >> 8);
pstSnsRegsInfo->astI2cData[LINEAR_VB_L].u32Data = (u32VB & 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;
GC1084_SLAVE_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] & 0xFF00) >> 8);
pstSnsRegsInfo->astI2cData[LINEAR_EXP_L].u32Data = (u32IntTime[0] & 0xFF);
return CVI_SUCCESS;
}
static CVI_U32 regValTable[25][6] = {
/* [reg] 0x00d1, 0x00d0, 0x0dc1, 0x00b8, 0x00b9, 0x155
* [name] AGAIN_M AGAIN_L AGAIN_H COLGA_H COLGA_L REG_0x0155
*/
{0x00, 0x00, 0x00, 0x01, 0x00, 0x00},
{0x0A, 0x00, 0x00, 0x01, 0x0c, 0x00},
{0x00, 0x01, 0x00, 0x01, 0x1a, 0x00},
{0x0A, 0x01, 0x00, 0x01, 0x2a, 0x00},
{0x00, 0x02, 0x00, 0x02, 0x00, 0x00},
{0x0A, 0x02, 0x00, 0x02, 0x18, 0x00},
{0x00, 0x03, 0x00, 0x02, 0x33, 0x00},
{0x0A, 0x03, 0x00, 0x03, 0x14, 0x00},
{0x00, 0x04, 0x00, 0x04, 0x00, 0x02},
{0x0A, 0x04, 0x00, 0x04, 0x2f, 0x02},
{0x00, 0x05, 0x00, 0x05, 0x26, 0x02},
{0x0A, 0x05, 0x00, 0x06, 0x29, 0x02},
{0x00, 0x06, 0x00, 0x08, 0x00, 0x02},
{0x0A, 0x06, 0x00, 0x09, 0x1f, 0x04},
{0x12, 0x46, 0x00, 0x0b, 0x0d, 0x04},
{0x19, 0x66, 0x00, 0x0d, 0x12, 0x06},
{0x00, 0x04, 0x01, 0x10, 0x00, 0x06},
{0x0A, 0x04, 0x01, 0x12, 0x3e, 0x08},
{0x00, 0x05, 0x01, 0x16, 0x1a, 0x0a},
{0x0A, 0x05, 0x01, 0x1a, 0x23, 0x0c},
{0x00, 0x06, 0x01, 0x20, 0x00, 0x0c},
{0x0A, 0x06, 0x01, 0x25, 0x3b, 0x0f},
{0x12, 0x46, 0x01, 0x2c, 0x33, 0x12},
{0x19, 0x66, 0x01, 0x35, 0x06, 0x14},
{0x20, 0x06, 0x01, 0x3f, 0x3f, 0x15},
};
static CVI_U32 gain_table[25] = {
1024, 1216, 1440, 1696, 2048, 2432, 2864, 3392,
4096, 4848, 5728, 6800, 8192, 9712, 11472, 13584,
16384, 19408, 22944, 27184, 32768, 38832, 45872, 54368,
65536
};
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)
{
UNUSED(ViPipe);
CMOS_CHECK_POINTER(pu32DgainLin);
CMOS_CHECK_POINTER(pu32DgainDb);
*pu32DgainLin = 1024;
*pu32DgainDb = 0;
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);
GC1084_SLAVE_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 */
/* To kepp the linearity. we assume AE algo adjusts the dgain only when the again reachs the maximum value */
if (pu32Again[0] < gain_table[total - 1]) {
for (i = 1; i < total; i++) {
if (*pu32Again < gain_table[i])
break;
}
i--;
// find the pregain
u32Dgain = pu32Again[0] * 64 / gain_table[i];
u32Again = i;
} else {
// find the pregain
u32Dgain = pu32Again[0] * 64 / gain_table[total - 1];
u32Again = total - 1;
}
if (pstSnsState->enWDRMode == WDR_MODE_NONE) {
pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_M].u32Data = regValTable[u32Again][0];
pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_L].u32Data = regValTable[u32Again][1];
pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_REG_0x031D_0x2E].u32Data = 0x2e;
pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_H].u32Data = regValTable[u32Again][2];
pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_REG_0x031D_0x28].u32Data = 0x28;
pstSnsRegsInfo->astI2cData[LINEAR_COL_AGAIN_H].u32Data = regValTable[u32Again][3];
pstSnsRegsInfo->astI2cData[LINEAR_COL_AGAIN_L].u32Data = regValTable[u32Again][4];
pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_REG_0x0155].u32Data = regValTable[u32Again][5];
pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_H].u32Data = (u32Dgain >> 6);
pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_L].u32Data = (u32Dgain & 0x3F) << 2;
} else {
CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport WDRMode: %d\n", pstSnsState->enWDRMode);
return CVI_FAILURE;
}
return CVI_SUCCESS;
}
static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio,
CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime)
{
UNUSED(ViPipe);
UNUSED(u16ManRatioEnable);
UNUSED(au32Ratio);
UNUSED(au32IntTimeMax);
UNUSED(au32IntTimeMin);
UNUSED(pu32LFMaxIntTime);
return CVI_SUCCESS;
}
/* Only used in LINE_WDR mode */
static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr)
{
CMOS_CHECK_POINTER(pstAeFSWDRAttr);
genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode;
gu32MaxTimeGetCnt[ViPipe] = 0;
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 GC1084_SLAVE_MODE_S *pstMode = CVI_NULL;
ISP_SNS_STATE_S *pstSnsState = CVI_NULL;
GC1084_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER(pstSnsState);
pstMode = &g_stGc1084_Slave_mode;
pstIspCfg->frm_num = 1;
memcpy(&pstIspCfg->img_size[0], &pstMode->stImg, 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;
GC1084_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER(pstSnsState);
pstSnsState->bSyncInit = CVI_FALSE;
switch (u8Mode) {
case WDR_MODE_NONE:
pstSnsState->u8ImgMode = GC1084_SLAVE_MODE_1280X720P30;
pstSnsState->enWDRMode = WDR_MODE_NONE;
pstSnsState->u32FLStd = g_stGc1084_Slave_mode.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);
GC1084_SLAVE_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_aunGc1084_Slave_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 = gc1084_slave_i2c_addr;
pstI2c_data[i].u32AddrByteNum = gc1084_slave_addr_byte;
pstI2c_data[i].u32DataByteNum = gc1084_slave_data_byte;
}
pstI2c_data[LINEAR_EXP_H].u32RegAddr = GC1084_SLAVE_EXP_H_ADDR;
pstI2c_data[LINEAR_EXP_L].u32RegAddr = GC1084_SLAVE_EXP_L_ADDR;
pstI2c_data[LINEAR_AGAIN_M].u32RegAddr = GC1084_SLAVE_AGAIN_M_ADDR;
pstI2c_data[LINEAR_AGAIN_L].u32RegAddr = GC1084_SLAVE_AGAIN_L_ADDR;
pstI2c_data[LINEAR_AGAIN_REG_0x031D_0x2E].u32RegAddr = GC1084_SLAVE_AGAIN_REG_0x031D;
pstI2c_data[LINEAR_AGAIN_H].u32RegAddr = GC1084_SLAVE_AGAIN_H_ADDR;
pstI2c_data[LINEAR_AGAIN_REG_0x031D_0x28].u32RegAddr = GC1084_SLAVE_AGAIN_REG_0x031D;
pstI2c_data[LINEAR_COL_AGAIN_H].u32RegAddr = GC1084_SLAVE_COL_AGAIN_H_ADDR;
pstI2c_data[LINEAR_COL_AGAIN_L].u32RegAddr = GC1084_SLAVE_COL_AGAIN_L_ADDR;
pstI2c_data[LINEAR_AGAIN_REG_0x0155].u32RegAddr = GC1084_SLAVE_AGAIN_REG_0x0155;
pstI2c_data[LINEAR_DGAIN_H].u32RegAddr = GC1084_SLAVE_DGAIN_H_ADDR;
pstI2c_data[LINEAR_DGAIN_L].u32RegAddr = GC1084_SLAVE_DGAIN_L_ADDR;
pstI2c_data[LINEAR_VTS_H].u32RegAddr = GC1084_SLAVE_VTS_H_ADDR;
pstI2c_data[LINEAR_VTS_L].u32RegAddr = GC1084_SLAVE_VTS_L_ADDR;
pstI2c_data[LINEAR_VB_H].u32RegAddr = GC1084_SLAVE_VB_H_ADDR;
pstI2c_data[LINEAR_VB_L].u32RegAddr = GC1084_SLAVE_VB_L_ADDR;
pstI2c_data[LINEAR_FLIP_MIRROR1].u32RegAddr = GC1084_SLAVE_FLIP_MIRROR_ADDR1;
pstI2c_data[LINEAR_FLIP_MIRROR2].u32RegAddr = GC1084_SLAVE_FLIP_MIRROR_ADDR2;
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, expUpdate = 0, vbUpdate = 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_M) && (i <= LINEAR_DGAIN_L))
gainsUpdate = 1;
if (i <= LINEAR_EXP_L)
expUpdate = 1;
if ((i >= LINEAR_VTS_H) && (i <= LINEAR_VB_L))
vbUpdate = 1;
pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE;
pstCfg0->snsCfg.need_update = CVI_TRUE;
}
}
if (gainsUpdate) {
pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_M].bUpdate = CVI_TRUE;
pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_L].bUpdate = CVI_TRUE;
pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_REG_0x031D_0x2E].bUpdate = CVI_TRUE;
pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_H].bUpdate = CVI_TRUE;
pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_REG_0x031D_0x28].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_REG_0x0155].bUpdate = CVI_TRUE;
pstCfg0->snsCfg.astI2cData[LINEAR_DGAIN_H].bUpdate = CVI_TRUE;
pstCfg0->snsCfg.astI2cData[LINEAR_DGAIN_L].bUpdate = CVI_TRUE;
}
if (expUpdate) {
pstCfg0->snsCfg.astI2cData[LINEAR_EXP_H].bUpdate = CVI_TRUE;
pstCfg0->snsCfg.astI2cData[LINEAR_EXP_L].bUpdate = CVI_TRUE;
}
if (vbUpdate) {
pstCfg0->snsCfg.astI2cData[LINEAR_VTS_H].bUpdate = CVI_TRUE;
pstCfg0->snsCfg.astI2cData[LINEAR_VTS_L].bUpdate = CVI_TRUE;
pstCfg0->snsCfg.astI2cData[LINEAR_VB_H].bUpdate = CVI_TRUE;
pstCfg0->snsCfg.astI2cData[LINEAR_VB_L].bUpdate = CVI_TRUE;
}
if ((pstI2c_data[LINEAR_FLIP_MIRROR1].bUpdate == CVI_TRUE) && (pstI2c_data[LINEAR_FLIP_MIRROR2].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];
pstCfg0->snsCfg.astI2cData[LINEAR_FLIP_MIRROR1].bDropFrm = CVI_FALSE;
pstCfg0->snsCfg.astI2cData[LINEAR_FLIP_MIRROR2].bDropFrm = CVI_FALSE;
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);
GC1084_SLAVE_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 (GC1084_SLAVE_RES_IS_720P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height))
u8SensorImageMode = GC1084_SLAVE_MODE_1280X720P30;
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)
{
CVI_U8 value = 0;
ISP_SNS_STATE_S *pstSnsState = CVI_NULL;
ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL;
GC1084_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER_VOID(pstSnsState);
pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg;
/* Apply the setting on the fly */
if (pstSnsState->bInit == CVI_TRUE && g_aeGc1084_Slave_MirrorFip[ViPipe] != eSnsMirrorFlip) {
switch (eSnsMirrorFlip) {
case ISP_SNS_NORMAL:
value = 0;
break;
case ISP_SNS_MIRROR:
value = 2;
break;
case ISP_SNS_FLIP:
value = 1;
break;
case ISP_SNS_MIRROR_FLIP:
value = 3;
break;
default:
return;
}
pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR1].u32Data = value;
pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR2].u32Data = value;
pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR1].bDropFrm = 1;
pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR2].bDropFrm = 1;
pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR1].u8DropFrmNum = 1;
pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR2].u8DropFrmNum = 1;
g_aeGc1084_Slave_MirrorFip[ViPipe] = eSnsMirrorFlip;
}
}
static CVI_VOID sensor_global_init(VI_PIPE ViPipe)
{
ISP_SNS_STATE_S *pstSnsState = CVI_NULL;
GC1084_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER_VOID(pstSnsState);
pstSnsState->bInit = CVI_FALSE;
pstSnsState->bSyncInit = CVI_FALSE;
pstSnsState->u8ImgMode = GC1084_SLAVE_MODE_1280X720P30;
pstSnsState->enWDRMode = WDR_MODE_NONE;
pstSnsState->u32FLStd = g_stGc1084_Slave_mode.u32VtsDef;
pstSnsState->au32FL[0] = g_stGc1084_Slave_mode.u32VtsDef;
pstSnsState->au32FL[1] = g_stGc1084_Slave_mode.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;
GC1084_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER(pstSnsState);
CMOS_CHECK_POINTER(pstRxAttr);
memcpy(pstRxAttr, &gc1084_slave_rx_attr, sizeof(*pstRxAttr));
pstRxAttr->img_size.width = g_stGc1084_Slave_mode.stImg.stSnsSize.u32Width;
pstRxAttr->img_size.height = g_stGc1084_Slave_mode.stImg.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 = &gc1084_slave_rx_attr;
int i;
CMOS_CHECK_POINTER(pstRxInitAttr);
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 = gc1084_slave_init;
pstSensorExpFunc->pfn_cmos_sensor_exit = gc1084_slave_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_S32 gc1084_slave_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo)
{
g_aunGc1084_Slave_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev;
return CVI_SUCCESS;
}
static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe)
{
ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL;
GC1084_SLAVE_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));
GC1084_SLAVE_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx);
return CVI_SUCCESS;
}
static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe)
{
ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL;
GC1084_SLAVE_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx);
SENSOR_FREE(pastSnsStateCtx);
GC1084_SLAVE_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 = GC1084_SLAVE_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, GC1084_SLAVE_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, GC1084_SLAVE_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, GC1084_SLAVE_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_au16Gc1084_Slave_GainMode[ViPipe] = pstInitAttr->enGainMode;
g_au16Gc1084_Slave_L2SMode[ViPipe] = pstInitAttr->enL2SMode;
return CVI_SUCCESS;
}
ISP_SNS_OBJ_S stSnsGc1084_Slave_Obj = {
.pfnRegisterCallback = sensor_register_callback,
.pfnUnRegisterCallback = sensor_unregister_callback,
.pfnStandby = gc1084_slave_standby,
.pfnRestart = gc1084_slave_restart,
.pfnWriteReg = gc1084_slave_write_register,
.pfnReadReg = gc1084_slave_read_register,
.pfnSetBusInfo = gc1084_slave_set_bus_info,
.pfnSetInit = sensor_set_init,
.pfnMirrorFlip = sensor_mirror_flip,
.pfnPatchRxAttr = sensor_patch_rx_attr,
.pfnPatchI2cAddr = CVI_NULL,
.pfnGetRxAttr = sensor_rx_attr,
.pfnExpSensorCb = cmos_init_sensor_exp_function,
.pfnExpAeCb = cmos_init_ae_exp_function,
.pfnSnsProbe = CVI_NULL,
};

View File

@ -0,0 +1,99 @@
#ifndef __GC1084_SLAVE_CMOS_EX_H_
#define __GC1084_SLAVE_CMOS_EX_H_
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
#ifdef ARCH_CV182X
#include <linux/cvi_vip_cif.h>
#include <linux/cvi_vip_snsr.h>
#include "cvi_type.h"
#else
#include <linux/cif_uapi.h>
#include <linux/vi_snsr.h>
#include <linux/cvi_type.h>
#endif
#include "cvi_sns_ctrl.h"
#ifndef UNUSED
#define UNUSED(x) ((void)(x))
#endif
enum gc1084_slave_linear_regs_e {
LINEAR_EXP_H,
LINEAR_EXP_L,
LINEAR_AGAIN_M,
LINEAR_AGAIN_L,
LINEAR_AGAIN_REG_0x031D_0x2E,
LINEAR_AGAIN_H,
LINEAR_AGAIN_REG_0x031D_0x28,
LINEAR_COL_AGAIN_H,
LINEAR_COL_AGAIN_L,
LINEAR_AGAIN_REG_0x0155,
LINEAR_DGAIN_H,
LINEAR_DGAIN_L,
LINEAR_VTS_H,
LINEAR_VTS_L,
LINEAR_VB_H,
LINEAR_VB_L,
LINEAR_FLIP_MIRROR1,
LINEAR_FLIP_MIRROR2,
LINEAR_REGS_NUM
};
typedef enum _GC1084_SLAVE_MODE_E {
GC1084_SLAVE_MODE_1280X720P30 = 0,
GC1084_SLAVE_MODE_NUM
} GC1084_SLAVE_SLAVE_MODE_E;
typedef struct _GC1084_SLAVE_STATE_S {
CVI_U32 u32Sexp_MAX;
} GC1084_SLAVE_STATE_S;
typedef struct _GC1084_SLAVE_MODE_S {
ISP_WDR_SIZE_S stImg;
CVI_FLOAT f32MaxFps;
CVI_FLOAT f32MinFps;
CVI_U32 u32HtsDef;
CVI_U32 u32VtsDef;
SNS_ATTR_S stExp;
SNS_ATTR_LARGE_S stAgain;
SNS_ATTR_LARGE_S stDgain;
char name[64];
} GC1084_SLAVE_MODE_S;
/****************************************************************************
* external variables and functions *
****************************************************************************/
extern ISP_SNS_STATE_S *g_pastGc1084_Slave[VI_MAX_PIPE_NUM];
extern ISP_SNS_COMMBUS_U g_aunGc1084_Slave_BusInfo[];
extern ISP_SNS_MIRRORFLIP_TYPE_E g_aeGc1084_Slave_MirrorFip[VI_MAX_PIPE_NUM];
extern const CVI_U8 gc1084_slave_i2c_addr;
extern const CVI_U32 gc1084_slave_addr_byte;
extern const CVI_U32 gc1084_slave_data_byte;
extern void gc1084_slave_init(VI_PIPE ViPipe);
extern void gc1084_slave_exit(VI_PIPE ViPipe);
extern void gc1084_slave_standby(VI_PIPE ViPipe);
extern void gc1084_slave_restart(VI_PIPE ViPipe);
extern int gc1084_slave_write_register(VI_PIPE ViPipe, int addr, int data);
extern int gc1084_slave_read_register(VI_PIPE ViPipe, int addr);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* End of #ifdef __cplusplus */
#endif /* __GC1084_SLAVE_CMOS_EX_H_ */

View File

@ -0,0 +1,219 @@
#ifndef __GC1084_SLAVE_CMOS_PARAM_H_
#define __GC1084_SLAVE_CMOS_PARAM_H_
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
#ifdef ARCH_CV182X
#include <linux/cvi_vip_cif.h>
#include <linux/cvi_vip_snsr.h>
#include "cvi_type.h"
#else
#include <linux/cif_uapi.h>
#include <linux/vi_snsr.h>
#include <linux/cvi_type.h>
#endif
#include "cvi_sns_ctrl.h"
#include "gc1084_slave_cmos_ex.h"
static const GC1084_SLAVE_MODE_S g_stGc1084_Slave_mode = {
.name = "1280X720P30",
.stImg = {
.stSnsSize = {
.u32Width = 1280,
.u32Height = 720,
},
.stWndRect = {
.s32X = 0,
.s32Y = 0,
.u32Width = 1280,
.u32Height = 720,
},
.stMaxSize = {
.u32Width = 1280,
.u32Height = 720,
},
},
.f32MaxFps = 30,
.f32MinFps = 1.31, /* 750 * 30 / 0xFFFF */
.u32HtsDef = 2200,
.u32VtsDef = 746, /* WIN_H + VB + 16 */
.stExp = {
.u16Min = 1,
.u16Max = 746 - 1, /* VtsDef - 1*/
.u16Def = 100,
.u16Step = 1,
},
.stAgain = {
.u32Min = 1024,
.u32Max = 64 * 1024,
.u32Def = 1024,
.u32Step = 1,
},
.stDgain = {
.u32Min = 1024,
.u32Max = 1024,
.u32Def = 1024,
.u32Step = 1,
},
};
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 = {0, 0, 0, 0, 0, 0, 0, 0
#ifdef ARCH_CV182X
, 1092, 1092, 1092, 1092
#endif
},
.stAuto = {
{0, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252 },
{0, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252 },
{0, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252 },
{0, 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
{1092, 1092, 1093, 1093, 1093, 1093, 1093, 1095,
1099, 1104, 1125, 1130, 1125, 1127, 1126, 1126},
{1092, 1092, 1093, 1093, 1093, 1093, 1094, 1095,
1097, 1104, 1128, 1128, 1126, 1124, 1127, 1127},
{1092, 1092, 1093, 1093, 1093, 1093, 1094, 1095,
1098, 1104, 1128, 1131, 1125, 1127, 1128, 1126},
{1092, 1092, 1093, 1093, 1093, 1093, 1093, 1095,
1097, 1103, 1123, 1124, 1124, 1123, 1121, 1125},
#endif
},
},
};
struct combo_dev_attr_s gc1084_slave_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, -1, -1, -1},
.wdr_mode = CVI_MIPI_WDR_MODE_NONE,
},
.mclk = {
.cam = 1,
.freq = CAMPLL_FREQ_27M,
},
.devno = 1,
};
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* End of #ifdef __cplusplus */
#endif /* __GC1084_SLAVE_CMOS_PARAM_H_ */

View File

@ -0,0 +1,271 @@
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <syslog.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#ifdef ARCH_CV182X
#include <linux/cvi_vip_snsr.h>
#include "cvi_comm_video.h"
#else
#include <linux/vi_snsr.h>
#include <linux/cvi_comm_video.h>
#endif
#include "cvi_sns_ctrl.h"
#include "gc1084_slave_cmos_ex.h"
static void gc1084_slave_linear_720p30_init(VI_PIPE ViPipe);
const CVI_U8 gc1084_slave_i2c_addr = 0x37;//0x42
const CVI_U32 gc1084_slave_addr_byte = 2;
const CVI_U32 gc1084_slave_data_byte = 1;
static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1};
int gc1084_slave_i2c_init(VI_PIPE ViPipe)
{
char acDevFile[16] = {0};
CVI_U8 u8DevNum;
if (g_fd[ViPipe] >= 0)
return CVI_SUCCESS;
int ret;
u8DevNum = g_aunGc1084_Slave_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, gc1084_slave_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 gc1084_slave_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 gc1084_slave_read_register(VI_PIPE ViPipe, int addr)
{
/* TODO:*/
UNUSED(ViPipe);
UNUSED(addr);
return CVI_SUCCESS;
}
int gc1084_slave_write_register(VI_PIPE ViPipe, int addr, int data)
{
CVI_U8 idx = 0;
int ret;
CVI_U8 buf[8];
if (gc1084_slave_addr_byte == 2) {
buf[idx] = (addr >> 8) & 0xff;
idx++;
buf[idx] = addr & 0xff;
idx++;
}
if (gc1084_slave_data_byte == 1) {
buf[idx] = data & 0xff;
idx++;
}
ret = write(g_fd[ViPipe], buf, gc1084_slave_addr_byte + gc1084_slave_data_byte);
if (ret < 0) {
CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n");
return CVI_FAILURE;
}
//ret = read(g_fd[ViPipe], buf, gc1084_slave_addr_byte + gc1084_slave_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 gc1084_slave_standby(VI_PIPE ViPipe)
{
UNUSED(ViPipe);
printf("gc1084_slave_standby\n");
}
void gc1084_slave_restart(VI_PIPE ViPipe)
{
UNUSED(ViPipe);
printf("gc1084_slave_restart\n");
}
void gc1084_slave_default_reg_init(VI_PIPE ViPipe)
{
CVI_U32 i;
for (i = 0; i < g_pastGc1084_Slave[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) {
gc1084_slave_write_register(ViPipe,
g_pastGc1084_Slave[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr,
g_pastGc1084_Slave[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data);
}
}
void gc1084_slave_init(VI_PIPE ViPipe)
{
WDR_MODE_E enWDRMode = g_pastGc1084_Slave[ViPipe]->enWDRMode;
gc1084_slave_i2c_init(ViPipe);
if (enWDRMode == WDR_MODE_2To1_LINE) {
CVI_TRACE_SNS(CVI_DBG_ERR, "not surpport this WDR_MODE_E!\n");
} else {
gc1084_slave_linear_720p30_init(ViPipe);
}
g_pastGc1084_Slave[ViPipe]->bInit = CVI_TRUE;
}
void gc1084_slave_exit(VI_PIPE ViPipe)
{
gc1084_slave_i2c_exit(ViPipe);
}
static void gc1084_slave_linear_720p30_init(VI_PIPE ViPipe)
{
gc1084_slave_write_register(ViPipe, 0x03fe,0xf0);
gc1084_slave_write_register(ViPipe, 0x03fe,0xf0);
gc1084_slave_write_register(ViPipe, 0x03fe,0xf0);
gc1084_slave_write_register(ViPipe, 0x03fe,0x00);
gc1084_slave_write_register(ViPipe, 0x03f2,0x00);
gc1084_slave_write_register(ViPipe, 0x03f3,0x00);
gc1084_slave_write_register(ViPipe, 0x03f4,0x36);
gc1084_slave_write_register(ViPipe, 0x03f5,0xc0);
gc1084_slave_write_register(ViPipe, 0x03f6,0x13);
gc1084_slave_write_register(ViPipe, 0x03f7,0x01);
gc1084_slave_write_register(ViPipe, 0x03f8,0x2c);
gc1084_slave_write_register(ViPipe, 0x03f9,0x21);
gc1084_slave_write_register(ViPipe, 0x03fc,0xae);
gc1084_slave_write_register(ViPipe, 0x0d05,0x08);
gc1084_slave_write_register(ViPipe, 0x0d06,0x98);
gc1084_slave_write_register(ViPipe, 0x0d08,0x10);
gc1084_slave_write_register(ViPipe, 0x0d0a,0x02);
gc1084_slave_write_register(ViPipe, 0x000c,0x03);
gc1084_slave_write_register(ViPipe, 0x0d0d,0x02);
gc1084_slave_write_register(ViPipe, 0x0d0e,0xd4);
gc1084_slave_write_register(ViPipe, 0x000f,0x05);
gc1084_slave_write_register(ViPipe, 0x0010,0x08);
gc1084_slave_write_register(ViPipe, 0x0017,0x08);
gc1084_slave_write_register(ViPipe, 0x0d73,0x92);
gc1084_slave_write_register(ViPipe, 0x0076,0x00);
gc1084_slave_write_register(ViPipe, 0x0d76,0x00);
gc1084_slave_write_register(ViPipe, 0x0d41,0x02);
gc1084_slave_write_register(ViPipe, 0x0d42,0xee);
gc1084_slave_write_register(ViPipe, 0x0d7a,0x0a);
gc1084_slave_write_register(ViPipe, 0x006b,0x18);
gc1084_slave_write_register(ViPipe, 0x0db0,0x9d);
gc1084_slave_write_register(ViPipe, 0x0db1,0x00);
gc1084_slave_write_register(ViPipe, 0x0db2,0xac);
gc1084_slave_write_register(ViPipe, 0x0db3,0xd5);
gc1084_slave_write_register(ViPipe, 0x0db4,0x00);
gc1084_slave_write_register(ViPipe, 0x0db5,0x97);
gc1084_slave_write_register(ViPipe, 0x0db6,0x09);
gc1084_slave_write_register(ViPipe, 0x00d2,0xfc);
gc1084_slave_write_register(ViPipe, 0x0d19,0x31);
gc1084_slave_write_register(ViPipe, 0x0d20,0x40);
gc1084_slave_write_register(ViPipe, 0x0d25,0xcb);
gc1084_slave_write_register(ViPipe, 0x0d27,0x03);
gc1084_slave_write_register(ViPipe, 0x0d29,0x40);
gc1084_slave_write_register(ViPipe, 0x0d43,0x20);
gc1084_slave_write_register(ViPipe, 0x0058,0x60);
gc1084_slave_write_register(ViPipe, 0x00d6,0x66);
gc1084_slave_write_register(ViPipe, 0x00d7,0x19);
gc1084_slave_write_register(ViPipe, 0x0093,0x02);
gc1084_slave_write_register(ViPipe, 0x00d9,0x14);
gc1084_slave_write_register(ViPipe, 0x00da,0xc1);
gc1084_slave_write_register(ViPipe, 0x0d2a,0x00);
gc1084_slave_write_register(ViPipe, 0x0d28,0x04);
gc1084_slave_write_register(ViPipe, 0x0dc2,0x84);
gc1084_slave_write_register(ViPipe, 0x0050,0x30);
gc1084_slave_write_register(ViPipe, 0x0080,0x07);
gc1084_slave_write_register(ViPipe, 0x008c,0x05);
gc1084_slave_write_register(ViPipe, 0x008d,0xa8);
gc1084_slave_write_register(ViPipe, 0x0077,0x01);
gc1084_slave_write_register(ViPipe, 0x0078,0xee);
gc1084_slave_write_register(ViPipe, 0x0079,0x02);
gc1084_slave_write_register(ViPipe, 0x0067,0xc0);
gc1084_slave_write_register(ViPipe, 0x0054,0xff);
gc1084_slave_write_register(ViPipe, 0x0055,0x02);
gc1084_slave_write_register(ViPipe, 0x0056,0x00);
gc1084_slave_write_register(ViPipe, 0x0057,0x04);
gc1084_slave_write_register(ViPipe, 0x005a,0xff);
gc1084_slave_write_register(ViPipe, 0x005b,0x07);
gc1084_slave_write_register(ViPipe, 0x00d5,0x03);
gc1084_slave_write_register(ViPipe, 0x0102,0xa9);
gc1084_slave_write_register(ViPipe, 0x0d03,0x02);
gc1084_slave_write_register(ViPipe, 0x0d04,0xd0);
gc1084_slave_write_register(ViPipe, 0x007a,0x60);
gc1084_slave_write_register(ViPipe, 0x04e0,0xff);
gc1084_slave_write_register(ViPipe, 0x0414,0x75);
gc1084_slave_write_register(ViPipe, 0x0415,0x75);
gc1084_slave_write_register(ViPipe, 0x0416,0x75);
gc1084_slave_write_register(ViPipe, 0x0417,0x75);
gc1084_slave_write_register(ViPipe, 0x0122,0x00);
gc1084_slave_write_register(ViPipe, 0x0121,0x80);
gc1084_slave_write_register(ViPipe, 0x0428,0x10);
gc1084_slave_write_register(ViPipe, 0x0429,0x10);
gc1084_slave_write_register(ViPipe, 0x042a,0x10);
gc1084_slave_write_register(ViPipe, 0x042b,0x10);
gc1084_slave_write_register(ViPipe, 0x042c,0x14);
gc1084_slave_write_register(ViPipe, 0x042d,0x14);
gc1084_slave_write_register(ViPipe, 0x042e,0x18);
gc1084_slave_write_register(ViPipe, 0x042f,0x18);
gc1084_slave_write_register(ViPipe, 0x0430,0x05);
gc1084_slave_write_register(ViPipe, 0x0431,0x05);
gc1084_slave_write_register(ViPipe, 0x0432,0x05);
gc1084_slave_write_register(ViPipe, 0x0433,0x05);
gc1084_slave_write_register(ViPipe, 0x0434,0x05);
gc1084_slave_write_register(ViPipe, 0x0435,0x05);
gc1084_slave_write_register(ViPipe, 0x0436,0x05);
gc1084_slave_write_register(ViPipe, 0x0437,0x05);
gc1084_slave_write_register(ViPipe, 0x0153,0x00);
gc1084_slave_write_register(ViPipe, 0x0190,0x01);
gc1084_slave_write_register(ViPipe, 0x0192,0x02);
gc1084_slave_write_register(ViPipe, 0x0194,0x04);
gc1084_slave_write_register(ViPipe, 0x0195,0x02);
gc1084_slave_write_register(ViPipe, 0x0196,0xd0);
gc1084_slave_write_register(ViPipe, 0x0197,0x05);
gc1084_slave_write_register(ViPipe, 0x0198,0x00);
gc1084_slave_write_register(ViPipe, 0x0201,0x23);
gc1084_slave_write_register(ViPipe, 0x0202,0x53);
gc1084_slave_write_register(ViPipe, 0x0203,0xce);
gc1084_slave_write_register(ViPipe, 0x0208,0x39);
gc1084_slave_write_register(ViPipe, 0x0212,0x06);
gc1084_slave_write_register(ViPipe, 0x0213,0x40);
gc1084_slave_write_register(ViPipe, 0x0215,0x12);
gc1084_slave_write_register(ViPipe, 0x0229,0x05);
gc1084_slave_write_register(ViPipe, 0x023e,0x98);
gc1084_slave_write_register(ViPipe, 0x031e,0x3e);
gc1084_slave_default_reg_init(ViPipe);
delay_ms(40);
printf("ViPipe:%d,===GC1084 720P 30fps 10bit LINE Init OK!===\n", ViPipe);
}

View File

@ -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_mis2008_1l.a
TARGET_SO = $(MW_LIB)/libsns_mis2008_1l.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)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,79 @@
#ifndef __MIS2008_1L_CMOS_EX_H_
#define __MIS2008_1L_CMOS_EX_H_
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
#ifdef ARCH_CV182X
#include <linux/cvi_vip_cif.h>
#include <linux/cvi_vip_snsr.h>
#include "cvi_type.h"
#else
#include <linux/cif_uapi.h>
#include <linux/vi_snsr.h>
#include <linux/cvi_type.h>
#endif
#include "cvi_sns_ctrl.h"
enum mis2008_1l_linear_regs_e {
LINEAR_SHS1_0_ADDR,
LINEAR_SHS1_1_ADDR,
LINEAR_SHS1_2_ADDR,
LINEAR_AGAIN_ADDR,
LINEAR_DGAIN_ADDR,
LINEAR_D_FINEGAIN_ADDR,
LINEAR_VMAX_0_ADDR,
LINEAR_VMAX_1_ADDR,
LINEAR_FLIP_MIRROR_ADDR,
LINEAR_REGS_NUM
};
typedef enum _MIS2008_1L_MODE_E {
MIS2008_1L_MODE_1080P30 = 0,
MIS2008_1L_MODE_NUM
} MIS2008_1L_MODE_E;
typedef struct _MIS2008_1L_MODE_S {
ISP_WDR_SIZE_S astImg[2];
CVI_FLOAT f32MaxFps;
CVI_FLOAT f32MinFps;
CVI_U32 u32HtsDef;
CVI_U32 u32VtsDef;
SNS_ATTR_LARGE_S stExp[2];
SNS_ATTR_LARGE_S stAgain[2];
SNS_ATTR_LARGE_S stDgain[2];
char name[64];
} MIS2008_1L_MODE_S;
/****************************************************************************
* external variables and functions *
****************************************************************************/
extern ISP_SNS_STATE_S *g_pastMIS2008_1L[VI_MAX_PIPE_NUM];
extern ISP_SNS_COMMBUS_U g_aunMIS2008_1L_BusInfo[];
extern CVI_U16 g_au16MIS2008_1L_GainMode[];
extern CVI_U16 g_au16MIS2008_1L_L2SMode[];
extern CVI_U8 mis2008_1l_i2c_addr;
extern const CVI_U32 mis2008_1l_addr_byte;
extern const CVI_U32 mis2008_1l_data_byte;
extern void mis2008_1l_init(VI_PIPE ViPipe);
extern void mis2008_1l_exit(VI_PIPE ViPipe);
extern void mis2008_1l_standby(VI_PIPE ViPipe);
extern void mis2008_1l_restart(VI_PIPE ViPipe);
extern int mis2008_1l_write_register(VI_PIPE ViPipe, int addr, int data);
extern int mis2008_1l_read_register(VI_PIPE ViPipe, int addr);
extern void mis2008_1l_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip);
extern int mis2008_1l_probe(VI_PIPE ViPipe);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* End of #ifdef __cplusplus */
#endif /* __MIS2008_1L_CMOS_EX_H_ */

View File

@ -0,0 +1,126 @@
#ifndef __MIS2008_1L_CMOS_PARAM_H_
#define __MIS2008_1L_CMOS_PARAM_H_
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
#ifdef ARCH_CV182X
#include <linux/cvi_vip_cif.h>
#include <linux/cvi_vip_snsr.h>
#include "cvi_type.h"
#else
#include <linux/cif_uapi.h>
#include <linux/vi_snsr.h>
#include <linux/cvi_type.h>
#endif
#include "cvi_sns_ctrl.h"
#include "mis2008_1l_cmos_ex.h"
static const MIS2008_1L_MODE_S g_astMIS2008_1L_mode[MIS2008_1L_MODE_NUM] = {
[MIS2008_1L_MODE_1080P30] = {
.name = "1080p30",
.astImg[0] = {
.stSnsSize = {
.u32Width = 1928,
.u32Height = 1088,
},
.stWndRect = {
.s32X = 8,
.s32Y = 8,
.u32Width = 1920,
.u32Height = 1080,
},
.stMaxSize = {
.u32Width = 1928,
.u32Height = 1088,
},
},
.f32MaxFps = 30,
.f32MinFps = 1, /* 1500 * 30 / 0x7FFF*/
.u32HtsDef = 2200,
.u32VtsDef = 1125,
.stExp[0] = {//exp_time
.u32Min = 1,
.u32Max = 1125 - 1, //exp_max
.u32Def = 128,
.u32Step = 1,
},
.stAgain[0] = {
.u32Min = 1024,
.u32Max = 16128,
.u32Def = 1024,
.u32Step = 1,
},
.stDgain[0] = {
.u32Min = 1024,
.u32Max = 16320,
.u32Def = 1024,
.u32Step = 1,
},
},
};
static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = {
.bUpdate = CVI_TRUE,
.blcAttr = {
.Enable = 1,
.enOpType = OP_TYPE_AUTO,
.stManual = {64, 64, 64, 64, 0, 0, 0, 0
#ifdef ARCH_CV182X
, 1040, 1040, 1040, 1040
#endif
},
.stAuto = {
{64, 64, 64, 64, 64, 64, 64, 64, /*8*/64, 64, 64, 64, 64, 64, 64, 64},
{64, 64, 64, 64, 64, 64, 64, 64, /*8*/64, 64, 64, 64, 64, 64, 64, 64},
{64, 64, 64, 64, 64, 64, 64, 64, /*8*/64, 64, 64, 64, 64, 64, 64, 64},
{64, 64, 64, 64, 64, 64, 64, 64, /*8*/64, 64, 64, 64, 64, 64, 64, 64},
{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
{1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040,
/*8*/1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040},
{1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040,
/*8*/1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040},
{1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040,
/*8*/1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040},
{1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040,
/*8*/1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040},
#endif
},
},
};
struct combo_dev_attr_s mis2008_1l_rx_attr = {
.input_mode = INPUT_MODE_MIPI,
.mac_clk = RX_MAC_CLK_400M,
.mipi_attr = {
.raw_data_type = RAW_DATA_12BIT,
.lane_id = {2, 0, -1, -1, -1},
.pn_swap = {1, 1, 0, 0, 0},
.wdr_mode = CVI_MIPI_WDR_MODE_NONE,
.dphy = {
.enable = 1,
.hs_settle = 8,
},
},
.mclk = {
.cam = 1,
.freq = CAMPLL_FREQ_27M,
},
.devno = 0,
};
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* End of #ifdef __cplusplus */
#endif /* __MIS2008_1L_CMOS_PARAM_H_ */

View File

@ -0,0 +1,393 @@
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <syslog.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#ifdef ARCH_CV182X
#include <linux/cvi_vip_snsr.h>
#include "cvi_comm_video.h"
#else
#include <linux/vi_snsr.h>
#include <linux/cvi_comm_video.h>
#endif
#include "cvi_sns_ctrl.h"
#include "mis2008_1l_cmos_ex.h"
static void mis2008_1l_linear_1080p30_init(VI_PIPE ViPipe);
CVI_U8 mis2008_1l_i2c_addr = 0x30; /* I2C Address of MIS2008_1L */
const CVI_U32 mis2008_1l_addr_byte = 2;
const CVI_U32 mis2008_1l_data_byte = 1;
static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1};
int mis2008_1l_i2c_init(VI_PIPE ViPipe)
{
char acDevFile[16] = {0};
CVI_U8 u8DevNum;
if (g_fd[ViPipe] >= 0)
return CVI_SUCCESS;
int ret;
u8DevNum = g_aunMIS2008_1L_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/cvi_i2c_drv-%u error!\n", u8DevNum);
return CVI_FAILURE;
}
ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, mis2008_1l_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 mis2008_1l_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 mis2008_1l_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 (mis2008_1l_addr_byte == 2)
buf[idx++] = (addr >> 8) & 0xff;
// add address byte 0
buf[idx++] = addr & 0xff;
ret = write(g_fd[ViPipe], buf, mis2008_1l_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, mis2008_1l_data_byte);
if (ret < 0) {
CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n");
return ret;
}
// pack read back data
data = 0;
if (mis2008_1l_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 mis2008_1l_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 (mis2008_1l_addr_byte == 2) {
buf[idx] = (addr >> 8) & 0xff;
idx++;
buf[idx] = addr & 0xff;
idx++;
}
if (mis2008_1l_data_byte == 1) {
buf[idx] = data & 0xff;
idx++;
}
ret = write(g_fd[ViPipe], buf, mis2008_1l_addr_byte + mis2008_1l_data_byte);
if (ret < 0) {
CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n");
return CVI_FAILURE;
}
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 mis2008_1l_standby(VI_PIPE ViPipe)
{
mis2008_1l_write_register(ViPipe, 0x3006, 0x02);
}
void mis2008_1l_restart(VI_PIPE ViPipe)
{
mis2008_1l_write_register(ViPipe, 0x3006, 0x01);
}
void mis2008_1l_default_reg_init(VI_PIPE ViPipe)
{
CVI_U32 i;
for (i = 0; i < g_pastMIS2008_1L[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) {
mis2008_1l_write_register(ViPipe,
g_pastMIS2008_1L[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr,
g_pastMIS2008_1L[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data);
}
}
#define MIS2008_1L_CHIP_ID_HI_ADDR 0x3000
#define MIS2008_1L_CHIP_ID_LO_ADDR 0x3001
#define MIS2008_1L_CHIP_ID 0x2008
int mis2008_1l_probe(VI_PIPE ViPipe)
{
int nVal;
CVI_U16 chip_id;
if (mis2008_1l_i2c_init(ViPipe) != CVI_SUCCESS)
return CVI_FAILURE;
delay_ms(5);
nVal = mis2008_1l_read_register(ViPipe, MIS2008_1L_CHIP_ID_HI_ADDR);
if (nVal < 0) {
CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n");
return nVal;
}
chip_id = (nVal & 0xFF) << 8;
nVal = mis2008_1l_read_register(ViPipe, MIS2008_1L_CHIP_ID_LO_ADDR);
if (nVal < 0) {
CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n");
return nVal;
}
chip_id |= (nVal & 0xFF);
if (chip_id != MIS2008_1L_CHIP_ID) {
CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n");
return CVI_FAILURE;
}
return CVI_SUCCESS;
}
void mis2008_1l_init(VI_PIPE ViPipe)
{
mis2008_1l_i2c_init(ViPipe);
mis2008_1l_linear_1080p30_init(ViPipe);
g_pastMIS2008_1L[ViPipe]->bInit = CVI_TRUE;
}
void mis2008_1l_exit(VI_PIPE ViPipe)
{
mis2008_1l_i2c_exit(ViPipe);
}
/* 1080p30 */
static void mis2008_1l_linear_1080p30_init(VI_PIPE ViPipe)
{
/* [ParaList] */
mis2008_1l_write_register(ViPipe, 0x300a, 0x01);
mis2008_1l_write_register(ViPipe, 0x300a, 0x01);
mis2008_1l_write_register(ViPipe, 0x3006, 0x02);
mis2008_1l_write_register(ViPipe, 0x3201, 0x65);
mis2008_1l_write_register(ViPipe, 0x3200, 0x04);
mis2008_1l_write_register(ViPipe, 0x3203, 0x98);
mis2008_1l_write_register(ViPipe, 0x3202, 0x08);
mis2008_1l_write_register(ViPipe, 0x3205, 0x04);
mis2008_1l_write_register(ViPipe, 0x3204, 0x00);
mis2008_1l_write_register(ViPipe, 0x3207, 0x43);
mis2008_1l_write_register(ViPipe, 0x3206, 0x04);
mis2008_1l_write_register(ViPipe, 0x3209, 0x04);
mis2008_1l_write_register(ViPipe, 0x3208, 0x00);
mis2008_1l_write_register(ViPipe, 0x320b, 0x8b);
mis2008_1l_write_register(ViPipe, 0x320a, 0x07);
mis2008_1l_write_register(ViPipe, 0x3007, 0x00);
mis2008_1l_write_register(ViPipe, 0x3300, 0x21);
mis2008_1l_write_register(ViPipe, 0x3301, 0x00);
mis2008_1l_write_register(ViPipe, 0x3302, 0x00);
mis2008_1l_write_register(ViPipe, 0x3303, 0x06);
mis2008_1l_write_register(ViPipe, 0x330d, 0x00);
mis2008_1l_write_register(ViPipe, 0x330b, 0x00);
mis2008_1l_write_register(ViPipe, 0x330f, 0x0f);
mis2008_1l_write_register(ViPipe, 0x3013, 0x00);
mis2008_1l_write_register(ViPipe, 0x3637, 0x1e);
mis2008_1l_write_register(ViPipe, 0x3900, 0x07);
mis2008_1l_write_register(ViPipe, 0x2107, 0x00);
mis2008_1l_write_register(ViPipe, 0x330e, 0x00);
mis2008_1l_write_register(ViPipe, 0x3900, 0x07);
mis2008_1l_write_register(ViPipe, 0x2108, 0x01);
mis2008_1l_write_register(ViPipe, 0x3c40, 0x8c);
mis2008_1l_write_register(ViPipe, 0x3c42, 0x01);
mis2008_1l_write_register(ViPipe, 0x3b01, 0x3f);
mis2008_1l_write_register(ViPipe, 0x3b03, 0x3f);
mis2008_1l_write_register(ViPipe, 0x3902, 0x01);
mis2008_1l_write_register(ViPipe, 0x3904, 0x00);
mis2008_1l_write_register(ViPipe, 0x3903, 0x00);
mis2008_1l_write_register(ViPipe, 0x3906, 0x1e);
mis2008_1l_write_register(ViPipe, 0x3905, 0x00);
mis2008_1l_write_register(ViPipe, 0x3908, 0x71);
mis2008_1l_write_register(ViPipe, 0x3907, 0x10);
mis2008_1l_write_register(ViPipe, 0x390a, 0xff);
mis2008_1l_write_register(ViPipe, 0x3909, 0x1f);
mis2008_1l_write_register(ViPipe, 0x390c, 0x67);
mis2008_1l_write_register(ViPipe, 0x390b, 0x03);
mis2008_1l_write_register(ViPipe, 0x390e, 0x77);
mis2008_1l_write_register(ViPipe, 0x390d, 0x00);
mis2008_1l_write_register(ViPipe, 0x3910, 0x71);
mis2008_1l_write_register(ViPipe, 0x390f, 0x10);
mis2008_1l_write_register(ViPipe, 0x3912, 0xff);
mis2008_1l_write_register(ViPipe, 0x3911, 0x1f);
mis2008_1l_write_register(ViPipe, 0x3919, 0x00);
mis2008_1l_write_register(ViPipe, 0x3918, 0x00);
mis2008_1l_write_register(ViPipe, 0x391b, 0x91);
mis2008_1l_write_register(ViPipe, 0x391a, 0x01);
mis2008_1l_write_register(ViPipe, 0x3983, 0x5a);
mis2008_1l_write_register(ViPipe, 0x3982, 0x00);
mis2008_1l_write_register(ViPipe, 0x3985, 0x0f);
mis2008_1l_write_register(ViPipe, 0x3984, 0x00);
mis2008_1l_write_register(ViPipe, 0x391d, 0x00);
mis2008_1l_write_register(ViPipe, 0x391c, 0x00);
mis2008_1l_write_register(ViPipe, 0x391f, 0x65);
mis2008_1l_write_register(ViPipe, 0x391e, 0x10);
mis2008_1l_write_register(ViPipe, 0x3921, 0xff);
mis2008_1l_write_register(ViPipe, 0x3920, 0x1f);
mis2008_1l_write_register(ViPipe, 0x3923, 0xff);
mis2008_1l_write_register(ViPipe, 0x3922, 0x1f);
mis2008_1l_write_register(ViPipe, 0x3932, 0x00);
mis2008_1l_write_register(ViPipe, 0x3931, 0x00);
mis2008_1l_write_register(ViPipe, 0x3934, 0x65);
mis2008_1l_write_register(ViPipe, 0x3933, 0x01);
mis2008_1l_write_register(ViPipe, 0x393f, 0x6c);
mis2008_1l_write_register(ViPipe, 0x393e, 0x00);
mis2008_1l_write_register(ViPipe, 0x3941, 0x67);
mis2008_1l_write_register(ViPipe, 0x3940, 0x00);
mis2008_1l_write_register(ViPipe, 0x3943, 0x55);
mis2008_1l_write_register(ViPipe, 0x3942, 0x01);
mis2008_1l_write_register(ViPipe, 0x3945, 0xc2);
mis2008_1l_write_register(ViPipe, 0x3944, 0x02);
mis2008_1l_write_register(ViPipe, 0x3925, 0x95);
mis2008_1l_write_register(ViPipe, 0x3924, 0x00);
mis2008_1l_write_register(ViPipe, 0x3927, 0xe1);
mis2008_1l_write_register(ViPipe, 0x3926, 0x02);
mis2008_1l_write_register(ViPipe, 0x3947, 0x74);
mis2008_1l_write_register(ViPipe, 0x3946, 0x01);
mis2008_1l_write_register(ViPipe, 0x3949, 0xda);
mis2008_1l_write_register(ViPipe, 0x3948, 0x0e);
mis2008_1l_write_register(ViPipe, 0x394b, 0x42);
mis2008_1l_write_register(ViPipe, 0x394a, 0x03);
mis2008_1l_write_register(ViPipe, 0x394d, 0xf2);
mis2008_1l_write_register(ViPipe, 0x394c, 0x01);
mis2008_1l_write_register(ViPipe, 0x3913, 0x01);
mis2008_1l_write_register(ViPipe, 0x3915, 0x0f);
mis2008_1l_write_register(ViPipe, 0x3914, 0x00);
mis2008_1l_write_register(ViPipe, 0x3917, 0x67);
mis2008_1l_write_register(ViPipe, 0x3916, 0x03);
mis2008_1l_write_register(ViPipe, 0x392a, 0x1e);
mis2008_1l_write_register(ViPipe, 0x3929, 0x00);
mis2008_1l_write_register(ViPipe, 0x392c, 0x0f);
mis2008_1l_write_register(ViPipe, 0x392b, 0x00);
mis2008_1l_write_register(ViPipe, 0x392e, 0x0f);
mis2008_1l_write_register(ViPipe, 0x392d, 0x00);
mis2008_1l_write_register(ViPipe, 0x3930, 0x6e);
mis2008_1l_write_register(ViPipe, 0x392f, 0x03);
mis2008_1l_write_register(ViPipe, 0x397f, 0x00);
mis2008_1l_write_register(ViPipe, 0x397e, 0x00);
mis2008_1l_write_register(ViPipe, 0x3981, 0x77);
mis2008_1l_write_register(ViPipe, 0x3980, 0x00);
mis2008_1l_write_register(ViPipe, 0x395d, 0x80);
mis2008_1l_write_register(ViPipe, 0x395c, 0x10);
mis2008_1l_write_register(ViPipe, 0x3962, 0x9e);
mis2008_1l_write_register(ViPipe, 0x3961, 0x10);
mis2008_1l_write_register(ViPipe, 0x3967, 0x50);
mis2008_1l_write_register(ViPipe, 0x3977, 0x22);
mis2008_1l_write_register(ViPipe, 0x3976, 0x00);
mis2008_1l_write_register(ViPipe, 0x3978, 0x00);
mis2008_1l_write_register(ViPipe, 0x3979, 0x04);
mis2008_1l_write_register(ViPipe, 0x396d, 0xc2);
mis2008_1l_write_register(ViPipe, 0x396c, 0x02);
mis2008_1l_write_register(ViPipe, 0x396f, 0xc2);
mis2008_1l_write_register(ViPipe, 0x396e, 0x02);
mis2008_1l_write_register(ViPipe, 0x3971, 0xc2);
mis2008_1l_write_register(ViPipe, 0x3970, 0x02);
mis2008_1l_write_register(ViPipe, 0x3973, 0xc2);
mis2008_1l_write_register(ViPipe, 0x3972, 0x02);
mis2008_1l_write_register(ViPipe, 0x3900, 0x01);
mis2008_1l_write_register(ViPipe, 0x3600, 0x00);
mis2008_1l_write_register(ViPipe, 0x3707, 0x00);
mis2008_1l_write_register(ViPipe, 0x3708, 0x80);
mis2008_1l_write_register(ViPipe, 0x3709, 0x00);
mis2008_1l_write_register(ViPipe, 0x370a, 0x80);
mis2008_1l_write_register(ViPipe, 0x370b, 0x00);
mis2008_1l_write_register(ViPipe, 0x370c, 0x80);
mis2008_1l_write_register(ViPipe, 0x370d, 0x00);
mis2008_1l_write_register(ViPipe, 0x370e, 0x80);
mis2008_1l_write_register(ViPipe, 0x3012, 0x01);
mis2008_1l_write_register(ViPipe, 0x3600, 0x13);
mis2008_1l_write_register(ViPipe, 0x3601, 0x02);
mis2008_1l_write_register(ViPipe, 0x360e, 0x00);
mis2008_1l_write_register(ViPipe, 0x360f, 0x00);
mis2008_1l_write_register(ViPipe, 0x3610, 0x02);
mis2008_1l_write_register(ViPipe, 0x3707, 0x00);
mis2008_1l_write_register(ViPipe, 0x3708, 0x40);
mis2008_1l_write_register(ViPipe, 0x3709, 0x00);
mis2008_1l_write_register(ViPipe, 0x370a, 0x40);
mis2008_1l_write_register(ViPipe, 0x370b, 0x00);
mis2008_1l_write_register(ViPipe, 0x370c, 0x40);
mis2008_1l_write_register(ViPipe, 0x370d, 0x00);
mis2008_1l_write_register(ViPipe, 0x370e, 0x40);
mis2008_1l_write_register(ViPipe, 0x3800, 0x01);
mis2008_1l_write_register(ViPipe, 0x3a03, 0x03);
mis2008_1l_write_register(ViPipe, 0x3a02, 0x0b);
mis2008_1l_write_register(ViPipe, 0x3a08, 0x34);
mis2008_1l_write_register(ViPipe, 0x3a1b, 0x54);
mis2008_1l_write_register(ViPipe, 0x3a1e, 0x80);
mis2008_1l_write_register(ViPipe, 0x3100, 0x04);
mis2008_1l_write_register(ViPipe, 0x3101, 0x64);
mis2008_1l_write_register(ViPipe, 0x3a1c, 0x10);
mis2008_1l_write_register(ViPipe, 0x3a0C, 0x04);
mis2008_1l_write_register(ViPipe, 0x3a0D, 0x12);
mis2008_1l_write_register(ViPipe, 0x3a0E, 0x15);
mis2008_1l_write_register(ViPipe, 0x3a0F, 0x18);
mis2008_1l_write_register(ViPipe, 0x3a10, 0x20);
mis2008_1l_write_register(ViPipe, 0x3a11, 0x3c);
mis2008_1l_write_register(ViPipe, 0x3a19, 0x10);
mis2008_1l_write_register(ViPipe, 0x3006, 0x00);
mis2008_1l_default_reg_init(ViPipe);
delay_ms(100);
printf("ViPipe:%d,===MIS2008_1L 1080P 30fps 12bit LINE Init OK!===\n", ViPipe);
}

View File

@ -39,12 +39,12 @@ static const SC2331_1L_MODE_S g_astSC2331_1L_mode[SC2331_1L_MODE_NUM] = {
},
},
.f32MaxFps = 30,
.f32MinFps = 0.51, /* 1125 * 30 / 0x7FFF */
.u32HtsDef = 2560,
.u32VtsDef = 1530,
.f32MinFps = 0.51, /* 1125 * 30 / 0xFFFF */
.u32HtsDef = 2200,
.u32VtsDef = 1125,
.stExp[0] = {
.u16Min = 2,//3
.u16Max = 1530*2 - 13,
.u16Max = 1125 - 13,
.u16Def = 400,
.u16Step = 1,
},

View File

@ -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_sc2336_1l.a
TARGET_SO = $(MW_LIB)/libsns_sc2336_1l.so
EXTRA_CFLAGS = $(INCS)
EXTRA_LDFLAGS =
.PHONY : clean all
all : $(TARGET_A) $(TARGET_SO)
$(SDIR)/%.o: $(SDIR)/%.c
@$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@
@echo [$(notdir $(CC))] $(notdir $@)
$(TARGET_A): $(OBJS)
@$(AR) $(ARFLAGS) $@ $(OBJ)
@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)

View File

@ -0,0 +1,905 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <syslog.h>
#include <errno.h>
#ifdef ARCH_CV182X
#include "cvi_type.h"
#include "cvi_comm_video.h"
#include <linux/cvi_vip_snsr.h>
#else
#include <linux/cvi_type.h>
#include <linux/cvi_comm_video.h>
#include <linux/vi_snsr.h>
#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 "sc2336_1L_cmos_ex.h"
#include "sc2336_1L_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 SC2336_1L_ID 35
#define SENSOR_SC2336_1L_WIDTH 1920
#define SENSOR_SC2336_1L_HEIGHT 1080
/****************************************************************************
* global variables *
****************************************************************************/
ISP_SNS_STATE_S *g_pastSC2336_1L[VI_MAX_PIPE_NUM] = {CVI_NULL};
#define SC2336_1L_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastSC2336_1L[dev])
#define SC2336_1L_SENSOR_SET_CTX(dev, pstCtx) (g_pastSC2336_1L[dev] = pstCtx)
#define SC2336_1L_SENSOR_RESET_CTX(dev) (g_pastSC2336_1L[dev] = CVI_NULL)
ISP_SNS_COMMBUS_U g_aunSC2336_1L_BusInfo[VI_MAX_PIPE_NUM] = {
[0] = { .s8I2cDev = 0},
[1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1}
};
CVI_U16 g_au16SC2336_1L_GainMode[VI_MAX_PIPE_NUM] = {0};
CVI_U16 g_au16SC2336_1L_L2SMode[VI_MAX_PIPE_NUM] = {0};
SC2336_1L_STATE_S g_astSC2336_1L_State[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);
/*****SC2336_1L Lines Range*****/
#define SC2336_1L_FULL_LINES_MAX (0xFFFF)
/*****SC2336_1L Register Address*****/
#define SC2336_1L_SHS1_0_ADDR 0x3E00
#define SC2336_1L_SHS1_1_ADDR 0x3E01
#define SC2336_1L_SHS1_2_ADDR 0x3E02
#define SC2336_1L_AGAIN0_ADDR 0x3E09
#define SC2336_1L_DGAIN0_ADDR 0x3E06
#define SC2336_1L_VMAX_ADDR 0x320E
#define SC2336_1L_TABLE_END 0xFFFF
#define SC2336_1L_RES_IS_1080P(w, h) ((w) <= 1920 && (h) <= 1080)
static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft)
{
const SC2336_1L_MODE_S *pstMode;
ISP_SNS_STATE_S *pstSnsState = CVI_NULL;
CMOS_CHECK_POINTER(pstAeSnsDft);
SC2336_1L_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER(pstSnsState);
pstMode = &g_astSC2336_1L_mode[pstSnsState->u8ImgMode];
#if 0
memset(&pstAeSnsDft->stAERouteAttr, 0, sizeof(ISP_AE_ROUTE_S));
#endif
pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd;
pstAeSnsDft->u32FlickerFreq = 50 * 256;
pstAeSnsDft->u32FullLinesMax = SC2336_1L_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_DB;
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];
pstAeSnsDft->u32SnsStableFrame = 0;
#if 0
pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0;
pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0;
pstAeSnsDft->bAERouteExValid = CVI_FALSE;
pstAeSnsDft->stAERouteAttr.u32TotalNum = 0;
pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0;
#endif
switch (pstSnsState->enWDRMode) {
default:
case WDR_MODE_NONE: /*linear mode*/
pstAeSnsDft->f32Fps = pstMode->f32MaxFps;
pstAeSnsDft->f32MinFps = pstMode->f32MinFps;
pstAeSnsDft->au8HistThresh[0] = 0xd;
pstAeSnsDft->au8HistThresh[1] = 0x28;
pstAeSnsDft->au8HistThresh[2] = 0x60;
pstAeSnsDft->au8HistThresh[3] = 0x80;
pstAeSnsDft->u32MaxAgain = pstMode->stAgain[0].u16Max;
pstAeSnsDft->u32MinAgain = pstMode->stAgain[0].u16Min;
pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain;
pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain;
pstAeSnsDft->u32MaxDgain = pstMode->stDgain[0].u16Max;
pstAeSnsDft->u32MinDgain = pstMode->stDgain[0].u16Min;
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] : 76151;
pstAeSnsDft->u32MaxIntTime = pstMode->stExp[0].u16Max;
pstAeSnsDft->u32MinIntTime = pstMode->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);
SC2336_1L_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER(pstSnsState);
u32Vts = g_astSC2336_1L_mode[pstSnsState->u8ImgMode].u32VtsDef;
pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg;
f32MaxFps = g_astSC2336_1L_mode[pstSnsState->u8ImgMode].f32MaxFps;
f32MinFps = g_astSC2336_1L_mode[pstSnsState->u8ImgMode].f32MinFps;
switch (pstSnsState->u8ImgMode) {
case SC2336_1L_MODE_1080P30:
if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) {
u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps);
} else {
CVI_TRACE_SNS(CVI_DBG_ERR, "Not support Fps: %f\n", f32Fps);
return CVI_FAILURE;
}
u32VMAX = (u32VMAX > SC2336_1L_FULL_LINES_MAX) ? SC2336_1L_FULL_LINES_MAX : u32VMAX;
break;
default:
CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode);
return CVI_FAILURE;
}
pstSnsState->u32FLStd = u32VMAX;
if (pstSnsState->enWDRMode == WDR_MODE_NONE) {
pstSnsRegsInfo->astI2cData[LINEAR_VMAX_0_ADDR].u32Data = ((u32VMAX & 0xFF00) >> 8);
pstSnsRegsInfo->astI2cData[LINEAR_VMAX_1_ADDR].u32Data = (u32VMAX & 0xFF);
}
pstAeSnsDft->f32Fps = f32Fps;
pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2;
pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd;
pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 6;
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;
SC2336_1L_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER(pstSnsState);
CMOS_CHECK_POINTER(u32IntTime);
pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg;
if (WDR_MODE_2To1_LINE != pstSnsState->enWDRMode) {
CVI_U32 u32TmpIntTime = u32IntTime[0];
/* linear exposure reg range:
* min : 1
* max : (vts - 6)
* step : 1
*/
u32TmpIntTime = (u32TmpIntTime > (pstSnsState->au32FL[0] - 6)) ?
(pstSnsState->au32FL[0] - 6) : u32TmpIntTime;
if (!u32TmpIntTime)
u32TmpIntTime = 1;
pstSnsRegsInfo->astI2cData[LINEAR_SHS1_0_ADDR].u32Data = ((u32TmpIntTime & 0xF000) >> 12);
pstSnsRegsInfo->astI2cData[LINEAR_SHS1_1_ADDR].u32Data = ((u32TmpIntTime & 0x0FF0) >> 4);
pstSnsRegsInfo->astI2cData[LINEAR_SHS1_2_ADDR].u32Data = (u32TmpIntTime & 0xF) << 4;
}
return CVI_SUCCESS;
}
struct gain_tbl_info_s {
CVI_U16 gainMax;
CVI_U16 idxBase;
CVI_U8 regGain;
CVI_U8 regGainFineBase;
CVI_U8 regGainFineStep;
};
static CVI_U32 Again_table[] = {
1024, 2048, 4096, 8192, 16384, 32768
};
static CVI_U32 AgainReg[] = {
0x00, 0x08, 0x09, 0x0b, 0x0f, 0x1f
};
static struct gain_tbl_info_s DgainInfo[] = {
{
.gainMax = 2016,
.idxBase = 0,
.regGain = 0x00,
.regGainFineBase = 0x80,
.regGainFineStep = 4,
},
{
.gainMax = 4032,
.idxBase = 32,
.regGain = 0x01,
.regGainFineBase = 0x80,
.regGainFineStep = 4,
},
{
.gainMax = 4096,
.idxBase = 64,
.regGain = 0x03,
.regGainFineBase = 0x80,
.regGainFineStep = 0,
},
};
static CVI_U32 Dgain_table[] = {
1024, 1056, 1088, 1120, 1152, 1184, 1216, 1248, 1280, 1312, 1344, 1376, 1408, 1440, 1472, 1504,
1536, 1568, 1600, 1632, 1664, 1696, 1728, 1760, 1792, 1824, 1856, 1888, 1920, 1952, 1984, 2016,
2048, 2112, 2176, 2240, 2304, 2368, 2432, 2496, 2560, 2624, 2688, 2752, 2816, 2880, 2944, 3008,
3072, 3136, 3200, 3264, 3328, 3392, 3456, 3520, 3584, 3648, 3712, 3776, 3840, 3904, 3968, 4032,
4096,
};
static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb)
{
CVI_U32 tableSize = sizeof(Again_table) / sizeof(CVI_U32);
(void)ViPipe;
CMOS_CHECK_POINTER(pu32AgainLin);
CMOS_CHECK_POINTER(pu32AgainDb);
if (*pu32AgainLin >= Again_table[tableSize - 1]) {
*pu32AgainLin = Again_table[tableSize - 1];
*pu32AgainDb = AgainReg[tableSize - 1];
return CVI_SUCCESS;
}
for (CVI_U32 i = 1; i < tableSize; i++) {
if (*pu32AgainLin < Again_table[i]) {
*pu32AgainLin = Again_table[i - 1];
*pu32AgainDb = AgainReg[i - 1];
break;
}
}
return CVI_SUCCESS;
}
static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb)
{
CVI_U32 tableSize = sizeof(Dgain_table) / sizeof(CVI_U32);
(void)ViPipe;
CMOS_CHECK_POINTER(pu32DgainLin);
CMOS_CHECK_POINTER(pu32DgainDb);
if (*pu32DgainLin >= Dgain_table[tableSize - 1]) {
*pu32DgainLin = Dgain_table[tableSize - 1];
*pu32DgainDb = tableSize - 1;
return CVI_SUCCESS;
}
for (CVI_U32 i = 1; i < tableSize; i++) {
if (*pu32DgainLin < Dgain_table[i]) {
*pu32DgainLin = Dgain_table[i - 1];
*pu32DgainDb = i - 1;
break;
}
}
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;
struct gain_tbl_info_s *info;
CVI_S32 i = 0, tbl_num = 0;
SC2336_1L_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER(pstSnsState);
CMOS_CHECK_POINTER(pu32Again);
CMOS_CHECK_POINTER(pu32Dgain);
pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg;
u32Again = pu32Again[0];
u32Dgain = pu32Dgain[0];
if (pstSnsState->enWDRMode == WDR_MODE_NONE) {
/* linear mode */
/* Again. */
pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_0_ADDR].u32Data = (u32Again & 0xFF);
/* find Dgain register setting. */
tbl_num = sizeof(DgainInfo)/sizeof(struct gain_tbl_info_s);
for (i = tbl_num - 1; i >= 0; i--) {
info = &DgainInfo[i];
if (u32Dgain >= info->idxBase)
break;
}
pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_0_ADDR].u32Data = (info->regGain & 0xFF);
u32Dgain = info->regGainFineBase + (u32Dgain - info->idxBase) * info->regGainFineStep;
pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_1_ADDR].u32Data = (u32Dgain & 0xFF);
}
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_slow_framerate_set = cmos_slow_framerate_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)
{
(void) ViPipe;
CMOS_CHECK_POINTER(pstAwbSnsDft);
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)
{
(void) ViPipe;
memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S));
return CVI_SUCCESS;
}
static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc)
{
(void) ViPipe;
CMOS_CHECK_POINTER(pstBlc);
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 SC2336_1L_MODE_S *pstMode = CVI_NULL;
ISP_SNS_STATE_S *pstSnsState = CVI_NULL;
SC2336_1L_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER(pstSnsState);
pstMode = &g_astSC2336_1L_mode[pstSnsState->u8ImgMode];
if (pstSnsState->enWDRMode != WDR_MODE_NONE) {
pstIspCfg->frm_num = 2;
memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S));
memcpy(&pstIspCfg->img_size[1], &pstMode->astImg[1], sizeof(ISP_WDR_SIZE_S));
} else {
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;
SC2336_1L_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER(pstSnsState);
pstSnsState->bSyncInit = CVI_FALSE;
switch (u8Mode) {
case WDR_MODE_NONE:
pstSnsState->u8ImgMode = SC2336_1L_MODE_1080P30;
pstSnsState->enWDRMode = WDR_MODE_NONE;
pstSnsState->u32FLStd = g_astSC2336_1L_mode[pstSnsState->u8ImgMode].u32VtsDef;
syslog(LOG_INFO, "linear mode\n");
break;
default:
CVI_TRACE_SNS(CVI_DBG_ERR, "NOT support this 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_U32 sensor_cmp_cif_wdr(ISP_SNS_CIF_INFO_S *pstWdr1, ISP_SNS_CIF_INFO_S *pstWdr2)
{
if (pstWdr1->wdr_manual.l2s_distance != pstWdr2->wdr_manual.l2s_distance)
goto _mismatch;
if (pstWdr1->wdr_manual.lsef_length != pstWdr2->wdr_manual.lsef_length)
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);
SC2336_1L_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_aunSC2336_1L_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 = sc2336_1L_i2c_addr;
pstI2c_data[i].u32AddrByteNum = sc2336_1L_addr_byte;
pstI2c_data[i].u32DataByteNum = sc2336_1L_data_byte;
}
//DOL 2t1 Mode Regs
switch (pstSnsState->enWDRMode) {
case WDR_MODE_2To1_LINE:
break;
default:
//Linear Mode Regs
pstI2c_data[LINEAR_SHS1_0_ADDR].u32RegAddr = SC2336_1L_SHS1_0_ADDR;
pstI2c_data[LINEAR_SHS1_1_ADDR].u32RegAddr = SC2336_1L_SHS1_1_ADDR;
pstI2c_data[LINEAR_SHS1_2_ADDR].u32RegAddr = SC2336_1L_SHS1_2_ADDR;
pstI2c_data[LINEAR_AGAIN_0_ADDR].u32RegAddr = SC2336_1L_AGAIN0_ADDR;
pstI2c_data[LINEAR_DGAIN_0_ADDR].u32RegAddr = SC2336_1L_DGAIN0_ADDR;
pstI2c_data[LINEAR_DGAIN_1_ADDR].u32RegAddr = SC2336_1L_DGAIN0_ADDR + 1;
pstI2c_data[LINEAR_VMAX_0_ADDR].u32RegAddr = SC2336_1L_VMAX_ADDR;
pstI2c_data[LINEAR_VMAX_1_ADDR].u32RegAddr = SC2336_1L_VMAX_ADDR + 1;
break;
}
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 {
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 {
pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE;
pstCfg0->snsCfg.need_update = CVI_TRUE;
}
}
/* check update isp crop or not */
pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ?
CVI_TRUE : CVI_FALSE);
/* check update cif wdr manual or not */
pstCfg0->cifCfg.need_update = (sensor_cmp_cif_wdr(&pstCfg0->cifCfg, &pstCfg1->cifCfg) ?
CVI_TRUE : CVI_FALSE);
}
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);
SC2336_1L_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 (SC2336_1L_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) {
u8SensorImageMode = SC2336_1L_MODE_1080P30;
} 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 {
}
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_global_init(VI_PIPE ViPipe)
{
ISP_SNS_STATE_S *pstSnsState = CVI_NULL;
const SC2336_1L_MODE_S *pstMode = CVI_NULL;
SC2336_1L_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER_VOID(pstSnsState);
pstSnsState->bInit = CVI_FALSE;
pstSnsState->bSyncInit = CVI_FALSE;
pstSnsState->u8ImgMode = SC2336_1L_MODE_1080P30;
pstSnsState->enWDRMode = WDR_MODE_NONE;
pstMode = &g_astSC2336_1L_mode[pstSnsState->u8ImgMode];
pstSnsState->u32FLStd = pstMode->u32VtsDef;
pstSnsState->au32FL[0] = pstMode->u32VtsDef;
pstSnsState->au32FL[1] = pstMode->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;
SC2336_1L_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER(pstSnsState);
CMOS_CHECK_POINTER(pstRxAttr);
memcpy(pstRxAttr, &sc2336_1L_rx_attr, sizeof(*pstRxAttr));
pstRxAttr->img_size.width = g_astSC2336_1L_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width;
pstRxAttr->img_size.height = g_astSC2336_1L_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 = &sc2336_1L_rx_attr;
int i;
CMOS_CHECK_POINTER(pstRxInitAttr);
if (pstRxInitAttr->stMclkAttr.bMclkEn)
pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk;
if (pstRxInitAttr->MipiDev >= 2)
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 = sc2336_1L_init;
pstSensorExpFunc->pfn_cmos_sensor_exit = sc2336_1L_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_S32 sc2336_1L_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo)
{
g_aunSC2336_1L_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev;
return CVI_SUCCESS;
}
static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe)
{
ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL;
SC2336_1L_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));
SC2336_1L_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx);
return CVI_SUCCESS;
}
static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe)
{
ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL;
SC2336_1L_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx);
SENSOR_FREE(pastSnsStateCtx);
SC2336_1L_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 = SC2336_1L_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, SC2336_1L_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, SC2336_1L_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, SC2336_1L_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_au16SC2336_1L_GainMode[ViPipe] = pstInitAttr->enGainMode;
g_au16SC2336_1L_L2SMode[ViPipe] = pstInitAttr->enL2SMode;
return CVI_SUCCESS;
}
ISP_SNS_OBJ_S stSnsSC2336_1L_Obj = {
.pfnRegisterCallback = sensor_register_callback,
.pfnUnRegisterCallback = sensor_unregister_callback,
.pfnStandby = sc2336_1L_standby,
.pfnRestart = sc2336_1L_restart,
.pfnMirrorFlip = sc2336_1L_mirror_flip,
.pfnWriteReg = sc2336_1L_write_register,
.pfnReadReg = sc2336_1L_read_register,
.pfnSetBusInfo = sc2336_1L_set_bus_info,
.pfnSetInit = sensor_set_init,
.pfnPatchRxAttr = sensor_patch_rx_attr,
.pfnPatchI2cAddr = CVI_NULL,
.pfnGetRxAttr = sensor_rx_attr,
.pfnExpSensorCb = cmos_init_sensor_exp_function,
.pfnExpAeCb = cmos_init_ae_exp_function,
.pfnSnsProbe = sc2336_1L_probe,
};

View File

@ -0,0 +1,85 @@
#ifndef __SC2336_1L_CMOS_EX_H_
#define __SC2336_1L_CMOS_EX_H_
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
#ifdef ARCH_CV182X
#include <linux/cvi_vip_cif.h>
#include <linux/cvi_vip_snsr.h>
#include "cvi_type.h"
#else
#include <linux/cif_uapi.h>
#include <linux/vi_snsr.h>
#include <linux/cvi_type.h>
#endif
#include "cvi_sns_ctrl.h"
enum sc2336_1L_linear_regs_e {
LINEAR_SHS1_0_ADDR,
LINEAR_SHS1_1_ADDR,
LINEAR_SHS1_2_ADDR,
LINEAR_AGAIN_0_ADDR,
LINEAR_DGAIN_0_ADDR,
LINEAR_DGAIN_1_ADDR,
LINEAR_VMAX_0_ADDR,
LINEAR_VMAX_1_ADDR,
LINEAR_REGS_NUM
};
typedef enum _SC2336_1L_MODE_E {
SC2336_1L_MODE_1080P30 = 0,
SC2336_1L_MODE_LINEAR_NUM,
SC2336_1L_MODE_NUM
} SC2336_1L_MODE_E;
typedef struct _SC2336_1L_STATE_S {
CVI_U32 u32Sexp_MAX; /* (2*{16h3e23,16h3e24} 'd10)/2 */
} SC2336_1L_STATE_S;
typedef struct _SC2336_1L_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_S stAgain[2];
SNS_ATTR_S stDgain[2];
CVI_U16 u16SexpMaxReg; /* {16h3e23,16h3e24} */
char name[64];
} SC2336_1L_MODE_S;
/****************************************************************************
* external variables and functions *
****************************************************************************/
extern ISP_SNS_STATE_S *g_pastSC2336_1L[VI_MAX_PIPE_NUM];
extern ISP_SNS_COMMBUS_U g_aunSC2336_1L_BusInfo[];
extern CVI_U16 g_au16SC2336_1L_GainMode[];
extern CVI_U16 g_au16SC2336_1L_L2SMode[];
extern const CVI_U8 sc2336_1L_i2c_addr;
extern const CVI_U32 sc2336_1L_addr_byte;
extern const CVI_U32 sc2336_1L_data_byte;
extern void sc2336_1L_init(VI_PIPE ViPipe);
extern void sc2336_1L_exit(VI_PIPE ViPipe);
extern void sc2336_1L_standby(VI_PIPE ViPipe);
extern void sc2336_1L_restart(VI_PIPE ViPipe);
extern int sc2336_1L_write_register(VI_PIPE ViPipe, int addr, int data);
extern int sc2336_1L_read_register(VI_PIPE ViPipe, int addr);
extern void sc2336_1L_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip);
extern int sc2336_1L_probe(VI_PIPE ViPipe);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* End of #ifdef __cplusplus */
#endif /* __SC2336_1L_CMOS_EX_H_ */

View File

@ -0,0 +1,125 @@
#ifndef __SC2336_1L_CMOS_PARAM_H_
#define __SC2336_1L_CMOS_PARAM_H_
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
#ifdef ARCH_CV182X
#include <linux/cvi_vip_cif.h>
#include <linux/cvi_vip_snsr.h>
#include "cvi_type.h"
#else
#include <linux/cif_uapi.h>
#include <linux/vi_snsr.h>
#include <linux/cvi_type.h>
#endif
#include "cvi_sns_ctrl.h"
#include "sc2336_1L_cmos_ex.h"
static const SC2336_1L_MODE_S g_astSC2336_1L_mode[SC2336_1L_MODE_NUM] = {
[SC2336_1L_MODE_1080P30] = {
.name = "1080p30",
.astImg[0] = {
.stSnsSize = {
.u32Width = 1920,
.u32Height = 1080,
},
.stWndRect = {
.s32X = 0,
.s32Y = 0,
.u32Width = 1920,
.u32Height = 1080,
},
.stMaxSize = {
.u32Width = 1920,
.u32Height = 1080,
},
},
.f32MaxFps = 30,
.f32MinFps = 0.51, /* 1125 * 30 / 0xFFFF*/
.u32HtsDef = 2560,
.u32VtsDef = 1125,
.stExp[0] = {
.u16Min = 1,
.u16Max = 12184 - 6,
.u16Def = 400,
.u16Step = 1,
},
.stAgain[0] = {
.u16Min = 1024,
.u16Max = 32768,
.u16Def = 1024,
.u16Step = 1,
},
.stDgain[0] = {
.u16Min = 1024,
.u16Max = 4096,
.u16Def = 1024,
.u16Step = 1,
},
},
};
static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = {
.bUpdate = CVI_TRUE,
.blcAttr = {
.Enable = 1,
.enOpType = OP_TYPE_AUTO,
.stManual = {260, 260, 260, 260, 0, 0, 0, 0
#ifdef ARCH_CV182X
, 1093, 1093, 1093, 1093
#endif
},
.stAuto = {
{260, 260, 260, 260, 260, 252, 252, 252, /*8*/260, 260, 260, 260, 260, 260, 260, 260},
{260, 260, 260, 260, 260, 252, 252, 252, /*8*/260, 260, 260, 260, 260, 260, 260, 260},
{260, 260, 260, 260, 260, 252, 252, 252, /*8*/260, 260, 260, 260, 260, 260, 260, 260},
{260, 260, 260, 260, 260, 252, 252, 252, /*8*/260, 260, 260, 260, 260, 260, 260, 260},
{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, 1091, 1091, 1091,
/*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093},
{1093, 1093, 1093, 1093, 1093, 1091, 1091, 1091,
/*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093},
{1093, 1093, 1093, 1093, 1093, 1091, 1091, 1091,
/*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093},
{1093, 1093, 1093, 1093, 1093, 1091, 1091, 1091,
/*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093},
#endif
},
},
};
struct combo_dev_attr_s sc2336_1L_rx_attr = {
.input_mode = INPUT_MODE_MIPI,
.mac_clk = RX_MAC_CLK_200M,
.mipi_attr = {
.raw_data_type = RAW_DATA_10BIT,
.lane_id = {2, 0, -1, -1, -1},
.wdr_mode = CVI_MIPI_WDR_MODE_NONE,
.dphy = {
.enable = 1,
.hs_settle = 8,
}
},
.mclk = {
.cam = 0,
.freq = CAMPLL_FREQ_27M,
},
.devno = 0,
};
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* End of #ifdef __cplusplus */
#endif /* __SC2336_1L_CMOS_PARAM_H_ */

View File

@ -0,0 +1,420 @@
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <syslog.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#ifdef ARCH_CV182X
#include <linux/cvi_vip_snsr.h>
#include "cvi_comm_video.h"
#else
#include <linux/vi_snsr.h>
#include <linux/cvi_comm_video.h>
#endif
#include "cvi_sns_ctrl.h"
#include "sc2336_1L_cmos_ex.h"
static void sc2336_1L_linear_1080p30_init(VI_PIPE ViPipe);
const CVI_U8 sc2336_1L_i2c_addr = 0x30; /* I2C Address of SC2336_1L */
const CVI_U32 sc2336_1L_addr_byte = 2;
const CVI_U32 sc2336_1L_data_byte = 1;
static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1};
int sc2336_1L_i2c_init(VI_PIPE ViPipe)
{
char acDevFile[16] = {0};
CVI_U8 u8DevNum;
if (g_fd[ViPipe] >= 0)
return CVI_SUCCESS;
int ret;
u8DevNum = g_aunSC2336_1L_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/cvi_i2c_drv-%u error!\n", u8DevNum);
return CVI_FAILURE;
}
ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, sc2336_1L_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 sc2336_1L_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 sc2336_1L_read_register(VI_PIPE ViPipe, int addr)
{
int ret, data;
char buf[8];
int idx = 0;
if (g_fd[ViPipe] < 0)
return CVI_FAILURE;
if (sc2336_1L_addr_byte == 2)
buf[idx++] = (addr >> 8) & 0xff;
// add address byte 0
buf[idx++] = addr & 0xff;
ret = write(g_fd[ViPipe], buf, sc2336_1L_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, sc2336_1L_data_byte);
if (ret < 0) {
CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n");
return ret;
}
// pack read back data
data = 0;
if (sc2336_1L_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 sc2336_1L_write_register(VI_PIPE ViPipe, int addr, int data)
{
int idx = 0;
int ret;
char buf[8];
if (g_fd[ViPipe] < 0)
return CVI_SUCCESS;
if (sc2336_1L_addr_byte == 2) {
buf[idx] = (addr >> 8) & 0xff;
idx++;
buf[idx] = addr & 0xff;
idx++;
}
if (sc2336_1L_data_byte == 1) {
buf[idx] = data & 0xff;
idx++;
}
ret = write(g_fd[ViPipe], buf, sc2336_1L_addr_byte + sc2336_1L_data_byte);
if (ret < 0) {
CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n");
return CVI_FAILURE;
}
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 sc2336_1L_prog(VI_PIPE ViPipe, int *rom)
{
int i = 0;
while (1) {
int lookup = rom[i++];
int addr = (lookup >> 16) & 0xFFFF;
int data = lookup & 0xFFFF;
if (addr == 0xFFFE)
delay_ms(data);
else if (addr != 0xFFFF)
sc2336_1L_write_register(ViPipe, addr, data);
}
}
void sc2336_1L_standby(VI_PIPE ViPipe)
{
sc2336_1L_write_register(ViPipe, 0x0100, 0x00);
}
void sc2336_1L_restart(VI_PIPE ViPipe)
{
sc2336_1L_write_register(ViPipe, 0x0100, 0x00);
delay_ms(20);
sc2336_1L_write_register(ViPipe, 0x0100, 0x01);
}
void sc2336_1L_default_reg_init(VI_PIPE ViPipe)
{
CVI_U32 i;
for (i = 0; i < g_pastSC2336_1L[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) {
sc2336_1L_write_register(ViPipe,
g_pastSC2336_1L[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr,
g_pastSC2336_1L[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data);
}
}
#define SC2336_1L_CHIP_ID_HI_ADDR 0x3107
#define SC2336_1L_CHIP_ID_LO_ADDR 0x3108
#define SC2336_1L_CHIP_ID 0xcb3a
void sc2336_1L_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip)
{
CVI_U8 val = 0;
switch (eSnsMirrorFlip) {
case ISP_SNS_NORMAL:
break;
case ISP_SNS_MIRROR:
val |= 0x6;
break;
case ISP_SNS_FLIP:
val |= 0x60;
break;
case ISP_SNS_MIRROR_FLIP:
val |= 0x66;
break;
default:
return;
}
sc2336_1L_write_register(ViPipe, 0x3221, val);
}
int sc2336_1L_probe(VI_PIPE ViPipe)
{
int nVal;
CVI_U16 chip_id;
usleep(4*1000);
if (sc2336_1L_i2c_init(ViPipe) != CVI_SUCCESS)
return CVI_FAILURE;
nVal = sc2336_1L_read_register(ViPipe, SC2336_1L_CHIP_ID_HI_ADDR);
if (nVal < 0) {
CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n");
return nVal;
}
chip_id = (nVal & 0xFF) << 8;
nVal = sc2336_1L_read_register(ViPipe, SC2336_1L_CHIP_ID_LO_ADDR);
if (nVal < 0) {
CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n");
return nVal;
}
chip_id |= (nVal & 0xFF);
if (chip_id != SC2336_1L_CHIP_ID) {
CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n");
return CVI_FAILURE;
}
return CVI_SUCCESS;
}
void sc2336_1L_init(VI_PIPE ViPipe)
{
WDR_MODE_E enWDRMode;
CVI_BOOL bInit;
bInit = g_pastSC2336_1L[ViPipe]->bInit;
enWDRMode = g_pastSC2336_1L[ViPipe]->enWDRMode;
sc2336_1L_i2c_init(ViPipe);
/* When sensor first init, config all registers */
if (bInit == CVI_FALSE) {
if (enWDRMode == WDR_MODE_NONE) {
sc2336_1L_linear_1080p30_init(ViPipe);
}
}
/* When sensor switch mode(linear<->WDR or resolution), config different registers(if possible) */
else {
if (enWDRMode == WDR_MODE_NONE) {
sc2336_1L_linear_1080p30_init(ViPipe);
}
}
g_pastSC2336_1L[ViPipe]->bInit = CVI_TRUE;
}
void sc2336_1L_exit(VI_PIPE ViPipe)
{
sc2336_1L_i2c_exit(ViPipe);
}
/* 1080P30 and 1080P25 */
static void sc2336_1L_linear_1080p30_init(VI_PIPE ViPipe)
{
sc2336_1L_write_register(ViPipe, 0x0103, 0x01);
sc2336_1L_write_register(ViPipe, 0x0100, 0x00);
sc2336_1L_write_register(ViPipe, 0x36e9, 0x80);
sc2336_1L_write_register(ViPipe, 0x37f9, 0x80);
sc2336_1L_write_register(ViPipe, 0x3018, 0x12);
sc2336_1L_write_register(ViPipe, 0x3019, 0x0e);
sc2336_1L_write_register(ViPipe, 0x301f, 0x3b);
sc2336_1L_write_register(ViPipe, 0x3106, 0x05);
sc2336_1L_write_register(ViPipe, 0x3248, 0x04);
sc2336_1L_write_register(ViPipe, 0x3249, 0x0b);
sc2336_1L_write_register(ViPipe, 0x3253, 0x08);
sc2336_1L_write_register(ViPipe, 0x3301, 0x09);
sc2336_1L_write_register(ViPipe, 0x3302, 0xff);
sc2336_1L_write_register(ViPipe, 0x3303, 0x10);
sc2336_1L_write_register(ViPipe, 0x3306, 0x60);
sc2336_1L_write_register(ViPipe, 0x3307, 0x02);
sc2336_1L_write_register(ViPipe, 0x330a, 0x01);
sc2336_1L_write_register(ViPipe, 0x330b, 0x10);
sc2336_1L_write_register(ViPipe, 0x330c, 0x16);
sc2336_1L_write_register(ViPipe, 0x330d, 0xff);
sc2336_1L_write_register(ViPipe, 0x3318, 0x02);
sc2336_1L_write_register(ViPipe, 0x3321, 0x0a);
sc2336_1L_write_register(ViPipe, 0x3327, 0x0e);
sc2336_1L_write_register(ViPipe, 0x332b, 0x12);
sc2336_1L_write_register(ViPipe, 0x3333, 0x10);
sc2336_1L_write_register(ViPipe, 0x3334, 0x40);
sc2336_1L_write_register(ViPipe, 0x335e, 0x06);
sc2336_1L_write_register(ViPipe, 0x335f, 0x0a);
sc2336_1L_write_register(ViPipe, 0x3364, 0x1f);
sc2336_1L_write_register(ViPipe, 0x337c, 0x02);
sc2336_1L_write_register(ViPipe, 0x337d, 0x0e);
sc2336_1L_write_register(ViPipe, 0x3390, 0x09);
sc2336_1L_write_register(ViPipe, 0x3391, 0x0f);
sc2336_1L_write_register(ViPipe, 0x3392, 0x1f);
sc2336_1L_write_register(ViPipe, 0x3393, 0x20);
sc2336_1L_write_register(ViPipe, 0x3394, 0x20);
sc2336_1L_write_register(ViPipe, 0x3395, 0xff);
sc2336_1L_write_register(ViPipe, 0x33a2, 0x04);
sc2336_1L_write_register(ViPipe, 0x33b1, 0x80);
sc2336_1L_write_register(ViPipe, 0x33b2, 0x68);
sc2336_1L_write_register(ViPipe, 0x33b3, 0x42);
sc2336_1L_write_register(ViPipe, 0x33f9, 0x70);
sc2336_1L_write_register(ViPipe, 0x33fb, 0xd0);
sc2336_1L_write_register(ViPipe, 0x33fc, 0x0f);
sc2336_1L_write_register(ViPipe, 0x33fd, 0x1f);
sc2336_1L_write_register(ViPipe, 0x349f, 0x03);
sc2336_1L_write_register(ViPipe, 0x34a6, 0x0f);
sc2336_1L_write_register(ViPipe, 0x34a7, 0x1f);
sc2336_1L_write_register(ViPipe, 0x34a8, 0x42);
sc2336_1L_write_register(ViPipe, 0x34a9, 0x06);
sc2336_1L_write_register(ViPipe, 0x34aa, 0x01);
sc2336_1L_write_register(ViPipe, 0x34ab, 0x23);
sc2336_1L_write_register(ViPipe, 0x34ac, 0x01);
sc2336_1L_write_register(ViPipe, 0x34ad, 0x84);
sc2336_1L_write_register(ViPipe, 0x3630, 0xf4);
sc2336_1L_write_register(ViPipe, 0x3633, 0x22);
sc2336_1L_write_register(ViPipe, 0x3639, 0xf4);
sc2336_1L_write_register(ViPipe, 0x363c, 0x47);
sc2336_1L_write_register(ViPipe, 0x3670, 0x09);
sc2336_1L_write_register(ViPipe, 0x3674, 0xf4);
sc2336_1L_write_register(ViPipe, 0x3675, 0xfb);
sc2336_1L_write_register(ViPipe, 0x3676, 0xed);
sc2336_1L_write_register(ViPipe, 0x367c, 0x09);
sc2336_1L_write_register(ViPipe, 0x367d, 0x0f);
sc2336_1L_write_register(ViPipe, 0x3690, 0x33);
sc2336_1L_write_register(ViPipe, 0x3691, 0x33);
sc2336_1L_write_register(ViPipe, 0x3692, 0x43);
sc2336_1L_write_register(ViPipe, 0x3698, 0x89);
sc2336_1L_write_register(ViPipe, 0x3699, 0x96);
sc2336_1L_write_register(ViPipe, 0x369a, 0xd0);
sc2336_1L_write_register(ViPipe, 0x369b, 0xd0);
sc2336_1L_write_register(ViPipe, 0x369c, 0x09);
sc2336_1L_write_register(ViPipe, 0x369d, 0x0f);
sc2336_1L_write_register(ViPipe, 0x36a2, 0x09);
sc2336_1L_write_register(ViPipe, 0x36a3, 0x0f);
sc2336_1L_write_register(ViPipe, 0x36a4, 0x1f);
sc2336_1L_write_register(ViPipe, 0x36d0, 0x01);
sc2336_1L_write_register(ViPipe, 0x36ec, 0x0c);
sc2336_1L_write_register(ViPipe, 0x3722, 0xe1);
sc2336_1L_write_register(ViPipe, 0x3724, 0x41);
sc2336_1L_write_register(ViPipe, 0x3725, 0xc1);
sc2336_1L_write_register(ViPipe, 0x3728, 0x20);
sc2336_1L_write_register(ViPipe, 0x3900, 0x0d);
sc2336_1L_write_register(ViPipe, 0x3905, 0x98);
sc2336_1L_write_register(ViPipe, 0x391b, 0x81);
sc2336_1L_write_register(ViPipe, 0x391c, 0x10);
sc2336_1L_write_register(ViPipe, 0x3933, 0x81);
sc2336_1L_write_register(ViPipe, 0x3934, 0xc5);
sc2336_1L_write_register(ViPipe, 0x3940, 0x68);
sc2336_1L_write_register(ViPipe, 0x3941, 0x00);
sc2336_1L_write_register(ViPipe, 0x3942, 0x01);
sc2336_1L_write_register(ViPipe, 0x3943, 0xc6);
sc2336_1L_write_register(ViPipe, 0x3952, 0x02);
sc2336_1L_write_register(ViPipe, 0x3953, 0x0f);
sc2336_1L_write_register(ViPipe, 0x3e01, 0x45);
sc2336_1L_write_register(ViPipe, 0x3e02, 0xf0);
sc2336_1L_write_register(ViPipe, 0x3e08, 0x1f);
sc2336_1L_write_register(ViPipe, 0x3e1b, 0x14);
sc2336_1L_write_register(ViPipe, 0x440e, 0x02);
sc2336_1L_write_register(ViPipe, 0x4509, 0x38);
sc2336_1L_write_register(ViPipe, 0x4819, 0x09);
sc2336_1L_write_register(ViPipe, 0x481b, 0x05);
sc2336_1L_write_register(ViPipe, 0x481d, 0x14);
sc2336_1L_write_register(ViPipe, 0x481f, 0x04);
sc2336_1L_write_register(ViPipe, 0x4821, 0x0a);
sc2336_1L_write_register(ViPipe, 0x4823, 0x05);
sc2336_1L_write_register(ViPipe, 0x4825, 0x04);
sc2336_1L_write_register(ViPipe, 0x4827, 0x05);
sc2336_1L_write_register(ViPipe, 0x4829, 0x08);
sc2336_1L_write_register(ViPipe, 0x5799, 0x06);
sc2336_1L_write_register(ViPipe, 0x5ae0, 0xfe);
sc2336_1L_write_register(ViPipe, 0x5ae1, 0x40);
sc2336_1L_write_register(ViPipe, 0x5ae2, 0x30);
sc2336_1L_write_register(ViPipe, 0x5ae3, 0x28);
sc2336_1L_write_register(ViPipe, 0x5ae4, 0x20);
sc2336_1L_write_register(ViPipe, 0x5ae5, 0x30);
sc2336_1L_write_register(ViPipe, 0x5ae6, 0x28);
sc2336_1L_write_register(ViPipe, 0x5ae7, 0x20);
sc2336_1L_write_register(ViPipe, 0x5ae8, 0x3c);
sc2336_1L_write_register(ViPipe, 0x5ae9, 0x30);
sc2336_1L_write_register(ViPipe, 0x5aea, 0x28);
sc2336_1L_write_register(ViPipe, 0x5aeb, 0x3c);
sc2336_1L_write_register(ViPipe, 0x5aec, 0x30);
sc2336_1L_write_register(ViPipe, 0x5aed, 0x28);
sc2336_1L_write_register(ViPipe, 0x5aee, 0xfe);
sc2336_1L_write_register(ViPipe, 0x5aef, 0x40);
sc2336_1L_write_register(ViPipe, 0x5af4, 0x30);
sc2336_1L_write_register(ViPipe, 0x5af5, 0x28);
sc2336_1L_write_register(ViPipe, 0x5af6, 0x20);
sc2336_1L_write_register(ViPipe, 0x5af7, 0x30);
sc2336_1L_write_register(ViPipe, 0x5af8, 0x28);
sc2336_1L_write_register(ViPipe, 0x5af9, 0x20);
sc2336_1L_write_register(ViPipe, 0x5afa, 0x3c);
sc2336_1L_write_register(ViPipe, 0x5afb, 0x30);
sc2336_1L_write_register(ViPipe, 0x5afc, 0x28);
sc2336_1L_write_register(ViPipe, 0x5afd, 0x3c);
sc2336_1L_write_register(ViPipe, 0x5afe, 0x30);
sc2336_1L_write_register(ViPipe, 0x5aff, 0x28);
sc2336_1L_write_register(ViPipe, 0x36e9, 0x20);
sc2336_1L_write_register(ViPipe, 0x37f9, 0x27);
sc2336_1L_default_reg_init(ViPipe);
sc2336_1L_write_register(ViPipe, 0x0100, 0x01);
printf("ViPipe:%d,===SC2336_1L 1080P 30fps 10bit LINE Init OK!===\n", ViPipe);
}

View File

@ -26,8 +26,12 @@ prepare:
brigates_bg0808:
$(call MAKE_SENSOR, ${@})
cvsens_cv4001:
$(call MAKE_SENSOR, ${@})
gcore_gc02m1:
$(call MAKE_SENSOR, ${@})
gcore_gc0312:
$(call MAKE_SENSOR, ${@})
@ -37,6 +41,12 @@ gcore_gc0329:
gcore_gc1054:
$(call MAKE_SENSOR, ${@})
gcore_gc1084:
$(call MAKE_SENSOR, ${@})
gcore_gc1084_slave:
$(call MAKE_SENSOR, ${@})
gcore_gc2053:
$(call MAKE_SENSOR, ${@})
@ -61,6 +71,9 @@ gcore_gc4653:
imgds_mis2008:
$(call MAKE_SENSOR, ${@})
imgds_mis2008_1L:
$(call MAKE_SENSOR, ${@})
nextchip_n5:
$(call MAKE_SENSOR, ${@})
@ -145,6 +158,9 @@ sms_sc2335:
sms_sc2336:
$(call MAKE_SENSOR, ${@})
sms_sc2336_1L:
$(call MAKE_SENSOR, ${@})
sms_sc2336p:
$(call MAKE_SENSOR, ${@})

View File

@ -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_cv4001.a
TARGET_SO = $(MW_LIB)/libsns_cv4001.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)

View File

@ -0,0 +1,939 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <syslog.h>
#include <errno.h>
#ifdef ARCH_CV182X
#include "cvi_type.h"
#include "cvi_comm_video.h"
#include <linux/cvi_vip_snsr.h>
#else
#include <linux/cvi_type.h>
#include <linux/cvi_comm_video.h>
#include <linux/vi_snsr.h>
#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 "cv4001_cmos_ex.h"
#include "cv4001_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 CV4001_ID 4001
#define CV4001_I2C_ADDR_1 0x35
#define CV4001_I2C_ADDR_2 0x36
#define CV4001_I2C_ADDR_IS_VALID(addr) ((addr) == CV4001_I2C_ADDR_1 || (addr) == CV4001_I2C_ADDR_2)
/****************************************************************************
* global variables *
***************************************************************************/
ISP_SNS_STATE_S *g_pastCV4001[VI_MAX_PIPE_NUM] = {CVI_NULL};
#define CV4001_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastCV4001[dev])
#define CV4001_SENSOR_SET_CTX(dev, pstCtx) (g_pastCV4001[dev] = pstCtx)
#define CV4001_SENSOR_RESET_CTX(dev) (g_pastCV4001[dev] = CVI_NULL)
ISP_SNS_COMMBUS_U g_aunCV4001_BusInfo[VI_MAX_PIPE_NUM] = {
[0] = { .s8I2cDev = 3},
[1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1}
};
ISP_SNS_MIRRORFLIP_TYPE_E g_aeCV4001_MirrorFip[VI_MAX_PIPE_NUM] = {0};
CVI_U16 g_au16CV4001_GainMode[VI_MAX_PIPE_NUM] = {0};
/****************************************************************************
* local variables and functions *
***************************************************************************/
static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = {
[0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE
};
static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0};
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);
/*****CV4001 Lines Range*****/
#define CV4001_FULL_LINES_MAX (0xfffff)
/*****CV4001 Register Address*****/
#define CV4001_EXP_ADDR0 0x3062 //bit[19:16]
#define CV4001_EXP_ADDR1 0x3061
#define CV4001_EXP_ADDR2 0x3060
#define CV4001_AGAIN_ADDR 0x3180 //bit[7:0]
#define CV4001_DGAIN_H_ADDR 0x3179 //bit[15:8]
#define CV4001_DGAIN_L_ADDR 0x3178 //bit[7:0]
#define CV4001_VTS_ADDR0 0x302A //bit[19:16]
#define CV4001_VTS_ADDR1 0x3029
#define CV4001_VTS_ADDR2 0x3028
#define CV4001_FLIP_MIRROR_ADDR 0x3034
#define CV4001_RES_IS_1440P(w, h) ((w) <= 2560 && (h) <= 1440)
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);
CV4001_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER(pstSnsState);
pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd;
pstAeSnsDft->u32FlickerFreq = 50 * 256;
pstAeSnsDft->u32FullLinesMax = CV4001_FULL_LINES_MAX;
pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 25);
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 * 25 / 2;
else
pstAeSnsDft->u32LinesPer500ms = g_au32LinesPer500ms[ViPipe];
switch (pstSnsState->enWDRMode) {
default:
case WDR_MODE_NONE: /*linear mode*/
pstAeSnsDft->f32Fps = g_astCV4001_mode[CV4001_MODE_2560X1440P25].f32MaxFps;
pstAeSnsDft->f32MinFps = g_astCV4001_mode[CV4001_MODE_2560X1440P25].f32MinFps;
pstAeSnsDft->au8HistThresh[0] = 0xd;
pstAeSnsDft->au8HistThresh[1] = 0x28;
pstAeSnsDft->au8HistThresh[2] = 0x60;
pstAeSnsDft->au8HistThresh[3] = 0x80;
pstAeSnsDft->u32MaxAgain = 16384;
pstAeSnsDft->u32MinAgain = 1024;
pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain;
pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain;
pstAeSnsDft->u32MaxDgain = 16384;
pstAeSnsDft->u32MinDgain = 1024;
pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain;
pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain;
pstAeSnsDft->u8AeCompensation = 40;
pstAeSnsDft->u32InitAESpeed = 64;
pstAeSnsDft->u32InitAETolerance = 2;
pstAeSnsDft->u32AEResponseFrame = 4;
pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR;
pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ?
g_au32InitExposure[ViPipe] : g_astCV4001_mode[CV4001_MODE_2560X1440P25].stExp[0].u16Def;
pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 8;
pstAeSnsDft->u32MinIntTime = g_astCV4001_mode[CV4001_MODE_2560X1440P25].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);
CV4001_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER(pstSnsState);
u32Vts = g_astCV4001_mode[pstSnsState->u8ImgMode].u32VtsDef;
pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg;
f32MaxFps = g_astCV4001_mode[pstSnsState->u8ImgMode].f32MaxFps;
f32MinFps = g_astCV4001_mode[pstSnsState->u8ImgMode].f32MinFps;
if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) {
u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps);
} else {
CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps);
return CVI_FAILURE;
}
u32VMAX = (u32VMAX > CV4001_FULL_LINES_MAX) ? CV4001_FULL_LINES_MAX : u32VMAX;
if (pstSnsState->enWDRMode == WDR_MODE_NONE) {
pstSnsRegsInfo->astI2cData[LINEAR_VTS_0].u32Data = ((u32VMAX & 0xFF0000) >> 16);
pstSnsRegsInfo->astI2cData[LINEAR_VTS_1].u32Data = ((u32VMAX & 0xFF00) >> 8);
pstSnsRegsInfo->astI2cData[LINEAR_VTS_2].u32Data = (u32VMAX & 0xFF);
} else {
CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport WDRMode: %d\n", pstSnsState->enWDRMode);
return CVI_FAILURE;
}
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;
CVI_S32 Cur_Vts;
CVI_S32 Reg_IntTime;
CV4001_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER(pstSnsState);
CMOS_CHECK_POINTER(u32IntTime);
Cur_Vts = pstSnsState->u32FLStd;
Reg_IntTime = ((Cur_Vts / 2) - u32IntTime[0]) * 2;
pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg;
pstSnsRegsInfo->astI2cData[LINEAR_EXP_0].u32Data = ((Reg_IntTime >> 16) & 0x0F);
pstSnsRegsInfo->astI2cData[LINEAR_EXP_1].u32Data = ((Reg_IntTime >> 8) & 0xFF);
pstSnsRegsInfo->astI2cData[LINEAR_EXP_2].u32Data = (Reg_IntTime & 0xFF);
return CVI_SUCCESS;
}
static CVI_U32 gain_table[242] = {
1024, 1024, 1024, 1024, 1040, 1040, 1040, 1040, 1056, 1056,
1056, 1056, 1072, 1072, 1072, 1072, 1088, 1088, 1088, 1104,
1104, 1104, 1120, 1120, 1120, 1120, 1136, 1136, 1136, 1152,
1152, 1152, 1168, 1168, 1168, 1184, 1184, 1184, 1200, 1200,
1200, 1216, 1216, 1216, 1232, 1232, 1248, 1248, 1248, 1264,
1264, 1264, 1280, 1280, 1296, 1296, 1296, 1312, 1312, 1328,
1328, 1344, 1344, 1344, 1360, 1360, 1376, 1376, 1392, 1392,
1408, 1408, 1424, 1424, 1440, 1440, 1456, 1456, 1472, 1472,
1488, 1488, 1504, 1504, 1520, 1520, 1536, 1536, 1552, 1568,
1568, 1584, 1584, 1600, 1616, 1616, 1632, 1648, 1648, 1664,
1680, 1680, 1696, 1712, 1712, 1728, 1744, 1744, 1760, 1776,
1792, 1808, 1808, 1824, 1840, 1856, 1872, 1872, 1888, 1904,
1920, 1936, 1952, 1968, 1984, 2000, 2016, 2016, 2048, 2064,
2080, 2096, 2112, 2128, 2144, 2160, 2176, 2192, 2208, 2240,
2256, 2272, 2288, 2304, 2336, 2352, 2368, 2400, 2416, 2448,
2464, 2496, 2512, 2544, 2560, 2592, 2608, 2640, 2672, 2688,
2720, 2752, 2784, 2816, 2848, 2880, 2912, 2944, 2976, 3008,
3040, 3072, 3120, 3152, 3184, 3232, 3264, 3312, 3360, 3392,
3440, 3488, 3536, 3584, 3632, 3680, 3744, 3792, 3840, 3904,
3968, 4032, 4096, 4160, 4224, 4288, 4368, 4432, 4512, 4592,
4672, 4752, 4848, 4944, 5040, 5136, 5232, 5344, 5456, 5568,
5696, 5824, 5952, 6080, 6240, 6384, 6544, 6720, 6896, 7072,
7280, 7488, 7696, 7936, 8192, 8448, 8736, 9024, 9360, 9696,
10080, 10480, 10912, 11392, 11904, 12480, 13104, 13792, 14560, 15408,
16384, 0x3FFFF,
};
static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb)
{
int i, total;
CVI_U32 pregain;
CMOS_CHECK_POINTER(pu32AgainLin);
CMOS_CHECK_POINTER(pu32AgainDb);
UNUSED(ViPipe);
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;
CMOS_CHECK_POINTER(pu32DgainLin);
CMOS_CHECK_POINTER(pu32DgainDb);
UNUSED(ViPipe);
// 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);
CV4001_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 */
for (i = 0; i < total; i++) {
if ((gain_table[i] <= pu32Again[0]) && (gain_table[i+1] >= pu32Again[0])) {
break;
}
}
u32Again = i;
u32Dgain = pu32Dgain[0] / 16;
if (u32Dgain < 64) {
u32Dgain = 64;
}
if (u32Dgain > 1024) {
u32Dgain = 1024;
}
if (pstSnsState->enWDRMode == WDR_MODE_NONE) {
pstSnsRegsInfo->astI2cData[LINEAR_AGAIN].u32Data = u32Again;
pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_H].u32Data = (u32Dgain >> 8);
pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_L].u32Data = (u32Dgain & 0xFF);
} else {
CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport WDRMode: %d\n", pstSnsState->enWDRMode);
return CVI_FAILURE;
}
return CVI_SUCCESS;
}
static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio,
CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime)
{
UNUSED(ViPipe);
UNUSED(u16ManRatioEnable);
UNUSED(au32Ratio);
UNUSED(au32IntTimeMax);
UNUSED(au32IntTimeMin);
UNUSED(pu32LFMaxIntTime);
CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport WDRMode\n");
return CVI_SUCCESS;
}
/* Only used in LINE_WDR mode */
static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr)
{
CMOS_CHECK_POINTER(pstAeFSWDRAttr);
genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode;
gu32MaxTimeGetCnt[ViPipe] = 0;
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));
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 CV4001_MODE_S *pstMode = CVI_NULL;
ISP_SNS_STATE_S *pstSnsState = CVI_NULL;
CV4001_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER(pstSnsState);
pstMode = &g_astCV4001_mode[pstSnsState->u8ImgMode];
if (pstSnsState->enWDRMode != WDR_MODE_NONE) {
CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport WDRMode: %d\n", pstSnsState->enWDRMode);
} else {
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)
{
UNUSED(ViPipe);
UNUSED(u8Mode);
CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport sensor mode!\n");
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);
CV4001_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_aunCV4001_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 = cv4001_i2c_addr;
pstI2c_data[i].u32AddrByteNum = cv4001_addr_byte;
pstI2c_data[i].u32DataByteNum = cv4001_data_byte;
}
pstI2c_data[LINEAR_EXP_0].u32RegAddr = CV4001_EXP_ADDR0;
pstI2c_data[LINEAR_EXP_1].u32RegAddr = CV4001_EXP_ADDR1;
pstI2c_data[LINEAR_EXP_2].u32RegAddr = CV4001_EXP_ADDR2;
pstI2c_data[LINEAR_AGAIN].u32RegAddr = CV4001_AGAIN_ADDR;
pstI2c_data[LINEAR_DGAIN_H].u32RegAddr = CV4001_DGAIN_H_ADDR;
pstI2c_data[LINEAR_DGAIN_L].u32RegAddr = CV4001_DGAIN_L_ADDR;
pstI2c_data[LINEAR_VTS_0].u32RegAddr = CV4001_VTS_ADDR0;
pstI2c_data[LINEAR_VTS_1].u32RegAddr = CV4001_VTS_ADDR1;
pstI2c_data[LINEAR_VTS_2].u32RegAddr = CV4001_VTS_ADDR2;
pstI2c_data[LINEAR_FLIP_MIRROR].u32RegAddr = CV4001_FLIP_MIRROR_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) && (i <= LINEAR_DGAIN_L)) {
gainsUpdate = 1;
}
if (i <= LINEAR_EXP_2) {
shutterUpdate = 1;
}
if ((i >= LINEAR_VTS_0) && (i <= LINEAR_VTS_2)) {
vtsUpdate = 1;
}
pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE;
pstCfg0->snsCfg.need_update = CVI_TRUE;
}
}
if (gainsUpdate) {
pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN].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_0].bUpdate = CVI_TRUE;
pstCfg0->snsCfg.astI2cData[LINEAR_EXP_1].bUpdate = CVI_TRUE;
pstCfg0->snsCfg.astI2cData[LINEAR_EXP_2].bUpdate = CVI_TRUE;
}
if (vtsUpdate) {
pstCfg0->snsCfg.astI2cData[LINEAR_VTS_0].bUpdate = CVI_TRUE;
pstCfg0->snsCfg.astI2cData[LINEAR_VTS_1].bUpdate = CVI_TRUE;
pstCfg0->snsCfg.astI2cData[LINEAR_VTS_2].bUpdate = CVI_TRUE;
}
/* check update isp crop or not */
pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ?
CVI_TRUE : CVI_FALSE);
}
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];
pstCfg0->snsCfg.astI2cData[LINEAR_FLIP_MIRROR].bDropFrm = CVI_FALSE;
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);
CV4001_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 (CV4001_RES_IS_1440P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height))
u8SensorImageMode = CV4001_MODE_2560X1440P25;
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)
{
CVI_U8 value = 0x0;
CVI_U8 start_x = 4;
CVI_U8 start_y = 4;
ISP_SNS_STATE_S *pstSnsState = CVI_NULL;
ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL;
ISP_SNS_ISP_INFO_S *pstIspCfg0 = CVI_NULL;
CV4001_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER_VOID(pstSnsState);
pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg;
pstIspCfg0 = &pstSnsState->astSyncInfo[0].ispCfg;
/* Apply the setting on the fly */
if (pstSnsState->bInit == CVI_TRUE && g_aeCV4001_MirrorFip[ViPipe] != eSnsMirrorFlip) {
switch (eSnsMirrorFlip) {
case ISP_SNS_NORMAL:
value = 0x0;
start_x = 4;
start_y = 4;
break;
case ISP_SNS_MIRROR:
value = 0x1;
start_x = 5;
start_y = 4;
break;
case ISP_SNS_FLIP:
value = 0x2;
start_x = 4;
start_y = 5;
break;
case ISP_SNS_MIRROR_FLIP:
value = 0x3;
start_x = 5;
start_y = 5;
break;
default:
return;
}
pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR].u32Data = value;
pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR].bDropFrm = 1;
pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR].u8DropFrmNum = 2;
g_aeCV4001_MirrorFip[ViPipe] = eSnsMirrorFlip;
pstIspCfg0->img_size[0].stWndRect.s32X = start_x;
pstIspCfg0->img_size[0].stWndRect.s32Y = start_y;
}
}
static CVI_VOID sensor_global_init(VI_PIPE ViPipe)
{
ISP_SNS_STATE_S *pstSnsState = CVI_NULL;
CV4001_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER_VOID(pstSnsState);
pstSnsState->bInit = CVI_FALSE;
pstSnsState->bSyncInit = CVI_FALSE;
pstSnsState->u8ImgMode = CV4001_MODE_2560X1440P25;
pstSnsState->enWDRMode = WDR_MODE_NONE;
pstSnsState->u32FLStd = g_astCV4001_mode[pstSnsState->u8ImgMode].u32VtsDef;
pstSnsState->au32FL[0] = g_astCV4001_mode[pstSnsState->u8ImgMode].u32VtsDef;
pstSnsState->au32FL[1] = g_astCV4001_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;
CV4001_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER(pstSnsState);
CMOS_CHECK_POINTER(pstRxAttr);
memcpy(pstRxAttr, &cv4001_rx_attr, sizeof(*pstRxAttr));
pstRxAttr->img_size.width = g_astCV4001_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width;
pstRxAttr->img_size.height = g_astCV4001_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 = &cv4001_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 = cv4001_init;
pstSensorExpFunc->pfn_cmos_sensor_exit = cv4001_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 (CV4001_I2C_ADDR_IS_VALID(s32I2cAddr))
cv4001_i2c_addr = s32I2cAddr;
}
static CVI_S32 cv4001_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo)
{
g_aunCV4001_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev;
return CVI_SUCCESS;
}
static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe)
{
ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL;
CV4001_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));
CV4001_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx);
return CVI_SUCCESS;
}
static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe)
{
ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL;
CV4001_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx);
SENSOR_FREE(pastSnsStateCtx);
CV4001_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 = CV4001_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, CV4001_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, CV4001_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, CV4001_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_au16CV4001_GainMode[ViPipe] = pstInitAttr->enGainMode;
return CVI_SUCCESS;
}
static CVI_S32 sensor_probe(VI_PIPE ViPipe)
{
return cv4001_probe(ViPipe);
}
ISP_SNS_OBJ_S stSnsCV4001_Obj = {
.pfnRegisterCallback = sensor_register_callback,
.pfnUnRegisterCallback = sensor_unregister_callback,
.pfnStandby = cv4001_standby,
.pfnRestart = cv4001_restart,
.pfnWriteReg = cv4001_write_register,
.pfnReadReg = cv4001_read_register,
.pfnSetBusInfo = cv4001_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,
};

View File

@ -0,0 +1,86 @@
#ifndef __CV4001_CMOS_EX_H_
#define __CV4001_CMOS_EX_H_
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
#ifdef ARCH_CV182X
#include <linux/cvi_vip_cif.h>
#include <linux/cvi_vip_snsr.h>
#include "cvi_type.h"
#else
#include <linux/cif_uapi.h>
#include <linux/vi_snsr.h>
#include <linux/cvi_type.h>
#endif
#include "cvi_sns_ctrl.h"
#ifndef UNUSED
#define UNUSED(x) ((void)(x))
#endif
enum cv4001_linear_regs_e {
LINEAR_EXP_0, //0x3062 bit[19:16]
LINEAR_EXP_1, //0x3061
LINEAR_EXP_2, //0x3060
LINEAR_AGAIN, //0x3180 bit[7:0]
LINEAR_DGAIN_H, //0x3179 bit[15:8]
LINEAR_DGAIN_L, //0x3178 bit[7:0]
LINEAR_VTS_0, //0x302A bit[19:16]
LINEAR_VTS_1, //0x3029
LINEAR_VTS_2, //0x3028
LINEAR_FLIP_MIRROR, //0x3034
LINEAR_REGS_NUM
};
typedef enum _CV4001_MODE_E {
CV4001_MODE_2560X1440P25 = 0,
CV4001_MODE_NUM
} CV4001_MODE_E;
typedef struct _CV4001_STATE_S {
CVI_U32 u32Sexp_MAX;
} CV4001_STATE_S;
typedef struct _CV4001_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];
} CV4001_MODE_S;
/****************************************************************************
* external variables and functions *
****************************************************************************/
extern ISP_SNS_STATE_S *g_pastCV4001[VI_MAX_PIPE_NUM];
extern ISP_SNS_COMMBUS_U g_aunCV4001_BusInfo[];
extern ISP_SNS_MIRRORFLIP_TYPE_E g_aeCV4001_MirrorFip[VI_MAX_PIPE_NUM];
extern CVI_U8 cv4001_i2c_addr;
extern const CVI_U32 cv4001_addr_byte;
extern const CVI_U32 cv4001_data_byte;
extern void cv4001_init(VI_PIPE ViPipe);
extern void cv4001_exit(VI_PIPE ViPipe);
extern void cv4001_standby(VI_PIPE ViPipe);
extern void cv4001_restart(VI_PIPE ViPipe);
extern int cv4001_write_register(VI_PIPE ViPipe, int addr, int data);
extern int cv4001_read_register(VI_PIPE ViPipe, int addr);
extern int cv4001_probe(VI_PIPE ViPipe);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* End of #ifdef __cplusplus */
#endif /* __CV4001_CMOS_EX_H_ */

View File

@ -0,0 +1,124 @@
#ifndef __CV4001_CMOS_PARAM_H_
#define __CV4001_CMOS_PARAM_H_
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
#ifdef ARCH_CV182X
#include <linux/cvi_vip_cif.h>
#include <linux/cvi_vip_snsr.h>
#include "cvi_type.h"
#else
#include <linux/cif_uapi.h>
#include <linux/vi_snsr.h>
#include <linux/cvi_type.h>
#endif
#include "cvi_sns_ctrl.h"
#include "cv4001_cmos_ex.h"
static const CV4001_MODE_S g_astCV4001_mode[CV4001_MODE_NUM] = {
[CV4001_MODE_2560X1440P25] = {
.name = "2560X1440P25",
.astImg[0] = {
.stSnsSize = {
.u32Width = 2568,
.u32Height = 1448,
},
.stWndRect = {
.s32X = 4,
.s32Y = 4,
.u32Width = 2560,
.u32Height = 1440,
},
.stMaxSize = {
.u32Width = 2568,
.u32Height = 1448,
},
},
.f32MaxFps = 25,
.f32MinFps = 0.076, /* 3200 * 25 / 0x0FFFFF */
.u32HtsDef = 743,
.u32VtsDef = 3200,
.stExp[0] = {
.u16Min = 8,
.u16Max = 3200-4,
.u16Def = 8,
.u16Step = 1,
},
.stAgain[0] = {
.u32Min = 1024,
.u32Max = 16384,
.u32Def = 1024,
.u32Step = 1,
},
.stDgain[0] = {
.u32Min = 1024,
.u32Max = 16384,
.u32Def = 1024,
.u32Step = 64,
},
},
};
static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = {
.bUpdate = CVI_TRUE,
.blcAttr = {
.Enable = 1,
.enOpType = OP_TYPE_AUTO,
.stManual = {196, 196, 196, 196, 0, 0, 0, 0
#ifdef ARCH_CV182X
, 1075, 1075, 1075, 1075
#endif
},
.stAuto = {
{196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196 },
{196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196 },
{196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196 },
{196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196 },
{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
{1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075,
1075, 1075},
{1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075,
1075, 1075},
{1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075,
1075, 1075},
{1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075, 1075,
1075, 1075},
#endif
},
},
};
struct combo_dev_attr_s cv4001_rx_attr = {
.input_mode = INPUT_MODE_MIPI,
.mac_clk = RX_MAC_CLK_200M,
.mipi_attr = {
.raw_data_type = RAW_DATA_12BIT,
.lane_id = {1, 2, 0, -1, -1},
.pn_swap = {1, 1, 1, 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 /* __CV4001_CMOS_PARAM_H_ */

View File

@ -0,0 +1,294 @@
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <syslog.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#ifdef ARCH_CV182X
#include <linux/cvi_vip_snsr.h>
#include "cvi_comm_video.h"
#else
#include <linux/vi_snsr.h>
#include <linux/cvi_comm_video.h>
#endif
#include "cvi_sns_ctrl.h"
#include "cv4001_cmos_ex.h"
#define CV4001_CHIP_ID_ADDR_H 0x3003
#define CV4001_CHIP_ID_ADDR_L 0x3002
#define CV4001_CHIP_ID 0x4001
static void cv4001_linear_1440p25_init(VI_PIPE ViPipe);
CVI_U8 cv4001_i2c_addr = 0x35;
const CVI_U32 cv4001_addr_byte = 2;
const CVI_U32 cv4001_data_byte = 1;
static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1};
int cv4001_i2c_init(VI_PIPE ViPipe)
{
char acDevFile[16] = {0};
CVI_U8 u8DevNum;
if (g_fd[ViPipe] >= 0)
return CVI_SUCCESS;
int ret;
u8DevNum = g_aunCV4001_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, cv4001_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 cv4001_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 cv4001_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 (cv4001_addr_byte == 2)
buf[idx++] = (addr >> 8) & 0xff;
// add address byte 0
buf[idx++] = addr & 0xff;
ret = write(g_fd[ViPipe], buf, cv4001_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, cv4001_data_byte);
if (ret < 0) {
CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n");
return ret;
}
// pack read back data
data = 0;
if (cv4001_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 cv4001_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 (cv4001_addr_byte == 2) {
buf[idx] = (addr >> 8) & 0xff;
idx++;
buf[idx] = addr & 0xff;
idx++;
}
if (cv4001_data_byte == 1) {
buf[idx] = data & 0xff;
idx++;
}
ret = write(g_fd[ViPipe], buf, cv4001_addr_byte + cv4001_data_byte);
if (ret < 0) {
CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n");
return CVI_FAILURE;
}
ret = read(g_fd[ViPipe], buf, cv4001_addr_byte + cv4001_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 cv4001_standby(VI_PIPE ViPipe)
{
cv4001_write_register(ViPipe, 0x3000, 0x1);
printf("%s\n", __func__);
}
void cv4001_restart(VI_PIPE ViPipe)
{
cv4001_write_register(ViPipe, 0x3000, 0x01);
delay_ms(20);
cv4001_write_register(ViPipe, 0x3000, 0x00);
printf("%s\n", __func__);
}
void cv4001_default_reg_init(VI_PIPE ViPipe)
{
CVI_U32 i;
for (i = 0; i < g_pastCV4001[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) {
cv4001_write_register(ViPipe,
g_pastCV4001[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr,
g_pastCV4001[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data);
}
}
int cv4001_probe(VI_PIPE ViPipe)
{
int nVal;
int nVal2;
usleep(50);
if (cv4001_i2c_init(ViPipe) != CVI_SUCCESS)
return CVI_FAILURE;
nVal = cv4001_read_register(ViPipe, CV4001_CHIP_ID_ADDR_H);
nVal2 = cv4001_read_register(ViPipe, CV4001_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)) != CV4001_CHIP_ID) {
CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n");
return CVI_FAILURE;
}
return CVI_SUCCESS;
}
void cv4001_init(VI_PIPE ViPipe)
{
cv4001_i2c_init(ViPipe);
cv4001_linear_1440p25_init(ViPipe);
g_pastCV4001[ViPipe]->bInit = CVI_TRUE;
}
void cv4001_exit(VI_PIPE ViPipe)
{
cv4001_i2c_exit(ViPipe);
}
static void cv4001_linear_1440p25_init(VI_PIPE ViPipe)
{
delay_ms(10);
//25fps 2lane
cv4001_write_register(ViPipe, 0x3028, 0xB8);
cv4001_write_register(ViPipe, 0x3029, 0x0B);
cv4001_write_register(ViPipe, 0x302C, 0xE4);
cv4001_write_register(ViPipe, 0x302D, 0x02);
cv4001_write_register(ViPipe, 0x3048, 0x40);
cv4001_write_register(ViPipe, 0x3049, 0x00);
cv4001_write_register(ViPipe, 0x304A, 0x08);
cv4001_write_register(ViPipe, 0x304B, 0x0A);
cv4001_write_register(ViPipe, 0x3054, 0x28);
cv4001_write_register(ViPipe, 0x3055, 0x00);
cv4001_write_register(ViPipe, 0x3056, 0xA8);
cv4001_write_register(ViPipe, 0x3057, 0x05);
cv4001_write_register(ViPipe, 0x3020, 0x04);
cv4001_write_register(ViPipe, 0x3908, 0x4A);
cv4001_write_register(ViPipe, 0x3306, 0x03);
cv4001_write_register(ViPipe, 0x343E, 0x00);
cv4001_write_register(ViPipe, 0x3401, 0x01);
cv4001_write_register(ViPipe, 0x3035, 0x01);
cv4001_write_register(ViPipe, 0x3036, 0x01);
cv4001_write_register(ViPipe, 0x343C, 0x01);
cv4001_write_register(ViPipe, 0x362A, 0x00);
cv4001_write_register(ViPipe, 0x3625, 0x01);
cv4001_write_register(ViPipe, 0x35A4, 0x09);
cv4001_write_register(ViPipe, 0x35A8, 0x09);
cv4001_write_register(ViPipe, 0x35AE, 0x07);
cv4001_write_register(ViPipe, 0x35AF, 0x07);
cv4001_write_register(ViPipe, 0x34A2, 0x2C);
cv4001_write_register(ViPipe, 0x3418, 0x9F);
cv4001_write_register(ViPipe, 0x341A, 0x57);
cv4001_write_register(ViPipe, 0x341C, 0x57);
cv4001_write_register(ViPipe, 0x341E, 0x6F);
cv4001_write_register(ViPipe, 0x341F, 0x01);
cv4001_write_register(ViPipe, 0x3420, 0x57);
cv4001_write_register(ViPipe, 0x3422, 0x9F);
cv4001_write_register(ViPipe, 0x3424, 0x57);
cv4001_write_register(ViPipe, 0x3426, 0x8F);
cv4001_write_register(ViPipe, 0x3428, 0x47);
cv4001_write_register(ViPipe, 0x3348, 0x00);
cv4001_write_register(ViPipe, 0x3000, 0x00);
cv4001_write_register(ViPipe, 0x3576, 0x06);
cv4001_write_register(ViPipe, 0x350F, 0x18);
cv4001_write_register(ViPipe, 0x3513, 0x07);
cv4001_write_register(ViPipe, 0x3517, 0x07);
cv4001_write_register(ViPipe, 0x351A, 0x05);
cv4001_write_register(ViPipe, 0x351E, 0x0B);
cv4001_write_register(ViPipe, 0x357A, 0x0B);
cv4001_write_register(ViPipe, 0x3348, 0x00);
cv4001_write_register(ViPipe, 0x316C, 0x64);
cv4001_write_register(ViPipe, 0x3258, 0x02);
cv4001_write_register(ViPipe, 0x3162, 0x01);
cv4001_write_register(ViPipe, 0x3347, 0x01);
cv4001_write_register(ViPipe, 0x3804, 0x0F);
cv4001_write_register(ViPipe, 0x3871, 0x00);
cv4001_write_register(ViPipe, 0x3244, 0x08);
cv4001_write_register(ViPipe, 0x3270, 0x60);
cv4001_write_register(ViPipe, 0x3271, 0x00);
cv4001_write_register(ViPipe, 0x3272, 0x00);
cv4001_write_register(ViPipe, 0x31AC, 0xC8);
cv4001_write_register(ViPipe, 0x3890, 0x00);
cv4001_write_register(ViPipe, 0x3894, 0x05);
cv4001_write_register(ViPipe, 0x3690, 0x00);
cv4001_write_register(ViPipe, 0x3898, 0x20);
cv4001_write_register(ViPipe, 0x3899, 0x20);
cv4001_write_register(ViPipe, 0x3583, 0x2f);
cv4001_write_register(ViPipe, 0x3b75, 0x00);
cv4001_write_register(ViPipe, 0x3b5E, 0x01);
cv4001_write_register(ViPipe, 0x3a10, 0x06);
cv4001_write_register(ViPipe, 0x3a11, 0x06);
cv4001_write_register(ViPipe, 0x316C, 0x64);
cv4001_write_register(ViPipe, 0x3000, 0x00);
cv4001_default_reg_init(ViPipe);
delay_ms(100);
printf("ViPipe:%d,===CV4001 1440P 25fps 12bit LINEAR Init OK!===\n", ViPipe);
}

View File

@ -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_gc1084.a
TARGET_SO = $(MW_LIB)/libsns_gc1084.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)

View File

@ -0,0 +1,971 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <syslog.h>
#include <errno.h>
#ifdef ARCH_CV182X
#include "cvi_type.h"
#include "cvi_comm_video.h"
#include <linux/cvi_vip_snsr.h>
#else
#include <linux/cvi_type.h>
#include <linux/cvi_comm_video.h>
#include <linux/vi_snsr.h>
#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 "gc1084_cmos_ex.h"
#include "gc1084_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 GC1084_ID 1084
/****************************************************************************
* global variables *
****************************************************************************/
ISP_SNS_STATE_S *g_pastGc1084[VI_MAX_PIPE_NUM] = {CVI_NULL};
#define GC1084_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastGc1084[dev])
#define GC1084_SENSOR_SET_CTX(dev, pstCtx) (g_pastGc1084[dev] = pstCtx)
#define GC1084_SENSOR_RESET_CTX(dev) (g_pastGc1084[dev] = CVI_NULL)
ISP_SNS_COMMBUS_U g_aunGc1084_BusInfo[VI_MAX_PIPE_NUM] = {
[0] = { .s8I2cDev = 0},
[1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1}
};
GC1084_STATE_S g_astGc1084_State[VI_MAX_PIPE_NUM] = { {0} };
ISP_SNS_MIRRORFLIP_TYPE_E g_aeGc1084_MirrorFip[VI_MAX_PIPE_NUM] = {0};
CVI_U16 g_au16Gc1084_GainMode[VI_MAX_PIPE_NUM] = {0};
CVI_U16 g_au16Gc1084_L2SMode[VI_MAX_PIPE_NUM] = {0};
/****************************************************************************
* local variables and functions *
****************************************************************************/
static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = {
[0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE
};
static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0};
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);
/*****Gc1084 Lines Range*****/
#define GC1084_FULL_LINES_MAX (17119) // 0x3FFF(Max VB) + 720 + 16
/*****Gc1084 Register Address*****/
#define GC1084_EXP_H_ADDR 0x0d03
#define GC1084_EXP_L_ADDR 0x0d04
#define GC1084_AGAIN_M_ADDR 0x00d1
#define GC1084_AGAIN_L_ADDR 0x00d0
#define GC1084_AGAIN_REG_0x031D 0x031d
#define GC1084_AGAIN_H_ADDR 0x0dc1
#define GC1084_COL_AGAIN_H_ADDR 0x00b8
#define GC1084_COL_AGAIN_L_ADDR 0x00b9
#define GC1084_AGAIN_REG_0x0155 0x0155
#define GC1084_DGAIN_H_ADDR 0x00b1
#define GC1084_DGAIN_L_ADDR 0x00b2
#define GC1084_VTS_H_ADDR 0x0d41
#define GC1084_VTS_L_ADDR 0x0d42
#define GC1084_FLIP_MIRROR_ADDR1 0x0015
#define GC1084_FLIP_MIRROR_ADDR2 0x0d15
#define GC1084_RES_IS_720P(w, h) ((w) <= 1280 && (h) <= 720)
static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft)
{
const GC1084_MODE_S *pstMode;
ISP_SNS_STATE_S *pstSnsState = CVI_NULL;
CMOS_CHECK_POINTER(pstAeSnsDft);
GC1084_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER(pstSnsState);
pstMode = &g_stGc1084_mode;
pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd;
pstAeSnsDft->u32FlickerFreq = 50 * 256;
pstAeSnsDft->u32FullLinesMax = GC1084_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 = pstMode->f32MaxFps;
pstAeSnsDft->f32MinFps = pstMode->f32MinFps;
pstAeSnsDft->au8HistThresh[0] = 0xd;
pstAeSnsDft->au8HistThresh[1] = 0x28;
pstAeSnsDft->au8HistThresh[2] = 0x60;
pstAeSnsDft->au8HistThresh[3] = 0x80;
pstAeSnsDft->u32MaxAgain = pstMode->stAgain.u32Max;
pstAeSnsDft->u32MinAgain = pstMode->stAgain.u32Min;
pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain;
pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain;
pstAeSnsDft->u32MaxDgain = pstMode->stDgain.u32Max;
pstAeSnsDft->u32MinDgain = pstMode->stDgain.u32Min;
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] :
pstMode->stExp.u16Def;
pstAeSnsDft->u32MaxIntTime = pstMode->stExp.u16Max;
pstAeSnsDft->u32MinIntTime = pstMode->stExp.u16Min;
pstAeSnsDft->u32MaxIntTimeTarget = 65535;
pstAeSnsDft->u32MinIntTimeTarget = 1;
break;
case WDR_MODE_2To1_LINE:
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 = 0;
CVI_FLOAT f32MaxFps = 0;
CVI_FLOAT f32MinFps = 0;
CVI_U32 u32Vts = 0;
ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL;
CMOS_CHECK_POINTER(pstAeSnsDft);
GC1084_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER(pstSnsState);
u32Vts = g_stGc1084_mode.u32VtsDef;
pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg;
f32MaxFps = g_stGc1084_mode.f32MaxFps;
f32MinFps = g_stGc1084_mode.f32MinFps;
if (pstSnsState->enWDRMode == WDR_MODE_NONE) {
if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) {
u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps);
} else {
CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps);
return CVI_FAILURE;
}
u32VMAX = (u32VMAX > GC1084_FULL_LINES_MAX) ? GC1084_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;
GC1084_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] & 0xFF00) >> 8);
pstSnsRegsInfo->astI2cData[LINEAR_EXP_L].u32Data = (u32IntTime[0] & 0xFF);
return CVI_SUCCESS;
}
static CVI_U32 regValTable[25][6] = {
/* [reg] 0x00d1, 0x00d0, 0x0dc1, 0x00b8, 0x00b9, 0x155
* [name] AGAIN_M, AGAIN_L, AGAIN_H, COLGA_H, COLGA_L, REG_0x0155
*/
{0x00, 0x00, 0x00, 0x01, 0x00, 0x00},
{0x0A, 0x00, 0x00, 0x01, 0x0c, 0x00},
{0x00, 0x01, 0x00, 0x01, 0x1a, 0x00},
{0x0A, 0x01, 0x00, 0x01, 0x2a, 0x00},
{0x00, 0x02, 0x00, 0x02, 0x00, 0x00},
{0x0A, 0x02, 0x00, 0x02, 0x18, 0x00},
{0x00, 0x03, 0x00, 0x02, 0x33, 0x00},
{0x0A, 0x03, 0x00, 0x03, 0x14, 0x00},
{0x00, 0x04, 0x00, 0x04, 0x00, 0x02},
{0x0A, 0x04, 0x00, 0x04, 0x2f, 0x02},
{0x00, 0x05, 0x00, 0x05, 0x26, 0x02},
{0x0A, 0x05, 0x00, 0x06, 0x29, 0x02},
{0x00, 0x06, 0x00, 0x08, 0x00, 0x02},
{0x0A, 0x06, 0x00, 0x09, 0x1f, 0x04},
{0x12, 0x46, 0x00, 0x0b, 0x0d, 0x04},
{0x19, 0x66, 0x00, 0x0d, 0x12, 0x06},
{0x00, 0x04, 0x01, 0x10, 0x00, 0x06},
{0x0A, 0x04, 0x01, 0x12, 0x3e, 0x08},
{0x00, 0x05, 0x01, 0x16, 0x1a, 0x0a},
{0x0A, 0x05, 0x01, 0x1a, 0x23, 0x0c},
{0x00, 0x06, 0x01, 0x20, 0x00, 0x0c},
{0x0A, 0x06, 0x01, 0x25, 0x3b, 0x0f},
{0x12, 0x46, 0x01, 0x2c, 0x33, 0x12},
{0x19, 0x66, 0x01, 0x35, 0x06, 0x14},
{0x20, 0x06, 0x01, 0x3f, 0x3f, 0x15},
};
static CVI_U32 gain_table[25] = {
1024, 1216, 1440, 1696, 2048, 2432, 2864, 3392,
4096, 4848, 5728, 6800, 8192, 9712, 11472, 13584,
16384, 19408, 22944, 27184, 32768, 38832, 45872, 54368,
65536
};
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)
{
UNUSED(ViPipe);
CMOS_CHECK_POINTER(pu32DgainLin);
CMOS_CHECK_POINTER(pu32DgainDb);
*pu32DgainLin = 1024;
*pu32DgainDb = 0;
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);
GC1084_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 */
/* To kepp the linearity. we assume AE algo adjusts the dgain only when the again reachs the maximum value */
if (pu32Again[0] < gain_table[total - 1]) {
for (i = 1; i < total; i++) {
if (*pu32Again < gain_table[i])
break;
}
i--;
// find the pregain
u32Dgain = pu32Again[0] * 64 / gain_table[i];
u32Again = i;
} else {
// find the pregain
u32Dgain = pu32Again[0] * 64 / gain_table[total - 1];
u32Again = total - 1;
}
if (pstSnsState->enWDRMode == WDR_MODE_NONE) {
pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_M].u32Data = regValTable[u32Again][0];
pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_L].u32Data = regValTable[u32Again][1];
pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_REG_0x031D_0x2E].u32Data = 0x2e;
pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_H].u32Data = regValTable[u32Again][2];
pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_REG_0x031D_0x28].u32Data = 0x28;
pstSnsRegsInfo->astI2cData[LINEAR_COL_AGAIN_H].u32Data = regValTable[u32Again][3];
pstSnsRegsInfo->astI2cData[LINEAR_COL_AGAIN_L].u32Data = regValTable[u32Again][4];
pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_REG_0x0155].u32Data = regValTable[u32Again][5];
pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_H].u32Data = (u32Dgain >> 6);
pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_L].u32Data = (u32Dgain & 0x3F) << 2;
} else {
CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport WDRMode: %d\n", pstSnsState->enWDRMode);
return CVI_FAILURE;
}
return CVI_SUCCESS;
}
static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio,
CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime)
{
UNUSED(ViPipe);
UNUSED(u16ManRatioEnable);
UNUSED(au32Ratio);
UNUSED(au32IntTimeMax);
UNUSED(au32IntTimeMin);
UNUSED(pu32LFMaxIntTime);
return CVI_SUCCESS;
}
/* Only used in LINE_WDR mode */
static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr)
{
CMOS_CHECK_POINTER(pstAeFSWDRAttr);
genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode;
gu32MaxTimeGetCnt[ViPipe] = 0;
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 GC1084_MODE_S *pstMode = CVI_NULL;
ISP_SNS_STATE_S *pstSnsState = CVI_NULL;
GC1084_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER(pstSnsState);
pstMode = &g_stGc1084_mode;
pstIspCfg->frm_num = 1;
memcpy(&pstIspCfg->img_size[0], &pstMode->stImg, 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;
GC1084_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER(pstSnsState);
pstSnsState->bSyncInit = CVI_FALSE;
switch (u8Mode) {
case WDR_MODE_NONE:
pstSnsState->u8ImgMode = GC1084_MODE_1280X720P30;
pstSnsState->enWDRMode = WDR_MODE_NONE;
pstSnsState->u32FLStd = g_stGc1084_mode.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);
GC1084_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_aunGc1084_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 = gc1084_i2c_addr;
pstI2c_data[i].u32AddrByteNum = gc1084_addr_byte;
pstI2c_data[i].u32DataByteNum = gc1084_data_byte;
}
pstI2c_data[LINEAR_EXP_H].u32RegAddr = GC1084_EXP_H_ADDR;
pstI2c_data[LINEAR_EXP_L].u32RegAddr = GC1084_EXP_L_ADDR;
pstI2c_data[LINEAR_AGAIN_M].u32RegAddr = GC1084_AGAIN_M_ADDR;
pstI2c_data[LINEAR_AGAIN_L].u32RegAddr = GC1084_AGAIN_L_ADDR;
pstI2c_data[LINEAR_AGAIN_REG_0x031D_0x2E].u32RegAddr = GC1084_AGAIN_REG_0x031D;
pstI2c_data[LINEAR_AGAIN_H].u32RegAddr = GC1084_AGAIN_H_ADDR;
pstI2c_data[LINEAR_AGAIN_REG_0x031D_0x28].u32RegAddr = GC1084_AGAIN_REG_0x031D;
pstI2c_data[LINEAR_COL_AGAIN_H].u32RegAddr = GC1084_COL_AGAIN_H_ADDR;
pstI2c_data[LINEAR_COL_AGAIN_L].u32RegAddr = GC1084_COL_AGAIN_L_ADDR;
pstI2c_data[LINEAR_AGAIN_REG_0x0155].u32RegAddr = GC1084_AGAIN_REG_0x0155;
pstI2c_data[LINEAR_DGAIN_H].u32RegAddr = GC1084_DGAIN_H_ADDR;
pstI2c_data[LINEAR_DGAIN_L].u32RegAddr = GC1084_DGAIN_L_ADDR;
pstI2c_data[LINEAR_VTS_H].u32RegAddr = GC1084_VTS_H_ADDR;
pstI2c_data[LINEAR_VTS_L].u32RegAddr = GC1084_VTS_L_ADDR;
pstI2c_data[LINEAR_FLIP_MIRROR1].u32RegAddr = GC1084_FLIP_MIRROR_ADDR1;
pstI2c_data[LINEAR_FLIP_MIRROR2].u32RegAddr = GC1084_FLIP_MIRROR_ADDR2;
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, expUpdate = 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_M) && (i <= LINEAR_DGAIN_L))
gainsUpdate = 1;
if (i <= LINEAR_EXP_L)
expUpdate = 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_M].bUpdate = CVI_TRUE;
pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_L].bUpdate = CVI_TRUE;
pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_REG_0x031D_0x2E].bUpdate = CVI_TRUE;
pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_H].bUpdate = CVI_TRUE;
pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_REG_0x031D_0x28].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_REG_0x0155].bUpdate = CVI_TRUE;
pstCfg0->snsCfg.astI2cData[LINEAR_DGAIN_H].bUpdate = CVI_TRUE;
pstCfg0->snsCfg.astI2cData[LINEAR_DGAIN_L].bUpdate = CVI_TRUE;
}
if (expUpdate) {
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];
pstCfg0->snsCfg.astI2cData[LINEAR_FLIP_MIRROR1].bDropFrm = CVI_FALSE;
pstCfg0->snsCfg.astI2cData[LINEAR_FLIP_MIRROR2].bDropFrm = CVI_FALSE;
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);
GC1084_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 (GC1084_RES_IS_720P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height))
u8SensorImageMode = GC1084_MODE_1280X720P30;
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)
{
CVI_U8 value = 0;
ISP_SNS_STATE_S *pstSnsState = CVI_NULL;
ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL;
GC1084_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER_VOID(pstSnsState);
pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg;
/* Apply the setting on the fly */
if (pstSnsState->bInit == CVI_TRUE && g_aeGc1084_MirrorFip[ViPipe] != eSnsMirrorFlip) {
switch (eSnsMirrorFlip) {
case ISP_SNS_NORMAL:
value = 0;
break;
case ISP_SNS_MIRROR:
value = 2;
break;
case ISP_SNS_FLIP:
value = 1;
break;
case ISP_SNS_MIRROR_FLIP:
value = 3;
break;
default:
return;
}
pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR1].u32Data = value;
pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR2].u32Data = value;
pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR1].bDropFrm = 1;
pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR2].bDropFrm = 1;
pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR1].u8DropFrmNum = 1;
pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR2].u8DropFrmNum = 1;
g_aeGc1084_MirrorFip[ViPipe] = eSnsMirrorFlip;
}
}
static CVI_VOID sensor_global_init(VI_PIPE ViPipe)
{
ISP_SNS_STATE_S *pstSnsState = CVI_NULL;
GC1084_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER_VOID(pstSnsState);
pstSnsState->bInit = CVI_FALSE;
pstSnsState->bSyncInit = CVI_FALSE;
pstSnsState->u8ImgMode = GC1084_MODE_1280X720P30;
pstSnsState->enWDRMode = WDR_MODE_NONE;
pstSnsState->u32FLStd = g_stGc1084_mode.u32VtsDef;
pstSnsState->au32FL[0] = g_stGc1084_mode.u32VtsDef;
pstSnsState->au32FL[1] = g_stGc1084_mode.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;
GC1084_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER(pstSnsState);
CMOS_CHECK_POINTER(pstRxAttr);
memcpy(pstRxAttr, &gc1084_rx_attr, sizeof(*pstRxAttr));
pstRxAttr->img_size.width = g_stGc1084_mode.stImg.stSnsSize.u32Width;
pstRxAttr->img_size.height = g_stGc1084_mode.stImg.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 = &gc1084_rx_attr;
int i;
CMOS_CHECK_POINTER(pstRxInitAttr);
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 = gc1084_init;
pstSensorExpFunc->pfn_cmos_sensor_exit = gc1084_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_S32 gc1084_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo)
{
g_aunGc1084_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev;
return CVI_SUCCESS;
}
static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe)
{
ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL;
GC1084_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));
GC1084_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx);
return CVI_SUCCESS;
}
static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe)
{
ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL;
GC1084_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx);
SENSOR_FREE(pastSnsStateCtx);
GC1084_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 = GC1084_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, GC1084_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, GC1084_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, GC1084_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_au16Gc1084_GainMode[ViPipe] = pstInitAttr->enGainMode;
g_au16Gc1084_L2SMode[ViPipe] = pstInitAttr->enL2SMode;
return CVI_SUCCESS;
}
static CVI_S32 sensor_probe(VI_PIPE ViPipe)
{
return gc1084_probe(ViPipe);
}
ISP_SNS_OBJ_S stSnsGc1084_Obj = {
.pfnRegisterCallback = sensor_register_callback,
.pfnUnRegisterCallback = sensor_unregister_callback,
.pfnStandby = gc1084_standby,
.pfnRestart = gc1084_restart,
.pfnWriteReg = gc1084_write_register,
.pfnReadReg = gc1084_read_register,
.pfnSetBusInfo = gc1084_set_bus_info,
.pfnSetInit = sensor_set_init,
.pfnMirrorFlip = sensor_mirror_flip,
.pfnPatchRxAttr = sensor_patch_rx_attr,
.pfnPatchI2cAddr = CVI_NULL,
.pfnGetRxAttr = sensor_rx_attr,
.pfnExpSensorCb = cmos_init_sensor_exp_function,
.pfnExpAeCb = cmos_init_ae_exp_function,
.pfnSnsProbe = sensor_probe,
};

View File

@ -0,0 +1,98 @@
#ifndef __GC1084_CMOS_EX_H_
#define __GC1084_CMOS_EX_H_
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
#ifdef ARCH_CV182X
#include <linux/cvi_vip_cif.h>
#include <linux/cvi_vip_snsr.h>
#include "cvi_type.h"
#else
#include <linux/cif_uapi.h>
#include <linux/vi_snsr.h>
#include <linux/cvi_type.h>
#endif
#include "cvi_sns_ctrl.h"
#ifndef UNUSED
#define UNUSED(x) ((void)(x))
#endif
enum gc1084_linear_regs_e {
LINEAR_EXP_H,
LINEAR_EXP_L,
LINEAR_AGAIN_M,
LINEAR_AGAIN_L,
LINEAR_AGAIN_REG_0x031D_0x2E,
LINEAR_AGAIN_H,
LINEAR_AGAIN_REG_0x031D_0x28,
LINEAR_COL_AGAIN_H,
LINEAR_COL_AGAIN_L,
LINEAR_AGAIN_REG_0x0155,
LINEAR_DGAIN_H,
LINEAR_DGAIN_L,
LINEAR_VTS_H,
LINEAR_VTS_L,
LINEAR_FLIP_MIRROR1,
LINEAR_FLIP_MIRROR2,
LINEAR_REGS_NUM
};
typedef enum _GC1084_MODE_E {
GC1084_MODE_1280X720P30 = 0,
GC1084_MODE_NUM
} GC1084_SLAVE_MODE_E;
typedef struct _GC1084_STATE_S {
CVI_U32 u32Sexp_MAX;
} GC1084_STATE_S;
typedef struct _GC1084_MODE_S {
ISP_WDR_SIZE_S stImg;
CVI_FLOAT f32MaxFps;
CVI_FLOAT f32MinFps;
CVI_U32 u32HtsDef;
CVI_U32 u32VtsDef;
SNS_ATTR_S stExp;
SNS_ATTR_LARGE_S stAgain;
SNS_ATTR_LARGE_S stDgain;
char name[64];
} GC1084_MODE_S;
/****************************************************************************
* external variables and functions *
****************************************************************************/
extern ISP_SNS_STATE_S *g_pastGc1084[VI_MAX_PIPE_NUM];
extern ISP_SNS_COMMBUS_U g_aunGc1084_BusInfo[];
extern ISP_SNS_MIRRORFLIP_TYPE_E g_aeGc1084_MirrorFip[VI_MAX_PIPE_NUM];
extern const CVI_U8 gc1084_i2c_addr;
extern const CVI_U32 gc1084_addr_byte;
extern const CVI_U32 gc1084_data_byte;
extern void gc1084_init(VI_PIPE ViPipe);
extern void gc1084_exit(VI_PIPE ViPipe);
extern void gc1084_standby(VI_PIPE ViPipe);
extern void gc1084_restart(VI_PIPE ViPipe);
extern int gc1084_write_register(VI_PIPE ViPipe, int addr, int data);
extern int gc1084_read_register(VI_PIPE ViPipe, int addr);
extern int gc1084_probe(VI_PIPE ViPipe);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* End of #ifdef __cplusplus */
#endif /* __GC1084_CMOS_EX_H_ */

View File

@ -0,0 +1,219 @@
#ifndef __GC1084_CMOS_PARAM_H_
#define __GC1084_CMOS_PARAM_H_
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
#ifdef ARCH_CV182X
#include <linux/cvi_vip_cif.h>
#include <linux/cvi_vip_snsr.h>
#include "cvi_type.h"
#else
#include <linux/cif_uapi.h>
#include <linux/vi_snsr.h>
#include <linux/cvi_type.h>
#endif
#include "cvi_sns_ctrl.h"
#include "gc1084_cmos_ex.h"
static const GC1084_MODE_S g_stGc1084_mode = {
.name = "1280X720P30",
.stImg = {
.stSnsSize = {
.u32Width = 1280,
.u32Height = 720,
},
.stWndRect = {
.s32X = 0,
.s32Y = 0,
.u32Width = 1280,
.u32Height = 720,
},
.stMaxSize = {
.u32Width = 1280,
.u32Height = 720,
},
},
.f32MaxFps = 30,
.f32MinFps = 1.31, /* 750 * 30 / 0xFFFF */
.u32HtsDef = 2200,
.u32VtsDef = 746, /* WIN_H + VB + 16 */
.stExp = {
.u16Min = 1,
.u16Max = 746 - 1, /* VtsDef - 1*/
.u16Def = 100,
.u16Step = 1,
},
.stAgain = {
.u32Min = 1024,
.u32Max = 64 * 1024,
.u32Def = 1024,
.u32Step = 1,
},
.stDgain = {
.u32Min = 1024,
.u32Max = 1024,
.u32Def = 1024,
.u32Step = 1,
},
};
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
, 1092, 1092, 1092, 1092
#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
{1092, 1092, 1093, 1093, 1093, 1093, 1093, 1095,
1099, 1104, 1125, 1130, 1125, 1127, 1126, 1126},
{1092, 1092, 1093, 1093, 1093, 1093, 1094, 1095,
1097, 1104, 1128, 1128, 1126, 1124, 1127, 1127},
{1092, 1092, 1093, 1093, 1093, 1093, 1094, 1095,
1098, 1104, 1128, 1131, 1125, 1127, 1128, 1126},
{1092, 1092, 1093, 1093, 1093, 1093, 1093, 1095,
1097, 1103, 1123, 1124, 1124, 1123, 1121, 1125},
#endif
},
},
};
struct combo_dev_attr_s gc1084_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, -1, -1, -1},
.wdr_mode = CVI_MIPI_WDR_MODE_NONE,
},
.mclk = {
.cam = 0,
.freq = CAMPLL_FREQ_27M,
},
.devno = 0,
};
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* End of #ifdef __cplusplus */
#endif /* __GC1084_CMOS_PARAM_H_ */

View File

@ -0,0 +1,332 @@
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <syslog.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#ifdef ARCH_CV182X
#include <linux/cvi_vip_snsr.h>
#include "cvi_comm_video.h"
#else
#include <linux/vi_snsr.h>
#include <linux/cvi_comm_video.h>
#endif
#include "cvi_sns_ctrl.h"
#include "gc1084_cmos_ex.h"
#define GC1084_CHIP_ID_ADDR_H 0x03f0
#define GC1084_CHIP_ID_ADDR_L 0x03f1
#define GC1084_CHIP_ID 0x1084
static void gc1084_linear_720p30_init(VI_PIPE ViPipe);
const CVI_U8 gc1084_i2c_addr = 0x37;//0x42
const CVI_U32 gc1084_addr_byte = 2;
const CVI_U32 gc1084_data_byte = 1;
static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1};
int gc1084_i2c_init(VI_PIPE ViPipe)
{
char acDevFile[16] = {0};
CVI_U8 u8DevNum;
if (g_fd[ViPipe] >= 0)
return CVI_SUCCESS;
int ret;
u8DevNum = g_aunGc1084_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, gc1084_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 gc1084_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 gc1084_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 (gc1084_addr_byte == 2)
buf[idx++] = (addr >> 8) & 0xff;
// add address byte 0
buf[idx++] = addr & 0xff;
ret = write(g_fd[ViPipe], buf, gc1084_addr_byte);
if (ret < 0) {
CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n");
return 0;
}
buf[0] = 0;
buf[1] = 0;
ret = read(g_fd[ViPipe], buf, gc1084_data_byte);
if (ret < 0) {
CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n");
return 0;
}
// pack read back data
data = 0;
if (gc1084_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 gc1084_write_register(VI_PIPE ViPipe, int addr, int data)
{
CVI_U8 idx = 0;
int ret;
CVI_U8 buf[8];
if (gc1084_addr_byte == 2) {
buf[idx] = (addr >> 8) & 0xff;
idx++;
buf[idx] = addr & 0xff;
idx++;
}
if (gc1084_data_byte == 1) {
buf[idx] = data & 0xff;
idx++;
}
ret = write(g_fd[ViPipe], buf, gc1084_addr_byte + gc1084_data_byte);
if (ret < 0) {
CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n");
return CVI_FAILURE;
}
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 gc1084_standby(VI_PIPE ViPipe)
{
UNUSED(ViPipe);
printf("%s\n", __func__);
}
void gc1084_restart(VI_PIPE ViPipe)
{
UNUSED(ViPipe);
printf("%s\n", __func__);
}
int gc1084_probe(VI_PIPE ViPipe)
{
int nVal;
int nVal2;
usleep(50);
if (gc1084_i2c_init(ViPipe) != CVI_SUCCESS)
return CVI_FAILURE;
nVal = gc1084_read_register(ViPipe, GC1084_CHIP_ID_ADDR_H);
nVal2 = gc1084_read_register(ViPipe, GC1084_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)) != GC1084_CHIP_ID) {
CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n");
return CVI_FAILURE;
}
return CVI_SUCCESS;
}
void gc1084_default_reg_init(VI_PIPE ViPipe)
{
CVI_U32 i;
for (i = 0; i < g_pastGc1084[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) {
gc1084_write_register(ViPipe,
g_pastGc1084[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr,
g_pastGc1084[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data);
}
}
void gc1084_init(VI_PIPE ViPipe)
{
WDR_MODE_E enWDRMode = g_pastGc1084[ViPipe]->enWDRMode;
gc1084_i2c_init(ViPipe);
if (enWDRMode == WDR_MODE_2To1_LINE) {
CVI_TRACE_SNS(CVI_DBG_ERR, "not surpport this WDR_MODE_E!\n");
} else {
gc1084_linear_720p30_init(ViPipe);
}
g_pastGc1084[ViPipe]->bInit = CVI_TRUE;
}
void gc1084_exit(VI_PIPE ViPipe)
{
gc1084_i2c_exit(ViPipe);
}
static void gc1084_linear_720p30_init(VI_PIPE ViPipe)
{
gc1084_write_register(ViPipe, 0x03fe, 0xf0);
gc1084_write_register(ViPipe, 0x03fe, 0xf0);
gc1084_write_register(ViPipe, 0x03fe, 0xf0);
gc1084_write_register(ViPipe, 0x03fe, 0x00);
gc1084_write_register(ViPipe, 0x03f2, 0x00);
gc1084_write_register(ViPipe, 0x03f3, 0x00);
gc1084_write_register(ViPipe, 0x03f4, 0x36);
gc1084_write_register(ViPipe, 0x03f5, 0xc0);
gc1084_write_register(ViPipe, 0x03f6, 0x13);
gc1084_write_register(ViPipe, 0x03f7, 0x01);
gc1084_write_register(ViPipe, 0x03f8, 0x2c);
gc1084_write_register(ViPipe, 0x03f9, 0x21);
gc1084_write_register(ViPipe, 0x03fc, 0xae);
gc1084_write_register(ViPipe, 0x0d05, 0x08);
gc1084_write_register(ViPipe, 0x0d06, 0x98);
gc1084_write_register(ViPipe, 0x0d08, 0x10);
gc1084_write_register(ViPipe, 0x0d0a, 0x02);
gc1084_write_register(ViPipe, 0x000c, 0x03);
gc1084_write_register(ViPipe, 0x0d0d, 0x02);
gc1084_write_register(ViPipe, 0x0d0e, 0xd4);
gc1084_write_register(ViPipe, 0x000f, 0x05);
gc1084_write_register(ViPipe, 0x0010, 0x08);
gc1084_write_register(ViPipe, 0x0017, 0x08);
gc1084_write_register(ViPipe, 0x0d73, 0x92);
gc1084_write_register(ViPipe, 0x0076, 0x00);
gc1084_write_register(ViPipe, 0x0d76, 0x00);
gc1084_write_register(ViPipe, 0x0d41, 0x02);
gc1084_write_register(ViPipe, 0x0d42, 0xee);
gc1084_write_register(ViPipe, 0x0d7a, 0x0a);
gc1084_write_register(ViPipe, 0x006b, 0x18);
gc1084_write_register(ViPipe, 0x0db0, 0x9d);
gc1084_write_register(ViPipe, 0x0db1, 0x00);
gc1084_write_register(ViPipe, 0x0db2, 0xac);
gc1084_write_register(ViPipe, 0x0db3, 0xd5);
gc1084_write_register(ViPipe, 0x0db4, 0x00);
gc1084_write_register(ViPipe, 0x0db5, 0x97);
gc1084_write_register(ViPipe, 0x0db6, 0x09);
gc1084_write_register(ViPipe, 0x00d2, 0xfc);
gc1084_write_register(ViPipe, 0x0d19, 0x31);
gc1084_write_register(ViPipe, 0x0d20, 0x40);
gc1084_write_register(ViPipe, 0x0d25, 0xcb);
gc1084_write_register(ViPipe, 0x0d27, 0x03);
gc1084_write_register(ViPipe, 0x0d29, 0x40);
gc1084_write_register(ViPipe, 0x0d43, 0x20);
gc1084_write_register(ViPipe, 0x0058, 0x60);
gc1084_write_register(ViPipe, 0x00d6, 0x66);
gc1084_write_register(ViPipe, 0x00d7, 0x19);
gc1084_write_register(ViPipe, 0x0093, 0x02);
gc1084_write_register(ViPipe, 0x00d9, 0x14);
gc1084_write_register(ViPipe, 0x00da, 0xc1);
gc1084_write_register(ViPipe, 0x0d2a, 0x00);
gc1084_write_register(ViPipe, 0x0d28, 0x04);
gc1084_write_register(ViPipe, 0x0dc2, 0x84);
gc1084_write_register(ViPipe, 0x0050, 0x30);
gc1084_write_register(ViPipe, 0x0080, 0x07);
gc1084_write_register(ViPipe, 0x008c, 0x05);
gc1084_write_register(ViPipe, 0x008d, 0xa8);
gc1084_write_register(ViPipe, 0x0077, 0x01);
gc1084_write_register(ViPipe, 0x0078, 0xee);
gc1084_write_register(ViPipe, 0x0079, 0x02);
gc1084_write_register(ViPipe, 0x0067, 0xc0);
gc1084_write_register(ViPipe, 0x0054, 0xff);
gc1084_write_register(ViPipe, 0x0055, 0x02);
gc1084_write_register(ViPipe, 0x0056, 0x00);
gc1084_write_register(ViPipe, 0x0057, 0x04);
gc1084_write_register(ViPipe, 0x005a, 0xff);
gc1084_write_register(ViPipe, 0x005b, 0x07);
gc1084_write_register(ViPipe, 0x00d5, 0x03);
gc1084_write_register(ViPipe, 0x0102, 0xa9);
gc1084_write_register(ViPipe, 0x0d03, 0x02);
gc1084_write_register(ViPipe, 0x0d04, 0xd0);
gc1084_write_register(ViPipe, 0x007a, 0x60);
gc1084_write_register(ViPipe, 0x04e0, 0xff);
gc1084_write_register(ViPipe, 0x0414, 0x75);
gc1084_write_register(ViPipe, 0x0415, 0x75);
gc1084_write_register(ViPipe, 0x0416, 0x75);
gc1084_write_register(ViPipe, 0x0417, 0x75);
gc1084_write_register(ViPipe, 0x0122, 0x00);
gc1084_write_register(ViPipe, 0x0121, 0x80);
gc1084_write_register(ViPipe, 0x0428, 0x10);
gc1084_write_register(ViPipe, 0x0429, 0x10);
gc1084_write_register(ViPipe, 0x042a, 0x10);
gc1084_write_register(ViPipe, 0x042b, 0x10);
gc1084_write_register(ViPipe, 0x042c, 0x14);
gc1084_write_register(ViPipe, 0x042d, 0x14);
gc1084_write_register(ViPipe, 0x042e, 0x18);
gc1084_write_register(ViPipe, 0x042f, 0x18);
gc1084_write_register(ViPipe, 0x0430, 0x05);
gc1084_write_register(ViPipe, 0x0431, 0x05);
gc1084_write_register(ViPipe, 0x0432, 0x05);
gc1084_write_register(ViPipe, 0x0433, 0x05);
gc1084_write_register(ViPipe, 0x0434, 0x05);
gc1084_write_register(ViPipe, 0x0435, 0x05);
gc1084_write_register(ViPipe, 0x0436, 0x05);
gc1084_write_register(ViPipe, 0x0437, 0x05);
gc1084_write_register(ViPipe, 0x0153, 0x00);
gc1084_write_register(ViPipe, 0x0190, 0x01);
gc1084_write_register(ViPipe, 0x0192, 0x02);
gc1084_write_register(ViPipe, 0x0194, 0x04);
gc1084_write_register(ViPipe, 0x0195, 0x02);
gc1084_write_register(ViPipe, 0x0196, 0xd0);
gc1084_write_register(ViPipe, 0x0197, 0x05);
gc1084_write_register(ViPipe, 0x0198, 0x00);
gc1084_write_register(ViPipe, 0x0201, 0x23);
gc1084_write_register(ViPipe, 0x0202, 0x53);
gc1084_write_register(ViPipe, 0x0203, 0xce);
gc1084_write_register(ViPipe, 0x0208, 0x39);
gc1084_write_register(ViPipe, 0x0212, 0x06);
gc1084_write_register(ViPipe, 0x0213, 0x40);
gc1084_write_register(ViPipe, 0x0215, 0x12);
gc1084_write_register(ViPipe, 0x0229, 0x05);
gc1084_write_register(ViPipe, 0x023e, 0x98);
gc1084_write_register(ViPipe, 0x031e, 0x3e);
gc1084_default_reg_init(ViPipe);
delay_ms(40);
printf("ViPipe:%d,===GC1084 720P 30fps 10bit LINE Init OK!===\n", ViPipe);
}

View File

@ -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_gc1084_slave.a
TARGET_SO = $(MW_LIB)/libsns_gc1084_slave.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)

View File

@ -0,0 +1,985 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <syslog.h>
#include <errno.h>
#ifdef ARCH_CV182X
#include "cvi_type.h"
#include "cvi_comm_video.h"
#include <linux/cvi_vip_snsr.h>
#else
#include <linux/cvi_type.h>
#include <linux/cvi_comm_video.h>
#include <linux/vi_snsr.h>
#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 "gc1084_slave_cmos_ex.h"
#include "gc1084_slave_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 GC1084_SLAVE_ID 1084
/****************************************************************************
* global variables *
****************************************************************************/
ISP_SNS_STATE_S *g_pastGc1084_Slave[VI_MAX_PIPE_NUM] = {CVI_NULL};
#define GC1084_SLAVE_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastGc1084_Slave[dev])
#define GC1084_SLAVE_SENSOR_SET_CTX(dev, pstCtx) (g_pastGc1084_Slave[dev] = pstCtx)
#define GC1084_SLAVE_SENSOR_RESET_CTX(dev) (g_pastGc1084_Slave[dev] = CVI_NULL)
ISP_SNS_COMMBUS_U g_aunGc1084_Slave_BusInfo[VI_MAX_PIPE_NUM] = {
[0] = { .s8I2cDev = 0},
[1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1}
};
GC1084_SLAVE_STATE_S g_astGc1084_Slave_State[VI_MAX_PIPE_NUM] = { {0} };
ISP_SNS_MIRRORFLIP_TYPE_E g_aeGc1084_Slave_MirrorFip[VI_MAX_PIPE_NUM] = {0};
CVI_U16 g_au16Gc1084_Slave_GainMode[VI_MAX_PIPE_NUM] = {0};
CVI_U16 g_au16Gc1084_Slave_L2SMode[VI_MAX_PIPE_NUM] = {0};
/****************************************************************************
* local variables and functions *
****************************************************************************/
static ISP_FSWDR_MODE_E genFSWDRMode[VI_MAX_PIPE_NUM] = {
[0 ... VI_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE
};
static CVI_U32 gu32MaxTimeGetCnt[VI_MAX_PIPE_NUM] = {0};
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);
/*****Gc1084 Lines Range*****/
#define GC1084_SLAVE_FULL_LINES_MAX (17119) // 0x3FFF(Max VB) + 720 + 16
/*****Gc1084 Register Address*****/
#define GC1084_SLAVE_EXP_H_ADDR 0x0d03
#define GC1084_SLAVE_EXP_L_ADDR 0x0d04
#define GC1084_SLAVE_AGAIN_M_ADDR 0x00d1
#define GC1084_SLAVE_AGAIN_L_ADDR 0x00d0
#define GC1084_SLAVE_AGAIN_REG_0x031D 0x031d
#define GC1084_SLAVE_AGAIN_H_ADDR 0x0dc1
#define GC1084_SLAVE_COL_AGAIN_H_ADDR 0x00b8
#define GC1084_SLAVE_COL_AGAIN_L_ADDR 0x00b9
#define GC1084_SLAVE_AGAIN_REG_0x0155 0x0155
#define GC1084_SLAVE_DGAIN_H_ADDR 0x00b1
#define GC1084_SLAVE_DGAIN_L_ADDR 0x00b2
#define GC1084_SLAVE_VTS_H_ADDR 0x0d41
#define GC1084_SLAVE_VTS_L_ADDR 0x0042
#define GC1084_SLAVE_VB_H_ADDR 0x0d79
#define GC1084_SLAVE_VB_L_ADDR 0x0d7a
#define GC1084_SLAVE_FLIP_MIRROR_ADDR1 0x0015
#define GC1084_SLAVE_FLIP_MIRROR_ADDR2 0x0d15
#define GC1084_SLAVE_RES_IS_720P(w, h) ((w) <= 1280 && (h) <= 720)
static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft)
{
const GC1084_SLAVE_MODE_S *pstMode;
ISP_SNS_STATE_S *pstSnsState = CVI_NULL;
CMOS_CHECK_POINTER(pstAeSnsDft);
GC1084_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER(pstSnsState);
pstMode = &g_stGc1084_Slave_mode;
pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd;
pstAeSnsDft->u32FlickerFreq = 50 * 256;
pstAeSnsDft->u32FullLinesMax = GC1084_SLAVE_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];
#if 0
pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0;
pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0;
pstAeSnsDft->bAERouteExValid = CVI_FALSE;
pstAeSnsDft->stAERouteAttr.u32TotalNum = 0;
pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0;
#endif
switch (pstSnsState->enWDRMode) {
default:
case WDR_MODE_NONE: /*linear mode*/
pstAeSnsDft->f32Fps = pstMode->f32MaxFps;
pstAeSnsDft->f32MinFps = pstMode->f32MinFps;
pstAeSnsDft->au8HistThresh[0] = 0xd;
pstAeSnsDft->au8HistThresh[1] = 0x28;
pstAeSnsDft->au8HistThresh[2] = 0x60;
pstAeSnsDft->au8HistThresh[3] = 0x80;
pstAeSnsDft->u32MaxAgain = pstMode->stAgain.u32Max;
pstAeSnsDft->u32MinAgain = pstMode->stAgain.u32Min;
pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain;
pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain;
pstAeSnsDft->u32MaxDgain = pstMode->stDgain.u32Max;
pstAeSnsDft->u32MinDgain = pstMode->stDgain.u32Min;
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] :
pstMode->stExp.u16Def;
pstAeSnsDft->u32MaxIntTime = pstMode->stExp.u16Max;
pstAeSnsDft->u32MinIntTime = pstMode->stExp.u16Min;
pstAeSnsDft->u32MaxIntTimeTarget = 65535;
pstAeSnsDft->u32MinIntTimeTarget = 1;
break;
case WDR_MODE_2To1_LINE:
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 = 0, u32VB = 0;
CVI_FLOAT f32MaxFps = 0;
CVI_FLOAT f32MinFps = 0;
CVI_U32 u32Vts = 0;
ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL;
CMOS_CHECK_POINTER(pstAeSnsDft);
GC1084_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER(pstSnsState);
u32Vts = g_stGc1084_Slave_mode.u32VtsDef;
pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg;
f32MaxFps = g_stGc1084_Slave_mode.f32MaxFps;
f32MinFps = g_stGc1084_Slave_mode.f32MinFps;
if (pstSnsState->enWDRMode == WDR_MODE_NONE) {
if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) {
u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps);
} else {
CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport Fps: %f\n", f32Fps);
return CVI_FAILURE;
}
u32VMAX = (u32VMAX > GC1084_SLAVE_FULL_LINES_MAX) ? GC1084_SLAVE_FULL_LINES_MAX : u32VMAX;
u32VB = u32VMAX - 720 - 16;//vts - win_h -16
pstSnsRegsInfo->astI2cData[LINEAR_VTS_H].u32Data = ((u32VMAX & 0xFF00) >> 8);
pstSnsRegsInfo->astI2cData[LINEAR_VTS_L].u32Data = (u32VMAX & 0xFF);
pstSnsRegsInfo->astI2cData[LINEAR_VB_H].u32Data = ((u32VB & 0xFF00) >> 8);
pstSnsRegsInfo->astI2cData[LINEAR_VB_L].u32Data = (u32VB & 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;
GC1084_SLAVE_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] & 0xFF00) >> 8);
pstSnsRegsInfo->astI2cData[LINEAR_EXP_L].u32Data = (u32IntTime[0] & 0xFF);
return CVI_SUCCESS;
}
static CVI_U32 regValTable[25][6] = {
/* [reg] 0x00d1, 0x00d0, 0x0dc1, 0x00b8, 0x00b9, 0x155
* [name] AGAIN_M AGAIN_L AGAIN_H COLGA_H COLGA_L REG_0x0155
*/
{0x00, 0x00, 0x00, 0x01, 0x00, 0x00},
{0x0A, 0x00, 0x00, 0x01, 0x0c, 0x00},
{0x00, 0x01, 0x00, 0x01, 0x1a, 0x00},
{0x0A, 0x01, 0x00, 0x01, 0x2a, 0x00},
{0x00, 0x02, 0x00, 0x02, 0x00, 0x00},
{0x0A, 0x02, 0x00, 0x02, 0x18, 0x00},
{0x00, 0x03, 0x00, 0x02, 0x33, 0x00},
{0x0A, 0x03, 0x00, 0x03, 0x14, 0x00},
{0x00, 0x04, 0x00, 0x04, 0x00, 0x02},
{0x0A, 0x04, 0x00, 0x04, 0x2f, 0x02},
{0x00, 0x05, 0x00, 0x05, 0x26, 0x02},
{0x0A, 0x05, 0x00, 0x06, 0x29, 0x02},
{0x00, 0x06, 0x00, 0x08, 0x00, 0x02},
{0x0A, 0x06, 0x00, 0x09, 0x1f, 0x04},
{0x12, 0x46, 0x00, 0x0b, 0x0d, 0x04},
{0x19, 0x66, 0x00, 0x0d, 0x12, 0x06},
{0x00, 0x04, 0x01, 0x10, 0x00, 0x06},
{0x0A, 0x04, 0x01, 0x12, 0x3e, 0x08},
{0x00, 0x05, 0x01, 0x16, 0x1a, 0x0a},
{0x0A, 0x05, 0x01, 0x1a, 0x23, 0x0c},
{0x00, 0x06, 0x01, 0x20, 0x00, 0x0c},
{0x0A, 0x06, 0x01, 0x25, 0x3b, 0x0f},
{0x12, 0x46, 0x01, 0x2c, 0x33, 0x12},
{0x19, 0x66, 0x01, 0x35, 0x06, 0x14},
{0x20, 0x06, 0x01, 0x3f, 0x3f, 0x15},
};
static CVI_U32 gain_table[25] = {
1024, 1216, 1440, 1696, 2048, 2432, 2864, 3392,
4096, 4848, 5728, 6800, 8192, 9712, 11472, 13584,
16384, 19408, 22944, 27184, 32768, 38832, 45872, 54368,
65536
};
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)
{
UNUSED(ViPipe);
CMOS_CHECK_POINTER(pu32DgainLin);
CMOS_CHECK_POINTER(pu32DgainDb);
*pu32DgainLin = 1024;
*pu32DgainDb = 0;
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);
GC1084_SLAVE_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 */
/* To kepp the linearity. we assume AE algo adjusts the dgain only when the again reachs the maximum value */
if (pu32Again[0] < gain_table[total - 1]) {
for (i = 1; i < total; i++) {
if (*pu32Again < gain_table[i])
break;
}
i--;
// find the pregain
u32Dgain = pu32Again[0] * 64 / gain_table[i];
u32Again = i;
} else {
// find the pregain
u32Dgain = pu32Again[0] * 64 / gain_table[total - 1];
u32Again = total - 1;
}
if (pstSnsState->enWDRMode == WDR_MODE_NONE) {
pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_M].u32Data = regValTable[u32Again][0];
pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_L].u32Data = regValTable[u32Again][1];
pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_REG_0x031D_0x2E].u32Data = 0x2e;
pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_H].u32Data = regValTable[u32Again][2];
pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_REG_0x031D_0x28].u32Data = 0x28;
pstSnsRegsInfo->astI2cData[LINEAR_COL_AGAIN_H].u32Data = regValTable[u32Again][3];
pstSnsRegsInfo->astI2cData[LINEAR_COL_AGAIN_L].u32Data = regValTable[u32Again][4];
pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_REG_0x0155].u32Data = regValTable[u32Again][5];
pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_H].u32Data = (u32Dgain >> 6);
pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_L].u32Data = (u32Dgain & 0x3F) << 2;
} else {
CVI_TRACE_SNS(CVI_DBG_ERR, "Unsupport WDRMode: %d\n", pstSnsState->enWDRMode);
return CVI_FAILURE;
}
return CVI_SUCCESS;
}
static CVI_S32 cmos_get_inttime_max(VI_PIPE ViPipe, CVI_U16 u16ManRatioEnable, CVI_U32 *au32Ratio,
CVI_U32 *au32IntTimeMax, CVI_U32 *au32IntTimeMin, CVI_U32 *pu32LFMaxIntTime)
{
UNUSED(ViPipe);
UNUSED(u16ManRatioEnable);
UNUSED(au32Ratio);
UNUSED(au32IntTimeMax);
UNUSED(au32IntTimeMin);
UNUSED(pu32LFMaxIntTime);
return CVI_SUCCESS;
}
/* Only used in LINE_WDR mode */
static CVI_S32 cmos_ae_fswdr_attr_set(VI_PIPE ViPipe, AE_FSWDR_ATTR_S *pstAeFSWDRAttr)
{
CMOS_CHECK_POINTER(pstAeFSWDRAttr);
genFSWDRMode[ViPipe] = pstAeFSWDRAttr->enFSWDRMode;
gu32MaxTimeGetCnt[ViPipe] = 0;
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 GC1084_SLAVE_MODE_S *pstMode = CVI_NULL;
ISP_SNS_STATE_S *pstSnsState = CVI_NULL;
GC1084_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER(pstSnsState);
pstMode = &g_stGc1084_Slave_mode;
pstIspCfg->frm_num = 1;
memcpy(&pstIspCfg->img_size[0], &pstMode->stImg, 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;
GC1084_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER(pstSnsState);
pstSnsState->bSyncInit = CVI_FALSE;
switch (u8Mode) {
case WDR_MODE_NONE:
pstSnsState->u8ImgMode = GC1084_SLAVE_MODE_1280X720P30;
pstSnsState->enWDRMode = WDR_MODE_NONE;
pstSnsState->u32FLStd = g_stGc1084_Slave_mode.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);
GC1084_SLAVE_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_aunGc1084_Slave_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 = gc1084_slave_i2c_addr;
pstI2c_data[i].u32AddrByteNum = gc1084_slave_addr_byte;
pstI2c_data[i].u32DataByteNum = gc1084_slave_data_byte;
}
pstI2c_data[LINEAR_EXP_H].u32RegAddr = GC1084_SLAVE_EXP_H_ADDR;
pstI2c_data[LINEAR_EXP_L].u32RegAddr = GC1084_SLAVE_EXP_L_ADDR;
pstI2c_data[LINEAR_AGAIN_M].u32RegAddr = GC1084_SLAVE_AGAIN_M_ADDR;
pstI2c_data[LINEAR_AGAIN_L].u32RegAddr = GC1084_SLAVE_AGAIN_L_ADDR;
pstI2c_data[LINEAR_AGAIN_REG_0x031D_0x2E].u32RegAddr = GC1084_SLAVE_AGAIN_REG_0x031D;
pstI2c_data[LINEAR_AGAIN_H].u32RegAddr = GC1084_SLAVE_AGAIN_H_ADDR;
pstI2c_data[LINEAR_AGAIN_REG_0x031D_0x28].u32RegAddr = GC1084_SLAVE_AGAIN_REG_0x031D;
pstI2c_data[LINEAR_COL_AGAIN_H].u32RegAddr = GC1084_SLAVE_COL_AGAIN_H_ADDR;
pstI2c_data[LINEAR_COL_AGAIN_L].u32RegAddr = GC1084_SLAVE_COL_AGAIN_L_ADDR;
pstI2c_data[LINEAR_AGAIN_REG_0x0155].u32RegAddr = GC1084_SLAVE_AGAIN_REG_0x0155;
pstI2c_data[LINEAR_DGAIN_H].u32RegAddr = GC1084_SLAVE_DGAIN_H_ADDR;
pstI2c_data[LINEAR_DGAIN_L].u32RegAddr = GC1084_SLAVE_DGAIN_L_ADDR;
pstI2c_data[LINEAR_VTS_H].u32RegAddr = GC1084_SLAVE_VTS_H_ADDR;
pstI2c_data[LINEAR_VTS_L].u32RegAddr = GC1084_SLAVE_VTS_L_ADDR;
pstI2c_data[LINEAR_VB_H].u32RegAddr = GC1084_SLAVE_VB_H_ADDR;
pstI2c_data[LINEAR_VB_L].u32RegAddr = GC1084_SLAVE_VB_L_ADDR;
pstI2c_data[LINEAR_FLIP_MIRROR1].u32RegAddr = GC1084_SLAVE_FLIP_MIRROR_ADDR1;
pstI2c_data[LINEAR_FLIP_MIRROR2].u32RegAddr = GC1084_SLAVE_FLIP_MIRROR_ADDR2;
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, expUpdate = 0, vbUpdate = 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_M) && (i <= LINEAR_DGAIN_L))
gainsUpdate = 1;
if (i <= LINEAR_EXP_L)
expUpdate = 1;
if ((i >= LINEAR_VTS_H) && (i <= LINEAR_VB_L))
vbUpdate = 1;
pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE;
pstCfg0->snsCfg.need_update = CVI_TRUE;
}
}
if (gainsUpdate) {
pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_M].bUpdate = CVI_TRUE;
pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_L].bUpdate = CVI_TRUE;
pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_REG_0x031D_0x2E].bUpdate = CVI_TRUE;
pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_H].bUpdate = CVI_TRUE;
pstCfg0->snsCfg.astI2cData[LINEAR_AGAIN_REG_0x031D_0x28].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_REG_0x0155].bUpdate = CVI_TRUE;
pstCfg0->snsCfg.astI2cData[LINEAR_DGAIN_H].bUpdate = CVI_TRUE;
pstCfg0->snsCfg.astI2cData[LINEAR_DGAIN_L].bUpdate = CVI_TRUE;
}
if (expUpdate) {
pstCfg0->snsCfg.astI2cData[LINEAR_EXP_H].bUpdate = CVI_TRUE;
pstCfg0->snsCfg.astI2cData[LINEAR_EXP_L].bUpdate = CVI_TRUE;
}
if (vbUpdate) {
pstCfg0->snsCfg.astI2cData[LINEAR_VTS_H].bUpdate = CVI_TRUE;
pstCfg0->snsCfg.astI2cData[LINEAR_VTS_L].bUpdate = CVI_TRUE;
pstCfg0->snsCfg.astI2cData[LINEAR_VB_H].bUpdate = CVI_TRUE;
pstCfg0->snsCfg.astI2cData[LINEAR_VB_L].bUpdate = CVI_TRUE;
}
if ((pstI2c_data[LINEAR_FLIP_MIRROR1].bUpdate == CVI_TRUE) && (pstI2c_data[LINEAR_FLIP_MIRROR2].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];
pstCfg0->snsCfg.astI2cData[LINEAR_FLIP_MIRROR1].bDropFrm = CVI_FALSE;
pstCfg0->snsCfg.astI2cData[LINEAR_FLIP_MIRROR2].bDropFrm = CVI_FALSE;
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);
GC1084_SLAVE_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 (GC1084_SLAVE_RES_IS_720P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height))
u8SensorImageMode = GC1084_SLAVE_MODE_1280X720P30;
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)
{
CVI_U8 value = 0;
ISP_SNS_STATE_S *pstSnsState = CVI_NULL;
ISP_SNS_REGS_INFO_S *pstSnsRegsInfo = CVI_NULL;
GC1084_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER_VOID(pstSnsState);
pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg;
/* Apply the setting on the fly */
if (pstSnsState->bInit == CVI_TRUE && g_aeGc1084_Slave_MirrorFip[ViPipe] != eSnsMirrorFlip) {
switch (eSnsMirrorFlip) {
case ISP_SNS_NORMAL:
value = 0;
break;
case ISP_SNS_MIRROR:
value = 2;
break;
case ISP_SNS_FLIP:
value = 1;
break;
case ISP_SNS_MIRROR_FLIP:
value = 3;
break;
default:
return;
}
pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR1].u32Data = value;
pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR2].u32Data = value;
pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR1].bDropFrm = 1;
pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR2].bDropFrm = 1;
pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR1].u8DropFrmNum = 1;
pstSnsRegsInfo->astI2cData[LINEAR_FLIP_MIRROR2].u8DropFrmNum = 1;
g_aeGc1084_Slave_MirrorFip[ViPipe] = eSnsMirrorFlip;
}
}
static CVI_VOID sensor_global_init(VI_PIPE ViPipe)
{
ISP_SNS_STATE_S *pstSnsState = CVI_NULL;
GC1084_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER_VOID(pstSnsState);
pstSnsState->bInit = CVI_FALSE;
pstSnsState->bSyncInit = CVI_FALSE;
pstSnsState->u8ImgMode = GC1084_SLAVE_MODE_1280X720P30;
pstSnsState->enWDRMode = WDR_MODE_NONE;
pstSnsState->u32FLStd = g_stGc1084_Slave_mode.u32VtsDef;
pstSnsState->au32FL[0] = g_stGc1084_Slave_mode.u32VtsDef;
pstSnsState->au32FL[1] = g_stGc1084_Slave_mode.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;
GC1084_SLAVE_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER(pstSnsState);
CMOS_CHECK_POINTER(pstRxAttr);
memcpy(pstRxAttr, &gc1084_slave_rx_attr, sizeof(*pstRxAttr));
pstRxAttr->img_size.width = g_stGc1084_Slave_mode.stImg.stSnsSize.u32Width;
pstRxAttr->img_size.height = g_stGc1084_Slave_mode.stImg.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 = &gc1084_slave_rx_attr;
int i;
CMOS_CHECK_POINTER(pstRxInitAttr);
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 = gc1084_slave_init;
pstSensorExpFunc->pfn_cmos_sensor_exit = gc1084_slave_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_S32 gc1084_slave_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo)
{
g_aunGc1084_Slave_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev;
return CVI_SUCCESS;
}
static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe)
{
ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL;
GC1084_SLAVE_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));
GC1084_SLAVE_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx);
return CVI_SUCCESS;
}
static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe)
{
ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL;
GC1084_SLAVE_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx);
SENSOR_FREE(pastSnsStateCtx);
GC1084_SLAVE_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 = GC1084_SLAVE_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, GC1084_SLAVE_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, GC1084_SLAVE_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, GC1084_SLAVE_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_au16Gc1084_Slave_GainMode[ViPipe] = pstInitAttr->enGainMode;
g_au16Gc1084_Slave_L2SMode[ViPipe] = pstInitAttr->enL2SMode;
return CVI_SUCCESS;
}
ISP_SNS_OBJ_S stSnsGc1084_Slave_Obj = {
.pfnRegisterCallback = sensor_register_callback,
.pfnUnRegisterCallback = sensor_unregister_callback,
.pfnStandby = gc1084_slave_standby,
.pfnRestart = gc1084_slave_restart,
.pfnWriteReg = gc1084_slave_write_register,
.pfnReadReg = gc1084_slave_read_register,
.pfnSetBusInfo = gc1084_slave_set_bus_info,
.pfnSetInit = sensor_set_init,
.pfnMirrorFlip = sensor_mirror_flip,
.pfnPatchRxAttr = sensor_patch_rx_attr,
.pfnPatchI2cAddr = CVI_NULL,
.pfnGetRxAttr = sensor_rx_attr,
.pfnExpSensorCb = cmos_init_sensor_exp_function,
.pfnExpAeCb = cmos_init_ae_exp_function,
.pfnSnsProbe = CVI_NULL,
};

View File

@ -0,0 +1,99 @@
#ifndef __GC1084_SLAVE_CMOS_EX_H_
#define __GC1084_SLAVE_CMOS_EX_H_
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
#ifdef ARCH_CV182X
#include <linux/cvi_vip_cif.h>
#include <linux/cvi_vip_snsr.h>
#include "cvi_type.h"
#else
#include <linux/cif_uapi.h>
#include <linux/vi_snsr.h>
#include <linux/cvi_type.h>
#endif
#include "cvi_sns_ctrl.h"
#ifndef UNUSED
#define UNUSED(x) ((void)(x))
#endif
enum gc1084_slave_linear_regs_e {
LINEAR_EXP_H,
LINEAR_EXP_L,
LINEAR_AGAIN_M,
LINEAR_AGAIN_L,
LINEAR_AGAIN_REG_0x031D_0x2E,
LINEAR_AGAIN_H,
LINEAR_AGAIN_REG_0x031D_0x28,
LINEAR_COL_AGAIN_H,
LINEAR_COL_AGAIN_L,
LINEAR_AGAIN_REG_0x0155,
LINEAR_DGAIN_H,
LINEAR_DGAIN_L,
LINEAR_VTS_H,
LINEAR_VTS_L,
LINEAR_VB_H,
LINEAR_VB_L,
LINEAR_FLIP_MIRROR1,
LINEAR_FLIP_MIRROR2,
LINEAR_REGS_NUM
};
typedef enum _GC1084_SLAVE_MODE_E {
GC1084_SLAVE_MODE_1280X720P30 = 0,
GC1084_SLAVE_MODE_NUM
} GC1084_SLAVE_SLAVE_MODE_E;
typedef struct _GC1084_SLAVE_STATE_S {
CVI_U32 u32Sexp_MAX;
} GC1084_SLAVE_STATE_S;
typedef struct _GC1084_SLAVE_MODE_S {
ISP_WDR_SIZE_S stImg;
CVI_FLOAT f32MaxFps;
CVI_FLOAT f32MinFps;
CVI_U32 u32HtsDef;
CVI_U32 u32VtsDef;
SNS_ATTR_S stExp;
SNS_ATTR_LARGE_S stAgain;
SNS_ATTR_LARGE_S stDgain;
char name[64];
} GC1084_SLAVE_MODE_S;
/****************************************************************************
* external variables and functions *
****************************************************************************/
extern ISP_SNS_STATE_S *g_pastGc1084_Slave[VI_MAX_PIPE_NUM];
extern ISP_SNS_COMMBUS_U g_aunGc1084_Slave_BusInfo[];
extern ISP_SNS_MIRRORFLIP_TYPE_E g_aeGc1084_Slave_MirrorFip[VI_MAX_PIPE_NUM];
extern const CVI_U8 gc1084_slave_i2c_addr;
extern const CVI_U32 gc1084_slave_addr_byte;
extern const CVI_U32 gc1084_slave_data_byte;
extern void gc1084_slave_init(VI_PIPE ViPipe);
extern void gc1084_slave_exit(VI_PIPE ViPipe);
extern void gc1084_slave_standby(VI_PIPE ViPipe);
extern void gc1084_slave_restart(VI_PIPE ViPipe);
extern int gc1084_slave_write_register(VI_PIPE ViPipe, int addr, int data);
extern int gc1084_slave_read_register(VI_PIPE ViPipe, int addr);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* End of #ifdef __cplusplus */
#endif /* __GC1084_SLAVE_CMOS_EX_H_ */

View File

@ -0,0 +1,219 @@
#ifndef __GC1084_SLAVE_CMOS_PARAM_H_
#define __GC1084_SLAVE_CMOS_PARAM_H_
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
#ifdef ARCH_CV182X
#include <linux/cvi_vip_cif.h>
#include <linux/cvi_vip_snsr.h>
#include "cvi_type.h"
#else
#include <linux/cif_uapi.h>
#include <linux/vi_snsr.h>
#include <linux/cvi_type.h>
#endif
#include "cvi_sns_ctrl.h"
#include "gc1084_slave_cmos_ex.h"
static const GC1084_SLAVE_MODE_S g_stGc1084_Slave_mode = {
.name = "1280X720P30",
.stImg = {
.stSnsSize = {
.u32Width = 1280,
.u32Height = 720,
},
.stWndRect = {
.s32X = 0,
.s32Y = 0,
.u32Width = 1280,
.u32Height = 720,
},
.stMaxSize = {
.u32Width = 1280,
.u32Height = 720,
},
},
.f32MaxFps = 30,
.f32MinFps = 1.31, /* 750 * 30 / 0xFFFF */
.u32HtsDef = 2200,
.u32VtsDef = 746, /* WIN_H + VB + 16 */
.stExp = {
.u16Min = 1,
.u16Max = 746 - 1, /* VtsDef - 1*/
.u16Def = 100,
.u16Step = 1,
},
.stAgain = {
.u32Min = 1024,
.u32Max = 64 * 1024,
.u32Def = 1024,
.u32Step = 1,
},
.stDgain = {
.u32Min = 1024,
.u32Max = 1024,
.u32Def = 1024,
.u32Step = 1,
},
};
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 = {0, 0, 0, 0, 0, 0, 0, 0
#ifdef ARCH_CV182X
, 1092, 1092, 1092, 1092
#endif
},
.stAuto = {
{0, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252 },
{0, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252 },
{0, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252 },
{0, 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
{1092, 1092, 1093, 1093, 1093, 1093, 1093, 1095,
1099, 1104, 1125, 1130, 1125, 1127, 1126, 1126},
{1092, 1092, 1093, 1093, 1093, 1093, 1094, 1095,
1097, 1104, 1128, 1128, 1126, 1124, 1127, 1127},
{1092, 1092, 1093, 1093, 1093, 1093, 1094, 1095,
1098, 1104, 1128, 1131, 1125, 1127, 1128, 1126},
{1092, 1092, 1093, 1093, 1093, 1093, 1093, 1095,
1097, 1103, 1123, 1124, 1124, 1123, 1121, 1125},
#endif
},
},
};
struct combo_dev_attr_s gc1084_slave_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, -1, -1, -1},
.wdr_mode = CVI_MIPI_WDR_MODE_NONE,
},
.mclk = {
.cam = 1,
.freq = CAMPLL_FREQ_27M,
},
.devno = 1,
};
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* End of #ifdef __cplusplus */
#endif /* __GC1084_SLAVE_CMOS_PARAM_H_ */

View File

@ -0,0 +1,271 @@
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <syslog.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#ifdef ARCH_CV182X
#include <linux/cvi_vip_snsr.h>
#include "cvi_comm_video.h"
#else
#include <linux/vi_snsr.h>
#include <linux/cvi_comm_video.h>
#endif
#include "cvi_sns_ctrl.h"
#include "gc1084_slave_cmos_ex.h"
static void gc1084_slave_linear_720p30_init(VI_PIPE ViPipe);
const CVI_U8 gc1084_slave_i2c_addr = 0x37;//0x42
const CVI_U32 gc1084_slave_addr_byte = 2;
const CVI_U32 gc1084_slave_data_byte = 1;
static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1};
int gc1084_slave_i2c_init(VI_PIPE ViPipe)
{
char acDevFile[16] = {0};
CVI_U8 u8DevNum;
if (g_fd[ViPipe] >= 0)
return CVI_SUCCESS;
int ret;
u8DevNum = g_aunGc1084_Slave_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, gc1084_slave_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 gc1084_slave_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 gc1084_slave_read_register(VI_PIPE ViPipe, int addr)
{
/* TODO:*/
UNUSED(ViPipe);
UNUSED(addr);
return CVI_SUCCESS;
}
int gc1084_slave_write_register(VI_PIPE ViPipe, int addr, int data)
{
CVI_U8 idx = 0;
int ret;
CVI_U8 buf[8];
if (gc1084_slave_addr_byte == 2) {
buf[idx] = (addr >> 8) & 0xff;
idx++;
buf[idx] = addr & 0xff;
idx++;
}
if (gc1084_slave_data_byte == 1) {
buf[idx] = data & 0xff;
idx++;
}
ret = write(g_fd[ViPipe], buf, gc1084_slave_addr_byte + gc1084_slave_data_byte);
if (ret < 0) {
CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n");
return CVI_FAILURE;
}
//ret = read(g_fd[ViPipe], buf, gc1084_slave_addr_byte + gc1084_slave_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 gc1084_slave_standby(VI_PIPE ViPipe)
{
UNUSED(ViPipe);
printf("gc1084_slave_standby\n");
}
void gc1084_slave_restart(VI_PIPE ViPipe)
{
UNUSED(ViPipe);
printf("gc1084_slave_restart\n");
}
void gc1084_slave_default_reg_init(VI_PIPE ViPipe)
{
CVI_U32 i;
for (i = 0; i < g_pastGc1084_Slave[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) {
gc1084_slave_write_register(ViPipe,
g_pastGc1084_Slave[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr,
g_pastGc1084_Slave[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data);
}
}
void gc1084_slave_init(VI_PIPE ViPipe)
{
WDR_MODE_E enWDRMode = g_pastGc1084_Slave[ViPipe]->enWDRMode;
gc1084_slave_i2c_init(ViPipe);
if (enWDRMode == WDR_MODE_2To1_LINE) {
CVI_TRACE_SNS(CVI_DBG_ERR, "not surpport this WDR_MODE_E!\n");
} else {
gc1084_slave_linear_720p30_init(ViPipe);
}
g_pastGc1084_Slave[ViPipe]->bInit = CVI_TRUE;
}
void gc1084_slave_exit(VI_PIPE ViPipe)
{
gc1084_slave_i2c_exit(ViPipe);
}
static void gc1084_slave_linear_720p30_init(VI_PIPE ViPipe)
{
gc1084_slave_write_register(ViPipe, 0x03fe,0xf0);
gc1084_slave_write_register(ViPipe, 0x03fe,0xf0);
gc1084_slave_write_register(ViPipe, 0x03fe,0xf0);
gc1084_slave_write_register(ViPipe, 0x03fe,0x00);
gc1084_slave_write_register(ViPipe, 0x03f2,0x00);
gc1084_slave_write_register(ViPipe, 0x03f3,0x00);
gc1084_slave_write_register(ViPipe, 0x03f4,0x36);
gc1084_slave_write_register(ViPipe, 0x03f5,0xc0);
gc1084_slave_write_register(ViPipe, 0x03f6,0x13);
gc1084_slave_write_register(ViPipe, 0x03f7,0x01);
gc1084_slave_write_register(ViPipe, 0x03f8,0x2c);
gc1084_slave_write_register(ViPipe, 0x03f9,0x21);
gc1084_slave_write_register(ViPipe, 0x03fc,0xae);
gc1084_slave_write_register(ViPipe, 0x0d05,0x08);
gc1084_slave_write_register(ViPipe, 0x0d06,0x98);
gc1084_slave_write_register(ViPipe, 0x0d08,0x10);
gc1084_slave_write_register(ViPipe, 0x0d0a,0x02);
gc1084_slave_write_register(ViPipe, 0x000c,0x03);
gc1084_slave_write_register(ViPipe, 0x0d0d,0x02);
gc1084_slave_write_register(ViPipe, 0x0d0e,0xd4);
gc1084_slave_write_register(ViPipe, 0x000f,0x05);
gc1084_slave_write_register(ViPipe, 0x0010,0x08);
gc1084_slave_write_register(ViPipe, 0x0017,0x08);
gc1084_slave_write_register(ViPipe, 0x0d73,0x92);
gc1084_slave_write_register(ViPipe, 0x0076,0x00);
gc1084_slave_write_register(ViPipe, 0x0d76,0x00);
gc1084_slave_write_register(ViPipe, 0x0d41,0x02);
gc1084_slave_write_register(ViPipe, 0x0d42,0xee);
gc1084_slave_write_register(ViPipe, 0x0d7a,0x0a);
gc1084_slave_write_register(ViPipe, 0x006b,0x18);
gc1084_slave_write_register(ViPipe, 0x0db0,0x9d);
gc1084_slave_write_register(ViPipe, 0x0db1,0x00);
gc1084_slave_write_register(ViPipe, 0x0db2,0xac);
gc1084_slave_write_register(ViPipe, 0x0db3,0xd5);
gc1084_slave_write_register(ViPipe, 0x0db4,0x00);
gc1084_slave_write_register(ViPipe, 0x0db5,0x97);
gc1084_slave_write_register(ViPipe, 0x0db6,0x09);
gc1084_slave_write_register(ViPipe, 0x00d2,0xfc);
gc1084_slave_write_register(ViPipe, 0x0d19,0x31);
gc1084_slave_write_register(ViPipe, 0x0d20,0x40);
gc1084_slave_write_register(ViPipe, 0x0d25,0xcb);
gc1084_slave_write_register(ViPipe, 0x0d27,0x03);
gc1084_slave_write_register(ViPipe, 0x0d29,0x40);
gc1084_slave_write_register(ViPipe, 0x0d43,0x20);
gc1084_slave_write_register(ViPipe, 0x0058,0x60);
gc1084_slave_write_register(ViPipe, 0x00d6,0x66);
gc1084_slave_write_register(ViPipe, 0x00d7,0x19);
gc1084_slave_write_register(ViPipe, 0x0093,0x02);
gc1084_slave_write_register(ViPipe, 0x00d9,0x14);
gc1084_slave_write_register(ViPipe, 0x00da,0xc1);
gc1084_slave_write_register(ViPipe, 0x0d2a,0x00);
gc1084_slave_write_register(ViPipe, 0x0d28,0x04);
gc1084_slave_write_register(ViPipe, 0x0dc2,0x84);
gc1084_slave_write_register(ViPipe, 0x0050,0x30);
gc1084_slave_write_register(ViPipe, 0x0080,0x07);
gc1084_slave_write_register(ViPipe, 0x008c,0x05);
gc1084_slave_write_register(ViPipe, 0x008d,0xa8);
gc1084_slave_write_register(ViPipe, 0x0077,0x01);
gc1084_slave_write_register(ViPipe, 0x0078,0xee);
gc1084_slave_write_register(ViPipe, 0x0079,0x02);
gc1084_slave_write_register(ViPipe, 0x0067,0xc0);
gc1084_slave_write_register(ViPipe, 0x0054,0xff);
gc1084_slave_write_register(ViPipe, 0x0055,0x02);
gc1084_slave_write_register(ViPipe, 0x0056,0x00);
gc1084_slave_write_register(ViPipe, 0x0057,0x04);
gc1084_slave_write_register(ViPipe, 0x005a,0xff);
gc1084_slave_write_register(ViPipe, 0x005b,0x07);
gc1084_slave_write_register(ViPipe, 0x00d5,0x03);
gc1084_slave_write_register(ViPipe, 0x0102,0xa9);
gc1084_slave_write_register(ViPipe, 0x0d03,0x02);
gc1084_slave_write_register(ViPipe, 0x0d04,0xd0);
gc1084_slave_write_register(ViPipe, 0x007a,0x60);
gc1084_slave_write_register(ViPipe, 0x04e0,0xff);
gc1084_slave_write_register(ViPipe, 0x0414,0x75);
gc1084_slave_write_register(ViPipe, 0x0415,0x75);
gc1084_slave_write_register(ViPipe, 0x0416,0x75);
gc1084_slave_write_register(ViPipe, 0x0417,0x75);
gc1084_slave_write_register(ViPipe, 0x0122,0x00);
gc1084_slave_write_register(ViPipe, 0x0121,0x80);
gc1084_slave_write_register(ViPipe, 0x0428,0x10);
gc1084_slave_write_register(ViPipe, 0x0429,0x10);
gc1084_slave_write_register(ViPipe, 0x042a,0x10);
gc1084_slave_write_register(ViPipe, 0x042b,0x10);
gc1084_slave_write_register(ViPipe, 0x042c,0x14);
gc1084_slave_write_register(ViPipe, 0x042d,0x14);
gc1084_slave_write_register(ViPipe, 0x042e,0x18);
gc1084_slave_write_register(ViPipe, 0x042f,0x18);
gc1084_slave_write_register(ViPipe, 0x0430,0x05);
gc1084_slave_write_register(ViPipe, 0x0431,0x05);
gc1084_slave_write_register(ViPipe, 0x0432,0x05);
gc1084_slave_write_register(ViPipe, 0x0433,0x05);
gc1084_slave_write_register(ViPipe, 0x0434,0x05);
gc1084_slave_write_register(ViPipe, 0x0435,0x05);
gc1084_slave_write_register(ViPipe, 0x0436,0x05);
gc1084_slave_write_register(ViPipe, 0x0437,0x05);
gc1084_slave_write_register(ViPipe, 0x0153,0x00);
gc1084_slave_write_register(ViPipe, 0x0190,0x01);
gc1084_slave_write_register(ViPipe, 0x0192,0x02);
gc1084_slave_write_register(ViPipe, 0x0194,0x04);
gc1084_slave_write_register(ViPipe, 0x0195,0x02);
gc1084_slave_write_register(ViPipe, 0x0196,0xd0);
gc1084_slave_write_register(ViPipe, 0x0197,0x05);
gc1084_slave_write_register(ViPipe, 0x0198,0x00);
gc1084_slave_write_register(ViPipe, 0x0201,0x23);
gc1084_slave_write_register(ViPipe, 0x0202,0x53);
gc1084_slave_write_register(ViPipe, 0x0203,0xce);
gc1084_slave_write_register(ViPipe, 0x0208,0x39);
gc1084_slave_write_register(ViPipe, 0x0212,0x06);
gc1084_slave_write_register(ViPipe, 0x0213,0x40);
gc1084_slave_write_register(ViPipe, 0x0215,0x12);
gc1084_slave_write_register(ViPipe, 0x0229,0x05);
gc1084_slave_write_register(ViPipe, 0x023e,0x98);
gc1084_slave_write_register(ViPipe, 0x031e,0x3e);
gc1084_slave_default_reg_init(ViPipe);
delay_ms(40);
printf("ViPipe:%d,===GC1084 720P 30fps 10bit LINE Init OK!===\n", ViPipe);
}

View File

@ -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_mis2008_1l.a
TARGET_SO = $(MW_LIB)/libsns_mis2008_1l.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)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,79 @@
#ifndef __MIS2008_1L_CMOS_EX_H_
#define __MIS2008_1L_CMOS_EX_H_
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
#ifdef ARCH_CV182X
#include <linux/cvi_vip_cif.h>
#include <linux/cvi_vip_snsr.h>
#include "cvi_type.h"
#else
#include <linux/cif_uapi.h>
#include <linux/vi_snsr.h>
#include <linux/cvi_type.h>
#endif
#include "cvi_sns_ctrl.h"
enum mis2008_1l_linear_regs_e {
LINEAR_SHS1_0_ADDR,
LINEAR_SHS1_1_ADDR,
LINEAR_SHS1_2_ADDR,
LINEAR_AGAIN_ADDR,
LINEAR_DGAIN_ADDR,
LINEAR_D_FINEGAIN_ADDR,
LINEAR_VMAX_0_ADDR,
LINEAR_VMAX_1_ADDR,
LINEAR_FLIP_MIRROR_ADDR,
LINEAR_REGS_NUM
};
typedef enum _MIS2008_1L_MODE_E {
MIS2008_1L_MODE_1080P30 = 0,
MIS2008_1L_MODE_NUM
} MIS2008_1L_MODE_E;
typedef struct _MIS2008_1L_MODE_S {
ISP_WDR_SIZE_S astImg[2];
CVI_FLOAT f32MaxFps;
CVI_FLOAT f32MinFps;
CVI_U32 u32HtsDef;
CVI_U32 u32VtsDef;
SNS_ATTR_LARGE_S stExp[2];
SNS_ATTR_LARGE_S stAgain[2];
SNS_ATTR_LARGE_S stDgain[2];
char name[64];
} MIS2008_1L_MODE_S;
/****************************************************************************
* external variables and functions *
****************************************************************************/
extern ISP_SNS_STATE_S *g_pastMIS2008_1L[VI_MAX_PIPE_NUM];
extern ISP_SNS_COMMBUS_U g_aunMIS2008_1L_BusInfo[];
extern CVI_U16 g_au16MIS2008_1L_GainMode[];
extern CVI_U16 g_au16MIS2008_1L_L2SMode[];
extern CVI_U8 mis2008_1l_i2c_addr;
extern const CVI_U32 mis2008_1l_addr_byte;
extern const CVI_U32 mis2008_1l_data_byte;
extern void mis2008_1l_init(VI_PIPE ViPipe);
extern void mis2008_1l_exit(VI_PIPE ViPipe);
extern void mis2008_1l_standby(VI_PIPE ViPipe);
extern void mis2008_1l_restart(VI_PIPE ViPipe);
extern int mis2008_1l_write_register(VI_PIPE ViPipe, int addr, int data);
extern int mis2008_1l_read_register(VI_PIPE ViPipe, int addr);
extern void mis2008_1l_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip);
extern int mis2008_1l_probe(VI_PIPE ViPipe);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* End of #ifdef __cplusplus */
#endif /* __MIS2008_1L_CMOS_EX_H_ */

View File

@ -0,0 +1,126 @@
#ifndef __MIS2008_1L_CMOS_PARAM_H_
#define __MIS2008_1L_CMOS_PARAM_H_
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
#ifdef ARCH_CV182X
#include <linux/cvi_vip_cif.h>
#include <linux/cvi_vip_snsr.h>
#include "cvi_type.h"
#else
#include <linux/cif_uapi.h>
#include <linux/vi_snsr.h>
#include <linux/cvi_type.h>
#endif
#include "cvi_sns_ctrl.h"
#include "mis2008_1l_cmos_ex.h"
static const MIS2008_1L_MODE_S g_astMIS2008_1L_mode[MIS2008_1L_MODE_NUM] = {
[MIS2008_1L_MODE_1080P30] = {
.name = "1080p30",
.astImg[0] = {
.stSnsSize = {
.u32Width = 1928,
.u32Height = 1088,
},
.stWndRect = {
.s32X = 8,
.s32Y = 8,
.u32Width = 1920,
.u32Height = 1080,
},
.stMaxSize = {
.u32Width = 1928,
.u32Height = 1088,
},
},
.f32MaxFps = 30,
.f32MinFps = 1, /* 1500 * 30 / 0x7FFF*/
.u32HtsDef = 2200,
.u32VtsDef = 1125,
.stExp[0] = {//exp_time
.u32Min = 1,
.u32Max = 1125 - 1, //exp_max
.u32Def = 128,
.u32Step = 1,
},
.stAgain[0] = {
.u32Min = 1024,
.u32Max = 16128,
.u32Def = 1024,
.u32Step = 1,
},
.stDgain[0] = {
.u32Min = 1024,
.u32Max = 16320,
.u32Def = 1024,
.u32Step = 1,
},
},
};
static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = {
.bUpdate = CVI_TRUE,
.blcAttr = {
.Enable = 1,
.enOpType = OP_TYPE_AUTO,
.stManual = {64, 64, 64, 64, 0, 0, 0, 0
#ifdef ARCH_CV182X
, 1040, 1040, 1040, 1040
#endif
},
.stAuto = {
{64, 64, 64, 64, 64, 64, 64, 64, /*8*/64, 64, 64, 64, 64, 64, 64, 64},
{64, 64, 64, 64, 64, 64, 64, 64, /*8*/64, 64, 64, 64, 64, 64, 64, 64},
{64, 64, 64, 64, 64, 64, 64, 64, /*8*/64, 64, 64, 64, 64, 64, 64, 64},
{64, 64, 64, 64, 64, 64, 64, 64, /*8*/64, 64, 64, 64, 64, 64, 64, 64},
{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
{1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040,
/*8*/1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040},
{1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040,
/*8*/1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040},
{1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040,
/*8*/1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040},
{1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040,
/*8*/1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040},
#endif
},
},
};
struct combo_dev_attr_s mis2008_1l_rx_attr = {
.input_mode = INPUT_MODE_MIPI,
.mac_clk = RX_MAC_CLK_400M,
.mipi_attr = {
.raw_data_type = RAW_DATA_12BIT,
.lane_id = {2, 0, -1, -1, -1},
.pn_swap = {1, 1, 0, 0, 0},
.wdr_mode = CVI_MIPI_WDR_MODE_NONE,
.dphy = {
.enable = 1,
.hs_settle = 8,
},
},
.mclk = {
.cam = 1,
.freq = CAMPLL_FREQ_27M,
},
.devno = 0,
};
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* End of #ifdef __cplusplus */
#endif /* __MIS2008_1L_CMOS_PARAM_H_ */

View File

@ -0,0 +1,393 @@
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <syslog.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#ifdef ARCH_CV182X
#include <linux/cvi_vip_snsr.h>
#include "cvi_comm_video.h"
#else
#include <linux/vi_snsr.h>
#include <linux/cvi_comm_video.h>
#endif
#include "cvi_sns_ctrl.h"
#include "mis2008_1l_cmos_ex.h"
static void mis2008_1l_linear_1080p30_init(VI_PIPE ViPipe);
CVI_U8 mis2008_1l_i2c_addr = 0x30; /* I2C Address of MIS2008_1L */
const CVI_U32 mis2008_1l_addr_byte = 2;
const CVI_U32 mis2008_1l_data_byte = 1;
static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1};
int mis2008_1l_i2c_init(VI_PIPE ViPipe)
{
char acDevFile[16] = {0};
CVI_U8 u8DevNum;
if (g_fd[ViPipe] >= 0)
return CVI_SUCCESS;
int ret;
u8DevNum = g_aunMIS2008_1L_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/cvi_i2c_drv-%u error!\n", u8DevNum);
return CVI_FAILURE;
}
ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, mis2008_1l_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 mis2008_1l_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 mis2008_1l_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 (mis2008_1l_addr_byte == 2)
buf[idx++] = (addr >> 8) & 0xff;
// add address byte 0
buf[idx++] = addr & 0xff;
ret = write(g_fd[ViPipe], buf, mis2008_1l_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, mis2008_1l_data_byte);
if (ret < 0) {
CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n");
return ret;
}
// pack read back data
data = 0;
if (mis2008_1l_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 mis2008_1l_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 (mis2008_1l_addr_byte == 2) {
buf[idx] = (addr >> 8) & 0xff;
idx++;
buf[idx] = addr & 0xff;
idx++;
}
if (mis2008_1l_data_byte == 1) {
buf[idx] = data & 0xff;
idx++;
}
ret = write(g_fd[ViPipe], buf, mis2008_1l_addr_byte + mis2008_1l_data_byte);
if (ret < 0) {
CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n");
return CVI_FAILURE;
}
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 mis2008_1l_standby(VI_PIPE ViPipe)
{
mis2008_1l_write_register(ViPipe, 0x3006, 0x02);
}
void mis2008_1l_restart(VI_PIPE ViPipe)
{
mis2008_1l_write_register(ViPipe, 0x3006, 0x01);
}
void mis2008_1l_default_reg_init(VI_PIPE ViPipe)
{
CVI_U32 i;
for (i = 0; i < g_pastMIS2008_1L[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) {
mis2008_1l_write_register(ViPipe,
g_pastMIS2008_1L[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr,
g_pastMIS2008_1L[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data);
}
}
#define MIS2008_1L_CHIP_ID_HI_ADDR 0x3000
#define MIS2008_1L_CHIP_ID_LO_ADDR 0x3001
#define MIS2008_1L_CHIP_ID 0x2008
int mis2008_1l_probe(VI_PIPE ViPipe)
{
int nVal;
CVI_U16 chip_id;
if (mis2008_1l_i2c_init(ViPipe) != CVI_SUCCESS)
return CVI_FAILURE;
delay_ms(5);
nVal = mis2008_1l_read_register(ViPipe, MIS2008_1L_CHIP_ID_HI_ADDR);
if (nVal < 0) {
CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n");
return nVal;
}
chip_id = (nVal & 0xFF) << 8;
nVal = mis2008_1l_read_register(ViPipe, MIS2008_1L_CHIP_ID_LO_ADDR);
if (nVal < 0) {
CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n");
return nVal;
}
chip_id |= (nVal & 0xFF);
if (chip_id != MIS2008_1L_CHIP_ID) {
CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n");
return CVI_FAILURE;
}
return CVI_SUCCESS;
}
void mis2008_1l_init(VI_PIPE ViPipe)
{
mis2008_1l_i2c_init(ViPipe);
mis2008_1l_linear_1080p30_init(ViPipe);
g_pastMIS2008_1L[ViPipe]->bInit = CVI_TRUE;
}
void mis2008_1l_exit(VI_PIPE ViPipe)
{
mis2008_1l_i2c_exit(ViPipe);
}
/* 1080p30 */
static void mis2008_1l_linear_1080p30_init(VI_PIPE ViPipe)
{
/* [ParaList] */
mis2008_1l_write_register(ViPipe, 0x300a, 0x01);
mis2008_1l_write_register(ViPipe, 0x300a, 0x01);
mis2008_1l_write_register(ViPipe, 0x3006, 0x02);
mis2008_1l_write_register(ViPipe, 0x3201, 0x65);
mis2008_1l_write_register(ViPipe, 0x3200, 0x04);
mis2008_1l_write_register(ViPipe, 0x3203, 0x98);
mis2008_1l_write_register(ViPipe, 0x3202, 0x08);
mis2008_1l_write_register(ViPipe, 0x3205, 0x04);
mis2008_1l_write_register(ViPipe, 0x3204, 0x00);
mis2008_1l_write_register(ViPipe, 0x3207, 0x43);
mis2008_1l_write_register(ViPipe, 0x3206, 0x04);
mis2008_1l_write_register(ViPipe, 0x3209, 0x04);
mis2008_1l_write_register(ViPipe, 0x3208, 0x00);
mis2008_1l_write_register(ViPipe, 0x320b, 0x8b);
mis2008_1l_write_register(ViPipe, 0x320a, 0x07);
mis2008_1l_write_register(ViPipe, 0x3007, 0x00);
mis2008_1l_write_register(ViPipe, 0x3300, 0x21);
mis2008_1l_write_register(ViPipe, 0x3301, 0x00);
mis2008_1l_write_register(ViPipe, 0x3302, 0x00);
mis2008_1l_write_register(ViPipe, 0x3303, 0x06);
mis2008_1l_write_register(ViPipe, 0x330d, 0x00);
mis2008_1l_write_register(ViPipe, 0x330b, 0x00);
mis2008_1l_write_register(ViPipe, 0x330f, 0x0f);
mis2008_1l_write_register(ViPipe, 0x3013, 0x00);
mis2008_1l_write_register(ViPipe, 0x3637, 0x1e);
mis2008_1l_write_register(ViPipe, 0x3900, 0x07);
mis2008_1l_write_register(ViPipe, 0x2107, 0x00);
mis2008_1l_write_register(ViPipe, 0x330e, 0x00);
mis2008_1l_write_register(ViPipe, 0x3900, 0x07);
mis2008_1l_write_register(ViPipe, 0x2108, 0x01);
mis2008_1l_write_register(ViPipe, 0x3c40, 0x8c);
mis2008_1l_write_register(ViPipe, 0x3c42, 0x01);
mis2008_1l_write_register(ViPipe, 0x3b01, 0x3f);
mis2008_1l_write_register(ViPipe, 0x3b03, 0x3f);
mis2008_1l_write_register(ViPipe, 0x3902, 0x01);
mis2008_1l_write_register(ViPipe, 0x3904, 0x00);
mis2008_1l_write_register(ViPipe, 0x3903, 0x00);
mis2008_1l_write_register(ViPipe, 0x3906, 0x1e);
mis2008_1l_write_register(ViPipe, 0x3905, 0x00);
mis2008_1l_write_register(ViPipe, 0x3908, 0x71);
mis2008_1l_write_register(ViPipe, 0x3907, 0x10);
mis2008_1l_write_register(ViPipe, 0x390a, 0xff);
mis2008_1l_write_register(ViPipe, 0x3909, 0x1f);
mis2008_1l_write_register(ViPipe, 0x390c, 0x67);
mis2008_1l_write_register(ViPipe, 0x390b, 0x03);
mis2008_1l_write_register(ViPipe, 0x390e, 0x77);
mis2008_1l_write_register(ViPipe, 0x390d, 0x00);
mis2008_1l_write_register(ViPipe, 0x3910, 0x71);
mis2008_1l_write_register(ViPipe, 0x390f, 0x10);
mis2008_1l_write_register(ViPipe, 0x3912, 0xff);
mis2008_1l_write_register(ViPipe, 0x3911, 0x1f);
mis2008_1l_write_register(ViPipe, 0x3919, 0x00);
mis2008_1l_write_register(ViPipe, 0x3918, 0x00);
mis2008_1l_write_register(ViPipe, 0x391b, 0x91);
mis2008_1l_write_register(ViPipe, 0x391a, 0x01);
mis2008_1l_write_register(ViPipe, 0x3983, 0x5a);
mis2008_1l_write_register(ViPipe, 0x3982, 0x00);
mis2008_1l_write_register(ViPipe, 0x3985, 0x0f);
mis2008_1l_write_register(ViPipe, 0x3984, 0x00);
mis2008_1l_write_register(ViPipe, 0x391d, 0x00);
mis2008_1l_write_register(ViPipe, 0x391c, 0x00);
mis2008_1l_write_register(ViPipe, 0x391f, 0x65);
mis2008_1l_write_register(ViPipe, 0x391e, 0x10);
mis2008_1l_write_register(ViPipe, 0x3921, 0xff);
mis2008_1l_write_register(ViPipe, 0x3920, 0x1f);
mis2008_1l_write_register(ViPipe, 0x3923, 0xff);
mis2008_1l_write_register(ViPipe, 0x3922, 0x1f);
mis2008_1l_write_register(ViPipe, 0x3932, 0x00);
mis2008_1l_write_register(ViPipe, 0x3931, 0x00);
mis2008_1l_write_register(ViPipe, 0x3934, 0x65);
mis2008_1l_write_register(ViPipe, 0x3933, 0x01);
mis2008_1l_write_register(ViPipe, 0x393f, 0x6c);
mis2008_1l_write_register(ViPipe, 0x393e, 0x00);
mis2008_1l_write_register(ViPipe, 0x3941, 0x67);
mis2008_1l_write_register(ViPipe, 0x3940, 0x00);
mis2008_1l_write_register(ViPipe, 0x3943, 0x55);
mis2008_1l_write_register(ViPipe, 0x3942, 0x01);
mis2008_1l_write_register(ViPipe, 0x3945, 0xc2);
mis2008_1l_write_register(ViPipe, 0x3944, 0x02);
mis2008_1l_write_register(ViPipe, 0x3925, 0x95);
mis2008_1l_write_register(ViPipe, 0x3924, 0x00);
mis2008_1l_write_register(ViPipe, 0x3927, 0xe1);
mis2008_1l_write_register(ViPipe, 0x3926, 0x02);
mis2008_1l_write_register(ViPipe, 0x3947, 0x74);
mis2008_1l_write_register(ViPipe, 0x3946, 0x01);
mis2008_1l_write_register(ViPipe, 0x3949, 0xda);
mis2008_1l_write_register(ViPipe, 0x3948, 0x0e);
mis2008_1l_write_register(ViPipe, 0x394b, 0x42);
mis2008_1l_write_register(ViPipe, 0x394a, 0x03);
mis2008_1l_write_register(ViPipe, 0x394d, 0xf2);
mis2008_1l_write_register(ViPipe, 0x394c, 0x01);
mis2008_1l_write_register(ViPipe, 0x3913, 0x01);
mis2008_1l_write_register(ViPipe, 0x3915, 0x0f);
mis2008_1l_write_register(ViPipe, 0x3914, 0x00);
mis2008_1l_write_register(ViPipe, 0x3917, 0x67);
mis2008_1l_write_register(ViPipe, 0x3916, 0x03);
mis2008_1l_write_register(ViPipe, 0x392a, 0x1e);
mis2008_1l_write_register(ViPipe, 0x3929, 0x00);
mis2008_1l_write_register(ViPipe, 0x392c, 0x0f);
mis2008_1l_write_register(ViPipe, 0x392b, 0x00);
mis2008_1l_write_register(ViPipe, 0x392e, 0x0f);
mis2008_1l_write_register(ViPipe, 0x392d, 0x00);
mis2008_1l_write_register(ViPipe, 0x3930, 0x6e);
mis2008_1l_write_register(ViPipe, 0x392f, 0x03);
mis2008_1l_write_register(ViPipe, 0x397f, 0x00);
mis2008_1l_write_register(ViPipe, 0x397e, 0x00);
mis2008_1l_write_register(ViPipe, 0x3981, 0x77);
mis2008_1l_write_register(ViPipe, 0x3980, 0x00);
mis2008_1l_write_register(ViPipe, 0x395d, 0x80);
mis2008_1l_write_register(ViPipe, 0x395c, 0x10);
mis2008_1l_write_register(ViPipe, 0x3962, 0x9e);
mis2008_1l_write_register(ViPipe, 0x3961, 0x10);
mis2008_1l_write_register(ViPipe, 0x3967, 0x50);
mis2008_1l_write_register(ViPipe, 0x3977, 0x22);
mis2008_1l_write_register(ViPipe, 0x3976, 0x00);
mis2008_1l_write_register(ViPipe, 0x3978, 0x00);
mis2008_1l_write_register(ViPipe, 0x3979, 0x04);
mis2008_1l_write_register(ViPipe, 0x396d, 0xc2);
mis2008_1l_write_register(ViPipe, 0x396c, 0x02);
mis2008_1l_write_register(ViPipe, 0x396f, 0xc2);
mis2008_1l_write_register(ViPipe, 0x396e, 0x02);
mis2008_1l_write_register(ViPipe, 0x3971, 0xc2);
mis2008_1l_write_register(ViPipe, 0x3970, 0x02);
mis2008_1l_write_register(ViPipe, 0x3973, 0xc2);
mis2008_1l_write_register(ViPipe, 0x3972, 0x02);
mis2008_1l_write_register(ViPipe, 0x3900, 0x01);
mis2008_1l_write_register(ViPipe, 0x3600, 0x00);
mis2008_1l_write_register(ViPipe, 0x3707, 0x00);
mis2008_1l_write_register(ViPipe, 0x3708, 0x80);
mis2008_1l_write_register(ViPipe, 0x3709, 0x00);
mis2008_1l_write_register(ViPipe, 0x370a, 0x80);
mis2008_1l_write_register(ViPipe, 0x370b, 0x00);
mis2008_1l_write_register(ViPipe, 0x370c, 0x80);
mis2008_1l_write_register(ViPipe, 0x370d, 0x00);
mis2008_1l_write_register(ViPipe, 0x370e, 0x80);
mis2008_1l_write_register(ViPipe, 0x3012, 0x01);
mis2008_1l_write_register(ViPipe, 0x3600, 0x13);
mis2008_1l_write_register(ViPipe, 0x3601, 0x02);
mis2008_1l_write_register(ViPipe, 0x360e, 0x00);
mis2008_1l_write_register(ViPipe, 0x360f, 0x00);
mis2008_1l_write_register(ViPipe, 0x3610, 0x02);
mis2008_1l_write_register(ViPipe, 0x3707, 0x00);
mis2008_1l_write_register(ViPipe, 0x3708, 0x40);
mis2008_1l_write_register(ViPipe, 0x3709, 0x00);
mis2008_1l_write_register(ViPipe, 0x370a, 0x40);
mis2008_1l_write_register(ViPipe, 0x370b, 0x00);
mis2008_1l_write_register(ViPipe, 0x370c, 0x40);
mis2008_1l_write_register(ViPipe, 0x370d, 0x00);
mis2008_1l_write_register(ViPipe, 0x370e, 0x40);
mis2008_1l_write_register(ViPipe, 0x3800, 0x01);
mis2008_1l_write_register(ViPipe, 0x3a03, 0x03);
mis2008_1l_write_register(ViPipe, 0x3a02, 0x0b);
mis2008_1l_write_register(ViPipe, 0x3a08, 0x34);
mis2008_1l_write_register(ViPipe, 0x3a1b, 0x54);
mis2008_1l_write_register(ViPipe, 0x3a1e, 0x80);
mis2008_1l_write_register(ViPipe, 0x3100, 0x04);
mis2008_1l_write_register(ViPipe, 0x3101, 0x64);
mis2008_1l_write_register(ViPipe, 0x3a1c, 0x10);
mis2008_1l_write_register(ViPipe, 0x3a0C, 0x04);
mis2008_1l_write_register(ViPipe, 0x3a0D, 0x12);
mis2008_1l_write_register(ViPipe, 0x3a0E, 0x15);
mis2008_1l_write_register(ViPipe, 0x3a0F, 0x18);
mis2008_1l_write_register(ViPipe, 0x3a10, 0x20);
mis2008_1l_write_register(ViPipe, 0x3a11, 0x3c);
mis2008_1l_write_register(ViPipe, 0x3a19, 0x10);
mis2008_1l_write_register(ViPipe, 0x3006, 0x00);
mis2008_1l_default_reg_init(ViPipe);
delay_ms(100);
printf("ViPipe:%d,===MIS2008_1L 1080P 30fps 12bit LINE Init OK!===\n", ViPipe);
}

View File

@ -39,12 +39,12 @@ static const SC2331_1L_MODE_S g_astSC2331_1L_mode[SC2331_1L_MODE_NUM] = {
},
},
.f32MaxFps = 30,
.f32MinFps = 0.51, /* 1125 * 30 / 0x7FFF */
.u32HtsDef = 2560,
.u32VtsDef = 1530,
.f32MinFps = 0.51, /* 1125 * 30 / 0xFFFF */
.u32HtsDef = 2200,
.u32VtsDef = 1125,
.stExp[0] = {
.u16Min = 2,//3
.u16Max = 1530*2 - 13,
.u16Max = 1125 - 13,
.u16Def = 400,
.u16Step = 1,
},

View File

@ -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_sc2336_1l.a
TARGET_SO = $(MW_LIB)/libsns_sc2336_1l.so
EXTRA_CFLAGS = $(INCS)
EXTRA_LDFLAGS =
.PHONY : clean all
all : $(TARGET_A) $(TARGET_SO)
$(SDIR)/%.o: $(SDIR)/%.c
@$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@
@echo [$(notdir $(CC))] $(notdir $@)
$(TARGET_A): $(OBJS)
@$(AR) $(ARFLAGS) $@ $(OBJ)
@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)

View File

@ -0,0 +1,905 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <syslog.h>
#include <errno.h>
#ifdef ARCH_CV182X
#include "cvi_type.h"
#include "cvi_comm_video.h"
#include <linux/cvi_vip_snsr.h>
#else
#include <linux/cvi_type.h>
#include <linux/cvi_comm_video.h>
#include <linux/vi_snsr.h>
#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 "sc2336_1L_cmos_ex.h"
#include "sc2336_1L_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 SC2336_1L_ID 35
#define SENSOR_SC2336_1L_WIDTH 1920
#define SENSOR_SC2336_1L_HEIGHT 1080
/****************************************************************************
* global variables *
****************************************************************************/
ISP_SNS_STATE_S *g_pastSC2336_1L[VI_MAX_PIPE_NUM] = {CVI_NULL};
#define SC2336_1L_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastSC2336_1L[dev])
#define SC2336_1L_SENSOR_SET_CTX(dev, pstCtx) (g_pastSC2336_1L[dev] = pstCtx)
#define SC2336_1L_SENSOR_RESET_CTX(dev) (g_pastSC2336_1L[dev] = CVI_NULL)
ISP_SNS_COMMBUS_U g_aunSC2336_1L_BusInfo[VI_MAX_PIPE_NUM] = {
[0] = { .s8I2cDev = 0},
[1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1}
};
CVI_U16 g_au16SC2336_1L_GainMode[VI_MAX_PIPE_NUM] = {0};
CVI_U16 g_au16SC2336_1L_L2SMode[VI_MAX_PIPE_NUM] = {0};
SC2336_1L_STATE_S g_astSC2336_1L_State[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);
/*****SC2336_1L Lines Range*****/
#define SC2336_1L_FULL_LINES_MAX (0xFFFF)
/*****SC2336_1L Register Address*****/
#define SC2336_1L_SHS1_0_ADDR 0x3E00
#define SC2336_1L_SHS1_1_ADDR 0x3E01
#define SC2336_1L_SHS1_2_ADDR 0x3E02
#define SC2336_1L_AGAIN0_ADDR 0x3E09
#define SC2336_1L_DGAIN0_ADDR 0x3E06
#define SC2336_1L_VMAX_ADDR 0x320E
#define SC2336_1L_TABLE_END 0xFFFF
#define SC2336_1L_RES_IS_1080P(w, h) ((w) <= 1920 && (h) <= 1080)
static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft)
{
const SC2336_1L_MODE_S *pstMode;
ISP_SNS_STATE_S *pstSnsState = CVI_NULL;
CMOS_CHECK_POINTER(pstAeSnsDft);
SC2336_1L_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER(pstSnsState);
pstMode = &g_astSC2336_1L_mode[pstSnsState->u8ImgMode];
#if 0
memset(&pstAeSnsDft->stAERouteAttr, 0, sizeof(ISP_AE_ROUTE_S));
#endif
pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd;
pstAeSnsDft->u32FlickerFreq = 50 * 256;
pstAeSnsDft->u32FullLinesMax = SC2336_1L_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_DB;
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];
pstAeSnsDft->u32SnsStableFrame = 0;
#if 0
pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0;
pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0;
pstAeSnsDft->bAERouteExValid = CVI_FALSE;
pstAeSnsDft->stAERouteAttr.u32TotalNum = 0;
pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0;
#endif
switch (pstSnsState->enWDRMode) {
default:
case WDR_MODE_NONE: /*linear mode*/
pstAeSnsDft->f32Fps = pstMode->f32MaxFps;
pstAeSnsDft->f32MinFps = pstMode->f32MinFps;
pstAeSnsDft->au8HistThresh[0] = 0xd;
pstAeSnsDft->au8HistThresh[1] = 0x28;
pstAeSnsDft->au8HistThresh[2] = 0x60;
pstAeSnsDft->au8HistThresh[3] = 0x80;
pstAeSnsDft->u32MaxAgain = pstMode->stAgain[0].u16Max;
pstAeSnsDft->u32MinAgain = pstMode->stAgain[0].u16Min;
pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain;
pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain;
pstAeSnsDft->u32MaxDgain = pstMode->stDgain[0].u16Max;
pstAeSnsDft->u32MinDgain = pstMode->stDgain[0].u16Min;
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] : 76151;
pstAeSnsDft->u32MaxIntTime = pstMode->stExp[0].u16Max;
pstAeSnsDft->u32MinIntTime = pstMode->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);
SC2336_1L_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER(pstSnsState);
u32Vts = g_astSC2336_1L_mode[pstSnsState->u8ImgMode].u32VtsDef;
pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg;
f32MaxFps = g_astSC2336_1L_mode[pstSnsState->u8ImgMode].f32MaxFps;
f32MinFps = g_astSC2336_1L_mode[pstSnsState->u8ImgMode].f32MinFps;
switch (pstSnsState->u8ImgMode) {
case SC2336_1L_MODE_1080P30:
if ((f32Fps <= f32MaxFps) && (f32Fps >= f32MinFps)) {
u32VMAX = u32Vts * f32MaxFps / DIV_0_TO_1_FLOAT(f32Fps);
} else {
CVI_TRACE_SNS(CVI_DBG_ERR, "Not support Fps: %f\n", f32Fps);
return CVI_FAILURE;
}
u32VMAX = (u32VMAX > SC2336_1L_FULL_LINES_MAX) ? SC2336_1L_FULL_LINES_MAX : u32VMAX;
break;
default:
CVI_TRACE_SNS(CVI_DBG_ERR, "Not support sensor mode: %d\n", pstSnsState->u8ImgMode);
return CVI_FAILURE;
}
pstSnsState->u32FLStd = u32VMAX;
if (pstSnsState->enWDRMode == WDR_MODE_NONE) {
pstSnsRegsInfo->astI2cData[LINEAR_VMAX_0_ADDR].u32Data = ((u32VMAX & 0xFF00) >> 8);
pstSnsRegsInfo->astI2cData[LINEAR_VMAX_1_ADDR].u32Data = (u32VMAX & 0xFF);
}
pstAeSnsDft->f32Fps = f32Fps;
pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2;
pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd;
pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 6;
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;
SC2336_1L_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER(pstSnsState);
CMOS_CHECK_POINTER(u32IntTime);
pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg;
if (WDR_MODE_2To1_LINE != pstSnsState->enWDRMode) {
CVI_U32 u32TmpIntTime = u32IntTime[0];
/* linear exposure reg range:
* min : 1
* max : (vts - 6)
* step : 1
*/
u32TmpIntTime = (u32TmpIntTime > (pstSnsState->au32FL[0] - 6)) ?
(pstSnsState->au32FL[0] - 6) : u32TmpIntTime;
if (!u32TmpIntTime)
u32TmpIntTime = 1;
pstSnsRegsInfo->astI2cData[LINEAR_SHS1_0_ADDR].u32Data = ((u32TmpIntTime & 0xF000) >> 12);
pstSnsRegsInfo->astI2cData[LINEAR_SHS1_1_ADDR].u32Data = ((u32TmpIntTime & 0x0FF0) >> 4);
pstSnsRegsInfo->astI2cData[LINEAR_SHS1_2_ADDR].u32Data = (u32TmpIntTime & 0xF) << 4;
}
return CVI_SUCCESS;
}
struct gain_tbl_info_s {
CVI_U16 gainMax;
CVI_U16 idxBase;
CVI_U8 regGain;
CVI_U8 regGainFineBase;
CVI_U8 regGainFineStep;
};
static CVI_U32 Again_table[] = {
1024, 2048, 4096, 8192, 16384, 32768
};
static CVI_U32 AgainReg[] = {
0x00, 0x08, 0x09, 0x0b, 0x0f, 0x1f
};
static struct gain_tbl_info_s DgainInfo[] = {
{
.gainMax = 2016,
.idxBase = 0,
.regGain = 0x00,
.regGainFineBase = 0x80,
.regGainFineStep = 4,
},
{
.gainMax = 4032,
.idxBase = 32,
.regGain = 0x01,
.regGainFineBase = 0x80,
.regGainFineStep = 4,
},
{
.gainMax = 4096,
.idxBase = 64,
.regGain = 0x03,
.regGainFineBase = 0x80,
.regGainFineStep = 0,
},
};
static CVI_U32 Dgain_table[] = {
1024, 1056, 1088, 1120, 1152, 1184, 1216, 1248, 1280, 1312, 1344, 1376, 1408, 1440, 1472, 1504,
1536, 1568, 1600, 1632, 1664, 1696, 1728, 1760, 1792, 1824, 1856, 1888, 1920, 1952, 1984, 2016,
2048, 2112, 2176, 2240, 2304, 2368, 2432, 2496, 2560, 2624, 2688, 2752, 2816, 2880, 2944, 3008,
3072, 3136, 3200, 3264, 3328, 3392, 3456, 3520, 3584, 3648, 3712, 3776, 3840, 3904, 3968, 4032,
4096,
};
static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb)
{
CVI_U32 tableSize = sizeof(Again_table) / sizeof(CVI_U32);
(void)ViPipe;
CMOS_CHECK_POINTER(pu32AgainLin);
CMOS_CHECK_POINTER(pu32AgainDb);
if (*pu32AgainLin >= Again_table[tableSize - 1]) {
*pu32AgainLin = Again_table[tableSize - 1];
*pu32AgainDb = AgainReg[tableSize - 1];
return CVI_SUCCESS;
}
for (CVI_U32 i = 1; i < tableSize; i++) {
if (*pu32AgainLin < Again_table[i]) {
*pu32AgainLin = Again_table[i - 1];
*pu32AgainDb = AgainReg[i - 1];
break;
}
}
return CVI_SUCCESS;
}
static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb)
{
CVI_U32 tableSize = sizeof(Dgain_table) / sizeof(CVI_U32);
(void)ViPipe;
CMOS_CHECK_POINTER(pu32DgainLin);
CMOS_CHECK_POINTER(pu32DgainDb);
if (*pu32DgainLin >= Dgain_table[tableSize - 1]) {
*pu32DgainLin = Dgain_table[tableSize - 1];
*pu32DgainDb = tableSize - 1;
return CVI_SUCCESS;
}
for (CVI_U32 i = 1; i < tableSize; i++) {
if (*pu32DgainLin < Dgain_table[i]) {
*pu32DgainLin = Dgain_table[i - 1];
*pu32DgainDb = i - 1;
break;
}
}
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;
struct gain_tbl_info_s *info;
CVI_S32 i = 0, tbl_num = 0;
SC2336_1L_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER(pstSnsState);
CMOS_CHECK_POINTER(pu32Again);
CMOS_CHECK_POINTER(pu32Dgain);
pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg;
u32Again = pu32Again[0];
u32Dgain = pu32Dgain[0];
if (pstSnsState->enWDRMode == WDR_MODE_NONE) {
/* linear mode */
/* Again. */
pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_0_ADDR].u32Data = (u32Again & 0xFF);
/* find Dgain register setting. */
tbl_num = sizeof(DgainInfo)/sizeof(struct gain_tbl_info_s);
for (i = tbl_num - 1; i >= 0; i--) {
info = &DgainInfo[i];
if (u32Dgain >= info->idxBase)
break;
}
pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_0_ADDR].u32Data = (info->regGain & 0xFF);
u32Dgain = info->regGainFineBase + (u32Dgain - info->idxBase) * info->regGainFineStep;
pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_1_ADDR].u32Data = (u32Dgain & 0xFF);
}
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_slow_framerate_set = cmos_slow_framerate_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)
{
(void) ViPipe;
CMOS_CHECK_POINTER(pstAwbSnsDft);
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)
{
(void) ViPipe;
memset(pstDef, 0, sizeof(ISP_CMOS_DEFAULT_S));
return CVI_SUCCESS;
}
static CVI_S32 cmos_get_blc_default(VI_PIPE ViPipe, ISP_CMOS_BLACK_LEVEL_S *pstBlc)
{
(void) ViPipe;
CMOS_CHECK_POINTER(pstBlc);
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 SC2336_1L_MODE_S *pstMode = CVI_NULL;
ISP_SNS_STATE_S *pstSnsState = CVI_NULL;
SC2336_1L_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER(pstSnsState);
pstMode = &g_astSC2336_1L_mode[pstSnsState->u8ImgMode];
if (pstSnsState->enWDRMode != WDR_MODE_NONE) {
pstIspCfg->frm_num = 2;
memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S));
memcpy(&pstIspCfg->img_size[1], &pstMode->astImg[1], sizeof(ISP_WDR_SIZE_S));
} else {
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;
SC2336_1L_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER(pstSnsState);
pstSnsState->bSyncInit = CVI_FALSE;
switch (u8Mode) {
case WDR_MODE_NONE:
pstSnsState->u8ImgMode = SC2336_1L_MODE_1080P30;
pstSnsState->enWDRMode = WDR_MODE_NONE;
pstSnsState->u32FLStd = g_astSC2336_1L_mode[pstSnsState->u8ImgMode].u32VtsDef;
syslog(LOG_INFO, "linear mode\n");
break;
default:
CVI_TRACE_SNS(CVI_DBG_ERR, "NOT support this 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_U32 sensor_cmp_cif_wdr(ISP_SNS_CIF_INFO_S *pstWdr1, ISP_SNS_CIF_INFO_S *pstWdr2)
{
if (pstWdr1->wdr_manual.l2s_distance != pstWdr2->wdr_manual.l2s_distance)
goto _mismatch;
if (pstWdr1->wdr_manual.lsef_length != pstWdr2->wdr_manual.lsef_length)
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);
SC2336_1L_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_aunSC2336_1L_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 = sc2336_1L_i2c_addr;
pstI2c_data[i].u32AddrByteNum = sc2336_1L_addr_byte;
pstI2c_data[i].u32DataByteNum = sc2336_1L_data_byte;
}
//DOL 2t1 Mode Regs
switch (pstSnsState->enWDRMode) {
case WDR_MODE_2To1_LINE:
break;
default:
//Linear Mode Regs
pstI2c_data[LINEAR_SHS1_0_ADDR].u32RegAddr = SC2336_1L_SHS1_0_ADDR;
pstI2c_data[LINEAR_SHS1_1_ADDR].u32RegAddr = SC2336_1L_SHS1_1_ADDR;
pstI2c_data[LINEAR_SHS1_2_ADDR].u32RegAddr = SC2336_1L_SHS1_2_ADDR;
pstI2c_data[LINEAR_AGAIN_0_ADDR].u32RegAddr = SC2336_1L_AGAIN0_ADDR;
pstI2c_data[LINEAR_DGAIN_0_ADDR].u32RegAddr = SC2336_1L_DGAIN0_ADDR;
pstI2c_data[LINEAR_DGAIN_1_ADDR].u32RegAddr = SC2336_1L_DGAIN0_ADDR + 1;
pstI2c_data[LINEAR_VMAX_0_ADDR].u32RegAddr = SC2336_1L_VMAX_ADDR;
pstI2c_data[LINEAR_VMAX_1_ADDR].u32RegAddr = SC2336_1L_VMAX_ADDR + 1;
break;
}
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 {
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 {
pstCfg0->snsCfg.astI2cData[i].bUpdate = CVI_TRUE;
pstCfg0->snsCfg.need_update = CVI_TRUE;
}
}
/* check update isp crop or not */
pstCfg0->ispCfg.need_update = (sensor_cmp_wdr_size(&pstCfg0->ispCfg, &pstCfg1->ispCfg) ?
CVI_TRUE : CVI_FALSE);
/* check update cif wdr manual or not */
pstCfg0->cifCfg.need_update = (sensor_cmp_cif_wdr(&pstCfg0->cifCfg, &pstCfg1->cifCfg) ?
CVI_TRUE : CVI_FALSE);
}
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);
SC2336_1L_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 (SC2336_1L_RES_IS_1080P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) {
u8SensorImageMode = SC2336_1L_MODE_1080P30;
} 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 {
}
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_global_init(VI_PIPE ViPipe)
{
ISP_SNS_STATE_S *pstSnsState = CVI_NULL;
const SC2336_1L_MODE_S *pstMode = CVI_NULL;
SC2336_1L_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER_VOID(pstSnsState);
pstSnsState->bInit = CVI_FALSE;
pstSnsState->bSyncInit = CVI_FALSE;
pstSnsState->u8ImgMode = SC2336_1L_MODE_1080P30;
pstSnsState->enWDRMode = WDR_MODE_NONE;
pstMode = &g_astSC2336_1L_mode[pstSnsState->u8ImgMode];
pstSnsState->u32FLStd = pstMode->u32VtsDef;
pstSnsState->au32FL[0] = pstMode->u32VtsDef;
pstSnsState->au32FL[1] = pstMode->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;
SC2336_1L_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER(pstSnsState);
CMOS_CHECK_POINTER(pstRxAttr);
memcpy(pstRxAttr, &sc2336_1L_rx_attr, sizeof(*pstRxAttr));
pstRxAttr->img_size.width = g_astSC2336_1L_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width;
pstRxAttr->img_size.height = g_astSC2336_1L_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 = &sc2336_1L_rx_attr;
int i;
CMOS_CHECK_POINTER(pstRxInitAttr);
if (pstRxInitAttr->stMclkAttr.bMclkEn)
pstRxAttr->mclk.cam = pstRxInitAttr->stMclkAttr.u8Mclk;
if (pstRxInitAttr->MipiDev >= 2)
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 = sc2336_1L_init;
pstSensorExpFunc->pfn_cmos_sensor_exit = sc2336_1L_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_S32 sc2336_1L_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo)
{
g_aunSC2336_1L_BusInfo[ViPipe].s8I2cDev = unSNSBusInfo.s8I2cDev;
return CVI_SUCCESS;
}
static CVI_S32 sensor_ctx_init(VI_PIPE ViPipe)
{
ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL;
SC2336_1L_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));
SC2336_1L_SENSOR_SET_CTX(ViPipe, pastSnsStateCtx);
return CVI_SUCCESS;
}
static CVI_VOID sensor_ctx_exit(VI_PIPE ViPipe)
{
ISP_SNS_STATE_S *pastSnsStateCtx = CVI_NULL;
SC2336_1L_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx);
SENSOR_FREE(pastSnsStateCtx);
SC2336_1L_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 = SC2336_1L_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, SC2336_1L_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, SC2336_1L_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, SC2336_1L_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_au16SC2336_1L_GainMode[ViPipe] = pstInitAttr->enGainMode;
g_au16SC2336_1L_L2SMode[ViPipe] = pstInitAttr->enL2SMode;
return CVI_SUCCESS;
}
ISP_SNS_OBJ_S stSnsSC2336_1L_Obj = {
.pfnRegisterCallback = sensor_register_callback,
.pfnUnRegisterCallback = sensor_unregister_callback,
.pfnStandby = sc2336_1L_standby,
.pfnRestart = sc2336_1L_restart,
.pfnMirrorFlip = sc2336_1L_mirror_flip,
.pfnWriteReg = sc2336_1L_write_register,
.pfnReadReg = sc2336_1L_read_register,
.pfnSetBusInfo = sc2336_1L_set_bus_info,
.pfnSetInit = sensor_set_init,
.pfnPatchRxAttr = sensor_patch_rx_attr,
.pfnPatchI2cAddr = CVI_NULL,
.pfnGetRxAttr = sensor_rx_attr,
.pfnExpSensorCb = cmos_init_sensor_exp_function,
.pfnExpAeCb = cmos_init_ae_exp_function,
.pfnSnsProbe = sc2336_1L_probe,
};

View File

@ -0,0 +1,85 @@
#ifndef __SC2336_1L_CMOS_EX_H_
#define __SC2336_1L_CMOS_EX_H_
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
#ifdef ARCH_CV182X
#include <linux/cvi_vip_cif.h>
#include <linux/cvi_vip_snsr.h>
#include "cvi_type.h"
#else
#include <linux/cif_uapi.h>
#include <linux/vi_snsr.h>
#include <linux/cvi_type.h>
#endif
#include "cvi_sns_ctrl.h"
enum sc2336_1L_linear_regs_e {
LINEAR_SHS1_0_ADDR,
LINEAR_SHS1_1_ADDR,
LINEAR_SHS1_2_ADDR,
LINEAR_AGAIN_0_ADDR,
LINEAR_DGAIN_0_ADDR,
LINEAR_DGAIN_1_ADDR,
LINEAR_VMAX_0_ADDR,
LINEAR_VMAX_1_ADDR,
LINEAR_REGS_NUM
};
typedef enum _SC2336_1L_MODE_E {
SC2336_1L_MODE_1080P30 = 0,
SC2336_1L_MODE_LINEAR_NUM,
SC2336_1L_MODE_NUM
} SC2336_1L_MODE_E;
typedef struct _SC2336_1L_STATE_S {
CVI_U32 u32Sexp_MAX; /* (2*{16h3e23,16h3e24} 'd10)/2 */
} SC2336_1L_STATE_S;
typedef struct _SC2336_1L_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_S stAgain[2];
SNS_ATTR_S stDgain[2];
CVI_U16 u16SexpMaxReg; /* {16h3e23,16h3e24} */
char name[64];
} SC2336_1L_MODE_S;
/****************************************************************************
* external variables and functions *
****************************************************************************/
extern ISP_SNS_STATE_S *g_pastSC2336_1L[VI_MAX_PIPE_NUM];
extern ISP_SNS_COMMBUS_U g_aunSC2336_1L_BusInfo[];
extern CVI_U16 g_au16SC2336_1L_GainMode[];
extern CVI_U16 g_au16SC2336_1L_L2SMode[];
extern const CVI_U8 sc2336_1L_i2c_addr;
extern const CVI_U32 sc2336_1L_addr_byte;
extern const CVI_U32 sc2336_1L_data_byte;
extern void sc2336_1L_init(VI_PIPE ViPipe);
extern void sc2336_1L_exit(VI_PIPE ViPipe);
extern void sc2336_1L_standby(VI_PIPE ViPipe);
extern void sc2336_1L_restart(VI_PIPE ViPipe);
extern int sc2336_1L_write_register(VI_PIPE ViPipe, int addr, int data);
extern int sc2336_1L_read_register(VI_PIPE ViPipe, int addr);
extern void sc2336_1L_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip);
extern int sc2336_1L_probe(VI_PIPE ViPipe);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* End of #ifdef __cplusplus */
#endif /* __SC2336_1L_CMOS_EX_H_ */

View File

@ -0,0 +1,125 @@
#ifndef __SC2336_1L_CMOS_PARAM_H_
#define __SC2336_1L_CMOS_PARAM_H_
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
#ifdef ARCH_CV182X
#include <linux/cvi_vip_cif.h>
#include <linux/cvi_vip_snsr.h>
#include "cvi_type.h"
#else
#include <linux/cif_uapi.h>
#include <linux/vi_snsr.h>
#include <linux/cvi_type.h>
#endif
#include "cvi_sns_ctrl.h"
#include "sc2336_1L_cmos_ex.h"
static const SC2336_1L_MODE_S g_astSC2336_1L_mode[SC2336_1L_MODE_NUM] = {
[SC2336_1L_MODE_1080P30] = {
.name = "1080p30",
.astImg[0] = {
.stSnsSize = {
.u32Width = 1920,
.u32Height = 1080,
},
.stWndRect = {
.s32X = 0,
.s32Y = 0,
.u32Width = 1920,
.u32Height = 1080,
},
.stMaxSize = {
.u32Width = 1920,
.u32Height = 1080,
},
},
.f32MaxFps = 30,
.f32MinFps = 0.51, /* 1125 * 30 / 0xFFFF*/
.u32HtsDef = 2560,
.u32VtsDef = 1125,
.stExp[0] = {
.u16Min = 1,
.u16Max = 12184 - 6,
.u16Def = 400,
.u16Step = 1,
},
.stAgain[0] = {
.u16Min = 1024,
.u16Max = 32768,
.u16Def = 1024,
.u16Step = 1,
},
.stDgain[0] = {
.u16Min = 1024,
.u16Max = 4096,
.u16Def = 1024,
.u16Step = 1,
},
},
};
static ISP_CMOS_BLACK_LEVEL_S g_stIspBlcCalibratio = {
.bUpdate = CVI_TRUE,
.blcAttr = {
.Enable = 1,
.enOpType = OP_TYPE_AUTO,
.stManual = {260, 260, 260, 260, 0, 0, 0, 0
#ifdef ARCH_CV182X
, 1093, 1093, 1093, 1093
#endif
},
.stAuto = {
{260, 260, 260, 260, 260, 252, 252, 252, /*8*/260, 260, 260, 260, 260, 260, 260, 260},
{260, 260, 260, 260, 260, 252, 252, 252, /*8*/260, 260, 260, 260, 260, 260, 260, 260},
{260, 260, 260, 260, 260, 252, 252, 252, /*8*/260, 260, 260, 260, 260, 260, 260, 260},
{260, 260, 260, 260, 260, 252, 252, 252, /*8*/260, 260, 260, 260, 260, 260, 260, 260},
{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, 1091, 1091, 1091,
/*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093},
{1093, 1093, 1093, 1093, 1093, 1091, 1091, 1091,
/*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093},
{1093, 1093, 1093, 1093, 1093, 1091, 1091, 1091,
/*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093},
{1093, 1093, 1093, 1093, 1093, 1091, 1091, 1091,
/*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093},
#endif
},
},
};
struct combo_dev_attr_s sc2336_1L_rx_attr = {
.input_mode = INPUT_MODE_MIPI,
.mac_clk = RX_MAC_CLK_200M,
.mipi_attr = {
.raw_data_type = RAW_DATA_10BIT,
.lane_id = {2, 0, -1, -1, -1},
.wdr_mode = CVI_MIPI_WDR_MODE_NONE,
.dphy = {
.enable = 1,
.hs_settle = 8,
}
},
.mclk = {
.cam = 0,
.freq = CAMPLL_FREQ_27M,
},
.devno = 0,
};
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* End of #ifdef __cplusplus */
#endif /* __SC2336_1L_CMOS_PARAM_H_ */

View File

@ -0,0 +1,420 @@
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <syslog.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#ifdef ARCH_CV182X
#include <linux/cvi_vip_snsr.h>
#include "cvi_comm_video.h"
#else
#include <linux/vi_snsr.h>
#include <linux/cvi_comm_video.h>
#endif
#include "cvi_sns_ctrl.h"
#include "sc2336_1L_cmos_ex.h"
static void sc2336_1L_linear_1080p30_init(VI_PIPE ViPipe);
const CVI_U8 sc2336_1L_i2c_addr = 0x30; /* I2C Address of SC2336_1L */
const CVI_U32 sc2336_1L_addr_byte = 2;
const CVI_U32 sc2336_1L_data_byte = 1;
static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1};
int sc2336_1L_i2c_init(VI_PIPE ViPipe)
{
char acDevFile[16] = {0};
CVI_U8 u8DevNum;
if (g_fd[ViPipe] >= 0)
return CVI_SUCCESS;
int ret;
u8DevNum = g_aunSC2336_1L_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/cvi_i2c_drv-%u error!\n", u8DevNum);
return CVI_FAILURE;
}
ret = ioctl(g_fd[ViPipe], I2C_SLAVE_FORCE, sc2336_1L_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 sc2336_1L_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 sc2336_1L_read_register(VI_PIPE ViPipe, int addr)
{
int ret, data;
char buf[8];
int idx = 0;
if (g_fd[ViPipe] < 0)
return CVI_FAILURE;
if (sc2336_1L_addr_byte == 2)
buf[idx++] = (addr >> 8) & 0xff;
// add address byte 0
buf[idx++] = addr & 0xff;
ret = write(g_fd[ViPipe], buf, sc2336_1L_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, sc2336_1L_data_byte);
if (ret < 0) {
CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_READ error!\n");
return ret;
}
// pack read back data
data = 0;
if (sc2336_1L_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 sc2336_1L_write_register(VI_PIPE ViPipe, int addr, int data)
{
int idx = 0;
int ret;
char buf[8];
if (g_fd[ViPipe] < 0)
return CVI_SUCCESS;
if (sc2336_1L_addr_byte == 2) {
buf[idx] = (addr >> 8) & 0xff;
idx++;
buf[idx] = addr & 0xff;
idx++;
}
if (sc2336_1L_data_byte == 1) {
buf[idx] = data & 0xff;
idx++;
}
ret = write(g_fd[ViPipe], buf, sc2336_1L_addr_byte + sc2336_1L_data_byte);
if (ret < 0) {
CVI_TRACE_SNS(CVI_DBG_ERR, "I2C_WRITE error!\n");
return CVI_FAILURE;
}
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 sc2336_1L_prog(VI_PIPE ViPipe, int *rom)
{
int i = 0;
while (1) {
int lookup = rom[i++];
int addr = (lookup >> 16) & 0xFFFF;
int data = lookup & 0xFFFF;
if (addr == 0xFFFE)
delay_ms(data);
else if (addr != 0xFFFF)
sc2336_1L_write_register(ViPipe, addr, data);
}
}
void sc2336_1L_standby(VI_PIPE ViPipe)
{
sc2336_1L_write_register(ViPipe, 0x0100, 0x00);
}
void sc2336_1L_restart(VI_PIPE ViPipe)
{
sc2336_1L_write_register(ViPipe, 0x0100, 0x00);
delay_ms(20);
sc2336_1L_write_register(ViPipe, 0x0100, 0x01);
}
void sc2336_1L_default_reg_init(VI_PIPE ViPipe)
{
CVI_U32 i;
for (i = 0; i < g_pastSC2336_1L[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) {
sc2336_1L_write_register(ViPipe,
g_pastSC2336_1L[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr,
g_pastSC2336_1L[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data);
}
}
#define SC2336_1L_CHIP_ID_HI_ADDR 0x3107
#define SC2336_1L_CHIP_ID_LO_ADDR 0x3108
#define SC2336_1L_CHIP_ID 0xcb3a
void sc2336_1L_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip)
{
CVI_U8 val = 0;
switch (eSnsMirrorFlip) {
case ISP_SNS_NORMAL:
break;
case ISP_SNS_MIRROR:
val |= 0x6;
break;
case ISP_SNS_FLIP:
val |= 0x60;
break;
case ISP_SNS_MIRROR_FLIP:
val |= 0x66;
break;
default:
return;
}
sc2336_1L_write_register(ViPipe, 0x3221, val);
}
int sc2336_1L_probe(VI_PIPE ViPipe)
{
int nVal;
CVI_U16 chip_id;
usleep(4*1000);
if (sc2336_1L_i2c_init(ViPipe) != CVI_SUCCESS)
return CVI_FAILURE;
nVal = sc2336_1L_read_register(ViPipe, SC2336_1L_CHIP_ID_HI_ADDR);
if (nVal < 0) {
CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n");
return nVal;
}
chip_id = (nVal & 0xFF) << 8;
nVal = sc2336_1L_read_register(ViPipe, SC2336_1L_CHIP_ID_LO_ADDR);
if (nVal < 0) {
CVI_TRACE_SNS(CVI_DBG_ERR, "read sensor id error.\n");
return nVal;
}
chip_id |= (nVal & 0xFF);
if (chip_id != SC2336_1L_CHIP_ID) {
CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n");
return CVI_FAILURE;
}
return CVI_SUCCESS;
}
void sc2336_1L_init(VI_PIPE ViPipe)
{
WDR_MODE_E enWDRMode;
CVI_BOOL bInit;
bInit = g_pastSC2336_1L[ViPipe]->bInit;
enWDRMode = g_pastSC2336_1L[ViPipe]->enWDRMode;
sc2336_1L_i2c_init(ViPipe);
/* When sensor first init, config all registers */
if (bInit == CVI_FALSE) {
if (enWDRMode == WDR_MODE_NONE) {
sc2336_1L_linear_1080p30_init(ViPipe);
}
}
/* When sensor switch mode(linear<->WDR or resolution), config different registers(if possible) */
else {
if (enWDRMode == WDR_MODE_NONE) {
sc2336_1L_linear_1080p30_init(ViPipe);
}
}
g_pastSC2336_1L[ViPipe]->bInit = CVI_TRUE;
}
void sc2336_1L_exit(VI_PIPE ViPipe)
{
sc2336_1L_i2c_exit(ViPipe);
}
/* 1080P30 and 1080P25 */
static void sc2336_1L_linear_1080p30_init(VI_PIPE ViPipe)
{
sc2336_1L_write_register(ViPipe, 0x0103, 0x01);
sc2336_1L_write_register(ViPipe, 0x0100, 0x00);
sc2336_1L_write_register(ViPipe, 0x36e9, 0x80);
sc2336_1L_write_register(ViPipe, 0x37f9, 0x80);
sc2336_1L_write_register(ViPipe, 0x3018, 0x12);
sc2336_1L_write_register(ViPipe, 0x3019, 0x0e);
sc2336_1L_write_register(ViPipe, 0x301f, 0x3b);
sc2336_1L_write_register(ViPipe, 0x3106, 0x05);
sc2336_1L_write_register(ViPipe, 0x3248, 0x04);
sc2336_1L_write_register(ViPipe, 0x3249, 0x0b);
sc2336_1L_write_register(ViPipe, 0x3253, 0x08);
sc2336_1L_write_register(ViPipe, 0x3301, 0x09);
sc2336_1L_write_register(ViPipe, 0x3302, 0xff);
sc2336_1L_write_register(ViPipe, 0x3303, 0x10);
sc2336_1L_write_register(ViPipe, 0x3306, 0x60);
sc2336_1L_write_register(ViPipe, 0x3307, 0x02);
sc2336_1L_write_register(ViPipe, 0x330a, 0x01);
sc2336_1L_write_register(ViPipe, 0x330b, 0x10);
sc2336_1L_write_register(ViPipe, 0x330c, 0x16);
sc2336_1L_write_register(ViPipe, 0x330d, 0xff);
sc2336_1L_write_register(ViPipe, 0x3318, 0x02);
sc2336_1L_write_register(ViPipe, 0x3321, 0x0a);
sc2336_1L_write_register(ViPipe, 0x3327, 0x0e);
sc2336_1L_write_register(ViPipe, 0x332b, 0x12);
sc2336_1L_write_register(ViPipe, 0x3333, 0x10);
sc2336_1L_write_register(ViPipe, 0x3334, 0x40);
sc2336_1L_write_register(ViPipe, 0x335e, 0x06);
sc2336_1L_write_register(ViPipe, 0x335f, 0x0a);
sc2336_1L_write_register(ViPipe, 0x3364, 0x1f);
sc2336_1L_write_register(ViPipe, 0x337c, 0x02);
sc2336_1L_write_register(ViPipe, 0x337d, 0x0e);
sc2336_1L_write_register(ViPipe, 0x3390, 0x09);
sc2336_1L_write_register(ViPipe, 0x3391, 0x0f);
sc2336_1L_write_register(ViPipe, 0x3392, 0x1f);
sc2336_1L_write_register(ViPipe, 0x3393, 0x20);
sc2336_1L_write_register(ViPipe, 0x3394, 0x20);
sc2336_1L_write_register(ViPipe, 0x3395, 0xff);
sc2336_1L_write_register(ViPipe, 0x33a2, 0x04);
sc2336_1L_write_register(ViPipe, 0x33b1, 0x80);
sc2336_1L_write_register(ViPipe, 0x33b2, 0x68);
sc2336_1L_write_register(ViPipe, 0x33b3, 0x42);
sc2336_1L_write_register(ViPipe, 0x33f9, 0x70);
sc2336_1L_write_register(ViPipe, 0x33fb, 0xd0);
sc2336_1L_write_register(ViPipe, 0x33fc, 0x0f);
sc2336_1L_write_register(ViPipe, 0x33fd, 0x1f);
sc2336_1L_write_register(ViPipe, 0x349f, 0x03);
sc2336_1L_write_register(ViPipe, 0x34a6, 0x0f);
sc2336_1L_write_register(ViPipe, 0x34a7, 0x1f);
sc2336_1L_write_register(ViPipe, 0x34a8, 0x42);
sc2336_1L_write_register(ViPipe, 0x34a9, 0x06);
sc2336_1L_write_register(ViPipe, 0x34aa, 0x01);
sc2336_1L_write_register(ViPipe, 0x34ab, 0x23);
sc2336_1L_write_register(ViPipe, 0x34ac, 0x01);
sc2336_1L_write_register(ViPipe, 0x34ad, 0x84);
sc2336_1L_write_register(ViPipe, 0x3630, 0xf4);
sc2336_1L_write_register(ViPipe, 0x3633, 0x22);
sc2336_1L_write_register(ViPipe, 0x3639, 0xf4);
sc2336_1L_write_register(ViPipe, 0x363c, 0x47);
sc2336_1L_write_register(ViPipe, 0x3670, 0x09);
sc2336_1L_write_register(ViPipe, 0x3674, 0xf4);
sc2336_1L_write_register(ViPipe, 0x3675, 0xfb);
sc2336_1L_write_register(ViPipe, 0x3676, 0xed);
sc2336_1L_write_register(ViPipe, 0x367c, 0x09);
sc2336_1L_write_register(ViPipe, 0x367d, 0x0f);
sc2336_1L_write_register(ViPipe, 0x3690, 0x33);
sc2336_1L_write_register(ViPipe, 0x3691, 0x33);
sc2336_1L_write_register(ViPipe, 0x3692, 0x43);
sc2336_1L_write_register(ViPipe, 0x3698, 0x89);
sc2336_1L_write_register(ViPipe, 0x3699, 0x96);
sc2336_1L_write_register(ViPipe, 0x369a, 0xd0);
sc2336_1L_write_register(ViPipe, 0x369b, 0xd0);
sc2336_1L_write_register(ViPipe, 0x369c, 0x09);
sc2336_1L_write_register(ViPipe, 0x369d, 0x0f);
sc2336_1L_write_register(ViPipe, 0x36a2, 0x09);
sc2336_1L_write_register(ViPipe, 0x36a3, 0x0f);
sc2336_1L_write_register(ViPipe, 0x36a4, 0x1f);
sc2336_1L_write_register(ViPipe, 0x36d0, 0x01);
sc2336_1L_write_register(ViPipe, 0x36ec, 0x0c);
sc2336_1L_write_register(ViPipe, 0x3722, 0xe1);
sc2336_1L_write_register(ViPipe, 0x3724, 0x41);
sc2336_1L_write_register(ViPipe, 0x3725, 0xc1);
sc2336_1L_write_register(ViPipe, 0x3728, 0x20);
sc2336_1L_write_register(ViPipe, 0x3900, 0x0d);
sc2336_1L_write_register(ViPipe, 0x3905, 0x98);
sc2336_1L_write_register(ViPipe, 0x391b, 0x81);
sc2336_1L_write_register(ViPipe, 0x391c, 0x10);
sc2336_1L_write_register(ViPipe, 0x3933, 0x81);
sc2336_1L_write_register(ViPipe, 0x3934, 0xc5);
sc2336_1L_write_register(ViPipe, 0x3940, 0x68);
sc2336_1L_write_register(ViPipe, 0x3941, 0x00);
sc2336_1L_write_register(ViPipe, 0x3942, 0x01);
sc2336_1L_write_register(ViPipe, 0x3943, 0xc6);
sc2336_1L_write_register(ViPipe, 0x3952, 0x02);
sc2336_1L_write_register(ViPipe, 0x3953, 0x0f);
sc2336_1L_write_register(ViPipe, 0x3e01, 0x45);
sc2336_1L_write_register(ViPipe, 0x3e02, 0xf0);
sc2336_1L_write_register(ViPipe, 0x3e08, 0x1f);
sc2336_1L_write_register(ViPipe, 0x3e1b, 0x14);
sc2336_1L_write_register(ViPipe, 0x440e, 0x02);
sc2336_1L_write_register(ViPipe, 0x4509, 0x38);
sc2336_1L_write_register(ViPipe, 0x4819, 0x09);
sc2336_1L_write_register(ViPipe, 0x481b, 0x05);
sc2336_1L_write_register(ViPipe, 0x481d, 0x14);
sc2336_1L_write_register(ViPipe, 0x481f, 0x04);
sc2336_1L_write_register(ViPipe, 0x4821, 0x0a);
sc2336_1L_write_register(ViPipe, 0x4823, 0x05);
sc2336_1L_write_register(ViPipe, 0x4825, 0x04);
sc2336_1L_write_register(ViPipe, 0x4827, 0x05);
sc2336_1L_write_register(ViPipe, 0x4829, 0x08);
sc2336_1L_write_register(ViPipe, 0x5799, 0x06);
sc2336_1L_write_register(ViPipe, 0x5ae0, 0xfe);
sc2336_1L_write_register(ViPipe, 0x5ae1, 0x40);
sc2336_1L_write_register(ViPipe, 0x5ae2, 0x30);
sc2336_1L_write_register(ViPipe, 0x5ae3, 0x28);
sc2336_1L_write_register(ViPipe, 0x5ae4, 0x20);
sc2336_1L_write_register(ViPipe, 0x5ae5, 0x30);
sc2336_1L_write_register(ViPipe, 0x5ae6, 0x28);
sc2336_1L_write_register(ViPipe, 0x5ae7, 0x20);
sc2336_1L_write_register(ViPipe, 0x5ae8, 0x3c);
sc2336_1L_write_register(ViPipe, 0x5ae9, 0x30);
sc2336_1L_write_register(ViPipe, 0x5aea, 0x28);
sc2336_1L_write_register(ViPipe, 0x5aeb, 0x3c);
sc2336_1L_write_register(ViPipe, 0x5aec, 0x30);
sc2336_1L_write_register(ViPipe, 0x5aed, 0x28);
sc2336_1L_write_register(ViPipe, 0x5aee, 0xfe);
sc2336_1L_write_register(ViPipe, 0x5aef, 0x40);
sc2336_1L_write_register(ViPipe, 0x5af4, 0x30);
sc2336_1L_write_register(ViPipe, 0x5af5, 0x28);
sc2336_1L_write_register(ViPipe, 0x5af6, 0x20);
sc2336_1L_write_register(ViPipe, 0x5af7, 0x30);
sc2336_1L_write_register(ViPipe, 0x5af8, 0x28);
sc2336_1L_write_register(ViPipe, 0x5af9, 0x20);
sc2336_1L_write_register(ViPipe, 0x5afa, 0x3c);
sc2336_1L_write_register(ViPipe, 0x5afb, 0x30);
sc2336_1L_write_register(ViPipe, 0x5afc, 0x28);
sc2336_1L_write_register(ViPipe, 0x5afd, 0x3c);
sc2336_1L_write_register(ViPipe, 0x5afe, 0x30);
sc2336_1L_write_register(ViPipe, 0x5aff, 0x28);
sc2336_1L_write_register(ViPipe, 0x36e9, 0x20);
sc2336_1L_write_register(ViPipe, 0x37f9, 0x27);
sc2336_1L_default_reg_init(ViPipe);
sc2336_1L_write_register(ViPipe, 0x0100, 0x01);
printf("ViPipe:%d,===SC2336_1L 1080P 30fps 10bit LINE Init OK!===\n", ViPipe);
}

Binary file not shown.

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More