/* 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 <asm/uaccess.h>
#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 "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_dvi2.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 "hw_tdsharp.h"
#include "hw_scpip_pq.h"
#include "hw_nr.h"
#include "b2r_if.h"
#include "hdmi_if.h"
#include "hw_predown.h"
//#if defined(CC_SUPPORT_4K2K)
#include "mtk_video_drv_4k2k.c"
//#else
//#include "mtk_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_blulight_def.h"
#ifdef CC_SUPPORT_TECHNICOLOR_HDR
#include "drv_technihdr.h" 
#endif


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;

enum
{    
    SNR,
    MNR,
    BNR,
    TNR,    
    SUPER_RES,
    DERING,
    CTI,
    LTI,
    SHARPNESS,
    SCE,
    MATRIX,
    BLUE_STRETCH,
    XVYCC,
    RGB_GAIN,
    RGB_OFFSET,
    GAMMA,
    LCDIM,
    OD,
    PQ_MODULE_MAX,
};


static UINT8 gbSmartPicIndex = 0;
static UINT8 gbSceUi = 0;
static UINT8 gbOdUi = 0;
static UINT8 gbGammaUi = 0;
static UINT16 gu2RawDataTblIndex = 0;
static UINT16 gu2RawDataCaseIndex = 0;

extern MMAppInfo sMMAppInfo;

//#define DRV_SUPPORT_CUST_SCPQ 1

#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

enum
{
	DEMO_PQ_OFF			= 0,
	DEMO_PQ_ON_RIGHT 	= 1,
	DEMO_PQ_ON_LEFT 	= 2
};
//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
#define DEMO_HDR			1	<<	10

#define EN_PEDASTAL_IN_SUB_PATH 1

extern void vUi_BLU_LIGHT_DEF(UINT8 u1VidPath, UINT8 bOnoff);//for demo
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};

UINT32 XVYCC_MATRIX_BT2020NCL[9] =
{
// TODO_RGB2020TORGB709
    0x2A45,    0x1DA64,    0x1FB56,
    0x1F807,    0x0881,    0x1FF77,
    0x1FED6,    0x1F990,    0x0799
};
extern UINT32 DEFAULT_XVYCC_MATRIX[9];
//HDR
PANEL_GAMUT_T panel_Gamut;
TONE_MAP_T    tone_mapping;
//HDR for 2.4 gamma to 2.2
static UINT16 u4TarCtrPoint[4096];
static UINT16 iTarResultOutput[SV_RGB_RGB][4096];
static UINT16 HDRResultGammaTable[GAMMA_INDEX]={0};
static UINT16 i4GamCurveRGB[SV_RGB_RGB][GAMMA_INDEX];
extern UINT16 u2GammaDecodedTable[3][GAMMA_INDEX];
UINT8 preStatusHDR;
#ifdef CC_SUPPORT_TECHNICOLOR_HDR
INT32 DisplayOETF=0;
INT32 DisplayBrightness = 1000;
#endif

#ifdef DRV_SUPPORT_CUST_SCPQ
UINT8 bSharpUITableForScaCoef[][SCAL_COEF_MAX][MAX_COEF_TPYE] =
{
    //HY                                           //HC                                      //VY                                         //VC
    {{255, 255, 255, 255, 255}, {255, 255, 255, 255, 255}, {10, 25, 255, 255, 255},   {10, 25, 255, 255,255},},//480
    {{255, 255, 255, 255, 255}, {255, 255, 255, 255, 255}, {10, 25, 255, 255, 255},   {10, 25, 255, 255, 255},},//576
    {{255, 255, 255, 255, 255}, {255, 255, 255, 255, 255}, {255, 255, 255, 255, 255}, {255, 255, 255, 255, 255},},//others
};

UINT8 bScaCoefIndex[][SCAL_COEF_MAX][MAX_COEF_TPYE] =
{
    //HY                //HC                     //VY                       //VC
    {{0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {6, 8, 8, 8, 8}, {4, 7, 7 ,7, 7},},//480
    {{0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {5, 7, 7, 7, 7}, {5, 7, 7, 7, 7},},//576
    {{0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {4, 4, 4, 4, 4}, {4, 4, 4, 4, 4},},//others
};

UINT32 u4SCVCCustCoeff[][SCPQ_COEF_TBLSIZE] =
{
    #include "Cust_Coef/CustCoef_VYC_p10.txt"  // 0
    #include "Cust_Coef/CustCoef_VYC_p10.txt"  // 1
    #include "Cust_Coef/CustCoef_VYC_p10.txt"  // 2
    #include "Cust_Coef/CustCoef_VYC_p10.txt"  // 3
    #include "Cust_Coef/CustCoef_VYC_p30.txt"  // 4
    #include "Cust_Coef/CustCoef_VYC_p50.txt"  // 5
    #include "Cust_Coef/CustCoef_VYC_p70.txt"   // 6
    #include "Cust_Coef/CustCoef_VC_New2_V6.txt"   // 7
    #include "Cust_Coef/CustCoef_VC_New3_V6.txt"   // 8
    #include "Cust_Coef/CustCoef_VC_New4_V6.txt"   // 9
    #include "Cust_Coef/CustCoef_VC_New5_V6.txt"   // 10
};

UINT32 u4SCVYCustCoeff[][SCPQ_COEF_TBLSIZE] =
{
    #include "Cust_Coef/CustCoef_VYC_p20.txt"  // 0
    #include "Cust_Coef/CustCoef_VYC_p25.txt"  // 1
    #include "Cust_Coef/CustCoef_VYC_p30.txt"  // 2
    #include "Cust_Coef/CustCoef_VYC_p35.txt"  // 3
    #include "Cust_Coef/CustCoef_VY_1.txt"  // 4
    #include "Cust_Coef/CustCoef_VY_4.txt"  // 5
    #include "Cust_Coef/CustCoef_VY_5.txt"  // 6
    #include "Cust_Coef/CustCoef_VY_6.txt"  // 7
    #include "Cust_Coef/CustCoef_VY_7.txt"  // 8
};

UINT32 u4SCVCCustCoeffHD[][SCPQ_COEF_TBLSIZE] =
{
    #include "Cust_Coef/CustCoef_VYC_p60.txt"  // 0
    #include "Cust_Coef/CustCoef_VYC_p70.txt"  // 1
    #include "Cust_Coef/CustCoef_VYC_p80.txt"  // 2
    #include "Cust_Coef/CustCoef_VYC_p90.txt"  // 3
    #include "Cust_Coef/CustCoef_VYC_Def.txt" // 4
};

UINT32 u4SCVYCustCoeffHD[][SCPQ_COEF_TBLSIZE] =
{
    #include "Cust_Coef/CustCoef_VYC_p60.txt"  // 0
    #include "Cust_Coef/CustCoef_VYC_p70.txt"  // 1
    #include "Cust_Coef/CustCoef_VYC_p80.txt"  // 2
    #include "Cust_Coef/CustCoef_VYC_p90.txt"  // 3
    #include "Cust_Coef/CustCoef_VYC_Def.txt" // 4
};

UINT32 u4FilterCoeff_HYDEF[SCPQ_COEF_TBLSIZE] =
{
	#include "Cust_Coef/HYDef.txt"
};
UINT32 u4FilterCoeff_HCDEF[SCPQ_COEF_TBLSIZE] =
{
	#include "Cust_Coef/HCDef.txt"
};
UINT32 u4FilterCoeff_VYCDEF[SCPQ_COEF_TBLSIZE] =
{
	#include "Cust_Coef/VYCDef.txt"
};

UINT32 u4FilterCoeff_HY3[SCPQ_COEF_TBLSIZE] =
{
	#include "Cust_Coef/HY3.txt"
};


UINT32 u4FilterCoeff_HY_CVBS[SCPQ_COEF_TBLSIZE] =
{
	#include "Cust_Coef/HY_CVBS.txt"
};

UINT32 u4FilterCoeff_VYC7[SCPQ_COEF_TBLSIZE] =
{
	#include "Cust_Coef/VY7.txt"
};
UINT32 u4FilterCoeff_HC7[SCPQ_COEF_TBLSIZE] =
{
	#include "Cust_Coef/HC7.txt"
};

UINT32 u4FilterCoeff_HC5[SCPQ_COEF_TBLSIZE] =
{
	#include "Cust_Coef/HC5.txt"
};

UINT32 u4FilterCoeff_HC1[SCPQ_COEF_TBLSIZE] =
{
	#include "Cust_Coef/HC1.txt"
};

UINT32 u4FilterCoeff_VYC6[SCPQ_COEF_TBLSIZE] =
{
	#include "Cust_Coef/VY6.txt"
};

UINT32 u4FilterCoeff_VYC5[SCPQ_COEF_TBLSIZE] =
{
	#include "Cust_Coef/VY5.txt"
};
UINT32 u4FilterCoeff_VYC1[SCPQ_COEF_TBLSIZE] =
{
	#include "Cust_Coef/VY1.txt"
};

UINT32 u4FilterCoeff_4Tap_HYC4[SCPQ_COEF_TBLSIZE] =
{
	#include "Cust_Coef/HY4_4Tap.txt"
};
UINT32 u4FilterCoeff_4Tap_VYC4[SCPQ_COEF_TBLSIZE] =
{
	#include "Cust_Coef/VY4_4Tap.txt"
};

UINT32 u4FilterCoeff_H3[SCPQ_COEF_TBLSIZE] =
{
	#include "Cust_Coef/HY3.txt"
};

UINT32 u4FilterCoeff_V_TTD[SCPQ_COEF_TBLSIZE] =
{
	#include "Cust_Coef/V_down_for_TTD.txt"
};
#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()
{
    //This is sample code : SCE ID can be decided 
    //by panel id , ui setting, picture mode .....
    //UINT8 bPanelIdx = GetCurrentPanelIndex();

    switch (gbSceUi)
    {
        case 0:
        default:
            return 0;
    }
}

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()
{
    //This is sample code : GAMMA ID can be deside 
    //by panel id , ui setting, picture mode .....
    //UINT8 bPanelIdx = GetCurrentPanelIndex();

    switch (gbGammaUi)
    {
        case 1:
            return 0;
        case 2:
            return 1;
        case 3:
            return 2;
        default:
    		return 0;
	}

#if 0 // This is sample code for different gamma table under 3D PR Panel
    switch (gbGammaUi)
    {
        case 1:
            // 3D Using Shutter Glass : IS_LVDS_DISP_3D_SHUTTER
            // 3D Using Polarized Panel : IS_LVDS_DISP_3D_POLARIZED
            //
            // u4DrvTDTV3DModeQuery() : Query 3D Mode

            if((u4DrvTDTV3DModeQuery() != E_TDTV_UI_3D_MODE_OFF) && (IS_LVDS_DISP_3D_POLARIZED))
            {
                return 0;       // gamma table for PR panel
            }
            else
			{
                return 1;       // gamma table for normal state
            }
        default:
    		return 0;
	}
#endif
}

void vApiFlashPqSetGammaId(UINT8 bIndex)
{
    gbGammaUi = bIndex;
}

UINT16 vApiFlashPqGetQtyId(UINT8 bIndex)
{
	UNUSED(bIndex);
    if (PANEL_GetPanelWidth() <= 1440)
    {
        return (2);
    }
    else if(PANEL_GetPanelWidth() <= 1920)
    {
        return (1);
    }
    else
    {
        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()
{
    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 vDrvPQModuleOnOffProc(void)
{
    UINT8 i = 0, j = 0;
    UINT8 fgPqModuleSetting[PQ_MODULE_MAX];
    static UINT8 fgPrePqModuleSetting[PQ_MODULE_MAX]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};

    fgPqModuleSetting[SNR] =(UINT8) IO32ReadFldAlign(SW_MODULE_ON_OFF,SW_CTRL_SNR_MODULE_ONOFF);
    fgPqModuleSetting[MNR] =(UINT8) IO32ReadFldAlign(SW_MODULE_ON_OFF,SW_CTRL_MNR_MODULE_ONOFF);
    fgPqModuleSetting[BNR] =(UINT8) IO32ReadFldAlign(SW_MODULE_ON_OFF,SW_CTRL_BNR_MODULE_ONOFF);
    fgPqModuleSetting[TNR] =(UINT8) IO32ReadFldAlign(SW_MODULE_ON_OFF,SW_CTRL_TNR_MODULE_ONOFF);
    fgPqModuleSetting[SUPER_RES] =(UINT8) (!bIsScalerInputRGB(SV_VP_MAIN) && IO32ReadFldAlign(SW_MODULE_ON_OFF,SW_CTRL_SUPER_RES_MODULE_ONOFF));
    fgPqModuleSetting[DERING] =(UINT8) IO32ReadFldAlign(SW_MODULE_ON_OFF,SW_CTRL_DERING_MODULE_ONOFF);
    fgPqModuleSetting[CTI] =(UINT8) (!bIsScalerInputRGB(SV_VP_MAIN) && IO32ReadFldAlign(SW_MODULE_ON_OFF,SW_CTRL_CTI_MODULE_ONOFF));
    fgPqModuleSetting[LTI] =(UINT8) (!bIsScalerInputRGB(SV_VP_MAIN) && IO32ReadFldAlign(SW_MODULE_ON_OFF,SW_CTRL_LTI_MODULE_ONOFF));
    fgPqModuleSetting[SHARPNESS] =(UINT8) (!bIsScalerInputRGB(SV_VP_MAIN) && IO32ReadFldAlign(SW_MODULE_ON_OFF,SW_CTRL_SHARPNESS_MODULE_ONOFF));   
    fgPqModuleSetting[SCE] =(UINT8) (!bIsScalerInputRGB(SV_VP_MAIN) && IO32ReadFldAlign(SW_MODULE_ON_OFF,SW_CTRL_SCE_MODULE_ONOFF));
    fgPqModuleSetting[BLUE_STRETCH] =(UINT8) IO32ReadFldAlign(SW_MODULE_ON_OFF,SW_CTRL_BLUE_STRETCH_MODULE_ONOFF);
    fgPqModuleSetting[MATRIX] =(UINT8) IO32ReadFldAlign(SW_MODULE_ON_OFF,SW_CTRL_MATRIX_MODULE_ONOFF);
    fgPqModuleSetting[XVYCC] =(UINT8) IO32ReadFldAlign(SW_MODULE_ON_OFF,SW_CTRL_XVYCC_MODULE_ONOFF);
    fgPqModuleSetting[RGB_GAIN] =(UINT8) IO32ReadFldAlign(SW_MODULE_ON_OFF,SW_CTRL_RGB_GAIN_MODULE_ONOFF);
    fgPqModuleSetting[RGB_OFFSET] =(UINT8) IO32ReadFldAlign(SW_MODULE_ON_OFF,SW_CTRL_RGB_OFFSET_MODULE_ONOFF);
    fgPqModuleSetting[GAMMA] =(UINT8) IO32ReadFldAlign(SW_MODULE_ON_OFF,SW_CTRL_GAMMA_MODULE_ONOFF);
    fgPqModuleSetting[LCDIM] =(UINT8) IO32ReadFldAlign(SW_MODULE_ON_OFF,SW_CTRL_LCDIM_MODULE_ONOFF);
    fgPqModuleSetting[OD] =(UINT8) IO32ReadFldAlign(SW_MODULE_ON_OFF,SW_CTRL_OD_MODULE_ONOFF);

    for(i = 0; i < PQ_MODULE_MAX; i++)
    {
        if(fgPqModuleSetting[i] != fgPrePqModuleSetting[i])
        {
            //snr           
            NR_W(NXNR_00, fgPqModuleSetting[SNR], NX_SNR_Y);
            
            //mnr           
            NR_W(NXNR_00, fgPqModuleSetting[MNR], NX_MNR);
            
            //bnr        
            NR_W(NXNR_00, fgPqModuleSetting[BNR], NX_BNR);

            //tnr            
            NR_W(MCNR_00, fgPqModuleSetting[TNR], MCNR_ENABLE);
            
            //super res                
            vIO32WriteFldAlign(CBE_00, fgPqModuleSetting[SUPER_RES], CBEENABLE);
            
            //Dering            
            vIO32WriteFldAlign(SCPIP_SCCTRL1_0A, 0, SCCTRL1_0A_SC_SET_RES_IMPORT_ENABLE_1);   
            vIO32WriteFldAlign(SCPIP_SCCTRL1_0A, 1, SCCTRL1_0A_SC_SET_RES_IMPORT_ENABLE_1);  
            vIO32WriteFldAlign(SCPIP_SCCTRL1_0C, fgPqModuleSetting[DERING], SCCTRL1_0C_SC_DERING_H_EN);           
            vIO32WriteFldAlign(SCPIP_SCCTRL1_0C, fgPqModuleSetting[DERING], SCCTRL1_0C_SC_DERING_V_EN);
            
            //CTI                     
            vIO32WriteFldAlign(ECTIF_00, fgPqModuleSetting[CTI], ECTIF_ENA);
            vIO32WriteFldAlign(CTIR_00, fgPqModuleSetting[CTI], CTIR_ENA);            
            
            //LTI
            vIO32WriteFldAlign(SHARP_00, (!fgPqModuleSetting[LTI]), TDS_DISABLE_LTI_V);	 
	        vIO32WriteFldAlign(SHARP_00, (!fgPqModuleSetting[LTI]), TDS_DISABLE_LTI_H1);	 
	        vIO32WriteFldAlign(SHARP_00, (!fgPqModuleSetting[LTI]), TDS_DISABLE_LTI_H2);	
	        
            //sharpness
            vIO32WriteFldAlign(HSHARP_00, fgPqModuleSetting[SHARPNESS], SHARP_EN); 
            vIO32WriteFldAlign(CDS_00, fgPqModuleSetting[SHARPNESS], CDS1_EN); 
            vIO32WriteFldAlign(CDS_2A, fgPqModuleSetting[SHARPNESS], CDS2_EN);       
            vIO32WriteFldAlign(CDS_54, fgPqModuleSetting[SHARPNESS], CDS3_EN);         
            vIO32WriteFldAlign(SHARP_00, fgPqModuleSetting[SHARPNESS], TDS_EN);
            
            //SCE           
            vIO32WriteFldAlign(SCE_CFG_MAIN, (!fgPqModuleSetting[SCE]), ALLBP);

            //blue stretch            
            vOSTG_IO32WriteFldAlign(BLUESTCH_00, fgPqModuleSetting[BLUE_STRETCH], C_BS_EN_MAIN);            
            vOSTG_IO32WriteFldAlign(BLUESTCH_00, fgPqModuleSetting[BLUE_STRETCH], C_BS_EN_PIP);

            //matrix
            fgPqModuleSetting[MATRIX] ? vDrvVideoColorMatrix(SV_VP_MAIN) : vDrvCalVideoColorMatrix(SV_VP_MAIN,0x80,0x80,0x80,0x80);
            fgPqModuleSetting[MATRIX] ? vDrvVideoColorMatrix(SV_VP_PIP) : vDrvCalVideoColorMatrix(SV_VP_PIP,0x80,0x80,0x80,0x80);

            //Gamma         
            vOSTG_IO32WriteFldAlign(GAMMA_00, fgPqModuleSetting[GAMMA], C_GM_EN);
            
            //RGB gain          
            fgPqModuleSetting[RGB_GAIN] ? bApiVideoProc(SV_VP_MAIN, PE_ARG_R_GAIN) : (vOSTG_IO32WriteFldAlign(GAINOSET_00, 0x200, R_GAIN_MAIN));
            fgPqModuleSetting[RGB_GAIN] ? bApiVideoProc(SV_VP_MAIN, PE_ARG_G_GAIN) : (vOSTG_IO32WriteFldAlign(GAINOSET_00, 0x200, G_GAIN_MAIN));
            fgPqModuleSetting[RGB_GAIN] ? bApiVideoProc(SV_VP_MAIN, PE_ARG_B_GAIN) : (vOSTG_IO32WriteFldAlign(GAINOSET_00, 0x200, B_GAIN_MAIN));
            fgPqModuleSetting[RGB_GAIN] ? bApiVideoProc(SV_VP_PIP, PE_ARG_R_GAIN) : (vOSTG_IO32WriteFldAlign(GAINOSET_01, 0x200, R_GAIN_PIP));                            
            fgPqModuleSetting[RGB_GAIN] ? bApiVideoProc(SV_VP_PIP, PE_ARG_G_GAIN) : (vOSTG_IO32WriteFldAlign(GAINOSET_01, 0x200, G_GAIN_PIP)); 
            fgPqModuleSetting[RGB_GAIN] ? bApiVideoProc(SV_VP_PIP, PE_ARG_B_GAIN) : (vOSTG_IO32WriteFldAlign(GAINOSET_01, 0x200, B_GAIN_PIP)); 

            //RGB offset
            fgPqModuleSetting[RGB_OFFSET] ? bApiVideoProc(SV_VP_MAIN, PE_ARG_R_OFFSET) : (vOSTG_IO32WriteFldAlign(GAINOSET_02, 0, R_OFST1_MAIN));
            fgPqModuleSetting[RGB_OFFSET] ? bApiVideoProc(SV_VP_MAIN, PE_ARG_G_OFFSET) : (vOSTG_IO32WriteFldAlign(GAINOSET_02, 0, G_OFST1_MAIN));
            fgPqModuleSetting[RGB_OFFSET] ? bApiVideoProc(SV_VP_MAIN, PE_ARG_B_OFFSET) : (vOSTG_IO32WriteFldAlign(GAINOSET_02, 0, B_OFST1_MAIN));
            fgPqModuleSetting[RGB_OFFSET] ? bApiVideoProc(SV_VP_PIP, PE_ARG_R_OFFSET) : (vOSTG_IO32WriteFldAlign(GAINOSET_04, 0, R_OFST1_PIP));                                 
            fgPqModuleSetting[RGB_OFFSET] ? bApiVideoProc(SV_VP_PIP, PE_ARG_G_OFFSET) : (vOSTG_IO32WriteFldAlign(GAINOSET_04, 0, G_OFST1_PIP));
            fgPqModuleSetting[RGB_OFFSET] ? bApiVideoProc(SV_VP_PIP, PE_ARG_B_OFFSET) : (vOSTG_IO32WriteFldAlign(GAINOSET_04, 0, B_OFST1_PIP));

            //OD
            //LCDim
            //xvYcc
            
            for(j = 0; j < PQ_MODULE_MAX; j++) 
            {
                fgPrePqModuleSetting[j] = fgPqModuleSetting[j];
            }
        }

    }
    
}

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

    return;
}

void DRVCUST_VideoInit(void)
{
    DRVCUST_AdaptiveBacklightInit();

#ifdef DRV_SUPPORT_CUST_SCPQ
    vIO32WriteFldAlign(VDP_SCPQ_01, SV_ON, SCPQ_CUST_UPCOEFF);
#endif
    vIO32WriteFldAlign(HDR_FW_TOP, 1, HDR_MERG_GAMMA_EN);
    vIO32WriteFldAlign(HDR_FW_TOP, 1, HDR_24_GAMMA_EN);
}

void DRVCUST_XvyccInit(void)
{
    //xvYCC HW init
    vOSTG_IO32WriteFldAlign(XVYCC_10, 0xFFF, REG_GAMMA_G_SRAM_4096);
	vOSTG_IO32WriteFldAlign(XVYCC_10, 0xFFF, REG_GAMMA_R_SRAM_4096);
	vOSTG_IO32WriteFldAlign(XVYCC_11, 0xFFF, REG_GAMMA_B_SRAM_4096);
    vDrvxvYCCLoad3x3Matrix(DEFAULT_XVYCC_MATRIX);
}

#ifdef DRV_SUPPORT_CUST_SCPQ
void vApiCheckSharpnessUIValueForScalerCoef(void)
{
    UINT8 i,j;
    UINT8 bCurrentSharpUI = IO32ReadFldAlign(VDP_SCPQ_02, SCPQ_CUST_SHARP_UI);
    UINT8 reMappingTiming;
    UINT8 bCurrentCoefIndex[SCAL_COEF_MAX] = {0, 0, 0, 0};
    UINT8 bIdxStep;
   
    switch (wDrvVideoInputHeight(SV_VP_MAIN))
    {
        case 480:
            reMappingTiming = 0;
            break;
        case 576:
            reMappingTiming = 1;
            break;
        case 720:
        case 1080:
        default:
            reMappingTiming = 2;
            break;
    }

    for (j = SCAL_COEF_VY; j<=SCAL_COEF_VC; j++)
    {
        for(i=0; i<MAX_COEF_TPYE; i++)
        {
            if (bCurrentSharpUI < bSharpUITableForScaCoef[reMappingTiming][j][i])
            {
                if (i==0)
                {
                    //bIdxStep = bSharpUITableForScaCoef[reMappingTiming][j][i];
                    //bCurrentCoefIndex[j] = (bScaCoefIndex[reMappingTiming][j][i]*bCurrentSharpUI)/bIdxStep ;
                    bCurrentCoefIndex[j] = bScaCoefIndex[reMappingTiming][j][i];
                }
                else
                {
                    bIdxStep = bSharpUITableForScaCoef[reMappingTiming][j][i] - bSharpUITableForScaCoef[reMappingTiming][j][i-1];
                    bCurrentCoefIndex[j] = (bScaCoefIndex[reMappingTiming][j][i-1]*(bSharpUITableForScaCoef[reMappingTiming][j][i]-bCurrentSharpUI) + 
                                                   bScaCoefIndex[reMappingTiming][j][i]*(bCurrentSharpUI - bSharpUITableForScaCoef[reMappingTiming][j][i-1]))/bIdxStep ;
               }                                
               break;
            }
        }
    }
    
    if ((bCurrentCoefIndex[SCAL_COEF_VY] != IO32ReadFldAlign(VDP_SCPQ_02, SCPQ_CUST_VY_FILTER_ID))
        ||(bCurrentCoefIndex[SCAL_COEF_VC] != IO32ReadFldAlign(VDP_SCPQ_02, SCPQ_CUST_VC_FILTER_ID)))
    {
        vIO32WriteFldAlign(VDP_SCPQ_02, bCurrentCoefIndex[SCAL_COEF_VY], SCPQ_CUST_VY_FILTER_ID);
        vIO32WriteFldAlign(VDP_SCPQ_02, bCurrentCoefIndex[SCAL_COEF_VC], SCPQ_CUST_VC_FILTER_ID);
        vApiRegisterVideoEvent(PE_EVENT_SCALER_V, SV_VP_MAIN, SV_ON);
    }

}

UINT8 vDrvCustSetVCoeff(UINT8 bPath, UINT8 Y_Coef_Index, UINT8 C_Coef_Index)
{    
    if(bPath!=SV_VP_MAIN)
        return SV_FALSE;

    if (Y_Coef_Index < MAX_VY_COEF_IDX)
    {
    	vDrvSCPQSetSramCoeff(COEFTYP_VER_Y, u4SCVYCustCoeff[Y_Coef_Index]);
    }
    if (C_Coef_Index < MAX_VC_COEF_IDX)
    {
    	vDrvSCPQSetSramCoeff(COEFTYP_VER_C, u4SCVCCustCoeff[C_Coef_Index]);					
    }
    return SV_TRUE;
}

UINT8 vDrvCustSetVCoeffHD(UINT8 bPath, UINT8 Y_Coef_Index, UINT8 C_Coef_Index)
{    
    if(bPath!=SV_VP_MAIN)
        return SV_FALSE;

    if (Y_Coef_Index < MAX_VY_COEF_HD_IDX)
    {
    	vDrvSCPQSetSramCoeff(COEFTYP_VER_Y, u4SCVYCustCoeffHD[Y_Coef_Index]);
    }
    if (C_Coef_Index < MAX_VC_COEF_HD_IDX)
    {
    	vDrvSCPQSetSramCoeff(COEFTYP_VER_C, u4SCVCCustCoeffHD[C_Coef_Index]);					
    }
    return SV_TRUE;
}

void DRVCUST_SetVCTIGain(UINT32 u4CoefVCOFST)
{
    UINT32 u4VCTIGain, u4Gain;

    u4VCTIGain = IO32ReadFldAlign(VDP_SCPQ_02, SCPQ_VCTI_GAIN);
    u4Gain = 0x80 - u4CoefVCOFST * 0x20;    // OFST = 0~4; Gain = 0x80~0x0
    u4VCTIGain = (u4VCTIGain * u4Gain) / 0x80;
    vIO32WriteFldAlign(SCFIR_11, u4VCTIGain, VERT_CTI_GAIN);
}
#endif

void DRVCUST_HUPSCaleCoeff(UINT8 bPath)
{
#ifdef DRV_SUPPORT_CUST_SCPQ
    UINT32 u4SrcType = bGetSignalType(bPath);
    UINT32 u4SrcHeight = wDrvVideoInputHeight(bPath);

    // Set up-scaler coefficient
    if (bIsScalerInput444(bPath))
    {
        if (u4IO32Read4B(SCALER_COEF_MAIN_H_IN) >= 1280 )
        {
            vDrvSCPQSetSramCoeff(COEFTYP_HOR_Y, u4FilterCoeff_HYDEF);
            vDrvSCPQSetSramCoeff(COEFTYP_HOR_C, u4FilterCoeff_HCDEF);   
            LOG(2, "Scaler Coefficient RGB444: u4FilterCoeff_4Tap_HDEF\n");

        }
        else
        {
		vDrvSCPQSetSramCoeff(COEFTYP_HOR_Y, u4FilterCoeff_4Tap_HYC4);
		vDrvSCPQSetSramCoeff(COEFTYP_HOR_C, u4FilterCoeff_4Tap_HYC4);
            LOG(2, "Scaler Coefficient RGB444: u4FilterCoeff_4Tap_HYC4\n");
        }
    }
    else if (u4SrcHeight >= 720)
    {   // HD source
		vDrvSCPQSetSramCoeff(COEFTYP_HOR_Y, u4FilterCoeff_HYDEF);
		vDrvSCPQSetSramCoeff(COEFTYP_HOR_C, u4FilterCoeff_HCDEF);	
        LOG(2, "Scaler Coefficient: u4FilterCoeff_DEF HYC\n");
    }
    else if (u4SrcHeight >= 500)
    {   // SD 576 source
        if ((u4SrcType == SV_ST_DVI)  || (u4SrcType == SV_ST_MPEG))
        {   // HDMI, DTV
			vDrvSCPQSetSramCoeff(COEFTYP_HOR_Y, u4FilterCoeff_HY3);
			vDrvSCPQSetSramCoeff(COEFTYP_HOR_C, u4FilterCoeff_HC5);
            LOG(2, "Scaler Coefficient: u4FilterCoeff_HY3 HC5 576\n");
        }
        else if (u4SrcType == SV_ST_YP)
        {   // Component
			vDrvSCPQSetSramCoeff(COEFTYP_HOR_Y, u4FilterCoeff_HY3);
			vDrvSCPQSetSramCoeff(COEFTYP_HOR_C, u4FilterCoeff_HC1);			
            LOG(2, "Scaler Coefficient: u4FilterCoeff_HY3_HC1 576\n");
        }
        else
		{   // ATV, AV, SV
			vDrvSCPQSetSramCoeff(COEFTYP_HOR_Y, u4FilterCoeff_HY_CVBS);
			vDrvSCPQSetSramCoeff(COEFTYP_HOR_C, u4FilterCoeff_HC7);		
            LOG(2, "Scaler Coefficient: u4FilterCoeff_HY3_HC7 576\n");
        }
    }
    else
    {   // SD 480 source
        if ((u4SrcType == SV_ST_DVI) || (u4SrcType == SV_ST_MPEG))
        {   // HDMI, DTV
			vDrvSCPQSetSramCoeff(COEFTYP_HOR_Y, u4FilterCoeff_HY3);
			vDrvSCPQSetSramCoeff(COEFTYP_HOR_C, u4FilterCoeff_HC5);		
            LOG(2, "Scaler Coefficient: u4FilterCoeff_HY3_HC5 480\n");
        }
        else if (u4SrcType == SV_ST_YP)
        {   // Component
			vDrvSCPQSetSramCoeff(COEFTYP_HOR_Y, u4FilterCoeff_HY3);
			vDrvSCPQSetSramCoeff(COEFTYP_HOR_C, u4FilterCoeff_HC1);		
            LOG(2, "Scaler Coefficient: u4FilterCoeff_HY3_HC1 480\n");
        }
        else
        {   // ATV, AV, SV
			vDrvSCPQSetSramCoeff(COEFTYP_HOR_Y, u4FilterCoeff_HY_CVBS);
			vDrvSCPQSetSramCoeff(COEFTYP_HOR_C, u4FilterCoeff_HC7);		
            LOG(2, "Scaler Coefficient: u4FilterCoeff_HY3_HC7 480\n");
        }
    }
#endif
}

void DRVCUST_VUPSCaleCoeff(UINT8 bPath)
{
#ifdef DRV_SUPPORT_CUST_SCPQ
    UINT32 u4SrcHeight = wDrvVideoInputHeight(bPath);
    UINT32 u4CoefVYID, u4CoefVCID, u4CoefVYOFST, u4CoefVCOFST;

    u4CoefVYID = IO32ReadFldAlign(VDP_SCPQ_02, SCPQ_CUST_VY_FILTER_ID);
    u4CoefVCID = IO32ReadFldAlign(VDP_SCPQ_02, SCPQ_CUST_VC_FILTER_ID);
    u4CoefVYOFST = IO32ReadFldAlign(VDP_SCPQ_03, SCPQ_CUST_VY_OFST);
    u4CoefVCOFST = IO32ReadFldAlign(VDP_SCPQ_03, SCPQ_CUST_VC_OFST);

    u4CoefVYID = (u4CoefVYID >= u4CoefVYOFST) ? (u4CoefVYID - u4CoefVYOFST) : 0;
    u4CoefVCID = (u4CoefVCID >= u4CoefVCOFST) ? (u4CoefVCID - u4CoefVCOFST) : 0;

    // Set up-scaler coefficient
    if (bIsScalerInput444(bPath))
    {
        if (u4IO32Read4B(SCALER_COEF_MAIN_V_IN) >= 720 )
        {
            vDrvSCPQSetSramCoeff(COEFTYP_VER_Y, u4FilterCoeff_VYCDEF);
            vDrvSCPQSetSramCoeff(COEFTYP_VER_C, u4FilterCoeff_VYCDEF);
            LOG(2, "Scaler Coefficient RGB444: u4FilterCoeff_4Tap VYCDEF\n");
        }
        else
        {
            vDrvSCPQSetSramCoeff(COEFTYP_VER_Y, u4FilterCoeff_4Tap_VYC4);
            vDrvSCPQSetSramCoeff(COEFTYP_VER_C, u4FilterCoeff_4Tap_VYC4);
            LOG(2, "Scaler Coefficient RGB444: u4FilterCoeff_4Tap VYC4\n");
        }
    }
    else if (u4DrvTDTV3DModeQuery() == E_TDTV_UI_3D_MODE_TTD)
    {
        vDrvSCPQSetSramCoeff(COEFTYP_VER_Y, u4FilterCoeff_V_TTD);
        vDrvSCPQSetSramCoeff(COEFTYP_VER_C, u4FilterCoeff_V_TTD);		
        LOG(2, "Scaler Coefficient: u4FilterCoeff VYC for TTD\n");
    }
    else if (u4DrvTDTV3DModeQuery() == E_TDTV_UI_3D_MODE_TB)
    {
        vDrvSCPQSetSramCoeff(COEFTYP_VER_Y, u4FilterCoeff_VYC7);
        vDrvSCPQSetSramCoeff(COEFTYP_VER_C, u4FilterCoeff_VYC7);
        LOG(2, "Scaler Coefficient: u4FilterCoeff VYC for TAB\n");
    }
    else if (u4DrvTDTV3DModeQuery() == E_TDTV_UI_3D_MODE_OFF)
    {
        if (u4SrcHeight >= 720)
        {   // HD source
            vDrvCustSetVCoeffHD(bPath, u4CoefVYID, u4CoefVCID);
            LOG(2, "Scaler Coefficient: u4FilterCoeff HD, VY %d, VC %d\n", u4CoefVYID, u4CoefVCID);
        }
        else if (u4SrcHeight >= 500)
        {
            // SD PAL
            vDrvCustSetVCoeff(bPath, u4CoefVYID, u4CoefVCID);
            LOG(2, "Scaler Coefficient: u4FilterCoeff 576, VY %d, VC %d\n", u4CoefVYID, u4CoefVCID);
        }
        else
        {  
            // SD NTSC
            vDrvCustSetVCoeff(bPath, u4CoefVYID, u4CoefVCID);
            LOG(2, "Scaler Coefficient: u4FilterCoeff 480, VY %d, VC %d\n", u4CoefVYID, u4CoefVCID);
        }
    }
    else
    {
        vDrvSCPQSetSramCoeff(COEFTYP_VER_Y, u4FilterCoeff_VYCDEF);
        vDrvSCPQSetSramCoeff(COEFTYP_VER_C, u4FilterCoeff_VYCDEF);	
        LOG(2, "Scaler Coefficient: u4FilterCoeff VYC DEF for other 3D mode\n");
    }

    if (bPath == SV_VP_MAIN)
    {
        DRVCUST_SetVCTIGain(u4CoefVCOFST);
    }
#endif
}

void DRVCUST_VdoModeChgDone(UINT8 bPath)
{
    UNUSED(bPath);
}

void DRVCUST_VideoMainloop()
{
	UINT8 i=0;

    DRVCUST_AdaptiveBacklightProc();

#ifdef DRV_SUPPORT_CUST_SCPQ
    vApiCheckSharpnessUIValueForScalerCoef();    
#endif
    if((bDrvVideoSignalStatus(SV_VP_MAIN) == (UINT8)SV_VDO_STABLE) ||
       (bDrvVideoSignalStatus(SV_VP_PIP) == (UINT8)SV_VDO_STABLE))
    {
         if(IO32ReadFldAlign(SW_MODULE_ON_OFF,SW_CTRL_MODULE_ONOFF))
        {
            vDrvPQModuleOnOffProc();
        }
		if(IO32ReadFldAlign(HDR_FW_TOP, RES_CHANGE_EN)&&(preStatusHDR!=fgIsHdr))
        {
            preStatusHDR=fgIsHdr;
            vVdoSetColorTransform(SV_VP_MAIN);
            vDrvVideoColorMatrix(SV_VP_MAIN);            
            for (i = PE_ARG_BRIGHTNESS; i < PE_ARG_BLULIGHT; i++)
            {

                bApiVideoProc(SV_VP_MAIN, i);
            }
            vIO32WriteFldAlign(HDR_FW_TOP, 0, RES_CHANGE_EN);
        }
    }
}

void DRVCUST_OutVSyncISR()
{
/*
    vDrvLcdimProc();
    if( IO32ReadFldAlign(ADAP_LCDIM_SPI, SPI_AUTO_VSYNC_EN)== SV_TRUE)
    {
        vDrvLcdimSpiCommandGen(E_SPI_PAGE_WRITE, 0);
    }
    */
    //static UINT8 arg=0xFF;
    static UINT8 u1VidPath = SV_VP_MAIN;
    static UINT8 i2Cur = 0;
	static UINT8 i2Pre = 0;
	i2Cur = (UINT8) IO32ReadFldAlign(BLULIGHT_CTL, BLU_CTL_STR);
	if (i2Cur != i2Pre)
	{
		 vUi_BLU_LIGHT_DEF(u1VidPath, i2Cur);		 
		 i2Pre = i2Cur;
	}
    return;
}

