/* SPDX-License-Identifier: LGPL-2.1-only OR BSD-3-Clause */
/******************************************************************************
 *
 * This file is provided under a dual license.  When you use or
 * distribute this software, you may choose to be licensed under
 * version 2.1 of the GNU Lesser General Public License
 * ("LGPLv2.1 License") or BSD License.
 *
 * LGPLv2.1 License
 *
 * Copyright(C) 2019 MediaTek Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of version 2.1 of the GNU Lesser General Public
 * License as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html for more
 * details.
 *
 * BSD LICENSE
 *
 * Copyright(C) 2019 MediaTek Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  * Neither the name of the copyright holder nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *****************************************************************************/

#include "general.h"
#include "util.h"
#include "pe_if.h"
#include "drv_nr.h"
#include "drv_nr_int.h"
#include "video_def.h"
#include "drv_video.h"
#include "api_backlt.h"
#include "drv_contrast.h"
#include "api_eep.h"
#include "eepdef.h"
#include "drv_tvd.h"
#include "vdo_misc.h"
#include "vdp_drvif.h"
#include "vdp_if.h"
#include "drv_scpos.h"
#include "eeprom_if.h"
#include "u_drv_cust.h"
#include "drvcust_if.h"
#include "drv_hdtv.h"
#include "drv_mpeg.h"
#include "x_debug.h"
#include "x_hal_5381.h"
#include "drv_vdoclk.h"
#include "drv_adcset.h"
#include "drv_autocolor.h"
#include "source_select.h"
#include "drv_pq_cust.h"
#include "drv_dvi.h"
#include "drv_hdmi.h"
#include "srm_drvif.h"
#include "drv_meter.h"
#include "drv_od.h"
#include "nptv_debug.h"
#include "panel.h"
#include "drv_default.h"
#include "drv_ldmspi.h"
#include "drv_upscaler.h"
#include "drv_mjc_if.h"
#include "hw_od.h"
#include "hw_lcdim_v2.h"
#include "drv_scaler.h"
#include "osd_drvif.h"
#include "vdo_rm.h"
#include "drv_tdtv.h"

#if defined(CC_SUPPORT_4K2K)
#include "sony_video_drv_4k2k.c"
#else
#include "sony_video_drv.c"
#endif
#include "hw_ycproc.h"
#include "hw_ttd.h"
#include "hw_scpip_pq.h"
#include "hw_mjc.h"
#include "hw_sw.h"

#include "drv_MapleGetApiAp.c"
#include "drv_MapleGetApiSys.c"
#include "drv_MapleSetApi.c"
#include "drv_MapleAudGetApi.c"
#include "MapleApi_cmd.c"


#ifdef CC_PowerCons_Ctrl
#include "sony_PowerConsumptionCtrl.h"
#endif

#include "ATV/priv_drv/sony_drv_inc/pq_gamma_if.h"
#include "ATV/priv_drv/sony_drv_inc/Sony_drv_cb.h"
#include "ATV/priv_drv/sony_drv_inc/wb_pbm.h"

typedef enum
{
    E_NR_CUST_ADAP_NL    = 0,
    E_NR_CUST_ADAP_XNR   = 1,
    E_NR_CUST_ADAP_RNR   = 2,
    E_NR_CUST_ADAP_MOANR = 3,
    E_NR_CUST_ADAP_FUNC_MAX
} E_NR_DFT_ADAP_FUNC;


typedef enum
{
    E_SCE_VIVID = 0,
    E_SCE_ST_OFF,
    E_SCE_ST_LOW,
    E_SCE_ST_MID,
    E_SCE_ST_HIGH,
    E_SCE_CI_LOW,
    E_SCE_CI_MID,
    E_SCE_CI_HIGH,
    E_SCE_SP_LOW,
    E_SCE_SP_MID,
    E_SCE_SP_HIGH,
    E_SCE_PH_LOW,
    E_SCE_PH_MID,
    E_SCE_PH_HIGH,
} E_CUST_SCE_MODE;

typedef enum
{
    E_SCE_UI_OFF = 0,
    E_SCE_UI_LOW,
    E_SCE_UI_MID,
    E_SCE_UI_HIGH,
} E_CUST_SCE_UI_MODE;

typedef enum
{
    E_SMART_PIC_VIVID = 0,
    E_SMART_PIC_STANDARD, 
    E_SMART_PIC_CUSTOM, 
    E_SMART_PIC_CINEMA_PRO, 
    E_SMART_PIC_CINEMA_HOME,
    E_SMART_PIC_SPORTS, 
    E_SMART_PIC_ANIMATION, 
    E_SMART_PIC_PHOTO_VIVID,
    E_SMART_PIC_PHOTO_STANDARD, 
    E_SMART_PIC_PHOTO_CUSTOM, 
    E_SMART_PIC_GAME, 
    E_SMART_PIC_GRAPHICS,
    E_SMART_PIC_RESERVE1,
} E_CUST_SMART_PIC_MODE;

typedef enum
{
    E_CT_COOL = 0,
    E_CT_NEUTRAL,
    E_CT_WARM1,
    E_CT_WARM2,
    E_CT_PHOTO,
    E_CT_MAX,
} E_CUST_COLOR_TEMP_MODE;

enum
{
	DEMO_PQ_OFF			= 0,
	DEMO_PQ_ON_RIGHT 	= 1,
	DEMO_PQ_ON_LEFT 	= 2
};

typedef struct _WB_TEST_PTN_STATUS{
    UINT8 u1PtnOnOff;
    UINT8 u1BlueStretchOnOff;
    UINT8 u1XvYccOnOff;
    UINT8 u1OPCOnOff;
    UINT8 u1MuteOnOff;  
    UINT8 u1LDOnOff;
    UINT8 u1PreDitherSel;
    UINT8 u1PostDitherSel;
    UINT8 u1ODOnOff;
}WB_TEST_PTN_STATUS;

extern INT32 COLOR_TRANSFORM_ADJ[15];

//DEMO modules

#define DEMO_TDC			1	<<	0	//driver not support now
#define DEMO_MDDI			1	<<	1	//driver not support now
#define DEMO_HSHARP			1	<<	2	//driver not support now
#define DEMO_2DNR			1	<<	3
#define DEMO_3DNR			1	<<	4
#define DEMO_TDSHARP		1	<<	5
#define DEMO_COLOR			1	<<	6
#define DEMO_ECTI			1	<<	7

static UINT8 gbSmartPicIndex = 0;
static UINT8 gbSceUi = 0;
static UINT8 gbOdUi = 0;
static UINT8 gbGammaUi = 0;
static UINT16 gu2RawDataTblIndex = 0;
static UINT16 gu2RawDataCaseIndex = 0;
BOOL fgCriticalSection = SV_FALSE;
BOOL fgYUVout = SV_FALSE;


UINT8* SRS_Table_A = NULL;
UINT8* SRS_Table_B = NULL;

AUTO_COLORTEMP_SETS_INFO_T stCTInfo;
UINT32 bi1GammaOfst;
extern MMAppInfo sMMAppInfo;

UINT8 	u1BePath[3];
UINT8 u1Connet[3] = {SV_FALSE,SV_FALSE,SV_FALSE};

extern UINT16 pPedestalMatrixISR[15];

UINT16 DRVCUST_pMecbethMatrix[15]={0};
UINT16 u2WBGain[SV_RGB_RGB] = {0x200, 0x200, 0x200};
UINT16 u2WBOfst[SV_RGB_RGB] = {0x00, 0x00, 0x00};
UINT8 bWBFlatPreOnoff = SV_FALSE;

#define MAX_COEF_TPYE 5
#define MAX_VC_COEF_IDX    11
#define MAX_VY_COEF_IDX    9
#define MAX_VC_COEF_HD_IDX    5
#define MAX_VY_COEF_HD_IDX    5

#define EN_PEDASTAL_IN_SUB_PATH 1

#define EEPROM_GAMMA_CCT_ADD 0x3200
#define GAMMA_BYTES		342	//57 * 3 *2
#define CUSTOM_GAMMA_BASE 0x3C00
#define GAMMA_MAGIC00 0x10
#define GAMMA_MAGIC01 0x20

#define GAMMA_CTRL_POINT_NUM_PBM 57
#define GAMMA_CTRL_POINT_NUM2_PBM 33		//For salvia
#define GAMMA_CTRL_POINT_NUM_TRACK 11
#define GAMMA_10P_OFST_CTRL_POINT_NUM 11

#define NUM_OF_TEMP_GAMMA 0x80

static UINT8 bGammaInit = SV_FALSE;

extern UINT16 u2GammaDecodedTable[3][GAMMA_INDEX];
extern INT32 _iUsedCtlValue_R[33], _iUsedCtlValue_G[33], _iUsedCtlValue_B[33];
extern INT32 _iUsedColorTemp;
extern UINT8 u1IsForceWBEepReload(void);

static SONY_DRV_CB_ST  callback_funcs;

UINT8 bColorIndex=0xFF;
UINT8 bPreGammaSel=0xFF;
UINT16 wHwGammaCurve[SV_RGB_RGB][GAMMA_INDEX];
INT16 i2WB10PUIValue[3][11] ={0};
UINT8 bVideoRangeMode = DRV_CUSTOM_HDMI_RANGE_LIMIT;

static UINT8 bGammaLinear = SV_FALSE;

static UINT8 u1WB_GAM_RGB[SV_RGB_RGB][GAMMA_CTRL_POINT_NUM_TRACK];
static UINT8 u1WB_OFST_RGB[E_CT_MAX][SV_RGB_RGB][GAMMA_CTRL_POINT_NUM_TRACK];
static UINT8 u1WB_GAM_GAIN[GAMMA_CTRL_POINT_NUM_TRACK];
static UINT16 u2WB_INP_LVL[GAMMA_CTRL_POINT_NUM_TRACK];
static UINT16 u2WB_INP_LVL_Fac[GAMMA_CTRL_POINT_NUM_TRACK];
static UINT8 u1WB_BASE_GAIN_RGB_EEP[E_CT_MAX][SV_RGB_RGB];

#ifdef CC_MAPLE_CUST_DRV
static UINT8 u110POfst[E_CT_MAX][SV_RGB_RGB][GAMMA_10P_OFST_CTRL_POINT_NUM];
static UINT8 u1Gam10PGain[GAMMA_10P_OFST_CTRL_POINT_NUM];
static UINT16 u2Inplvl10P[GAMMA_10P_OFST_CTRL_POINT_NUM];
static INT32 i4Ctrl10POfst[SV_RGB_RGB][GAMMA_10P_OFST_CTRL_POINT_NUM];
static INT32 i4Gam10POfst[SV_RGB_RGB][GAMMA_INDEX];
#endif
static UINT8 PreHDRType = SV_HDR_TYPE_SDR;
UINT8 IsHDRFlg = SV_FALSE;
UINT8 bIsMetaData = SV_FALSE;
UINT8 bIsSeamless = SV_FALSE;
VP9_HDR_TYPE_E eVP9HDRType = SV_VP9_HDR_TYPE_NONE;

#ifdef CC_MAPLE_CUST_DRV
//For Sakura
static UINT16 u2CtlPos_PBM[GAMMA_CTRL_POINT_NUM_PBM] = {0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E,
												     	0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x1E,
												  	 	0x20, 0x22, 0x24, 0x26, 0x28, 0x2A, 0x2C, 0x2E,
												  	 	0x30, 0x32, 0x34, 0x36, 0x38, 0x3A, 0x3C, 0x3E,
												   	 	0x40, 0x48, 0x50, 0x58, 0x60, 0x68, 0x70, 0x78,
												   	 	0x80, 0x88, 0x90, 0x98, 0xA0, 0xA8, 0xB0, 0xB8,
												   	 	0xC0, 0xC8, 0xD0, 0xD8, 0xE0, 0xE8, 0xF0, 0xF8, 0x100}; 
#else
//For Salvia
static UINT16 u2CtlPos_PBM[GAMMA_CTRL_POINT_NUM2_PBM] = {0x00, 0x04, 0x08, 0x0B, 0x10, 0x14, 0x18, 0x1C,
														  0x20, 0x24, 0x28, 0x2C, 0x30, 0x34, 0x38, 0x3C,
														  0x40, 0x4C, 0x58, 0x64, 0x70, 0x7C, 0x88, 0x94,
														  0xA0, 0xAC, 0xB8, 0xC4, 0xD0, 0xDC, 0xE8, 0xF4, 0x100};
#endif
//257 base value for tracking mode
/*
static INT32 u4WB_BASE_VALUE[GAMMA_INDEX] = {0,   16,   32,   48,   64,   80,   96,  112,  128,  144,  160,  176,  192,  208,  224,  240,
										   256,  272,  288,  304,  320,  336,  352,  368,  384,  400,  416,  432,  448,  464,  480,  496,
										   512,  528,  544,  560,  576,  592,  608,  624,  640,  656,  672,  688,  704,  720,  736,  752,
										   768,  784,  800,  816,  832,  848,  864,  880,  896,  912,  928,  944,  960,  976,  992, 1008,
										  1024, 1040, 1056, 1072, 1088, 1104, 1120, 1136, 1152, 1168, 1184, 1200, 1216, 1232, 1248, 1264,
										  1280, 1296, 1312, 1328, 1344, 1360, 1376, 1392, 1408, 1424, 1440, 1456, 1472, 1488, 1504, 1520,
										  1536, 1552, 1568, 1584, 1600, 1616, 1632, 1648, 1664, 1680, 1696, 1712, 1728, 1744, 1760, 1776,
										  1792, 1808, 1824, 1840, 1856, 1872, 1888, 1904, 1920, 1936, 1952, 1968, 1984, 2000, 2016, 2032,
										  2048, 2064, 2080, 2096, 2112, 2128, 2144, 2160, 2176, 2192, 2208, 2224, 2240, 2256, 2272, 2288,
										  2304, 2320, 2336, 2352, 2368, 2384, 2400, 2416, 2432, 2448, 2464, 2480, 2496, 2512, 2528, 2544,
										  2560, 2576, 2592, 2608, 2624, 2640, 2656, 2672, 2688, 2704, 2720, 2736, 2752, 2768, 2784, 2800,
										  2816, 2832, 2848, 2864, 2880, 2896, 2912, 2928, 2944, 2960, 2976, 2992, 3008, 3024, 3040, 3056,
										  3072, 3088, 3104, 3120, 3136, 3152, 3168, 3184, 3200, 3216, 3232, 3248, 3264, 3280, 3296, 3312,
										  3328, 3344, 3360, 3376, 3392, 3408, 3424, 3440, 3456, 3472, 3488, 3504, 3520, 3536, 3552, 3568,
										  3584, 3600, 3616, 3632, 3648, 3664, 3680, 3696, 3712, 3728, 3744, 3760, 3776, 3792, 3808, 3824,
										  3840, 3856, 3872, 3888, 3904, 3920, 3936, 3952, 3968, 3984, 4000, 4016, 4032, 4048, 4064, 4080, 4096};

*/
const  UINT16 PANEL_GAMMA_REMAP_TBL[]=
{
    #include "maple_GammaRemapTbl.h"
};

static INT32 i4DynGammaIndex=0x40;

enum
{
    SCAL_COEF_HY,
    SCAL_COEF_HC,
    SCAL_COEF_VY,
    SCAL_COEF_VC,
    SCAL_COEF_MAX,
};


UINT8 u1SatHistBoundary[] = {5, 13, 21, 29, 37, 45, 58}; //{1, 4, 9, 16, 25, 36, 49};


#ifdef CC_PowerCons_Ctrl
void DRVCUST_PowerConsCtrlStatusCheck(void);
#endif

#ifdef DRV_SUPPORT_CUST_ANR
static NR_ADAP_WREG_BASE_T _rCustNrWRegState[E_NR_CUST_ADAP_FUNC_MAX+1] =
{
    {fgDrvAnrAutoOnNL,  fgDrvAnrFromSWOff, vDrvAnrSetNL,  vDrvAnrResetNL,  NR_WR_ST_IDLE},
    {fgDrvAnrAutoOnXNR, fgDrvAnrFromSWOff, vDrvAnrSetXNR, vDrvAnrResetXNR, NR_WR_ST_IDLE},
    {fgDrvAnrAutoOnRNR, fgDrvAnrFromSWRNR, vDrvAnrSetRNR, vDrvAnrResetRNR, NR_WR_ST_IDLE},
    {fgDrvAnrAutoOnMOANR, fgDrvAnrFromSWMOANR, vDrvAnrSetMOANR, vDrvAnrResetMOANR, NR_WR_ST_IDLE},
    {NULL, NULL, NULL, NULL, NR_WR_ST_NULL}
};

static void DRVCUST_AnrProc(const NR_NM_STA_T* prNmSta, const NR_NM_ANA_T* prNmAna)
{
    UINT32 u4NoiseLvl;
    UINT32 u4MaxNL;

    u4MaxNL = _SWR(NR_NM_03, MAX_NOISE_LVL);
    u4NoiseLvl = ((_SWR(NR_NM_00, FORCE_NOISE_LVL_EN)) ? _SWR(NR_NM_00, FORCE_NOISE_LVL) : prNmAna->u1NoiseLevel);
    u4NoiseLvl = MIN(u4NoiseLvl, u4MaxNL);

    if (_rCustNrWRegState[E_NR_CUST_ADAP_NL].fgAutoOn())
    {
        vDrvAnrNLProc(u4NoiseLvl);
    }

    if (_rCustNrWRegState[E_NR_CUST_ADAP_XNR].fgAutoOn())
    {
        vDrvAnrDCAlphaProc(u4NoiseLvl);
    }

    if (_rCustNrWRegState[E_NR_CUST_ADAP_RNR].fgAutoOn())
    {
        vDrvAnrRnrProc(u4NoiseLvl);
    }

    if (_rCustNrWRegState[E_NR_CUST_ADAP_MOANR].fgAutoOn())
    {
        vDrvAnrMoAnrProc(u4NoiseLvl, prNmAna->u1MoIdx);
    }
}
#endif

//extern PE_UI_RANGE_TBL rPEUITable;

UINT16 vApiFlashPqGetSceId()
{
    if (gbSceUi == E_SCE_UI_OFF)
    {
        return E_SCE_ST_OFF;
    }    
    
    else if (gbSmartPicIndex == E_SMART_PIC_VIVID)
    {
        if (gbSceUi == E_SCE_UI_LOW)
            return E_SCE_ST_LOW;
        else if (gbSceUi == E_SCE_UI_MID)
            return E_SCE_ST_MID;
        else    
            return E_SCE_VIVID;
    }
    else if ((gbSmartPicIndex == E_SMART_PIC_STANDARD) || (gbSmartPicIndex == E_SMART_PIC_CUSTOM))
    {
        if (gbSceUi == E_SCE_UI_LOW)
            return E_SCE_ST_LOW;
        else if (gbSceUi == E_SCE_UI_MID)
            return E_SCE_ST_MID;
        else
            return E_SCE_ST_HIGH;        
    }
    else if ((gbSmartPicIndex == E_SMART_PIC_CINEMA_PRO) || (gbSmartPicIndex == E_SMART_PIC_CINEMA_HOME)|| (gbSmartPicIndex == E_SMART_PIC_RESERVE1))
    {        
        if (gbSceUi == E_SCE_UI_LOW)
            return E_SCE_CI_LOW;
        else if (gbSceUi == E_SCE_UI_MID)
            return E_SCE_CI_MID;
        else
            return E_SCE_CI_HIGH;        
    }
    else if ((gbSmartPicIndex == E_SMART_PIC_SPORTS) || (gbSmartPicIndex == E_SMART_PIC_ANIMATION) 
        || (gbSmartPicIndex == E_SMART_PIC_GAME) || (gbSmartPicIndex == E_SMART_PIC_GRAPHICS)) 
    {        
        if (gbSceUi == E_SCE_UI_LOW)
            return E_SCE_SP_LOW;
        else if (gbSceUi == E_SCE_UI_MID)
            return E_SCE_SP_MID;
        else
            return E_SCE_SP_HIGH;        
    }    
    else if ((gbSmartPicIndex == E_SMART_PIC_PHOTO_VIVID) || (gbSmartPicIndex == E_SMART_PIC_PHOTO_STANDARD) 
        || (gbSmartPicIndex == E_SMART_PIC_PHOTO_CUSTOM)) 
    {        
        if (gbSceUi == E_SCE_UI_LOW)
            return E_SCE_PH_LOW;
        else if (gbSceUi == E_SCE_UI_MID)
            return E_SCE_PH_MID;
        else
            return E_SCE_PH_HIGH;
    }
    else
    {        
        LOG(0, "Unknown SCE : SmartPic  %d    SCE  %d\n", gbSmartPicIndex, gbSceUi);
        return E_SCE_VIVID;
    }
}

UINT16 vApiFlashPqGetMinSceId()
{
    //This is sample code : SCE ID can be decided 
    //by panel id , ui setting, picture mode .....
    //UINT8 bPanelIdx = GetCurrentPanelIndex();

    return (1);
}

void vApiFlashPqSetSceId(UINT8 bIndex)
{
    gbSceUi = bIndex;
}

UINT16 vApiFlashPqGetOdId(void)
{
    //UINT8 bPanelIdx = GetCurrentPanelIndex();   
    
    return gbOdUi;
}

void vApiFlashPqSetOdId(UINT8 bIndex)
{
    gbOdUi = bIndex;
}

UINT16 vApiFlashPqGetGammaId()
{
    return gbGammaUi;
}

void vApiFlashPqSetGammaId(UINT8 bIndex)
    {
    if (bIndex == D_AP_PIC_COL_TMP_COOL)
    {
    	gbGammaUi = E_CT_COOL;
    }
	else if (bIndex == D_AP_PIC_COL_TMP_NATURAL)
    {
    	gbGammaUi = E_CT_NEUTRAL;
    }
	else if (bIndex == D_AP_PIC_COL_TMP_WARM)
    {
        if ((gbSmartPicIndex == D_AP_PIC_MODE_PHOTO_VIVID) || (gbSmartPicIndex == D_AP_PIC_MODE_PHOTO_STD) || (gbSmartPicIndex == D_AP_PIC_MODE_PHOTO_CUST))
    {
            gbGammaUi = E_CT_WARM2;
    }    
        else
        {
            gbGammaUi = E_CT_WARM1;
    }    
    }
	else if (bIndex == D_AP_PIC_COL_TMP_EXPERT1)
    {
        if ((gbSmartPicIndex == D_AP_PIC_MODE_PHOTO_VIVID) || (gbSmartPicIndex == D_AP_PIC_MODE_PHOTO_STD) || (gbSmartPicIndex == D_AP_PIC_MODE_PHOTO_CUST))
        {
            gbGammaUi = E_CT_PHOTO;
        }
        else
        {
            gbGammaUi = E_CT_WARM2;
    }
    }
	else if (bIndex == D_AP_PIC_COL_TMP_EXPERT2)
    {
        if ((gbSmartPicIndex == D_AP_PIC_MODE_PHOTO_VIVID) || (gbSmartPicIndex == D_AP_PIC_MODE_PHOTO_STD) || (gbSmartPicIndex == D_AP_PIC_MODE_PHOTO_CUST))
        {
            gbGammaUi = E_CT_PHOTO;
        }
        else
        {
            gbGammaUi = E_CT_WARM2;
        }
    }    
    else
    {        
        LOG(0, "Unknown Gamma : SmartPic  %d    Gamma  %d\n", gbSmartPicIndex, gbGammaUi);
        gbGammaUi = E_CT_COOL;
}
}

UINT16 vApiFlashPqGetQtyId(UINT8 bIndex)
{
	UNUSED(bIndex);

	return (0);

}


