/**
 * @file hv_mw_InputPortManager.h
 * @brief Header file of InputPortManager module.
 * 
 * @verbatim
 * ==============================================================================
 *                        ##### How to use #####
 * ==============================================================================
 * (+) At first, use Hv_Mw_InputPort_CreateManager(...) create InputPortManager object.
 * (+) Use Hv_Mw_InputPort_ManagerInit(...) to initial InputPortManager.
 * (+) Use Hv_Mw_InputPort_SendInnerMsg(...) send a message to ChannelManager Inner MessageQueue immediately.
 * (+) Use Hv_Mw_InputPort_ProcSystemQueueMsg(...) will process one Message from SystemQueue. 
 * (+) Use Hv_Mw_InputPort_ProcInnerMsgs(...) will proc all Channel inner MessageQueue messages once time. 
 * (+) Use Hv_Mw_InputPort_HasInnerMsgs(...) judge whether there are messages in the InputPort messsage pool.
 * 
 * @endverbatim
 *
 * @author HiView SoC Software Team
 * @version 1.0.0
 * @date 2022-08-10
 */
#ifndef __SDK_MIDDLEWARE_RUNTIME_SYSTEM_MANAGER_INPUT_PORT_MANAGER_H__
#define __SDK_MIDDLEWARE_RUNTIME_SYSTEM_MANAGER_INPUT_PORT_MANAGER_H__

#include "hv_comm_Assert.h"
#include "hv_comm_Define.h"
#include "hv_comm_Utilities.h"
#include "hv_comm_Timer.h"
#include "hv_comm_Event.h"
#include "hv_comm_LinkedList.h"
#include "hv_comm_DataBase.h"
#include "hv_drv_HdcpRx.h"
#include "ProjectConfig.h"
#include "hv_mw_StateMachine.h"
#include "hv_mw_Channel_Manager.h"

#define HV_INPUT_DEBUG_OPEN
#ifdef HV_INPUT_DEBUG_OPEN
#define HV_INPUT_LOG_INFO(module_name, ...)           HV_LOG_WRITE(HV_LOG_LEVEL_INFO, __VA_ARGS__)
//#define HV_INPUT_DETAIL_OPEN
#ifdef HV_INPUT_DETAIL_OPEN
#define HV_INPUT_LOG_DEBUG(module_name, ...)          HV_LOG_WRITE(HV_LOG_LEVEL_INFO, __VA_ARGS__)
#else
#define HV_INPUT_LOG_DEBUG(module_name, ...) 
#endif
#else
#define HV_INPUT_LOG_INFO(module_name, ...) 
#define HV_INPUT_LOG_DEBUG(module_name, ...) 
#endif

/*注意此处宏定义必须加()，否则会有运算符优先级bug,a % MAX_CHANNEL_QUEUE_SIZE运算的结果是
(a % HV_BOARD_CONFIG_MAX_CHANNEL_NUM) * 20!!!! */
#define MAX_INPUT_QUEUE_SIZE            ((HV_BOARD_CONFIG_MAX_HDMI_PORT_NUM + HV_BOARD_CONFIG_MAX_DP_PORT_NUM) * 20)

#if (HV_PROJECT_CONFIG_ESEGMENT == HV_CONFIG_ON)
#define HV_HDMI_MAX_EDID_LENTH                  512  /* Max EDID Length */
#else
#define HV_HDMI_MAX_EDID_LENTH                  256  /* Max EDID Length */
#endif

#define HV_HDMI_PRE_EQ_RESULT_TABLE_CONT        50   /* 每12.8M一个挡位 */

#define HV_HDMI_MAX_WAIT_SYNC_CNT               10

#define HV_EDID_DESCRIPTOR4_OFFSET      0x6C
#define HV_EDID_BASE_WEEK_OFFSET        0x10
#define HV_EDID_BASE_YEAR_OFFSET        0x11
#define HV_EDID_PRODUCT_SN_ADDR_START   0x0C
#define HV_EDID_PRODUCT_SN_ADDR_END     0x0F

