/******************************************************************************
Copyright (C), 2016, Hisilicon Tech. Co., Ltd.
******************************************************************************
File Name : imx327_cmos.c
Version : Initial Draft
Author : Hisilicon multimedia software group
Created : 2016/06/28
Description :
History :
1.Date : 2016/06/28
Author :
Modification: Created file
******************************************************************************/
#if !defined(__IMX327_CMOS_H_)
#define __IMX327_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 "imx327_cmos_ex.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* End of #ifdef __cplusplus */
#define IMX327_ID 327
#define SENSOR_IMX327_WIDTH 1920
#define SENSOR_IMX327_HEIGHT 1080
/****************************************************************************
* global variables *
****************************************************************************/
ISP_SNS_STATE_S *g_pastImx327[ISP_MAX_PIPE_NUM] = {HI_NULL};
#define IMX327_SENSOR_GET_CTX(dev, pstCtx) (pstCtx = g_pastImx327[dev])
#define IMX327_SENSOR_SET_CTX(dev, pstCtx) (g_pastImx327[dev] = pstCtx)
#define IMX327_SENSOR_RESET_CTX(dev) (g_pastImx327[dev] = HI_NULL)
ISP_SNS_COMMBUS_U g_aunImx327BusInfo[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 imx327_i2c_addr;
extern unsigned int imx327_addr_byte;
extern unsigned int imx327_data_byte;
typedef struct hiIMX327_STATE_S
{
HI_U8 u8Hcg;
HI_U32 u32BRL;
HI_U32 u32RHS1_MAX;
HI_U32 u32RHS2_MAX;
} IMX327_STATE_S;
IMX327_STATE_S g_astimx327State[ISP_MAX_PIPE_NUM] = {{0}};
extern void imx327_init(VI_PIPE ViPipe);
extern void imx327_exit(VI_PIPE ViPipe);
extern void imx327_standby(VI_PIPE ViPipe);
extern void imx327_restart(VI_PIPE ViPipe);
extern int imx327_write_register(VI_PIPE ViPipe, int addr, int data);
extern int imx327_read_register(VI_PIPE ViPipe, int addr);
/****************************************************************************
* local variables *
****************************************************************************/
#define IMX327_FULL_LINES_MAX (0x3FFFF)
#define IMX327_FULL_LINES_MAX_2TO1_WDR (0x8AA) // considering the YOUT_SIZE and bad frame
/*****Imx327 Register Address*****/
#define IMX327_SHS1_ADDR (0x3020)
#define IMX327_SHS2_ADDR (0x3024)
#define IMX327_GAIN_ADDR (0x3014)
#define IMX327_HCG_ADDR (0x3009)
#define IMX327_VMAX_ADDR (0x3018)
#define IMX327_HMAX_ADDR (0x301c)
#define IMX327_RHS1_ADDR (0x3030)
#define IMX327_RHS2_ADDR (0x3034)
#define IMX327_Y_OUT_SIZE_ADDR (0x3418)
#define IMX327_INCREASE_LINES (1) /* make real fps less than stand fps because NVR require*/
#define IMX327_VMAX_1080P30_LINEAR (1125+IMX327_INCREASE_LINES)
//#define IMX327_VMAX_1080P60TO30_WDR (1156+IMX327_INCREASE_LINES) //12bit
#define IMX327_VMAX_1080P60TO30_WDR (1220+IMX327_INCREASE_LINES) //10bit
//sensor fps mode
#define IMX327_SENSOR_1080P_30FPS_LINEAR_MODE (1)
#define IMX327_SENSOR_1080P_30FPS_WDR_2to1_MODE (2)
#define IMX327_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);
IMX327_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 = IMX327_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 = 62416;
pstAeSnsDft->u32MinAgain = 1024;
pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain;
pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain;
pstAeSnsDft->u32MaxDgain = 38485;
pstAeSnsDft->u32MinDgain = 1024;
pstAeSnsDft->u32MaxDgainTarget = pstAeSnsDft->u32MaxDgain;
pstAeSnsDft->u32MinDgainTarget = pstAeSnsDft->u32MinDgain;
pstAeSnsDft->u8AeCompensation = 0x38;
pstAeSnsDft->enAeExpMode = AE_EXP_HIGHLIGHT_PRIOR;
pstAeSnsDft->u32InitExposure = g_au32InitExposure[ViPipe] ? g_au32InitExposure[ViPipe] : 76151;
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 = 62416;
pstAeSnsDft->u32MinAgain = 1024;
pstAeSnsDft->u32MaxAgainTarget = pstAeSnsDft->u32MaxAgain;
pstAeSnsDft->u32MinAgainTarget = pstAeSnsDft->u32MinAgain;
pstAeSnsDft->u32MaxDgain = 38485;
pstAeSnsDft->u32MinDgain = 1024;
pstAeSns