//
// 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>

#define RETRY_COUNT     1 // 3
#define FAST_CALL       FALSE

static I2C_FASTCALL FastCall;

BOOL ReadI2C_Camera(HANDLE hI2C, PBYTE pWData, DWORD dwWDatas, BOOL bStop, PBYTE pRData, DWORD dwRDatas);

HANDLE
OpenI2C(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"[XXX] I2C OPEN : %s ERROR(%d) \r\n", lpGroupName, GetLastError()));
	    hI2C = NULL;
	}
    else
    {
        DBGMSG(CAMC_FUNC && CAMC_USR2, (L"[XXX] I2C OPEN : %s SUCCESS\r\n", lpGroupName));
    }

	return hI2C;
}

BOOL
InitI2C(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"[XXX] IOCTL_I2C_INIT is failed(Error %d) \r\n", GetLastError()));
		return FALSE;
	}

	DBGMSG(CAMC_FUNC && CAMC_USR2, (L"[XXX] 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"[XXX] IOCTL_I2C_GET_FASTCALL is failed(Error %d) \r\n", GetLastError()));
		return FALSE;
	}

    DBGMSG(CAMC_FUNC && CAMC_USR2, (L"[XXX] FastCall : Context : %X, Read Function :  %X Write Function : %X\r\n", FastCall.Context, FastCall.I2CRead, FastCall.I2CWrite));
#endif

	return TRUE;
}

BOOL
WriteI2C_Camera(HANDLE hI2C, PBYTE pWData, DWORD dwWDatas)
{
    BOOL bWrite = TRUE;
    DWORD dwTry;
    I2C_WRITE_DESC I2CWriteDesc;

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

    for(dwTry=0; dwTry<RETRY_COUNT; ++dwTry)
    {
//    	RETAILMSG(1, (TEXT(".")));
#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"[XXX] IOCTL_I2C_GENERAL_WRITE ERROR: %u \r\n", GetLastError()));
            if(dwTry == (RETRY_COUNT-1)) bWrite = FALSE;
            continue;
        }

        break;
    }



	return bWrite;
}

BOOL
ReadI2C_Camera(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"[XXX] 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"[XXX] IOCTL_I2C_GENERAL_READ ERROR: %u \r\n", GetLastError()));
    			if(dwTry == (RETRY_COUNT-1)) bRead = FALSE;
                continue;
    		}
    	}

        break;
    }

	return bRead;
}