#define HV_EDID_COLOR_CHARACS_OFFSET    (25)

typedef struct _InputPortStateMachine
{
    USHORT16          usAcceptStates;/*不能使用枚举*/
    USHORT16          usEventId;     /*不能使用枚举, 有timer消息不是InputPortEvent类型*/
    Status            (*pfActionHandle)(const InputPortEvent* pstEvent, VOID* pstPortData);
    InputPortState    enNextSuccessState;
    InputPortState    enNextFailState;
}InputPortStateMachine;

typedef enum _LastPortUnSyncReason
{
    LastPortUnSyncReason_None         = 0,
    LastPortUnSyncReason_TimingChange = 1,
    LastPortUnSyncReason_SignalLoss   = 2,
    LastPortUnSyncReason_ColorChange  = 3,
    LastPortUnSyncReason_PlugOut      = 4,
}LastPortUnSyncReason;

typedef enum _HdmiEqStatus
{
    HdmiEqStatus_Init         = 0,
    HdmiEqStatus_EQLoopDone   = 1,
    HdmiEqStatus_SwEQStart    = 2,
    HdmiEqStatus_SwEQDone     = 3,
    HdmiEqStatus_HwEQStart    = 4,
    HdmiEqStatus_HwEQDone     = 5,
    HdmiEqStatus_EqStable     = 7
}HdmiEqStatus;

typedef enum _HdcpEncStatus
{
    HdcpEncStatus_NoneEnc  = 0,
    HdcpEncStatus_1XStart  = 1,
    HdcpEncStatus_1XDone   = 2,
    HdcpEncStatus_2XStart  = 3,
    HdcpEncStatus_2XDone   = 4,
    HdcpEncStatus_WaitSync = 5,
    HdcpEncStatus_Cnt      = 6
}HdcpEncStatus;

typedef struct
{
    UCHAR8   ucBestStart;
    UCHAR8   ucBestStop;
    USHORT16 usBestCedValue;
}HDMIRxSwEq;

