#include "si_datatypes.h"
#include "sii9777_platform_api.h"
#include "sii9777rx_api.h"
#include "host9777_if.h"
#include "sii9777mhl_data.h"
#include "sii9777common_data.h"
#include "x_os.h"
#include "x_assert.h"
#include "drvcust_if.h"
#include <linux/fs.h>
#include <asm/uaccess.h>
#include <linux/param.h>
#include "msdc_if.h"
#include "mhl_if.h"
#include "drv_hdmi.h"
#ifdef SYS_ANDROID_TV_TIF_SUPPORT
extern UINT32 u4MhlMscbArg;//MSC Callback arg
void vCbus_NotifyMscResult(UINT8 u1Port,UINT8 u1Opcode,UINT8 data,void *arg);
void vCbus_NotifyScratchPadResult(CBUS_MSG_DESCRIPTION_T *msg);
#endif
#ifdef CUSTOM_SELF_DIAG_ENABLE
extern void SelfDiagGoingToStartBostonCheck(void);
#endif

#define SIL9777_SUCCESS 0
#define SIL9777_ERROR 1
UINT8 u1Boston_Mhl_port = 2;
#define BOSTON_MHL_PORT u1Boston_Mhl_port
#define INAVLID_SII977_RX_PORT 4
SiiInst_t sii9777Instance;
UINT8 fgSii9777UpdateStatus = 0;
Sii9777AvLink_t preAvlinkStatus = SII9777_AV_LINK__NONE;
UINT8 u1CurrentSilRxPort = INAVLID_SII977_RX_PORT;
BOOL fgManualHpdLow = FALSE;
HAL_TIME_T tHpdLowTime;
HAL_TIME_T tHpdTmpTime;
HAL_TIME_T tHpdDeltaTime;

extern INT16 GPIO_SetOut(INT16 i4GpioNum, INT16 i4Val);
int hwId = 0;
UINT8 dualLinkStatus = 0;
#define FILE_BASE_UPDATE_BOSTON 1
#define EMMC_BASE_UPDATE_BOSTON 1
bool_t mhl_mute_onOff = 0;
UINT8 cbusLocalDev[16]=
{
	0x00,
	0x32,
	0x51,
	0x01,
	0x43,
	0x7f,
	0x03,
	0x8f,
	0x01,
	0x0f,
	0x27,
	0x00,
	0x07,
	0x10,
	0x33,
	0x00
};
UINT8 cbusLocalXDev[4]={
	0x07,
	0x07,
	0x00,
	0x00
};
UINT8 fgUseFileUpdate = 0;
//SiiLibEvtCbFunc_t Sii9777CallBackHandler;
Sii9777EventCallbackFunc_t Sii9777CallBackHandler;

void SiiEventCbFunc( SiiInst_t inst, Sii9777EventFlags_t eventFlags );



#define SII9777_BUFFER_SIZE   256

#if FILE_BASE_UPDATE_BOSTON
struct file * sp9777BinFile = NULL;
mm_segment_t oldfs;
#endif
#if EMMC_BASE_UPDATE_BOSTON
UINT32 readOffset = 0;
UINT32 BostonFwPartitionID = 50;
UINT32 BostonfiwareSize= 0x47000;
static UINT8 u1CurrentRxPort = 0;

#endif
UINT8 u1ArcEnable = FALSE;
static Sii9777BootStat_t _tHostSii9777BootStatusQuery(UINT32 u4TimeOut) //ms
{
	Sii9777BootStat_t bootStatus;
	UINT32 bootStartTime = SiiPlatformTimeMsecQuery();
	UINT32 currentTime = SiiPlatformTimeMsecQuery();

	bootStatus = SII9777_BOOT_STAT__IN_PROGRESS;
	while(SII9777_BOOT_STAT__IN_PROGRESS == bootStatus)
	{
		Sii9777BootStatusQuery(sii9777Instance,&bootStatus);
		x_thread_delay(20);
		currentTime = SiiPlatformTimeMsecQuery();
		if((currentTime - bootStartTime) > u4TimeOut)
		{
			printf("take too long to boot up, consider boot fail, go to update firware........\n");
			bootStatus = SII9777_BOOT_STAT__FAILURE;
			break;
		}
	}
	if(SII9777_BOOT_STAT__SUCCESS == bootStatus)
	{
		fgSwitchInitFlag = 1;
	}

	return bootStatus;
}

