#ifndef __HDMI_EARC_IF_H
#define __HDMI_EARC_IF_H
#include "x_typedef.h"
#include "x_gpio.h"
#include "drv_hdmi2.h"

#define SII9438_INST_1      2
#define SII9438_INST_2      4

#define SII9438_INST_1_I2C_ADDR_PAGE0      0x60
#define SII9438_INST_1_I2C_ADDR_PAGE1      0x68
#define SII9438_INST_1_I2C_ADDR_PAGE2      0x6C
#define SII9438_INST_1_I2C_ADDR_PAGE3      0x6A
#define SII9438_INST_1_I2C_ADDR_PAGE4      0x64

#define SUPPORT_ATMOS_UPDATE    0
#define MS12_NO_ATMOS_CONTROL   1

enum {
    EARC_PAGE_0 = 0x00,
    EARC_PAGE_1 = 0x01,
    EARC_PAGE_2 = 0x02,
    EARC_PAGE_3 = 0x03,
    EARC_PAGE_4 = 0x04,
    EARC_PAGE_5 = 0x05
};

enum {
    RET_SUCCESS = 0x00,
    RET_FAIL    = 0x01
};

/*
 * HDMI earc event type. 
 */
typedef enum
{
    HDMI_EARC_NOT_ENABLED = 0,
    HDMI_EARC_WAITING  = 1,
    HDMI_EARC_ENABLED  = 2,
}EARCStatus_t;

enum
{
    HDMI_EARC_NOT_CONNECT = 0,
    HDMI_EARC_CONNECT  = 1,
};

typedef enum
{
    EARC_EVENT_CONNECT_CHG_TO_CEC = 0,
    EARC_EVENT_CONNECT_CHG_TO_AUDIO,
    EARC_EVENT_CONNECT_CHG_TO_APP,
    EARC_EVENT_HBRA_MODE,
    EARC_EVENT_MAX,
}EARCEvent_t;

typedef struct
{
    EARCStatus_t eStatus;
    UINT32 u4PortId;
}EARCPortStatus_t;

typedef struct
{
    BOOL bEARCConnect;
    UINT8 u1Capability;
    UINT8 u1Mpeg4AacLcCapability;
}EARCAudioStatus_t;

typedef struct
{
    UINT8 u1Status[5];
    UINT8 u1Length;         //5
}EARCChannelStatus_t;

typedef struct
{
    UINT8 u1Info[10];
    UINT8 u1Length;         //10
}EARCAudioInfoFrame_t;

typedef struct
{
    UINT8 u1DataBlock[256];
    BOOL bEARCConnect;   
    UINT8 u1DDP;
    UINT8 u1EAC3;
    UINT8 AAC_LC;
    UINT8 AAC_LC_Ch;
    UINT8 AAC_LC_22ch;
}EARCEDIDInfo_t;

typedef struct
{
    UINT8 u1HPDStatus;
    UINT8 u15VStatus;
    BOOL bEnable;
    BOOL bTVStatus;
    BOOL bBtHpStatus;
}EARCInitInfo_t;

typedef void (*pfnEARCEventCallback)(void *pArg);

typedef struct
{
    UINT8 (*pfnSetChannelStatus)(EARCChannelStatus_t *eStatus);
    UINT8 (*pfnSetAudioInfoFrame)(EARCAudioInfoFrame_t *eInfoFrame);
    UINT8 (*pfnSetValidityBit)(BOOL bValidity);
    UINT8 (*pfnSetHPDStatus)(UINT8 u1HpdStatus);
    UINT8 (*pfnSet5VStatus)(UINT8 u15VStatus);
    UINT8 (*pfnSetHBRAInputStatus)(BOOL bHbr);
    UINT8 (*pfnSetLayoutBit)(BOOL bLayout);
    UINT8 (*pfnSetArcStatus)(BOOL bOnOff);
    UINT8 (*pfnSetAudioPath)(BOOL bPath);
    UINT8 (*pfnSetAudioLatency)(INT16 i2Ms);
    UINT8 (*pfnSetTVStatus)(BOOL bTVStatus);
    UINT8 (*pfnSetBtHpStatus)(BOOL bConnect);
    UINT8 (*pfnSetEnable)(BOOL bEn);
    UINT8 (*pfnSetHdmiMute)(BOOL bMute);
    UINT8 (*pfnSetAudioMute)(BOOL bMute);
    EARCStatus_t (*pfnGetEARCStatus)(UINT32 u4PortId);
    UINT8 (*pfnGetEARCAudioStatus)(EARCAudioStatus_t* eStatus);
}EARCFuncTable_t;

