/* 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 "drv_MapleApi.h"
#include "nptv_debug.h"
#include "pdwnc_if.h"
#include "msdc_if.h"

/*********************** Definition & Macro *******************************/
typedef enum { 
    E_CUST_PQ_BUF_COMTRAST      = 1<<0,
    E_CUST_PQ_BUF_COLOR         = 1<<1,
    E_CUST_PQ_BUF_HUE           = 1<<2, 
    E_CUST_PQ_BUF_LUMA_CURVE    = 1<<3,    
    E_CUST_PQ_BUF_SRS           = 1<<4,   
    E_CUST_PQ_BUF_SHARPNESS     = 1<<5,    
    E_CUST_PQ_BUF_SCE           = 1<<6,
    E_CUST_PQ_BUF_RGB_GAIN_OFST = 1<<7,
    E_CUST_PQ_BUF_YLEV		    = 1<<8,
    E_CUST_PQ_BUF_MATRIX		= 1<<9,
    E_CUST_PQ_BUF_PARTIALY      = 1<<10,
    E_CUST_PQ_BUF_PARTIALS      = 1<<11,
    E_CUST_PQ_BUF_FLUSH         = 1<<31,
} E_CUST_PQ_BUF_TYPE;


/************************** Extenl function *******************************/

/************************** Global Variable *******************************/
SONY_PQ_FUNC_T* sony_pq_func = NULL;
SONY_BE_FUNC_T* sony_be_func = NULL;
SONY_BE_GEN_FUNC_T* sony_be_gen_func = NULL;
UINT8  gu1EcsCommandReply[256];
UINT32  gu4EcsCommandReplySize;
UINT8	gBEErrorDetect = 0xFF;
E_BE_DEVICE		gBEDevice;
UINT32		gBEDeviceInfoSize;
VOID*		gBEInfoPara;

UINT8   gBEVersionNum = 8;
UINT8*  gBEVersion = NULL;
static BOOL fgBEVersionIsSet = FALSE;

static UINT16 u2LumaArrayBuf[LUMA_CURVE_NUM_65]; 
static UINT16 u2SkinArrayBuf[LUMA_CURVE_NUM_65]; 
static UINT16 u2ContrastBuf, u2ColorBuf, u2HueBuf, u2BrightnessBuf;
static UINT16 u2MatrixContrastBuf, u2MatrixColorBuf, u2MatrixHueBuf, u2MatrixBrightnessBuf;
static UINT32 PhyAddrBuf_A, PhyAddrBuf_B;
static UINT32 u4BufFlag = 0;
static CUST_SHARP_OFST_T stSharpOfst;
static UINT8 u1SceYSlope[SCE_LUMA_HUE_SLICE];
static UINT8 u1SceSGain1[SCE_HUE_SLICE];
static UINT8 u1SceSGain2[SCE_HUE_SLICE];
static UINT8 u1SceSGain3[SCE_HUE_SLICE];
static CUST_RGB_GAIN_OFST_T stRGBGainOfst;
extern BOOL fgCriticalSection;
static UINT8 u1YLevArrayBuf[17]; 


/*************************** static functions *****************************/
static void vDrvSetSRS(UINT32 u4Addr_A, UINT32 u4Addr_B)
{       
    LOG(2, "DRVCUST_SetSRSLut Table A Addr 0x%08x Table B Addr 0x%08x \n", u4Addr_A, u4Addr_B);

    if (IO32ReadFldAlign(SRS_3, STA_TBL_UPDATE))
    {        
        LOG(0, "DRVCUST_SetSRSLut Busy !!!! \n");
        return;
    }

    if (u4Addr_A && u4Addr_B)
    {
    	
        vIO32WriteFldAlign(SRS_0, (u4Addr_A & 0x0FFFFFF0)>>4, C_SRS_DRAM_ADR_A);
        vIO32WriteFldAlign(SRS_2, (u4Addr_B & 0x0FFFFFF0)>>4, C_SRS_DRAM_ADR_B);
		vIO32WriteFldAlign(SRS_1, (u4Addr_A & 0x70000000)>>28, C_SRS_ADDR_MSB);

        vIO32WriteFldAlign(SRS_0, 1, C_TBL_UPDATE_TRIG);
        vIO32WriteFldAlign(SRS_0, 0, C_TBL_UPDATE_TRIG);
    }
    else
    {
        LOG(0, "DRVCUST_SetSRSLut Parametes error !!!! \n");
    }    
}