void vApiFlashPqSetSmartPicId(UINT8 bIndex)
{
#if 0    
#ifndef CC_DRIVER_PROGRAM    
	UINT8 i4UiIndex, j;

	Printf("Smart Pic XXXXX %d\n", bIndex);
#endif
#endif
    gbSmartPicIndex = bIndex;

#if 0
#ifndef CC_DRIVER_PROGRAM
#ifdef __KERNEL__   
	ASSERT(rPEUITable.ptUiPicMinMaxDftTbl!=NULL && gbSmartPicIndex<rPEUITable.bSmartPicNum);   
	// update all source UI default table, since the table is same
	for (i4UiIndex = 0; i4UiIndex < (UINT8)EVDP_VIS_MAX; i4UiIndex++)
	{
		for(j=0; j< rPEUITable.bUIPQItemNum; j++)
		{
			if(rPEUITable.ptUiPicMinMaxDftTbl[gbSmartPicIndex][j].rPQItemType >=PE_ARG_BRIGHTNESS &&
				rPEUITable.ptUiPicMinMaxDftTbl[gbSmartPicIndex][j].rPQItemType < PE_ARG_NS)
			{
/*				printf("rPEUITable.ptUiPicMinMaxDftTbl[%d][%d].rPQItemType| %x, Min %x, Max %x, Dft %x \n", gbSmartPicIndex,j,rPEUITable.ptUiPicMinMaxDftTbl[gbSmartPicIndex][j].rPQItemType,
					rPEUITable.ptUiPicMinMaxDftTbl[gbSmartPicIndex][j].rPQItemRange.i4Min, rPEUITable.ptUiPicMinMaxDftTbl[gbSmartPicIndex][j].rPQItemRange.i4Max,
					rPEUITable.ptUiPicMinMaxDftTbl[gbSmartPicIndex][j].rPQItemRange.i4Dft);
*/
				PE_SetUiRange(i4UiIndex, rPEUITable.ptUiPicMinMaxDftTbl[gbSmartPicIndex][j].rPQItemType, 
														 &(rPEUITable.ptUiPicMinMaxDftTbl[gbSmartPicIndex][j].rPQItemRange));
			}
		}
}
#endif
#endif
#endif
}

UINT8 vApiFlashPqGetSmartPicId()
{
	if(gbSmartPicIndex == E_SMART_PIC_RESERVE1)
	{
		return E_SMART_PIC_CINEMA_PRO;
	}
	else
	{
    	return (gbSmartPicIndex);
	}
}

UINT8 DRVCUST_GetUISmartPicId()
{
    return (gbSmartPicIndex);
}


UINT16 u2ApiFlashPqGetRawDataTblId(void)
{
    return gu2RawDataTblIndex;
}

UINT16 u2ApiFlashPqGetRawDataCaseId(void)
{
    return gu2RawDataCaseIndex;
}

void vApiFlashPqSetRawDataTblId(UINT16 u2Index)
{
    gu2RawDataTblIndex = u2Index;
}

void vApiFlashPqSetRawDataCaseId(UINT16 u2Index)
{
    gu2RawDataCaseIndex = u2Index;
}

UINT8 bApiFlashPqUpdateRawDataEx(UINT16 u2TblId, UINT16 u2CaseId)
{
    vApiFlashPqSetRawDataTblId(u2TblId);
    vApiFlashPqSetRawDataCaseId(u2CaseId);
	
    return bApiFlashPqUpdateRawData();
}

void DRVCUST_SetMacbethOnOff(UINT8 bOnoff, UINT16 u2Ylvl, UINT16 u2Ulvl, UINT16 u2Vlvl)
{
	if(bOnoff)
	{
		memset(DRVCUST_pMecbethMatrix, 0x00, sizeof(DRVCUST_pMecbethMatrix));
		DRVCUST_pMecbethMatrix[12] = u2Ylvl;
		DRVCUST_pMecbethMatrix[13] = u2Ulvl;
		DRVCUST_pMecbethMatrix[14] = u2Vlvl;
		
		x_memcpy(pPedestalMatrixISR, DRVCUST_pMecbethMatrix, sizeof(DRVCUST_pMecbethMatrix));
        vApiRegisterVideoEvent(PE_EVENT_COLOR_TRANSFORM, SV_VP_MAIN, SV_ON);
	}
	else
	{
		vVdoSetColorTransform(SV_VP_MAIN);
	}
}

void cbSony_GammaOSDControl(void* pvArg);

void DRVCUST_SetWBTestPtnOnOff(UINT8 bOnoff, UINT16 u2Rlvl, UINT16 u2Glvl, UINT16 u2Blvl)
{
    static WB_TEST_PTN_STATUS WBTestPtnStatus = {SV_OFF, SV_OFF, SV_OFF, SV_OFF, SV_OFF, SV_OFF, SV_OFF};
    static INT32 DRVCUST_pWBTestPtnMatrix[15]={0};
    UINT8 u1bOSDOnOff;
    
	if(bOnoff)
	{
	    if(SV_OFF == WBTestPtnStatus.u1PtnOnOff)
	    {
            //get status
            WBTestPtnStatus.u1PtnOnOff = SV_ON;
            
            //disable blue stretch
            WBTestPtnStatus.u1BlueStretchOnOff = bDrvGetBlueStretchOnOff();
            if(WBTestPtnStatus.u1BlueStretchOnOff)
            {
                vDrvSetBlueStretchOnOff(SV_VP_MAIN, SV_OFF);
            }

            
            //disable xvycc
            WBTestPtnStatus.u1XvYccOnOff = bDrvGetxvYCCOnOff();
            if(WBTestPtnStatus.u1XvYccOnOff)
            {
                vDrvxvYCCOnOff(SV_OFF);
            }
            
            //disable OPC
            WBTestPtnStatus.u1OPCOnOff = IO32ReadFldAlign(DBL_00, DBL_ENABLE);
            if(WBTestPtnStatus.u1OPCOnOff)
            {
                vIO32WriteFldAlign(DBL_00, SV_OFF, DBL_ENABLE);
            }
            
            //disable Mute
            WBTestPtnStatus.u1MuteOnOff = fgMainMuteOn();
            if(WBTestPtnStatus.u1MuteOnOff)
            {
                vDrvMainMute(SV_OFF);
            }

            if(3 == IO32ReadFldAlign(OSTG_01, REG_OP_SEL))
            {
                #ifdef CC_MAPLE_CUST_DRV
                //disable LD
                WBTestPtnStatus.u1LDOnOff = !IO32ReadFldAlign(LD2_MODE_00, C_LD_BYPASS);
                vIO32WriteFldAlign(LD2_MODE_00, SV_TRUE, C_LD_BYPASS);
                #endif

                //disable PreDither
                WBTestPtnStatus.u1PreDitherSel = IO32ReadFldAlign(OS_DITHER_02, DRMOD_R);
                vIO32WriteFldAlign(OS_DITHER_02, 0, DRMOD_R);

                //disable PostDither
                WBTestPtnStatus.u1PostDitherSel = IO32ReadFldAlign(OS_DITHER_05, REG_DRMOD_R_POST);
                vIO32WriteFldAlign(OS_DITHER_05, 0, REG_DRMOD_R_POST);
                     
                //disable OD
                WBTestPtnStatus.u1ODOnOff = IO32ReadFldAlign(OD_REG54, BYPASS_ALL_SYNC_V);
                vIO32WriteFldAlign(OD_REG54, SV_TRUE, BYPASS_ALL_SYNC_V);
            }

            //disable OSD
            u1bOSDOnOff = SV_ON;
            cbSony_GammaOSDControl(&u1bOSDOnOff);
	    }
	    
		memset(DRVCUST_pWBTestPtnMatrix, 0x00, sizeof(DRVCUST_pWBTestPtnMatrix));
		DRVCUST_pWBTestPtnMatrix[12] = u2Rlvl;
		DRVCUST_pWBTestPtnMatrix[13] = u2Glvl;
		DRVCUST_pWBTestPtnMatrix[14] = u2Blvl;
		
		vLoadOSColorMatrix(SV_VP_MAIN, DRVCUST_pWBTestPtnMatrix);
	}
	else
	{
	    if(SV_ON == WBTestPtnStatus.u1PtnOnOff)
	    {
            //set status
            WBTestPtnStatus.u1PtnOnOff = SV_OFF;
            
            vDrvSetBlueStretchOnOff(SV_VP_MAIN, WBTestPtnStatus.u1BlueStretchOnOff);
            vDrvxvYCCOnOff(WBTestPtnStatus.u1XvYccOnOff);
            vIO32WriteFldAlign(DBL_00, WBTestPtnStatus.u1XvYccOnOff, DBL_ENABLE);
            vDrvMainMute(WBTestPtnStatus.u1MuteOnOff);
            if(3 == IO32ReadFldAlign(OSTG_01, REG_OP_SEL))
            {
                #ifdef CC_MAPLE_CUST_DRV
                vIO32WriteFldAlign(LD2_MODE_00, WBTestPtnStatus.u1LDOnOff, C_LD_BYPASS);
                #endif
                vIO32WriteFldAlign(OS_DITHER_02, WBTestPtnStatus.u1PreDitherSel, DRMOD_R);
                vIO32WriteFldAlign(OS_DITHER_05, WBTestPtnStatus.u1PostDitherSel, REG_DRMOD_R_POST);
                vIO32WriteFldAlign(OD_REG54, WBTestPtnStatus.u1ODOnOff, BYPASS_ALL_SYNC_V);
            }

            u1bOSDOnOff = SV_OFF;
            cbSony_GammaOSDControl(&u1bOSDOnOff);
	    }
	    
	    vLoadOSColorMatrix(SV_VP_MAIN, COLOR_TRANSFORM_ADJ);
	}
}

/*
DRV_WB_TEST_PTN DRVCUST_GetWBTestPtnOnOff(void)
{
    DRV_WB_TEST_PTN temp;
    
    return temp;
}
*/

void DRVCUST_SetPGAM_EN(UINT8 bOnoff)
{
    bGammaLinear = (bOnoff==0) ? 1 : 0;
    DRVCUST_SET_GAMMA();
    //vDrvGammaOnOff(bOnoff);
}

UINT8 DRVCUST_GetPGAM_EN(void)
{
    return (!bGammaLinear);
}

void DRVCUST_ReadRGBGainOfst(void)
{
	u2WBGain[SV_RGB_R] = wDrvGetRGain1(SV_VP_MAIN);
	u2WBGain[SV_RGB_G] = wDrvGetGGain1(SV_VP_MAIN);
	u2WBGain[SV_RGB_B] = wDrvGetBGain1(SV_VP_MAIN);
	u2WBOfst[SV_RGB_R] = dwDrvGetROffset11(SV_VP_MAIN);
	u2WBOfst[SV_RGB_G] = dwDrvGetGOffset11(SV_VP_MAIN);
	u2WBOfst[SV_RGB_B] = dwDrvGetBOffset11(SV_VP_MAIN);
}

void DRVCUST_SetUWBFLAT(UINT8 bOnoff)
{
    bOnoff = bOnoff ? SV_TRUE : SV_FALSE;
	if(bOnoff == bWBFlatPreOnoff)
		return;
	
	if(bOnoff)
	{
		DRVCUST_ReadRGBGainOfst();
		
		vHalVideoRGBGain(SV_VP_MAIN, SV_RGB_R, 0x200);
	    vHalVideoRGBGain(SV_VP_MAIN, SV_RGB_G, 0x200);
	    vHalVideoRGBGain(SV_VP_MAIN, SV_RGB_B, 0x200);
	    vHalVideoRGBOffset(SV_VP_MAIN, SV_RGB_R ,0);
	    vHalVideoRGBOffset(SV_VP_MAIN, SV_RGB_G ,0);
	    vHalVideoRGBOffset(SV_VP_MAIN, SV_RGB_B ,0);
	}
	else
	{
		vHalVideoRGBGain(SV_VP_MAIN, SV_RGB_R, u2WBGain[SV_RGB_R]);
	    vHalVideoRGBGain(SV_VP_MAIN, SV_RGB_G, u2WBGain[SV_RGB_G]);
	    vHalVideoRGBGain(SV_VP_MAIN, SV_RGB_B, u2WBGain[SV_RGB_B]);
	    vHalVideoRGBOffset(SV_VP_MAIN, SV_RGB_R, u2WBOfst[SV_RGB_R]);
	    vHalVideoRGBOffset(SV_VP_MAIN, SV_RGB_G, u2WBOfst[SV_RGB_G]);
	    vHalVideoRGBOffset(SV_VP_MAIN, SV_RGB_B, u2WBOfst[SV_RGB_B]);
	}

    bWBFlatPreOnoff = bOnoff;
	DRVCUST_SET_GAMMA();
}

UINT8 DRVCUST_GetUWBFLAT(void)
{
    return (bWBFlatPreOnoff ? SV_TRUE : SV_FALSE);
}

/*
* For Sakura eeprom dual bank
*  @i4Ret   0        SUCCESS.
*  @i4Ret   1        FAIL.
*/
UINT8 DRVCUST_DoubleEepromWrite(UINT64 u8Offset, UINT32 u4MemPtr, UINT32 u4MemLen)
{
    UINT8 i;
    INT32 i4Ret;

    for(i=0; i<2; i++)
    {
        i4Ret = EEPROM_Write(u8Offset, u4MemPtr, u4MemLen);

    	if(i4Ret)
    	{
    		Printf("Double EEP Write Error\n");
    		return (1);
    	}
	}
	
	return (0);
}

UINT8 DRVCUST_EepromReadByte(UINT16 waddr)
{
	INT32 i4Ret;
	UINT8 u4Data = 0;
	
	i4Ret = EEPROM_Read(waddr, (UINT32)&u4Data, 1);

	if(i4Ret)
	{
		Printf("EEP ReadByte Error\n");
		return (0);
	}
	return (u4Data);
}

BOOL DRVCUST_EepromWriteByte(UINT16 waddr, UINT8 u1Data)
{
	INT32 i4Ret;
	
	i4Ret = DRVCUST_DoubleEepromWrite(waddr, (UINT32)&u1Data, 1);
	
	if(i4Ret)
	{
		return (SV_FALSE);
	}
	else
	{
		return (SV_TRUE);
	}
}

#ifdef CC_SONY_GAMMA 
void CheckToEnablePBM(void)
{
	/*
    UINT8 bPBMOnOff,bMagic1,bMagic2;
    EEPROM_Read(CUSTOM_GAMMA_BASE,(UINT32)&bMagic1, 1);
    EEPROM_Read((CUSTOM_GAMMA_BASE+0x1),(UINT32)&bMagic2, 1); 
    
    bPBMOnOff = ((bApiEepromReadByte(EEP_PBM_GAMMA_ONOFF)==0x01)&&
                  (bMagic1 == GAMMA_MAGIC00)&&
                  (bMagic2 == GAMMA_MAGIC01));
    //vIO32WriteFldAlign(CUST_GAMMA_01, bPBMOnOff, CUST_GAMMA_PBM_ON);
    */
}

void DRVCUST_SetPBMGammaByte(UINT8 bOnOff)
{
    DRVCUST_EepromWriteByte(EEP_WB_LUT_ADJ_ON, bOnOff);
}
UINT8 DRVCUST_GetPBMGammaByte(void)
{
	return DRVCUST_EepromReadByte(EEP_WB_LUT_ADJ_ON);
}

void DRVCUST_TurnOnInkMark(UINT8 ui1_onOff)
{
    if(ui1_onOff)
    {
        vRegWriteFldAlign(DBG_CFG_MAIN, 1, INK_EN);
        vRegWriteFldAlign(DBG_CFG_MAIN, 0, Y_INK_MODE);
        vRegWriteFldAlign(DBG_CFG_MAIN, 0, CB_INK_MODE);
        vRegWriteFldAlign(DBG_CFG_MAIN, 0, CR_INK_MODE);

        // ink color
        vRegWriteFldMulti(INK_DATA_MAIN,
            P_Fld(0x100, INK_DATA_Y) |
            P_Fld(0, INK_DATA_CB));
        vRegWriteFldAlign(INK_DATA_MAIN_CR, 0, INK_DATA_CR);
    }
    else
    {
        vRegWriteFldAlign(DBG_CFG_MAIN, 0, INK_EN);
    }
}
void DRVCUST_SetInkMark(UINT16 ui2_x, UINT16 ui2_y)
{
    vRegWriteFldMulti(POS_MAIN, P_Fld(ui2_x, SCE_POS_X)|P_Fld(ui2_y, SCE_POS_Y));
}
#endif
void DRVCUST_SetOutputRGB2YUV(void)
{
	UINT8 u1PanelIdx = GetCurrentPanelIndex();
	
	//if((u1PanelIdx == PANEL_LG_42_WU5_SLB1_VB1) || (u1PanelIdx == PANEL_VB1_V420DK1_KS1) || (u1PanelIdx == PANEL_4K1K_VB1))
	if(IS_DISP_4K2K_FORMAT_YUV444)
	{
		vIO32WriteFldAlign(OSTG_01, SV_ON, REG_RGB2YUV_BYPASS);
		fgYUVout = SV_TRUE;
	}
}

void DRVCUST_HwInit(void)
{
#ifdef DRV_SUPPORT_CUST_ANR
    NR_FW_ANR_RegisterCustFunc(DRVCUST_AnrProc, _rCustNrWRegState);
#endif
    WB_EEP_Data_Init_To_Default();

    return;
}

void DRVCUST_SRSInit(void)
{     

    //SRS_Table_A = (UINT8*)x_mem_alloc(SRS_TBL_A_SIZE*SRS_TBL_A_NUM); 
    //SRS_Table_B = (UINT8*)x_mem_alloc(SRS_TBL_B_SIZE*SRS_TBL_B_NUM);	

	#if defined(CC_FBM_SUPPORT_SRS)
	FBM_POOL_T* prPool = FBM_GetPoolInfoAuto((UCHAR)FBM_POOL_TYPE_SRS, NULL); 
	
	SRS_Table_A = (UINT8*)VIRTUAL(prPool->u4Addr);
	SRS_Table_B = (UINT8*)VIRTUAL(prPool->u4Addr +  (SRS_TBL_A_SIZE*SRS_TBL_A_NUM));
	#endif
	
	if ((SRS_Table_A == NULL) || (SRS_Table_B == NULL))
    {
        LOG(0, "SRS Table memory alloc Failed \n");
		return;
    }

	x_memset(SRS_Table_A, 0, (SRS_TBL_A_SIZE*SRS_TBL_A_NUM));  
	x_memset(SRS_Table_B, 0, (SRS_TBL_B_SIZE*SRS_TBL_B_NUM)); 
	
}


void DRVCUST_4KBE_OSTG_Bypass(void)
{
#ifdef CC_COMBINE_4K_2K
		UINT32 u4ModelType = 0;
	
		if (DRVCUST_InitQuery(eGet2KModelSupport, &u4ModelType) == 0)
		{
			if ((u4ModelType&0x00000001) == 0)
			{
				//2K Model

			}
			else
			{
				//4K Model
				//Blue Stretch
				vIO32WriteFldAlign(BLUESTCH_00, SV_ON, C_BS_BYPASS);

				//xvYCC
			vDrvxvYCCOnOff(SV_OFF);

			// modify for R2Y overfow issue.
		   vIO32WriteFldAlign(OSTG_00, 0, REG_XVYCC_CLIP_EN);
			//vIO32WriteFldAlign(OSTG_01, 0, R_R2Y_S12IN_U10OUT);
			vIO32WriteFldAlign(OSTG_01, 0, R_R2Y_TABLE_SEL);
			//vIO32WriteFldAlign(XVYCC_17, 1, REG_XVS_BYPASS);
				
			//OPC
			vIO32WriteFldAlign(DBL_00, SV_OFF, DBL_ENABLE);			

				//Gamma Option3
				vIO32WriteFldAlign(OSTG_01, SV_ON, REG_BYPASS_OP3);

				//Local Dimming
			vIO32WriteFldAlign(LD2_MODE_00, SV_TRUE, C_LD_BYPASS);

				//Dither 1 & 2
				vIO32WriteFldAlign(OS_DITHER_02, 0, DRMOD_R);
			vIO32WriteFldAlign(OS_DITHER_05, 0, REG_DRMOD_R_POST);

				//OD
			vDrvODBypass(SV_ON);

				// POST
				vDrvSCEAllOnOff(SV_OFF);

				//Vertical CTI
				vDrvSCPQVCTIOnOff(SV_OFF);
				
			}
		}
#endif
	
}


void sonyDrv_RegisterCallback(void);

void DRVCUST_VideoInit(void)
{
    sonyDrv_RegisterCallback();
    DRVCUST_AdaptiveBacklightInit();
    DRVCUST_SRSInit();
	DRVCUST_SetOutputRGB2YUV();
	
	
	vIO32WriteFldAlign(VDP_SCPQ_01, SV_ON, SCPQ_CUST_UPCOEFF);
	vIO32WriteFldAlign(VDP_SCPQ_01, SV_ON, SCPQ_CUST_UIMAPPING);
	
}

void DRVCUST_HUPSCaleCoeff(UINT8 bPath)
{

}

void DRVCUST_VUPSCaleCoeff(UINT8 bPath)
{
    
}

void DRVCUST_VdoModeChgDone(UINT8 bPath)
{
	DRVCUST_4KBE_OSTG_Bypass();

	DRVCUST_SendEvent(E_CUST_SIGNAL_FMT_CHANGE, bPath);
    DRVCUST_SendEvent(E_CUST_VDO_DELAY_CHANGE, 0);
	if (sony_pq_func)
    {
        sony_pq_func->pq_vdo_mode_chg_done_func();
    }
	
	DRVCUST_ReadRGBGainOfst();
}

UINT8 u1SonyFactoryMode = 0;
static UINT8 DRVCUST_GetSRSOnOff()
{
	static UINT8 u1Cnt = 0;
	UINT8 u1SRSOnOff = 0;

    VRM_INFO_T* vrmInfo1;
    VRM_INFO_T* vrmInfo2;
    UINT32  u4BlankCounter = 0;
    
    vrmInfo1 = VRMGetVRMInfo(SV_VP_MAIN, VRM_MODULE_MIXER);
    vrmInfo2 = VRMGetVRMInfo(SV_VP_MAIN, VRM_MODULE_OSTG);
    
    if (IS_IC_5890_ES1() || IS_IC_5890_MPS1())
    {
       u4BlankCounter = 1023 ;// Process for ES1 and MPS1
    }
    else 
    {
       u4BlankCounter = 4095 ;// Process for ES3 and later version
    }

    //Following is for SRS bypass when 3D or 4K, and delay to enable when 2D stable.
    if(_fgAutoSearch || u1DrvTDTVCurIs3DMode() || (bDrvVideoSignalStatus(SV_VP_MAIN) != SV_VDO_STABLE) || u1SonyFactoryMode ||
        (vrmInfo1->u2Width > 1920) || (vrmInfo1->u2Height > 1080) || (vrmInfo2->u2HTotal- vrmInfo2->u2Width > u4BlankCounter))
	{
		 u1SRSOnOff = SV_OFF;
		 u1Cnt = 8;
	}
	else
	{
		if(u1Cnt != 0)
		{
			u1Cnt--;
		}
		else
		{
			u1SRSOnOff = SV_ON;
		}
	}
	return u1SRSOnOff;
}
static void DRVCUST_SRSCtrl()
{
	static UINT8 u1PreSRSOnOff = 0;
	UINT8 u1SRSOnOff = 0;

	u1SRSOnOff = DRVCUST_GetSRSOnOff();
	if(u1PreSRSOnOff != u1SRSOnOff)
	{
		u1PreSRSOnOff = u1SRSOnOff;
		DRVCUST_SharpnessEnhanceEn(u1PreSRSOnOff);
	}
}
static void DRVCUST_SendMuteEvent()
{
	static UINT8 u1PreMuteOnOff[VDP_NS] = {0xFF, 0xFF};
	UINT8 u1CurMuteOnOff[VDP_NS];
	UINT32 u4Path;
	for(u4Path = SV_VP_MAIN; u4Path <= SV_VP_PIP; u4Path++)
	{
		u1CurMuteOnOff[u4Path] = _u4DrvVideoGetMute(u4Path);
		if(u1CurMuteOnOff[u4Path] != u1PreMuteOnOff[u4Path])
		{
			u1PreMuteOnOff[u4Path] = u1CurMuteOnOff[u4Path];
			if(SV_ON == u1CurMuteOnOff[u4Path])
			{
			   LOG(2,"Send VIDEO mute event ----------------u4Path(%d)\n",u4Path);
		        DRVCUST_SendEvent(E_CUST_PLANE_MUTE_CHANGE, u4Path);
			}
		}
	}
}