void DRVCUST_PostOutVSyncISR(void)
{

}

void DRVCUST_PostDEEndISR(void)
{

}

void DRVCUST_VdoInISR()
{
    return;
}

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_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
}

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

UINT8 DRVCUST_HDMIGetColorSpace(UINT8 bPath)
{
    return (UINT8)eHdmiIf_GetColorSpace(bPath);
}

UINT8 DRVCUST_HDMIGetHDRType(UINT8 bPath)
{
    UINT8 u1EOTF = 0;

    u1EOTF = u1HdmiIf_GetHdrEOTF(bPath);
    if(HDMI_INVALID_HDR_EOTF_VALUE == u1EOTF)
    {
        return SV_HDR_TYPE_UNKNOWN;
    }

    if(u1EOTF == 2)
    {
        return SV_HDR_TYPE_HDR1;
    }
    else if(u1EOTF == 3)
    {
        return SV_HDR_TYPE_HDR2;
    }

    return SV_HDR_TYPE_SDR;
}


BOOL DRVCUST_HDMIGetHDRInfo(UINT8 bPath, SV_HDR_INFO_T* prHDRInfo)
{
    HDMI_IF_HDR_METADATA rHdmiIfHdrMetaData;
    HDR_ETOF_MODE eEOTF = SV_HDRTYPE_UNKNOWN;
    UINT8 u1HdmiParseEOTF = 0;

    if(prHDRInfo == NULL)
    {
        return FALSE;
    }

    u1HdmiParseEOTF = u1HdmiIf_GetHdrEOTF(bPath);
    if(HDMI_INVALID_HDR_EOTF_VALUE == u1HdmiParseEOTF)
    {
        LOG(1,"No EOTF is valid!\n");
        return FALSE;
    }

    switch (u1HdmiParseEOTF)
    {
        case 0:
            eEOTF = SV_HDRTYPE_SDR;
            break;
        case 1:
            eEOTF = SV_HDRTYPE_HDR;
            break;
        case 2:
            eEOTF = SV_HDRTYPE_ST2084;
            break;
        case 3:
            eEOTF = SV_HDRTYPE_HLG;
            break;
        default:
            eEOTF = SV_HDRTYPE_Future_EOTF;
            break;
    }
    prHDRInfo->eEOTF = eEOTF;

    vHdmiIf_GetHdrMetadata(bPath,&rHdmiIfHdrMetaData);
    prHDRInfo->au2Primaries_x[0] = (rHdmiIfHdrMetaData.au1HdrMetadata[1]<<8) | rHdmiIfHdrMetaData.au1HdrMetadata[0];
    prHDRInfo->au2Primaries_y[0] = (rHdmiIfHdrMetaData.au1HdrMetadata[3]<<8) | rHdmiIfHdrMetaData.au1HdrMetadata[2];
    prHDRInfo->au2Primaries_x[1] = (rHdmiIfHdrMetaData.au1HdrMetadata[5]<<8) | rHdmiIfHdrMetaData.au1HdrMetadata[4];
    prHDRInfo->au2Primaries_y[1] = (rHdmiIfHdrMetaData.au1HdrMetadata[7]<<8) | rHdmiIfHdrMetaData.au1HdrMetadata[6];
    prHDRInfo->au2Primaries_x[2] = (rHdmiIfHdrMetaData.au1HdrMetadata[9]<<8) | rHdmiIfHdrMetaData.au1HdrMetadata[8];
    prHDRInfo->au2Primaries_y[2] = (rHdmiIfHdrMetaData.au1HdrMetadata[11]<<8) | rHdmiIfHdrMetaData.au1HdrMetadata[10];

    prHDRInfo->u2White_Point_x = (rHdmiIfHdrMetaData.au1HdrMetadata[13]<<8) | rHdmiIfHdrMetaData.au1HdrMetadata[12];
    prHDRInfo->u2White_Point_y = (rHdmiIfHdrMetaData.au1HdrMetadata[15]<<8) | rHdmiIfHdrMetaData.au1HdrMetadata[14];

    prHDRInfo->u2MaxLuminance = (rHdmiIfHdrMetaData.au1HdrMetadata[17]<<8) | rHdmiIfHdrMetaData.au1HdrMetadata[16];
    prHDRInfo->u2MinLuminance = (rHdmiIfHdrMetaData.au1HdrMetadata[19]<<8) | rHdmiIfHdrMetaData.au1HdrMetadata[18];
    prHDRInfo->u2ContentLevel = (rHdmiIfHdrMetaData.au1HdrMetadata[21]<<8) | rHdmiIfHdrMetaData.au1HdrMetadata[20];
    prHDRInfo->u2FrameAverageLevel = (rHdmiIfHdrMetaData.au1HdrMetadata[23]<<8) | rHdmiIfHdrMetaData.au1HdrMetadata[22];
        
    return TRUE;
}