void FirmwareUpdateRequest( void )
{
#if 0
    oldfs = get_fs();
	set_fs(KERNEL_DS);
	sp9777BinFile = filp_open("/basic/boston.bin", (O_RDONLY), 0);
	if (IS_ERR(sp9777BinFile))
	{
		set_fs(oldfs);
		LOG(0, "[boston] filp_open error!\n");
		return;
	}
#else
	readOffset = 16;  //for jump header
	BostonFwPartitionID = (INT32) DRVCUST_InitGet(eHDMIBOSTONFWPartId);
#endif
	/*
	{

		UINT8 versionBuffer[16]; //sp9777BinFile->f_pos = 16; //skip the version info
		UINT32 readSize = 0;
		UINT8 i = 0;
		sp9777BinFile->f_pos = 0;
		readSize = sp9777BinFile->f_op->read(sp9777BinFile,versionBuffer,16,&sp9777BinFile->f_pos);
		for(i=0;i<16;i++)
		{
			printf("versionBuffer[%d]: %x \n",i,versionBuffer[i]);
		}
	}

	printf("skip version Info.........../n");*/
    Sii9777FirmwareInit(sii9777Instance);
	printf("sii977 firmware erasing.........../n");
    return;
}
void FirmwareUpdateRequestByfile(UINT8 haveHeader)
{

    oldfs = get_fs();
	set_fs(KERNEL_DS);
	sp9777BinFile = filp_open("/mnt/boston.bin", (O_RDONLY), 0);
	if (IS_ERR(sp9777BinFile))
	{
		set_fs(oldfs);
		LOG(0, "[boston] filp_open error!\n");
		return;
	}

	{
		UINT8 versionBuffer[16]; //sp9777BinFile->f_pos = 16; //skip the version info
		UINT32 readSize = 0;
		UINT8 i;
		sp9777BinFile->f_pos = 0;
		if(haveHeader == 1)
		{
			readSize = sp9777BinFile->f_op->read(sp9777BinFile,versionBuffer,16,&sp9777BinFile->f_pos);
			for(i=0;i<16;i++)
			{
				printf("versionBuffer[%d]: %x \n",i,versionBuffer[i]);
			}
		}
	}
	printf("skip version Info.........../n");
    Sii9777FirmwareInit(sii9777Instance);
	printf("sii977 firmware erasing by file.........../n");
    return;
}
UINT8 u1IsBostonBootOK(void)
{
	return fgSwitchInitFlag;
}
void replaceEdidData(UINT8 data[256],UINT8 port)
{

	struct file * sp9777EdidBinFile = NULL;
	UINT32 writeSize = 0;
	mm_segment_t edidOldfs;
    edidOldfs = get_fs();
	set_fs(KERNEL_DS);
	sp9777EdidBinFile = filp_open("/basic/boston.bin", (O_RDWR), 0);
	if (IS_ERR(sp9777EdidBinFile))
	{
		set_fs(edidOldfs);
		LOG(0, "[boston] filp_open error!\n");
		return;
	}
	sp9777EdidBinFile->f_pos = /*16 +*/ 0x5000 + (port-1)*0x100;
	writeSize = sp9777EdidBinFile->f_op->write(sp9777EdidBinFile,data,256,&sp9777EdidBinFile->f_pos);
	set_fs(edidOldfs);
	filp_close(sp9777EdidBinFile,NULL);
	sp9777EdidBinFile = NULL;
}
void replaceFourPortEdidData(void)
{
	UINT8 i;
	UINT8 muffinedidData[256];
	for(i=1;i<=4;i++)
	{
		u1HDMI_GetEdidData(i,muffinedidData,256);
		replaceEdidData(muffinedidData,i);
	}
}
UINT8 checkEdidof9777IsSame(void)
{
	UINT8 sii9777edidData[256];
	UINT8 muffinedidData[256];
	UINT32 i;
	UINT8 edidEqual = 1;
	u1HostSii9777EdidGet(0,sii9777edidData);
	u1HDMI_GetEdidData(1,muffinedidData,256);
	for(i=0;i<256;i++)
	{
		if(sii9777edidData[i]!=muffinedidData[i])
		{
			edidEqual = 0;
			printf("not equal,need to replaced the edid data\n");
			break;
		}
	}
	if(edidEqual == 0)
	{
	}
	else
	{
		printf("edid same , no need to replaced the edid data\n");
	}
	return edidEqual;
}
UINT32 getFileVersionInfo(void)
{
#if 0
	struct file * sp9777EdidBinFile = NULL;
	UINT32 ReadSize = 0;
	UINT32 version[4];  //16bytes
	mm_segment_t edidOldfs;
    edidOldfs = get_fs();
	set_fs(KERNEL_DS);
	sp9777EdidBinFile = filp_open("/basic/boston.bin", (O_RDONLY), 0);
	if (IS_ERR(sp9777EdidBinFile))
	{
		set_fs(edidOldfs);
		LOG(0, "[boston] filp_open error!\n");
		return 0;     //if error ,return 0, prevent firmware update request
	}
	ReadSize = sp9777EdidBinFile->f_op->read(sp9777EdidBinFile,((UINT8 *)&version[0]),16,&sp9777EdidBinFile->f_pos);
	set_fs(edidOldfs);
	filp_close(sp9777EdidBinFile,NULL);
	sp9777EdidBinFile = NULL;
	return version[0];
#else
	UINT32 version = 0xffffffff;
	readEmmcBostonData((UINT8*)&version,0,4);
	return version;
#endif
}
extern UINT8 fgSwitchInitFlag;
void vSii9777ResumeInit(void);
void SiiEventCbFunc( SiiInst_t inst, Sii9777EventFlags_t eventFlags )
{
	if(eventFlags & SII9777_EVENT_FLAGS__FLASH_DONE)
	{
		if(fgUseFileUpdate)
		{
				if( sp9777BinFile ) // More data to be programmed
				{
					uint8_t  buffer[SII9777_BUFFER_SIZE];
					UINT32 readSize = 0;
					readSize = sp9777BinFile->f_op->read(sp9777BinFile,buffer,SII9777_BUFFER_SIZE,&sp9777BinFile->f_pos);
				   // Retrieve binary data from file
					if(readSize == SII9777_BUFFER_SIZE)
					{
						Sii9777FirmwareUpdate(inst, &buffer, readSize);
					}
					else
					{
						Sii9777FirmwareUpdate(inst, &buffer, readSize);
						set_fs(oldfs);
						filp_close(sp9777BinFile,NULL);
						sp9777BinFile = NULL;
					}
					printf("sii977 firmware update use file in progress........./n");
				}
				else
				{
					Sii9777FirmwareRestart(inst);
					printf("sii977 firmware update done , restart/n");
				}
		}
		else
		{
				uint8_t  buffer[SII9777_BUFFER_SIZE];
				UINT64 u8Offset;
				if(readOffset >= BostonfiwareSize)
				{
					Sii9777FirmwareRestart(inst);
					printf("sii977 firmware update done , restart\n");
					{
						UINT32 disableAllEvent = 0x0;
						fgSii9777UpdateStatus = 2;
						u1Host9777EventFlagsMaskSet(&disableAllEvent);
						vHwGpio9777Reset();
                                                _tHostSii9777BootStatusQuery(20000);
						vSii9777ResumeInit();
					}
					// _tHostSii9777BootStatusQuery(20000);
					if(fgSwitchInitFlag && (u1CurrentSilRxPort < INAVLID_SII977_RX_PORT))
					{
						printf("Testlog:Set RX port as %d\n>>>>>>>>>>>>>>>>>>>.\n",u1CurrentSilRxPort);
						u1HostSii9777RxPortSet(&u1CurrentSilRxPort);
					}
					return;
				}
				u8Offset = (readOffset ) | (((UINT64)(UINT32)BostonFwPartitionID) << 32);
				MSDCPART_Read(u8Offset, buffer, SII9777_BUFFER_SIZE);
				Sii9777FirmwareUpdate(inst, buffer, SII9777_BUFFER_SIZE);
				fgSii9777UpdateStatus = 1;
				readOffset += 0x100;
				printf("sii977 firmware update using EMMC Read write in progress.........\n");
		}
	}
	if(eventFlags & SII9777_EVENT_FLAGS__AV_LINK_CHNG)
	{

		Sii9777AvLink_t avLinkStatus;
		Sii9777AvLinkQuery(sii9777Instance,&avLinkStatus);
		if(avLinkStatus != preAvlinkStatus)
		{
			#if 0
			if(preAvlinkStatus == SII9777_AV_LINK__MHL)
			{
				Mhl_NotifyHotPlug(u1Boston_Mhl_port,0);
				printf("notify mhl hot plug off\n");
			}
			if(avLinkStatus == SII9777_AV_LINK__MHL)
			{
				Mhl_NotifyHotPlug(u1Boston_Mhl_port,1);
				printf("notify mhl hot plug on\n");
			}
			#endif
			if((avLinkStatus == SII9777_AV_LINK__HDMI1) ||(avLinkStatus == SII9777_AV_LINK__HDMI2) || (avLinkStatus == SII9777_AV_LINK__DVI))
			{
				mhl_mute_onOff = 0;
				Sii9777AvMuteSet(sii9777Instance,SII9777_TX_PORT__2,&mhl_mute_onOff);
				Sii9777AvMuteSet(sii9777Instance,SII9777_TX_PORT__1,&mhl_mute_onOff);
				printf("if HDMI ,mute function should be off\n");
			}
			else
			{
				mhl_mute_onOff = 0;
				Sii9777AvMuteSet(sii9777Instance,SII9777_TX_PORT__2,&mhl_mute_onOff);
				Sii9777AvMuteSet(sii9777Instance,SII9777_TX_PORT__1,&mhl_mute_onOff);
				printf("if HDMI ,mute function should be off\n");
			}
			vNotifyHdmiHdrChg(SDR_RANGE); //Notify SDR_RANGE at AV_LINK change
			preAvlinkStatus = avLinkStatus;
		}
		printf("sii9777 avlink change event\n");
	}
	if(eventFlags & SII9777_EVENT_FLAGS__BOOT_DONE)
	{
		printf("sii977 Boot \n");
		//boot done success , Firwadonere normal in flash
	}
	if( eventFlags & SII9777_EVENT_FLAGS__PLUS_5V_CHNG )
    {
		printf("sii977 5V call back \n");
		updateHdmi4KModelPort5VStatus();
	}
	if( eventFlags & SII9777_EVENT_FLAGS__CBUS_EVENT )
    {

		Sii9777CbusEvt_t cbusEventQuery;
		printf("SII9777_EVENT_FLAGS__CBUS_EVENT back \n");
		Sii9777CbusEventQuery(sii9777Instance,&cbusEventQuery);

		printf("SII9777_EVENT_FLAGS__CBUS_EVENT type cbusEventQuery: %x \n",cbusEventQuery);
		if(cbusEventQuery & SII9777_CBUS_EVT__MSC_MESSAGE_RECEIVED)
		{
			Sii9777MscCmd_t mscCommand;
			Sii9777CbusMscMsgReceive(sii9777Instance,&mscCommand);
			printf("receive MSC command SII9777_CBUS_EVT__MSC_MESSAGE_RECEIVED,mscCommand.subCmd: %x,mscCommand.codeValue: %x\n",mscCommand.subCmd,mscCommand.codeValue);
			if(mscCommand.subCmd == SII9777_MSC_SUB_COMMAND__RAP)
			{
				if(u1CurrentSilRxPort == SII9777_RX_PORT__1) //Not to mute SII9777 TX when current source is not HDMI2(MHL)
				{
					if(mscCommand.codeValue == 0x10)
					{
						//content on
						mhl_mute_onOff = 0;
						Sii9777AvMuteSet(sii9777Instance,SII9777_TX_PORT__2,&mhl_mute_onOff);
						Sii9777AvMuteSet(sii9777Instance,SII9777_TX_PORT__1,&mhl_mute_onOff);
						printf("content on\n");
					}
					else if(mscCommand.codeValue == 0x11)
					{
						//content off
						mhl_mute_onOff = 1;
						Sii9777AvMuteSet(sii9777Instance,SII9777_TX_PORT__2,&mhl_mute_onOff);
						Sii9777AvMuteSet(sii9777Instance,SII9777_TX_PORT__1,&mhl_mute_onOff);
						printf("content off\n");
					}
				}
			}
#ifdef SYS_ANDROID_TV_TIF_SUPPORT
			vCbus_NotifyMscResult(BOSTON_MHL_PORT,mscCommand.subCmd,mscCommand.codeValue,(void *)u4MhlMscbArg);
#endif
			//notify
		}
		if(cbusEventQuery & SII9777_CBUS_EVT__SCRATCH_PAD_CHANGED)
		{
			UINT8 burstData[16];
			UINT8 i;
			UINT8 length;
			CBUS_MSG_DESCRIPTION_T cbusDescription;
			Sii9777CbusBurstReceive(sii9777Instance,burstData,0,16);
			cbusDescription.u1Port = BOSTON_MHL_PORT;
			cbusDescription.Opcode = 0x00;
			cbusDescription.MscMsg = 0x6c;
			cbusDescription.Size = 16;
			cbusDescription.offset = 0;
			for(i=0;i<16;i++)
			{
				cbusDescription.Data[i] =  burstData[i];
			}
#ifdef SYS_ANDROID_TV_TIF_SUPPORT
			vCbus_NotifyScratchPadResult(&cbusDescription);
#endif
		}
		if(cbusEventQuery & SII9777_CBUS_EVT__REMOTE_DEVCAP_CHANGED)
		{
			UINT8 deviceCapbility[16];
			Sii9777CbusRemoteDevcapQuery(sii9777Instance,deviceCapbility,0,16);
#ifdef SYS_ANDROID_TV_TIF_SUPPORT
//notify adopter ID
			vCbus_NotifyDcChange(BOSTON_MHL_PORT,deviceCapbility[0x3],deviceCapbility[0x4]);
#endif
		}
		if(cbusEventQuery & SII9777_CBUS_EVT__FEEDBACK_RECEIVED)
		{
			Sii9777MscCmd_t mscCommand;
			Sii9777CbusMscMsgReceive(sii9777Instance,&mscCommand);
			printf("receive MSC command  SII9777_CBUS_EVT__FEEDBACK_RECEIVED ,mscCommand.subCmd: %x,mscCommand.codeValue: %x\n",mscCommand.subCmd,mscCommand.codeValue);
			#ifdef SYS_ANDROID_TV_TIF_SUPPORT
			vCbus_NotifyMscResult(BOSTON_MHL_PORT,mscCommand.subCmd,mscCommand.codeValue,(void *)u4MhlMscbArg);
			#endif
		}
		if(cbusEventQuery & SII9777_CBUS_EVT__MSC_SENDING_FAILED)
		{

		}
		if(cbusEventQuery & SII9777_CBUS_EVT__BURST_WRITE_FAILED)
		{

		}
		if(cbusEventQuery & SII9777_CBUS_EVT__BURST_WRITE_SUCCEEDED)
		{

		}
		if(cbusEventQuery & SII9777_CBUS_EVT__DEVCAP_NOTIFICATION_FAILED)
		{

		}
		if(cbusEventQuery & SII9777_CBUS_EVT__DEVCAP_NOTIFICATION_SUCCEEDED)
		{

		}
		if(cbusEventQuery & SII9777_CBUS_EVT__MSC_SEND_SUCCESSFULLY)
		{

		}
	}
    if( eventFlags & SII9777_EVENT_FLAGS__DUAL_LINK_CHNG )
    {
		UINT8 dualLink = 0;
		u1HostSii9777DualLinkStatusGet(&dualLink);
		dualLinkStatus = dualLink;
        printf("SII9777_EVENT_FLAGS__DUAL_LINK_CHNG: %d\n",dualLink);
    }
	if( eventFlags & SII9777_EVENT_FLAGS__MHL_VERSION_CHNG)
	{
		Sii9777MhlVersion_t mhlVersion = SII9777_MHL_VERSION__NONE;
		Sii9777MHLVersionQuery(sii9777Instance,&mhlVersion);
		if(SII9777_MHL_VERSION__NONE == mhlVersion)
		{
			Mhl_NotifyHotPlug(u1Boston_Mhl_port,0);
			printf("notify mhl hot plug off\n");

		}
		else
		{
			Mhl_NotifyHotPlug(u1Boston_Mhl_port,1);
			printf("notify mhl hot plug on\n");
		}
	}
	if( eventFlags & SII9777_EVENT_FLAGS__HDR_CHNG)
	{
		Sii9777Hdr_t eHdrInfo;
		Sii9777HdrQuery(sii9777Instance,&eHdrInfo);
		vNotifyHdmiHdrChg((E_HDMI_HDR_EOTF)eHdrInfo.hdrData[4]);
	}
}