/*************************** functions ************************************/
void DRVCUST_SetExclusiveReg(UINT8 u1Enable)
{

	vDrvADLSetYHistogramMode(u1Enable ? 1 : 0);
	vDrvADLSetLumaCurveMode(u1Enable ? 0 : 1);
    vDrvADLManualLumaCurveOnOff(u1Enable ? 1 : 0);
	vDrvADLOnOff(u1Enable ? 0 : 1);
    vDrvSCECalculateOnOff(u1Enable ? 0 : 1);

    if (u1Enable == SV_FALSE)
    {
        // reset to default 
        DRVCUST_SetContrast(0x80);
        DRVCUST_SetColor(0x80);
        DRVCUST_SetHue(0x80);
    }

    // SRS todo

    LOG(2, "DRVCUST_SetExclusiveReg %d \n", u1Enable); 
}

void DRVCUST_SetLumaCurve(const UINT16* waLArray, const UINT16* waSkinLArray)
{
    x_memcpy(u2LumaArrayBuf, waLArray, LUMA_CURVE_NUM_65*sizeof(UINT16));
	x_memcpy(u2SkinArrayBuf, waSkinLArray, LUMA_CURVE_SKIN_NUM_65*sizeof(UINT16));
    u4BufFlag |= E_CUST_PQ_BUF_LUMA_CURVE;
    //LOG(2, "DRVCUST_SetLumaCurve \n");
}

void DRVCUST_SetContrast(UINT16 u2Value)
{
    u2ContrastBuf = u2Value;      
    u4BufFlag |= E_CUST_PQ_BUF_COMTRAST;
    //LOG(2, "DRVCUST_SetContrast %d \n", u2Value);
}

void DRVCUST_SetColor(UINT16 u2Value)
{
    u2ColorBuf= u2Value;  
    
    u4BufFlag |= E_CUST_PQ_BUF_COLOR;
    //LOG(2, "DRVCUST_SetColor %d \n", u2Value);
}

void DRVCUST_SetHue(UINT16 u2Value)
{    
    u2HueBuf = u2Value;  
   
    u4BufFlag |= E_CUST_PQ_BUF_HUE;
    //LOG(2, "DRVCUST_SetHue %d \n", u2Value);
}

void DRVCUST_SetPqWBGainOffset(CUST_RGB_GAIN_OFST_T* pstRgbGainOfst)
{        
    if (pstRgbGainOfst != NULL)
    {
        x_memcpy(&stRGBGainOfst, pstRgbGainOfst, sizeof(CUST_RGB_GAIN_OFST_T));
    }
    else
    {
        LOG(0, "DRVCUST_SetPqWBGainOffset Failed !!!!\n");
        return;
    }

    u4BufFlag |= E_CUST_PQ_BUF_RGB_GAIN_OFST;
    //LOG(2, "DRVCUST_SetPqWBGainOffset\n");
}