BOOL vDrvGetHDRCapabilities(UINT32* u4OutNumTypes, UINT32* u4Types, UINT32* u4maxLuminance, UINT32* u4maxAverageLuminance, UINT32* u4minLuminance )
{
    UINT32 u4HdrNumTypes = 2;
    UINT32 u4HdrTypes[HDR_TYPE] = {2,3};//1:HDR_TYPE_DOLBY_VISION,2:HDR_TYPE_HDR10,3:HDR_TYPE_HLG
    UINT32 u4HdrMaxLuminance = 2000;
    UINT32 u4HdrMaxAverageLuminance = 1000;
    UINT32 u4HdrMinLuminance = 5;

    if(u4Types == NULL)
    {
        if(u4OutNumTypes != NULL )
        {
        		*u4OutNumTypes = u4HdrNumTypes;  
          }
          else
          {
                LOG(0,"****vDrvGetHDRCapabilities u4OutNumTypes is NULL****\n");
          }
         LOG(0,"****vDrvGetHDRCapabilities u4Types is NULL****\n");
        return SV_FALSE;
    }
    else if((u4maxLuminance == NULL )||(u4maxAverageLuminance == NULL)||(u4minLuminance == NULL) )
    {
    	 LOG(0,"****vDrvGetHDRCapabilities other element is NULL****\n");
    	 return SV_FALSE;
    }
    //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 SV_TRUE;
}

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_MMAPPGetTiming(UINT8 bOutputTiming)
{
    if (sMMAppInfo.u1AppType == 0xFF) //Pretend for Netflix App
    {
        // Temp threshold
        bOutputTiming = (sMMAppInfo.u4BitRate < 100) ?  
            SOURCE_TYPE_TIMING_MM_720P_SD : SOURCE_TYPE_TIMING_MM_720P_HD;
    }

    LOG(5, "DRVCUST_MMAPPGetTiming %d %d\n", sMMAppInfo.u4BitRate, bOutputTiming);

    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);
}