Sii9777Config_t config9777 =
{
	"9777-Rx",							 // pNameStr[8] 		- Name of Object
	false,								 // bIpcSemaphore		-
	0xFFFFFFFF, 						 // eventFlagsMask		-
	0x00,								 // gpioIoConfigMask	-
	0x00,								 // gpioOutputLevelMask -
	SII9777_DUAL_LINK_MODE__LEFT_RIGHT,  // splitMode			- Video Split Mode
	SII9777_TX_PORT__2, 				 // primTxPort			- Output port used for downstream EDID, HPD.
	false,								 // bEdidReplicate		- Enable/Disable Edid replication from primary output to input
	true,								 // bHpdReplicate		- Enable/Disable Hot-Plug replication from primary output to input
	false								 // bHdcpRepeaterBit	- Set ‘false?for sink implementation. Set ‘true?for repeater implementation
};

UINT32 siiPlatformInit(void)
{
	Sii9777CallBackHandler = SiiEventCbFunc;
    sii9777Instance = Sii9777Create(hwId, Sii9777CallBackHandler, &config9777);
	return (UINT32)sii9777Instance;
}
UINT32 siiPlatformEndrun(void)
{
	Sii9777Delete(sii9777Instance);
	return (UINT32)sii9777Instance;
}


void vHost9777Handle(void)
{
   Sii9777Handle(sii9777Instance);
}
UINT8 getDualLinkStatus(void)
{
	return dualLinkStatus?1:0;
}
UINT8 u1HostSii9777RxPortSet(UINT8 *port)
{
	Sii9777RxPort_t sii9777rxPort;
	UINT8 u1Hpd = 0;
	switch(*port)
	{
		case 0:
			sii9777rxPort = SII9777_RX_PORT__0;
			break;
		case 1:
			sii9777rxPort = SII9777_RX_PORT__1;
			break;
#ifdef SII9777_REF_ES1
		case 2:
			sii9777rxPort = SII9777_RX_PORT__2;
			break;
		case 3:
			sii9777rxPort = SII9777_RX_PORT__3;
			break;
#endif
		default :
		sii9777rxPort = SII9777_RX_PORT__0;
		break;
	}
	u1CurrentRxPort = *port;
	Sii9777InputSelectSet(sii9777Instance,&sii9777rxPort);
	if((INAVLID_SII977_RX_PORT == u1CurrentSilRxPort) && (SII9777_RX_PORT__0 == sii9777rxPort))
	{
		u1HostHpdSet(SII9777_RX_PORT__0,&u1Hpd);
		fgManualHpdLow = TRUE;
		HAL_GetTime(&tHpdLowTime);
		printf("SII9777:Set HPD low!\n");
	}
	return SIL9777_SUCCESS;
}
UINT8 u1HostSii9777RxPortGet(UINT8 *port)
{
	Sii9777RxPort_t rxPort;
	Sii9777InputSelectGet(sii9777Instance,&rxPort);
	*port = (UINT8)rxPort;
	return SIL9777_SUCCESS;
}
UINT8 u1HostSii9777GetCurrentRxPort(void)
{
	return u1CurrentRxPort;
}
UINT8 u1HostSii9777TxPortSet(UINT8 *port)
{
	Sii9777TxPort_t sii9777TxPort;
	switch(*port)
	{
		case 0:
			sii9777TxPort = SII9777_TX_PORT__0;
			break;
		case 1:
			sii9777TxPort = SII9777_TX_PORT__1;
			break;
		case 2:
			sii9777TxPort = SII9777_TX_PORT__2;
			break;
		default :
			sii9777TxPort = SII9777_TX_PORT__1;
			break;
	}
	Sii9777PrimTxPortSet(sii9777Instance,&sii9777TxPort);
	return SIL9777_SUCCESS;
}
UINT8  u1HostSii9777TxPortGet(UINT8 *port)
{
	Sii9777TxPort_t txPort;
	Sii9777PrimTxPortGet(sii9777Instance,&txPort);
	*port = (UINT8)txPort;
	return SIL9777_SUCCESS;
}