void DRVCUST_SetSharpnessOffset(CUST_SHARP_OFST_T* pSharpOfst)
{   
    if (pSharpOfst != NULL)
    {
        x_memcpy(&stSharpOfst, pSharpOfst, sizeof(CUST_SHARP_OFST_T));
    }
    else
    {
        LOG(0, "DRVCUST_SetSharpnessOffset Failed !!!!\n");
        return;
    }
    
    u4BufFlag |= E_CUST_PQ_BUF_SHARPNESS; 

	#if 0
    LOG(2, "DRVCUST_SetSharpnessOffset\n");
    
    LOG(2, "GainH           %d %d %d \n", 
        stSharpOfst.u1GainH[0], stSharpOfst.u1GainH[1], stSharpOfst.u1GainH[2]);
    LOG(2, "GainV           %d %d %d \n", 
        stSharpOfst.u1GainV[0], stSharpOfst.u1GainV[1], stSharpOfst.u1GainV[2]);
    LOG(2, "GainD           %d %d %d \n", 
        stSharpOfst.u1GainD[0], stSharpOfst.u1GainD[1], stSharpOfst.u1GainD[2]);    
    LOG(2, "CoringZeroH     %d %d %d \n", 
        stSharpOfst.u1CorzH[0], stSharpOfst.u1CorzH[1], stSharpOfst.u1CorzH[2]);        
    LOG(2, "CoringZeroV     %d %d %d \n", 
        stSharpOfst.u1CorzV[0], stSharpOfst.u1CorzV[1], stSharpOfst.u1CorzV[2]);
    LOG(2, "CoringZeroD     %d %d %d \n", 
        stSharpOfst.u1CorzD[0], stSharpOfst.u1CorzD[1], stSharpOfst.u1CorzD[2]);
	LOG(2, "HSHPGainLow          %d %d \n", 
        stSharpOfst.u1HSHPGainLow[0], stSharpOfst.u1HSHPGainLow[1]);
    LOG(2, "HSHPGainMid          %d %d \n", 
        stSharpOfst.u1HSHPGainMid[0], stSharpOfst.u1HSHPGainMid[1]);
    LOG(2, "HSHPGainHigh         %d %d \n", 
        stSharpOfst.u1HSHPGainHigh[0], stSharpOfst.u1HSHPGainHigh[1]);    
    LOG(2, "HSHPCoringZero     %d %d %d \n", 
        stSharpOfst.u1HSHPCor[0], stSharpOfst.u1HSHPCor[1], stSharpOfst.u1HSHPCor[2]);        
    LOG(2, "EdgeGain     %d %d %d \n", 
        stSharpOfst.u1EdgeGain[0], stSharpOfst.u1EdgeGain[1], stSharpOfst.u1EdgeGain[2]);
    LOG(2, "DetailGain     %d %d %d \n", 
        stSharpOfst.u1DetailGain[0], stSharpOfst.u1DetailGain[1], stSharpOfst.u1DetailGain[2]);
	LOG(2, "LTIGain     %d %d %d \n", 
        stSharpOfst.u1LTIGain[0], stSharpOfst.u1LTIGain[1], stSharpOfst.u1LTIGain[2]);
    LOG(2, "LTICoringZero     %d %d %d \n", 
        stSharpOfst.u1LTICorz[0], stSharpOfst.u1LTICorz[1], stSharpOfst.u1LTICorz[2]);
	#endif
	
}


void DRVCUST_SetSRSLut(UINT8* pTableA, UINT8* pTableB)
{  
    LOG(2, "DRVCUST_SetSRSLut Table A Addr 0x%08x Table B Addr 0x%08x \n", pTableA, pTableB);

    if (pTableA && pTableB)
    {
        PhyAddrBuf_A = PHYSICAL((UINT32)pTableA);
        PhyAddrBuf_B = PHYSICAL((UINT32)pTableB);        
        u4BufFlag |= E_CUST_PQ_BUF_SRS;
    }
    else
    {
        LOG(0, "DRVCUST_SetSRSLut Parametes error !!!! \n");
    }    
}

UINT8 DRVCUST_FlushPqSetting(void)
{  
	if(fgCriticalSection)
{    
		return SV_FALSE;
	}
	
    u4BufFlag |= E_CUST_PQ_BUF_FLUSH;

    //LOG(2, "DRVCUST_FlushPqSetting !!!! \n");

	return SV_TRUE;
}

void DRVCUST_EnNoiseLevel(UINT8 u1Enable)
{
    vIO32WriteFldAlign(NR_NM_16, u1Enable, CUST_FORCE_NOISE_LVL_EN);
    //LOG(2, "DRVCUST_EnNoiseLevel %d \n", u1Enable);
}

void DRVCUST_SetNoiseLevel(UINT8 u1NoiseLevel)
{
    vIO32WriteFldAlign(NR_NM_16, u1NoiseLevel, CUST_FORCE_NOISE_LVL);
    //LOG(2, "DRVCUST_SetNoiseLevel %d \n", u1NoiseLevel);
}

void DRVCUST_SetPostSharpYLev(UINT8* pYLev)
{
    x_memcpy(u1YLevArrayBuf, pYLev, 17);
    u4BufFlag |= E_CUST_PQ_BUF_YLEV;
    //LOG(2, "DRVCUST_SetPostSharpYLev \n");
}