#if defined(CC_MAPLE_CUST_DRV) && defined(CC_MT5890) && defined(CC_SUPPORT_4KBE) 
EXTERN UINT8 _u1tvmode_scart;
EXTERN UINT32 GetPANEL4K2K_TYPE(void);
static void DRVCUST_BEConnectCtrl()
{
    static UINT32 u4PrePanelType = 0;
    static UINT32 u4PreTVMode = 0;
    static UINT32 u4PreScartOnOff = 0;
    
    if((GetPANEL4K2K_TYPE()!= u4PrePanelType) || 
        (u4PreTVMode != SRM_GetTvMode()) ||
        (_u1tvmode_scart != u4PreScartOnOff))
    {
        if((_u1tvmode_scart == 1) ||  // TV scart out on
            ((GetPANEL4K2K_TYPE() != PANEL_TYPE_4K1K_60) && (GetPANEL4K2K_TYPE() != PANEL_TYPE_MAX)) ||  //Panel type is not 4k1k
            (SRM_GetTvMode() == SRM_TV_MODE_TYPE_NORMAL)   //TV mode is not pip/pop
            )
        {
            if(u1Connet[SV_VP_PIP])
            {
                LOG(1,"Disconnect BE sub\n");
                DRVCUST_BE_Disconnect(E_CUST_BE_TX_PATH_VIDEO, SV_VP_PIP);
            }
        }
        else
        {
            if(!u1Connet[SV_VP_PIP])
            {
                LOG(1,"Connect BE sub\n");
                DRVCUST_BE_Connect(E_CUST_BE_TX_PATH_VIDEO,E_CUST_BE_SCL_TYPE_VIDEO,E_CUST_BE_PLANE_ORDER_1,SV_VP_PIP);
                DRVCUST_SendEvent(E_CUST_SCALING_REQ_CHANGE, SV_VP_PIP);
                DRVCUST_SendEvent(E_CUST_SRC_AREA_CHANGE, SV_VP_PIP);
            }
        }

        u4PrePanelType = GetPANEL4K2K_TYPE();
        u4PreTVMode = SRM_GetTvMode();
        u4PreScartOnOff = _u1tvmode_scart;
    }

}
#endif

void DRVCUST_VideoMainloop()
{
	static UINT8 bOSD_En, bPreOSD_En;
	static UINT8 u1PreIs3DFmt = 0;
	static UINT8 u1PreMuteSta = 0;
	
    DRVCUST_AdaptiveBacklightProc();
    vScpipSetSuperGameMode(SV_VP_MAIN, DRVCUST_SuperGameMode(SV_VP_MAIN));
	
	if (sony_pq_func)
    {
        sony_pq_func->pq_video_main_loop_func();
    }
	#ifdef CC_PowerCons_Ctrl
    DRVCUST_PowerConsCtrlStatusCheck();
	#endif
	//CustomReadTemperature();

	bOSD_En = OSD_BASE_IsDisplaying();

	if(bOSD_En != bPreOSD_En)
	{
		bPreOSD_En = bOSD_En;
		DRVCUST_SendEvent(E_CUST_OSD_STATE_CHANGE, 0);
	}
	DRVCUST_PanelGammaRemapProc();
	
	DRVCUST_SRSCtrl();

	#if defined(CC_MAPLE_CUST_DRV) && defined(CC_MT5890) && defined(CC_SUPPORT_4KBE) 
	DRVCUST_BEConnectCtrl();
    #endif
	
	DRVCUST_SendMuteEvent();
	
}

void DRVCUST_OutVSyncISR()
{
/*
    vDrvLcdimProc();
    if( IO32ReadFldAlign(ADAP_LCDIM_SPI, SPI_AUTO_VSYNC_EN)== SV_TRUE)
    {
        vDrvLcdimSpiCommandGen(E_SPI_PAGE_WRITE, 0);
    }
    */
    if (sony_pq_func)
    {
        sony_pq_func->pq_out_vsync_isr_func();
    }
    
    DRVCUST_Gamma_ISR();
}

void DRVCUST_PostOutVSyncISR()
{  
	if(fgCriticalSection)
	{
		fgCriticalSection = SV_FALSE;
	}
    // for no-double buffer hardware register and software register
    if (u4BufFlag&E_CUST_PQ_BUF_FLUSH)
    {        
        if (u4BufFlag&E_CUST_PQ_BUF_COMTRAST)       
        {   
            vDrvSetSCEContrast(u2ContrastBuf); 
        }
        
        if (u4BufFlag&E_CUST_PQ_BUF_COLOR)          
        {         
            vDrvSetSCESaturation(u2ColorBuf);  
        }
        
        if (u4BufFlag&E_CUST_PQ_BUF_HUE)            
        {       
            vDrvSetSCEHue((u2HueBuf <<2));
        }
		
		if (u4BufFlag&E_CUST_PQ_BUF_MATRIX)            
        {
        	vDrvSetExtContrast(SV_VP_MAIN, u2MatrixContrastBuf); 
			vDrvSetExtSaturation(SV_VP_MAIN, u2MatrixColorBuf);
            vDrvSetExtBrightness(SV_VP_MAIN, u2MatrixBrightnessBuf);
        }
        
        if (u4BufFlag&E_CUST_PQ_BUF_SHARPNESS)      
        {           
            vDrvPostSharpGainHOffset(stSharpOfst.u1GainH[0], stSharpOfst.u1GainH[1], stSharpOfst.u1GainH[2]);
            vDrvPostSharpGainVOffset(stSharpOfst.u1GainV[0], stSharpOfst.u1GainV[1], stSharpOfst.u1GainV[2]);
            vDrvPostSharpGainDOffset(stSharpOfst.u1GainD[0], stSharpOfst.u1GainD[1], stSharpOfst.u1GainD[2]);
            vDrvPostSharpCorzHOffset(stSharpOfst.u1CorzH[0], stSharpOfst.u1CorzH[1], stSharpOfst.u1CorzH[2]);
            vDrvPostSharpCorzVOffset(stSharpOfst.u1CorzV[0], stSharpOfst.u1CorzV[1], stSharpOfst.u1CorzV[2]);
            vDrvPostSharpCorzDOffset(stSharpOfst.u1CorzD[0], stSharpOfst.u1CorzD[1], stSharpOfst.u1CorzD[2]);			
			vDrvHSharpGainOffset(stSharpOfst.u1HSHPGainLow[0], stSharpOfst.u1HSHPGainLow[1], stSharpOfst.u1HSHPGainMid[0], stSharpOfst.u1HSHPGainMid[1], stSharpOfst.u1HSHPGainHigh[0], stSharpOfst.u1HSHPGainHigh[1]);
            vDrvHSharpCorzOffset(stSharpOfst.u1HSHPCor[0], stSharpOfst.u1HSHPCor[1], stSharpOfst.u1HSHPCor[2]);
            vDrvPostSharpEdgeGainOffset(stSharpOfst.u1EdgeGain[0], stSharpOfst.u1EdgeGain[1], stSharpOfst.u1EdgeGain[2]);
            vDrvPostSharpDetailGainOffset(stSharpOfst.u1DetailGain[0], stSharpOfst.u1DetailGain[1], stSharpOfst.u1DetailGain[2]);
            vDrvPostSharpLTIGainOffset(stSharpOfst.u1LTIGain[0], stSharpOfst.u1LTIGain[1], stSharpOfst.u1LTIGain[2]);
            vDrvPostSharpLTICorzOffset(stSharpOfst.u1LTICorz[0], stSharpOfst.u1LTICorz[1], stSharpOfst.u1LTICorz[2]);
        }
        
		if (u4BufFlag&E_CUST_PQ_BUF_PARTIALY)      
        {            
            x_memcpy((DEFAULT_SCE_TBL + ENUM_Y_SLOPE*SCE_HUE_SLICE), u1SceYSlope, SCE_LUMA_HUE_SLICE);  
			LOG(2, "E_CUST_PQ_BUF_PARTIALY \n");
        }

		if (u4BufFlag&E_CUST_PQ_BUF_PARTIALS)      
        {            
            x_memcpy((DEFAULT_SCE_TBL + ENUM_S_GAIN1*SCE_HUE_SLICE), u1SceSGain1, SCE_HUE_SLICE);
            x_memcpy((DEFAULT_SCE_TBL + ENUM_S_GAIN2*SCE_HUE_SLICE), u1SceSGain2, SCE_HUE_SLICE);
            x_memcpy((DEFAULT_SCE_TBL + ENUM_S_GAIN3*SCE_HUE_SLICE), u1SceSGain3, SCE_HUE_SLICE);
			LOG(2, "E_CUST_PQ_BUF_PARTIALS \n");
        }
		
        if (u4BufFlag&E_CUST_PQ_BUF_SCE)      
        {            
			LOG(2, "E_CUST_PQ_BUF_SCE \n");
            vApiRegisterVideoEvent(PE_EVENT_SCE, VDP_1, SV_ON);
        }

        if (u4BufFlag&E_CUST_PQ_BUF_RGB_GAIN_OFST)      
        {            
            vDrvSetRGain1(SV_VP_MAIN, stRGBGainOfst.u2RGain);
            vDrvSetGGain1(SV_VP_MAIN, stRGBGainOfst.u2GGain);
            vDrvSetBGain1(SV_VP_MAIN, stRGBGainOfst.u2BGain);
            vDrvSetROffset11(SV_VP_MAIN, stRGBGainOfst.u2ROffset);
            vDrvSetGOffset11(SV_VP_MAIN, stRGBGainOfst.u2GOffset);
            vDrvSetBOffset11(SV_VP_MAIN, stRGBGainOfst.u2BOffset);            
        }

		if (u4BufFlag&E_CUST_PQ_BUF_YLEV)      
        {         
            vDrvSetYLevTable(u1YLevArrayBuf);
        }
        
        u4BufFlag = 0;
    }
    
    if (sony_pq_func)
    {
        sony_pq_func->pq_post_out_vsync_isr_func();
    }
}


void DRVCUST_PostDEEndISR(void)
{   
	if(!fgCriticalSection)
	{
		fgCriticalSection = SV_TRUE;
	}
	// for double buffer hardware register 
    if (u4BufFlag&E_CUST_PQ_BUF_FLUSH)
    {
        if (u4BufFlag&E_CUST_PQ_BUF_LUMA_CURVE)     
        {
            vDrvADLSetLumaCurve65(u2LumaArrayBuf);
			vDrvADLSetLumaSecCurve65(u2SkinArrayBuf);
			vApiRegisterVideoEvent(PE_EVENT_LUMA_CURVE, VDP_1, SV_ON);
			vApiRegisterVideoEvent(PE_EVENT_LUMA_SEC_CURVE, VDP_1, SV_ON);
        }

        if (u4BufFlag&E_CUST_PQ_BUF_SRS)
        {
            vDrvSetSRS(PhyAddrBuf_A, PhyAddrBuf_B);
        }
    }
	
	if (sony_pq_func)
    {
        sony_pq_func->pq_post_de_end_isr_func();
    }
}

void DRVCUST_VdoInISR()
{
	if (sony_pq_func)
    {
        sony_pq_func->pq_vdo_in_isr_func();
    }

}

E_CUST_RESULT BeAllocateResource(UINT8 u1TxPath, E_CUST_BE_SCL_TYPE eBeSclType, CUST_BE_SCL_CONFIG_T* pSclConfig, UINT8* u1BeHandle)
{
	if (sony_be_func)
    {
        return sony_be_func->be_allocate_resource(u1TxPath, eBeSclType, pSclConfig, u1BeHandle);
    }
	
	return E_CUST_RESULT_ERROR_NOT_READY;
}

E_CUST_RESULT BeFreeResource(UINT8 u1BeHandle)
{
	if (sony_be_func)
    {
        return sony_be_func->be_free_resource(u1BeHandle);
    }
	return E_CUST_RESULT_ERROR_NOT_READY;
}

E_CUST_RESULT BeAssociatePath(UINT8 u1BeHandle, UINT8 bPath)
{
	if (sony_be_func)
    {
        return sony_be_func->be_associate_path(u1BeHandle, bPath);
    }
	return E_CUST_RESULT_ERROR_NOT_READY;
}

E_CUST_RESULT BeDissociatePath(UINT8 u1BeHandle, UINT8 bPath)
{
	if (sony_be_func)
    {
        return sony_be_func->be_dissociate_path(u1BeHandle, bPath);
    }
	return E_CUST_RESULT_ERROR_NOT_READY;
}

void PqAssociatePath(UINT8 bPqPath, UINT8 bPath)
{
	if (sony_pq_func)
    {
        sony_pq_func->pq_associate_path(bPqPath, bPath);
    }

}

void PqDissociatePath(UINT8 bPath)
{
	if (sony_pq_func)
    {
        sony_pq_func->pq_dissociate_path(bPath);
    }

}

UINT8 DRVCUST_GetPathByBeHandle(UINT8 u4BeHandle)
{
    UINT32 u4Index;

    for (u4Index = 0; u4Index < sizeof(u1BePath); u4Index++)
    {
        if (u1BePath[u4Index] == u4BeHandle)
        {
            break;
        }
    }

    return u4Index;
}

UINT8 DRVCUST_BE_Connect(UINT8 u1TxPath, UINT8 u1BeSclType , UINT8 u1PlaneOrder, UINT8 bPath)
{
	UINT8 u1BeHandle;
	CUST_BE_SCL_CONFIG_T pSclConfig;
	//VRM_INFO_T* prVrmInfo;


    //prVrmInfo = VRMGetVRMInfo(bPath, VRM_MODULE_MIXER);
    
	pSclConfig.u1PlaneOrder 	= u1PlaneOrder;
	//pSclConfig.u4SrcX 			= vrmInfo->u2X;
	//pSclConfig.u4SrcY 			= vrmInfo->u2Y;
	//pSclConfig.u4SrcWidth 		= vrmInfo->u2Width;
	//pSclConfig.u4SrcHeight		= vrmInfo->u2Height;
	//pSclConfig.u4DestX			= vrmInfo->u2X;
	//pSclConfig.u4DestY 		= vrmInfo->u2Y;
	//pSclConfig.u4DestWidth 	= vrmInfo->u2Width;
	//pSclConfig.u4DestHeight	= vrmInfo->u2Height;
	
	//temporal solution
	pSclConfig.u4SrcX 			= 0;//prVrmInfo->u2X;
	pSclConfig.u4SrcY 			= 0;//prVrmInfo->u2Y;
	pSclConfig.u4SrcWidth 		= 1920;//prVrmInfo->u2Width;
	pSclConfig.u4SrcHeight		= 1080;//prVrmInfo->u2Height;
	pSclConfig.u4DestX			= 0;
	pSclConfig.u4DestY 		= 0;
	pSclConfig.u4DestWidth 	= 3840;
	pSclConfig.u4DestHeight	= 2160;
	if(bPath == SV_VP_PIP)
	{
	    pSclConfig.u4SrcX 			= 1920;//prVrmInfo->u2X;
		pSclConfig.u4SrcY 			= 0;//prVrmInfo->u2Y;
		pSclConfig.u4SrcWidth 		= 1920;//prVrmInfo->u2Width;
		pSclConfig.u4SrcHeight		= 1080;//prVrmInfo->u2Height;
		pSclConfig.u4DestX			= 1920;
		pSclConfig.u4DestY 		= 0;
		pSclConfig.u4DestWidth 	= 1920;
		pSclConfig.u4DestHeight	= 2160;
	}

	
	if(u1TxPath == E_CUST_BE_TX_PATH_GFX)
	{
	    u1Connet[2]= SV_TRUE;
	}
    if(bPath == SV_VP_MAIN)
	{
	    u1Connet[0]= SV_TRUE;
	}
	else if(bPath == SV_VP_PIP)
	{
	    u1Connet[1]= SV_TRUE;
	}
	if(BeAllocateResource(u1TxPath, u1BeSclType, &pSclConfig, &u1BeHandle))
	{
	    LOG(0," DRVCUST_BE_Connect Allocate resouce fail u1TxPath(%d),u1BeSclType(%d)!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n",u1TxPath,u1BeSclType);
		return SV_FAIL;
	}
    
	if(u1TxPath == E_CUST_BE_TX_PATH_VIDEO)
	{
		if(bPath == SV_VP_MAIN)
		{
			u1BePath[0] = u1BeHandle;
		}
		else 
		{
			u1BePath[1] = u1BeHandle;
		}
	}
	else
	{
		u1BePath[2] = u1BeHandle;
	}

	if(bPath > SV_VP_PIP)
	{
		return SV_SUCCESS;
	}
	
	if(BeAssociatePath(u1BeHandle,bPath))
	{
	    LOG(0," BeAssociatePath fail bPath(%d) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n",bPath);
		return SV_FAIL;
	}

	return SV_SUCCESS;
	

	
}

UINT8 DRVCUST_BE_Disconnect(UINT8 u1TxPath, UINT8 bPath)
{
	UINT8 u1BeHandle;
	
	if(u1TxPath == E_CUST_BE_TX_PATH_VIDEO)
	{
		if(bPath == SV_VP_MAIN)
		{
			u1BeHandle = u1BePath[0];
			u1Connet[0]= SV_FALSE;
		}
		else
		{
			u1BeHandle = u1BePath[1];
			u1Connet[1]= SV_FALSE;
		}
	}
	else
	{
		u1BeHandle = u1BePath[2];
		u1Connet[2]= SV_FALSE;
	}
	
	if(BeDissociatePath(u1BeHandle, bPath))
	{
		return SV_FAIL;
	}

	if(BeFreeResource(u1BeHandle))
	{
		return SV_FAIL;
	}

	return SV_SUCCESS;
	
}

void DRVCUST_PQ_Associate(UINT8 bPqPath, UINT8 bPath)
{
	PqAssociatePath(bPqPath, bPath);
}

void DRVCUST_PQ_Disassociate(UINT8 bPqPath)
{
	PqDissociatePath(bPqPath);
}

UINT32 DRVCUST_RGBOfstRemap(UINT32 u4Value)
{
    return u4Value<<2;
}

UINT16 DRVCUST_Y2RMap(void)
{
    //HSI SPEC change , Always -16 For video mode / Special Mode , 
    //because of DEMO Mode Support
    return  0;
}

/* @ Auto NR default Initial setting
 *      1: low
 *      2: Middle
 */
UINT8 DRVCUST_AutoNRDefSet(void)
{
    return 2;
}

/* @ Auto NR noise level implement
 * @ return noise level
 */
UINT8 DRVCUST_NoiseLevel(void)
{
#if 0
    UINT8 bNoiseLevel = NM_INVALIDLEVEL;
    UINT8 bRFNMLevel;

    if((bGetVideoDecType(bDrvNRGetCurrentPath())==SV_VD_TVD3D)&&
        	 (bGetSignalType(bDrvNRGetCurrentPath())==SV_ST_TV))// TVD RF source
    {

        bRFNMLevel = bTvdSignalStrengthLevel(1);   //RF level 0 ~ 80

        if(bRFNMLevel > 75)
        {
            bNoiseLevel = NM_LEVEL1_3;
        }
        else if(bRFNMLevel > 69)
        {
            bNoiseLevel = NM_LEVEL2;
        }
        else if(bRFNMLevel > 59)
        {
            bNoiseLevel = NM_LEVEL3;
        }
        else if(bRFNMLevel > 55)
        {
            bNoiseLevel = NM_LEVEL4;
        }
        else
        {
            bNoiseLevel = NM_LEVEL5;
        }
    }
    else
    {
        bNoiseLevel = vDrvNMLevel();   //content NR, Noise level 0 ~ 4
    }
    
    return bNoiseLevel;
#endif
    return 0;
}

void DRVCUST_SET_DEFAULT_GAMMA_REMAP(void)
{
    vIO32WriteFldAlign(ADAPTIVE_RGB_GAMMA_REG, 0x40, ADAPTIVE_RGB_GAMMA_SEL);
}

void DRVCUST_SetGammaRemapForceLoad(UINT8 bForceLoadGamma)
{
	//if have remap spec, need to modify... Currently, set to default, means no remap
	DRVCUST_SET_DEFAULT_GAMMA_REMAP();
	vIO32WriteFldAlign(ADAPTIVE_RGB_GAMMA_REG, bForceLoadGamma, ADAPTIVE_RGB_GAMMA_FORCE_LOAD);
}

void DRVCUST_GAMMA_REMAP_CALC(UINT32 u4GammaSel)
{
	UINT32 i;
	EXTERN UINT16 u2GammaDecodedTable[3][257];

	UINT16 *wTmpGammaCurve; 
	UINT16 GammaLength = 2*3*257;
	const UINT16 *pwRemapTable=NULL;
	UINT32 u4Index,u4IndexNxt;
	UINT32 u4CurrentCh;
	UINT8  bDecayUpTh,bDecayLowTh;
	UINT16 bAlpha;
	UINT8  bGammaBlendingEn;

	bDecayUpTh= IO32ReadFldAlign(ADAPTIVE_RGB_GAMMA_REG_01, ADAPTIVE_RGB_GAMMA_DECAY_UPTH);
	bDecayLowTh= IO32ReadFldAlign(ADAPTIVE_RGB_GAMMA_REG_01, ADAPTIVE_RGB_GAMMA_DECAY_LOWTH);
	bGammaBlendingEn= IO32ReadFldAlign(ADAPTIVE_RGB_GAMMA_REG_01, ADAPTIVE_RGB_GAMMA_BLENING_EN);
	if((wTmpGammaCurve = x_mem_alloc(GammaLength)) == NULL)
		return;
	
	if(u4GammaSel > 50)
	{
		bGammaBlendingEn = 0;
	}
	
	if(u4GammaSel <= NUM_OF_TEMP_GAMMA)
	{
		pwRemapTable=PANEL_GAMMA_REMAP_TBL+u4GammaSel*0x100;		
	}

	bDecayUpTh = MAX(bDecayLowTh+1,bDecayUpTh);



	if(pwRemapTable!=NULL)
	{ 

		for(u4CurrentCh=0; u4CurrentCh<3; ++u4CurrentCh)
		{
			for(i=0;i<256;++i)
			{
				if(i >= bDecayUpTh)
				{
					bAlpha = 100;
				}
				else if(i <= bDecayLowTh) 
				{
					bAlpha = 15;
				}
				else
				{
					bAlpha = (85 * (i - bDecayLowTh) / (bDecayUpTh - bDecayLowTh)) + 15;
				}
				
				if(!bGammaBlendingEn)
				{
					u4Index = (pwRemapTable[i] >> 2)&0xFF;
					u4IndexNxt = MIN(u4Index + 1,0xFF);
				}
				else
				{
					u4Index = ((i*4 + (((pwRemapTable[i] - i*4) * bAlpha )/100)) >> 2)&0xFF;
					u4IndexNxt = MIN(u4Index + 1,0xFF);
				}

				wTmpGammaCurve[u4CurrentCh*257 + i] = 
					((wHwGammaCurve[u4CurrentCh][u4Index] * (4-(pwRemapTable[i]&3)) +
						wHwGammaCurve[u4CurrentCh][u4IndexNxt]*(pwRemapTable[i]&3) + 2)>>2);
			}
		}

		wTmpGammaCurve[256] = wHwGammaCurve[0][256];
		wTmpGammaCurve[1*257+256] = wHwGammaCurve[1][256];
		wTmpGammaCurve[2*257+256] = wHwGammaCurve[2][256];
		
	}
	else
	{
		for(i=0;i<257;++i)
		{
			/*wTmpGammaCurve[0][i]=wHwGammaCurve[0][i];
			wTmpGammaCurve[1][i]=wHwGammaCurve[1][i];
			wTmpGammaCurve[2][i]=wHwGammaCurve[2][i];*/  // modify to fix warning "Frame size bigger than 1024Byte"
			wTmpGammaCurve[i]=wHwGammaCurve[0][i];
			wTmpGammaCurve[1*257+i]=wHwGammaCurve[1][i];
			wTmpGammaCurve[2*257+i]=wHwGammaCurve[2][i];
		}	
	}
	
    LOG(5, "***********HW GAMMA CURVE AFTER REMAP***********\n  Idx	  R 	G	  B\n");
	for(i=0; i<257; i++)
    {
		LOG(5, " %d  %d  %d  %d\n", i, wTmpGammaCurve[i], wTmpGammaCurve[1*257+i], wTmpGammaCurve[2*257+i]);
    }
	LOG(5, "***********HW GAMMA CURVE AFTER REMAP END***********\n");	
	
	x_memcpy(u2GammaDecodedTable, wTmpGammaCurve, GammaLength); 	
	x_mem_free(wTmpGammaCurve);
	wTmpGammaCurve = NULL;
}

/*
void DRVCUST_PANEL_GAMMA_REMAP(UINT32 u4GammaSel)
{
    
	i4DynGammaIndex = u4GammaSel + 0x10;
	DRVCUST_GAMMA_REMAP_CALC(i4DynGammaIndex);	
}
*/