void DRVCUST_SET_GAMMA(void)
{
    /* ============================= Sample code ===================================
    
    1. Read gamma data from EEPROM, maybe need some check flow
        => Example 8bit 6 control points with 12bit gamma data
        INT32 iCtlPos[6] =   {0x000, 0x020, 0x040, 0x080, 0x0C0, 0x0FF};
        INT32 iCtlValue_R[6] = {0x013, 0x233, 0x3E5, 0x7C4, 0xB20, 0xEF4};

    2. Interplaotion to 257 red gamma table
        static INT32 OutputLut[257];
        vDrvGammaInterpolation(6, iCtlPos, iCtlValue_R, OutputLut);        

    3. Copy 257 data to u2GammaDecodedTable[] 
        
    ============================= Sample code End ===================================*/        
    if (IO32ReadFldAlign(HDR_FW_TOP, HDR_24_GAMMA_EN) && (IO32ReadFldAlign(HDR2SDR_NXNR_CTRL_0, C_HDR2SDR_NXNR_BYPASS_0) == 0))
     {  
        u1DRVCUST_LoadHDRGammaTbl();
     } 
}
//Interpolate from 257 ctrl point to 4096 point gamma curve
void DRVCUST_GAMLinearInterpolation(UINT16 u4CtrlCount, UINT16* u4CtrlPos, UINT16* u4TarCtrPos, UINT16* iCtrlValue, UINT16* OutputLut)
{
	int i, j,idx;
	INT32 u4Temp;
	
	OutputLut[0] = iCtrlValue[0];
	OutputLut[4095] = iCtrlValue[u4CtrlCount - 1];
	
	for(i = 0; i<u4CtrlCount-1; i++)
	{
		for(j = u4CtrlPos[i]; j<4096; j++)
		{
		    if(j > u4CtrlPos[i+1]-1)
		    {
               LOG(4,"j=%d > u4CtrlPos[%d]=%d break\n",j,i+1,u4CtrlPos[i+1]);
			   break;
		    }
		    else 
		    {
		     //Rounding
		        u4Temp = (iCtrlValue[i+1] - iCtrlValue[i])*(j -  u4CtrlPos[i])/(u4CtrlPos[i+1] - u4CtrlPos[i]);
		        LOG(4,"temp=%d \n", u4Temp);
		        OutputLut[j] = iCtrlValue[i] + (UINT16)(u4Temp);//how to rounding?
		        LOG(4,"iCtrlValue[%d]=%d ;iCtrlValue[%d]=%d,u4CtrlPos[i]%d ;OutputLut[%d]=%d \n",i,iCtrlValue[i],i+1,iCtrlValue[i+1],u4CtrlPos[i],j,OutputLut[j]);		        
		    }
		}
	}	
	return;
}