typedef struct _HdmiCtrlData
{
    InputPortState      enCurrentPortState;     /* 当前端口的即时状态 */
    LinkPortIndex       enPortIndex;            /* 物理端口号 */
    EDIDType            enEdidConfiged;         /* EDID Configured */
    HdmiVersion         enHdmiVersion;          /* HDMI Version Configured */
    LastPortUnSyncReason enLastPortUnSyncReason;/* Mute Abmormal Used for check the Black Reason. */
    BOOL                bIsCableConnected;      /* HV_TRUE : PlugIn; False PlugOut */
    BOOL                bHPDStatus;             /* Status of HPD HV_TRUE: HPD UP, HV_FALSE HPD DOWN */
    BOOL                bEnteredVRR;            /* Notice DPU Entered Free Sync Mode on AMD, NVIDIA, HF-VRR */
    BOOL                bEnterAllm;             /* Notice DPU Entered ALLM HV_TRUE: Entered Allm Mode;*/
    BOOL                bIdleStart;             /* TRUE: Have Received Idle Start */
    BOOL                bEnterManualAudClk;     /* Enter Manual Audio Cts N Clock */
    BOOL                bAudioAbnormal;         /* Audio is Abnormal */
    BOOL                bEnterLowBnd;           /* Enter Ratio Low Bnd Mode */
    BOOL                bEnterEQBypassMode;     /* Enter EQ Bypass Mode */
    BOOL                bSendTimeChange;        /* Have Send out the Timing change message. */
    BOOL                bInRobustRatio;         /* Robust Ratio and Enter Protect Period. */
    USHORT16            usLastOverValue;        /* Last OverFlow Configured CTS Value */
    USHORT16            usLastUnderValue;       /* Last UnderFlow Configured CTS Value */
    UCHAR8              ucDataPortIndex;        /* HDMI Drvier Port Index. */
    /*** 0 : No FRL, TMDS Only  * 1 :  3G @ 3Lane * 2 :  6G @ 3Lane * 3 :  6G @ 4Lane * 
         4 :  8G @ 4Lane * 5 : 10G @ 4Lane  * 6 : 12G @ 4Lane ****/
    /* 必须要清空，当链路状态变化后 */
    UCHAR8              ucHdmiFRLRate;          /* 0:TMDS Mode, 1-6 :FRL mode */
    UCHAR8              ucGrearMode;            /* SysConfigured PHY OSR HdmiRxGearMode */
    UCHAR8              ucWaitSyncTimerOutCnt;  /* Wait Sync Timer Out Counter */
    UCHAR8              ucEQInitValue;          /* Auto EQ Table Init Value */
    UCHAR8              ucEqSwTable;            /* Sw EQ Table 档位 */
    UCHAR8              ucLaneLockTimes;        /* Eq Table Valid Bit */
    UCHAR8              ucEqStatus;             /* 0: Init; 2 : Start SW EQ; 3 : Sw Done; 4 : Hw EQ Start; 5 : HW EQ Done; 7 : EQ Timing Stable */
    UCHAR8              ucHdcpEncStatus;        /* Hdcp Encry Status */
    UCHAR8              ucMccsFreeSyncStatus;   /* 0: FreeSync Closed; 1: fressSync Open*/
    USHORT16            ausPreEqTable[HV_HDMI_PRE_EQ_RESULT_TABLE_CONT][4];         /*  */
    HDMIRxSwEq          astSwEqResult[4];       /* Sw EQ Table 结果 */
    USHORT16            usTmdsClkFreqEqLabel;   /* Frequncy: Use the Last Sw EQ ; 12.8M; Solve 2238 ReAuther with Timingchange*/
    UCHAR8              aucEdidData[HV_HDMI_MAX_EDID_LENTH];  /* HDMI EDID Content */
    UINT32              uiEdidLength;           /*EDID Content Length*/
    UINT32              uiAudioFsValue;         /* HDMI Audio Fs Value */
    VideoTimingParam    stTimingPara;           /* Timing Info on channel to show */
    VideoColorParam     stColorPara;            /* Color Info on channel to show */
    HDRParam            stHdrPara;              /* HDR Info on channel to show */
    VRRInfoParam        stVrrInfo;              /* Vendor Spec Info Frame */
    AudioTimingParam    stAudioTimingPara;      /* audio timing param */

    HV_TIMER_S          *pstHpdControlTimer;    /* HPD Timer for PULL UP */
    HV_TIMER_S          *pstWaitSyncTimer;      /* WaitSync Timer for Timeout */
    HV_TIMER_S          *pstSyncOkTimer;        /* SyncOK Timer for Timeout */
    HV_TIMER_S          *pstEqCheckTimer;       /* Eq Checking Timer for Timeout */
    HV_TIMER_S          *pstLaneLockedTimer;    /* Start EQ with the Lane Locked */
    HV_TIMER_S          *pstHdcpSyncTimer;      /* HDCP 1X Sync Timer for 128 Frame */
    HV_TIMER_S          *pstRobustRatio;        /* Entered Robust Ratio Timer. */
}HdmiCtrlData;

typedef struct _HdcpCtrlData
{
    HdcpPort2xState     enCurrentPort2xState;   /* 当前端口的即时状态 */
    HdcpVersion         enHdcpVersion;          /* HDCP Version Configured */
    HdcpPortType        enHdcpPortType;         /* HDCP Port Type Used For Hdmi Or DP: HdcpPortType_Invalid==>unused */
    LinkPortIndex       enInputPortIndex;       /* HDMI or DP Input Port Index ： LINK_PORT_INDEX_INVALID==>unused*/
    UCHAR8              ucHdcpIndex;            /* HDCP Local Port Index of this Data */
    UCHAR8              ucPortIndex;            /* HDMI or DP Local Port Index */
    LinkPortIndex       enWaitPort;
    HdcpRole            enRole;
    HdcpRx              stHdcpRx;               /*  */
    BOOL                bAuth;                  /* HDCP Authenticated or not */
    BOOL                bHdcp1XReAuthed;        /* HDCP 1X Received */
    HV_TIMER_S          *pstRcvEks;             /* HDCP Eks Received Timer */
}HdcpCtrlData;