void DRVCUST_PanelGammaRemapProc(void)
{
	//Gamma Proc for Gamma Remap.
    if ((bGammaInit && ((bPreGammaSel!= IO32ReadFldAlign(ADAPTIVE_RGB_GAMMA_REG, ADAPTIVE_RGB_GAMMA_SEL)) || 
		IO32ReadFldAlign(ADAPTIVE_RGB_GAMMA_REG, ADAPTIVE_RGB_GAMMA_FORCE_LOAD)))
        /*&&(bAingFlag == FALSE)&&(fgpicturemodechange == SV_FALSE)*/)
    {
        bPreGammaSel= IO32ReadFldAlign(ADAPTIVE_RGB_GAMMA_REG, ADAPTIVE_RGB_GAMMA_SEL);
        DRVCUST_GAMMA_REMAP_CALC(bPreGammaSel);
        vDrvSetGammaWritePingPongFlag(SV_TRUE);
        vIO32WriteFldAlign(ADAPTIVE_RGB_GAMMA_REG, SV_FALSE, ADAPTIVE_RGB_GAMMA_FORCE_LOAD);
    }
}
void DRVCUST_PANEL_GAMMA_REMAP(UINT32 u4GammaSel)
{
    UNUSED(u4GammaSel);
}

void DRVCUST_SetBlackLvlCtrl(UINT8 bPath)
{    
#if 0 // Below is SAMPLE CODE for function customization.
    UINT8 bLevel = GET_BLK_LVL(bPath);
    if (bPath == SV_VP_MAIN)
    {
        if(fgIsMainDVI())
        {
            SET_MATRIX_PED(SV_OFF);
            switch (bLevel)
            {
                case SV_OFF:
                    vSetHDMIRangeMode(SV_HDMI_RANGE_FORCE_FULL);
                    break;
                case SV_ON:
                    vSetHDMIRangeMode(SV_HDMI_RANGE_FORCE_LIMIT);
                    break;
                default:
                    vSetHDMIRangeMode(SV_HDMI_RANGE_FORCE_AUTO);
                    break;                
            }
        }
        else if (fgIsMainTvd3d() || fgIsMainYPbPr())
        {
            SET_MATRIX_PED(bLevel);
            vSetHDMIRangeMode(SV_HDMI_RANGE_FORCE_AUTO);
        }
        else
        {
            SET_MATRIX_PED(SV_OFF);
            vSetHDMIRangeMode(SV_HDMI_RANGE_FORCE_AUTO);
        }
    }
    else
    {
        SET_MATRIX_PED(SV_OFF);
        vSetHDMIRangeMode(SV_HDMI_RANGE_FORCE_AUTO);
    }
#endif
}

BOOL vDrvGetHDRCapabilities(UINT32* u4OutNumTypes, UINT32* u4Types, UINT32* u4maxLuminance, UINT32* u4maxAverageLuminance, UINT32* u4minLuminance )
{
	UINT32 u4HdrNumTypes = 2;
	UINT32 u4HdrTypes[HDR_TYPE] = {2,3};
	UINT32 u4HdrMaxLuminance = 2000;
	UINT32 u4HdrMaxAverageLuminance = 1000;
	UINT32 u4HdrMinLuminance = 5;
#ifdef CC_PANEL_FROM_FLASH
	UINT32 u4ControlWord3 = FlashPanel_GetControlWord3();// bit[27:26]	0: no 3D , 1:active 3D	,2:Passive 3D 
#else
	UINT32 u4ControlWord3 = 0;// bit[27:26]  0: no 3D , 1:active 3D  ,2:Passive 3D 
#endif
	UINT32 u4SonyModelType=0;
	UINT32 u4WCGType = 0;
	u4WCGType = (u4ControlWord3 & 0x00000003);
	if(DRVCUST_InitQuery(eGet2KModelSupport, &u4SonyModelType) == 0)
	{
		if((u4SonyModelType&0x01)==0x00)// 2k
		{
			u4HdrNumTypes = 0;
			LOG(0,"****2K is not support HDR****\n");
		}
	}
	
	if(u4WCGType==0)//non-wcg
	{
		u4HdrNumTypes = 0;
		LOG(0,"****Non-WCG is not support HDR****\n");
	}	
	
	if(u4Types == NULL)
	{
		if(u4OutNumTypes != NULL )
		{
				*u4OutNumTypes = u4HdrNumTypes;  
		  }
		  else
		  {
				LOG(0,"****vDrvGetHDRCapabilities u4OutNumTypes is NULL****\n");
		  }
		 LOG(0,"****vDrvGetHDRCapabilities u4Types is NULL****\n");
		return TRUE;
	}
	else if((u4maxLuminance == NULL )||(u4maxAverageLuminance == NULL)||(u4minLuminance == NULL) )
	{
		 LOG(0,"****vDrvGetHDRCapabilities other element is NULL****\n");
		 return TRUE;
	}
	//TO-be

	*u4OutNumTypes = u4HdrNumTypes;    
	x_memcpy(u4Types, u4HdrTypes, HDR_TYPE*sizeof(UINT32));
	*u4maxLuminance = u4HdrMaxLuminance;
	*u4maxAverageLuminance = u4HdrMaxAverageLuminance;
	*u4minLuminance = u4HdrMinLuminance;
	
	LOG(0,"****vDrvGetHDRCapabilities u4maxLuminance=%d, u4maxAverageLuminance=%d, u4minLuminance=%d ****\n",
		*u4maxLuminance, *u4maxAverageLuminance, *u4minLuminance);

	return TRUE;
}


UINT32 DRVCUST_HDMIRange(UINT8 bPath)
{
    return (bDviIsVideoTiming() ? SV_HDMI_RANGE_LIMIT : SV_HDMI_RANGE_FULL);
}

void DRVCUST_SetVideoRange(UINT8 bMode)
{
	bVideoRangeMode = bMode;
}

UINT8 DRVCUST_GetVideoRange(UINT8 bPath)
{
	E_CUST_INPUT_TYPE eInputType = BEPQ_AP_Get_Input_Type(bPath);
	if(eInputType == E_CUST_INPUT_TYPE_WIFI_DISPLAY)
	{
		return bVideoRangeMode;
	}
	else
	{
		return (UINT8)DRV_CUSTOM_HDMI_RANGE_LIMIT;
	}
}
	
BOOL DRVCUST_HDMIWithValidAviInfo(void)
{
    if(u1IsHdmiMode()) //HDMI mode
    {
        if(((u1IO32Read1B(INTR_STATE1_0 + u4ActiveHdmiRegBase) & 0x10) != 0x10)/*has AVI info*/
            &&(u1IO32Read1B(AVIRX0_0 + u4ActiveHdmiRegBase) == 0x82))          /*valid AVI info*/
        {
            return TRUE;
        }
    }
    return FALSE;
}


//TRUE:photo
//FALSE:video
BOOL DRVCUST_HDMIIsPhotoMode(void)
{
    if(DRVCUST_HDMIWithValidAviInfo())    //Valid AviInfo
    {
    	if((u1IO32Read1B(AVIRX2_0 + u4ActiveHdmiRegBase) & 0x30) == 0x10 )//CN1,CN0=0,1
        {
    		if((_bDviTiming == MODE_1080i_50) || (_bDviTiming == MODE_1080i) \
    		   || (_bDviTiming == MODE_1080p_50) || (_bDviTiming == MODE_1080p_60)\
    		   || (_bDviTiming == MODE_480P) || (_bDviTiming == MODE_576P)\
    		   || (_bDviTiming == MODE_3840_2160P_25) || (_bDviTiming == MODE_3840_2160P_30))
    		{
    			return TRUE;//photo
    		}
    	}
    }
	return FALSE;
}

UINT8 DRVCUST_HDMIGetVideoColorSpace(void)
{
	UINT8 u1Ecvalue;

    if(DRVCUST_HDMIWithValidAviInfo())    //Valid AviInfo
    {
    	if((u1IO32Read1B(AVIRX1_0 + u4ActiveHdmiRegBase) & 0x60) != 0x00 )//C1,C0=0,1
    	{
    		if((u1IO32Read1B(AVIRX1_1 + u4ActiveHdmiRegBase) & 0xC0) == 0xC0 )
    	    {
    	    	u1Ecvalue = u1IO32Read1B(AVIRX1_2 + u4ActiveHdmiRegBase) >>4;
    	    	if((u1Ecvalue & 0x4) == 0x4)
    	    	{
    	    		if((u1Ecvalue & 0x2) == 0x2)
    	    		{
    	    			return SV_COLOR_HDMI_BT2020;
    	    		}
    				else if((u1Ecvalue & 0x1) == 0x1)
    				{
    					return SV_COLOR_HDMI_BT2020c;
    				}
    	    	}
    			else
    			{
    				return SV_COLOR_HDMI_xvYCC;
    			}
    	    }
    	}
    	else
		{
    		if((u1IO32Read1B(AVIRX1_1 + u4ActiveHdmiRegBase) & 0xC0) == 0xC0)
			{
				u1Ecvalue = u1IO32Read1B(AVIRX1_2 + u4ActiveHdmiRegBase) >>4;
				if((u1Ecvalue & 0x04) == 0x4)
				{
					if((u1Ecvalue & 0x2) == 0x2)
					{
						return SV_COLOR_HDMI_BT2020;
					}
				}
			}
		}
    }
	return SV_COLOR_HDMI_Normal;
}

UINT8 DRVCUST_HDMIGetPhotoColorSpace(void)
{
    UINT8 u1Ecvalue;

    if(DRVCUST_HDMIWithValidAviInfo())    //Valid AviInfo
    {
    	if((u1IO32Read1B(AVIRX1_0 + u4ActiveHdmiRegBase) & 0x60) != 0x00 )
    	{
    		if((u1IO32Read1B(AVIRX1_1 + u4ActiveHdmiRegBase) & 0xC0) == 0xC0)
    	    {
    	    	u1Ecvalue = u1IO32Read1B(AVIRX1_2 + u4ActiveHdmiRegBase) >> 4;
    	    	if((u1Ecvalue & 0x7) == 0x3)
    	    	{
    	    		return SV_COLOR_HDMI_Adobe_RGB;
    	    	}
    			else
    			{
    				return SV_COLOR_HDMI_sYCC;
    			}
    	    }			
    	}
    	else
    	{
    		if((u1IO32Read1B(AVIRX1_1 + u4ActiveHdmiRegBase) & 0xC0) == 0xC0)
    	    {
    	    	u1Ecvalue = u1IO32Read1B(AVIRX1_2 + u4ActiveHdmiRegBase) >> 4;
    	    	if((u1Ecvalue & 0x7) == 0x4)
    	    	{
    	    		return SV_COLOR_HDMI_Adobe_RGB;
    	    	}
    	    }
    	}
    }
    return SV_COLOR_HDMI_sRGB;
}

UINT8 DRVCUST_HDMIGetColorimetry(void)
{
	UINT8 u1ECValue = 0;
	UINT8 u1CNValue = 0;
	
    if(DRVCUST_HDMIWithValidAviInfo())    //Valid AviInfo
    {
    	if((u1IO32Read1B(AVIRX1_0 + u4ActiveHdmiRegBase) & 0x60) != 0x00 )//YCC
    	{
    		u1CNValue = u1IO32Read1B(AVIRX1_1 + u4ActiveHdmiRegBase) & 0xC0;
    		if(u1CNValue == 0x40)
    		{
    			return SV_COLOR_HDMI_Colorimetry_601;
    		}
    		else if(u1CNValue == 0x80)
    		{
    			return SV_COLOR_HDMI_Colorimetry_709;
    		}
    		else //refer extended colorimetry
    	    {
    	    	u1ECValue = u1IO32Read1B(AVIRX1_2 + u4ActiveHdmiRegBase) & 0x70;
    	    	if(u1ECValue == 0x00)
    	    	{
    	    		return SV_COLOR_HDMI_Colorimetry_XVYCC601;
    	    	}
    			else if(u1ECValue == 0x10)
    			{
    				return SV_COLOR_HDMI_Colorimetry_XVYCC709;
    			}
    			else if(u1ECValue == 0x20)
    			{
    				return SV_COLOR_HDMI_Colorimetry_sYCC601;
    			}
    			else if(u1ECValue == 0x30)
    			{
    				return SV_COLOR_HDMI_Colorimetry_AdobeYCC601;
    			}
    			else if((u1ECValue == 0x60) || (u1ECValue == 0x50))
    			{
    				return SV_COLOR_HDMI_Colorimetry_BT2020;
    			}
    	    }
    	}
    	else //RGB
    	{
    		u1CNValue = u1IO32Read1B(AVIRX1_1 + u4ActiveHdmiRegBase) & 0xC0;
    		if( u1CNValue == 0x00) //no data
    		{
    			return SV_COLOR_HDMI_Colorimetry_RGB;
    		}
    		else if(u1CNValue == 0xc0)//refer extended colorimetry
    		{
    			u1ECValue = u1IO32Read1B(AVIRX1_2 + u4ActiveHdmiRegBase) >>4;
    			if((u1ECValue & 0x7) == 0x4)
    			{
    				return SV_COLOR_HDMI_Colorimetry_AdobeRGB;
    			}
    			else if((u1ECValue & 0x7) == 0x6)
    			{
    				return SV_COLOR_HDMI_Colorimetry_BT2020;
    			}
    		}
    	}
    }
	return SV_COLOR_HDMI_Colorimetry_UnKnown;
}


UINT8 DRVCUST_HDMIGetAspectRatio(void)
{
	UINT8 u1R4Value=0;
	UINT8 u1M2Value=0;
	UINT8 u1Ret=E_CUST_ASPECT_UNKNOWN;
	
	if(DRVCUST_HDMIWithValidAviInfo())    //Valid AviInfo
    {
    	u1R4Value = u1IO32Read1B(AVIRX1_1 + u4ActiveHdmiRegBase) & 0xf;
		u1M2Value = (u1IO32Read1B(AVIRX1_1 + u4ActiveHdmiRegBase) >>4) & 0x3;
		switch(u1R4Value)
		{
			case 0x8:
				if(u1M2Value == 1)
				{
					u1Ret = E_CUST_ASPECT_4_3;
				}
				else if(u1M2Value == 2)
				{
					u1Ret = E_CUST_ASPECT_16_9;
				}
				else
				{
					u1Ret=E_CUST_ASPECT_UNKNOWN;
				}
				break;
			case 0x9:
				u1Ret = E_CUST_ASPECT_4_3;
				break;
			case 0xa:
				u1Ret = E_CUST_ASPECT_16_9;
				break;
			case 0xb:
				u1Ret = E_CUST_ASPECT_14_9;
				break;
			default:
				u1Ret=E_CUST_ASPECT_UNKNOWN;
				break;
		}
	}

	return u1Ret;
}

UINT32 DRVCUST_GetOSMatrix709(UINT8 bPath)
{
    UINT32 u4Matrix709;

#if 1
    u4Matrix709 = GET_MATRIX_HD_709 && (wDrvVideoInputHeight(bPath) >= 720);
#else
    UINT32 u4ScrTiming = bDrvVideoGetSourceTypeTiming(bPath);
    u4Matrix709 = ((u4ScrTiming >= SOURCE_TYPE_TIMING_MM_SD_I) && (u4ScrTiming <= SOURCE_TYPE_TIMING_MM_1080IP_HD)) ? 
                    SV_FALSE : (GET_MATRIX_HD_709 && (wDrvVideoInputHeight(bPath) >= 720));
#endif
    return u4Matrix709;

}
UINT8 DRVCUST_MMGetHDRType(UINT8 bPath)
{	
	B2R_CUST_INFO_T t_B2RCustInfo;	
	
	if(!B2R_Get_Cust_info(bPath, B2R_GET_TYPE_CUST_INFO, &t_B2RCustInfo, sizeof(B2R_CUST_INFO_T)))
	{
		    LOG(2, "\n====== B2R_Get_Cust_info fail ======\n");
	}

	if(t_B2RCustInfo.tHdrDetectInfo.u4SEIHDRContent == 18)
	{
		return  SV_HDR_TYPE_HDR2;
	}
	else if(t_B2RCustInfo.tHdrDetectInfo.u4SEIHDRContent == 16)
	{
		return  SV_HDR_TYPE_HDR1;
	}
	else if(t_B2RCustInfo.tHdrDetectInfo.u4VUIHDRContent== 16)
	{
		return  SV_HDR_TYPE_HDR1;
	}
	else if(t_B2RCustInfo.tHdrDetectInfo.u4VUIHDRContent== 18)
	{
		return  SV_HDR_TYPE_HDR2;
	}
	else
	{
		return  SV_HDR_TYPE_SDR;
	}

}

void DRCUST_SetVP9HDRType(VP9_HDR_TYPE_E eHDRType)
{
	eVP9HDRType = eHDRType;
}

UINT8 DRVCUST_GetVP9HDRType(void)
{
	return (UINT8)eVP9HDRType;
}
void DRVCUST_Resume(void)
{
	PreHDRType = SV_HDR_TYPE_SDR;
	bIsSeamless = SV_FALSE;
	eVP9HDRType = SV_VP9_HDR_TYPE_NONE;
	//DRVCUST_MURA_CUCInit();
	DRVCUST_4KBE_OSTG_Bypass();
}

UINT8 DRVCUST_MMAPPGetTiming(UINT8 bOutputTiming)
{
    switch(bOutputTiming)
	{
        case SOURCE_TYPE_TIMING_MM_1080IP_HD:
		case SOURCE_TYPE_TIMING_MM_1080IP_SD:
            return SOURCE_TYPE_TIMING_NET_1080IP;

       	case SOURCE_TYPE_TIMING_MM_720P_SD:
		case SOURCE_TYPE_TIMING_MM_720P_HD:
            return SOURCE_TYPE_TIMING_NET_720P;

		case SOURCE_TYPE_TIMING_MM_SD_P:
			return SOURCE_TYPE_TIMING_NET_SD_P;
			
		case SOURCE_TYPE_TIMING_MM_SD_I:
            return SOURCE_TYPE_TIMING_NET_SD_I;
        default:
            return (bOutputTiming);
    }
	
}

extern OD_PARAM_T _ODParam;
void DRVCUST_SetODTable(void)
{
    //get OD table from flashPQ
    bApiFlashPqUpdateOD();

    //change OD table DMA, only support OD
    vDrvODSetDMA(OD_TABLE_CONFIG,OD_Table, sizeof(OD_Table));
    vDrvODMode(_ODParam.u1OD_ON);
    
    //channge OD table in Vsync
    //vApiRegisterVideoEvent(PE_EVENT_OD, SV_VP_MAIN, SV_ON);
}

#if 0
BOOL DRVCUST_WBSetPBMCtrlPointNum(UINT8 bSel)
{
	return DRVCUST_EepromWriteByte(EEP_WB_PBM_CTRL_POINT_SEL, bSel);
}
#endif

//Interpolate from 11 or 57 ctrl point to 257 point gamma curve
void DRVCUST_PBM_GAMLinearInterpolation(UINT32 u4CtrlCount, UINT16* u4CtrlPos, UINT16* u4TarCtrPos, INT32* iCtrlValue, INT32* OutputLut)
{
	int i, j;
	INT32 u4Temp;
	
	OutputLut[0] = iCtrlValue[0];
	OutputLut[256] = iCtrlValue[u4CtrlCount - 1];
	
	for(i=0; i<GAMMA_INDEX; i++)
	{
		for(j=0; j<u4CtrlCount-1; j++)
		{
			if((u4TarCtrPos[i] > u4CtrlPos[j]) && (u4TarCtrPos[i] <= u4CtrlPos[j+1]))
			{
				//Need do rounding
				u4Temp = (u4TarCtrPos[i] - u4CtrlPos[j]) * (iCtrlValue[j+1] - iCtrlValue[j]) * 10 / (u4CtrlPos[j+1] - u4CtrlPos[j]);
				OutputLut[i] = iCtrlValue[j] + ((u4Temp > 0) ? (u4Temp + 5)/10 : (u4Temp - 5)/10);
				break;
			}
		}
	}
	
	return;
}

#ifdef CC_MAPLE_CUST_DRV
//Only for Sakura, Salvia NO need
BOOL DRVCUST_GAMMA_Ofst_ADJ_UI(UINT8 u1Channel, UINT8 u1Index, UINT8 u1Value)
{
	UINT16 u2GammaIndex;

	u2GammaIndex = vApiFlashPqGetGammaId();

    LOG(2, "DRVCUST_GAMMA_Ofst_ADJ_UI: Channel: %d, Index: %d, Value: %d\n", u1Channel, u1Index, u1Value);
	//u1Channel: 0:R; 1:G; 2:B
	if(u1Channel>2 || u1Index>(GAMMA_10P_OFST_CTRL_POINT_NUM-1) || u1Value>40 || u1Value<0 || u2GammaIndex >= E_CT_MAX)
	{
		LOG(0, "Gamma Adjust UI error! Channel: %d, Index: %d, Value:%d, u2GammaIndex:%d\n",  u1Channel, u1Index, u1Value, u2GammaIndex);
		return SV_FALSE;
	}

	//AP set gamma!!!
	//DRVCUST_SET_GAMMA();

	i2WB10PUIValue[u1Channel][u1Index] = (INT16)(u1Value - 20);
	DRVCUST_SendEvent(E_CUST_WB_OFFSET_CHANGE, 0);
	
    u110POfst[u2GammaIndex][u1Channel][u1Index] = (UINT8)((INT32)u1Value - 20 + 128);
	if(SV_FALSE == DRVCUST_EepromWriteByte(EEP_WB_10P_OFST_G0_START + 
		(u2GammaIndex*3*GAMMA_10P_OFST_CTRL_POINT_NUM + u1Channel*GAMMA_10P_OFST_CTRL_POINT_NUM + u1Index), u110POfst[u2GammaIndex][u1Channel][u1Index]))
	{
		Printf("Write Gamma to EEPROM Fail!!\n");
		return SV_FALSE;
	}

	return SV_TRUE;
}
#if 1   //def CUST_S_AVOID_SVC_CHANGE_PROCESS_LONG_TIME
    BOOL DRVCUST_GAMMA_Ofst_ADJ_UI_GLOBLE(UINT8 u1Channel, UINT8 u1Index, UINT8 u1Value)
    {
        UINT16 u2GammaIndex;
        u2GammaIndex = vApiFlashPqGetGammaId();
    
        LOG(2, "DRVCUST_GAMMA_Ofst_ADJ_UI: Channel: %d, Index: %d, Value: %d\n", u1Channel, u1Index, u1Value);
        //u1Channel: 0:R; 1:G; 2:B
        if(u1Channel>2 || u1Index>(GAMMA_10P_OFST_CTRL_POINT_NUM-1) || u1Value>40 || u1Value<0 || u2GammaIndex >= E_CT_MAX)
        {
            LOG(0, "Gamma Adjust UI error! Channel: %d, Index: %d, Value:%d, u2GammaIndex:%d\n",  u1Channel, u1Index, u1Value, u2GammaIndex);
            return SV_FALSE;
        }
    
        //AP set gamma!!!
        //DRVCUST_SET_GAMMA();
    
        i2WB10PUIValue[u1Channel][u1Index] = (INT16)(u1Value - 20);
        DRVCUST_SendEvent(E_CUST_WB_OFFSET_CHANGE, 0);
        u110POfst[u2GammaIndex][u1Channel][u1Index] = (UINT8)((INT32)u1Value - 20 + 128);
        //below marked for delay time , every sigle value change , the whole arry be written
        /*
        if(SV_FALSE == DRVCUST_EepromWriteByte(EEP_WB_10P_OFST_G0_START + 
            (u2GammaIndex*3*GAMMA_10P_OFST_CTRL_POINT_NUM + u1Channel*GAMMA_10P_OFST_CTRL_POINT_NUM + u1Index), u110POfst[u2GammaIndex][u1Channel][u1Index]))
        {
            Printf("Write Gamma to EEPROM Fail!!\n");
            return SV_FALSE;
        }
        */
        return SV_TRUE;
    }
    
    BOOL DRVCUST_GAMMA_Ofst_ADJ_UI_Write2EEP(VOID)
    {
    
        if(SV_FALSE == EEPROM_Write(EEP_WB_10P_OFST_G0_START, (UINT32)u110POfst,(E_CT_MAX*SV_RGB_RGB*GAMMA_10P_OFST_CTRL_POINT_NUM)))
        {
            Printf("Write Gamma to EEPROM Done!!\n");
            return SV_TRUE;
        }
        else
        {
            return SV_FALSE;
        }
    
    }
    VOID DRVCUST_GAMMA_Ofst_ADJ_UI_ReadEEP(VOID)
    {
        UINT8 i;
        UINT8 j;
        UINT8 k;
        
        for(i=0;i<E_CT_MAX;i++)
        {
            for(j=0;j<SV_RGB_RGB;j++)
            {
                for(k=0;k<GAMMA_10P_OFST_CTRL_POINT_NUM;k++)
                {
                    Printf("u110POfst[%d][%d][%d]=%d\n",i,j,k,u110POfst[i][j][k]);
                }
            }
            
        }
    }
#endif
#endif