void u1DRVCUST_LoadHDRGammaTbl(void)
{	
    int i;
    UINT16 u2Idx;
    UINT16 u4CtrlPoint[GAMMA_INDEX];

    LOG(1,"**************u1DRVCUST_LoadHDRGammaTbl******************\n");
    x_memcpy(HDRResultGammaTable,GAMMA_2P4,GAMMA_INDEX*sizeof(UINT16));
    if(IO32ReadFldAlign(HDR_FW_TOP, HDR_MERG_GAMMA_EN))
    {
        for(i = 0;i < GAMMA_INDEX; i++)
        {
            if(i == (GAMMA_INDEX-1))
            {
                 u4CtrlPoint[i] = (UINT16)((i<<4)-1);
            }
            else
            {
                u4CtrlPoint[i] = (UINT16)(i<<4);
            }
            LOG(3,"u2GammaDecodedTable[%d]=%d \n",i,u2GammaDecodedTable[0][i]);
        }
        x_memcpy(&iTarResultOutput[0],HDR_TartRTable,4096*sizeof(UINT16));
        x_memcpy(&iTarResultOutput[1],HDR_TartRTable,4096*sizeof(UINT16));
        x_memcpy(&iTarResultOutput[2],HDR_TartRTable,4096*sizeof(UINT16));
        
    
        DRVCUST_GAMLinearInterpolation(GAMMA_INDEX, u4CtrlPoint, u4TarCtrPoint, u2GammaDecodedTable[SV_RGB_R], iTarResultOutput[SV_RGB_R]);
        DRVCUST_GAMLinearInterpolation(GAMMA_INDEX, u4CtrlPoint, u4TarCtrPoint, u2GammaDecodedTable[SV_RGB_G], iTarResultOutput[SV_RGB_G]);
        DRVCUST_GAMLinearInterpolation(GAMMA_INDEX, u4CtrlPoint, u4TarCtrPoint, u2GammaDecodedTable[SV_RGB_B], iTarResultOutput[SV_RGB_B]);
        for(i = 0;i < GAMMA_INDEX; i++)
        {
            u2Idx = MIN(4095,HDRResultGammaTable[i]);

                i4GamCurveRGB[SV_RGB_R][i] = MIN(4095,iTarResultOutput[SV_RGB_R][u2Idx]);
                i4GamCurveRGB[SV_RGB_G][i] = MIN(4095,iTarResultOutput[SV_RGB_G][u2Idx]);
                i4GamCurveRGB[SV_RGB_B][i] = MIN(4095,iTarResultOutput[SV_RGB_B][u2Idx]);

                LOG(3,"u2Idx=%d, iTarResultOutputR[%d]= %d \n",u2Idx,i,iTarResultOutput[SV_RGB_R][u2Idx]);
                LOG(3,"u2Idx=%d, iTarResultOutputG[%d]= %d \n",u2Idx,i,iTarResultOutput[SV_RGB_G][u2Idx]);
                LOG(3,"u2Idx=%d, iTarResultOutputB[%d]= %d \n",u2Idx,i,iTarResultOutput[SV_RGB_B][u2Idx]);
                     
        }
    	for (i = 0; i<GAMMA_INDEX; i++) 																																	  
    	{																																				  
    		u2GammaDecodedTable[SV_RGB_R][i] =i4GamCurveRGB[SV_RGB_R][i];																									  
    		u2GammaDecodedTable[SV_RGB_G][i] = i4GamCurveRGB[SV_RGB_G][i];																									  
    		u2GammaDecodedTable[SV_RGB_B][i] = i4GamCurveRGB[SV_RGB_B][i];																									  
    	}        
    }
    else
    {    
        for(i = 0;i < GAMMA_INDEX; i++)
        {
            u2GammaDecodedTable[0][i] = HDRResultGammaTable[i];
            u2GammaDecodedTable[1][i] = HDRResultGammaTable[i];
            u2GammaDecodedTable[2][i] = HDRResultGammaTable[i];
        }
    }
}
UINT16 DRVCUST_GetPanelNits(void)
{
    UINT16 PanelNits = 350;
//TO-BE by cust

    return PanelNits;
    
}
UINT8 DRVCUST_GetPanelMode(void)
{
//TO-BE by cust
//709 return 0,other return 1
 if(1)
  {
     return SV_FALSE;
  }
  else
  {
    //DRVCUST_GetPanelGamut must set
     return SV_TRUE;
  }    
}

