
#include <windows.h>
//#include <ceddk.h>
#include <nkintr.h>
#include <oalintr.h>
#include <pm.h>
#include "pmplatform.h"
#include "Pkfuncs.h"
#include "s2440.h"


volatile IOPreg 	*s2440IOP = (IOPreg *)IOP_BASE;
volatile INTreg 	*s2440INT = (INTreg *)INT_BASE;

HANDLE KeyThread;
HANDLE KeyEvent;

BOOL mInitialized;
void Virtual_Alloc();						// Virtual allocation


DWORD UserKeyProcessThread(void);
BOOL InitInterruptThread();



DWORD UserKeyProcessThread(void)
{
	
	while(1)
	{
		WaitForSingleObject(KeyEvent, INFINITE);
		
		//EINT8 - K1 - VK_TAB - 0x09
		if(s2440IOP->rEINTMASK&1<<8)
		{
			RETAILMSG(1,(TEXT("UserKeyProcessThread Processing! -K1\r\n")));
			keybd_event(VK_TAB ,0x09, 0, 0);
			Sleep(30);
			keybd_event(VK_TAB ,0x09, KEYEVENTF_KEYUP, 0);
			InterruptDone(SYSINTR_USER_KEY);
		}

		//EINT11 - K2 - VK_UP - 0x26
		if(s2440IOP->rEINTMASK&1<<11)
		{
			RETAILMSG(1,(TEXT("UserKeyProcessThread Processing! -K2\r\n")));
			keybd_event(VK_UP ,0x26, 0, 0);
			Sleep(30);
			keybd_event(VK_UP ,0x26, KEYEVENTF_KEYUP, 0);
			InterruptDone(SYSINTR_USER_KEY);
			
		}

		//EINT13 - K3 - VK_RETURN - 0x0D
		if(s2440IOP->rEINTMASK&1<<13)
		{
			RETAILMSG(1,(TEXT("UserKeyProcessThread Processing! -K3\r\n")));
			keybd_event(VK_RETURN ,0x0D, 0, 0);
			Sleep(30);
			keybd_event(VK_RETURN ,0x0D, KEYEVENTF_KEYUP, 0);
			InterruptDone(SYSINTR_USER_KEY);
			
		}
				
		//EINT14 - K4 - VK_DOWN - 0x28
		if(s2440IOP->rEINTMASK&1<<14)
		{
			RETAILMSG(1,(TEXT("UserKeyProcessThread Processing! -K4\r\n")));
			keybd_event(VK_DOWN ,0x28, 0, 0);
			Sleep(30);
			keybd_event(VK_DOWN ,0x28, KEYEVENTF_KEYUP, 0);
			InterruptDone(SYSINTR_USER_KEY);
			
		}

		//EINT15 - K5 - VK_LEFT - 0x25
		if(s2440IOP->rEINTMASK&1<<15)
		{
			RETAILMSG(1,(TEXT("UserKeyProcessThread Processing! -K5\r\n")));
			keybd_event(VK_LEFT ,0x25, 0, 0);
			Sleep(30);
			keybd_event(VK_LEFT ,0x25, KEYEVENTF_KEYUP, 0);
			InterruptDone(SYSINTR_USER_KEY);
			
		}
		
		//EINT15 - K5 - VK_RIGHT - 0x27		
		if(s2440IOP->rEINTMASK&1<<19)
		{
			RETAILMSG(1,(TEXT("UserKeyProcessThread Processing! -K6\r\n")));
			keybd_event(VK_RIGHT ,0x27, 0, 0);
			Sleep(30);
			keybd_event(VK_RIGHT ,0x27, KEYEVENTF_KEYUP, 0);
			InterruptDone(SYSINTR_USER_KEY);
		}
	}
}



void Virtual_Alloc()
{

    // GPIO Virtual alloc
	s2440IOP = (volatile IOPreg *) VirtualAlloc(0,sizeof(IOPreg),MEM_RESERVE, PAGE_NOACCESS);
	if(s2440IOP == NULL) {
		RETAILMSG(1,(TEXT("For s2440IOP: VirtualAlloc failed!\r\n")));
	}
	else {
		if(!VirtualCopy((PVOID)s2440IOP,(PVOID)(IOP_BASE),sizeof(IOPreg),PAGE_READWRITE | PAGE_NOCACHE )) {
			RETAILMSG(1,(TEXT("For s2440IOP: VirtualCopy failed!\r\n")));
		}
	}
 

	// Interrupt Virtual alloc
	s2440INT = (volatile INTreg *) VirtualAlloc(0,sizeof(INTreg),MEM_RESERVE, PAGE_NOACCESS);
	if(s2440INT == NULL) {
		RETAILMSG(1,(TEXT("For s2440INT: VirtualAlloc failed!\r\n")));
	}
	else {
		if(!VirtualCopy((PVOID)s2440INT,(PVOID)(INT_BASE),sizeof(INTreg),PAGE_READWRITE | PAGE_NOCACHE )) {
			RETAILMSG(1,(TEXT("For s2440INT: VirtualCopy failed!\r\n")));
		}
	}
	
}