BOOL DRVCUST_SET_WB_GAM(UINT8 u1Channel, UINT8 u1Index, UINT8 u1Value)
{
    //u1Channel: 0:R; 1:G; 2:B
	if(u1Channel>2 || u1Index>(GAMMA_CTRL_POINT_NUM_TRACK-1) || u1Value<0)
	{
		LOG(0, "Tracking mode: Set WB_GAM_XX error! Channel: %d, Index: %d, Value:%d\n", u1Channel, u1Index, u1Value);
		return SV_FALSE;
	}

    if(SV_FALSE == DRVCUST_EepromWriteByte(EEP_WB_GAM0_START + (GAMMA_CTRL_POINT_NUM_TRACK*u1Channel + u1Index), u1Value))
	{
		LOG(0, "Tracking mode: Write WB_GAM_XX to EEPROM Fail!!\n");
		return SV_FALSE;
	}
	
    return SV_TRUE;
}

BOOL DRVCUST_SET_INP_LVL_WB(UINT8 u1Index, UINT16 u2Value)
{
    UINT8 u1Temp[2] = {0};
    //u1Channel: 0:R; 1:G; 2:B
	if(u1Index>(GAMMA_CTRL_POINT_NUM_TRACK-1) || u2Value>8192 || u2Value<0)
	{
		LOG(0, "Tracking mode: Set INP_LVL_WB_XX error! Index: %d, Value:%d\n", u1Index, u2Value);
		return SV_FALSE;
	}

    u1Temp[0] = u2Value & 0xFF;
    u1Temp[0] = (u2Value>>8) & 0xFF;
    
    if(SV_TRUE == DRVCUST_DoubleEepromWrite(EEP_WB_INP_LVL_START, (UINT32)u1Temp, 2))//DRVCUST_EepromWriteByte(EEP_WB_INP_LVL_START + u1Index*2, u1Value))
	{
		LOG(0, "Tracking mode: Write INP_LVL_WB_XX to EEPROM Fail!!\n");
		return SV_FALSE;
	}
	
    return SV_TRUE;
}

BOOL DRVCUST_SET_WB_GAM_GAIN(UINT8 u1Index, UINT8 u1Value)
{
	if(u1Index>(GAMMA_CTRL_POINT_NUM_TRACK-1) || u1Value<0)
	{
		LOG(0, "Tracking mode: Set WB_GAM_GAIN_XX error! Index: %d, Value:%d\n", u1Index, u1Value);
		return SV_FALSE;
	}

    if(SV_FALSE == DRVCUST_EepromWriteByte(EEP_WB_GAM_GAIN_START + u1Index, u1Value))
	{
		LOG(0, "Tracking mode: Write WB_GAM_GAIN_XX to EEPROM Fail!!\n");
		return SV_FALSE;
	}
	
    return SV_TRUE;
}

BOOL DRVCUST_SET_WB_BASE_GAIN(UINT8 u1ColorTemp, UINT8 u1Channel, UINT8 u1Value)
{
    //u1Channel: 0:R; 1:G; 2:B
	if(u1Channel>2)
	{
		LOG(0, "Tracking mode: Set WB_GAM_XX error! Channel: %d, Index: %d, Value:%d\n", u1Channel, u1Value);
		return SV_FALSE;
	}

    if(SV_FALSE == DRVCUST_EepromWriteByte(EEP_WB_BASE_GAIN_START + (u1ColorTemp*3 + u1Channel), u1Value))
	{
		LOG(0, "Tracking mode: Write WB_BASE_GAIN_XX to EEPROM Fail!!\n");
		return SV_FALSE;
	}
	
    return SV_TRUE;
}


BOOL DRVCUST_SET_WB_GAM_SEL(UINT8 u1Value)
{
	if(SV_FALSE == DRVCUST_EepromWriteByte(EEP_WB_GAM_SEL, u1Value))
	{
		LOG(0, "Tracking mode: Write WB_GAIN_SEL to EEPROM Fail!!\n");
		return SV_FALSE;
	}
	
    return SV_TRUE;
}

BOOL DRVCUST_SET_WB_OFST(UINT8 u1ColorTemp, UINT8 u1Channel, UINT8 u1Index, UINT8 u1Value)
{
    //u1Channel: 0:R; 1:G; 2:B
	if(u1Channel>2 || u1Index>(GAMMA_CTRL_POINT_NUM_TRACK-1) || u1Value<0)
	{
		LOG(0, "Tracking mode: Set WB_OFST_XX error! Channel: %d, Index: %d, Value:%d\n", u1Channel, u1Index, u1Value);
		return SV_FALSE;
	}

    if(SV_FALSE == DRVCUST_EepromWriteByte(EEP_WB_OFST_START + 
        (GAMMA_CTRL_POINT_NUM_TRACK*u1ColorTemp*3 + GAMMA_CTRL_POINT_NUM_TRACK*u1Channel + u1Index), u1Value))
	{
		LOG(0, "Tracking mode: Write WB_OFST_XX to EEPROM Fail!!\n");
		return SV_FALSE;
	}
	
    return SV_TRUE;
}

BOOL DRVCUST_SET_WBADJ_GODID_EEP(UINT8 u1Value)
{
    if(SV_FALSE == DRVCUST_EepromWriteByte(EEP_WB_WBADJ_GODID, u1Value))
    {
        LOG(0, "Write WBADJ_GODID to EEPROM Fail!!\n");
        return SV_FALSE;
    }
    return SV_TRUE;
}

BOOL DRVCUST_SET_WBADJ_PON_TIME_EEP(UINT8 u1Value)
{
    if(SV_FALSE == DRVCUST_EepromWriteByte(EEP_WB_WBADJ_PON_TIME, u1Value))
    {
        LOG(0, "Write WBADJ_PON_TIME to EEPROM Fail!!\n");
        return SV_FALSE;
    }
    return SV_TRUE;
}

BOOL DRVCUST_SET_WBADJ_JIG_VER_EEP(UINT16 u2Value)
{
    UINT8 u1Temp[2] = {0};

    LOG(1, "---->DRVCUST_SET_WBADJ_JIG_VER_EEP: %d\n", u2Value);
    u1Temp[0] = (UINT8)(u2Value & 0xFF);
    u1Temp[1] = (UINT8)((u2Value>>8) & 0xFF);
    
    if(SV_TRUE == DRVCUST_DoubleEepromWrite(EEP_WB_WBADJ_JJG_VER, (UINT32)u1Temp, 2))
    {
        LOG(0, "Write WBADJ_JIG_VER to EEPROM Fail!!\n");
        return SV_FALSE;
    }
    return SV_TRUE;
}

BOOL DRVCUST_SET_WBADJ_DS_DATE_EEP(UINT16 u2Value)
{
    UINT8 u1Temp[2] = {0};

    LOG(1, "---->DRVCUST_SET_WBADJ_DS_DATE_EEP: %d\n", u2Value);
    u1Temp[0] = (UINT8)(u2Value & 0xFF);
    u1Temp[1] = (UINT8)((u2Value>>8) & 0xFF);
    
    if(SV_TRUE == DRVCUST_DoubleEepromWrite(EEP_WB_WBADJ_DS_DATE, (UINT32)u1Temp, 2))
    {
        LOG(0, "Write WBADJ_DS_DATE to EEPROM Fail!!\n");
        return SV_FALSE;
    }
    return SV_TRUE;
}

BOOL DRVCUST_SET_WBADJ_ADJ_DATE_EEP(UINT16 u2Value)
{
    UINT8 u1Temp[2] = {0};

    LOG(1, "---->DRVCUST_SET_WBADJ_ADJ_DATE_EEP: %d\n", u2Value);
    u1Temp[0] = (UINT8)(u2Value & 0xFF);
    u1Temp[1] = (UINT8)((u2Value>>8) & 0xFF);
    
    if(SV_TRUE == DRVCUST_DoubleEepromWrite(EEP_WB_WBADJ_ADJ_DATE, (UINT32)u1Temp, 2))
    {
        LOG(0, "Write WBADJ_ADJ_DATE to EEPROM Fail!!\n");
        return SV_FALSE;
    }
    return SV_TRUE;
}

BOOL DRVCUST_SET_WBADJ_AGING1_EEP(UINT16 u2Value)
{
    UINT8 u1Temp[2] = {0};

    LOG(1, "---->DRVCUST_SET_WBADJ_AGING1_EEP: %d\n", u2Value);
    u1Temp[0] = (UINT8)(u2Value & 0xFF);
    u1Temp[1] = (UINT8)((u2Value>>8) & 0xFF);
    
    if(SV_TRUE == DRVCUST_DoubleEepromWrite(EEP_WB_WBADJ_AGING1, (UINT32)u1Temp, 2))
    {
        LOG(0, "Write WBADJ_AGING1 to EEPROM Fail!!\n");
        return SV_FALSE;
    }
    return SV_TRUE;
}

BOOL DRVCUST_SET_WBADJ_AGING2_EEP(UINT16 u2Value)
{
    UINT8 u1Temp[2] = {0};

    LOG(1, "---->DRVCUST_SET_WBADJ_AGING2_EEP: %d\n", u2Value);
    u1Temp[0] = (UINT8)(u2Value & 0xFF);
    u1Temp[1] = (UINT8)((u2Value>>8) & 0xFF);
    
    if(SV_TRUE == DRVCUST_DoubleEepromWrite(EEP_WB_WBADJ_AGING2, (UINT32)u1Temp, 2))
    {
        LOG(0, "Write WBADJ_AGING2 to EEPROM Fail!!\n");
        return SV_FALSE;
    }
    return SV_TRUE;
}

BOOL DRVCUST_SET_WBADJ_JJG_INFO1_EEP(UINT16 u2Value)
{
    UINT8 u1Temp[2] = {0};

    LOG(1, "---->DRVCUST_SET_WBADJ_JJG_INFO1_EEP: %d\n", u2Value);
    u1Temp[0] = (UINT8)(u2Value & 0xFF);
    u1Temp[1] = (UINT8)((u2Value>>8) & 0xFF);
    
    if(SV_TRUE == DRVCUST_DoubleEepromWrite(EEP_WB_WBADJ_JJG_INFO_1, (UINT32)u1Temp, 2))
    {
        LOG(0, "Write WBADJ_JJG_INFO_1 to EEPROM Fail!!\n");
        return SV_FALSE;
    }
    return SV_TRUE;
}

BOOL DRVCUST_SET_WBADJ_JJG_INFO2_EEP(UINT16 u2Value)
{
    UINT8 u1Temp[2] = {0};

    LOG(1, "---->DRVCUST_SET_WBADJ_JJG_INFO2_EEP: %d\n", u2Value);
    u1Temp[0] = (UINT8)(u2Value & 0xFF);
    u1Temp[1] = (UINT8)((u2Value>>8) & 0xFF);
    
    if(SV_TRUE == DRVCUST_DoubleEepromWrite(EEP_WB_WBADJ_JJG_INFO_2, (UINT32)u1Temp, 2))
    {
        LOG(0, "Write WBADJ_JJG_INFO_2 to EEPROM Fail!!\n");
        return SV_FALSE;
    }
    return SV_TRUE;
}

BOOL DRVCUST_SET_WB_INFO0_EEP(UINT16 u2Value)
{
    UINT8 u1Temp[2] = {0};

    LOG(1, "---->DRVCUST_SET_WB_INFO0_EEP: %d\n", u2Value);
    u1Temp[0] = (UINT8)(u2Value & 0xFF);
    u1Temp[1] = (UINT8)((u2Value>>8) & 0xFF);
    
    if(SV_TRUE == DRVCUST_DoubleEepromWrite(EEP_WB_INFO_0, (UINT32)u1Temp, 2))
    {
        LOG(0, "Write WBADJ_INFO_0 to EEPROM Fail!!\n");
        return SV_FALSE;
    }
    return SV_TRUE;
}

BOOL DRVCUST_SET_WB_INFO1_EEP(UINT16 u2Value)
{
    UINT8 u1Temp[2] = {0};

    LOG(1, "---->DRVCUST_SET_WB_INFO1_EEP: %d\n", u2Value);
    u1Temp[0] = (UINT8)(u2Value & 0xFF);
    u1Temp[1] = (UINT8)((u2Value>>8) & 0xFF);
    
    if(SV_TRUE == DRVCUST_DoubleEepromWrite(EEP_WB_INFO_1, (UINT32)u1Temp, 2))
    {
        LOG(0, "Write WBADJ_INFO_1 to EEPROM Fail!!\n");
        return SV_FALSE;
    }
    return SV_TRUE;
}

BOOL DRVCUST_SET_WB_INFO2_EEP(UINT16 u2Value)
{
    UINT8 u1Temp[2] = {0};

    LOG(1, "---->DRVCUST_SET_WB_INFO2_EEP: %d\n", u2Value);
    u1Temp[0] = (UINT8)(u2Value & 0xFF);
    u1Temp[1] = (UINT8)((u2Value>>8) & 0xFF);
    
    if(SV_TRUE == DRVCUST_DoubleEepromWrite(EEP_WB_INFO_2, (UINT32)u1Temp, 2))
    {
        LOG(0, "Write WBADJ_INFO_2 to EEPROM Fail!!\n");
        return SV_FALSE;
    }
    return SV_TRUE;
}

BOOL DRVCUST_SET_WB_INFO3_EEP(UINT16 u2Value)
{
    UINT8 u1Temp[2] = {0};

    LOG(1, "---->DRVCUST_SET_WB_INFO3_EEP: %d\n", u2Value);
    u1Temp[0] = (UINT8)(u2Value & 0xFF);
    u1Temp[1] = (UINT8)((u2Value>>8) & 0xFF);
    
    if(SV_TRUE == DRVCUST_DoubleEepromWrite(EEP_WB_INFO_3, (UINT32)u1Temp, 2))
    {
        LOG(0, "Write WBADJ_INFO_3 to EEPROM Fail!!\n");
        return SV_FALSE;
    }
    return SV_TRUE;
}

BOOL DRVCUST_SET_WB_INFO4_EEP(UINT16 u2Value)
{
    UINT8 u1Temp[2] = {0};

    LOG(1, "---->DRVCUST_SET_WB_INFO4_EEP: %d\n", u2Value);
    u1Temp[0] = (UINT8)(u2Value & 0xFF);
    u1Temp[1] = (UINT8)((u2Value>>8) & 0xFF);
    
    if(SV_TRUE == DRVCUST_DoubleEepromWrite(EEP_WB_INFO_4, (UINT32)u1Temp, 2))
    {
        LOG(0, "Write WBADJ_INFO_4 to EEPROM Fail!!\n");
        return SV_FALSE;
    }
    return SV_TRUE;
}
UINT8 DRVCUST_GET_WB_GAM(UINT8 u1Channel, UINT8 u1Index)
{
    //u1Channel: 0:R; 1:G; 2:B
	if(u1Channel>2 || u1Index>GAMMA_CTRL_POINT_NUM_TRACK-1)
	{
		LOG(0, "Tracking mode: Get WB_GAM_XX error! Channel: %d, Index: %d, Value:%d\n", u1Channel, u1Index);
		return SV_FALSE;
	}
	
    return DRVCUST_EepromReadByte(EEP_WB_GAM0_START + (GAMMA_CTRL_POINT_NUM_TRACK*u1Channel + u1Index));
}

UINT16 DRVCUST_GET_INP_LVL_WB(UINT8 u1Index)
{
    UINT8 u2Value[2] = {0};
    //u1Channel: 0:R; 1:G; 2:B
	if(u1Index>GAMMA_CTRL_POINT_NUM_TRACK-1)
	{
		LOG(0, "Tracking mode: Get INP_LVL_WB_XX error! Index: %d, Value:%d\n", u1Index);
		return SV_FALSE;
	}

    EEPROM_Read(EEP_WB_INP_LVL_START, (UINT32)u2Value, 2);
	
    return (u2Value[1]<<8 | u2Value[0]);
}

UINT8 DRVCUST_GET_WB_GAM_GAIN(UINT8 u1Index)
{
	if(u1Index>GAMMA_CTRL_POINT_NUM_TRACK-1)
	{
		LOG(0, "Tracking mode: Get WB_GAM_GAIN_XX error! Index: %d, Value:%d\n", u1Index);
		return SV_FALSE;
	}
	
    return DRVCUST_EepromReadByte(EEP_WB_GAM_GAIN_START + u1Index);
}

UINT8 DRVCUST_GET_WB_BASE_GAIN(UINT8 u1ColorTemp, UINT8 u1Channel)
{
    //u1Channel: 0:R; 1:G; 2:B
	if(u1Channel>2)
	{
		LOG(0, "Tracking mode: Get WB_GAM_XX error! Channel: %d, Index: %d, Value:%d\n", u1Channel);
		return SV_FALSE;
	}
	
    return DRVCUST_EepromReadByte(EEP_WB_BASE_GAIN_START + (u1ColorTemp*3 + u1Channel));
}

UINT8 DRVCUST_GET_WB_GAM_SEL(void)
{	
    return DRVCUST_EepromReadByte(EEP_WB_GAM_SEL);
}

UINT8 DRVCUST_GET_WB_OFST(UINT8 u1ColorTemp, UINT8 u1Channel, UINT8 u1Index)
{
    //u1Channel: 0:R; 1:G; 2:B
	if(u1Channel>2 || u1Index>GAMMA_CTRL_POINT_NUM_TRACK-1)
	{
		LOG(0, "Tracking mode: Get WB_OFST_XX error! Channel: %d, Index: %d, Value:%d\n", u1Channel, u1Index);
		return SV_FALSE;
	}
	
    return DRVCUST_EepromReadByte(EEP_WB_OFST_START + 
        (GAMMA_CTRL_POINT_NUM_TRACK*u1ColorTemp*3 + GAMMA_CTRL_POINT_NUM_TRACK*u1Channel + u1Index));
}

UINT8 DRVCUST_GET_WBADJ_GODID_EEP(void)
{
    return DRVCUST_EepromReadByte(EEP_WB_WBADJ_GODID);
}

UINT8 DRVCUST_GET_WBADJ_PON_TIME_EEP(void)
{
    return DRVCUST_EepromReadByte(EEP_WB_WBADJ_PON_TIME);
}

UINT16 DRVCUST_GET_WBADJ_JIG_VER_EEP(void)
{
    UINT8 u1Temp[2] = {0};

    EEPROM_Read(EEP_WB_WBADJ_JJG_VER, (UINT32)u1Temp, 2);
	
    return (UINT16)(u1Temp[1]<<8 | u1Temp[0]);
}

UINT16 DRVCUST_GET_WBADJ_DS_DATE_EEP(void)
{
    UINT8 u1Temp[2] = {0};

    EEPROM_Read(EEP_WB_WBADJ_DS_DATE, (UINT32)u1Temp, 2);
    
    return (UINT16)(u1Temp[1]<<8 | u1Temp[0]);
}



UINT16 DRVCUST_GET_WBADJ_ADJ_DATE_EEP(void)
{
    UINT8 u1Temp[2] = {0};

    EEPROM_Read(EEP_WB_WBADJ_ADJ_DATE, (UINT32)u1Temp, 2);
    
    return (UINT16)(u1Temp[1]<<8 | u1Temp[0]);
}


UINT16 DRVCUST_GET_WBADJ_AGING1_EEP(void)
{
    UINT8 u1Temp[2] = {0};

    EEPROM_Read(EEP_WB_WBADJ_AGING1, (UINT32)u1Temp, 2);
    
    return (UINT16)(u1Temp[1]<<8 | u1Temp[0]);
}


UINT16 DRVCUST_GET_WBADJ_AGING2_EEP(void)
{
    UINT8 u1Temp[2] = {0};

    EEPROM_Read(EEP_WB_WBADJ_AGING2, (UINT32)u1Temp, 2);
    
    return (UINT16)(u1Temp[1]<<8 | u1Temp[0]);
}


UINT16 DRVCUST_GET_WBADJ_JJG_INFO1_EEP(void)
{
    UINT8 u1Temp[2] = {0};

    EEPROM_Read(EEP_WB_WBADJ_JJG_INFO_1, (UINT32)u1Temp, 2);
    
    return (UINT16)(u1Temp[1]<<8 | u1Temp[0]);
}


UINT16 DRVCUST_GET_WBADJ_JJG_INFO2_EEP(void)
{
    UINT8 u1Temp[2] = {0};

    EEPROM_Read(EEP_WB_WBADJ_JJG_INFO_2, (UINT32)u1Temp, 2);
    
    return (UINT16)(u1Temp[1]<<8 | u1Temp[0]);
}


UINT16 DRVCUST_GET_WB_INFO0_EEP(void)
{
    UINT8 u1Temp[2] = {0};

    EEPROM_Read(EEP_WB_INFO_0, (UINT32)u1Temp, 2);
    
    return (UINT16)(u1Temp[1]<<8 | u1Temp[0]);
}


UINT16 DRVCUST_GET_WB_INFO1_EEP(void)
{
    UINT8 u1Temp[2] = {0};

    EEPROM_Read(EEP_WB_INFO_1, (UINT32)u1Temp, 2);
    
    return (UINT16)(u1Temp[1]<<8 | u1Temp[0]);
}


UINT16 DRVCUST_GET_WB_INFO2_EEP(void)
{
    UINT8 u1Temp[2] = {0};

    EEPROM_Read(EEP_WB_INFO_2, (UINT32)u1Temp, 2);
    
    return (UINT16)(u1Temp[1]<<8 | u1Temp[0]);
}


UINT16 DRVCUST_GET_WB_INFO3_EEP(void)
{
    UINT8 u1Temp[2] = {0};

    EEPROM_Read(EEP_WB_INFO_3, (UINT32)u1Temp, 2);
    
    return (UINT16)(u1Temp[1]<<8 | u1Temp[0]);
}


UINT16 DRVCUST_GET_WB_INFO4_EEP(void)
{
    UINT8 u1Temp[2] = {0};

    EEPROM_Read(EEP_WB_INFO_4, (UINT32)u1Temp, 2);
    
    return (UINT16)(u1Temp[1]<<8 | u1Temp[0]);
}

UINT8 DRVCUST_GET_WB_GAM_ForFac(UINT8 u1Channel, UINT8 u1Index)
{
    //u1Channel: 0:R; 1:G; 2:B
	if(u1Channel>2 || u1Index>GAMMA_CTRL_POINT_NUM_TRACK-1)
	{
		LOG(0, "Tracking mode: DRVCUST_GET_WB_GAM_ForFac error! Channel: %d, Index: %d\n", u1Channel, u1Index);
		return SV_FALSE;
	}
	
    return u1WB_GAM_RGB[u1Channel][u1Index];
}

UINT16 DRVCUST_GET_INP_LVL_WB_ForFac(UINT8 u1Index)
{
    //u1Channel: 0:R; 1:G; 2:B
	if(u1Index>GAMMA_CTRL_POINT_NUM_TRACK-1)
	{
		LOG(0, "Tracking mode: DRVCUST_GET_INP_LVL_WB_ForFac error! Index: %d\n", u1Index);
		return SV_FALSE;
	}
	
    return u2WB_INP_LVL_Fac[u1Index];
}

UINT8 DRVCUST_GET_WB_GAM_GAIN_ForFac(UINT8 u1Index)
{
	if(u1Index>GAMMA_CTRL_POINT_NUM_TRACK-1)
	{
		LOG(0, "Tracking mode: DRVCUST_GET_WB_GAM_GAIN_ForFac error! Index: %d\n", u1Index);
		return SV_FALSE;
	}
	
    return u1WB_GAM_GAIN[u1Index];
}

UINT8 DRVCUST_GET_WB_BASE_GAIN_ForFac(UINT8 u1Channel)
{
    //u1Channel: 0:R; 1:G; 2:B
	if(u1Channel>2)
	{
		LOG(0, "Tracking mode: DRVCUST_GET_WB_BASE_GAIN_ForFac error! Channel: %d\n", u1Channel);
		return SV_FALSE;
	}
	
    return u1WB_BASE_GAIN_RGB_EEP[stCTInfo.ui1CTIndex][u1Channel];
}

UINT8 DRVCUST_GET_WB_OFST_ForFac(UINT8 u1Channel, UINT8 u1Index)
{
    //u1Channel: 0:R; 1:G; 2:B
	if(u1Channel>2 || u1Index>GAMMA_CTRL_POINT_NUM_TRACK-1)
	{
		LOG(0, "Tracking mode: DRVCUST_GET_WB_OFST_ForFac error! Channel: %d, Index: %d\n", u1Channel, u1Index);
		return SV_FALSE;
	}
	
    return u1WB_OFST_RGB[stCTInfo.ui1CTIndex][u1Channel][u1Index];
}