PANEL_GAMUT_T DRVCUST_GetPanelGamut(void)
{
    panel_Gamut.BT2020_c00=0;
    panel_Gamut.BT2020_c01=0;
    panel_Gamut.BT2020_c02=0;
    panel_Gamut.BT2020_c10=0;
    panel_Gamut.BT2020_c11=0;
    panel_Gamut.BT2020_c12=0;
    panel_Gamut.BT2020_c20=0;
    panel_Gamut.BT2020_c21=0;        
    panel_Gamut.BT2020_c22=0;

    panel_Gamut.BT709_c00=0;
    panel_Gamut.BT709_c01=0;
    panel_Gamut.BT709_c02=0;
    panel_Gamut.BT709_c10=0;
    panel_Gamut.BT709_c11=0;
    panel_Gamut.BT709_c12=0;
    panel_Gamut.BT709_c20=0;
    panel_Gamut.BT709_c21=0;        
    panel_Gamut.BT709_c22=0;
    
    return panel_Gamut;
    
};
TONE_MAP_T DRVCUST_GetToneMap(void)
{
    //TO-BE by cust
	tone_mapping.reg_p1 = 5576;
                          
	tone_mapping.reg_p2 = 11151;
                          
	tone_mapping.reg_p3 = 18204;
                          
	tone_mapping.reg_p4 = 25258;
                          
	tone_mapping.reg_p5 = 32311;
                          
	tone_mapping.reg_p6 = 39365;
                          
	tone_mapping.reg_p7 = 47794;
                          
	tone_mapping.reg_p8 = 56222;
                          
	tone_mapping.reg_p9 = 64651;

	tone_mapping.reg_p10 = 73080;
                           
	tone_mapping.reg_p11 = 81015;
                           
	tone_mapping.reg_p12 = 91536;
                           
	tone_mapping.reg_p13 = 102056;
                           
	tone_mapping.reg_p14 = 116545;
                           
	tone_mapping.reg_p15 = 131033;
                           
	tone_mapping.reg_p16 = 524287;

	tone_mapping.reg_slope0 = 39201;
                              
	tone_mapping.reg_slope1 = 37866;
                              
	tone_mapping.reg_slope2 = 35092;
                              
	tone_mapping.reg_slope3 = 31874;
                              
	tone_mapping.reg_slope4 = 28815;
                              
	tone_mapping.reg_slope5 = 25914;
                              
	tone_mapping.reg_slope6 = 22952;
                              
	tone_mapping.reg_slope7 = 20110;
                              
	tone_mapping.reg_slope8 = 17702;
                              
	tone_mapping.reg_slope9 = 15727;

	tone_mapping.reg_slope10 = 14187;
                               
	tone_mapping.reg_slope11 = 12711;
                               
	tone_mapping.reg_slope12 = 12001;
                               
	tone_mapping.reg_slope13 = 9988;
                               
	tone_mapping.reg_slope14 = 8972;
                               
	tone_mapping.reg_slope15 = 4380;

    return tone_mapping;
    
};
#ifdef CC_SUPPORT_TECHNICOLOR_HDR
INT32 DRVCUST_GetDisplayBri(void)
{
    return DisplayBrightness;
}
INT32 DRVCUST_GetDisplayOETF(void)
{
    return DisplayOETF;
}
void DRVCUST_SetDisplayBri(INT32 displayBrightness)
{
    DisplayBrightness = displayBrightness;
}
void DRVCUST_SetDisplayOETF(INT32 displayOETF)
{
    DisplayOETF = displayOETF;
}