UINT8 u1HostHpdSet(UINT8 port,UINT8 *hpdSet)
{
	Sii9777RxPort_t sii9777rxPort;
	bool_t siiHpdSet;
	siiHpdSet = (*hpdSet)?1:0;
	switch(port)
	{
		case 0:
			sii9777rxPort = SII9777_RX_PORT__0;
			break;
		case 1:
			sii9777rxPort = SII9777_RX_PORT__1;
			break;
#ifdef SII9777_REF_ES1
		case 2:
			sii9777rxPort = SII9777_RX_PORT__2;
			break;
		case 3:
			sii9777rxPort = SII9777_RX_PORT__3;
			break;
#endif
		default :
		sii9777rxPort = SII9777_RX_PORT__0;
		break;
	}
	Sii9777HpdSet(sii9777Instance,sii9777rxPort,&siiHpdSet);
	return SIL9777_SUCCESS;
}
UINT8 u1HostHpdGet(UINT8 port,UINT8 *hpdGet)
{
	Sii9777RxPort_t sii9777rxPort;
	bool_t sii9777HpdStatus;
	switch(port)
	{
		case 0:
			sii9777rxPort = SII9777_RX_PORT__0;
			break;
		case 1:
			sii9777rxPort = SII9777_RX_PORT__1;
			break;
#ifdef SII9777_REF_ES1
		case 2:
			sii9777rxPort = SII9777_RX_PORT__2;
			break;
		case 3:
			sii9777rxPort = SII9777_RX_PORT__3;
			break;
#endif
		default :
		sii9777rxPort = SII9777_RX_PORT__0;
		break;
	}

	Sii9777HpdQuery(sii9777Instance,sii9777rxPort,&sii9777HpdStatus);
	(*hpdGet) = sii9777HpdStatus?1:0;
	return SIL9777_SUCCESS;
}
UINT8 u1HostSii9777HpdReplicateSet(UINT8 *u1Replicate)
{
	bool_t replicate = (*u1Replicate)?1:0;
	Sii9777HpdReplicateEnableSet(sii9777Instance,&replicate);
	return 1;
}
UINT8 u1HostSii9777HpdReplicateGet(UINT8 *u1Replicate)
{
	bool_t replicate;
	Sii9777HpdReplicateEnableGet(sii9777Instance,&replicate);
	(*u1Replicate) = replicate?1:0;
	return SIL9777_SUCCESS;
}