BOOL WINAPI  
DllEntry(HANDLE	hinstDLL, 
			DWORD dwReason, 
			LPVOID  Reserved/* lpvReserved */)
{
	switch(dwReason)
	{
	case DLL_PROCESS_ATTACH:
		DEBUGREGISTER((HINSTANCE)hinstDLL);
//		DEBUGMSG(ZONE_INIT,(TEXT("CAMERA: DLL_PROCESS_ATTACH\r\n")));
		//liudiping
		//RETAILMSG(1,(TEXT("CAMERA: DLL_PROCESS_ATTACH\r\n")));
		return TRUE;
	case DLL_THREAD_ATTACH:
//		DEBUGMSG(ZONE_THREAD,(TEXT("CAMERA: DLL_THREAD_ATTACH\r\n")));
		//RETAILMSG(1,(TEXT("CAMERA: DLL_THREAD_ATTACH\r\n")));
		break;
	case DLL_THREAD_DETACH:
//		DEBUGMSG(ZONE_THREAD,(TEXT("CAMERA: DLL_THREAD_DETACH\r\n")));
		break;
	case DLL_PROCESS_DETACH:
//		DEBUGMSG(ZONE_INIT,(TEXT("CAMERA: DLL_PROCESS_DETACH\r\n")));
		break;
#ifdef UNDER_CE
	case DLL_PROCESS_EXITING:
//		DEBUGMSG(ZONE_INIT,(TEXT("CAMERA: DLL_PROCESS_EXITING\r\n")));
		break;
	case DLL_SYSTEM_STARTED:
//		DEBUGMSG(ZONE_INIT,(TEXT("CAMERA: DLL_SYSTEM_STARTED\r\n")));
		break;
#endif
	}

	return TRUE;
}


BOOL KEY_Deinit(DWORD hDeviceContext)
{
	BOOL bRet = TRUE;
	
	RETAILMSG(1,(TEXT("USERKEY: KEY_Deinit\r\n")));

//	s2440INT->rINTMSK   |= BIT_EINT8_23;
	InterruptDisable(SYSINTR_USER_KEY);

	
	CloseHandle(KeyThread);
	
	VirtualFree((void*)s2440IOP, sizeof(IOPreg), MEM_RELEASE);
	VirtualFree((void*)s2440INT, sizeof(INTreg), MEM_RELEASE);

	return TRUE;
} 



BOOL InitInterruptThread()
{
	//s2440INT->rINTMSK   &= ~BIT_EINT8_23;
//	s2440IOP->rEINTMASK &= ~0x800;
	
	DWORD         threadID;                         // thread ID
	BOOL bSuccess;

    KeyEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    
    if (!KeyEvent)
    {
    	return FALSE;
    }

	bSuccess = InterruptInitialize(SYSINTR_USER_KEY, KeyEvent, NULL, 0);
    if (!bSuccess) 
    {
        RETAILMSG(1,(TEXT("Fail to initialize userkey interrupt event\r\n")));
        return FALSE;
    }    
	
    KeyThread = CreateThread(NULL,
                                 0,
                                 (LPTHREAD_START_ROUTINE)UserKeyProcessThread,
                                 0,
                                 0,
                                 &threadID);
    
    if (NULL == KeyThread ) {
    	RETAILMSG(1,(TEXT("Create Key Thread Fail\r\n")));
    }
	
	RETAILMSG(1,(_T("UserKey.DLL::InterruptThread Initialized.\r\n")));
	return TRUE;
}