typedef struct _DisplayPortCtrlData
{
    HV_TIMER_S*          pstHpdTimer;
    HV_TIMER_S*          pstTimingCheckTimer;
    HV_TIMER_S*          pstTrainingTimer;
    HV_TIMER_S*          pstAudioCheckTimer;
    InputPortState       enCurrentPortState;   /* Current port status */
    LinkPortIndex        enPortIndex;          /* Link port in system */
    EDIDType             enCurEdidType;
    UCHAR8               ucCurPort;            /* DP port：0 or 1*/
    UCHAR8               ucHpdLevel;           /* 0:Low 1:High */
    UCHAR8               ucTimChkCnt;          /* Timing check count */
    BOOL                 bDpHpdTimerStart;
    BOOL                 bDpChkTimerStart;
    BOOL                 bDpTrainingTimerStart;
    BOOL                 bDpAudioTimerStart;
    BOOL                 bCableConnected;      /* HV_FALSE:Plugout HV_TRUE:Plugin */
    BOOL                 bLinkSync;            /* HV_FALSE:Not Sync HV_TRUE:Sync */
    BOOL                 bLinkPeriod;
    BOOL                 bIsNoSignal;
    BOOL                 bAuxState;
    BOOL                 bAudioAbnormal;
    VideoTimingParam     stCurTiming;
    VideoColorParam      stCurColor;
    HDRParam             stCurHdr;
    VRRInfoParam         stCurVrr;
    AudioTimingParam     stCurAudioTiming;
    LastPortUnSyncReason enLastPortUnSyncReason;
}DisplayPortCtrlData;

typedef struct _HDMIManager
{
    /*Hv_Mw_HdmiHPDControl*/
    VOID         (*pfHPDToggle)(USHORT16 usLinkPortIndex);
    /* Switch == True ==> HPD ON; HPD Swith false ==> HPD OFF */
    Status       (*pfHPDAction)(LinkPortIndex enPortIndex, BOOL bHpdSwitch);
    /* Get HDMI Video Para */
    Status       (*pfGetVideoPara)(LinkPortIndex usLinkPortIndex,ChannelData* pstChannelData);
    /* Get HDMI Vendor Info for FreeSync, GSync, HF-VRR */
    Status       (*pfGetSourceVendorInfo)(LinkPortIndex enPortIndex, VRRInfoParam *ptSourceVendInfo);
    /* Audio Status for input port */
    BOOL         (*pfGetAudioStatus)(LinkPortIndex enPortIndex);
    /* Update the Edid for input port-- Already including HPD ctrol after EDID Update. */
    Status       (*pfUpdateEdid)(LinkPortIndex enPortIndex, EDIDType eEdidConfigure);
    /* Get Current Frame rate */
    UINT32       (*pfGetCurrentFrameRate)(LinkPortIndex enPortIndex);
    /* Get Current EDID Data */
    UINT32       (*pfGetEdidData)(LinkPortIndex enPortIndex, UCHAR8 *pucEdidData);

    Status       (*pfStartAudio)(LinkPortIndex enPortIndex);

    Status       (*pfStopAudio)(LinkPortIndex enPortIndex);
    
    VOID         (*pfReset)(LinkPortIndex enPortIndex);
    
    Status       (*pfGetPortErrorCode)(LinkPortIndex enPortIndex);
    /* HDMI Control Data */
    HdmiCtrlData astHdmiData[HV_BOARD_CONFIG_MAX_HDMI_PORT_NUM];
}HDMIManager;

typedef struct _HDCPIManager
{
    HDCPKeyDataDBRegion *pstHdcpKey;
    Hdcp2xRxMmult stMmult;
    HdcpCtrlData    astHdcpData[HV_BOARD_CONFIG_MAX_HDCP_PORT_NUM];
}HDCPManager;