UINT8 u1HostSii9777DualLinkAutoSet(UINT8 *u1AutoSet)
{
	bool_t autoSet = (*u1AutoSet)?1:0;
	Sii9777DualLinkAutoEnableSet(sii9777Instance,&autoSet);
	return SIL9777_SUCCESS;
}
UINT8 u1HostSii9777DualLinkAutoGet(UINT8 *u1Autoget)
{
	bool_t autoSet = (*u1Autoget)?1:0;
	Sii9777DualLinkAutoEnableSet(sii9777Instance,&autoSet);
	*u1Autoget = autoSet?1:0;
	return SIL9777_SUCCESS;
}

UINT8 u1HostSii9777SplitModeSet(UINT8 *splitMode)
{
/*	Sii9777SplitMode_t localSplictMode = (Sii9777SplitMode_t)(*splitMode);
	Sii9777SplitModeSet(sii9777Instance,&localSplictMode);*/
	Sii9777DualLinkMode_t localSplictMode = (Sii9777DualLinkMode_t)(*splitMode);
	Sii9777DualLinkModeSet(sii9777Instance,&localSplictMode);
	return SIL9777_SUCCESS;

}
UINT8 u1HostSii9777SplitModeGet(UINT8 *splitMode)
{
/*	Sii9777SplitMode_t sii977splitMode;
	Sii9777SplitModeGet(sii9777Instance,&sii977splitMode);
	(*splitMode) = (UINT8)sii977splitMode;*/
	Sii9777DualLinkMode_t localSplictMode = (Sii9777DualLinkMode_t)(*splitMode);
	Sii9777DualLinkModeGet(sii9777Instance,&localSplictMode);
	return SIL9777_SUCCESS;

}

UINT8 u1HostSii9777DualLinkSet(UINT8 *dualLinkEn)
{
	bool_t localDualLink = (*dualLinkEn)?1:0;
	Sii9777DualLinkManualSet(sii9777Instance,&localDualLink);
	return SIL9777_SUCCESS;
}
UINT8 u1HostSii9777DualLinkGet(UINT8 *dualLinkEn)
{
	bool_t dualLinkEnable;
	Sii9777DualLinkManualGet(sii9777Instance,&dualLinkEnable);
	(*dualLinkEn) = (UINT8)dualLinkEnable;
	return SIL9777_SUCCESS;
}
UINT8 u1HostSii9777DualLinkStatusGet(UINT8 *dualLinkStatusGet)
{
	bool_t sii9777dualLinkSta;
	Sii9777DualLinkQuery(sii9777Instance,&sii9777dualLinkSta);
	*dualLinkStatusGet = sii9777dualLinkSta;
	return SIL9777_SUCCESS;
}

UINT8 u1HostSii9777GetFirmwareVersion(UINT32 *version)
{
	uint32_t sii9777version;
	SiiRetVal_t         retVal = 0;
	retVal = Sii9777FirmwareVersionQuery(sii9777Instance,&sii9777version);
	*version = sii9777version;
	if(retVal == 0)
	{
		return SIL9777_SUCCESS;
	}
	else
	{
		return SIL9777_ERROR;
	}
}
UINT8 u1HostSii9777EdidReplicateSet(UINT8 *ReplicatedEn)
{
	bool_t bReplicatedEn = (*ReplicatedEn)?1:0;
	Sii9777EdidReplicateEnableSet(sii9777Instance,&bReplicatedEn);
	return SIL9777_SUCCESS;
}
UINT8 u1HostSii9777EdidReplicateGet(UINT8 *ReplicatedEn)
{
	bool_t bReplicatedEn;
	Sii9777EdidReplicateEnableGet(sii9777Instance,&bReplicatedEn);
	*ReplicatedEn = (UINT8)bReplicatedEn;
	return SIL9777_SUCCESS;
}
UINT8 u1HostSii9777EdidSet(UINT8 port,UINT8 *pEdidData)
{
	Sii9777EdidSet(sii9777Instance,port,0,pEdidData,256);
	return SIL9777_SUCCESS;
}
UINT8 u1HostSii9777EdidGet(UINT8 port,UINT8 *pEdidData)
{
	Sii9777EdidGet(sii9777Instance,port,0,pEdidData,256);
	return SIL9777_SUCCESS;
}
UINT8 u1HostSii9777VideoTimingGet(HostSii9777VideoTiming_t *HostSii9777Timing)
{
	Sii9777VideoTiming_t sii9777Timing;
	//Sii9777VideoTimingStatusGet(sii9777Instance,&sii9777Timing);
	Sii9777VideoTimingQuery(sii9777Instance,&sii9777Timing);
	HostSii9777Timing->hActive = sii9777Timing.hActive;
	HostSii9777Timing->hFrontPorch = sii9777Timing.hFrontPorch;
	HostSii9777Timing->hSync = sii9777Timing.hSync;
	HostSii9777Timing->hTotal = sii9777Timing.hTotal;
	HostSii9777Timing->interlaced = sii9777Timing.interlaced?1:0;
	HostSii9777Timing->pixelFreq = sii9777Timing.pixelFreq;
	HostSii9777Timing->posHsync = sii9777Timing.posHsync;
	HostSii9777Timing->posVsync = sii9777Timing.posVsync;
	HostSii9777Timing->vActive = sii9777Timing.vActive;
	HostSii9777Timing->vFrontPorch = sii9777Timing.vFrontPorch;
	HostSii9777Timing->vSync =  sii9777Timing.vSync;
	HostSii9777Timing->vTotal = sii9777Timing.vTotal;
	return SIL9777_SUCCESS;
}



UINT8 u1HostSii9777ProductIdStatusGet(UINT32 *ProductId)
{
	uint32_t Sii9777ProductID;
	//Sii9777ProductIdStatusGet(sii9777Instance,&Sii9777ProductID);
	Sii9777ProductIdQuery(sii9777Instance,&Sii9777ProductID);
	(*ProductId) = Sii9777ProductID;
	return SIL9777_SUCCESS;
}
UINT8 u1HostSii9777ChipRevisionStatusGet(UINT32 *chipVer)
{
	uint32_t chipVersion;
	Sii9777ChipRevisionQuery(sii9777Instance,&chipVersion);
	*chipVer = chipVersion;
	return SIL9777_SUCCESS;
}
UINT8 u1HostSii9777ChipIdStatusGet(UINT32 *chipIDnum)
{
	uint32_t chipID;
	Sii9777ChipIdQuery(sii9777Instance,&chipID);
	*chipIDnum = chipID;
	return SIL9777_SUCCESS;
}