#endif

UINT8 DRVCUST_GET_CTMode(void)
{
      return FALSE;
}
UINT8 DRVCUST_BE_Connect(UINT8 u1TxPath, UINT8 u1BeSclType , UINT8 u1PlaneOrder, UINT8 bPath)
{
	return SV_FAIL;
}

UINT8 DRVCUST_BE_Disconnect(UINT8 u1TxPath, UINT8 bPath)
{
	return SV_FAIL;
}

void DRVCUST_PQ_Associate(UINT8 bPqPath, UINT8 bPath)
{

}

void DRVCUST_PQ_Disassociate(UINT8 bPqPath)
{

}


void DRVCUST_SET_YGAMMA(UINT32 i1Mode)
{

}

void DRVCUST_AutoColorTempUpdate(AUTO_COLORTEMP_SETS_INFO_T *aCTInfo)
{

}

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 =(UINT8) 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] =(UINT8) 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 =(UINT8) 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]);
    }    
}

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_XVYCC:
                break;
            default:
                UNUSED(bApiVideoProc(bPath, (PE_ARG_TYPE)i));
                break;
        }
    }   
}
void DRVCUST_SendEvent(E_CUST_EVENT eCustEvent, UINT8 u1Option)
{

}
void DRVCUST_SendEcsCommand(UINT8* pData, UINT32 u4Size)
{

}