typedef struct _DisplayPortManager
{
    DisplayPortCtrlData astDpCtrl[HV_BOARD_CONFIG_MAX_DP_PORT_NUM];

    Status (*pfGetVideoPara)(LinkPortIndex enPortIndex, ChannelData* pstChannelData);

    Status (*pfGetVrrPara)(LinkPortIndex enPortIndex, VRRInfoParam *pstVrrInfo);

    Status (*pfHpdToggle)(LinkPortIndex enPortIndex);

    /* Switch == True ==> HPD ON; HPD Swith false ==> HPD OFF */
    Status (*pfHPDAction)(LinkPortIndex enPortIndex, BOOL bHpdSwitch);

    BOOL   (*pfGetAudioStatus)(LinkPortIndex enPortIndex);

    Status (*pfUpdateEdid)(LinkPortIndex enPortIndex, EDIDType eEdidConfigure);

    UINT32 (*pfGetCurrentFrameRate)(LinkPortIndex enPortIndex);

    UINT32 (*pfGetEdidData)(LinkPortIndex enPortIndex, UCHAR8 *pucEdidData);

    Status (*pfStartAudio)(LinkPortIndex enPortIndex);

    Status (*pfStopAudio)(LinkPortIndex enPortIndex);

    Status (*pfReset)(LinkPortIndex enPortIndex);

    Status (*pfGetPortErrorCode)(LinkPortIndex enPortIndex);
}DisplayPortManager;

typedef struct _InputPortInnerMsgQueue
{
    USHORT16 usWriteAddr;           /* 写地址 */
    USHORT16 usReadAddr;            /* 读地址 */
    InputPortEvent astFifo[MAX_INPUT_QUEUE_SIZE];
}__attribute__((aligned(4)))InputPortInnerMsgQueue;


typedef struct _InputPortManager
{
    InputPortInnerMsgQueue  stIPInnerMsgQueue;      /*内部消息队列用于缓存挂在SystemTask其他模块发给RX模块的消息*/
    HDMIManager             stHDMIManager;          /*HDMI管理struct*/
    DisplayPortManager      stDisplayPortManager;   /*DP管理struct*/
    HDCPManager             stHDCPManager;          /*HDCP管理struct*/
    LinkPortIndex           enMainPortIndex;        /*Channel主通道选择的端口, channel会动态更新*/
    LinkPortIndex           enSubPortIndex;         /*辅主通道选择的端口, channel会动态更新*/

    Status (*pfGetVideoPara)(LinkPortIndex enPortIndex,ChannelData* pstChannelData);

    Status (*pfGetSourceVendorInfo)(LinkPortIndex enPortIndex, VRRInfoParam *ptSourceVendInfo);

    BOOL   (*pfGetAudioStatus)(LinkPortIndex enPortIndex);

    UINT32 (*pfGetMuteStatus)(ChannelType mutePath);

    BOOL   (*pfGetPortLastUnSyncStatus)(LinkPortIndex enPortIndex, LastPortUnSyncReason* penLastPortUnSyncReason);
    
    VOID   (*pfClearPortLastUnSyncStatus)(LinkPortIndex enPortIndex);

    Status (*pfUpdateEdid)(LinkPortIndex enPortIndex, EDIDType eEdidConfigure);

    UINT32 (*pfGetCurrentFrameRate)(LinkPortIndex enPortIndex);

    Status (*pfBindChannelPortIndex)(ChannelType enChannelType, LinkPortIndex enPortIndex);

    Status (*pfStartAudio)(LinkPortIndex enPortIndex);

    Status (*pfStopAudio)(LinkPortIndex enPortIndex);

    Status (*pfCheckAudio)(LinkPortIndex enPortIndex);

    Status (*pfPreProcess)(LinkPortIndex enPortIndex);

    Status (*pfPostProcess)(LinkPortIndex enPortIndex);

    Status (*pfEnterStandby)(VOID);

    Status (*pfEnterPowerOff)(VOID);

    Status (*pfEnterResume)(VOID);

    Status (*pfReset)(LinkPortIndex enPortIndex);

    Status (*pfGetPortErrorCode)(LinkPortIndex enPortIndex);
}__attribute__((aligned(4)))InputPortManager;

