SensorSupportList: weekly rls 2024.06.6
-bb7dfa, add sc3336_1l Change-Id: I5082244998caf0a16371bd3588904196d18d5dd3
This commit is contained in:
committed by
carbon
parent
b8a32e0560
commit
78730ed72b
@ -108,6 +108,7 @@ sensor-$(CONFIG_SENSOR_SMS_SC531AI_2L) += sms_sc531ai_2L
|
||||
sensor-$(CONFIG_SENSOR_SMS_SC3332) += sms_sc3332
|
||||
sensor-$(CONFIG_SENSOR_SMS_SC3335) += sms_sc3335
|
||||
sensor-$(CONFIG_SENSOR_SMS_SC3336) += sms_sc3336
|
||||
sensor-$(CONFIG_SENSOR_SMS_SC3336_1L) += sms_sc3336_1L
|
||||
sensor-$(CONFIG_SENSOR_SMS_SC3336P) += sms_sc3336p
|
||||
sensor-$(CONFIG_SENSOR_SMS_SC2331_1L) += sms_sc2331_1L
|
||||
sensor-$(CONFIG_SENSOR_SMS_SC2331_1L_SLAVE) += sms_sc2331_1L_slave
|
||||
|
||||
@ -191,6 +191,9 @@ sms_sc3335:
|
||||
sms_sc3336:
|
||||
$(call MAKE_SENSOR, ${@})
|
||||
|
||||
sms_sc3336_1L:
|
||||
$(call MAKE_SENSOR, ${@})
|
||||
|
||||
sms_sc3336p:
|
||||
$(call MAKE_SENSOR, ${@})
|
||||
|
||||
|
||||
@ -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_sc3336_1l.a
|
||||
TARGET_SO = $(MW_LIB)/libsns_sc3336_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)
|
||||
@ -0,0 +1,946 @@
|
||||
#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 "sc3336_1L_cmos_ex.h"
|
||||
#include "sc3336_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 SC3336_1L_ID 3336
|
||||
#define SC3336_1L_I2C_ADDR_1 0x30
|
||||
#define SC3336_1L_I2C_ADDR_2 0x32
|
||||
#define SC3336_1L_I2C_ADDR_IS_VALID(addr) ((addr) == SC3336_1L_I2C_ADDR_1 || (addr) == SC3336_1L_I2C_ADDR_2)
|
||||
|
||||
/****************************************************************************
|
||||
* global variables *
|
||||
****************************************************************************/
|
||||
|
||||
ISP_SNS_STATE_S *g_pastSC3336_1L[VI_MAX_PIPE_NUM] = {CVI_NULL};
|
||||
|
||||
#define SC3336_1L_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastSC3336_1L[dev])
|
||||
#define SC3336_1L_SENSOR_SET_CTX(dev, pstCtx) (g_pastSC3336_1L[dev] = pstCtx)
|
||||
#define SC3336_1L_SENSOR_RESET_CTX(dev) (g_pastSC3336_1L[dev] = CVI_NULL)
|
||||
|
||||
ISP_SNS_COMMBUS_U g_aunSC3336_1L_BusInfo[VI_MAX_PIPE_NUM] = {
|
||||
[0] = { .s8I2cDev = 2},
|
||||
[1 ... VI_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1}
|
||||
};
|
||||
|
||||
CVI_U16 g_au16SC3336_1L_GainMode[VI_MAX_PIPE_NUM] = {0};
|
||||
CVI_U16 g_au16SC3336_1L_L2SMode[VI_MAX_PIPE_NUM] = {0};
|
||||
|
||||
ISP_SNS_MIRRORFLIP_TYPE_E g_aeSC3336_1L_MirrorFip[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);
|
||||
/*****SC3336_1L Lines Range*****/
|
||||
#define SC3336_1L_FULL_LINES_MAX (0x7FFF)
|
||||
|
||||
/*****SC3336_1L Register Address*****/
|
||||
#define SC3336_1L_EXP_H_ADDR (0x3e00)
|
||||
#define SC3336_1L_EXP_M_ADDR (0x3e01)
|
||||
#define SC3336_1L_EXP_L_ADDR (0x3e02)
|
||||
|
||||
#define SC3336_1L_AGAIN_ADDR (0x3e09)
|
||||
|
||||
#define SC3336_1L_DGAIN_H_ADDR (0x3e06)
|
||||
#define SC3336_1L_DGAIN_L_ADDR (0x3e07)
|
||||
|
||||
#define SC3336_1L_VMAX_H_ADDR (0x320e)
|
||||
#define SC3336_1L_VMAX_L_ADDR (0x320f)
|
||||
|
||||
#define SC3336_1L_RES_IS_1296P(w, h) ((w) == 2304 && (h) == 1296)
|
||||
|
||||
#define SC3336_1L_EXPACCURACY (1)
|
||||
|
||||
static CVI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft)
|
||||
{
|
||||
const SC3336_1L_MODE_S *pstMode;
|
||||
ISP_SNS_STATE_S *pstSnsState = CVI_NULL;
|
||||
|
||||
CMOS_CHECK_POINTER(pstAeSnsDft);
|
||||
SC3336_1L_SENSOR_GET_CTX(ViPipe, pstSnsState);
|
||||
CMOS_CHECK_POINTER(pstSnsState);
|
||||
|
||||
pstMode = &g_astSC3336_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 = SC3336_1L_FULL_LINES_MAX;
|
||||
pstAeSnsDft->u32HmaxTimes = (1000000) / (pstSnsState->u32FLStd * 20);
|
||||
|
||||
pstAeSnsDft->stIntTimeAccu.enAccuType = AE_ACCURACY_LINEAR;
|
||||
pstAeSnsDft->stIntTimeAccu.f32Accuracy = SC3336_1L_EXPACCURACY;
|
||||
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 * 20 / 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) {
|
||||
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 = pstAeSnsDft->u32MaxIntTime;
|
||||
pstAeSnsDft->u32MinIntTimeTarget = pstAeSnsDft->u32MinIntTime;
|
||||
break;
|
||||
default:
|
||||
CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode);
|
||||
return CVI_FAILURE;
|
||||
}
|
||||
|
||||
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);
|
||||
SC3336_1L_SENSOR_GET_CTX(ViPipe, pstSnsState);
|
||||
CMOS_CHECK_POINTER(pstSnsState);
|
||||
|
||||
u32Vts = g_astSC3336_1L_mode[pstSnsState->u8ImgMode].u32VtsDef;
|
||||
pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg;
|
||||
f32MaxFps = g_astSC3336_1L_mode[pstSnsState->u8ImgMode].f32MaxFps;
|
||||
f32MinFps = g_astSC3336_1L_mode[pstSnsState->u8ImgMode].f32MinFps;
|
||||
|
||||
switch (pstSnsState->u8ImgMode) {
|
||||
case SC3336_1L_MODE_2304X1296P20:
|
||||
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 > SC3336_1L_FULL_LINES_MAX) ? SC3336_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_H_ADDR].u32Data = ((u32VMAX & 0xFF00) >> 8);
|
||||
pstSnsRegsInfo->astI2cData[LINEAR_VMAX_L_ADDR].u32Data = (u32VMAX & 0xFF);
|
||||
} else {
|
||||
CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode);
|
||||
return CVI_FAILURE;
|
||||
}
|
||||
|
||||
pstAeSnsDft->f32Fps = f32Fps;
|
||||
pstAeSnsDft->u32LinesPer500ms = pstSnsState->u32FLStd * f32Fps / 2;
|
||||
pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd;
|
||||
pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 10;
|
||||
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_U32 u32TmpIntTime, u32MinTime, u32MaxTime;
|
||||
|
||||
SC3336_1L_SENSOR_GET_CTX(ViPipe, pstSnsState);
|
||||
CMOS_CHECK_POINTER(pstSnsState);
|
||||
CMOS_CHECK_POINTER(u32IntTime);
|
||||
pstSnsRegsInfo = &pstSnsState->astSyncInfo[0].snsCfg;
|
||||
|
||||
if (pstSnsState->enWDRMode == WDR_MODE_NONE) {
|
||||
/* linear exposure reg range:
|
||||
* min : 0
|
||||
* max : vts - 10
|
||||
* step : 1
|
||||
*/
|
||||
u32MinTime = 0;
|
||||
u32MaxTime = pstSnsState->au32FL[0] - 10;
|
||||
u32TmpIntTime = (u32IntTime[0] > u32MaxTime) ? u32MaxTime : u32IntTime[0];
|
||||
u32TmpIntTime = (u32TmpIntTime < u32MinTime) ? u32MinTime : u32TmpIntTime;
|
||||
|
||||
pstSnsRegsInfo->astI2cData[LINEAR_EXP_H_ADDR].u32Data = ((u32TmpIntTime & 0xF000) >> 12);
|
||||
pstSnsRegsInfo->astI2cData[LINEAR_EXP_M_ADDR].u32Data = ((u32TmpIntTime & 0x0FF0) >> 4);
|
||||
pstSnsRegsInfo->astI2cData[LINEAR_EXP_L_ADDR].u32Data = ((u32TmpIntTime & 0x000F) << 4);
|
||||
} else {
|
||||
CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode);
|
||||
return CVI_FAILURE;
|
||||
}
|
||||
|
||||
return CVI_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
typedef struct gain_tbl_info_s {
|
||||
CVI_U16 gainMax;
|
||||
CVI_U16 idxBase;
|
||||
CVI_U8 regGain;
|
||||
CVI_U8 regGainFineBase;
|
||||
CVI_U8 regGainFineStep;
|
||||
} gain_tbl_info_s;
|
||||
|
||||
static struct gain_tbl_info_s DgainInfo[4] = {
|
||||
{
|
||||
.gainMax = 2016,
|
||||
.idxBase = 0,
|
||||
.regGain = 0x00,
|
||||
.regGainFineBase = 0x80,
|
||||
.regGainFineStep = 4,
|
||||
},
|
||||
{
|
||||
.gainMax = 4032,
|
||||
.idxBase = 32,
|
||||
.regGain = 0x01,
|
||||
.regGainFineBase = 0x80,
|
||||
.regGainFineStep = 4,
|
||||
},
|
||||
{
|
||||
.gainMax = 8064,
|
||||
.idxBase = 64,
|
||||
.regGain = 0x03,
|
||||
.regGainFineBase = 0x80,
|
||||
.regGainFineStep = 4,
|
||||
},
|
||||
{
|
||||
.gainMax = 16128,
|
||||
.idxBase = 96,
|
||||
.regGain = 0x07,
|
||||
.regGainFineBase = 0x80,
|
||||
.regGainFineStep = 4,
|
||||
},
|
||||
};
|
||||
|
||||
static CVI_U32 Dgain_table[128] = {
|
||||
1024, 1055, 1088, 1120, 1152, 1183, 1216, 1248, 1280, 1311, 1344, 1376,
|
||||
1408, 1439, 1472, 1504, 1536, 1567, 1600, 1632, 1664, 1695, 1728, 1760,
|
||||
1792, 1823, 1856, 1888, 1920, 1951, 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, 4224, 4352, 4480, 4608, 4736, 4864, 4992,
|
||||
5120, 5248, 5376, 5504, 5632, 5760, 5888, 6016, 6144, 6272, 6400, 6528,
|
||||
6656, 6784, 6912, 7040, 7168, 7296, 7424, 7552, 7680, 7808, 7936, 8064,
|
||||
8192, 8448, 8704, 8960, 9216, 9472, 9728, 9984, 10240, 10496, 10752, 11008,
|
||||
11264, 11520, 11776, 12032, 12288, 12544, 12800, 13056, 13312, 13568, 13824,
|
||||
14080, 14336, 14592, 14848, 15104, 15360, 15616, 15872, 16128
|
||||
};
|
||||
|
||||
static CVI_S32 cmos_again_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32AgainLin, CVI_U32 *pu32AgainDb)
|
||||
{
|
||||
CVI_U32 again = *pu32AgainLin;
|
||||
|
||||
(void) ViPipe;
|
||||
|
||||
CMOS_CHECK_POINTER(pu32AgainLin);
|
||||
CMOS_CHECK_POINTER(pu32AgainDb);
|
||||
|
||||
if (again < 1556) {
|
||||
*pu32AgainDb = 0x00;
|
||||
*pu32AgainLin = 1024;
|
||||
} else if (again < 3122) {
|
||||
*pu32AgainDb = 0x40;
|
||||
*pu32AgainLin = 1556;
|
||||
} else if (again < 6225) {
|
||||
*pu32AgainDb = 0x48;
|
||||
*pu32AgainLin = 3122;
|
||||
} else if (again < 12451) {
|
||||
*pu32AgainDb = 0x49;
|
||||
*pu32AgainLin = 6225;
|
||||
} else if (again < 24903) {
|
||||
*pu32AgainDb = 0x4b;
|
||||
*pu32AgainLin = 12451;
|
||||
} else if (again < 49807) {
|
||||
*pu32AgainDb = 0x4f;
|
||||
*pu32AgainLin = 24903;
|
||||
} else {
|
||||
*pu32AgainDb = 0x5f;
|
||||
*pu32AgainLin = 49807;
|
||||
}
|
||||
|
||||
return CVI_SUCCESS;
|
||||
}
|
||||
|
||||
static CVI_S32 cmos_dgain_calc_table(VI_PIPE ViPipe, CVI_U32 *pu32DgainLin, CVI_U32 *pu32DgainDb)
|
||||
{
|
||||
int i;
|
||||
|
||||
(void) ViPipe;
|
||||
|
||||
CMOS_CHECK_POINTER(pu32DgainLin);
|
||||
CMOS_CHECK_POINTER(pu32DgainDb);
|
||||
|
||||
if (*pu32DgainLin >= Dgain_table[127]) {
|
||||
*pu32DgainLin = Dgain_table[127];
|
||||
*pu32DgainDb = 127;
|
||||
return CVI_SUCCESS;
|
||||
}
|
||||
|
||||
for (i = 1; i < 128; 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;
|
||||
int i, tbl_num;
|
||||
|
||||
SC3336_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 */
|
||||
|
||||
/* find Again register setting. */
|
||||
pstSnsRegsInfo->astI2cData[LINEAR_AGAIN_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_H_ADDR].u32Data = (info->regGain & 0xFF);
|
||||
u32Dgain = info->regGainFineBase + (u32Dgain - info->idxBase) * info->regGainFineStep;
|
||||
pstSnsRegsInfo->astI2cData[LINEAR_DGAIN_L_ADDR].u32Data = (u32Dgain & 0xFF);
|
||||
|
||||
} else {
|
||||
CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode);
|
||||
return CVI_FAILURE;
|
||||
}
|
||||
|
||||
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 SC3336_1L_MODE_S *pstMode = CVI_NULL;
|
||||
ISP_SNS_STATE_S *pstSnsState = CVI_NULL;
|
||||
|
||||
SC3336_1L_SENSOR_GET_CTX(ViPipe, pstSnsState);
|
||||
CMOS_CHECK_POINTER(pstSnsState);
|
||||
pstMode = &g_astSC3336_1L_mode[pstSnsState->u8ImgMode];
|
||||
|
||||
pstIspCfg->frm_num = 1;
|
||||
memcpy(&pstIspCfg->img_size[0], &pstMode->astImg[0], sizeof(ISP_WDR_SIZE_S));
|
||||
|
||||
return CVI_SUCCESS;
|
||||
}
|
||||
|
||||
static CVI_S32 cmos_set_wdr_mode(VI_PIPE ViPipe, CVI_U8 u8Mode)
|
||||
{
|
||||
ISP_SNS_STATE_S *pstSnsState = CVI_NULL;
|
||||
|
||||
SC3336_1L_SENSOR_GET_CTX(ViPipe, pstSnsState);
|
||||
CMOS_CHECK_POINTER(pstSnsState);
|
||||
|
||||
pstSnsState->bSyncInit = CVI_FALSE;
|
||||
|
||||
switch (u8Mode) {
|
||||
case WDR_MODE_NONE:
|
||||
pstSnsState->u8ImgMode = SC3336_1L_MODE_2304X1296P20;
|
||||
pstSnsState->enWDRMode = WDR_MODE_NONE;
|
||||
pstSnsState->u32FLStd = g_astSC3336_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);
|
||||
SC3336_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_aunSC3336_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 = sc3336_1l_i2c_addr;
|
||||
pstI2c_data[i].u32AddrByteNum = sc3336_1l_addr_byte;
|
||||
pstI2c_data[i].u32DataByteNum = sc3336_1l_data_byte;
|
||||
}
|
||||
|
||||
switch (pstSnsState->enWDRMode) {
|
||||
case WDR_MODE_NONE:
|
||||
//Linear Mode Regs
|
||||
pstI2c_data[LINEAR_EXP_H_ADDR].u32RegAddr = SC3336_1L_EXP_H_ADDR;
|
||||
pstI2c_data[LINEAR_EXP_M_ADDR].u32RegAddr = SC3336_1L_EXP_M_ADDR;
|
||||
pstI2c_data[LINEAR_EXP_L_ADDR].u32RegAddr = SC3336_1L_EXP_L_ADDR;
|
||||
pstI2c_data[LINEAR_AGAIN_ADDR].u32RegAddr = SC3336_1L_AGAIN_ADDR;
|
||||
pstI2c_data[LINEAR_DGAIN_H_ADDR].u32RegAddr = SC3336_1L_DGAIN_H_ADDR;
|
||||
pstI2c_data[LINEAR_DGAIN_L_ADDR].u32RegAddr = SC3336_1L_DGAIN_L_ADDR;
|
||||
pstI2c_data[LINEAR_VMAX_H_ADDR].u32RegAddr = SC3336_1L_VMAX_H_ADDR;
|
||||
pstI2c_data[LINEAR_VMAX_L_ADDR].u32RegAddr = SC3336_1L_VMAX_L_ADDR;
|
||||
break;
|
||||
default:
|
||||
CVI_TRACE_SNS(CVI_DBG_ERR, "Not support WDR: %d\n", pstSnsState->enWDRMode);
|
||||
return CVI_FAILURE;
|
||||
}
|
||||
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);
|
||||
SC3336_1L_SENSOR_GET_CTX(ViPipe, pstSnsState);
|
||||
CMOS_CHECK_POINTER(pstSnsState);
|
||||
|
||||
u8SensorImageMode = pstSnsState->u8ImgMode;
|
||||
pstSnsState->bSyncInit = CVI_FALSE;
|
||||
|
||||
if (pstSensorImageMode->f32Fps <= 20) {
|
||||
if (pstSnsState->enWDRMode == WDR_MODE_NONE) {
|
||||
if (SC3336_1L_RES_IS_1296P(pstSensorImageMode->u16Width, pstSensorImageMode->u16Height)) {
|
||||
u8SensorImageMode = SC3336_1L_MODE_2304X1296P20;
|
||||
} 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;
|
||||
}
|
||||
}
|
||||
|
||||
if ((pstSnsState->bInit == CVI_TRUE) && (u8SensorImageMode == pstSnsState->u8ImgMode)) {
|
||||
/* Don't need to switch SensorImageMode */
|
||||
return CVI_FAILURE;
|
||||
}
|
||||
|
||||
pstSnsState->u8ImgMode = u8SensorImageMode;
|
||||
|
||||
return CVI_SUCCESS;
|
||||
}
|
||||
|
||||
static CVI_VOID sensor_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip)
|
||||
{
|
||||
ISP_SNS_STATE_S *pstSnsState = CVI_NULL;
|
||||
|
||||
SC3336_1L_SENSOR_GET_CTX(ViPipe, pstSnsState);
|
||||
CMOS_CHECK_POINTER_VOID(pstSnsState);
|
||||
if (pstSnsState->bInit == CVI_TRUE && g_aeSC3336_1L_MirrorFip[ViPipe] != eSnsMirrorFlip) {
|
||||
sc3336_1l_mirror_flip(ViPipe, eSnsMirrorFlip);
|
||||
g_aeSC3336_1L_MirrorFip[ViPipe] = eSnsMirrorFlip;
|
||||
}
|
||||
}
|
||||
|
||||
static CVI_VOID sensor_global_init(VI_PIPE ViPipe)
|
||||
{
|
||||
ISP_SNS_STATE_S *pstSnsState = CVI_NULL;
|
||||
const SC3336_1L_MODE_S *pstMode = CVI_NULL;
|
||||
|
||||
SC3336_1L_SENSOR_GET_CTX(ViPipe, pstSnsState);
|
||||
CMOS_CHECK_POINTER_VOID(pstSnsState);
|
||||
|
||||
pstSnsState->bInit = CVI_FALSE;
|
||||
pstSnsState->bSyncInit = CVI_FALSE;
|
||||
pstSnsState->u8ImgMode = SC3336_1L_MODE_2304X1296P20;
|
||||
pstSnsState->enWDRMode = WDR_MODE_NONE;
|
||||
pstMode = &g_astSC3336_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;
|
||||
|
||||
SC3336_1L_SENSOR_GET_CTX(ViPipe, pstSnsState);
|
||||
CMOS_CHECK_POINTER(pstSnsState);
|
||||
CMOS_CHECK_POINTER(pstRxAttr);
|
||||
|
||||
memcpy(pstRxAttr, &sc3336_1l_rx_attr, sizeof(*pstRxAttr));
|
||||
|
||||
pstRxAttr->img_size.width = g_astSC3336_1L_mode[pstSnsState->u8ImgMode].astImg[0].stSnsSize.u32Width;
|
||||
pstRxAttr->img_size.height = g_astSC3336_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 = &sc3336_1l_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 = sc3336_1l_init;
|
||||
pstSensorExpFunc->pfn_cmos_sensor_exit = sc3336_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_VOID sensor_patch_i2c_addr(CVI_S32 s32I2cAddr)
|
||||
{
|
||||
if (SC3336_1L_I2C_ADDR_IS_VALID(s32I2cAddr))
|
||||
sc3336_1l_i2c_addr = s32I2cAddr;
|
||||
}
|
||||
|
||||
static CVI_S32 sc3336_1l_set_bus_info(VI_PIPE ViPipe, ISP_SNS_COMMBUS_U unSNSBusInfo)
|
||||
{
|
||||
g_aunSC3336_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;
|
||||
|
||||
SC3336_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));
|
||||
|
||||
SC3336_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;
|
||||
|
||||
SC3336_1L_SENSOR_GET_CTX(ViPipe, pastSnsStateCtx);
|
||||
SENSOR_FREE(pastSnsStateCtx);
|
||||
SC3336_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 = SC3336_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, SC3336_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, SC3336_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, SC3336_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_au16SC3336_1L_GainMode[ViPipe] = pstInitAttr->enGainMode;
|
||||
g_au16SC3336_1L_L2SMode[ViPipe] = pstInitAttr->enL2SMode;
|
||||
|
||||
return CVI_SUCCESS;
|
||||
}
|
||||
|
||||
ISP_SNS_OBJ_S stSnsSC3336_1L_Obj = {
|
||||
.pfnRegisterCallback = sensor_register_callback,
|
||||
.pfnUnRegisterCallback = sensor_unregister_callback,
|
||||
.pfnStandby = sc3336_1l_standby,
|
||||
.pfnRestart = sc3336_1l_restart,
|
||||
.pfnMirrorFlip = sensor_mirror_flip,
|
||||
.pfnWriteReg = sc3336_1l_write_register,
|
||||
.pfnReadReg = sc3336_1l_read_register,
|
||||
.pfnSetBusInfo = sc3336_1l_set_bus_info,
|
||||
.pfnSetInit = sensor_set_init,
|
||||
.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 = sc3336_1l_probe,
|
||||
};
|
||||
|
||||
@ -0,0 +1,80 @@
|
||||
#ifndef __SC3336_1L_CMOS_EX_H_
|
||||
#define __SC3336_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 sc3336_1l_linear_regs_e {
|
||||
LINEAR_EXP_H_ADDR,
|
||||
LINEAR_EXP_M_ADDR,
|
||||
LINEAR_EXP_L_ADDR,
|
||||
LINEAR_AGAIN_ADDR,
|
||||
LINEAR_DGAIN_H_ADDR,
|
||||
LINEAR_DGAIN_L_ADDR,
|
||||
LINEAR_VMAX_H_ADDR,
|
||||
LINEAR_VMAX_L_ADDR,
|
||||
LINEAR_REGS_NUM
|
||||
};
|
||||
|
||||
typedef enum _SC3336_1L_MODE_E {
|
||||
SC3336_1L_MODE_2304X1296P20 = 0,
|
||||
SC3336_1L_MODE_LINEAR_NUM,
|
||||
SC3336_1L_MODE_2304X1296P20_WDR = SC3336_1L_MODE_LINEAR_NUM,
|
||||
SC3336_1L_MODE_NUM
|
||||
} SC3336_1L_MODE_E;
|
||||
|
||||
typedef struct _SC3336_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];
|
||||
char name[64];
|
||||
} SC3336_1L_MODE_S;
|
||||
|
||||
/****************************************************************************
|
||||
* external variables and functions *
|
||||
****************************************************************************/
|
||||
|
||||
extern ISP_SNS_STATE_S *g_pastSC3336_1L[VI_MAX_PIPE_NUM];
|
||||
extern ISP_SNS_COMMBUS_U g_aunSC3336_1L_BusInfo[];
|
||||
extern CVI_U16 g_au16SC3336_1L_GainMode[];
|
||||
extern CVI_U16 g_au16SC3336_1L_L2SMode[];
|
||||
extern CVI_U8 sc3336_1l_i2c_addr;
|
||||
extern const CVI_U32 sc3336_1l_addr_byte;
|
||||
extern const CVI_U32 sc3336_1l_data_byte;
|
||||
extern void sc3336_1l_mirror_flip(VI_PIPE ViPipe, ISP_SNS_MIRRORFLIP_TYPE_E eSnsMirrorFlip);
|
||||
extern void sc3336_1l_init(VI_PIPE ViPipe);
|
||||
extern void sc3336_1l_exit(VI_PIPE ViPipe);
|
||||
extern void sc3336_1l_standby(VI_PIPE ViPipe);
|
||||
extern void sc3336_1l_restart(VI_PIPE ViPipe);
|
||||
extern int sc3336_1l_write_register(VI_PIPE ViPipe, int addr, int data);
|
||||
extern int sc3336_1l_read_register(VI_PIPE ViPipe, int addr);
|
||||
extern int sc3336_1l_probe(VI_PIPE ViPipe);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* End of #ifdef __cplusplus */
|
||||
|
||||
|
||||
#endif /* __SC3336_1L_CMOS_EX_H_ */
|
||||
@ -0,0 +1,121 @@
|
||||
#ifndef __SC3336_1L_CMOS_PARAM_H_
|
||||
#define __SC3336_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 "sc3336_1L_cmos_ex.h"
|
||||
|
||||
static const SC3336_1L_MODE_S g_astSC3336_1L_mode[SC3336_1L_MODE_NUM] = {
|
||||
[SC3336_1L_MODE_2304X1296P20] = {
|
||||
.name = "1296p20",
|
||||
.astImg[0] = {
|
||||
.stSnsSize = {
|
||||
.u32Width = 2304,
|
||||
.u32Height = 1296,
|
||||
},
|
||||
.stWndRect = {
|
||||
.s32X = 0,
|
||||
.s32Y = 0,
|
||||
.u32Width = 2304,
|
||||
.u32Height = 1296,
|
||||
},
|
||||
.stMaxSize = {
|
||||
.u32Width = 2304,
|
||||
.u32Height = 1296,
|
||||
},
|
||||
},
|
||||
.f32MaxFps = 20,
|
||||
.f32MinFps = 0.82, /* 1350 * 20 / 0x7FFF */
|
||||
.u32HtsDef = 4938,
|
||||
.u32VtsDef = 1350,
|
||||
.stExp[0] = {
|
||||
.u16Min = 0,
|
||||
.u16Max = 1340,//vts - 10
|
||||
.u16Def = 400,
|
||||
.u16Step = 1,
|
||||
},
|
||||
.stAgain[0] = {
|
||||
.u16Min = 1024,
|
||||
.u16Max = 49807,
|
||||
.u16Def = 1024,
|
||||
.u16Step = 1,
|
||||
},
|
||||
.stDgain[0] = {
|
||||
.u16Min = 1024,
|
||||
.u16Max = 16128,
|
||||
.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, 260, 260, 260, /*8*/260, 260, 260, 260, 260, 260, 260, 260},
|
||||
{260, 260, 260, 260, 260, 260, 260, 260, /*8*/260, 260, 260, 260, 260, 260, 260, 260},
|
||||
{260, 260, 260, 260, 260, 260, 260, 260, /*8*/260, 260, 260, 260, 260, 260, 260, 260},
|
||||
{260, 260, 260, 260, 260, 260, 260, 260, /*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, 1093, 1093, 1093,
|
||||
/*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093},
|
||||
{1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093,
|
||||
/*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093},
|
||||
{1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093,
|
||||
/*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093},
|
||||
{1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093,
|
||||
/*8*/1093, 1093, 1093, 1093, 1093, 1093, 1093, 1093},
|
||||
#endif
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
struct combo_dev_attr_s sc3336_1l_rx_attr = {
|
||||
.input_mode = INPUT_MODE_MIPI,
|
||||
.mac_clk = RX_MAC_CLK_200M,
|
||||
.mipi_attr = {
|
||||
.raw_data_type = RAW_DATA_10BIT,
|
||||
.lane_id = {0, 1, 2, -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 /* __SC3336_1L_CMOS_PARAM_H_ */
|
||||
@ -0,0 +1,397 @@
|
||||
#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 "sc3336_1L_cmos_ex.h"
|
||||
|
||||
#define SC3336_1L_CHIP_ID_HI_ADDR 0x3107
|
||||
#define SC3336_1L_CHIP_ID_LO_ADDR 0x3108
|
||||
#define SC3336_1L_CHIP_ID 0xcc41
|
||||
|
||||
static void sc3336_1l_linear_1296P20_init(VI_PIPE ViPipe);
|
||||
|
||||
CVI_U8 sc3336_1l_i2c_addr = 0x30; /* I2C Address of SC3336_1L */
|
||||
const CVI_U32 sc3336_1l_addr_byte = 2;
|
||||
const CVI_U32 sc3336_1l_data_byte = 1;
|
||||
static int g_fd[VI_MAX_PIPE_NUM] = {[0 ... (VI_MAX_PIPE_NUM - 1)] = -1};
|
||||
|
||||
int sc3336_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_aunSC3336_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, sc3336_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 sc3336_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 sc3336_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 (sc3336_1l_addr_byte == 2)
|
||||
buf[idx++] = (addr >> 8) & 0xff;
|
||||
|
||||
// add address byte 0
|
||||
buf[idx++] = addr & 0xff;
|
||||
|
||||
ret = write(g_fd[ViPipe], buf, sc3336_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, sc3336_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 (sc3336_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 sc3336_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 (sc3336_1l_addr_byte == 2) {
|
||||
buf[idx] = (addr >> 8) & 0xff;
|
||||
idx++;
|
||||
buf[idx] = addr & 0xff;
|
||||
idx++;
|
||||
}
|
||||
|
||||
if (sc3336_1l_data_byte == 1) {
|
||||
buf[idx] = data & 0xff;
|
||||
idx++;
|
||||
}
|
||||
|
||||
ret = write(g_fd[ViPipe], buf, sc3336_1l_addr_byte + sc3336_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 sc3336_1l_standby(VI_PIPE ViPipe)
|
||||
{
|
||||
sc3336_1l_write_register(ViPipe, 0x0100, 0x00);
|
||||
}
|
||||
|
||||
void sc3336_1l_restart(VI_PIPE ViPipe)
|
||||
{
|
||||
sc3336_1l_write_register(ViPipe, 0x0100, 0x00);
|
||||
delay_ms(20);
|
||||
sc3336_1l_write_register(ViPipe, 0x0100, 0x01);
|
||||
}
|
||||
|
||||
void sc3336_1l_default_reg_init(VI_PIPE ViPipe)
|
||||
{
|
||||
CVI_U32 i;
|
||||
|
||||
for (i = 0; i < g_pastSC3336_1L[ViPipe]->astSyncInfo[0].snsCfg.u32RegNum; i++) {
|
||||
if (g_pastSC3336_1L[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].bUpdate == CVI_TRUE) {
|
||||
sc3336_1l_write_register(ViPipe,
|
||||
g_pastSC3336_1L[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32RegAddr,
|
||||
g_pastSC3336_1L[ViPipe]->astSyncInfo[0].snsCfg.astI2cData[i].u32Data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void sc3336_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;
|
||||
}
|
||||
|
||||
sc3336_1l_write_register(ViPipe, 0x3221, val);
|
||||
}
|
||||
|
||||
int sc3336_1l_probe(VI_PIPE ViPipe)
|
||||
{
|
||||
int nVal;
|
||||
CVI_U16 chip_id;
|
||||
|
||||
delay_ms(4);
|
||||
if (sc3336_1l_i2c_init(ViPipe) != CVI_SUCCESS)
|
||||
return CVI_FAILURE;
|
||||
|
||||
nVal = sc3336_1l_read_register(ViPipe, SC3336_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 = sc3336_1l_read_register(ViPipe, SC3336_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 != SC3336_1L_CHIP_ID) {
|
||||
CVI_TRACE_SNS(CVI_DBG_ERR, "Sensor ID Mismatch! Use the wrong sensor??\n");
|
||||
return CVI_FAILURE;
|
||||
}
|
||||
|
||||
return CVI_SUCCESS;
|
||||
}
|
||||
|
||||
void sc3336_1l_init(VI_PIPE ViPipe)
|
||||
{
|
||||
sc3336_1l_i2c_init(ViPipe);
|
||||
|
||||
//linear mode only
|
||||
sc3336_1l_linear_1296P20_init(ViPipe);
|
||||
|
||||
g_pastSC3336_1L[ViPipe]->bInit = CVI_TRUE;
|
||||
}
|
||||
|
||||
void sc3336_1l_exit(VI_PIPE ViPipe)
|
||||
{
|
||||
sc3336_1l_i2c_exit(ViPipe);
|
||||
}
|
||||
|
||||
/* 1296P20 and 1296P25 */
|
||||
static void sc3336_1l_linear_1296P20_init(VI_PIPE ViPipe)
|
||||
{
|
||||
sc3336_1l_write_register(ViPipe, 0x0103, 0x01);
|
||||
sc3336_1l_write_register(ViPipe, 0x36e9, 0x80);
|
||||
sc3336_1l_write_register(ViPipe, 0x37f9, 0x80);
|
||||
sc3336_1l_write_register(ViPipe, 0x3018, 0x1a);
|
||||
sc3336_1l_write_register(ViPipe, 0x3019, 0x0e);
|
||||
sc3336_1l_write_register(ViPipe, 0x301f, 0x14);
|
||||
sc3336_1l_write_register(ViPipe, 0x30b8, 0x33);
|
||||
sc3336_1l_write_register(ViPipe, 0x3253, 0x10);
|
||||
sc3336_1l_write_register(ViPipe, 0x325f, 0x20);
|
||||
sc3336_1l_write_register(ViPipe, 0x3301, 0x04);
|
||||
sc3336_1l_write_register(ViPipe, 0x3306, 0x50);
|
||||
sc3336_1l_write_register(ViPipe, 0x3309, 0xa8);
|
||||
sc3336_1l_write_register(ViPipe, 0x330a, 0x00);
|
||||
sc3336_1l_write_register(ViPipe, 0x330b, 0xd8);
|
||||
sc3336_1l_write_register(ViPipe, 0x3314, 0x13);
|
||||
sc3336_1l_write_register(ViPipe, 0x331f, 0x99);
|
||||
sc3336_1l_write_register(ViPipe, 0x3333, 0x10);
|
||||
sc3336_1l_write_register(ViPipe, 0x3334, 0x40);
|
||||
sc3336_1l_write_register(ViPipe, 0x335e, 0x06);
|
||||
sc3336_1l_write_register(ViPipe, 0x335f, 0x0a);
|
||||
sc3336_1l_write_register(ViPipe, 0x3364, 0x5e);
|
||||
sc3336_1l_write_register(ViPipe, 0x337c, 0x02);
|
||||
sc3336_1l_write_register(ViPipe, 0x337d, 0x0e);
|
||||
sc3336_1l_write_register(ViPipe, 0x3390, 0x01);
|
||||
sc3336_1l_write_register(ViPipe, 0x3391, 0x03);
|
||||
sc3336_1l_write_register(ViPipe, 0x3392, 0x07);
|
||||
sc3336_1l_write_register(ViPipe, 0x3393, 0x04);
|
||||
sc3336_1l_write_register(ViPipe, 0x3394, 0x04);
|
||||
sc3336_1l_write_register(ViPipe, 0x3395, 0x04);
|
||||
sc3336_1l_write_register(ViPipe, 0x3396, 0x08);
|
||||
sc3336_1l_write_register(ViPipe, 0x3397, 0x0b);
|
||||
sc3336_1l_write_register(ViPipe, 0x3398, 0x1f);
|
||||
sc3336_1l_write_register(ViPipe, 0x3399, 0x04);
|
||||
sc3336_1l_write_register(ViPipe, 0x339a, 0x0a);
|
||||
sc3336_1l_write_register(ViPipe, 0x339b, 0x3a);
|
||||
sc3336_1l_write_register(ViPipe, 0x339c, 0xa0);
|
||||
sc3336_1l_write_register(ViPipe, 0x33a2, 0x04);
|
||||
sc3336_1l_write_register(ViPipe, 0x33ac, 0x08);
|
||||
sc3336_1l_write_register(ViPipe, 0x33ad, 0x1c);
|
||||
sc3336_1l_write_register(ViPipe, 0x33ae, 0x10);
|
||||
sc3336_1l_write_register(ViPipe, 0x33af, 0x30);
|
||||
sc3336_1l_write_register(ViPipe, 0x33b1, 0x80);
|
||||
sc3336_1l_write_register(ViPipe, 0x33b3, 0x48);
|
||||
sc3336_1l_write_register(ViPipe, 0x33f9, 0x60);
|
||||
sc3336_1l_write_register(ViPipe, 0x33fb, 0x74);
|
||||
sc3336_1l_write_register(ViPipe, 0x33fc, 0x4b);
|
||||
sc3336_1l_write_register(ViPipe, 0x33fd, 0x5f);
|
||||
sc3336_1l_write_register(ViPipe, 0x349f, 0x03);
|
||||
sc3336_1l_write_register(ViPipe, 0x34a6, 0x4b);
|
||||
sc3336_1l_write_register(ViPipe, 0x34a7, 0x5f);
|
||||
sc3336_1l_write_register(ViPipe, 0x34a8, 0x20);
|
||||
sc3336_1l_write_register(ViPipe, 0x34a9, 0x18);
|
||||
sc3336_1l_write_register(ViPipe, 0x34ab, 0xe8);
|
||||
sc3336_1l_write_register(ViPipe, 0x34ac, 0x01);
|
||||
sc3336_1l_write_register(ViPipe, 0x34ad, 0x00);
|
||||
sc3336_1l_write_register(ViPipe, 0x34f8, 0x5f);
|
||||
sc3336_1l_write_register(ViPipe, 0x34f9, 0x18);
|
||||
sc3336_1l_write_register(ViPipe, 0x3630, 0xc0);
|
||||
sc3336_1l_write_register(ViPipe, 0x3631, 0x84);
|
||||
sc3336_1l_write_register(ViPipe, 0x3632, 0x64);
|
||||
sc3336_1l_write_register(ViPipe, 0x3633, 0x32);
|
||||
sc3336_1l_write_register(ViPipe, 0x363b, 0x03);
|
||||
sc3336_1l_write_register(ViPipe, 0x363c, 0x08);
|
||||
sc3336_1l_write_register(ViPipe, 0x3641, 0x38);
|
||||
sc3336_1l_write_register(ViPipe, 0x3670, 0x4e);
|
||||
sc3336_1l_write_register(ViPipe, 0x3674, 0xc0);
|
||||
sc3336_1l_write_register(ViPipe, 0x3675, 0xc0);
|
||||
sc3336_1l_write_register(ViPipe, 0x3676, 0xc0);
|
||||
sc3336_1l_write_register(ViPipe, 0x3677, 0x86);
|
||||
sc3336_1l_write_register(ViPipe, 0x3678, 0x86);
|
||||
sc3336_1l_write_register(ViPipe, 0x3679, 0x86);
|
||||
sc3336_1l_write_register(ViPipe, 0x367c, 0x48);
|
||||
sc3336_1l_write_register(ViPipe, 0x367d, 0x49);
|
||||
sc3336_1l_write_register(ViPipe, 0x367e, 0x4b);
|
||||
sc3336_1l_write_register(ViPipe, 0x367f, 0x5f);
|
||||
sc3336_1l_write_register(ViPipe, 0x3690, 0x32);
|
||||
sc3336_1l_write_register(ViPipe, 0x3691, 0x32);
|
||||
sc3336_1l_write_register(ViPipe, 0x3692, 0x42);
|
||||
sc3336_1l_write_register(ViPipe, 0x369c, 0x4b);
|
||||
sc3336_1l_write_register(ViPipe, 0x369d, 0x5f);
|
||||
sc3336_1l_write_register(ViPipe, 0x36b0, 0x87);
|
||||
sc3336_1l_write_register(ViPipe, 0x36b1, 0x90);
|
||||
sc3336_1l_write_register(ViPipe, 0x36b2, 0xa1);
|
||||
sc3336_1l_write_register(ViPipe, 0x36b3, 0xd8);
|
||||
sc3336_1l_write_register(ViPipe, 0x36b4, 0x49);
|
||||
sc3336_1l_write_register(ViPipe, 0x36b5, 0x4b);
|
||||
sc3336_1l_write_register(ViPipe, 0x36b6, 0x4f);
|
||||
sc3336_1l_write_register(ViPipe, 0x36ea, 0x0a);
|
||||
sc3336_1l_write_register(ViPipe, 0x36eb, 0x0d);
|
||||
sc3336_1l_write_register(ViPipe, 0x36ec, 0x0c);
|
||||
sc3336_1l_write_register(ViPipe, 0x36ed, 0x26);
|
||||
sc3336_1l_write_register(ViPipe, 0x370f, 0x01);
|
||||
sc3336_1l_write_register(ViPipe, 0x3722, 0x09);
|
||||
sc3336_1l_write_register(ViPipe, 0x3724, 0x41);
|
||||
sc3336_1l_write_register(ViPipe, 0x3725, 0xc1);
|
||||
sc3336_1l_write_register(ViPipe, 0x3771, 0x09);
|
||||
sc3336_1l_write_register(ViPipe, 0x3772, 0x09);
|
||||
sc3336_1l_write_register(ViPipe, 0x3773, 0x05);
|
||||
sc3336_1l_write_register(ViPipe, 0x377a, 0x48);
|
||||
sc3336_1l_write_register(ViPipe, 0x377b, 0x5f);
|
||||
sc3336_1l_write_register(ViPipe, 0x37fa, 0x0a);
|
||||
sc3336_1l_write_register(ViPipe, 0x37fb, 0x33);
|
||||
sc3336_1l_write_register(ViPipe, 0x37fc, 0x11);
|
||||
sc3336_1l_write_register(ViPipe, 0x37fd, 0x18);
|
||||
sc3336_1l_write_register(ViPipe, 0x3904, 0x04);
|
||||
sc3336_1l_write_register(ViPipe, 0x3905, 0x8c);
|
||||
sc3336_1l_write_register(ViPipe, 0x391d, 0x04);
|
||||
sc3336_1l_write_register(ViPipe, 0x3921, 0x20);
|
||||
sc3336_1l_write_register(ViPipe, 0x3926, 0x21);
|
||||
sc3336_1l_write_register(ViPipe, 0x3933, 0x80);
|
||||
sc3336_1l_write_register(ViPipe, 0x3934, 0x0a);
|
||||
sc3336_1l_write_register(ViPipe, 0x3935, 0x00);
|
||||
sc3336_1l_write_register(ViPipe, 0x3936, 0x2a);
|
||||
sc3336_1l_write_register(ViPipe, 0x3937, 0x6a);
|
||||
sc3336_1l_write_register(ViPipe, 0x3938, 0x6a);
|
||||
sc3336_1l_write_register(ViPipe, 0x39dc, 0x02);
|
||||
sc3336_1l_write_register(ViPipe, 0x3e01, 0x53);
|
||||
sc3336_1l_write_register(ViPipe, 0x3e02, 0xe0);
|
||||
sc3336_1l_write_register(ViPipe, 0x3e09, 0x00);
|
||||
sc3336_1l_write_register(ViPipe, 0x440d, 0x10);
|
||||
sc3336_1l_write_register(ViPipe, 0x440e, 0x01);
|
||||
sc3336_1l_write_register(ViPipe, 0x4509, 0x20);
|
||||
sc3336_1l_write_register(ViPipe, 0x4819, 0x09);
|
||||
sc3336_1l_write_register(ViPipe, 0x481b, 0x05);
|
||||
sc3336_1l_write_register(ViPipe, 0x481d, 0x12);
|
||||
sc3336_1l_write_register(ViPipe, 0x481f, 0x04);
|
||||
sc3336_1l_write_register(ViPipe, 0x4821, 0x0a);
|
||||
sc3336_1l_write_register(ViPipe, 0x4823, 0x05);
|
||||
sc3336_1l_write_register(ViPipe, 0x4825, 0x04);
|
||||
sc3336_1l_write_register(ViPipe, 0x4827, 0x04);
|
||||
sc3336_1l_write_register(ViPipe, 0x4829, 0x07);
|
||||
sc3336_1l_write_register(ViPipe, 0x5ae0, 0xfe);
|
||||
sc3336_1l_write_register(ViPipe, 0x5ae1, 0x40);
|
||||
sc3336_1l_write_register(ViPipe, 0x5ae2, 0x38);
|
||||
sc3336_1l_write_register(ViPipe, 0x5ae3, 0x30);
|
||||
sc3336_1l_write_register(ViPipe, 0x5ae4, 0x28);
|
||||
sc3336_1l_write_register(ViPipe, 0x5ae5, 0x38);
|
||||
sc3336_1l_write_register(ViPipe, 0x5ae6, 0x30);
|
||||
sc3336_1l_write_register(ViPipe, 0x5ae7, 0x28);
|
||||
sc3336_1l_write_register(ViPipe, 0x5ae8, 0x3f);
|
||||
sc3336_1l_write_register(ViPipe, 0x5ae9, 0x34);
|
||||
sc3336_1l_write_register(ViPipe, 0x5aea, 0x2c);
|
||||
sc3336_1l_write_register(ViPipe, 0x5aeb, 0x3f);
|
||||
sc3336_1l_write_register(ViPipe, 0x5aec, 0x34);
|
||||
sc3336_1l_write_register(ViPipe, 0x5aed, 0x2c);
|
||||
sc3336_1l_write_register(ViPipe, 0x36e9, 0x20);
|
||||
sc3336_1l_write_register(ViPipe, 0x37f9, 0x20);
|
||||
|
||||
sc3336_1l_default_reg_init(ViPipe);
|
||||
|
||||
sc3336_1l_write_register(ViPipe, 0x0100, 0x01);
|
||||
|
||||
printf("ViPipe:%d,===SC3336_1L 1296P 20fps 10bit LINE Init OK!===\n", ViPipe);
|
||||
}
|
||||
Reference in New Issue
Block a user