]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Bus/Isa/Ps2MouseSimulateTouchPadDxe/CommPs2.c
change "Ps2MouseSimulateTouchPad" to "Ps2MouseAbsolutePointer" for more clearing...
[mirror_edk2.git] / IntelFrameworkModulePkg / Bus / Isa / Ps2MouseSimulateTouchPadDxe / CommPs2.c
CommitLineData
0f8304cd 1/**@file\r
2 PS2 Mouse Communication Interface \r
3 \r
4Copyright (c) 2006 - 2007, Intel Corporation\r
5All rights reserved. This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
52e6faea 15#include "Ps2MouseAbsolutePointer.h"\r
0f8304cd 16#include "CommPs2.h"\r
17\r
18UINT8 SampleRateTbl[MAX_SR] = { 0xa, 0x14, 0x28, 0x3c, 0x50, 0x64, 0xc8 };\r
19\r
20UINT8 ResolutionTbl[MAX_CMR] = { 0, 1, 2, 3 };\r
21\r
22EFI_STATUS\r
23KbcSelfTest (\r
24 IN EFI_ISA_IO_PROTOCOL *IsaIo\r
25 )\r
26/*++\r
27\r
28Routine Description:\r
29\r
30 GC_TODO: Add function description\r
31\r
32Arguments:\r
33\r
34 IsaIo - GC_TODO: add argument description\r
35\r
36Returns:\r
37\r
38 EFI_DEVICE_ERROR - GC_TODO: Add description for return value\r
39 EFI_SUCCESS - GC_TODO: Add description for return value\r
40\r
41--*/\r
42{\r
43 EFI_STATUS Status;\r
44 UINT8 Data;\r
45\r
46 //\r
47 // Keyboard controller self test\r
48 //\r
49 Status = Out8042Command (IsaIo, SELF_TEST);\r
50 if (EFI_ERROR (Status)) {\r
51 return Status;\r
52 }\r
53 //\r
54 // Read return code\r
55 //\r
56 Status = In8042Data (IsaIo, &Data);\r
57 if (EFI_ERROR (Status)) {\r
58 return Status;\r
59 }\r
60\r
61 if (Data != 0x55) {\r
62 return EFI_DEVICE_ERROR;\r
63 }\r
64 //\r
65 // Set system flag\r
66 //\r
67 Status = Out8042Command (IsaIo, READ_CMD_BYTE);\r
68 if (EFI_ERROR (Status)) {\r
69 return Status;\r
70 }\r
71\r
72 Status = In8042Data (IsaIo, &Data);\r
73 if (EFI_ERROR (Status)) {\r
74 return Status;\r
75 }\r
76\r
77 Status = Out8042Command (IsaIo, WRITE_CMD_BYTE);\r
78 if (EFI_ERROR (Status)) {\r
79 return Status;\r
80 }\r
81\r
82 Data |= CMD_SYS_FLAG;\r
83 Status = Out8042Data (IsaIo, Data);\r
84 if (EFI_ERROR (Status)) {\r
85 return Status;\r
86 }\r
87\r
88 return EFI_SUCCESS;\r
89}\r
90\r
91EFI_STATUS\r
92KbcEnableAux (\r
93 IN EFI_ISA_IO_PROTOCOL *IsaIo\r
94 )\r
95/*++\r
96\r
97Routine Description:\r
98\r
99 GC_TODO: Add function description\r
100\r
101Arguments:\r
102\r
103 IsaIo - GC_TODO: add argument description\r
104\r
105Returns:\r
106\r
107 GC_TODO: add return values\r
108\r
109--*/\r
110{\r
111 //\r
112 // Send 8042 enable mouse command\r
113 //\r
114 return Out8042Command (IsaIo, ENABLE_AUX);\r
115}\r
116\r
117EFI_STATUS\r
118KbcDisableAux (\r
119 IN EFI_ISA_IO_PROTOCOL *IsaIo\r
120 )\r
121/*++\r
122\r
123Routine Description:\r
124\r
125 GC_TODO: Add function description\r
126\r
127Arguments:\r
128\r
129 IsaIo - GC_TODO: add argument description\r
130\r
131Returns:\r
132\r
133 GC_TODO: add return values\r
134\r
135--*/\r
136{\r
137 //\r
138 // Send 8042 disable mouse command\r
139 //\r
140 return Out8042Command (IsaIo, DISABLE_AUX);\r
141}\r
142\r
143EFI_STATUS\r
144KbcEnableKb (\r
145 IN EFI_ISA_IO_PROTOCOL *IsaIo\r
146 )\r
147/*++\r
148\r
149Routine Description:\r
150\r
151 GC_TODO: Add function description\r
152\r
153Arguments:\r
154\r
155 IsaIo - GC_TODO: add argument description\r
156\r
157Returns:\r
158\r
159 GC_TODO: add return values\r
160\r
161--*/\r
162{\r
163 //\r
164 // Send 8042 enable keyboard command\r
165 //\r
166 return Out8042Command (IsaIo, ENABLE_KB);\r
167}\r
168\r
169EFI_STATUS\r
170KbcDisableKb (\r
171 IN EFI_ISA_IO_PROTOCOL *IsaIo\r
172 )\r
173/*++\r
174\r
175Routine Description:\r
176\r
177 GC_TODO: Add function description\r
178\r
179Arguments:\r
180\r
181 IsaIo - GC_TODO: add argument description\r
182\r
183Returns:\r
184\r
185 GC_TODO: add return values\r
186\r
187--*/\r
188{\r
189 //\r
190 // Send 8042 disable keyboard command\r
191 //\r
192 return Out8042Command (IsaIo, DISABLE_KB);\r
193}\r
194\r
195EFI_STATUS\r
196CheckKbStatus (\r
197 IN EFI_ISA_IO_PROTOCOL *IsaIo,\r
198 OUT BOOLEAN *KeyboardEnable\r
199 )\r
200/*++\r
201\r
202Routine Description:\r
203\r
204 GC_TODO: Add function description\r
205\r
206Arguments:\r
207\r
208 IsaIo - GC_TODO: add argument description\r
209 KeyboardEnable - GC_TODO: add argument description\r
210\r
211Returns:\r
212\r
213 EFI_SUCCESS - GC_TODO: Add description for return value\r
214\r
215--*/\r
216{\r
217 EFI_STATUS Status;\r
218 UINT8 Data;\r
219\r
220 //\r
221 // Send command to read KBC command byte\r
222 //\r
223 Status = Out8042Command (IsaIo, READ_CMD_BYTE);\r
224 if (EFI_ERROR (Status)) {\r
225 return Status;\r
226 }\r
227\r
228 Status = In8042Data (IsaIo, &Data);\r
229 if (EFI_ERROR (Status)) {\r
230 return Status;\r
231 }\r
232 //\r
233 // Check keyboard enable or not\r
234 //\r
235 if ((Data & CMD_KB_STS) == CMD_KB_DIS) {\r
236 *KeyboardEnable = FALSE;\r
237 } else {\r
238 *KeyboardEnable = TRUE;\r
239 }\r
240\r
241 return EFI_SUCCESS;\r
242}\r
243\r
244EFI_STATUS\r
245PS2MouseReset (\r
246 IN EFI_ISA_IO_PROTOCOL *IsaIo\r
247 )\r
248/*++\r
249\r
250Routine Description:\r
251\r
252 GC_TODO: Add function description\r
253\r
254Arguments:\r
255\r
256 IsaIo - GC_TODO: add argument description\r
257\r
258Returns:\r
259\r
260 EFI_DEVICE_ERROR - GC_TODO: Add description for return value\r
261 EFI_DEVICE_ERROR - GC_TODO: Add description for return value\r
262 EFI_SUCCESS - GC_TODO: Add description for return value\r
263\r
264--*/\r
265{\r
266 EFI_STATUS Status;\r
267 UINT8 Data;\r
268\r
269 Status = Out8042AuxCommand (IsaIo, RESET_CMD, FALSE);\r
270 if (EFI_ERROR (Status)) {\r
271 return Status;\r
272 }\r
273\r
274 Status = In8042AuxData (IsaIo, &Data);\r
275 if (EFI_ERROR (Status)) {\r
276 return Status;\r
277 }\r
278 //\r
279 // Check BAT Complete Code\r
280 //\r
281 if (Data != PS2MOUSE_BAT1) {\r
282 return EFI_DEVICE_ERROR;\r
283 }\r
284\r
285 Status = In8042AuxData (IsaIo, &Data);\r
286 if (EFI_ERROR (Status)) {\r
287 return Status;\r
288 }\r
289 //\r
290 // Check BAT Complete Code\r
291 //\r
292 if (Data != PS2MOUSE_BAT2) {\r
293 return EFI_DEVICE_ERROR;\r
294 }\r
295\r
296 return EFI_SUCCESS;\r
297}\r
298\r
299EFI_STATUS\r
300PS2MouseSetSampleRate (\r
301 IN EFI_ISA_IO_PROTOCOL *IsaIo,\r
302 IN MOUSE_SR SampleRate\r
303 )\r
304/*++\r
305\r
306Routine Description:\r
307\r
308 GC_TODO: Add function description\r
309\r
310Arguments:\r
311\r
312 IsaIo - GC_TODO: add argument description\r
313 SampleRate - GC_TODO: add argument description\r
314\r
315Returns:\r
316\r
317 GC_TODO: add return values\r
318\r
319--*/\r
320{\r
321 EFI_STATUS Status;\r
322\r
323 //\r
324 // Send auxiliary command to set mouse sample rate\r
325 //\r
326 Status = Out8042AuxCommand (IsaIo, SETSR_CMD, FALSE);\r
327 if (EFI_ERROR (Status)) {\r
328 return Status;\r
329 }\r
330\r
331 Status = Out8042AuxData (IsaIo, SampleRateTbl[SampleRate]);\r
332\r
333 return Status;\r
334}\r
335\r
336EFI_STATUS\r
337PS2MouseSetResolution (\r
338 IN EFI_ISA_IO_PROTOCOL *IsaIo,\r
339 IN MOUSE_RE Resolution\r
340 )\r
341/*++\r
342\r
343Routine Description:\r
344\r
345 GC_TODO: Add function description\r
346\r
347Arguments:\r
348\r
349 IsaIo - GC_TODO: add argument description\r
350 Resolution - GC_TODO: add argument description\r
351\r
352Returns:\r
353\r
354 GC_TODO: add return values\r
355\r
356--*/\r
357{\r
358 EFI_STATUS Status;\r
359\r
360 //\r
361 // Send auxiliary command to set mouse resolution\r
362 //\r
363 Status = Out8042AuxCommand (IsaIo, SETRE_CMD, FALSE);\r
364 if (EFI_ERROR (Status)) {\r
365 return Status;\r
366 }\r
367\r
368 Status = Out8042AuxData (IsaIo, ResolutionTbl[Resolution]);\r
369\r
370 return Status;\r
371}\r
372\r
373EFI_STATUS\r
374PS2MouseSetScaling (\r
375 IN EFI_ISA_IO_PROTOCOL *IsaIo,\r
376 IN MOUSE_SF Scaling\r
377 )\r
378/*++\r
379\r
380Routine Description:\r
381\r
382 GC_TODO: Add function description\r
383\r
384Arguments:\r
385\r
386 IsaIo - GC_TODO: add argument description\r
387 Scaling - GC_TODO: add argument description\r
388\r
389Returns:\r
390\r
391 GC_TODO: add return values\r
392\r
393--*/\r
394{\r
395 UINT8 Command;\r
396\r
397 Command = (UINT8) (Scaling == SF1 ? SETSF1_CMD : SETSF2_CMD);\r
398\r
399 //\r
400 // Send auxiliary command to set mouse scaling data\r
401 //\r
402 return Out8042AuxCommand (IsaIo, Command, FALSE);\r
403}\r
404\r
405EFI_STATUS\r
406PS2MouseEnable (\r
407 IN EFI_ISA_IO_PROTOCOL *IsaIo\r
408 )\r
409/*++\r
410\r
411Routine Description:\r
412\r
413 GC_TODO: Add function description\r
414\r
415Arguments:\r
416\r
417 IsaIo - GC_TODO: add argument description\r
418\r
419Returns:\r
420\r
421 GC_TODO: add return values\r
422\r
423--*/\r
424{\r
425 //\r
426 // Send auxiliary command to enable mouse\r
427 //\r
428 return Out8042AuxCommand (IsaIo, ENABLE_CMD, FALSE);\r
429}\r
430\r
431EFI_STATUS\r
432PS2MouseGetPacket (\r
52e6faea 433 PS2_MOUSE_ABSOLUTE_POINTER_DEV *MouseAbsolutePointerDev\r
0f8304cd 434 )\r
435/*++\r
436\r
437Routine Description:\r
438\r
439 Get mouse packet . Only care first 3 bytes\r
440\r
441Arguments:\r
442\r
443 MouseDev - Pointer of PS2 Mouse Private Data Structure \r
444\r
445Returns:\r
446\r
447 EFI_NOT_READY - Mouse Device not ready to input data packet, or some error happened during getting the packet\r
448 EFI_SUCCESS - The data packet is gotten successfully.\r
449\r
450--*/\r
451{\r
452 EFI_STATUS Status;\r
453 BOOLEAN KeyboardEnable;\r
454 UINT8 Packet[PS2_PACKET_LENGTH];\r
455 UINT8 Data;\r
456 UINTN Count;\r
457 UINTN State;\r
458 INT16 RelativeMovementX;\r
459 INT16 RelativeMovementY;\r
460 BOOLEAN LButton;\r
461 BOOLEAN RButton;\r
462\r
463 KeyboardEnable = FALSE;\r
464 Count = 1;\r
465 State = PS2_READ_BYTE_ONE;\r
466\r
467 //\r
468 // State machine to get mouse packet\r
469 //\r
470 while (1) {\r
471\r
472 switch (State) {\r
473 case PS2_READ_BYTE_ONE:\r
474 //\r
475 // Read mouse first byte data, if failed, immediately return\r
476 //\r
52e6faea 477 KbcDisableAux (MouseAbsolutePointerDev->IsaIo);\r
478 Status = PS2MouseRead (MouseAbsolutePointerDev->IsaIo, &Data, &Count, State);\r
0f8304cd 479 if (EFI_ERROR (Status)) {\r
52e6faea 480 KbcEnableAux (MouseAbsolutePointerDev->IsaIo);\r
0f8304cd 481 return EFI_NOT_READY;\r
482 }\r
483\r
484 if (Count != 1) {\r
52e6faea 485 KbcEnableAux (MouseAbsolutePointerDev->IsaIo);\r
0f8304cd 486 return EFI_NOT_READY;\r
487 }\r
488\r
489 if (IS_PS2_SYNC_BYTE (Data)) {\r
490 Packet[0] = Data;\r
491 State = PS2_READ_DATA_BYTE;\r
492\r
52e6faea 493 CheckKbStatus (MouseAbsolutePointerDev->IsaIo, &KeyboardEnable);\r
494 KbcDisableKb (MouseAbsolutePointerDev->IsaIo);\r
495 KbcEnableAux (MouseAbsolutePointerDev->IsaIo);\r
0f8304cd 496 }\r
497 break;\r
498\r
499 case PS2_READ_DATA_BYTE:\r
500 Count = 2;\r
52e6faea 501 Status = PS2MouseRead (MouseAbsolutePointerDev->IsaIo, (Packet + 1), &Count, State);\r
0f8304cd 502 if (EFI_ERROR (Status)) {\r
503 if (KeyboardEnable) {\r
52e6faea 504 KbcEnableKb (MouseAbsolutePointerDev->IsaIo);\r
0f8304cd 505 }\r
506\r
507 return EFI_NOT_READY;\r
508 }\r
509\r
510 if (Count != 2) {\r
511 if (KeyboardEnable) {\r
52e6faea 512 KbcEnableKb (MouseAbsolutePointerDev->IsaIo);\r
0f8304cd 513 }\r
514\r
515 return EFI_NOT_READY;\r
516 }\r
517\r
518 State = PS2_PROCESS_PACKET;\r
519 break;\r
520\r
521 case PS2_PROCESS_PACKET:\r
522 if (KeyboardEnable) {\r
52e6faea 523 KbcEnableKb (MouseAbsolutePointerDev->IsaIo);\r
0f8304cd 524 }\r
525 //\r
526 // Decode the packet\r
527 //\r
528 RelativeMovementX = Packet[1];\r
529 RelativeMovementY = Packet[2];\r
530 //\r
531 // Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0 \r
532 // Byte 0 | Y overflow | X overflow | Y sign bit | X sign bit | Always 1 | Middle Btn | Right Btn | Left Btn \r
533 // Byte 1 | 8 bit X Movement \r
534 // Byte 2 | 8 bit Y Movement \r
535 // \r
536 // X sign bit + 8 bit X Movement : 9-bit signed twos complement integer that presents the relative displacement of the device in the X direction since the last data transmission.\r
537 // Y sign bit + 8 bit Y Movement : Same as X sign bit + 8 bit X Movement.\r
538 //\r
539 //\r
540 // First, Clear X and Y high 8 bits\r
541 //\r
542 RelativeMovementX = (INT16) (RelativeMovementX & 0xFF); \r
543 RelativeMovementY = (INT16) (RelativeMovementY & 0xFF); \r
544 //\r
545 // Second, if the 9-bit signed twos complement integer is negative, set the high 8 bit 0xff\r
546 //\r
547 if ((Packet[0] & 0x10) != 0) {\r
548 RelativeMovementX = (INT16) (RelativeMovementX | 0xFF00);\r
549 }\r
550 if ((Packet[0] & 0x20) != 0) {\r
551 RelativeMovementY = (INT16) (RelativeMovementY | 0xFF00);\r
552 }\r
553\r
554 \r
555 RButton = (UINT8) (Packet[0] & 0x2);\r
556 LButton = (UINT8) (Packet[0] & 0x1);\r
557\r
558 //\r
559 // Update mouse state\r
560 //\r
52e6faea 561 MouseAbsolutePointerDev->State.CurrentX += RelativeMovementX;\r
562 MouseAbsolutePointerDev->State.CurrentY -= RelativeMovementY;\r
563 MouseAbsolutePointerDev->State.CurrentZ = 0;\r
564 MouseAbsolutePointerDev->State.ActiveButtons = (UINT8) (LButton || RButton) & 0x3;\r
565 MouseAbsolutePointerDev->StateChanged = TRUE;\r
0f8304cd 566\r
567 return EFI_SUCCESS;\r
568 }\r
569 }\r
570}\r
571\r
572EFI_STATUS\r
573PS2MouseRead (\r
574 IN EFI_ISA_IO_PROTOCOL *IsaIo,\r
575 OUT VOID *Buffer,\r
576 IN OUT UINTN *BufSize,\r
577 IN UINTN State\r
578 )\r
579/*++\r
580\r
581Routine Description:\r
582\r
583 GC_TODO: Add function description\r
584\r
585Arguments:\r
586\r
587 IsaIo - GC_TODO: add argument description\r
588 Buffer - GC_TODO: add argument description\r
589 BufSize - GC_TODO: add argument description\r
590 State - GC_TODO: add argument description\r
591\r
592Returns:\r
593\r
594 GC_TODO: add return values\r
595\r
596--*/\r
597{\r
598 EFI_STATUS Status;\r
599 UINTN BytesRead;\r
600\r
601 Status = EFI_SUCCESS;\r
602 BytesRead = 0;\r
603\r
604 if (State == PS2_READ_BYTE_ONE) {\r
605 //\r
606 // Check input for mouse\r
607 //\r
608 Status = CheckForInput (IsaIo);\r
609\r
610 if (EFI_ERROR (Status)) {\r
611 return Status;\r
612 }\r
613 }\r
614\r
615 while (BytesRead < *BufSize) {\r
616\r
617 Status = WaitOutputFull (IsaIo, TIMEOUT);\r
618 if (EFI_ERROR (Status)) {\r
619 break;\r
620 }\r
621\r
622 IsaIo->Io.Read (IsaIo, EfiIsaIoWidthUint8, KBC_DATA_PORT, 1, Buffer);\r
623\r
624 BytesRead++;\r
625 Buffer = (UINT8 *) Buffer + 1;\r
626 }\r
627 //\r
628 // Verify the correct number of bytes read\r
629 //\r
630 if (BytesRead == 0 || BytesRead != *BufSize) {\r
631 Status = EFI_NOT_FOUND;\r
632 }\r
633\r
634 *BufSize = BytesRead;\r
635 return Status;\r
636}\r
637//\r
638// 8042 I/O function\r
639//\r
640EFI_STATUS\r
641Out8042Command (\r
642 IN EFI_ISA_IO_PROTOCOL *IsaIo,\r
643 IN UINT8 Command\r
644 )\r
645/*++\r
646\r
647Routine Description:\r
648\r
649 GC_TODO: Add function description\r
650\r
651Arguments:\r
652\r
653 IsaIo - GC_TODO: add argument description\r
654 Command - GC_TODO: add argument description\r
655\r
656Returns:\r
657\r
658 EFI_SUCCESS - GC_TODO: Add description for return value\r
659\r
660--*/\r
661{\r
662 EFI_STATUS Status;\r
663 UINT8 Data;\r
664\r
665 //\r
666 // Wait keyboard controller input buffer empty\r
667 //\r
668 Status = WaitInputEmpty (IsaIo, TIMEOUT);\r
669 if (EFI_ERROR (Status)) {\r
670 return Status;\r
671 }\r
672 //\r
673 // Send command\r
674 //\r
675 Data = Command;\r
676 IsaIo->Io.Write (IsaIo, EfiIsaIoWidthUint8, KBC_CMD_STS_PORT, 1, &Data);\r
677\r
678 Status = WaitInputEmpty (IsaIo, TIMEOUT);\r
679 if (EFI_ERROR (Status)) {\r
680 return Status;\r
681 }\r
682\r
683 return EFI_SUCCESS;\r
684}\r
685\r
686EFI_STATUS\r
687Out8042Data (\r
688 IN EFI_ISA_IO_PROTOCOL *IsaIo,\r
689 IN UINT8 Data\r
690 )\r
691/*++\r
692\r
693Routine Description:\r
694\r
695 GC_TODO: Add function description\r
696\r
697Arguments:\r
698\r
699 IsaIo - GC_TODO: add argument description\r
700 Data - GC_TODO: add argument description\r
701\r
702Returns:\r
703\r
704 EFI_SUCCESS - GC_TODO: Add description for return value\r
705\r
706--*/\r
707{\r
708 EFI_STATUS Status;\r
709 UINT8 temp;\r
710 //\r
711 // Wait keyboard controller input buffer empty\r
712 //\r
713 Status = WaitInputEmpty (IsaIo, TIMEOUT);\r
714 if (EFI_ERROR (Status)) {\r
715 return Status;\r
716 }\r
717\r
718 temp = Data;\r
719 IsaIo->Io.Write (IsaIo, EfiIsaIoWidthUint8, KBC_DATA_PORT, 1, &temp);\r
720\r
721 Status = WaitInputEmpty (IsaIo, TIMEOUT);\r
722 if (EFI_ERROR (Status)) {\r
723 return Status;\r
724 }\r
725\r
726 return EFI_SUCCESS;\r
727}\r
728\r
729EFI_STATUS\r
730In8042Data (\r
731 IN EFI_ISA_IO_PROTOCOL *IsaIo,\r
732 IN OUT UINT8 *Data\r
733 )\r
734/*++\r
735\r
736Routine Description:\r
737\r
738 GC_TODO: Add function description\r
739\r
740Arguments:\r
741\r
742 IsaIo - GC_TODO: add argument description\r
743 Data - GC_TODO: add argument description\r
744\r
745Returns:\r
746\r
747 EFI_TIMEOUT - GC_TODO: Add description for return value\r
748 EFI_SUCCESS - GC_TODO: Add description for return value\r
749\r
750--*/\r
751{\r
752 UINTN Delay;\r
753 UINT8 temp;\r
754\r
755 Delay = TIMEOUT / 50;\r
756\r
757 do {\r
758 IsaIo->Io.Read (IsaIo, EfiIsaIoWidthUint8, KBC_CMD_STS_PORT, 1, &temp);\r
759\r
760 //\r
761 // Check keyboard controller status bit 0(output buffer status)\r
762 //\r
763 if ((temp & KBC_OUTB) == KBC_OUTB) {\r
764 break;\r
765 }\r
766\r
767 gBS->Stall (50);\r
768 Delay--;\r
769 } while (Delay);\r
770\r
771 if (Delay == 0) {\r
772 return EFI_TIMEOUT;\r
773 }\r
774\r
775 IsaIo->Io.Read (IsaIo, EfiIsaIoWidthUint8, KBC_DATA_PORT, 1, Data);\r
776\r
777 return EFI_SUCCESS;\r
778}\r
779\r
780EFI_STATUS\r
781Out8042AuxCommand (\r
782 IN EFI_ISA_IO_PROTOCOL *IsaIo,\r
783 IN UINT8 Command,\r
784 IN BOOLEAN Resend\r
785 )\r
786/*++\r
787\r
788Routine Description:\r
789\r
790 GC_TODO: Add function description\r
791\r
792Arguments:\r
793\r
794 IsaIo - GC_TODO: add argument description\r
795 Command - GC_TODO: add argument description\r
796 Resend - GC_TODO: add argument description\r
797\r
798Returns:\r
799\r
800 EFI_SUCCESS - GC_TODO: Add description for return value\r
801 EFI_DEVICE_ERROR - GC_TODO: Add description for return value\r
802 EFI_DEVICE_ERROR - GC_TODO: Add description for return value\r
803 EFI_SUCCESS - GC_TODO: Add description for return value\r
804\r
805--*/\r
806{\r
807 EFI_STATUS Status;\r
808 UINT8 Data;\r
809\r
810 //\r
811 // Wait keyboard controller input buffer empty\r
812 //\r
813 Status = WaitInputEmpty (IsaIo, TIMEOUT);\r
814 if (EFI_ERROR (Status)) {\r
815 return Status;\r
816 }\r
817 //\r
818 // Send write to auxiliary device command\r
819 //\r
820 Data = WRITE_AUX_DEV;\r
821 IsaIo->Io.Write (IsaIo, EfiIsaIoWidthUint8, KBC_CMD_STS_PORT, 1, &Data);\r
822\r
823 Status = WaitInputEmpty (IsaIo, TIMEOUT);\r
824 if (EFI_ERROR (Status)) {\r
825 return Status;\r
826 }\r
827 //\r
828 // Send auxiliary device command\r
829 //\r
830 IsaIo->Io.Write (IsaIo, EfiIsaIoWidthUint8, KBC_DATA_PORT, 1, &Command);\r
831\r
832 //\r
833 // Read return code\r
834 //\r
835 Status = In8042AuxData (IsaIo, &Data);\r
836 if (EFI_ERROR (Status)) {\r
837 return Status;\r
838 }\r
839\r
840 if (Data == PS2_ACK) {\r
841 //\r
842 // Receive mouse acknowledge, command send success\r
843 //\r
844 return EFI_SUCCESS;\r
845\r
846 } else if (Resend) {\r
847 //\r
848 // Resend fail\r
849 //\r
850 return EFI_DEVICE_ERROR;\r
851\r
852 } else if (Data == PS2_RESEND) {\r
853 //\r
854 // Resend command\r
855 //\r
856 Status = Out8042AuxCommand (IsaIo, Command, TRUE);\r
857 if (EFI_ERROR (Status)) {\r
858 return Status;\r
859 }\r
860\r
861 } else {\r
862 //\r
863 // Invalid return code\r
864 //\r
865 return EFI_DEVICE_ERROR;\r
866\r
867 }\r
868\r
869 return EFI_SUCCESS;\r
870}\r
871\r
872EFI_STATUS\r
873Out8042AuxData (\r
874 IN EFI_ISA_IO_PROTOCOL *IsaIo,\r
875 IN UINT8 Data\r
876 )\r
877/*++\r
878\r
879Routine Description:\r
880\r
881 GC_TODO: Add function description\r
882\r
883Arguments:\r
884\r
885 IsaIo - GC_TODO: add argument description\r
886 Data - GC_TODO: add argument description\r
887\r
888Returns:\r
889\r
890 EFI_SUCCESS - GC_TODO: Add description for return value\r
891\r
892--*/\r
893{\r
894 EFI_STATUS Status;\r
895 UINT8 Temp;\r
896 //\r
897 // Wait keyboard controller input buffer empty\r
898 //\r
899 Status = WaitInputEmpty (IsaIo, TIMEOUT);\r
900 if (EFI_ERROR (Status)) {\r
901 return Status;\r
902 }\r
903 //\r
904 // Send write to auxiliary device command\r
905 //\r
906 Temp = WRITE_AUX_DEV;\r
907 IsaIo->Io.Write (IsaIo, EfiIsaIoWidthUint8, KBC_CMD_STS_PORT, 1, &Temp);\r
908\r
909 Status = WaitInputEmpty (IsaIo, TIMEOUT);\r
910 if (EFI_ERROR (Status)) {\r
911 return Status;\r
912 }\r
913\r
914 Temp = Data;\r
915 IsaIo->Io.Write (IsaIo, EfiIsaIoWidthUint8, KBC_DATA_PORT, 1, &Temp);\r
916\r
917 Status = WaitInputEmpty (IsaIo, TIMEOUT);\r
918 if (EFI_ERROR (Status)) {\r
919 return Status;\r
920 }\r
921\r
922 return EFI_SUCCESS;\r
923}\r
924\r
925EFI_STATUS\r
926In8042AuxData (\r
927 IN EFI_ISA_IO_PROTOCOL *IsaIo,\r
928 IN OUT UINT8 *Data\r
929 )\r
930/*++\r
931\r
932Routine Description:\r
933\r
934 GC_TODO: Add function description\r
935\r
936Arguments:\r
937\r
938 IsaIo - GC_TODO: add argument description\r
939 Data - GC_TODO: add argument description\r
940\r
941Returns:\r
942\r
943 EFI_SUCCESS - GC_TODO: Add description for return value\r
944\r
945--*/\r
946{\r
947 EFI_STATUS Status;\r
948\r
949 //\r
950 // wait for output data\r
951 //\r
952 Status = WaitOutputFull (IsaIo, BAT_TIMEOUT);\r
953 if (EFI_ERROR (Status)) {\r
954 return Status;\r
955 }\r
956\r
957 IsaIo->Io.Read (IsaIo, EfiIsaIoWidthUint8, KBC_DATA_PORT, 1, Data);\r
958\r
959 return EFI_SUCCESS;\r
960}\r
961\r
962EFI_STATUS\r
963CheckForInput (\r
964 IN EFI_ISA_IO_PROTOCOL *IsaIo\r
965 )\r
966/*++\r
967\r
968Routine Description:\r
969\r
970 GC_TODO: Add function description\r
971\r
972Arguments:\r
973\r
974 IsaIo - GC_TODO: add argument description\r
975\r
976Returns:\r
977\r
978 EFI_NOT_READY - GC_TODO: Add description for return value\r
979 EFI_SUCCESS - GC_TODO: Add description for return value\r
980\r
981--*/\r
982{\r
983 UINT8 Data;\r
984\r
985 IsaIo->Io.Read (IsaIo, EfiIsaIoWidthUint8, KBC_CMD_STS_PORT, 1, &Data);\r
986\r
987 //\r
988 // Check keyboard controller status, if it is output buffer full and for auxiliary device\r
989 //\r
990 if ((Data & (KBC_OUTB | KBC_AUXB)) != (KBC_OUTB | KBC_AUXB)) {\r
991 return EFI_NOT_READY;\r
992 }\r
993\r
994 return EFI_SUCCESS;\r
995}\r
996\r
997EFI_STATUS\r
998WaitInputEmpty (\r
999 IN EFI_ISA_IO_PROTOCOL *IsaIo,\r
1000 IN UINTN Timeout\r
1001 )\r
1002/*++\r
1003\r
1004Routine Description:\r
1005\r
1006 GC_TODO: Add function description\r
1007\r
1008Arguments:\r
1009\r
1010 IsaIo - GC_TODO: add argument description\r
1011 Timeout - GC_TODO: add argument description\r
1012\r
1013Returns:\r
1014\r
1015 EFI_TIMEOUT - GC_TODO: Add description for return value\r
1016 EFI_SUCCESS - GC_TODO: Add description for return value\r
1017\r
1018--*/\r
1019{\r
1020 UINTN Delay;\r
1021 UINT8 Data;\r
1022\r
1023 Delay = Timeout / 50;\r
1024\r
1025 do {\r
1026 IsaIo->Io.Read (IsaIo, EfiIsaIoWidthUint8, KBC_CMD_STS_PORT, 1, &Data);\r
1027\r
1028 //\r
1029 // Check keyboard controller status bit 1(input buffer status)\r
1030 //\r
1031 if ((Data & KBC_INPB) == 0) {\r
1032 break;\r
1033 }\r
1034\r
1035 gBS->Stall (50);\r
1036 Delay--;\r
1037 } while (Delay);\r
1038\r
1039 if (Delay == 0) {\r
1040 return EFI_TIMEOUT;\r
1041 }\r
1042\r
1043 return EFI_SUCCESS;\r
1044}\r
1045\r
1046EFI_STATUS\r
1047WaitOutputFull (\r
1048 IN EFI_ISA_IO_PROTOCOL *IsaIo,\r
1049 IN UINTN Timeout\r
1050 )\r
1051/*++\r
1052\r
1053Routine Description:\r
1054\r
1055 GC_TODO: Add function description\r
1056\r
1057Arguments:\r
1058\r
1059 IsaIo - GC_TODO: add argument description\r
1060 Timeout - GC_TODO: add argument description\r
1061\r
1062Returns:\r
1063\r
1064 EFI_TIMEOUT - GC_TODO: Add description for return value\r
1065 EFI_SUCCESS - GC_TODO: Add description for return value\r
1066\r
1067--*/\r
1068{\r
1069 UINTN Delay;\r
1070 UINT8 Data;\r
1071\r
1072 Delay = Timeout / 50;\r
1073\r
1074 do {\r
1075 IsaIo->Io.Read (IsaIo, EfiIsaIoWidthUint8, KBC_CMD_STS_PORT, 1, &Data);\r
1076\r
1077 //\r
1078 // Check keyboard controller status bit 0(output buffer status)\r
1079 // & bit5(output buffer for auxiliary device)\r
1080 //\r
1081 if ((Data & (KBC_OUTB | KBC_AUXB)) == (KBC_OUTB | KBC_AUXB)) {\r
1082 break;\r
1083 }\r
1084\r
1085 gBS->Stall (50);\r
1086 Delay--;\r
1087 } while (Delay);\r
1088\r
1089 if (Delay == 0) {\r
1090 return EFI_TIMEOUT;\r
1091 }\r
1092\r
1093 return EFI_SUCCESS;\r
1094}\r