void DRVCUST_UpdateTimingGroup(UINT8* pCustSrcTimingTbl, UINT8* pCustSrcGroup)
{    
    UINT32 u4SrcTimingSize = sizeof(bCustomSrcTimingTbl);
    UINT32 u4SrcGroupSize = sizeof(bCustomSourceGroup);

    if (pCustSrcTimingTbl && pCustSrcGroup)
    {           
        if ((pCustSrcTimingTbl[u4SrcTimingSize-1] == SOURCE_TYPE_TIMING_MAX)
            && (pCustSrcGroup[u4SrcGroupSize-1] == SOURCE_TYPE_TIMING_MAX)
            && (pCustSrcGroup[u4SrcGroupSize-2] == SOURCE_TYPE_TIMING_MAX))
        {
    	    x_memcpy(bCustomSrcTimingTbl, pCustSrcTimingTbl, u4SrcTimingSize);
    	    x_memcpy(bCustomSourceGroup, pCustSrcGroup, u4SrcGroupSize);
            bApiParseCustomQtyItem();
        }
        else
        {
            LOG(0, "DRVCUST_UpdateTimingGroup : Array mismatch !!! \n");
        }
    }
    else
    {
        LOG(0, "DRVCUST_UpdateTimingGroup : Null pointer !!! \n");
    }

    //LOG(2, "DRVCUST_UpdateTimingGroup \n");
}

void DRVCUST_PqSendDataToBe(UINT8* pData, UINT32 u4Size)
{
    if (sony_be_func)
    {
        sony_be_func->be_receive_from_pq(pData, u4Size);
    }
}

void DRVCUST_RegisterPqFunc(SONY_PQ_FUNC_T *pq_func)
{
    if (pq_func)
    {
        sony_pq_func = pq_func;
        LOG(2, "Sony PQ function registered \n");	
    }
    else
    {
        LOG(2, "Sony PQ function NULL \n");
    }
}

void DRVCUST_DeregisterPqFunc(void)
{
    sony_pq_func = NULL;    
    LOG(2, "Sony PQ function unregistered \n");
}

void DRVCUST_RegisterBeFunc(SONY_BE_FUNC_T *be_func)
{
    if (be_func)
    {
        sony_be_func = be_func;
        LOG(2, "Sony BE function registered \n");
		//DRVCUST_BE_Connect(0,0,0,0);
		//DRVCUST_BE_Connect(1,2,2,2);
		DRVCUST_BE_Connect(E_CUST_BE_TX_PATH_VIDEO,E_CUST_BE_SCL_TYPE_PQ,E_CUST_BE_PLANE_ORDER_0,SV_VP_MAIN);
		DRVCUST_BE_Connect(E_CUST_BE_TX_PATH_GFX,E_CUST_BE_SCL_TYPE_GFX,E_CUST_BE_PLANE_ORDER_2,SV_VP_NA);
	//	DRVCUST_BE_Connect(E_CUST_BE_TX_PATH_VIDEO,E_CUST_BE_SCL_TYPE_VIDEO,E_CUST_BE_PLANE_ORDER_1,SV_VP_PIP);//just for test
    }
    else
    {
        LOG(2, "Sony BE function NULL \n");
    }
}

void DRVCUST_DeregisterBeFunc(void)
{
    sony_be_func = NULL;    
    LOG(2, "Sony BE function unregistered \n");
}

void DRVCUST_RegisterBeGeneralFunc (SONY_BE_GEN_FUNC_T* be_gen_func)
{
    if (be_gen_func)
    {
        sony_be_gen_func = be_gen_func;
        LOG(2, "Sony BE General function registered \n");
    }
    else
    {
        LOG(2, "Sony BE General function NULL \n");
    }
}

void DRVCUST_DeregisterBeGeneralFunc(void)
{
    sony_be_gen_func = NULL;    
    LOG(2, "Sony BE General function unregistered \n");
}