typedef enum
{
    COLOR_ID_RED_X,
    COLOR_ID_RED_Y,
    COLOR_ID_GREEN_X,
    COLOR_ID_GREEN_Y,
    COLOR_ID_BLUE_X,
    COLOR_ID_BLUE_Y,
    COLOR_ID_WHITE_X,
    COLOR_ID_WHITE_Y,
    COLOR_ID_BUTT
} EDID_COLOR_CHARACS_E;

/**
 * @brief initial InputPortManager object.
 * @param[in] pointer of InputPortManager object to be initial.
 * @return Status, 0-HV_SUCCESS, 1-HV_FAILURE.
 */
Status Hv_Mw_InputPortManager_Init(VOID);

/**
 * @brief judge whether there are messages in the InputPort messsage pool.
 * @param[in] None.
 * @return BOOL type of result, 0-empty, 1-not empty.
 */
BOOL Hv_Mw_InputPort_HasInnerMsgs( VOID );

/**
 * @brief proc one InputPortEvent messsage form System messageQueue.
 * @param[in] pstInputPortEvent pointer to message to process.
 * @return Status, 0-HV_SUCCESS, 1-HV_FAILURE.
 */
Status Hv_Mw_InputPort_ProcSystemQueueMsg(const SystemEvent* pstSystemEvent);

/**
 * @brief proc all of the messages in the input port inner Message pool once time.
 * @param[in] pstInputPortManager pointer to InputPortManager.
 * @return Status, 0-HV_SUCCESS, 1-HV_FAILURE.
 */
Status Hv_Mw_InputPort_ProcInnerMsgs(VOID);

/**
 * @brief send a message to the input port messsage pool.
 * @param[in] point to ChannelEvent*  messages type to send.
 * @return Status, 0-HV_SUCCESS, 1-HV_FAILURE.
 */
Status Hv_Mw_InputPort_SendInnerMsg(const InputPortEvent* pstInputPortEvent);

/**
 * @brief Get The Unsync status Reason.
 * @param[in] Inputport idnex.
 * @return Status, 0-HV_SUCCESS, 1-HV_FAILURE & the reason of Unsync.
 */
BOOL Hv_Mw_InputPort_GetPortLastUnSyncStatus(LinkPortIndex enPortIndex, LastPortUnSyncReason* penLastPortUnSyncReason);

/**
 * @brief Clear The Unsync status Reason.
 * @param[in] Inputport idnex.
 * @return Status, 0-HV_SUCCESS, 1-HV_FAILURE .
 */
VOID Hv_Mw_InputPort_ClearPortLastUnSyncStatus(LinkPortIndex enPortIndex);

/**
 * @brief -- Get The Channel bind link port index.
 * @param[in] Channel Type want to get.
 * @return Link port Index.
 */
LinkPortIndex Hv_Mw_InputPort_GetChannelBindPortIndex(ChannelType enChannelType);

/**
 * @brief Get The Unsync status Reason.
 * @param[in] Inputport idnex.
 * @return Status, 0-HV_SUCCESS, 1-HV_FAILURE & the reason of Unsync.
 */
InputPortManager* Hv_Mw_InputPort_GetManagerPtr(VOID);

/**
 * @brief Get The Unsync status Reason.
 * @param[in] Inputport idnex.
 * @return Status, 0-HV_SUCCESS, 1-HV_FAILURE & the reason of Unsync.
 */
BOOL Hv_Mw_InputPort_GetCableStatus(LinkPortIndex enPortIndex);

/**
 * @brief Toggle InputPort HPD.
 * @param[in] Inputport idnex.
 * @return Status, 0-HV_SUCCESS, 1-HV_FAILURE & the reason of Unsync.
 */
Status Hv_Mw_InputPort_ToggleHpd(LinkPortIndex enPortIndex);

/**
 * @brief Common interface for EDID Block Insert Data.
 * @param[in] ucAddrStart Block data start address.
 * @param[in] ucAddrEnd Block data end addrss
 * @param[in] pucValueInsert  the Value want to Insert pointer.
 * @param[out] The EDID after Inser value and checksum updated.
 * @return Status, 0-HV_SUCCESS, 1-HV_FAILURE & the reason of Unsync.
 */
