/******************************************************************************
Copyright (C), 2016, Hisilicon Tech. Co., Ltd.
******************************************************************************
File Name : imx290_cmos.c
Version : Initial Draft
Author : Hisilicon multimedia software group
Created : 2013/11/07
Description :
History :
1.Date : 2013/11/07
Author :
Modification: Created file
******************************************************************************/
#if !defined(__IMX290_CMOS_H_)
#define __IMX290_CMOS_H_
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "hi_comm_sns.h"
#include "hi_comm_video.h"
#include "hi_sns_ctrl.h"
#include "mpi_isp.h"
#include "mpi_ae.h"
#include "mpi_awb.h"
#include "imx290_cmos_ex.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* End of #ifdef __cplusplus */
#define IMX290_ID 290
/****************************************************************************
* global variables *
****************************************************************************/
ISP_SNS_STATE_S *g_pastImx290[ISP_MAX_PIPE_NUM] = {HI_NULL};
#define IMX290_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastImx290[dev])
#define IMX290_SENSOR_SET_CTX(dev, pstCtx) (g_pastImx290[dev] = pstCtx)
#define IMX290_SENSOR_RESET_CTX(dev) (g_pastImx290[dev] = HI_NULL)
ISP_SNS_COMMBUS_U g_aunImx290BusInfo[ISP_MAX_PIPE_NUM] =
{
[0] = { .s8I2cDev = 0},
[1 ... ISP_MAX_PIPE_NUM - 1] = { .s8I2cDev = -1}
};
static ISP_FSWDR_MODE_E genFSWDRMode[ISP_MAX_PIPE_NUM] =
{
[0 ... ISP_MAX_PIPE_NUM - 1] = ISP_FSWDR_NORMAL_MODE
};
static HI_U32 gu32MaxTimeGetCnt[ISP_MAX_PIPE_NUM] = {0};
static HI_U32 g_au32InitExposure[ISP_MAX_PIPE_NUM] = {0};
static HI_U32 g_au32LinesPer500ms[ISP_MAX_PIPE_NUM] = {0};
static HI_U16 g_au16InitWBGain[ISP_MAX_PIPE_NUM][3] = {{0}};
static HI_U16 g_au16SampleRgain[ISP_MAX_PIPE_NUM] = {0};
static HI_U16 g_au16SampleBgain[ISP_MAX_PIPE_NUM] = {0};
extern const unsigned int imx290_i2c_addr;
extern unsigned int imx290_addr_byte;
extern unsigned int imx290_data_byte;
typedef struct hiIMX290_STATE_S
{
HI_U8 u8Hcg;
HI_U32 u32BRL;
HI_U32 u32RHS1_MAX;
HI_U32 u32RHS2_MAX;
} IMX290_STATE_S;
IMX290_STATE_S g_astimx290State[ISP_MAX_PIPE_NUM] = {{0}};
extern void imx290_init(VI_PIPE ViPipe);
extern void imx290_exit(VI_PIPE ViPipe);
extern void imx290_standby(VI_PIPE ViPipe);
extern void imx290_restart(VI_PIPE ViPipe);
extern int imx290_write_register(VI_PIPE ViPipe, int addr, int data);
extern int imx290_read_register(VI_PIPE ViPipe, int addr);
/****************************************************************************
* local variables *
****************************************************************************/
#define IMX290_FULL_LINES_MAX (0x3FFFF)
#define IMX290_FULL_LINES_MAX_2TO1_WDR (0x8AA) // considering the YOUT_SIZE and bad frame
#define IMX290_FULL_LINES_MAX_3TO1_WDR (0x7FC)
/*****Imx290 Register Address*****/
#define IMX290_SHS1_ADDR (0x3020)
#define IMX290_SHS2_ADDR (0x3024)
#define IMX290_SHS3_ADDR (0x3028)
#define IMX290_GAIN_ADDR (0x3014)
#define IMX290_HCG_ADDR (0x3009)
#define IMX290_VMAX_ADDR (0x3018)
#define IMX290_HMAX_ADDR (0x301c)
#define IMX290_RHS1_ADDR (0x3030)
#define IMX290_RHS2_ADDR (0x3034)
#define IMX290_Y_OUT_SIZE_ADDR (0x3418)
#define IMX290_INCREASE_LINES (1) /* make real fps less than stand fps because NVR require*/
#define IMX290_VMAX_1080P30_LINEAR (1125+IMX290_INCREASE_LINES)
#define IMX290_VMAX_720P60TO30_WDR (750+IMX290_INCREASE_LINES)
#define IMX290_VMAX_1080P60TO30_WDR (1220+IMX290_INCREASE_LINES)
#define IMX290_VMAX_1080P120TO30_WDR (1125+IMX290_INCREASE_LINES)
//sensor fps mode
#define IMX290_SENSOR_1080P_30FPS_LINEAR_MODE (1)
#define IMX290_SENSOR_1080P_30FPS_3t1_WDR_MODE (2)
#define IMX290_SENSOR_1080P_30FPS_2t1_WDR_MODE (3)
#define IMX290_SENSOR_720P_30FPS_2t1_WDR_MODE (4)
#define IMX290_RES_IS_720P(w, h) ((w) <= 1280 && (h) <= 720)
#define IMX290_RES_IS_1080P(w, h) ((w) <= 1920 && (h) <= 1080)
static HI_S32 cmos_get_ae_default(VI_PIPE ViPipe, AE_SENSOR_DEFAULT_S *pstAeSnsDft)
{
ISP_SNS_STATE_S *pstSnsState = HI_NULL;
CMOS_CHECK_POINTER(pstAeSnsDft);
IMX290_SENSOR_GET_CTX(ViPipe, pstSnsState);
CMOS_CHECK_POINTER(pstSnsState);
memset(&pstAeSnsDft->stAERouteAttr, 0, sizeof(ISP_AE_ROUTE_S));
pstAeSnsDft->u32FullLinesStd = pstSnsState->u32FLStd;
pstAeSnsDft->u32FlickerFreq = 50 * 256;
pstAeSnsDft->u32FullLinesMax = IMX290_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];
}
pstAeSnsDft->enMaxIrisFNO = ISP_IRIS_F_NO_1_0;
pstAeSnsDft->enMinIrisFNO = ISP_IRIS_F_NO_32_0;
pstAeSnsDft->bAERouteExValid = HI_FALSE;
pstAeSnsDft->stAERouteAttr.u32TotalNum = 0;
pstAeSnsDft->stAERouteAttrEx.u32TotalNum = 0;
switch (pstSnsState->enWDRMode)
{
default:
case WDR_MODE_NONE: /*linear mode*/
pstAeSnsDft->au8HistThresh[0] = 0xd;
pstAeSnsDft->au8HistThresh[1] = 0x28;
pstAeSnsDft->au8HistThresh[2] = 0x60;
pstAeSnsDft->au8HistThresh[3] = 0x80;
pstAeSnsDft->u32MaxAgain = 62564;
pstAeSnsDft->u32MinAgain = 1024;
pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain;
pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain;
pstAeSnsDft->u32MaxDgain = 38577;
pstAeSnsDft->u32MinDgain = 1024;
pstAeSnsDft->u32MaxDgainTarget = 20013;
pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain;
pstAeSnsDft->u8AeCompensation = 0x38;
pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR;
pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 148859;
pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 2;
pstAeSnsDft->u32MinIntTime = 1;
pstAeSnsDft->u32MaxIntTimeTarget = 65535;
pstAeSnsDft->u32MinIntTimeTarget = 1;
break;
case WDR_MODE_2To1_FRAME:
pstAeSnsDft->au8HistThresh[0] = 0xC;
pstAeSnsDft->au8HistThresh[1] = 0x18;
pstAeSnsDft->au8HistThresh[2] = 0x60;
pstAeSnsDft->au8HistThresh[3] = 0x80;
pstAeSnsDft->u8AeCompensation = 0x18;
pstAeSnsDft->enAeExpMode = AE_EXP_LOWLIGHT_PRIOR;
pstAeSnsDft->u32MaxIntTime = pstSnsState->u32FLStd - 2;
pstAeSnsDft->u32MinIntTime = 1;
pstAeSnsDft->u32MaxIntTimeTarget = 65535;
pstAeSnsDft->u32MinIntTimeTarget = pstAeSnsDft->u32MinIntTime;
pstAeSnsDft->u32MaxAgain = 62564;
pstAeSnsDft->u32MinAgain = 1024;
pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain;
pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain;
pstAeSnsDft->u32MaxDgain = 38577;
pstAeSnsDft->u32MinDgain = 1024;