void DRVCUST_ResetSystem(E_CUST_RESET eReset)
{   
    switch (eReset)
    {
        case E_CUST_RESET_SHUTDOWN:                        
            PDWNC_EnterPowerDown(WAK_IRRX | WAK_RTC, (UINT32)PDWNC_POWER_DOWN_UNKNOWN);            
            break;
        default:
        case E_CUST_RESET_REBOOT:
            PDWNC_Reboot();
            break;
    }
    
    LOG(2, "DRVCUST_ResetSystem %d \n", eReset);
}

void DRVCUST_SetEcsCommandReply(UINT8* pData, UINT32 u4Size)
{
	
	if (u4Size <= 256) 
	{
		gu4EcsCommandReplySize = u4Size;
		x_memcpy(gu1EcsCommandReply, pData, u4Size);
	}
	
    //LOG(2, "DRVCUST_SetEcsCommandReply \n");
}

UINT32 DRVCUST_BePartitionWrite(E_CUST_BE_PART ePartId, UINT32 u4Offset, VOID *pvBuf, UINT32 u4BufSize)
{
	UINT64 u8Offset;
    UINT64 u8offsetTmp;
	UINT64 u4RelPartId=0 ;
    INT32  i4Ret, u4PartitionSize, u4FooterInfo;
    UINT8 u4Tmp0, u4Tmp1, u4Tmp2, u4Tmp3, u4BankIndexNum, u4DualFlagIsSupported;
    UINT8 _u4FooterInfo[8];
    UINT8 *pu4FooterInfo = &_u4FooterInfo;

    LOG(2, "DRVCUST_BePartitionWrite\n");
	if(ePartId >= E_CUST_PART_MAX)
	{
		Printf("%s error : partid is invalid\n", __FUNCTION__);
		return 1 ;
}
	if (DRVCUST_InitQuery64(eBELPartitionId, &u4RelPartId) != 0 )
	{
		Printf("%s error query BE ID\n", __FUNCTION__);
		return 1;
	}

    u4RelPartId += ePartId ;
	u8Offset = ((UINT64)(u4RelPartId << 32)) | u4Offset ;

    /* Dual Bank Partition */
    if (ePartId == E_CUST_PART_FDAT || ePartId == E_CUST_PART_UDAT) {
        /* Read Bank Ctrl Info */
        u4PartitionSize     = DRVCUST_InitGet64((QUERY_TYPE_T)(eNANDFlashPartSize0 + ePartId));
        u8offsetTmp = ((UINT64)((UINT64)u4RelPartId << 32)) | (u4PartitionSize - 32);
        MSDCPART_Read(u8offsetTmp, pu4FooterInfo, 8);
        u4Tmp0 = *pu4FooterInfo;
        u4Tmp1 = *(pu4FooterInfo+1);
        u4Tmp2 = *(pu4FooterInfo+2);
        u4Tmp3 = *(pu4FooterInfo+3);
        u4FooterInfo = ((UINT32)(u4Tmp0<<24)+(UINT32)(u4Tmp1<<16)+(UINT32)(u4Tmp2<<8)+(UINT32)u4Tmp3);

        u4DualFlagIsSupported = *(pu4FooterInfo+4);
        u4BankIndexNum        = *(pu4FooterInfo+5);

        if (u4FooterInfo == 0x4354524C && u4DualFlagIsSupported) {
            if (u4BankIndexNum == 0) {
                u8Offset += ((u4PartitionSize / 2) - 16);
                Printf("%s  u4BankIndexNum = 0: u8Offset => 0x%08x %ld\n", __FUNCTION__, u8Offset, u8Offset);
                i4Ret = MSDCPART_Write((UINT64)u8Offset, (UINT32)pvBuf, u4BufSize);

                if (i4Ret == 0) {
                    u4BankIndexNum = 1;
                    u8offsetTmp = ((UINT64)((UINT64)u4RelPartId << 32)) | (u4PartitionSize - 27);
                    MSDCPART_Write((UINT64)u8offsetTmp, (UINT32)&u4BankIndexNum, 1);
                }
            } else {
                Printf("%s u4BankIndexNum = 1: u8Offset => 0x%08x %ld\n", __FUNCTION__, u8Offset, u8Offset);
                i4Ret = MSDCPART_Write((UINT64)u8Offset, (UINT32)pvBuf, u4BufSize);

                 if (i4Ret == 0) {
                    u4BankIndexNum = 0;
                    u8offsetTmp = ((UINT64)((UINT64)u4RelPartId << 32)) | (u4PartitionSize - 27);
                    MSDCPART_Write((UINT64)u8offsetTmp, (UINT32)&u4BankIndexNum, 1);
                }
            }
        } else {
            i4Ret = MSDCPART_Write((UINT64)u8Offset, (UINT32)pvBuf, u4BufSize);
        }
    } else {
        /* Single Bank Partition */
        i4Ret = MSDCPART_Write((UINT64)u8Offset, (UINT32)pvBuf, u4BufSize);
    }
    return i4Ret;
}