Status Hv_Mw_InputPort_InsertEdidBlockData(UCHAR8 ucAddrStart, UCHAR8 ucAddrEnd, UCHAR8* pucEdidData, const UCHAR8 *pucValueInsert);
/**
 * @brief Common interface for EDID Block Insert Descriptor SN.
 * @param[in] pucDescSnInsert  the Descriptor SN want to Insert.
 * @param[out] The EDID after Inser Descriptor SN and checksum updated.
 * @return Status, 0-HV_SUCCESS, 1-HV_FAILURE & the reason of Unsync.
 */
Status Hv_Mw_InputPort_InsertEdidDescSn(UCHAR8* pucEdidData, const CHAR8 *pcDescSnInsert);

/**
 * @brief return edid info.
 * @param[in] pstFactEdidDetail  edid info.
 * @return Status, 0-HV_SUCCESS, 1-HV_FAILURE & the reason of Unsync.
 */
Status Hv_Mw_InputPort_GetFactoryEdidInfo(LinkPortIndex enPortIndex, HvFactoryEdidInfo *pstFactEdidDetail);

/**
 * @brief return edid info to osd.
 * @param[in] pstEdidInfo  edid info.
 * @return Status, 0-HV_SUCCESS, 1-HV_FAILURE & the reason of Unsync.
 */
Status Hv_Mw_InputPort_GetFactoryEdidInfoToOsd(LinkPortIndex enPortIndex, HvEdidInfoToOsd *pstEdidInfo);

/**
 * @brief remove hdr support.
 * @param[in] pucEdidUpdate,  edid to be modified.
 * @param[in] uiEdidLength.
 * @return void.
 */
VOID Hv_Mw_InputPort_RmvEdidHdr(UCHAR8* pucEdidUpdate, UINT32 uiEdidLength);

#ifdef HDR_PARAM_DYNAMIC_UP
/**
 * @brief update edid hdr param by macro definition.
 * @param[in] pucEdidData edid data.
 * @param[in] pucEdidData edid length.
 * @return Status, 0-HV_SUCCESS, 1-HV_FAILURE & the reason of Unsync.
 */
Status Hv_Mw_InputPort_UpdateEdidHdrParam(UCHAR8 *pucEdidData, UINT32 uiEdidLength);
#endif

EDIDType Hv_Mw_InputPort_GetCurrentEdidType(LinkPortIndex enPortIndex);
Status Hv_Mw_InputPort_SetHpdStatus(LinkPortIndex enPortIndex, BOOL bHpdStatus);
BOOL Hv_Mw_InputPort_GetHpdStatus(LinkPortIndex enPortIndex);

/**
 * @brief Interface for Caculate the Checksum of EDID Block,
 * @param[in] Edid Data point for the beginning of the Block.
 * @param[in] Edid Length of the block want to caculate, should transfer 127.
 * @return the checksum of the EDID Block
 */
UCHAR8 Hv_Mw_InputPort_CaculateCheckSum(UCHAR8* pucData, UCHAR8 ucLength);

/**
 * @brief Interface for current port status is on training or syncok or displayready.
 * @param[in] Inputport idnex.
 * @return The status of current input port index.
 */
InputPortState Hv_Mw_InputPort_GetInputPortStatus(LinkPortIndex enPortIndex);

/**
 * @brief Interface for factory to get edid checksum.
 * @param[in] port index, edid type, block id.
 * @param[out] checksum.
 * @return status.
 */
Status Hv_Mw_InputPort_GetEdidChecksum(LinkPortIndex enPortId, EDIDType enType, UCHAR8 ucBlock, UCHAR8 *pucChecksum);
#define FACTORY_GET_EDID_CHECKSUM(id, type, block) ({ \
    UCHAR8 ucVal; \
    ucVal = Hv_Mw_InputPort_GetEdidChecksum(id, type, block, &ucVal) == HV_SUCCESS ? ucVal : 0; \
})

#endif

