s3c2440kbd.cpp
上传用户:qiulin1960
上传日期:2013-10-16
资源大小:2844k
文件大小:13k
源码类别:

Windows CE

开发平台:

Windows_Unix

  1. /*++
  2. THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  3. ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  4. THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  5. PARTICULAR PURPOSE.
  6. Copyright (c) 2002. Samsung Electronics, co. ltd  All rights reserved.
  7. Module Name:  
  8. Abstract:
  9. This file implements the S3C2440 Keyboard function
  10. rev:
  11. 2002.4.4 : First S3C2410 version (kwangyoon LEE, kwangyoon@samsung.com)
  12. 2002.1.31 : CE.NET port (kwangyoon LEE, kwangyoon@samsung.com)
  13. Notes: 
  14. --*/
  15. #include <windows.h>
  16. #include <ceddk.h>
  17. #include <nkintr.h>
  18. #include <drv_glob.h>
  19. #undef ZONE_INIT
  20. #include <keybddbg.h>
  21. #include <keybddr.h>
  22. #include <keybdpdd.h>
  23. #include <keybdist.h>
  24. #include "s3c2440kbd.hpp"
  25. #include "S2440.h"
  26. // Pointer to device control registers
  27. volatile IOPreg *v_pIOPregs;
  28. volatile SSPreg *v_pSSPregs;
  29. // Pointer to driver globals area
  30. PDRIVER_GLOBALS v_pDriverGlobals;
  31. DWORD dwSysIntr_Keybd;
  32. // Scan code consts
  33. static const UINT8 scE0Extended = 0xe0;
  34. static const UINT8 scE1Extended = 0xe1;
  35. static const UINT8 scKeyUpMask = 0x80;
  36. UINT32
  37. ScanCodeToVKeyEx(
  38.         UINT32                  ScanCode,
  39.         KEY_STATE_FLAGS KeyStateFlags,
  40.         UINT32                  VKeyBuf[16],
  41.         UINT32                  ScanCodeBuf[16],
  42.         KEY_STATE_FLAGS KeyStateFlagsBuf[16]
  43.         );
  44. // There is really only one physical keyboard supported by the system.
  45. Ps2Keybd *v_pp2k;
  46. extern void ReadRegDWORD( LPCWSTR szKeyName, LPCWSTR szValueName, LPDWORD pdwValue );
  47. void WINAPI KeybdPdd_PowerHandler(BOOL bOff)
  48. {
  49. // DEBUGMSG(1, (TEXT("++KeybdPdd_PowerHandlerrn")));
  50. if (!bOff) { 
  51.    v_pp2k->KeybdPowerOn();
  52. }
  53. else {
  54.    v_pp2k->KeybdPowerOff();
  55. }
  56. // DEBUGMSG(1, (TEXT("--KeybdPdd_PowerHandlerrn")));
  57. return;
  58. }
  59. #define ONEBIT    0x1
  60. int putcToKBCTL(UCHAR c)
  61. {
  62. UINT i;
  63. // UINT rxbuf[10];
  64. // UINT  x;
  65.    v_pIOPregs->rGPBDAT &= ~(ONEBIT << 6);       //Set _SS signal to low (Slave Select)
  66. while((v_pSSPregs->rSPSTA1 & ONEBIT)==0); // wait while busy
  67. v_pSSPregs->rSPTDAT1 = c;                 // write left justified data
  68. while((v_pSSPregs->rSPSTA1 & ONEBIT)==0); // wait while busy
  69.    
  70.     v_pIOPregs->rGPBDAT |= (ONEBIT << 6);        //Set _SS signal to high (Slave Select)
  71. i = v_pSSPregs->rSPRDAT1;
  72. return(i);
  73. }
  74. void getsFromKBCTL(UINT8 *m, int cnt) {
  75. int i, j;
  76. volatile tmp = 1;
  77. for(j = 0; j < 3; j++)
  78. tmp += tmp;
  79. for(j = 0; j < 250 * 30; j++)
  80. tmp += tmp;
  81. for(i = 0; i < cnt; i++) {
  82. m[i] = putcToKBCTL(0xFF);
  83. for(j = 0; j < 400; j++)
  84. tmp+= tmp;
  85. }
  86. }
  87. void putsToKBCTL(UINT8 *m,  int cnt)
  88. {
  89. int i, j, x;
  90. volatile tmp = 1;
  91. for(j = 0; j < 3; j++)
  92. x = j;
  93. for(j = 0; j < 3; j++)
  94. tmp += tmp;
  95. for(j = 0; j < 250 * 30; j++)
  96. tmp += tmp;
  97. for(i = 0; i < cnt; i++) {
  98. j = putcToKBCTL(m[i]);
  99. for(j = 0; j < 400; j++)
  100. tmp+= tmp;
  101. for(j = 0; j < 400; j++)
  102. x = j;
  103.     }
  104. }
  105. char lrc(UINT8 *buffer, int count)
  106. {
  107.     char lrc;
  108.     int n;
  109.     lrc = buffer[0] ^ buffer[1];
  110.     for (n = 2; n < count; n++)
  111.     {
  112.         lrc ^= buffer[n];
  113.     }
  114.     if (lrc & 0x80)
  115.         lrc ^= 0xC0;
  116.     return lrc;
  117. }
  118. int USAR_WriteRegister(int reg, int data)
  119. {
  120.     UINT8 cmd_buffer[4];
  121.     cmd_buffer[0] = 0x1b; //USAR_PH_WR;
  122.     cmd_buffer[1] = (unsigned char)reg;
  123.     cmd_buffer[2] = (unsigned char)data;
  124.     cmd_buffer[3] = lrc((UINT8 *)cmd_buffer,3);
  125.     putsToKBCTL((UINT8 *)cmd_buffer,4);
  126.     return TRUE;
  127. }
  128. BOOL
  129. KeybdDriverInitializeAddresses(
  130. void
  131. )
  132. {
  133. bool RetValue = TRUE;
  134. DWORD dwIOBase;
  135. DWORD dwSSPBase;
  136. DEBUGMSG(1,(TEXT("++KeybdDriverInitializeAddressesrn")));
  137. ReadRegDWORD(TEXT("HARDWARE\DEVICEMAP\KEYBD"), _T("IOBase"), &dwIOBase );
  138. if(dwIOBase == 0) {
  139. DEBUGMSG(1, (TEXT("Can't fount registry entry : HARDWARE\DEVICEMAP\KEYBD\IOBasern")));
  140. goto error_return;
  141. }
  142. DEBUGMSG(1, (TEXT("HARDWARE\DEVICEMAP\KEYBD\IOBase:%xrn"), dwIOBase));
  143. ReadRegDWORD(TEXT("HARDWARE\DEVICEMAP\KEYBD"), _T("SSPBase"), &dwSSPBase );
  144. if(dwSSPBase == 0) {
  145. DEBUGMSG(1, (TEXT("Can't fount registry entry : HARDWARE\DEVICEMAP\KEYBD\SSPBasern")));
  146. goto error_return;
  147. }
  148. DEBUGMSG(1, (TEXT("HARDWARE\DEVICEMAP\KEYBD\SSPBase:%xrn"), dwSSPBase));
  149. v_pIOPregs = (volatile IOPreg *)VirtualAlloc(0, sizeof(IOPreg), MEM_RESERVE, PAGE_NOACCESS);
  150. if(v_pIOPregs == NULL) {
  151. DEBUGMSG(1,(TEXT("[KBD] v_pIOPregs : VirtualAlloc failed!rn")));
  152. goto error_return;
  153. }
  154. else {
  155. if(!VirtualCopy((PVOID)v_pIOPregs, (PVOID)(dwIOBase), sizeof(IOPreg), PAGE_READWRITE|PAGE_NOCACHE )) 
  156. {
  157. DEBUGMSG(1,(TEXT("[KBD] v_pIOPregs : VirtualCopy failed!rn")));
  158. goto error_return;
  159. }
  160. }
  161. DEBUGMSG(1, (TEXT("[KBD] v_pIOPregs mapped at %xrn"), v_pIOPregs));
  162. v_pSSPregs = (volatile SSPreg *)VirtualAlloc(0, sizeof(SSPreg), MEM_RESERVE, PAGE_NOACCESS);
  163. if (v_pSSPregs == NULL) {
  164. DEBUGMSG(1, (TEXT("[KBD] v_pSSPregs : VirtualAlloc failed!rn")));
  165. goto error_return;
  166. }
  167. else {
  168. if (!VirtualCopy((PVOID)v_pSSPregs, (PVOID)(dwSSPBase), sizeof(SSPreg), PAGE_READWRITE | PAGE_NOCACHE)) 
  169. {
  170.      DEBUGMSG(1, (TEXT("[KBD] v_pSSPregs : VirtualCopy failed!rn")));
  171. goto error_return;
  172. }
  173. }
  174. DEBUGMSG(1, (TEXT("[KBD] v_pSSPregs mapped at %xrn"), v_pSSPregs));
  175. v_pDriverGlobals = (PDRIVER_GLOBALS)VirtualAlloc(0, DRIVER_GLOBALS_PHYSICAL_MEMORY_SIZE,
  176.                                                      MEM_RESERVE, PAGE_NOACCESS);
  177. if (v_pDriverGlobals == NULL)
  178. {
  179. DEBUGMSG(1, (TEXT("[KBD] v_pDriverGlobals : VirtualAlloc failed!rn")));
  180. goto error_return;
  181. }
  182. if (!VirtualCopy((PVOID)v_pDriverGlobals,
  183.                       (PVOID)DRIVER_GLOBALS_PHYSICAL_MEMORY_START,
  184.                       DRIVER_GLOBALS_PHYSICAL_MEMORY_SIZE,
  185.                       PAGE_READWRITE|PAGE_NOCACHE))
  186. {
  187. DEBUGMSG(1, (TEXT("[KBD] v_pDriverGlobals : VirtualCopy failed!rn")));
  188. goto error_return;
  189. }
  190. DEBUGMSG(1,(TEXT("--KeybdDriverInitializeAddressesrn")));
  191. return TRUE;
  192. error_return:
  193. if ( v_pIOPregs )
  194. VirtualFree((PVOID)v_pIOPregs, 0, MEM_RELEASE);
  195. if ( v_pSSPregs )
  196. VirtualFree((PVOID)v_pSSPregs, 0, MEM_RELEASE);
  197. if ( v_pDriverGlobals )
  198. VirtualFree((PVOID)v_pDriverGlobals, 0, MEM_RELEASE);
  199. v_pIOPregs = 0;
  200. v_pSSPregs = 0;
  201. v_pDriverGlobals = 0;
  202. DEBUGMSG(1,(TEXT("--KeybdDriverInitializeAddresses[FAILED!!!]rn")));
  203. return FALSE;
  204. }
  205. static UINT KeybdPdd_GetEventEx2(UINT uiPddId, UINT32 rguiScanCode[16], BOOL rgfKeyUp[16])
  206. {
  207.     SETFNAME(_T("KeybdPdd_GetEventEx2"));
  208.     UINT32   scInProgress = 0;
  209.     static UINT32   scPrevious;
  210.     BOOL            fKeyUp;
  211.     UINT8           ui8ScanCode;
  212.     UINT            cEvents = 0;
  213.     DEBUGCHK(rguiScanCode != NULL);
  214.     DEBUGCHK(rgfKeyUp != NULL);
  215. getsFromKBCTL(&ui8ScanCode, 1);
  216.     DEBUGMSG(ZONE_SCANCODES, 
  217.         (_T("%s: scan code 0x%08x, code in progress 0x%08x, previous 0x%08xrn"),
  218.         pszFname, ui8ScanCode, scInProgress, scPrevious));
  219.     scInProgress = ui8ScanCode;
  220.     if (scInProgress == scPrevious) {
  221.         // mdd handles auto-repeat so ignore auto-repeats from keybd
  222.     } else {
  223.         // Not a repeated key.  This is the real thing.
  224.         scPrevious = scInProgress;
  225.         
  226.         if (ui8ScanCode & scKeyUpMask) {
  227.             fKeyUp = TRUE;
  228.             scInProgress &= ~scKeyUpMask;
  229.         } else {
  230.             fKeyUp = FALSE;
  231.         }
  232.         
  233.         rguiScanCode[cEvents] = scInProgress;
  234. rgfKeyUp[cEvents] = fKeyUp;
  235.         ++cEvents;
  236.     }
  237.     return cEvents;
  238. }
  239. void WINAPI KeybdPdd_ToggleKeyNotification(KEY_STATE_FLAGS KeyStateFlags)
  240. {
  241. unsigned int fLights;
  242. DEBUGMSG(1, (TEXT("KeybdPdd_ToggleKeyNotificationrn")));
  243. fLights = 0;
  244. if (KeyStateFlags & KeyShiftCapitalFlag) {
  245. fLights |= 0x04;
  246. }
  247. if (KeyStateFlags & KeyShiftNumLockFlag) {
  248. fLights |= 0x2;
  249. }
  250. /*
  251. Keyboard lights is disabled once driver is installed because the
  252. PS2 controller sends back a response which goes to the IST and corrupts
  253. the interface.  When we figure out how to disable the PS2 response we
  254. can re-enable the lights routine below
  255. */
  256. return;
  257. }
  258. BOOL Ps2Keybd::IsrThreadProc()
  259. {
  260. DWORD dwPriority;
  261. // look for our priority in the registry -- this routine sets it to zero if
  262. // it can't find it.
  263. ReadRegDWORD( TEXT("HARDWARE\DEVICEMAP\KEYBD"), _T("Priority256"), &dwPriority );
  264. if(dwPriority == 0) {
  265. // dwPriority = 145; // default value is 145
  266. dwPriority = 240; // default value is 145
  267. }
  268.     DEBUGMSG(1, (TEXT("IsrThreadProc:rn")));
  269.     m_hevInterrupt = CreateEvent(NULL,FALSE,FALSE,NULL);
  270.     if (m_hevInterrupt == NULL) {
  271.         DEBUGMSG(1, (TEXT("IsrThreadProc: InterruptInitializern")));
  272. goto leave;
  273. }
  274. ReadRegDWORD( TEXT("HARDWARE\DEVICEMAP\KEYBD"), _T("SysIntr"), &dwSysIntr_Keybd );
  275. if( !dwSysIntr_Keybd ) {
  276. goto leave;
  277. }
  278. if (!InterruptInitialize(dwSysIntr_Keybd,m_hevInterrupt,NULL,0)) {
  279. DEBUGMSG(1, (TEXT("IsrThreadProc: KeybdInterruptEnablern")));
  280. goto leave;
  281. }
  282. // update the IST priority
  283. CeSetThreadPriority(GetCurrentThread(), (int)dwPriority);
  284. #if 0
  285. while (1)
  286. {
  287. if ( WaitForSingleObject(m_hevInterrupt, INFINITE) == WAIT_TIMEOUT )
  288. DEBUGMSG(1, (TEXT("timeoutrn")));
  289. else
  290. DEBUGMSG(1, (TEXT("I got onern")));
  291. InterruptDone(dwSysIntr_Keybd);
  292. }
  293. #endif
  294. extern UINT v_uiPddId;
  295. extern PFN_KEYBD_EVENT v_pfnKeybdEvent;
  296. KEYBD_IST keybdIst;
  297. keybdIst.hevInterrupt = m_hevInterrupt;
  298. keybdIst.dwSysIntr_Keybd = dwSysIntr_Keybd;
  299. keybdIst.uiPddId = v_uiPddId;
  300. keybdIst.pfnGetKeybdEvent = KeybdPdd_GetEventEx2;
  301. keybdIst.pfnKeybdEvent = v_pfnKeybdEvent;
  302. KeybdIstLoop(&keybdIst);
  303. leave:
  304.     return 0;
  305. }
  306. DWORD Ps2KeybdIsrThread(Ps2Keybd *pp2k)
  307. {
  308. DEBUGMSG(1,(TEXT("Ps2KeybdIsrThread:rn")));
  309. pp2k->IsrThreadProc();
  310. return 0;
  311. }
  312. BOOL Ps2Keybd::IsrThreadStart()
  313. {
  314. HANDLE hthrd;
  315. DEBUGMSG(1,(TEXT("IsrThreadStart:rn")));
  316. hthrd = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)Ps2KeybdIsrThread,this,0,NULL);
  317. // Since we don't need the handle, close it now.
  318. CloseHandle(hthrd);
  319. return TRUE;
  320. }
  321. BOOL Ps2Keybd::Initialize()
  322. {
  323. DEBUGMSG(1,(TEXT("Ps2Keybd::Initializern")));
  324. DEBUGMSG(1,(TEXT("Ps2Keybd::Initialize Donern")));
  325. return TRUE;
  326. }
  327. BOOL Ps2Keybd::KeybdPowerOn()
  328. {
  329.     UINT8 msg[5];
  330.     int t;
  331.     char dummy = (char)0xff;
  332. DEBUGMSG(1,(TEXT("++Ps2Keybd::KeybdPowerOnrn")));
  333. // Setup IO port for SPI interface & Keyboard
  334. // Setup EINT1 (KBDINT)
  335.     v_pIOPregs->rGPFCON &= ~(0x3 << 2);  // Clear GPF1 
  336.     v_pIOPregs->rGPFCON |= (0x2 << 2);   // Set GPF1 to EINT1 for Keyboard interrupt
  337.     v_pIOPregs->rEXTINT0 &= ~(0x7 << 4);    // Clear EINT1
  338.     v_pIOPregs->rEXTINT0 |= (0x2 << 4);     // fallig edge triggered for EINT1
  339. // setup SPI interface
  340. // GPG5 : SPIMISO (KBDSPIMISO)
  341. // GPG6 : SPIMOSI (KBDSPIMOSI)
  342. // GPG7 : SPICLK  (KBDSPICLK)
  343.     v_pIOPregs->rGPGCON &= ~((0x3 << 10) | (0x3 << 12) | (0x3 << 14));   // Clear GPG5,6,7
  344.     v_pIOPregs->rGPGCON |= ((0x3 << 10) | (0x3 << 12) | (0x3 << 14));    
  345.      
  346. // setup _SS signal(nSS_KBD)
  347.     v_pIOPregs->rGPBCON &= ~(0x3 << 12);         // Clear GPB6
  348.     v_pIOPregs->rGPBCON |= (ONEBIT << 12);        // Set Port GPB6 to output for nSS signal
  349. // setup _PWR_OK signal (KEYBOARD)
  350.     v_pIOPregs->rGPBCON &= ~(0x3 << 0);         // Clear GPB0 
  351.     v_pIOPregs->rGPBCON |= (ONEBIT << 0);       // Set Port GPB0 to output for _PWR_OK signal
  352.     v_pIOPregs->rGPDDAT &=~(ONEBIT << 0);        // set _PWR_OK to 0
  353.     
  354. // Setup SPI registers
  355.     // Interrupt mode, prescaler enable, master mode, active high clock, format B, normal mode
  356.     v_pSSPregs->rSPCON1 = (ONEBIT<<5)|(ONEBIT<<4)|(ONEBIT<<3)|(0x0<<2)|(ONEBIT<<1);
  357.     
  358. // Developer MUST change the value of prescaler properly whenever value of PCLK is changed.
  359.     v_pSSPregs->rSPPRE1 = 255;// 99.121K = 203M/4/2/(255+1) PCLK=50.75Mhz FCLK=203Mhz SPICLK=99.121Khz
  360.          
  361.     for(t=0;t<20000; t++); // delay
  362.     msg[0] = (char)0x1b; msg[1] = (char)0xa0; msg[2] = (char)0x7b; msg[3] = (char)0; // Initialize USAR
  363.      for(t=0; t < 10; t++) {
  364.      dummy = putcToKBCTL(0xff);
  365.     }
  366.     
  367.     for(t=0; t<10; t++) { // wait for a while
  368.         putsToKBCTL(msg,3);
  369.         for(t=0;t<20000; t++);
  370.     }
  371.     t = 100;
  372.     while(t--) {
  373.         if((v_pIOPregs->rGPFDAT & 0x2)==0) { // Read _ATN
  374.             break;
  375.         }
  376.     } //check _ATN
  377.     if(t != 0) {
  378.         getsFromKBCTL(msg,3);
  379.     }    
  380.     t=100000;
  381.     while(t--); // delay
  382. msg[0] = (char)0x1b; msg[1] = (char)0xa1; msg[2] = (char)0x7a; msg[3] = (char)0; //Initialization complete
  383. putsToKBCTL(msg,3);
  384. DEBUGMSG(1,(TEXT("--Ps2Keybd::KeybdPowerOnrn")));
  385. return(TRUE);
  386. }
  387. BOOL Ps2Keybd::KeybdPowerOff()
  388. {
  389. DEBUGMSG(1,(TEXT("++Ps2Keybd::KeybdPowerOffrn")));
  390. DEBUGMSG(1,(TEXT("--Ps2Keybd::KeybdPowerOffrn")));
  391. return(TRUE);
  392. }