UINT8 u1HostSii9777FirmwareTimeStampStatusGet(UINT32 *timeStampGet)
{
	uint32_t timeStamp;
	Sii9777FirmwareVersionQuery(sii9777Instance,&timeStamp);
	(*timeStampGet) = timeStamp;
	return SIL9777_SUCCESS;
}

UINT8 u1HostSii9777BootStatusGet(UINT8 *bootStatus)
{
	Sii9777BootStat_t sii9777BootSta;
	Sii9777BootStatusQuery(sii9777Instance,&sii9777BootSta);
	(*bootStatus) = sii9777BootSta;
	return SIL9777_SUCCESS;
}


UINT8 u1HostSii9777AvLinkStatusGet(UINT8 *avLinkStatusGet)
{
	Sii9777AvLink_t avLinkStatus;
	Sii9777AvLinkQuery(sii9777Instance,&avLinkStatus);
	(*avLinkStatusGet) =  avLinkStatus;
	return SIL9777_SUCCESS;
}

UINT8 u1HostSii9777HdcpStatusGet(UINT8 *hpdStaGet)
{
	Sii9777HdcpStatus_t hpdStatus;
	Sii9777HdcpStatusQuery(sii9777Instance,&hpdStatus);
	(*hpdStaGet) = hpdStatus;
	return SIL9777_SUCCESS;
}
UINT8 u1HostSii9777AvMuteStatusGet(UINT8 *avMuteStatusGet)
{
	bool_t avMuteStatus;
	Sii9777AvMuteQuery(sii9777Instance,&avMuteStatus);
	(*avMuteStatusGet) = avMuteStatus;
	return SIL9777_SUCCESS;
}
UINT8 u1HostSii9777Plus5vStatusGet(UINT8 port,UINT8 *Rx5VStatus)
{
	UINT32 Ret = 0;

	bool_t rx5VStatus = false;
	Sii9777RxPort_t rxPort = port;
	Ret = Sii9777Plus5vQuery(sii9777Instance,rxPort,&rx5VStatus);
	*Rx5VStatus = rx5VStatus;
	return SIL9777_SUCCESS;
}

static UINT8 port5VStatus[4];
UINT8 GetHdmi4KModelPort5VStatus(UINT8 port)
{
	if(port >= 4)
	{
		port = 0;
	}
	return port5VStatus[port]?1:0;
}
UINT8 updateHdmi4KModelPort5VStatus(void)
{
	UINT8 port = 0;
	for(port=0;port<4;port++)
	{
		u1HostSii9777Plus5vStatusGet(port,&port5VStatus[port]);
	}

    return 0;
}


UINT8 u1HostSii9777VideoFmtStatusGet(HostSii9777VideoFormat_t *vdoFormatGet)
{
	Sii9777VideoFmt_t videoFormat;
	Sii9777Data_t dataValid;
	dataValid = Sii9777VideoFormatQuery(sii9777Instance,&videoFormat);
	if(dataValid == SII9777_DATA__SUCCESS)
	{
		vdoFormatGet->ActiveAR = videoFormat.activeAR;
		vdoFormatGet->bitDepth = videoFormat.pixFmt.bitDepth;
		vdoFormatGet->chromaSample = videoFormat.pixFmt.crSmpl;
		vdoFormatGet->colorSpace = videoFormat.pixFmt.clrFmt;
		vdoFormatGet->contentType = videoFormat.contentType;
		vdoFormatGet->horizBarInfo.pixNumEndOfLeftBar = videoFormat.horizBarInfo.pixNumEndOfLeftBar;
		vdoFormatGet->horizBarInfo.pixNumStartOfRightBar = videoFormat.horizBarInfo.pixNumStartOfRightBar;
		vdoFormatGet->isActiveFmt = videoFormat.isActiveFormat;
		vdoFormatGet->isITcontent = videoFormat.isITContent;
		vdoFormatGet->isHorizBarInfoValid = videoFormat.isHorizBarInfoValid;
		vdoFormatGet->isVertBarInfoValid = videoFormat.isVertBarInfoValid;
		vdoFormatGet->pictureAR = videoFormat.pictureAR;
		vdoFormatGet->pictureScaling = videoFormat.picScaling;
		vdoFormatGet->pixelRepetition = videoFormat.pixelRepetition;
		vdoFormatGet->scanInfo = videoFormat.scanInfo;
		vdoFormatGet->vertBarInfo.lineNumEndOfTopBar = videoFormat.vertBarInfo.lineNumEndOfTopBar;
		vdoFormatGet->vertBarInfo.lineNumStartOfBottomBar = videoFormat.vertBarInfo.lineNumStartOfBottomBar;
		vdoFormatGet->video3Dmode = videoFormat.mode3D;
		vdoFormatGet->videoVid = videoFormat.vidRes;
	}
	return (dataValid == SII9777_DATA__SUCCESS)?SIL9777_SUCCESS:SIL9777_ERROR;
}