void DRVCUST_SetBeDeviceInformation(E_BE_DEVICE device, VOID* pParam, UINT32 size)
{
	gBEDevice = device;
	gBEInfoPara = pParam;
	gBEDeviceInfoSize = size;
	UINT8 arPanelIDString_New_Recipe[ATV_PANEL_ID_STRING_LEN+1]={0};

	
	//get panel ID string forn New_Recipe_condition_data
	EEPROM_Read(0x10020, (UINT32)arPanelIDString_New_Recipe, 16);
	arPanelIDString_New_Recipe[ATV_PANEL_ID_STRING_LEN]='\0';
	Printf("4K New_Recipe_condition_data_PANEL_ID_STRING=%s \n",arPanelIDString_New_Recipe);

	//panel ID string forn 4KBE
	Printf("4K Panel ID String From 4KBE=%s \n",pParam);
	
	if (x_strncmp((const char *)pParam, (const char *)arPanelIDString_New_Recipe, ATV_PANEL_ID_STRING_LEN) == 0)	
	{
		Printf("4K Panel ID String From 4KBE = [New]Recipe Condition Data \n");
	}
	else
	{
		Printf("Panel ID String From 4KBE != [New]Recipe Condition Data \n");
		//Write  panel ID string forn 4KBE to [New]Recipe Condition Data
		if(device == PANEL_INFO)
		{
			EEPROM_Write(0x10020, pParam, size);
		}		
		//LED blinking +turn 4K panel off
		GPIO_CustomLedCtrlFunc(eLedErrPanelID);
		ostg_set_fgPanelPowerState(FALSE);//4K set pnael power off
	}
	
	//LOG(2, "DRVCUST_SetBeDeviceInformation\n");
}


void DRVCUST_SetBeDeviceErrorDetect(E_BE_ERROR_DETECT Efactor)
{
	gBEErrorDetect = Efactor;
	//LOG(2, "DRVCUST_SetBeDeviceInformation: %d\n", Efactor);
}

void DRV_CUST_SetBEDeviceVersion(UINT8 u1Number, UINT8* pVersion)
{
    gBEVersionNum = u1Number;

    if (gBEVersion != NULL)
    {
        x_mem_free(gBEVersion);
        gBEVersion = NULL;
    }

    if ((gBEVersion = (UINT8*)x_mem_alloc(gBEVersionNum*20)) == NULL)
    {
        LOG(0, "DRVCUST_SetBeDeviceInformation: gBEVersion memory allocation fail!\n");
    }
    else
    {
        x_memcpy(gBEVersion, pVersion, gBEVersionNum*20);
    }
    
    if (!fgBEVersionIsSet)
    {
        fgBEVersionIsSet = TRUE;
    }
    //LOG (2, "DRVCUST_SetBeDeviceInformation\n");
}

UINT8 QueryBEDeviceVersionNum(void)
{
    return gBEVersionNum;
}

INT32 QueryBEDeviceVersion(UINT8* pOut)
{
    if (pOut == NULL)
   {
        LOG(0, "DRVCUST_GetBEDeviceVersion: output pointer is null\n");
        return -1;
   }
   else
   {
        if (fgBEVersionIsSet)
        {
            x_memcpy(pOut, gBEVersion, gBEVersionNum*20);
            return 0;
        }
        else
        {            
            LOG(0, "DRVCUST_GetBEDeviceVersion: BE version has not been set\n");
            return -1;
        }
   }
}

