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