void DRVCUST_SET_GAMMA(void)
{
	UINT32 i, j;		
	UINT8 u1CttlPointNum;
	static UINT8 bBootUp=SV_TRUE;			
	static INT32 i4GamCurveRGB[SV_RGB_RGB][GAMMA_INDEX];
	static UINT8 u1GammaPBMMode;
	UINT16 u2TarCtlPos[GAMMA_INDEX];
	UINT16 u2GammaIndex;
	
	#ifdef CC_MAPLE_CUST_DRV
    UINT8 u1EepInplvl10PBuf[GAMMA_10P_OFST_CTRL_POINT_NUM*sizeof(UINT16)];
	#endif
	
	bGammaInit = SV_FALSE;		
	
	vApiFlashPqSetGammaId(stCTInfo.ui1CTIndex); 

	u2GammaIndex = vApiFlashPqGetGammaId();

	if(u2GammaIndex >= E_CT_MAX)
	{
		Printf("DRVCUST_SET_GAMMA Gamma index error!!\n");
		Printf("u2GammaIndex : %d\n", u2GammaIndex);
		return;
	}
	
	//PBM and Tracking use different gamma points.
	u1GammaPBMMode = DRVCUST_EepromReadByte(EEP_WB_LUT_ADJ_ON);
	//bColorIndex = MIN(E_CT_MAX-1, bColorIndex);

    printf("WB Method  %d, CT_Index:%d   Gamma_Index : %d \n", u1GammaPBMMode, stCTInfo.ui1CTIndex, u2GammaIndex);
    
	//This for temporary check, because the EEPROM have NOT ready!!
	if((DRVCUST_EepromReadByte(EEP_WB_TRAK_MAGIC_NUM_START) != GAMMA_MAGIC00) &&
		(DRVCUST_EepromReadByte(EEP_WB_TRAK_MAGIC_NUM_START + 1) != GAMMA_MAGIC01) &&
		(DRVCUST_EepromReadByte(EEP_WB_PBM_MAGIC_NUM00) != GAMMA_MAGIC01) &&
		(DRVCUST_EepromReadByte(EEP_WB_PBM_MAGIC_NUM01) != GAMMA_MAGIC01))
	{
		bApiFlashPqUpdateGamma();
		vDrvGammaDecodeTable();
		vDrvSetGammaWritePingPongFlag(SV_TRUE); 
		return;
	}

	if(!u1GammaPBMMode)//Tracking	
	{
	    UINT8 u1WB_INP_LVL_EEP_BUF[GAMMA_CTRL_POINT_NUM_TRACK*2]={0};
	    /*
		static UINT8 u1WB_GAM_RGB[SV_RGB_RGB][GAMMA_CTRL_POINT_NUM_TRACK];
		static UINT8 u1WB_OFST_RGB[E_CT_MAX][SV_RGB_RGB][GAMMA_CTRL_POINT_NUM_TRACK];
		static UINT8 u1WB_GAM_GAIN[GAMMA_CTRL_POINT_NUM_TRACK];
		static UINT16 u2WB_INP_LVL[GAMMA_CTRL_POINT_NUM_TRACK];
		static UINT8 u1WB_BASE_GAIN_RGB_EEP[E_CT_MAX][SV_RGB_RGB];
		*/

		INT32 u4Determination_OFST[SV_RGB_RGB][GAMMA_CTRL_POINT_NUM_TRACK];
		//INT32 i4New_OFST[SV_RGB_RGB][GAMMA_CTRL_POINT_NUM_TRACK];
		INT32 iWB_BASE_GAIN_RGB[E_CT_MAX][SV_RGB_RGB];
		Printf("Tracking \n\n");
		
#ifdef CC_SONY_GAMMA
		/* init all gamma related parameters */
		//DRVCUST_Gamma_Init();
		//x_thread_delay(100);
#endif /* CC_SONY_GAMMA */

		if((DRVCUST_EepromReadByte(EEP_WB_TRAK_MAGIC_NUM_START) != GAMMA_MAGIC00) || 
			(DRVCUST_EepromReadByte(EEP_WB_TRAK_MAGIC_NUM_START + 1) != GAMMA_MAGIC01) || (bGammaLinear == SV_TRUE))
		{																																						  
			// Apply linear gamma			
			
			for (i=0; i<GAMMA_INDEX; i++)																														  
			{																																				  
				i4GamCurveRGB[SV_RGB_R][i] = i<<4; 																										  
				i4GamCurveRGB[SV_RGB_G][i] = i<<4; 																										  
				i4GamCurveRGB[SV_RGB_B][i] = i<<4; 																										  
			}
		}																																						  
		else// Gamma was enabled																																  
		{
			// Get EEPROM Gamma
			if(bBootUp || u1IsForceWBEepReload()) 	//Read PBM data from EEPROM 1st time to initialize gamma
			{
				if(EEPROM_Read(EEP_WB_GAM0_START, (UINT32)&u1WB_GAM_RGB, GAMMA_CTRL_POINT_NUM_TRACK*SV_RGB_RGB))
				{
					Printf("Read Gamma from EEPROM Fail!!\n");
				}
				if(EEPROM_Read(EEP_WB_OFST_START, (UINT32)&u1WB_OFST_RGB, E_CT_MAX*SV_RGB_RGB*GAMMA_CTRL_POINT_NUM_TRACK))
				{
					Printf("Read Gamma from EEPROM Fail!!\n");
				}
				if(EEPROM_Read(EEP_WB_GAM_GAIN_START, (UINT32)&u1WB_GAM_GAIN, GAMMA_CTRL_POINT_NUM_TRACK))
				{
					Printf("Read Gamma from EEPROM Fail!!\n");
				}
				if(EEPROM_Read(EEP_WB_INP_LVL_START, (UINT32)&u1WB_INP_LVL_EEP_BUF, GAMMA_CTRL_POINT_NUM_TRACK*2))
				{
					Printf("Read Gamma from EEPROM Fail!!\n");
				}
				u2WB_INP_LVL[0] = (u1WB_INP_LVL_EEP_BUF[0*2+1] << 8 | u1WB_INP_LVL_EEP_BUF[0*2]) >> 4;
    			for(i=1; i<GAMMA_CTRL_POINT_NUM_TRACK; i++)
    			{
    			    u2WB_INP_LVL[i] = u1WB_INP_LVL_EEP_BUF[i*2+1] << 8 | u1WB_INP_LVL_EEP_BUF[i*2];
    			    
    				if(u2WB_INP_LVL[i] < u2WB_INP_LVL[i-1])
    				{
    					u2WB_INP_LVL[i] = (u2WB_INP_LVL[i-1]<=4096) ? u2WB_INP_LVL[i-1] : 4096;
    				}
    				u2WB_INP_LVL_Fac[i] = u2WB_INP_LVL[i];
    				u2WB_INP_LVL[i] = u2WB_INP_LVL[i] >> 4;
    			}
				if(EEPROM_Read(EEP_WB_BASE_GAIN_START, (UINT32)&u1WB_BASE_GAIN_RGB_EEP, SV_RGB_RGB*E_CT_MAX))
				{
					Printf("Read Gamma from EEPROM Fail!!\n");
				}
			}

			for(i=0; i<GAMMA_CTRL_POINT_NUM_TRACK; i++)
			{
				u4Determination_OFST[SV_RGB_R][i] = ((INT32)((u1WB_GAM_RGB[SV_RGB_R][i] - 128) + (u1WB_OFST_RGB[u2GammaIndex][SV_RGB_R][i] -128))) * u1WB_GAM_GAIN[i];
				u4Determination_OFST[SV_RGB_G][i] = ((INT32)((u1WB_GAM_RGB[SV_RGB_G][i] - 128) + (u1WB_OFST_RGB[u2GammaIndex][SV_RGB_G][i] -128))) * u1WB_GAM_GAIN[i];
				u4Determination_OFST[SV_RGB_B][i] = ((INT32)((u1WB_GAM_RGB[SV_RGB_B][i] - 128) + (u1WB_OFST_RGB[u2GammaIndex][SV_RGB_B][i] -128))) * u1WB_GAM_GAIN[i];
			}

			for(i=0; i<GAMMA_INDEX; i++)
			{
				u2TarCtlPos[i] = i;
			}

			//Only for debug log
			LOG(4, "***********Track GAMMA Parameter ***********\nCtrlIdx    WB_GAM_R    WB_GAM_G    WB_GAM_B    WB_OFST_R    WB_OFST_G    WB_OFST_B\n");
			for(i=0; i<GAMMA_CTRL_POINT_NUM_TRACK; i++)
			{
			    LOG(4, "  %04d	  %04d	  %04d	  %04d	  %04d	  %04d	  %04d\n", i, u1WB_GAM_RGB[SV_RGB_R][i], u1WB_GAM_RGB[SV_RGB_G][i], u1WB_GAM_RGB[SV_RGB_B][i],
			        u1WB_OFST_RGB[u2GammaIndex][SV_RGB_R][i], u1WB_OFST_RGB[u2GammaIndex][SV_RGB_G][i], u1WB_OFST_RGB[u2GammaIndex][SV_RGB_B][i]);
			}

			for(i=0; i<GAMMA_CTRL_POINT_NUM_TRACK; i++)
			{
			    if(i==0)
			    {
                    LOG(4, "WB_GAM_GAIN:\n");
			    }
			    LOG(4, "    %04d\n",  u1WB_GAM_GAIN[i]);
			}

			for(i=0; i<GAMMA_CTRL_POINT_NUM_TRACK; i++)
			{
			    if(i==0)
			    {
                    LOG(4, "WB_INP_LVL:\n");
			    }
			    LOG(4, "  %04d\n", u2WB_INP_LVL[i]);
			}

			LOG(4, "WB_BASE_GAIN_RGB:   %04d	  %04d	  %04d\n", u1WB_BASE_GAIN_RGB_EEP[u2GammaIndex][SV_RGB_R], u1WB_BASE_GAIN_RGB_EEP[u2GammaIndex][SV_RGB_G], u1WB_BASE_GAIN_RGB_EEP[u2GammaIndex][SV_RGB_B]);
			
			LOG(4, "***********Track GAMMA Parameter END***********\n\n");

			LOG(3, "***********Track GAMMA u4Determination_OFST ***********\nCtrlIdx    R    G    B\n");
			for(i=0; i<GAMMA_CTRL_POINT_NUM_TRACK; i++)
			{
			    for(j=0; j<SV_RGB_RGB; j++)
			    {
				    LOG(3, "  %04d	  %04d	  %04d	  %04d\n", i, u4Determination_OFST[SV_RGB_R][i], u4Determination_OFST[SV_RGB_G][i], u4Determination_OFST[SV_RGB_B][i]);
                }
			}
			LOG(3, "***********Track GAMMA u4Determination_OFST END***********\n\n");

			//New OFST, ofst interpolate from 11 ctrl point to 257 point.
			DRVCUST_PBM_GAMLinearInterpolation(GAMMA_CTRL_POINT_NUM_TRACK, u2WB_INP_LVL, u2TarCtlPos, u4Determination_OFST[0], i4GamCurveRGB[0]);
			DRVCUST_PBM_GAMLinearInterpolation(GAMMA_CTRL_POINT_NUM_TRACK, u2WB_INP_LVL, u2TarCtlPos, u4Determination_OFST[1], i4GamCurveRGB[1]);
			DRVCUST_PBM_GAMLinearInterpolation(GAMMA_CTRL_POINT_NUM_TRACK, u2WB_INP_LVL, u2TarCtlPos, u4Determination_OFST[2], i4GamCurveRGB[2]);

			//Only for debug log
			LOG(3, "***********Track GAMMA New Offset***********\nCtrlIdx  CtrlPos	R_OFST	G_OFST	B_OFST\n");
			for(i=0; i<GAMMA_INDEX; i++)
			{
				LOG(3, "  %04d	  %04d	  %04d	  %04d	  %04d\n", i, u2TarCtlPos[i], i4GamCurveRGB[0][i], i4GamCurveRGB[1][i], i4GamCurveRGB[2][i]);
			}
			LOG(3, "***********Track GAMMA New Offset END***********\n\n");
				
			for(i=0; i<E_CT_MAX; i++)
			{
				for(j=0; j<SV_RGB_RGB; j++)
				{
					iWB_BASE_GAIN_RGB[i][j] = u1WB_BASE_GAIN_RGB_EEP[i][j]; 	//convert from UINT8 to INT32, because the max the 0xff, if NOT convert,  (u1WB_BASE_GAIN_RGB_EEP + 1 >> 8) will error.

				}
			}

			for(i=0; i<GAMMA_INDEX; i++)
			{
				i4GamCurveRGB[SV_RGB_R][i] = ((u4WB_BASE_VALUE[i] * (iWB_BASE_GAIN_RGB[u2GammaIndex][SV_RGB_R] + 1))>>8) + i4GamCurveRGB[SV_RGB_R][i];
				i4GamCurveRGB[SV_RGB_G][i] = ((u4WB_BASE_VALUE[i] * (iWB_BASE_GAIN_RGB[u2GammaIndex][SV_RGB_G] + 1))>>8) + i4GamCurveRGB[SV_RGB_G][i];
				i4GamCurveRGB[SV_RGB_B][i] = ((u4WB_BASE_VALUE[i] * (iWB_BASE_GAIN_RGB[u2GammaIndex][SV_RGB_B] + 1))>>8) + i4GamCurveRGB[SV_RGB_B][i];
			}
		}
	}	
	else // PBM 																																				  
	{																																							  
		if((DRVCUST_EepromReadByte(EEP_WB_PBM_MAGIC_NUM00) != GAMMA_MAGIC00) || 
			(DRVCUST_EepromReadByte(EEP_WB_PBM_MAGIC_NUM01) != GAMMA_MAGIC01) || (bGammaLinear == SV_TRUE))
		{																																						  
			// Apply linear gamma			
			
			for (i=0; i<GAMMA_INDEX; i++)																														  
			{																																				  
				i4GamCurveRGB[SV_RGB_R][i] = i<<4; 																										  
				i4GamCurveRGB[SV_RGB_G][i] = i<<4; 																										  
				i4GamCurveRGB[SV_RGB_B][i] = i<<4; 																										  
			}
		}		
		else
		{
		// 5 Gamma for color temp
		// 3 channel R, G, B for each Gamma
		// 33 points for each channel
		// 2 bytes for each points 
		static UINT8 u1EEPGammaBuf[E_CT_MAX][SV_RGB_RGB][GAMMA_CTRL_POINT_NUM_PBM * 2];
		UINT16 u2CtlPos[GAMMA_CTRL_POINT_NUM_PBM] = {0};
		
		INT32 iCtlValue_RGB[SV_RGB_RGB][GAMMA_CTRL_POINT_NUM_PBM];
			
		LOG(0, "PBM GAMMA\n\n");

	#ifdef CC_MAPLE_CUST_DRV
        //For Sakura
        u1CttlPointNum = GAMMA_CTRL_POINT_NUM_PBM;
    #else
        //For Salvia
        u1CttlPointNum = GAMMA_CTRL_POINT_NUM2_PBM;
    #endif
        for(i=0; i< u1CttlPointNum; i++)
        {
            u2CtlPos[i] = u2CtlPos_PBM[i];
        }
        
		if(bBootUp || u1IsForceWBEepReload())//Read PBM data from EEPROM 1st time to initialize gamma
		{
			if(EEPROM_Read(EEP_WB_LUT_ADJ_G0_START,(UINT32)&u1EEPGammaBuf, E_CT_MAX*GAMMA_CTRL_POINT_NUM_PBM*2*SV_RGB_RGB))
			{
				Printf("Read Gamma from EEPROM Fail!!\n");
			}
		}

		LOG(3, "***********PBM GAMMA CONTROL POINT***********\n  CtrlIdx	CtrlPos    R	 G	  B\n");
		
		// Get EEPROM Gamma  from buffer (EEPROM already meet magic No.)
		for (i=0; i<u1CttlPointNum; i++)																														  
		{																																				  
			iCtlValue_RGB[SV_RGB_R][i] = (INT32)(u1EEPGammaBuf[u2GammaIndex][SV_RGB_R][i*2+1]<<8) |
								        u1EEPGammaBuf[u2GammaIndex][SV_RGB_R][i*2];
																																							  
			iCtlValue_RGB[SV_RGB_G][i] = (INT32)(u1EEPGammaBuf[u2GammaIndex][SV_RGB_G][i*2+1]<<8) |
								        u1EEPGammaBuf[u2GammaIndex][SV_RGB_G][i*2];	
																																							  
			iCtlValue_RGB[SV_RGB_B][i] = (INT32)(u1EEPGammaBuf[u2GammaIndex][SV_RGB_B][i*2+1]<<8) |
								        u1EEPGammaBuf[u2GammaIndex][SV_RGB_B][i*2];	

			LOG(3, "  %d,  %d,  %04d, %04d, %04d\n", i, u2CtlPos[i], iCtlValue_RGB[SV_RGB_R][i], iCtlValue_RGB[SV_RGB_G][i], iCtlValue_RGB[SV_RGB_B][i]);
		}
		LOG(3, "***********PBM GAMMA CONTROL POINT END***********\n");
		
#if 1//def CC_Factory2K12
		for (i=0; i<u1CttlPointNum; ++i)
		{
			_iUsedCtlValue_R[i] = iCtlValue_RGB[SV_RGB_R][i];
			_iUsedCtlValue_G[i] = iCtlValue_RGB[SV_RGB_G][i];
			_iUsedCtlValue_B[i] = iCtlValue_RGB[SV_RGB_B][i];
		}
#endif

		for(i=0; i<GAMMA_INDEX; i++)
		{
			u2TarCtlPos[i] = i;
		}
		// GAMMA INTERPOLATION																																		
		DRVCUST_PBM_GAMLinearInterpolation(u1CttlPointNum, u2CtlPos, u2TarCtlPos, iCtlValue_RGB[SV_RGB_R], i4GamCurveRGB[SV_RGB_R]);	
		DRVCUST_PBM_GAMLinearInterpolation(u1CttlPointNum, u2CtlPos, u2TarCtlPos, iCtlValue_RGB[SV_RGB_G], i4GamCurveRGB[SV_RGB_G]); 
		DRVCUST_PBM_GAMLinearInterpolation(u1CttlPointNum, u2CtlPos, u2TarCtlPos, iCtlValue_RGB[SV_RGB_B], i4GamCurveRGB[SV_RGB_B]);																																										  
		}
	}		

    _iUsedColorTemp = u2GammaIndex;
    
#ifdef CC_MAPLE_CUST_DRV
	//Only for Sakura, Salvia NO need
	if(bBootUp || u1IsForceWBEepReload())
	{
		if(EEPROM_Read(EEP_WB_10P_OFST_G0_START,(UINT32)&u110POfst, E_CT_MAX*GAMMA_10P_OFST_CTRL_POINT_NUM*SV_RGB_RGB))
		{
			Printf("Read Gamma from EEPROM Fail!!\n");
		}
		if(EEPROM_Read(EEP_WB_GAM_10P_GAIN_START,(UINT32)&u1Gam10PGain, GAMMA_10P_OFST_CTRL_POINT_NUM))
		{
			Printf("Read Gamma from EEPROM Fail!!\n");
		}
		if(EEPROM_Read(EEP_INP_LVL_10P_START,(UINT32)&u1EepInplvl10PBuf, GAMMA_10P_OFST_CTRL_POINT_NUM*2))
		{
			Printf("Read Gamma from EEPROM Fail!!\n");
		}
		for(i=0; i<GAMMA_10P_OFST_CTRL_POINT_NUM; i++)
		{
            u2Inplvl10P[i] = u1EepInplvl10PBuf[i*2+1]<<8 | u1EepInplvl10PBuf[i*2];
            u2Inplvl10P[i] = u2Inplvl10P[i] >> 4;
		}
	}

	if(bWBFlatPreOnoff == SV_FALSE)
	{
		i4Ctrl10POfst[SV_RGB_R][0] = 0;
		i4Ctrl10POfst[SV_RGB_G][0] = 0;
		i4Ctrl10POfst[SV_RGB_B][0] = 0;

		for(i=1; i<GAMMA_10P_OFST_CTRL_POINT_NUM; i++)
		{
			i4Ctrl10POfst[SV_RGB_R][i] = ((INT32)u110POfst[u2GammaIndex][SV_RGB_R][i] - 128) * u1Gam10PGain[i];
			i4Ctrl10POfst[SV_RGB_G][i] = ((INT32)u110POfst[u2GammaIndex][SV_RGB_G][i] - 128) * u1Gam10PGain[i];
			i4Ctrl10POfst[SV_RGB_B][i] = ((INT32)u110POfst[u2GammaIndex][SV_RGB_B][i] - 128) * u1Gam10PGain[i];
		}

		//Only for debug log
		LOG(4, "***********User 10P GAMMA Parameters***********\n  CtrlIdx    INP_LVL    GAM_GAIN	 1OFST_R	  OFST_G    OFST_B\n");
		for (i=0; i<GAMMA_10P_OFST_CTRL_POINT_NUM; i++) 																													  
		{																																				  
			LOG(4, "  %d,  %04d,  %04d,  %04d,    %04d,    %04d\n", i, u1Gam10PGain[i], u2Inplvl10P[i], u110POfst[u2GammaIndex][SV_RGB_R][i], 
			    u110POfst[u2GammaIndex][SV_RGB_G][i], u110POfst[u2GammaIndex][SV_RGB_B][i]);
		}
		LOG(4, "***********User 10P GAMMA Parameters END***********\n");
		
		LOG(3, "***********User 10P GAMMA CONTROL POINT***********\n  CtrlIdx	 R	  G    B\n");
		for (i=0; i<GAMMA_10P_OFST_CTRL_POINT_NUM; i++) 																													  
		{																																				  
			LOG(3, "  %d,  %04d,  %04d,    %04d,    %04d\n", i, u2Inplvl10P[i], i4Ctrl10POfst[0][i], i4Ctrl10POfst[1][i], i4Ctrl10POfst[2][i]);
		}
		LOG(3, "***********User 10P GAMMA CONTROL POINT END***********\n");

		for(i=0; i<GAMMA_INDEX; i++)
		{
			u2TarCtlPos[i] = i;
		}

		DRVCUST_PBM_GAMLinearInterpolation(GAMMA_10P_OFST_CTRL_POINT_NUM, u2Inplvl10P, u2TarCtlPos, i4Ctrl10POfst[SV_RGB_R], i4Gam10POfst[SV_RGB_R]); 
		DRVCUST_PBM_GAMLinearInterpolation(GAMMA_10P_OFST_CTRL_POINT_NUM, u2Inplvl10P, u2TarCtlPos, i4Ctrl10POfst[SV_RGB_G], i4Gam10POfst[SV_RGB_G]); 
		DRVCUST_PBM_GAMLinearInterpolation(GAMMA_10P_OFST_CTRL_POINT_NUM, u2Inplvl10P, u2TarCtlPos, i4Ctrl10POfst[SV_RGB_B], i4Gam10POfst[SV_RGB_B]);

		for(i=0; i<SV_RGB_RGB; i++)
		{
			for(j=0; j<GAMMA_INDEX; j++)
			{
				i4GamCurveRGB[i][j] += i4Gam10POfst[i][j] ;
			}
		}
	}		
#endif

	//Only for debug log
	LOG(5, "***********HW GAMMA CURVE AFTER INTP***********\n  Idx	  R 	G	  B\n");
	for(i=0; i<GAMMA_INDEX; i++)
	{
		LOG(5, " %04d  %04d  %04d  %04d\n", i, i4GamCurveRGB[0][i], i4GamCurveRGB[1][i], i4GamCurveRGB[2][i]);
	}
	LOG(5, "***********HW GAMMA CURVE AFTER INTP END***********\n");	

	for(i=0; i<GAMMA_INDEX; i++)
    {
        for(j=0; j<SV_RGB_RGB; j++)
        {
            if(i4GamCurveRGB[j][i] < 0)
            {
                i4GamCurveRGB[j][i] = 0;
            }
            if(i4GamCurveRGB[j][i] > ((i==GAMMA_INDEX-1) ? 4096 : 4095))
            {
                i4GamCurveRGB[j][i] = ((i==GAMMA_INDEX-1) ? 4096 : 4095);
            }
        }
    }
	
	u2GammaDecodedTable[SV_RGB_R][0] = (UINT16)(i4GamCurveRGB[SV_RGB_R][0]);																									  
	u2GammaDecodedTable[SV_RGB_G][0] = (UINT16)(i4GamCurveRGB[SV_RGB_G][0]);																									  
	u2GammaDecodedTable[SV_RGB_B][0] = (UINT16)(i4GamCurveRGB[SV_RGB_B][0]);																										  
	wHwGammaCurve[SV_RGB_R][0] = (UINT16)(i4GamCurveRGB[SV_RGB_R][0]);																											  
	wHwGammaCurve[SV_RGB_G][0] = (UINT16)(i4GamCurveRGB[SV_RGB_G][0]);																											  
	wHwGammaCurve[SV_RGB_B][0] = (UINT16)(i4GamCurveRGB[SV_RGB_B][0]);	

	//limter before to decoder table.																																							  
	for (i=1; i<GAMMA_INDEX; i++) 																																	  
	{																																						  
		if ((i4GamCurveRGB[SV_RGB_R][i] < i4GamCurveRGB[SV_RGB_R][i-1]) || (i4GamCurveRGB[SV_RGB_R][i]==0))																					  
		{																																				  
			i4GamCurveRGB[SV_RGB_R][i] = i4GamCurveRGB[SV_RGB_R][i-1];																										  
		}																																				  
		if ((i4GamCurveRGB[SV_RGB_G][i] < i4GamCurveRGB[SV_RGB_G][i-1]) || (i4GamCurveRGB[SV_RGB_G][i]==0))																					  
		{																																				  
			i4GamCurveRGB[SV_RGB_G][i] = i4GamCurveRGB[SV_RGB_G][i-1];																										  
		}																																				  
		if ((i4GamCurveRGB[SV_RGB_B][i] < i4GamCurveRGB[SV_RGB_B][i-1]) || (i4GamCurveRGB[SV_RGB_B][i]==0))																					  
		{																																				  
			i4GamCurveRGB[SV_RGB_B][i] = i4GamCurveRGB[SV_RGB_B][i-1];																										  
		}																																				  
																																						  
		u2GammaDecodedTable[SV_RGB_R][i] = (UINT16)(i4GamCurveRGB[SV_RGB_R][i]);																									  
		u2GammaDecodedTable[SV_RGB_G][i] = (UINT16)(i4GamCurveRGB[SV_RGB_G][i]);																									  
		u2GammaDecodedTable[SV_RGB_B][i] = (UINT16)(i4GamCurveRGB[SV_RGB_B][i]);																									  
		wHwGammaCurve[SV_RGB_R][i] = (UINT16)(i4GamCurveRGB[SV_RGB_R][i]);																										  
		wHwGammaCurve[SV_RGB_G][i] = (UINT16)(i4GamCurveRGB[SV_RGB_G][i]);																										  
		wHwGammaCurve[SV_RGB_B][i] = (UINT16)(i4GamCurveRGB[SV_RGB_B][i]);	
	}			

	vDrvSetGammaWritePingPongFlag(SV_TRUE);
	
	bBootUp = SV_FALSE;
	bGammaInit = SV_TRUE;
	DRVCUST_SetGammaRemapForceLoad(SV_ON); //ForceGammaRemmap
}