void DRVCUST_SetPqColMatrixParam(UINT8 u1Upof_ext, UINT8 u1Ucof_ext,UINT8 u1Ubof_ext )
{
	u2MatrixContrastBuf = u1Upof_ext;      
	u2MatrixColorBuf = u1Ucof_ext;      
	u2MatrixBrightnessBuf = u1Ubof_ext;      
    u4BufFlag |= E_CUST_PQ_BUF_MATRIX;
	//LOG(2, "DRVCUST_SetPqColMatrixParam\n");
}

void DRVCUST_SetPqNewPartialS(UINT8* u1PointL, UINT8* u1PointM, UINT8* u1PointH)
{     
    if (u1PointL != NULL)
    {
        x_memcpy(u1SceSGain1, u1PointL, SCE_HUE_SLICE);
    }
    else
    {
        LOG(0, "DRVCUST_SetPqNewPartialSFailed u1PointL!!!!\n");
        return;
    }

	if (u1PointM != NULL)
    {
        x_memcpy(u1SceSGain2, u1PointM, SCE_HUE_SLICE);
    }
    else
    {
        LOG(0, "DRVCUST_SetPqNewPartialSFailed u1PointM!!!!\n");
        return;
    }

	if (u1PointH != NULL)
    {
        x_memcpy(u1SceSGain3, u1PointH, SCE_HUE_SLICE);
    }
    else
    {
        LOG(0, "DRVCUST_SetPqNewPartialSFailed u1PointH!!!!\n");
        return;
    }
	
	u4BufFlag |= E_CUST_PQ_BUF_PARTIALS;
    u4BufFlag |= E_CUST_PQ_BUF_SCE;
    //LOG(2, "DRVCUST_SetPqNewPartialS \n");
}

void DRVCUST_SetPqPartialY(UINT8* u1Point)
{     
    if (u1Point != NULL)
    {
        x_memcpy(u1SceYSlope, u1Point, SCE_LUMA_HUE_SLICE);
    }
    else
    {
        LOG(0, "DRVCUST_SetPqPartialY Failed !!!!\n");
        return;
    }
    
    u4BufFlag |= E_CUST_PQ_BUF_SCE;
	u4BufFlag |= E_CUST_PQ_BUF_PARTIALY;
    //LOG(2, "DRVCUST_SetPqPartialY \n");
}

void DRVCUST_SetScalerCoefLumaH(UINT32* u4Array)
{     
	vDrvSCPQSetSramCoeff(COEFTYP_HOR_Y, u4Array);
}

void DRVCUST_SetScalerCoefChromaH(UINT32* u4Array)
{     
	vDrvSCPQSetSramCoeff(COEFTYP_HOR_C, u4Array);
}

void DRVCUST_SetScalerCoefLumaV(UINT32* u4Array)
{     
	vDrvSCPQSetSramCoeff(COEFTYP_VER_Y, u4Array);
}

void DRVCUST_SetScalerCoefChromaV(UINT32* u4Array)
{     
	vDrvSCPQSetSramCoeff(COEFTYP_VER_C, u4Array);
}

void DRVCUST_SetLdHwParam(CUST_LD_HW_PARAM_T* pLDHWParam)
{     
	vDrvLcDimSetHWParam(pLDHWParam);
}

void DRVCUST_SetLdSwParam(CUST_LD_SW_PARAM_T* pLDSWParam)
{     
	vDrvLcDimSetSWParam(pLDSWParam);
}

void DRVCUST_SetLdHwTable(CUST_LD_HW_TABLE_T* pLDHWTable)
{     
	vDrvLcdimWriteDimTable(pLDHWTable->u2LDDimTable);
    vDrvLcdimWriteGainTable(pLDHWTable->u2LDGainTable);
    vDrvLcdimWriteGainLimitTable(pLDHWTable->u2LDGainLimitTable); 
}

void DRVCUST_SetLdSwTable(CUST_LD_SW_TABLE_T* pLDSWTable)
{     
	vDrvLcDimSetSWTable(pLDSWTable->u2LDGainLimitTable_LOW_BND, pLDSWTable->u2LDGainLimitTable_UP_BND);
	//LOG(2, "DRVCUST_SetLdSwTable \n");
}

void DRVCUST_SetPqSwVersion(UINT8* pData)
{     

}