typedef struct
{
    BOOL bSupported;            //Hardware support
    BOOL bEnable;                 //Software enable
    BOOL bMWReady;
    BOOL bTVStatus;               //0:TV Speaker, 1:Audio System
    BOOL bBtHpStatus;          //btheadphone status
    BOOL bHbrInputStatus;
    BOOL bValidity;
    BOOL bLayout;
    BOOL bPath;                     //0:spdif 1:i2s
    BOOL bHdmiMute;
    BOOL bAudioMute;
    UINT8 u1DDPOut;             //0:DDP_OUT_OFF, 1:DDP_OUT_AUTO
    UINT8 u1DDPCap;             //0:NOT_CAPABLE, 1:DDP_CAPABLE, 2:ATMOS_CAPABLE
    UINT8 u1DDPeARC;         //
    UINT8 u1HPDStatus;
    UINT8 u15VStatus;
    UINT8 u1ARCStatus;          //0:cec disable arc 1:cec enable arc
    UINT8 u1eARCStatus;
    INT16 i2Latency;                //-250ms ~ 250ms
    pfnEARCEventCallback pfnCallback[EARC_EVENT_MAX];
    EARCFuncTable_t *pFuncTable;
    EARCChannelStatus_t eChStatus;
    EARCAudioInfoFrame_t eAudInfoFrame;
    EARCEDIDInfo_t eEDIDInfo;
}EARCObject_t;

extern void _vHDMIEARCSetEnable(BOOL bValue);
/**
 * @brief        Delay for some ms.
*/
extern void vHDMIEARCSleepMsec(UINT32 u4Count);
/**
 * @brief        Time inquiry in milliseconds
 * @retval      Current System time.
*/
extern UINT32 u4HDMIEARCMsecQuery(void);
/**
 * @brief        Read Data throuth I2C
 * @param      u2Addr----16 bit address of register.
 * @retval       0 for success, 1 for fail
*/
extern UINT32 u4HDMIEARCHostBlockRead(UINT32 u4DevID, UINT16 u2Addr, UINT8 *pDataIn, UINT16 u2Length);
/**
 * @brief        Write Data throuth I2C
 * @param      u2Addr----16 bit address of register.
 * @retval       0 for success, 1 for fail
*/
extern UINT32 u4HDMIEARCHostBlockWrite(UINT32 u4DevID, UINT16 u2Addr, const UINT8 *pDataOut, UINT16 u2Length);