UINT8 u1HostSii9777AudioFmtStatusGet(void)
{
	return SIL9777_SUCCESS;
}
//void Sii9777TmdsEnableSet( SiiInst_t inst, Sii9777TxPort_t port, bool_t* bTmds );
//void Sii9777TmdsEnableGet( SiiInst_t inst, Sii9777TxPort_t port, bool_t* bTmds );
UINT8 u1HostSii9777TmdsEnableSet(UINT8 txPort, UINT8 *enable)
{
	bool_t tmdsEnable;
	Sii9777TxPort_t sii9777txPort;
	tmdsEnable = *enable;
	switch(txPort)
		{
			case 0:
				sii9777txPort = SII9777_TX_PORT__0;
				break;
			case 1:
				sii9777txPort = SII9777_TX_PORT__1;
				break;
			case 2:
				sii9777txPort = SII9777_TX_PORT__2;
				break;
			default:
				sii9777txPort = SII9777_TX_PORT__1;
				break;
		}
	Sii9777TmdsEnableSet(sii9777Instance,sii9777txPort,&tmdsEnable);
	return SIL9777_SUCCESS;
}
UINT8 u1HostSii9777TmdsEnableGet(UINT8 txPort, UINT8 *enable)
{
	bool_t tmdsEnable;
	Sii9777TxPort_t sii9777txPort;
	switch(txPort)
		{
			case 0:
				sii9777txPort = SII9777_TX_PORT__0;
				break;
			case 1:
				sii9777txPort = SII9777_TX_PORT__1;
				break;
			case 2:
				sii9777txPort = SII9777_TX_PORT__2;
				break;
			default:
				sii9777txPort = SII9777_TX_PORT__1;
				break;
		}
	Sii9777TmdsEnableGet(sii9777Instance,sii9777txPort,&tmdsEnable);
	*enable = tmdsEnable?1:0;
	return SIL9777_SUCCESS;
}
UINT8 u1Host9777TmdsSwingLevelGet(UINT8 txPort,UINT8 *tmdsSwingLevel)
{
	Sii9777TxPort_t switchTxPort = txPort;
	SiiRetVal_t retVal;
	retVal = Sii9777TmdsSwingLevelGet(sii9777Instance, switchTxPort, tmdsSwingLevel);
	return SIL9777_SUCCESS;
}
UINT8 u1Host9777TmdsSwingLevelSet(UINT8 txPort,UINT8 *tmdsSwingLevel)
{
	Sii9777TxPort_t switchTxPort = txPort;
	SiiRetVal_t retVal;
	retVal = Sii9777TmdsSwingLevelSet(sii9777Instance, switchTxPort, tmdsSwingLevel);
	return SIL9777_SUCCESS;
}
UINT8 u1Host9777TmdsPinSwapSet(UINT8 txPort,UINT8 *pinSwapOn)
{
	Sii9777TxPort_t switchRxPort = txPort;
	SiiRetVal_t retVal;
	bool_t swapOn = (*pinSwapOn);
	retVal = Sii9777TmdsPinSwapSet(sii9777Instance, switchRxPort, &swapOn);
	return SIL9777_SUCCESS;
}
UINT8 u1Host9777TmdsPinSwapGet(UINT8 rxPort,UINT8 *pinSwapOn)
{
	Sii9777RxPort_t switchRxPort = rxPort;
	SiiRetVal_t retVal;
	bool_t swapOn;
	retVal = Sii9777TmdsPinSwapGet(sii9777Instance, switchRxPort, &swapOn);
	(*pinSwapOn) = swapOn;
	return SIL9777_SUCCESS;
}
UINT8 u1Host9777ArcGet(UINT8 *enable)
{
	SiiRetVal_t u4RetVal;
	bool_t arcOn;
	u4RetVal = Sii9777ArcEnableGet(sii9777Instance, &arcOn);
	(*enable) = arcOn;
	return SIL9777_SUCCESS;
}
UINT8 u1Host9777ArcSet(UINT8 *enable)
{
	SiiRetVal_t u4RetVal;
	bool_t arcOn = *enable;
	u4RetVal = Sii9777ArcEnableSet(sii9777Instance, &arcOn);
	u1ArcEnable = *enable;
	return SIL9777_SUCCESS;
}
UINT8 u1Host9777HdcpBksvRxidListSet(SwitchBksv_t *switchBksv,UINT8 length)
{
	Sii9777HdcpBksvRxidListSet(sii9777Instance,(Sii9777HdcpKsv_t*)switchBksv,length);
	return SIL9777_SUCCESS;
}
UINT8 u1Host9777HdcpBksvRxidListGet(SwitchBksv_t *switchBksv,UINT8 length)
{
	Sii9777HdcpBksvRxidListGet(sii9777Instance,(Sii9777HdcpKsv_t*)switchBksv,length);
	return SIL9777_SUCCESS;
}
UINT8 u1Host9777RxHdcpBksvOwnQuery(SwitchBksv_t *switchBksv)
{
	Sii9777RxHdcpBksvOwnQuery(sii9777Instance,(Sii9777HdcpKsv_t*)switchBksv);
	return SIL9777_SUCCESS;
}
UINT8 u1Host9777RxHdcpRxIdOwnQuery(SwitchBksv_t *switchBksv)
{
	Sii9777RxHdcpRxIdOwnQuery(sii9777Instance,(Sii9777HdcpKsv_t*)switchBksv);
	return SIL9777_SUCCESS;
}
UINT8 u1Host9777RxCdSenseQuery(UINT8 *cdsenseDectected)
{
	//SiiRetVal_t retVal;
	Sii9777CdSense_t cdsenseIn = SII9777_CD_SENSE__NONE;
	Sii9777RxCdSenseQuery(sii9777Instance, &cdsenseIn);
	*cdsenseDectected = (cdsenseIn == SII9777_CD_SENSE__MHL_CABLE)?1:0;
	return SIL9777_SUCCESS;
}
UINT8 u1Host9777CbusModeQuery(UINT8 *cbusConected)
{
	Sii9777CbusMode_t cbusMode = SII9777_CBUS_MODE__NONE;
	Sii9777CbusModeQuery(sii9777Instance,&cbusMode);
	if(cbusMode == SII9777_CBUS_MODE__NONE)
	{
		*cbusConected = 0;
	}
	else
	{
		*cbusConected = 1;
	}
	return SIL9777_SUCCESS;
}
UINT8 u1Host9777GetCbusMode(UINT8 *getCbusMode)
{
	Sii9777CbusMode_t cbusMode = SII9777_CBUS_MODE__NONE;
	Sii9777CbusModeQuery(sii9777Instance,&cbusMode);
	*getCbusMode = cbusMode;
	return SIL9777_SUCCESS;
}
UINT8 u1Host9777GetDeviceRole(UINT8 *deviceRole)
{
	//Sii9777CbusLocalXDevcapGet(sii9777Instance,deviceRole,2,1);
	*deviceRole = cbusLocalXDev[2];
	return SIL9777_SUCCESS;
}
UINT8 u1Host9777GetSupportFeature(UINT8 *supportFeature)
{
	*supportFeature = cbusLocalDev[0xa];
	return SIL9777_SUCCESS;
}

UINT8 u1Host9777CbusLocalDevcapSet(UINT8 offset,UINT8 value)
{
	Sii9777CbusLocalDevcapSet(sii9777Instance,&value,offset,1);
	return SIL9777_SUCCESS;
}
UINT8 u1Host9777CbusLocalDevcapGet(UINT8 offset,UINT8 *pValue,UINT8 length)
{
	Sii9777CbusLocalDevcapGet(sii9777Instance,pValue,offset,length);
	return SIL9777_SUCCESS;
}
UINT8 u1Host9777CbusLocalXDevcapSet(UINT8 offset,UINT8 value)
{
	Sii9777CbusLocalXDevcapSet(sii9777Instance,&value,offset,1);
	return SIL9777_SUCCESS;
}
UINT8 u1Host9777CbusLocalXDevcapGet(UINT8 offset,UINT8 *pValue,UINT8 length)
{
	Sii9777CbusLocalXDevcapGet(sii9777Instance,pValue,offset,length);
	return SIL9777_SUCCESS;
}

extern void x_thread_delay(UINT32 u4Ms);
extern INT16 GPIO_GetIn(INT16 i4GpioNum);
static HANDLE_T phSii9777ThreadHdl;
void sEnableCallBackNotifications( Sii9777EventFlags_t eventFlagsMask )
{
    Sii9777EventFlagsMaskSet(sii9777Instance, &eventFlagsMask);
}