void DRVCUST_SetBEGeneralData(UINT8* pData, UINT8 u1Size)
{

}

void DRVCUST_PanelPowerStateToBe(BOOL bOnOff)
{

}

void DRVCUST_SharpnessEnhanceEn(UINT8 u1Onoff)
{
	
}

UINT32 DRVCUST_DemoRegion(void)
{  
    return DEMO_PQ_ON_RIGHT;
}

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

void DRVCUST_SharpnessEnhanceCFGInit(void)
{
	
}

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

	 // 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 =(UINT16) 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 =(UINT16) 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 =(UINT16) i4UiRangeDft;
	            }
	            else
	            {
	                ReturnVal = (UINT16) ((i2Cur - i2Min) * (i4UiRangeDft - i4UiRangeMin) /
	                                (i2Dft - i2Min) + i4UiRangeMin);
	            }
	        }
	    }
		return ReturnVal;
}
void vDrvBluLightStrUIRemap(UINT8 u1Value)
{
	switch(u1Value)
	{
		case 1:
			//UI LOW
			vDrvBluLightSetStrength(0x40);
			break;
		case 2:
			//UI MID
			vDrvBluLightSetStrength(0x80);
			break;
		case 3:
			//UI HIGH
			vDrvBluLightSetStrength(0xff);
			break;
		default:
			//MID
			vDrvBluLightSetStrength(0x80);
			break;
	}

}

void DRVCUST_CalVideoColorMatrix(UINT8 bPath, UINT16 wBriValue, UINT16 wContValue,
                          UINT16 wSatValue, UINT16 wHueValue)
{

}