BOOL KeyGpioInit()
{
	RETAILMSG(1,(TEXT("Key_Gpio_Setting----\r\n")));
	s2440IOP->rGPGCON  = (s2440IOP->rGPGCON  & ~(0x3 << 0x0)) | (0x2 << 0x0);	// GPG0 == EINT8
	s2440IOP->rEXTINT1 = (s2440IOP->rEXTINT1 & ~(0x7<< 0)) | (0x3 << 0);		// Falling-edge triggered.
	
	s2440IOP->rGPGCON  = (s2440IOP->rGPGCON  & ~(0x3 << 0x6)) | (0x2 << 0x6);	// GPG3 == EINT11
	s2440IOP->rEXTINT1 = (s2440IOP->rEXTINT1 & ~(0x7<< 12)) | (0x3 << 12);		// Falling-edge triggered.

	s2440IOP->rGPGCON  = (s2440IOP->rGPGCON  & ~(0x3 << 0x10)) | (0x2 << 0x10);	// GPG5 == EINT13
	s2440IOP->rEXTINT1 = (s2440IOP->rEXTINT1 & ~(0x7<< 20)) | (0x3 << 20);		// Falling-edge triggered.

	s2440IOP->rGPGCON  = (s2440IOP->rGPGCON  & ~(0x3 << 0x12)) | (0x2 << 0x12);	// GPG6 == EINT14
	s2440IOP->rEXTINT1 = (s2440IOP->rEXTINT1 & ~(0x7<< 24)) | (0x3 << 24);		// Falling-edge triggered.

	s2440IOP->rGPGCON  = (s2440IOP->rGPGCON  & ~(0x3 << 0x14)) | (0x2 << 0x14);	// GPG7 == EINT15
	s2440IOP->rEXTINT1 = (s2440IOP->rEXTINT1 & ~(0x7<< 28)) | (0x3 << 28);		// Falling-edge triggered.
	
	s2440IOP->rGPGCON  = (s2440IOP->rGPGCON  & ~(0x3 << 0x22)) | (0x2 << 0x22);	// GPG11 == EINT19
	s2440IOP->rEXTINT2 = (s2440IOP->rEXTINT2 & ~(0x7<< 12)) | (0x3 << 12);		// Falling-edge triggered.
	return TRUE;
}




DWORD KEY_Init(DWORD dwContext)
{
	
	RETAILMSG(1,(TEXT("KEY_Init----\r\n")));

	// 1. Virtual Alloc
	Virtual_Alloc();
	
	KeyGpioInit();
	
	if (!InitInterruptThread())
	{
        RETAILMSG(1,(TEXT("Fail to initialize userkey interrupt event\r\n")));
        return FALSE;
    }    
	
	
	mInitialized = TRUE;
	return TRUE;
}

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
BOOL KEY_IOControl(DWORD hOpenContext, 
				   DWORD dwCode, 
				   PBYTE pBufIn, 
				   DWORD dwLenIn, 
				   PBYTE pBufOut, 
				   DWORD dwLenOut, 
				   PDWORD pdwActualOut)
{
    
	RETAILMSG(1,(TEXT("KEY:Ioctl code = 0x%x\r\n"), dwCode));
	return TRUE;
} 

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
DWORD KEY_Open(DWORD hDeviceContext, DWORD AccessCode, DWORD ShareMode)
{
	RETAILMSG(1,(TEXT("USERKEY: KEY_Open\r\n")));
    RETAILMSG(1,(TEXT("USERKEY: KEY_Open---------\r\n")));
	RETAILMSG(1,(TEXT("USERKEY: KEY_Open----------\r\n")));
	RETAILMSG(1,(TEXT("USERKEY: KEY_Open-----------\r\n")));
	
	return TRUE;
} 

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
BOOL KEY_Close(DWORD hOpenContext)
{
	RETAILMSG(1,(TEXT("USERKEY: KEY_Close\r\n")));
	return TRUE;
} 

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void KEY_PowerDown(DWORD hDeviceContext)
{
	RETAILMSG(1,(TEXT("USERKEY: KEY_PowerDown\r\n")));
	
} 

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
void KEY_PowerUp(DWORD hDeviceContext)
{
	RETAILMSG(1,(TEXT("USERKEY: KEY_PowerUp\r\n")));
} 

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
DWORD KEY_Read(DWORD hOpenContext, LPVOID pBuffer, DWORD Count)
{
	RETAILMSG(1,(TEXT("USERKEY: KEY_Read\r\n")));
	return TRUE;
} 

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
DWORD KEY_Seek(DWORD hOpenContext, long Amount, DWORD Type)
{
	RETAILMSG(1,(TEXT("USERKEY: KEY_Seek\r\n")));
	return 0;
} 

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
DWORD KEY_Write(DWORD hOpenContext, LPCVOID pSourceBytes, DWORD NumberOfBytes)
{
	RETAILMSG(1,(TEXT("USERKEY: KEY_Write\r\n")));
	return 0;
}