UINT8 u1Host9777EventFlagsMaskSet(UINT32 *eventMsk)
{
	Sii9777EventFlags_t eventFlagMsk = *eventMsk;
	Sii9777EventFlagsMaskSet(sii9777Instance,&eventFlagMsk);
	return SIL9777_SUCCESS;
}
UINT8 u1Host9777EventFlagsMaskGet(UINT32 *eventMsk)
{
	Sii9777EventFlags_t eventFlagMsk;
	Sii9777EventFlagsMaskGet(sii9777Instance,&eventFlagMsk);
	*eventMsk = eventFlagMsk;
	return SIL9777_SUCCESS;
}
void vHwGpio9777Reset(void)
{
	GPIO_SetOut(219,1);
	x_thread_delay(10);
	GPIO_SetOut(219,0);
}
void vHost9777Init(void)
{
	Sii9777BootStat_t bootStatus;
	UINT8 notUpdateFwOfBoston = 0;

	EEPROM_Read(0x10508,&notUpdateFwOfBoston,1);
	//notUpdateFwOfBoston = ((notUpdateFwOfBoston>>5)&0x1);
	/*
	readEmmcBostonData(&notUpdateFwOfBoston,14,1);
	*/
	siiPlatformInit();
	sEnableCallBackNotifications(SII9777_EVENT_FLAGS__ALL);
	bootStatus = _tHostSii9777BootStatusQuery(20000);
	if(SII9777_BOOT_STAT__SUCCESS == bootStatus)
	{
		UINT8 modelLevel = 0;
		EEPROM_Read(0x10012,&modelLevel,1);
		if(modelLevel >=3)
		{
			u1Boston_Mhl_port = 2;
		}
		else
		{
			u1Boston_Mhl_port = 1;
		}
		vHost9777CbusInit();
		{
			UINT32 version;
			if(SIL9777_SUCCESS == u1HostSii9777GetFirmwareVersion(&version))
			{
				if(version < getFileVersionInfo())
				{
					printf("version older than bin file , start to update........\n");
					if(notUpdateFwOfBoston == 0)
					FirmwareUpdateRequest();
				}
			}
		}
		{
			UINT8 edidUpdateRequest = 0;
			readEmmcBostonData(&edidUpdateRequest,15,1);
			if(edidUpdateRequest == 1)
			{
				if(notUpdateFwOfBoston == 0)
				{
					FirmwareUpdateRequest();
					edidUpdateRequest = 0;
					writeEmmcBostonData(&edidUpdateRequest,15,1);
				}
			}
		}
		updateHdmi4KModelPort5VStatus();
	}
	else
	{
		printf("boston init failure , start to update........\n");
		if(notUpdateFwOfBoston == 0)
		FirmwareUpdateRequest();
	}
	sEnableCallBackNotifications(SII9777_EVENT_FLAGS__ALL);
	updateHdmi4KModelPort5VStatus();
}
void vSii9777ResumeInit(void)
{

	UINT8 modelLevel = 0;
	EEPROM_Read(0x10012,&modelLevel,1);
	if(modelLevel >=3)
	{
		u1Boston_Mhl_port = 2;
	}
	else
	{
		u1Boston_Mhl_port = 1;
	}
	vHost9777CbusInit();
	sEnableCallBackNotifications(SII9777_EVENT_FLAGS__ALL);
	updateHdmi4KModelPort5VStatus();
	u1Host9777ArcSet(&u1ArcEnable);
}
static void _Sii9777_Thread( void * pvArgs )
{
	vHost9777Init();
#ifdef CUSTOM_SELF_DIAG_ENABLE
	SelfDiagGoingToStartBostonCheck();
#endif
	while(1)
	{
		x_thread_delay(20);
		if(fgManualHpdLow)
		{
			UINT32 u4HpdDeltaMs = 0;
			UINT8 u1Hpd = 1;
			HAL_GetTime(&tHpdTmpTime);
			HAL_GetDeltaTime(&tHpdDeltaTime,&tHpdLowTime,&tHpdTmpTime);
			u4HpdDeltaMs = (tHpdDeltaTime.u4Seconds * 1000) + (tHpdDeltaTime.u4Micros/1000);
			if(u4HpdDeltaMs >= 500)
			{
				u1HostHpdSet(SII9777_RX_PORT__0,&u1Hpd);
				fgManualHpdLow = FALSE;
				printf("SII9777:Set HPD high!\n");
			}
		}
		if(GPIO_GetIn(61) == 0)
		{
			vHost9777Handle();
		}
	}
}
UINT8 sii9777ThreadCreated = 0;
void vCreateSii9777Thread(void)
{
	if(sii9777ThreadCreated == 0)
	{
		sii9777ThreadCreated = 1;
		VERIFY(x_thread_create(&phSii9777ThreadHdl,
				"SII9777Thread", 2048,	60, _Sii9777_Thread, 0, NULL) == OSR_OK);
		printf("create SII9777 thread\n");
	}
	else
	{
		printf("SII9777 thread already exist\n");
	}
}
void vHost9777CbusInit(void)
{

#ifdef CC_PANEL_FROM_FLASH
	UINT32 localPtiInfo = 0;
	UINT32 localPtiColorSpace = 0;
	extern UINT32 FlashPanel_GetControlWord3(void);
	localPtiInfo = FlashPanel_GetControlWord3();
	localPtiColorSpace = (localPtiInfo & 0x3);
	if(localPtiColorSpace == 0)
	{
		cbusLocalDev[0xa] = 0x07;
	}
	else
	{
		cbusLocalDev[0xa] = 0x27;
	}
#endif

	Sii9777CbusMode_t cbusMode = SII9777_CBUS_MODE__NONE;
	Sii9777CbusLocalDevcapSet(sii9777Instance,cbusLocalDev,0,16);
	Sii9777CbusLocalXDevcapSet(sii9777Instance,cbusLocalXDev,0,4);
	Sii9777CbusModeQuery(sii9777Instance,&cbusMode);
	if(cbusMode!=SII9777_CBUS_MODE__NONE)
	{
		Sii9777CbusDcapChgSend(sii9777Instance);
	}
}
UINT8 u1Host9777CbusBurstSend(CBUS_MSG_DESCRIPTION_T *burstdata)
{
	Sii9777CbusBurstSend(sii9777Instance,burstdata->Data,burstdata->offset,burstdata->Size);
	return 1;
}
UINT8 u1Host9777CbusMscMsgSend(CBUS_MSC_MSG_COMMAND_T *msg)
{
	Sii9777MscCmd_t mscCommand;
	mscCommand.subCmd = msg->opcode;
	mscCommand.codeValue = msg->data;
	Sii9777CbusMscMsgSend(sii9777Instance,&mscCommand);
	return 1;
}
void vHost9777_pm_Resume(void)
{
	u1CurrentSilRxPort = INAVLID_SII977_RX_PORT;
	preAvlinkStatus = SII9777_AV_LINK__NONE;
	printf("boston switch resume init......test_remove_some_functions\n");
        _tHostSii9777BootStatusQuery(20000);
	vSii9777ResumeInit();
}
