//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
////////////////////////////////////////////////////////////////////////////////
#include <windows.h>
#include <BSP.h>
#include <iic.h>

#if __cplusplus
	extern "C"
	{
#endif


#define RETRY_COUNT     3
#define FAST_CALL       FALSE
#define DEBUG_MSG_ON    TRUE

static I2C_FASTCALL FastCall;

HANDLE
Open_HDCP_I2C(LPWSTR lpGroupName)
{
    HANDLE hI2C;
    
	hI2C = CreateFile(lpGroupName,
	                  GENERIC_READ|GENERIC_WRITE,
	                  FILE_SHARE_READ|FILE_SHARE_WRITE,
	                  NULL, OPEN_EXISTING, 0, 0);
	               
	if(hI2C == INVALID_HANDLE_VALUE) 
	{
	    ERRMSG((L"[Open_HDCP_I2C] I2C OPEN : %s ERROR(%d) \r\n", lpGroupName, GetLastError()));
	    hI2C = NULL;
	}
    else
    {
        DBGMSG(DEBUG_MSG_ON, (L"[Open_HDCP_I2C] I2C OPEN : %s SUCCESS\r\n", lpGroupName));
    }

	return hI2C;
}

BOOL
Init_HDCP_I2C(HANDLE hI2C, WORD wSlaveAddr, DWORD dwSpead)
{
	I2C_INIT_DESC I2CInitDesc;
    
	I2CInitDesc.IN_wSlaveAddr 	    = wSlaveAddr; 
	I2CInitDesc.IN_dwClockSpeed     = dwSpead;
	I2CInitDesc.OUT_dwActualSpeed   = 0;

    if(!DeviceIoControl(hI2C,
	                    IOCTL_I2C_INIT, 
	                    &I2CInitDesc, sizeof(I2CInitDesc), 
	                    NULL, 0,
	                    NULL, NULL) ) 
	{
		ERRMSG((L"[Init_HDCP_I2C] IOCTL_I2C_INIT is failed(Error %d) \r\n", GetLastError()));
		return FALSE;
	} 

	DBGMSG(DEBUG_MSG_ON, (L"[Init_HDCP_I2C] ACTUAL I2C CLCOK SPEAD : %d Khz\r\n", I2CInitDesc.OUT_dwActualSpeed));

#if FAST_CALL
	if (!DeviceIoControl(hI2C,
	                     IOCTL_I2C_GET_FASTCALL, 
	                     NULL, 0, 
	                     &FastCall, sizeof(I2C_FASTCALL),
	                     NULL, NULL) ) 
    {
		ERRMSG((L"[Init_HDCP_I2C] IOCTL_I2C_GET_FASTCALL is failed(Error %d) \r\n", GetLastError()));
		return FALSE;
	} 

    DBGMSG(DEBUG_MSG_ON, (L"[Init_HDCP_I2C] FastCall : Context : %X, Read Function :  %X Write Function : %X\r\n", FastCall.Context, FastCall.I2CRead, FastCall.I2CWrite));
#endif
    
	return TRUE;
}

BOOL
Write_HDCP_I2C(HANDLE hI2C, PBYTE pWData, DWORD dwWDatas, BOOL bStop)
{
    BOOL bWrite = TRUE;
    DWORD dwTry;
    I2C_WRITE_DESC I2CWriteDesc;
    
	I2CWriteDesc.IO_pbtData = pWData;
	I2CWriteDesc.IN_dwData  = dwWDatas;
	I2CWriteDesc.IN_bStop   = bStop;

    for(dwTry=0; dwTry<RETRY_COUNT; ++dwTry)
    {
#if FAST_CALL
        if(!FastCall.I2CWrite(FastCall.Context, &I2CWriteDesc))
#else
    	if(!DeviceIoControl(hI2C,
    	                    IOCTL_I2C_GENERAL_WRITE, 
    	                    &I2CWriteDesc, sizeof(I2C_WRITE_DESC), 
    	                    NULL, 0,
    	                    NULL, NULL)) 
#endif
        {
            ERRMSG((L"[Write_HDCP_I2C] IOCTL_I2C_GENERAL_WRITE ERROR: %u \r\n", GetLastError()));
            if(dwTry == (RETRY_COUNT-1)) bWrite = FALSE;
            continue;
        }

        break;
    }


	return bWrite;
}

BOOL
Read_HDCP_I2C(HANDLE hI2C, PBYTE pWData, DWORD dwWDatas, BOOL bStop, PBYTE pRData, DWORD dwRDatas)
{
	BOOL bRead = TRUE;
    DWORD dwTry;
	I2C_WRITE_DESC I2CWriteDesc;
    I2C_READ_DESC I2CReadDesc;

	I2CWriteDesc.IO_pbtData = pWData;
	I2CWriteDesc.IN_dwData  = dwWDatas;
	I2CWriteDesc.IN_bStop   = bStop;

    for(dwTry=0; dwTry<RETRY_COUNT; ++dwTry)
    {
#if FAST_CALL
        if(!FastCall.I2CWrite(FastCall.Context, &I2CWriteDesc))
#else
    	if (!DeviceIoControl(hI2C,
    	                     IOCTL_I2C_GENERAL_WRITE, 
    	                     &I2CWriteDesc, sizeof(I2C_WRITE_DESC), 
    	                     NULL, 0,
    	                     NULL, NULL)) 
#endif
    	{
    		ERRMSG((L"[Read_HDCP_I2C] IOCTL_I2C_GENERAL_WRITE ERROR: %u \r\n", GetLastError()));
    		if(dwTry == (RETRY_COUNT-1)) bRead = FALSE;
            continue;
    	} 
    	else
    	{
    		I2CReadDesc.IO_pbtData 		= pRData;
    		I2CReadDesc.IN_dwData 		= dwRDatas;
    		I2CReadDesc.IN_bStop		= TRUE;

#if FAST_CALL
            if(!FastCall.I2CRead(FastCall.Context, &I2CReadDesc))
#else
    		if (!DeviceIoControl(hI2C,
    		                     IOCTL_I2C_GENERAL_READ, 
    		                     &I2CReadDesc, sizeof(I2C_READ_DESC), 
    		                     NULL, 0,
    		                     NULL, NULL))
#endif
    		{
    			ERRMSG((L"[Read_HDCP_I2C] IOCTL_I2C_GENERAL_READ ERROR: %u \r\n", GetLastError()));
    			if(dwTry == (RETRY_COUNT-1)) bRead = FALSE;
                continue;
    		} 		
    	}

        break;
    }
    
	return bRead;
}


#if __cplusplus
	}
#endif