/**
 * @brief        Set eARC Chip Reset Pin
 * @param      u1Status---- Set Reset GPIO HIGH/LOW.
*/
extern void vHDMIEARCResetSet( UINT8 u1Status );
/**
 * @brief        Print log
*/
extern void HDMIEARCLogPrint(const char *pStr);
/**
 * @brief        unregister gpio interrupt
 * @param      pfnISR---- EARCEvent_t type.
*/
extern void vHDMIEARCUnregisterInt(PFN_GPIO_CALLBACK pfnISR);
/**
 * @brief        register gpio interrupt
 * @param      pfnISR---- EARCEvent_t type.
*/
extern void vHDMIEARCRegisterInt(PFN_GPIO_CALLBACK pfnISR);
/**
 * @brief        Notify eARC Event, used by eARC lib.
 * @param      type---- EARCEvent_t type.
 * @param      pArg---- point to Data/Status to be notified.
*/
extern void vHDMIEARCEventNotify(EARCEvent_t type, void *pArg);
/**
 * @brief        Register eARC Callback , used by MTAL/AUDIO.
 * @param      pCallback---- callback pointer
 * @param      eType---- callback type
 * @retval       0 for success, 1 for fail
*/
extern UINT8 u1HDMIEARCRegCB(pfnEARCEventCallback pCallback, EARCEvent_t eType);
/**
 * @brief        Register function table , used by eARC lib.
 * @param      pFuncTable---- callback pointer
 * @retval       0 for success, 1 for fail
*/
extern UINT8 u1HDMIEARCRegFuncTable(EARCFuncTable_t *pFuncTable);
/**
 * @brief        Init eARC system
*/
extern void vHDMIEARCSystemInit(void);
/**
 * @brief        Suspend eARC system
*/
extern void vHDMIEARCSystemSuspend(void);
/**
 * @brief        Resume eARC system
*/
extern void vHDMIEARCSystemResume(void);
/**
 * @brief        Get HDMI Channel Status
 * @param        peStatus---- pointer
 * @retval      0 for success, 1 for fail
*/
extern UINT8 u1HDMIEARCGetChannelStatus(EARCChannelStatus_t *peStatus);
/**
 * @brief        Get HDMI Audio InfoFrame
 * @param        peInfoFrame---- pointer
 * @retval      0 for success, 1 for fail
*/
extern UINT8 u1HDMIEARCGetAudInfoFrame(EARCAudioInfoFrame_t *peInfoFrame);
/**
 * @brief        Get Validity Bit
 * @param        pValidity---- pointer, 0:LPCM 1:compressed audio
 * @retval      0 for success, 1 for fail
*/
extern UINT8 u1HDMIEARCGetValidityBit(BOOL *pValidity);
/**
 * @brief        Get HBR Input Status
 * @param        pHbr---- pointer, 0:No HBR 1:HBR input
 * @retval      0 for success, 1 for fail
*/
extern UINT8 u1HDMIEARCIsHBRInput(BOOL *pHbr);
/**
 * @brief        Get Layout Bit
 * @param        pLayout---- pointer,
 * @retval      0 for success, 1 for fail
*/
extern UINT8 u1HDMIEARCGetLayoutBit(BOOL *pLayout);
/**
 * @brief        Get Audio Frequency
 * @param        pFs---- pointer,
 * @retval      0 for success, 1 for fail
*/
extern UINT8 u1HDMIEARCGetAudioFs(UINT32 *pFs);
/**
 * @brief        Is HDMI Input?
 * @param        pFlag---- pointer, 0:No 1:Yes
 * @retval      0 for success, 1 for fail
*/
extern UINT8 u1HDMIEARCIsHDMIInput(BOOL *pFlag);
/**
 * @brief        Get Status for eARC initialization
 * @param        pInitInfo---- pointer,
 * @retval      0 for success, 1 for fail
*/
extern UINT8 u1HDMIEARCGetInitialStatus(EARCInitInfo_t *pInitInfo);
/**
 * @brief        Get Audio Latency
 * @param        pLatency---- pointer, -250msec~250msec
 * @retval      0 for success, 1 for fail
*/
extern UINT8 u1HDMIEARCGetAudioLatency(INT16 *pLatency);
/**
 * @brief        Get Framework Ready
 * @param        pReady---- pointer,0:Not ready 1:Ready
 * @retval      0 for success, 1 for fail
*/
extern UINT8 u1HDMIEARCGetMWReady(BOOL *pReady);
/**
 * @brief        Change HDMI HPD
 * @param        u1HPDStatus----
 *                               bit0: hdmi0's hpd
 *                               bit1: hdmi1's hpd
 *                               bit2: hdmi2's hpd
 *                               bit3: hdmi3's hpd
 * @retval      0 for success, 1 for fail
*/
extern UINT8 u1HDMIEARCChgHPD(UINT8 u1HPDStatus);
/**
 * @brief        update edid
 * @param        pEdidInfo---- pointer, include input/output.
 * @retval      0 for success, 1 for fail
*/
extern UINT8 u1HDMIEARCUpdateEdid(EARCEDIDInfo_t *pEdidInfo);
/**
 * @brief        Get EDID Data Block Information
 * @param        pEdidInfo---- pointer
 * @retval      0 for success, 1 for fail
*/
extern UINT8 u1HDMIEARCGetEDIDInfo(EARCEDIDInfo_t **pEdidInfo);
/**
 * @brief        Set Framework Ready
 * @param        bReady---- 0:not ready 1:ready
 * @retval      0 for success, 1 for fail
*/
extern UINT8 u1HDMIEARCSetMWReady(BOOL bReady);
/**
 * @brief        Set Audio Channel Status
 * @param        eStatus----5 bytes
 * @retval      0 for success, 1 for fail
*/
extern UINT8 u1HDMIEARCSetChannelStatus(EARCChannelStatus_t *eStatus);
/**
 * @brief        Set Audio InfoFrame
 * @param        eInfoFrame----10 bytes
 * @retval      0 for success, 1 for fail
*/
extern UINT8 u1HDMIEARCSetAudInfoFrame(EARCAudioInfoFrame_t *eInfoFrame);
/**
 * @brief        Set Validity Bit
 * @param        bValidity----V bit
 * @retval      0 for success, 1 for fail
*/
extern UINT8 u1HDMIEARCSetValidityBit(BOOL bValidity);
/**
 * @brief        Set HPD Status
 * @param        u1HpdStatus----
 *                               bit0: hdmi0's hpd
 *                               bit1: hdmi1's hpd
 *                               bit2: hdmi2's hpd
 *                               bit3: hdmi3's hpd
 * @retval      0 for success, 1 for fail
*/
extern UINT8 u1HDMIEARCSetHPDStatus(UINT8 u1HpdStatus);
/**
 * @brief        Set HPD Status
 * @param        ePort ----hdmi1/2/3/4
 * @param        u1HpdStatus----0:low 1:high
 * @retval      0 for success, 1 for fail
*/
extern void vHDMIEARCSetHPD(E_HDMI_SWITCH_NUM ePort, UINT8 u1HpdStatus);
/**
 * @brief        Set 5V Status
 * @param        u15VStatus----
 * @retval      0 for success, 1 for fail
*/
extern UINT8 u1HDMIEARCSet5VStatus(UINT8 u15VStatus);
/**
 * @brief        Set HBRA Input Status
 * @param        bHbr----0:no hbr input 1:hbr input
 * @retval      0 for success, 1 for fail
*/
extern UINT8 u1HDMIEARCSetHBRAInputStatus(BOOL bHbr);
/**
 * @brief        Set Layout Bit
 * @param        bLayout----0:2 channels 1:up to 8 channels
 * @retval      0 for success, 1 for fail
*/
extern UINT8 u1HDMIEARCSetLayoutBit(BOOL bLayout);
/**
 * @brief        Set ARC Status
 * @param        bOnOff----0:ARC is not terminated by CEC 1:ARC is terminated by CEC
 * @retval      0 for success, 1 for fail
*/
extern UINT8 u1HDMIEARCSetArcStatus(BOOL bOnOff);
/**
 * @brief        Get ARC Status
 * @param        
 * @retval      
*/
extern UINT8 u1HDMIEARCGetArcStatus(void);
/**
 * @brief        Set Audio Path
 * @param        bPath----0:SPDIF 1:I2S
 * @retval      0 for success, 1 for fail
*/
extern UINT8 u1HDMIEARCSetAudioPath(BOOL bPath);
/**
 * @brief        Set Audio Latency
 * @param        i2Ms----- 250msec~250msec
 * @retval      0 for success, 1 for fail
*/
extern UINT8 u1HDMIEARCSetAudioLatency(INT16 i2Ms);
/**
 * @brief        Set TV Status
 * @param        bTVStatus----- 0:TV speaker 1:Audio system
 * @retval      0 for success, 1 for fail
*/
extern UINT8 u1HDMIEARCMenuSetTVStatus(BOOL bTVStatus);
/**
 * @brief        Set btheadphone Status
 * @param        bConnect----- 0:disconnected 1:connected
 * @retval      0 for success, 1 for fail
*/
extern UINT8 u1HDMIEARCSetBtHpStatus(BOOL bConnect);
/**
 * @brief        Set ddp Status
 * @param        u1DDPCap-----0:NOT_CAPABLE, 
 *                                                  1:DDP_CAPABLE, 
 *                                                  2:ATMOS_CAPABLE
 * @retval      0 for success, 1 for fail
*/
extern UINT8 u1HDMIEARCMenuSetDDPCap(UINT8 u1DDPCap);
/**
 * @brief        Set ddp Status
 * @param        u1DDPOut-----0:DDP_OUT_OFF, 1:DDP_OUT_AUTO
 * @retval      0 for success, 1 for fail
*/
extern UINT8 u1HDMIEARCMenuSetDDPOut(UINT8 u1DDPOut);
/**
 * @brief        Set eARC enable
 * @param        bEn----- 0:disable 1:enable
 * @retval      0 for success, 1 for fail
*/
extern UINT8 u1HDMIEARCSetEnable(BOOL bEn);
/**
 * @brief        Set Hdmi Mute 
 * @param      bMute---- 1:mute  0:unmute
 * @retval       0 for success, 1 for fail
*/
extern UINT8 u1HDMIEARCSetHdmiMute(BOOL bMute);
/**
 * @brief        Set Audio Mute 
 * @param      bMute---- 1:mute  0:unmute
 * @retval       0 for success, 1 for fail
*/
extern UINT8 u1HDMIEARCSetAudioMute(BOOL bMute);
/**
 * @brief        Get eARC State
 * @param        ePort---- dst port
 * @retval      dst port's earc status.
*/
extern UINT8 u1HDMIEARCGetStatus(E_HDMI_SWITCH_NUM ePort);
/**
 * @brief        Check eARC Audio Related Status
*/
extern void vHDMIEARCChgHandler(E_HDMI_SWITCH_NUM ePort);
/**
 * @brief        Print current eARC State
*/
extern void vHDMIEARCPrintStatus(void);
/**
 * @brief        Set Param to Gen module
*/
extern void vHDMIEARCSetGenParam(UINT32 u4Type, UINT8* pData, UINT8 u1Size);
/**
 * @brief        Set Param to BEGen module
*/
extern void vHDMIEARCSetBEGenParam(UINT32 u4Type, UINT8* pData, UINT8 u1Size);
/**
 * @brief        Set Param to PQGen module
*/
extern void vHDMIEARCSetPQGenParam(UINT32 u4Type, UINT8* pData, UINT8 u1Size);
/**
 * @brief        JNI to get eARC Audio status(Connection and DD+ capability) for Android App
*/
extern UINT8 u1HDMIEARCGetAudioStatus(EARCAudioStatus_t* eStatus);
extern void vHDMIEARCGetEnable(UINT8 *pu1Info);
extern void vHDMIEARCReplaceCap(UINT8* au1EdidData);
extern void vHDMIEARCReqArcTerminate(void);
extern void vHDMIEARCDelayARCHandshake(void);
extern void vHDMIEARCReplyFmARCInit(void);
extern void vHDMIEARCReqARCInit(void);
#endif