UINT8 DRVCUST_GET_CTMode(void)
{
      return TRUE;
}


void DRVCUST_SET_YGAMMA(UINT32 i1Mode)
{
    EXTERN void vDrvADLSetYGamma(UINT8 bIndex);
    
    switch((INT8)i1Mode)
    {
        case -3:
            vDrvADLSetYGamma(9);
            break;
        case -2:
            vDrvADLSetYGamma(8);
            break;

        case -1:
            vDrvADLSetYGamma(7);

            break;
        case 1:
            vDrvADLSetYGamma(1);
            break;

        case 2:
            vDrvADLSetYGamma(3);
            break;
        case 3:
            vDrvADLSetYGamma(5);
            break;

        default:
            vDrvADLSetYGamma(0);
            break;
    }
	
	if (bi1GammaOfst != i1Mode)
		{		 
			bi1GammaOfst = i1Mode;
			DRVCUST_SendEvent(E_CUST_PIC_SETTING_CHANGE, 0);
		}

    return;
}

void DRVCUST_AutoColorTempUpdate(AUTO_COLORTEMP_SETS_INFO_T *aCTInfo)
{
	if(stCTInfo.ui1CTIndex != aCTInfo->ui1CTIndex)
	{
	    stCTInfo.ui1CTIndex = aCTInfo->ui1CTIndex;
		DRVCUST_SendEvent(E_CUST_PIC_SETTING_CHANGE, 0);
	}
        DRVCUST_SET_GAMMA();
    
}

void DRVCUST_MMAPProc(void)
{
    if (sMMAppInfo.u1AppType == 0xFF) /*Pretend for Netflix App */
    {
        //Update new QtyTbl
        bApiVideoProc(SV_VP_MAIN, PE_ARG_3D_NR);
        bApiVideoProc(SV_VP_MAIN, PE_ARG_NR);
        bApiVideoProc(SV_VP_MAIN, PE_ARG_MPEG_NR);
        bApiVideoProc(SV_VP_MAIN, PE_ARG_SHARPNESS);
    }
}

void DRVCUST_GetLcdimPanelOrder(UINT8 *u1PanelOrder, UINT8 u1BlockNum)
{
	UINT8 bIndex;
	UINT16 i;
    bIndex = GetCurrentPanelIndex();

    if(bIndex == PANEL_EPI_LGDV12GIPFHD120)          // 1 * 12, LGD protocal
    {
        UINT8 u1PanelOrderCust[12] = {0, 2, 4, 6, 8, 10, 11, 9, 7, 5, 3, 1};      // MTK IC HW Sequence            
        x_memcpy(u1PanelOrder, u1PanelOrderCust, sizeof(u1PanelOrderCust));
    }   
    else if(bIndex == PANEL_LG_47_EUH_PR)          // 8 * 2, AMS protocal
    {
        UINT8 u1PanelOrderCust[16] = {0, 15, 1, 14, 2, 13, 3, 12, 4, 11, 5, 10, 6, 9, 7, 8};      // MTK IC HW Sequence
        x_memcpy(u1PanelOrder, u1PanelOrderCust, sizeof(u1PanelOrderCust));
    }       
    else
    {
        for(i = 0; i < u1BlockNum; i++)
        {
            u1PanelOrder[i] = i;
        }
    }        
    
    LOG(0, "Panel Order = ");
    
    for(i = 0; i < u1BlockNum; i++)
    {
        LOG(0, "%d  ", u1PanelOrder[i]);
    }    
}

void DRVCUST_GetLcdimPanelDimGain(UINT8 *u1PanelDimGain, UINT8 u1BlockNum)
{
	UINT8 bIndex;
	UINT16 i;
    bIndex = GetCurrentPanelIndex();

    if(bIndex == PANEL_EPI_LGDV12GIPFHD120)          // 1 * 12, LGD protocal
    {
        UINT8 u1PanelDimGainCust[12] = {0x98, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x98};
        x_memcpy(u1PanelDimGain, u1PanelDimGainCust, sizeof(u1PanelDimGainCust));
    }
    else if(bIndex == PANEL_LG_47_EUH_PR)          // 8 * 2, AMS protocal
    {
        UINT8 u1PanelDimGainCust[16] = {0xFF, 0xFF, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xFF, 0xFF};
        x_memcpy(u1PanelDimGain, u1PanelDimGainCust, sizeof(u1PanelDimGainCust));
    }       
    else
    {
        for(i = 0; i < u1BlockNum; i++)
        {
            u1PanelDimGain[i] = 0x80;   //0x80 means gain 1
        }
    }        
    
    LOG(0, "Panel Dim Gain = ");
    
    for(i = 0; i < u1BlockNum; i++)
    {
        LOG(0, "%d  ", u1PanelDimGain[i]);
    }    
}
UINT32 DRVCUST_DemoRegion(void)
{  
    return DEMO_PQ_ON_RIGHT;
}

UINT32 DRVCUST_DemoModule(void)
{
    return (DEMO_3DNR | DEMO_TDSHARP | DEMO_COLOR | DEMO_ECTI );
}

void DRVCUST_SetDemoMode(E_CUST_DEMO_MODE eDemoMode, E_CUST_DEMO_PATTERN eDemoPattern, UINT32 u4DemoOption)
{ 
	UINT8 u1DemoModule = 0;
	UINT8 u1DemoEffect = 0;

	Region rDummyRegion;
    //support only Split demo.
    rDummyRegion.u1OnOff = SV_ON;
    rDummyRegion.wHEnd = 200;
    rDummyRegion.wHStart=0;
    rDummyRegion.wVEnd = 200;
    rDummyRegion.wVStart = 0;

	if(eDemoMode == E_CUST_DEMO_MODE_OFF)
	{
		u1DemoModule = 0;
		u1DemoEffect = DEMO_PQ_OFF;
	}
	else if(eDemoMode == E_CUST_DEMO_MODE_STANDBY)
	{
		u1DemoModule = 0;
		u1DemoEffect = DEMO_PQ_OFF;
	}
	else if(eDemoMode == E_CUST_DEMO_MODE_X_REALITY)
	{
		u1DemoModule = DEMO_HSHARP | DEMO_2DNR | DEMO_3DNR | DEMO_TDSHARP | DEMO_COLOR | DEMO_ECTI ;
		
		if(eDemoPattern == E_CUST_DEMO_PATTERN_SPLIT_L_ON)
		{
			u1DemoEffect = DEMO_PQ_ON_LEFT;
		}
		else if(eDemoPattern == E_CUST_DEMO_PATTERN_SPLIT_R_ON)
		{
			u1DemoEffect = DEMO_PQ_ON_RIGHT;
		}
		else if(eDemoPattern == E_CUST_DEMO_PATTERN_FULL_ON)
		{
			u1DemoEffect = DEMO_PQ_OFF;
		}
		else if(eDemoPattern == E_CUST_DEMO_PATTERN_FULL_OFF)
		{
			u1DemoEffect = DEMO_PQ_OFF;
		}
		else
		{
			u1DemoEffect = DEMO_PQ_OFF;
		}
	}
	else if(eDemoMode == E_CUST_DEMO_MODE_X_REALITY_2)
	{
		u1DemoModule = DEMO_HSHARP | DEMO_2DNR | DEMO_3DNR | DEMO_TDSHARP | DEMO_ECTI ;
		
		if(eDemoPattern == E_CUST_DEMO_PATTERN_SPLIT_L_ON)
		{
			u1DemoEffect = DEMO_PQ_ON_LEFT;
		}
		else if(eDemoPattern == E_CUST_DEMO_PATTERN_SPLIT_R_ON)
		{
			u1DemoEffect = DEMO_PQ_ON_RIGHT;
		}
		else if(eDemoPattern == E_CUST_DEMO_PATTERN_FULL_ON)
		{
			u1DemoEffect = DEMO_PQ_OFF;
		}
		else if(eDemoPattern == E_CUST_DEMO_PATTERN_FULL_OFF)
		{
			u1DemoEffect = DEMO_PQ_OFF;
		}
		else
		{
			u1DemoEffect = DEMO_PQ_OFF;
		}
	}
	else if(eDemoMode == E_CUST_DEMO_MODE_TRILUMINOUS)
	{
		u1DemoModule = 0;
		u1DemoEffect = DEMO_PQ_OFF;
	}
	else
	{
		u1DemoModule = 0;
		u1DemoEffect = DEMO_PQ_OFF;
	}

	vApiVideoDemoMode(u1DemoEffect, rDummyRegion, u1DemoModule);

	if(eDemoMode == E_CUST_DEMO_MODE_TRILUMINOUS)
	{
		if(eDemoPattern == E_CUST_DEMO_PATTERN_FULL_OFF)
		{
			vDrvPreSharpOnOff(SV_VP_MAIN, SV_ON);
    		vDrvPostSharpOnOff(SV_ON);
			vDrvCTIROnOff(SV_ON);
			vDrvSCEAllOnOff(SV_OFF);
			vDrvNRSet2DNRBNROnOff(SV_ON);
			vDrvNRSet2DNRMNROnOff(SV_ON);
			vDrvNRSet2DNRSNROnOff(SV_ON);
			vDrvNRSet3DNROnOff(SV_ON);
			
		}
		else
		{
			vDrvPreSharpOnOff(SV_VP_MAIN, SV_ON);
    		vDrvPostSharpOnOff(SV_ON);
			vDrvCTIROnOff(SV_ON);
			vDrvSCEAllOnOff(SV_ON);
			vDrvNRSet2DNRBNROnOff(SV_ON);
			vDrvNRSet2DNRMNROnOff(SV_ON);
			vDrvNRSet2DNRSNROnOff(SV_ON);
			vDrvNRSet3DNROnOff(SV_ON);
		}
	}
	else if(eDemoMode == E_CUST_DEMO_MODE_X_REALITY)
	{
		if(eDemoPattern == E_CUST_DEMO_PATTERN_FULL_OFF)
		{
			vDrvPreSharpOnOff(SV_VP_MAIN, SV_OFF);
    		vDrvPostSharpOnOff(SV_OFF);
			vDrvCTIROnOff(SV_OFF);
			vDrvSCEAllOnOff(SV_OFF);
			vDrvNRSet2DNRBNROnOff(SV_OFF);
			vDrvNRSet2DNRMNROnOff(SV_OFF);
			vDrvNRSet2DNRSNROnOff(SV_OFF);
			vDrvNRSet3DNROnOff(SV_OFF);
		}
		else
		{
			vDrvPreSharpOnOff(SV_VP_MAIN, SV_ON);
    		vDrvPostSharpOnOff(SV_ON);
			vDrvCTIROnOff(SV_ON);
			vDrvSCEAllOnOff(SV_ON);
			vDrvNRSet2DNRBNROnOff(SV_ON);
			vDrvNRSet2DNRMNROnOff(SV_ON);
			vDrvNRSet2DNRSNROnOff(SV_ON);
			vDrvNRSet3DNROnOff(SV_ON);
		}
	}
	else if(eDemoMode == E_CUST_DEMO_MODE_X_REALITY_2)
	{
		if(eDemoPattern == E_CUST_DEMO_PATTERN_FULL_OFF)
		{
			vDrvPreSharpOnOff(SV_VP_MAIN, SV_OFF);
    		vDrvPostSharpOnOff(SV_OFF);
			vDrvCTIROnOff(SV_OFF);
			vDrvSCEAllOnOff(SV_ON);
			vDrvNRSet2DNRBNROnOff(SV_OFF);
			vDrvNRSet2DNRMNROnOff(SV_OFF);
			vDrvNRSet2DNRSNROnOff(SV_OFF);
			vDrvNRSet3DNROnOff(SV_OFF);
		}
		else
		{
			vDrvPreSharpOnOff(SV_VP_MAIN, SV_ON);
    		vDrvPostSharpOnOff(SV_ON);
			vDrvCTIROnOff(SV_ON);
			vDrvSCEAllOnOff(SV_ON);
			vDrvNRSet2DNRBNROnOff(SV_ON);
			vDrvNRSet2DNRMNROnOff(SV_ON);
			vDrvNRSet2DNRSNROnOff(SV_ON);
			vDrvNRSet3DNROnOff(SV_ON);
		}
	}
	else
	{
			vDrvPreSharpOnOff(SV_VP_MAIN, SV_ON);
    		vDrvPostSharpOnOff(SV_ON);
			vDrvCTIROnOff(SV_ON);
			vDrvSCEAllOnOff(SV_ON);
			vDrvNRSet2DNRBNROnOff(SV_ON);
			vDrvNRSet2DNRMNROnOff(SV_ON);
			vDrvNRSet2DNRSNROnOff(SV_ON);
			vDrvNRSet3DNROnOff(SV_ON);
	}


	if(eDemoMode == E_CUST_DEMO_MODE_MOTION_FLOW)
	{
		if(eDemoPattern == E_CUST_DEMO_PATTERN_SPLIT_L_ON)
		{
			MJC_SetDemo(MJC_DEMO_SIDEBYSIDE, MJC_INTP_FULL, MJC_INTP_OFF);
			MJC_SetDemoBar(SV_ON, 128, 16, 128);
		}
		else if(eDemoPattern == E_CUST_DEMO_PATTERN_SPLIT_R_ON)
		{
			MJC_SetDemo(MJC_DEMO_SIDEBYSIDE, MJC_INTP_OFF, MJC_INTP_FULL);
			MJC_SetDemoBar(SV_ON, 128, 16, 128);
		}
		else if(eDemoPattern == E_CUST_DEMO_PATTERN_FULL_ON)
		{
			MJC_SetDemo(MJC_DEMO_SIDEBYSIDE, MJC_INTP_FULL, MJC_INTP_FULL);
			MJC_SetDemoBar(SV_OFF, 128, 16, 128);
		}
		else if(eDemoPattern == E_CUST_DEMO_PATTERN_FULL_OFF)
		{
			MJC_SetDemo(MJC_DEMO_SIDEBYSIDE, MJC_INTP_OFF, MJC_INTP_OFF);
			MJC_SetDemoBar(SV_OFF, 128, 16, 128);
		}
		else
		{
			MJC_SetDemo(MJC_DEMO_OFF, MJC_INTP_FULL, MJC_INTP_FULL);
			MJC_SetDemoBar(SV_OFF, 128, 16, 128);
		}
	}

}

void DRVCUST_PqModeChange(UINT8 bPath)
{
    UINT32 i;
    
    for (i=0; i < (UINT8)PE_ARG_NS; i++)
    {
        switch (i)
        {
            // List all the quality items that do not update after mode change done.
            //  the back light is not relative to video timing, nor main/pip change.
            case PE_ARG_ADAPTIVE_BACK_LIGHT:
            case PE_ARG_BACK_LIGHT_LVL:
			case PE_ARG_R_GAIN:
            case PE_ARG_G_GAIN:
            case PE_ARG_B_GAIN:
            case PE_ARG_R_OFFSET:
            case PE_ARG_G_OFFSET:
            case PE_ARG_B_OFFSET:
			case PE_ARG_GAMMA:
                break;
            default:
                UNUSED(bApiVideoProc(bPath, (PE_ARG_TYPE)i));
                break;
        }
    }
}

void DRVCUST_SendEvent(E_CUST_EVENT eCustEvent, UINT8 u1Option)
{
    if (sony_be_func)
    {
        sony_be_func->be_send_event_func(eCustEvent, u1Option);
    }
    
    if (sony_pq_func)
    {
        sony_pq_func->pq_send_event_func(eCustEvent, u1Option);
    }

	LOG(2, "DRVCUST_SendEvent  eCustEvent = %x u1Option = %d\n",eCustEvent, u1Option);

}

void DRVCUST_SendEcsCommand(UINT8* pData, UINT32 u4Size)
{
    if (sony_be_func)
    {
        sony_be_func->be_send_ecs_func(pData, u4Size);
    }
    
    if (sony_pq_func)
    {
        sony_pq_func->pq_send_ecs_func(pData, u4Size);
    }
}

void DRVCUST_SetBEGeneralData(UINT8* pData, UINT8 u1Size)
{
    if (sony_be_gen_func)
    {
        sony_be_gen_func->be_set_general_data(pData, u1Size);
    }
}

void DRVCUST_GetBEGeneralData(UINT8* pData, UINT8* u1Size)
{
    if (sony_be_gen_func)
    {
        sony_be_gen_func->be_get_general_data(pData, u1Size);
    }
}

void DRVCUST_SetColorPickData(UINT16 u1X, UINT16 u1Y)
{
    if (sony_be_gen_func)
    {
        sony_be_gen_func->be_set_color_pickup_data(u1X, u1Y);
    }
}

void DRVCUST_GetColorPickData(UINT16* pRed, UINT16* pGreen, UINT16* pBlue)
{
    if (sony_be_gen_func)
    {
        sony_be_gen_func->be_get_color_pickup_data(pRed, pGreen, pBlue);
    }
}

void DRVCUST_PanelPowerStateToBe(BOOL bOnOff)
{
    if (sony_be_func)
    {
        sony_be_func->be_panel_power_func(bOnOff);
    }
}

void DRVCUST_GetWBGammaTable(UINT8 u1Index, UINT16 * pData)
{
	if(u1Index > 4)
	{
		LOG(0, "Wrong WB Index \n");
	}
	else
	{
		EEPROM_Read((UINT64)((EEP_WB_LUT_ADJ_G0_START + GAMMA_BYTES * u1Index)), (UINT32)pData, GAMMA_BYTES);
	}
	LOG(2, "DRVCUST_GetWBGammaTable \n");
}
void DRVCUST_SetWBGammaTable(UINT8 u1Index, UINT16 * pData)
{
	if(u1Index > 4)
	{
		LOG(0, "Wrong WB Index \n");
	}
	else if(pData == NULL)
	{
		LOG(0, "Set Array is NULL \n");
	}
	else
	{
		DRVCUST_DoubleEepromWrite((UINT64)((EEP_WB_LUT_ADJ_G0_START + GAMMA_BYTES * u1Index)), (UINT32)pData, GAMMA_BYTES);
	}
	LOG(2, "DRVCUST_SetWBGammaTable \n");
}

UINT8 DRVCUST_SuperGameMode(UINT32 u4VdpId)
{
    BOOL ret = SV_ON;
    VRM_INFO_T* infoVRM;
    UINT8 u1InFR, u1OutFR;
    VDP_REGION_T rOutRegion;
    UCHAR ucFull;
#ifdef CC_MAPLE_CUST_DRV
    CUST_SCREEN_SETTING_T rScreenInfoFromAP;
#endif

    // 1. game mode
    if (SRM_IsGameMode(u4VdpId) == 0)
    {
        ret = SV_OFF;
    }
    
    // 2. Not flip-mirror
#ifdef CC_FLIP_MIRROR_SUPPORT
    if (u1GetFlipMirrorConfig() != 0)
    {
        ret = SV_OFF;
    }
#endif

    // 3. Not PIP/POP
    if (SRM_IsSubVideoDisplay() != 0)
    {
        ret = SV_OFF;
    }
    
    // 4. Input framerate 60  
    if (bDrvVideoGetRefreshRate(u4VdpId) != 60)
    {
        ret = SV_OFF;
    }
        
    // 5. Progressive
    if (bDrvVideoIsSrcInterlace(u4VdpId) != 0)
    {
        ret = SV_OFF;
    }
    
    // 6. CE timing
    if (fgApiVideoIsVgaTiming(u4VdpId) != 0)
    {
        ret = SV_OFF;
    }
    
    // 7. Write speed >= Read speed
    infoVRM = VRMGetVRMInfo(SV_VP_MAIN, VRM_MODULE_OMUX);
    u1InFR  = infoVRM->u2FrameRate;

    infoVRM = VRMGetVRMInfo(SV_VP_MAIN, VRM_MODULE_MIXER);
    u1OutFR = infoVRM->u2FrameRate;
    if (u1InFR < u1OutFR)
    {
        ret = SV_OFF;
    }

    // 9. No black on bottom
    VDP_GetOutRegion(u4VdpId, &ucFull, &rOutRegion);
    if (ucFull != 0 && (rOutRegion.u4Y + rOutRegion.u4Height) < VDP_MAX_REGION_HEIGHT)
    {
        ret = SV_OFF;
    }

#ifdef CC_MAPLE_CUST_DRV
    BEPQ_AP_Get_WideMode_Setting(&rScreenInfoFromAP);

    // 8. Wide mode "Full" or "Normal"
    if (rScreenInfoFromAP.eWideMode != E_CUST_WIDE_MODE_FULL || rScreenInfoFromAP.eWideMode != E_CUST_WIDE_MODE_NORMAL)
    {
        ret = SV_OFF;
    }

    // 10. Display area "Full Pixel" or "+1"
    if (rScreenInfoFromAP.eDisplayArea != E_CUST_DISPLAY_AREA_FULL || rScreenInfoFromAP.eDisplayArea != E_CUST_DISPLAY_AREA_NORMAL)
    {
        ret = SV_OFF;
    }
#endif

    // 11. Vsync lock
    return ret;
}

// SONY power consumptaion control
#ifdef CC_PowerCons_Ctrl

#define PowerConsCtrl_ISSUE_DEBUG_MSG 1
static UINT8 volume_setting;
static BOOL speaker_unmute;
static BOOL mhl_use;
static BOOL lnb_use;
static BOOL ci_use;

UINT8 C_BL_POWER_LIMIT=255;

//HANDLE_T _hIRLedCtrlTimer = NULL_HANDLE;
HANDLE_T _hPowerConsCtrlMsgQue = NULL_HANDLE;
HANDLE_T _hPowerConsCtrlHandle = NULL_HANDLE;
  
void DRVCUST_PowerConsCtrl(void)
{
    UINT16 POWER_CONS_TOTAL_MAX;
	UINT16 POWER_CONS_TOTAL_TYP;
	UINT16 POWER_CONS_AUDIO_MAX;
	UINT16 POWER_CONS_AUDIO_TYP;
	UINT16 bl_power_limit_max;
	UINT16 bl_power_limit_TYP;
	UINT8 Model_ID=0;
	//Check model ID based on Option bit

	//Get related data from data table

	//start
	 if(power_cons_data_table[Model_ID].POWER_CONS_CTL_ON==1)
	{
	    //Check argument stability about 500msec
		x_thread_delay(500);
		//Calculate audio power consumption	
		//1.for maximum
		POWER_CONS_AUDIO_MAX=power_cons_data_table[Model_ID].AUDIO_PWR_OFFSET_MAX+(((UINT32)((power_cons_data_table[Model_ID].AUDIO_PWR_LIMIT_UP_MAX - power_cons_data_table[Model_ID].AUDIO_PWR_OFFSET_MAX)*volume_setting*speaker_unmute))/power_cons_data_table[Model_ID].AUDIO_VOLUME_TH_MAX);
		if (POWER_CONS_AUDIO_MAX > power_cons_data_table[Model_ID].AUDIO_PWR_LIMIT_UP_MAX) 
		{
			POWER_CONS_AUDIO_MAX = power_cons_data_table[Model_ID].AUDIO_PWR_LIMIT_UP_MAX;
		}
		if (POWER_CONS_AUDIO_MAX < power_cons_data_table[Model_ID].AUDIO_PWR_LIMIT_LOW_MAX) 
		{
			POWER_CONS_AUDIO_MAX = power_cons_data_table[Model_ID].AUDIO_PWR_LIMIT_LOW_MAX;
		}
		//2.for typical
		POWER_CONS_AUDIO_TYP=power_cons_data_table[Model_ID].AUDIO_PWR_OFFSET_TYP+(((UINT32)((power_cons_data_table[Model_ID].AUDIO_PWR_LIMIT_UP_TYP - power_cons_data_table[Model_ID].AUDIO_PWR_OFFSET_TYP)*volume_setting*speaker_unmute))/power_cons_data_table[Model_ID].AUDIO_VOLUME_TH_TYP);

		if (POWER_CONS_AUDIO_TYP > power_cons_data_table[Model_ID].AUDIO_PWR_LIMIT_UP_TYP) 
		{
			POWER_CONS_AUDIO_TYP = power_cons_data_table[Model_ID].AUDIO_PWR_LIMIT_UP_TYP;
		}
		if (POWER_CONS_AUDIO_TYP < power_cons_data_table[Model_ID].AUDIO_PWR_LIMIT_LOW_TYP) 
		{
			POWER_CONS_AUDIO_TYP = power_cons_data_table[Model_ID].AUDIO_PWR_LIMIT_LOW_TYP;
		}
		//Calculate total power consumptio
		//1.for maximum
		POWER_CONS_TOTAL_MAX = power_cons_data_table[Model_ID].BL_POWER_WATT_MAX+ POWER_CONS_AUDIO_MAX+ mhl_use*static_power_cons_data_table[0].POWER_CONS_MHL_MAX+ lnb_use * static_power_cons_data_table[0].POWER_CONS_LNB_MAX+ ci_use * static_power_cons_data_table[0].POWER_CONS_CI_MAX+ power_cons_data_table[Model_ID].POWER_CONS_BASE_MAX;
		//2.for typical
		POWER_CONS_TOTAL_TYP = power_cons_data_table[Model_ID].BL_POWER_WATT_TYP+ POWER_CONS_AUDIO_TYP+ mhl_use*static_power_cons_data_table[0].POWER_CONS_MHL_TYP+ lnb_use * static_power_cons_data_table[0].POWER_CONS_LNB_TYP+ ci_use * static_power_cons_data_table[0].POWER_CONS_CI_TYP+ power_cons_data_table[Model_ID].POWER_CONS_BASE_TYP;

		//Calculate C_BL_POWER_LIMIT
		//1.for maximum
        if (POWER_CONS_TOTAL_MAX > power_cons_data_table[Model_ID].POWER_CONS_LIMIT_MAX) 
		{
			bl_power_limit_max = POWER_CONS_TOTAL_MAX - power_cons_data_table[Model_ID].POWER_CONS_LIMIT_MAX;
        }
		else
		{
		    bl_power_limit_max = 0;
		}
		//2.for typical
        if (POWER_CONS_TOTAL_TYP > power_cons_data_table[Model_ID].POWER_CONS_LIMIT_TYP) 
		{
			bl_power_limit_TYP = POWER_CONS_TOTAL_TYP - power_cons_data_table[Model_ID].POWER_CONS_LIMIT_TYP;
        }
		else
		{
		    bl_power_limit_TYP = 0;
		}
        //Lower limit of bl_power_limit_typ
        if((power_cons_data_table[Model_ID].BL_POWER_WATT_TYP - bl_power_limit_TYP) < ((UINT32)(power_cons_data_table[Model_ID].BL_POWER_WATT_TYP * power_cons_data_table[Model_ID].BL_POWER_LIMIT_LOWER))/ 255) 
		{
			bl_power_limit_TYP = power_cons_data_table[Model_ID].BL_POWER_WATT_TYP - ((UINT32)(power_cons_data_table[Model_ID].BL_POWER_WATT_TYP*power_cons_data_table[Model_ID].BL_POWER_LIMIT_LOWER))/255;
        }
		//Use bigger value of "bl_power_limit_max" and "bl_power_limit_typ"
		if(bl_power_limit_max > bl_power_limit_TYP) 
		{
			C_BL_POWER_LIMIT = (((UINT32)((power_cons_data_table[Model_ID].BL_POWER_WATT_MAX - bl_power_limit_max)*255))/power_cons_data_table[Model_ID].BL_POWER_WATT_MAX);
		}
		else
		{
			C_BL_POWER_LIMIT = (((UINT32)((power_cons_data_table[Model_ID].BL_POWER_WATT_TYP - bl_power_limit_TYP)*255))/power_cons_data_table[Model_ID].BL_POWER_WATT_TYP);
		}
		Printf("DRVCUST_PowerConsCtrl C_BL_POWER_LIMIT==%d \n",C_BL_POWER_LIMIT);
		
	}
    else
	{
		C_BL_POWER_LIMIT=255;
	}
	DRVCUST_SendEvent(E_CUST_BL_POWER_LIMIT_CHANGE, 0);
}
void DRVCUST_PowerConsCtrlHandle(void)
{
     //Printf("PowerConsCtrlHandle \n");
	 DRVCUST_PowerConsCtrl();
}

static void DRVCUST_PowerConsCtrlMsgHandle(void *pvArg)
{
    UINT16 u2MsgIdx;
    PowerCons_Change_STATE rPowerConsCtrlMsg;
    
    while (1)
    {
        SIZE_T zMsgSize = sizeof(PowerCons_Change_STATE);
        INT32  i4MsgRet;
     
        i4MsgRet = x_msg_q_receive(&u2MsgIdx, &rPowerConsCtrlMsg, &zMsgSize,
                                   &_hPowerConsCtrlMsgQue, 1, X_MSGQ_OPTION_WAIT);
        if (i4MsgRet == OSR_OK)
        {
          DRVCUST_PowerConsCtrlHandle();
            //PowerConsCtrlHandle(rPowerConsCtrlMsg.Mute_State,rPowerConsCtrlMsg.MHL_State,rPowerConsCtrlMsg.LNB_State,rPowerConsCtrlMsg.CI_State,rPowerConsCtrlMsg.u1volume_set);
        }
    }
}

void DRVCUST_PowerConsCtrlResourceInit(void)
{
    if (_hPowerConsCtrlMsgQue == NULL_HANDLE)
    {
        VERIFY(x_msg_q_create(&_hPowerConsCtrlMsgQue, "PowerConsCtrlMsgQue", 
                              sizeof(PowerCons_Change_STATE), 8) == OSR_OK);
        
        // Create the Led state handle handle task
        if (x_thread_create(&_hPowerConsCtrlHandle, "PowerConsCtrlHandle",
                            0x800, DRVCUST_OptGet(eReleaseWatchdogPriority),
                            DRVCUST_PowerConsCtrlMsgHandle, 0, NULL) != OSR_OK)
        {
            Printf("\nError: Create Power consumption ctrl handle thread fail\n");
            x_msg_q_delete(_hPowerConsCtrlMsgQue);
            _hPowerConsCtrlMsgQue = NULL_HANDLE;
        }
    }
}

void DRVCUST_PowerConsCtrlTrigger(bool Mute_State,bool MHL_State,bool LNB_State,bool CI_State, UINT8 u1volume_set)
{
#if PowerConsCtrl_ISSUE_DEBUG_MSG
    Printf("Power Consumption Ctrl Trigger %d %d %d %d %d\n", Mute_State, MHL_State,LNB_State,CI_State,u1volume_set);
#endif

    PowerCons_Change_STATE rPowerConsCtrlMsg;
    DRVCUST_PowerConsCtrlResourceInit();
    if (_hPowerConsCtrlMsgQue != NULL_HANDLE)
    {
        rPowerConsCtrlMsg.Mute_State = Mute_State;
		rPowerConsCtrlMsg.MHL_State = MHL_State;
		rPowerConsCtrlMsg.LNB_State = LNB_State;
		rPowerConsCtrlMsg.CI_State = CI_State;
		rPowerConsCtrlMsg.u1volume_set = u1volume_set;

        UNUSED(x_msg_q_send(_hPowerConsCtrlMsgQue, &rPowerConsCtrlMsg,
                            sizeof(PowerCons_Change_STATE), 1));
    }
}

void DRVCUST_PowerConsCtrlStatusCheck(void)
{
     UINT32 u4Vuale;
     BOOL ci_use_tmp;
	 UINT8 volume_set_tmp;
	 BOOL MHL_use_tmp;
	 BOOL speaker_unmute_tmp;
	 
    //check CI status change  if bit9 and bit10,  are zeor, it means CI connected
    u4Vuale=u4IO32Read4B(0xf001f00c);
    if((u4Vuale & 0x0600)==0x00)
    	ci_use_tmp=1;
    else
		ci_use_tmp=0;
	if(ci_use_tmp!=ci_use)
	{
    	ci_use=ci_use_tmp;
		DRVCUST_PowerConsCtrlTrigger(speaker_unmute,mhl_use,lnb_use,ci_use,volume_setting);
    }
	
	//check MHL status change
	if(_bIsMhlDevice==1)
    	MHL_use_tmp=1;
    else
		MHL_use_tmp=0;

	if(MHL_use_tmp!=mhl_use)
	{
    	mhl_use=MHL_use_tmp;
		DRVCUST_PowerConsCtrlTrigger(speaker_unmute,mhl_use,lnb_use,ci_use,volume_setting);
    }
	//check AMP mute
	if(ADAC_AmpEnableFlag()==1)
    	speaker_unmute_tmp=1;
    else
		speaker_unmute_tmp=0;

	if(speaker_unmute_tmp!=speaker_unmute)
	{
    	speaker_unmute=speaker_unmute_tmp;
		DRVCUST_PowerConsCtrlTrigger(speaker_unmute,mhl_use,lnb_use,ci_use,volume_setting);
    }
    //check volume change
	volume_set_tmp=AUD_DspGetMasterVolume(AUD_DEC_MAIN);
    if(volume_set_tmp!=volume_setting)
    {
    	volume_setting=volume_set_tmp;
		DRVCUST_PowerConsCtrlTrigger(speaker_unmute,mhl_use,lnb_use,ci_use,volume_setting);
    }
}

#endif

static UINT8 fgSrsBypass=0;
void DRVCUST_SharpnessEnhanceEn(UINT8 u1Onoff)
{
    CRIT_STATE_T csState;
    csState = x_crit_start();
    fgSrsBypass = u1Onoff;
    x_crit_end(csState);
}
UINT8 DRVCUST_GetSrsStatus(void)
{
    return( fgSrsBypass );
}

void DRVCUST_SRSOnOff(UINT8 u1Onoff)
{
    if(u1Onoff == SV_ON)/*Core Reset (delay match reset) before SRS enable */
    {
        vIO32WriteFldAlign(SRS_1, 0x1, C_SRS_BYPASS);
        
        vIO32WriteFldAlign(SRS_1, 0x2, C_SRS_RST_CTRL);
        vIO32WriteFldAlign(SRS_1, 0x0, C_SRS_RST_CTRL); 
    }
	
    vIO32WriteFldAlign(TDPROC_MISC_SRS, u1Onoff, LINEBUF_4SRS_EN);
    vIO32WriteFldAlign(YCPROC_SRS, u1Onoff, SRS_EN);
    vIO32WriteFldAlign(SRS_1, !u1Onoff, C_SRS_BYPASS);
  
    vIO32WriteFldAlign(SRS_1, !u1Onoff, C_SRS_DSR_ZERO_EN);
}

void DRVCUST_SharpnessEnhanceCFGInit(void)
{
    vIO32WriteFldAlign(SRS_0, 1, C_SRS_DRAM_RD_EN);
	vIO32WriteFldAlign(SRS_2, 1, C_SRS_DRAM_ADR_B_EN);
	vIO32WriteFldAlign(SRS_3, 0x38, C_LUT_A_DAT_CNT);
	vIO32WriteFldAlign(SRS_3, 1, C_SRS_4K1K_MASK_EN);
	
}

UINT16 DRVCUST_QtyUIMapping(UINT8 u1SrcTypTmg, UINT16 u2QtyItem, INT32 i4UiRangeMin, INT32 i4UiRangeDft,INT32 i4UiRangeMax,INT16 i2Min, INT16 i2Max, INT16 i2Dft, INT16 i2Cur)
{
    UINT16 ReturnVal = 0;

	if((u2QtyItem >= QUALITY_HSHARP_LOW) && (u2QtyItem <= QUALITY_HSHARP_HIGH_NEG))
	{
		if ((i4UiRangeMin == 0) && (i4UiRangeMax == 0))
		{
		    ReturnVal = i4UiRangeDft;
		}
		else
		{
		if(i2Dft > 50)
		{
			if(i2Cur < 50)
			{
				ReturnVal = (UINT16) ((i2Cur - 0) * (0x40 - MIN(0x40, i4UiRangeMin)) /
		                                (50 - 0) + i4UiRangeMin);
			}
			else
			{
				if (i2Cur > i2Dft)
		        {
		            // Prevent UI_max, UI_dft miss setting, and div=0.
		            if ((i2Max - i2Dft) <= 0)
		            {
		                ReturnVal = i4UiRangeDft;
		            }
		            else
		            {
		                ReturnVal = (UINT16) ((i2Cur - i2Dft) * (i4UiRangeMax - i4UiRangeDft) /
		                            (i2Max - i2Dft) + i4UiRangeDft);
		            }
		        }
		        // Get HW value for UI_current < UI_default.
		        else
		        {
		            // Prevent UI_dft, UI_min miss setting, and div=0.
		            if ((i2Dft - i2Min) <= 0)
		            {
		                ReturnVal = i4UiRangeDft;
		            }
		            else
		            {
		                ReturnVal = (UINT16) ((i2Cur - 50) * (MAX(0x40, i4UiRangeDft) - 0x40) /
		                                (i2Dft - 50) + 0x40);
		            }
		        }
			}
		}
		else
		{
			if(i2Cur < 50)
			{
				ReturnVal = (UINT16) ((i2Cur - 0) * (0x40 - MIN(0x40, i4UiRangeMin)) /
		                                (50 - 0) + i4UiRangeMin);
			}
			else
			{
				ReturnVal = (UINT16) ((i2Cur - 50) * (MAX(0x40, i4UiRangeMax) - 0x40) /
		                            (i2Max - 50) + 0x40);
			}
		}
		}
	}
	else if((u2QtyItem >= QUALITY_HSHARP_LOW_CORING) && (u2QtyItem <= QUALITY_CTIR_COR))
	{
		if ((i4UiRangeMin == 0) && (i4UiRangeMax == 0))
		{
		    ReturnVal = i4UiRangeDft;
		}
		else
		{
		if(i2Dft > 50)
		{
			if(i2Cur < 50)
			{
				ReturnVal = i4UiRangeMin;
			}
			else
			{
				if (i2Cur > i2Dft)
		        {
		            // Prevent UI_max, UI_dft miss setting, and div=0.
		            if ((i2Max - i2Dft) <= 0)
		            {
		                ReturnVal = i4UiRangeDft;
		            }
		            else
		            {
		                ReturnVal = (UINT16) ((i2Cur - i2Dft) * (i4UiRangeMax - i4UiRangeDft) /
		                            (i2Max - i2Dft) + i4UiRangeDft);
		            }
		        }
		        // Get HW value for UI_current < UI_default.
		        else
		        {
		            // Prevent UI_dft, UI_min miss setting, and div=0.
		            if ((i2Dft - i2Min) <= 0)
		            {
		                ReturnVal = i4UiRangeDft;
		            }
		            else
		            {
		                ReturnVal = (UINT16) ((i2Cur - 50) * (i4UiRangeDft - i4UiRangeMin) /
		                                (i2Dft - 50) + i4UiRangeMin);
		            }
		        }
			}
		}
		else
		{
			if(i2Cur < 50)
			{
				ReturnVal = i4UiRangeMin;
			}
			else
			{
				ReturnVal = (UINT16) ((i2Cur - 50) * (MAX(i4UiRangeMax, i4UiRangeMin) - i4UiRangeMin) /
		                            (i2Max - 50) + i4UiRangeMin);
			}
		}
	}
	}
	else
	{

		 // Some qty_item does not need mapping, return default HW value.
		    // or UI_cur == UI_dft, return default HW value.
		    if (((i4UiRangeMin == 0) && (i4UiRangeMax == 0)) || (i2Cur == i2Dft))
		    {
		        ReturnVal = i4UiRangeDft;
		    }
		    else
		    {
		        // Get HW value for UI_current > UI_default.
		        if (i2Cur > i2Dft)
		        {
		            // Prevent UI_max, UI_dft miss setting, and div=0.
		            if ((i2Max - i2Dft) <= 0)
		            {
		                ReturnVal = i4UiRangeDft;
		            }
		            else
		            {
		                ReturnVal = (UINT16) ((i2Cur - i2Dft) * (i4UiRangeMax - i4UiRangeDft) /
		                            (i2Max - i2Dft) + i4UiRangeDft);
		            }
		        }
		        // Get HW value for UI_current < UI_default.
		        else
		        {
		            // Prevent UI_dft, UI_min miss setting, and div=0.
		            if ((i2Dft - i2Min) <= 0)
		            {
		                ReturnVal = i4UiRangeDft;
		            }
		            else
		            {
		                ReturnVal = (UINT16) ((i2Cur - i2Min) * (i4UiRangeDft - i4UiRangeMin) /
		                                (i2Dft - i2Min) + i4UiRangeMin);
		            }
		        }
		    }
		}
		return ReturnVal;
}


#if 1//def CC_Factory2K12
/* BEGIN SONY, ramesh, 21/07/09 */

///////////////BEGIN SONY DRV CALLBACK/////////////////

#define NULL_CHK(ptr)  \
          do {                                              \
            if (ptr == NULL)\
            {\
                    return;\
            } } while (0)


extern INT32 OSD_PLA_Enable(UINT32 u4Plane, BOOL fgEnable);

/* >>> START, cheah 31-Jul-09, callback for Sony GammaWB adj + AutoWB */
void cbSony_GammaOSDControl(void* pvArg)
{
    BOOL* bOnOff = (BOOL*)pvArg;
    NULL_CHK(pvArg);

    /* disable/enable OSD */
    if (*bOnOff)
    {
        //OSD_PLA_Force_Off(TRUE);    //OSD_PLA_Force_Off
        OSD_PLA_Enable(OSD_PLANE_1, FALSE);
        OSD_PLA_Enable(OSD_PLANE_2, FALSE);
        OSD_PLA_Enable(OSD_PLANE_3, FALSE);
		//OSD_PLA_Enable_Ex(OSD_PLANE_2, 0);
    }
    else
    {
        //OSD_PLA_Force_Off(FALSE);   //OSD_PLA_Force_Off
        OSD_PLA_Enable(OSD_PLANE_1, TRUE);
        OSD_PLA_Enable(OSD_PLANE_2, TRUE);
        OSD_PLA_Enable(OSD_PLANE_3, TRUE);
        //OSD_PLA_Enable_Ex(OSD_PLANE_2, 1);
    }
}

void cbSony_GammaSetPat(void* pvArg)
{
	ST_PARAM_GAM_PTG* gam_param = (ST_PARAM_GAM_PTG*)pvArg;
	NULL_CHK(pvArg);
	
	if (gam_param->onOff == SV_TRUE)
	{
		/* toggle off first to avoid gamma curve corruption */
		vDrvGammaUnmute(); 
		/* turn ON gamma pattern */
		vDrvGammaMute(gam_param->wGammaR, \
                      gam_param->wGammaG, \
                      gam_param->wGammaB);
	}
	else
	{
		/* turn OFF gamma pattern */
		vDrvGammaUnmute(); 
	}
}

void cbSony_GammaSetSCEPat(void* pvArg)
{
	extern INT32 const YCBCR2RGBOS[3][15];	
	extern INT32 COLOR_TRANSFORM_ADJ[15];
    INT32 COLOR_TRANSFORM_Y2R[15];
    static UINT8 fgOnOff = SV_OFF;
    ST_PARAM_SCE_PTG* sce_param = (ST_PARAM_SCE_PTG*)pvArg;
    NULL_CHK(pvArg);

    vDrvSCEPatGen(sce_param->onOff, sce_param->data);
    vDrvSCEAllOnOff(sce_param->sceProc);       
    if (sce_param->onOff) 
    { 
        fgOnOff = bDrvGetBlueStretchOnOff(); /* store latest setting */
        if (fgOnOff)
        {
            vDrvSetBlueStretchOnOff(SV_VP_MAIN, SV_OFF); /* bypass blue stretch */
        }
        
		x_memcpy(COLOR_TRANSFORM_Y2R, YCBCR2RGBOS[0], sizeof(COLOR_TRANSFORM_Y2R));
        vLoadOSColorMatrix(SV_VP_MAIN, COLOR_TRANSFORM_Y2R);
        vOSTGVideoPlaneHWMute(SV_VP_MAIN,0); //Disable HDMI mute during pattern on
        _vDrvVideoForceUnMute(0, 1);
    }
    else
    { 
        if (fgOnOff != bDrvGetBlueStretchOnOff())
        {
            vDrvSetBlueStretchOnOff(SV_VP_MAIN, fgOnOff); /* restore user blue stretch setting */
        }
        
        vOSTGVideoPlaneHWMute(SV_VP_MAIN,1); //Enable HDMI mute
        _vDrvVideoForceUnMute(0, 0);		
        vLoadOSColorMatrix(SV_VP_MAIN, COLOR_TRANSFORM_ADJ);
    }	
}


void cbSony_WBSetGainOfst(void* pvArg)
{
	ST_PARAM_WB_T* wb_param = (ST_PARAM_WB_T*)pvArg;
	NULL_CHK(pvArg);
	
	/* Color Gain */
	vHalVideoRGBGain(SV_VP_MAIN, SV_RGB_R, wb_param->wGainR);
	vHalVideoRGBGain(SV_VP_MAIN, SV_RGB_G, wb_param->wGainG);
	vHalVideoRGBGain(SV_VP_MAIN, SV_RGB_B, wb_param->wGainB);
	
	/* Color offset */
	vHalVideoRGBOffset(SV_VP_MAIN, SV_RGB_R, wb_param->wOfstR);
	vHalVideoRGBOffset(SV_VP_MAIN, SV_RGB_G, wb_param->wOfstG);
	vHalVideoRGBOffset(SV_VP_MAIN, SV_RGB_B, wb_param->wOfstB);
}

void sonyDrv_RegisterCallback(void)
{
  UINT8 i;
  
  for(i=0; i < CB_DRV_FUNC_COUNT; i++)
  {
    callback_funcs.cbDrv[i] = NULL;
  }

  callback_funcs.cbDrv[CB_DRV_GAM_OSD_CONTROL]       = cbSony_GammaOSDControl;
  callback_funcs.cbDrv[CB_DRV_GAM_PATGEN_GAM]        = cbSony_GammaSetPat;
  callback_funcs.cbDrv[CB_DRV_GAM_PATGEN_SCE]        = cbSony_GammaSetSCEPat;
  callback_funcs.cbDrv[CB_DRV_WB_GAINOFST]           = cbSony_WBSetGainOfst;

  sonyDrvRegisterCallback(&callback_funcs);
}
#endif

//-=============================================


