]>
git.proxmox.com Git - mirror_edk2.git/blob - IntelFrameworkModulePkg/Bus/Isa/Ps2MouseDxe/CommPs2.c
3 Copyright (c) 2006 - 2007, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14 PS2 Mouse Communication Interface
22 UINT8 SampleRateTbl
[ MAX_SR
] = { 0xa , 0x14 , 0x28 , 0x3c , 0x50 , 0x64 , 0xc8 };
24 UINT8 ResolutionTbl
[ MAX_CMR
] = { 0 , 1 , 2 , 3 };
28 IN EFI_ISA_IO_PROTOCOL
* IsaIo
34 GC_TODO: Add function description
38 IsaIo - GC_TODO: add argument description
42 EFI_DEVICE_ERROR - GC_TODO: Add description for return value
43 EFI_SUCCESS - GC_TODO: Add description for return value
51 // Keyboard controller self test
53 Status
= Out8042Command ( IsaIo
, SELF_TEST
);
54 if ( EFI_ERROR ( Status
)) {
60 Status
= In8042Data ( IsaIo
, & Data
);
61 if ( EFI_ERROR ( Status
)) {
66 return EFI_DEVICE_ERROR
;
71 Status
= Out8042Command ( IsaIo
, READ_CMD_BYTE
);
72 if ( EFI_ERROR ( Status
)) {
76 Status
= In8042Data ( IsaIo
, & Data
);
77 if ( EFI_ERROR ( Status
)) {
81 Status
= Out8042Command ( IsaIo
, WRITE_CMD_BYTE
);
82 if ( EFI_ERROR ( Status
)) {
87 Status
= Out8042Data ( IsaIo
, Data
);
88 if ( EFI_ERROR ( Status
)) {
97 IN EFI_ISA_IO_PROTOCOL
* IsaIo
103 GC_TODO: Add function description
107 IsaIo - GC_TODO: add argument description
111 GC_TODO: add return values
116 // Send 8042 enable mouse command
118 return Out8042Command ( IsaIo
, ENABLE_AUX
);
123 IN EFI_ISA_IO_PROTOCOL
* IsaIo
129 GC_TODO: Add function description
133 IsaIo - GC_TODO: add argument description
137 GC_TODO: add return values
142 // Send 8042 disable mouse command
144 return Out8042Command ( IsaIo
, DISABLE_AUX
);
149 IN EFI_ISA_IO_PROTOCOL
* IsaIo
155 GC_TODO: Add function description
159 IsaIo - GC_TODO: add argument description
163 GC_TODO: add return values
168 // Send 8042 enable keyboard command
170 return Out8042Command ( IsaIo
, ENABLE_KB
);
175 IN EFI_ISA_IO_PROTOCOL
* IsaIo
181 GC_TODO: Add function description
185 IsaIo - GC_TODO: add argument description
189 GC_TODO: add return values
194 // Send 8042 disable keyboard command
196 return Out8042Command ( IsaIo
, DISABLE_KB
);
201 IN EFI_ISA_IO_PROTOCOL
* IsaIo
,
202 OUT BOOLEAN
* KeyboardEnable
208 GC_TODO: Add function description
212 IsaIo - GC_TODO: add argument description
213 KeyboardEnable - GC_TODO: add argument description
217 EFI_SUCCESS - GC_TODO: Add description for return value
225 // Send command to read KBC command byte
227 Status
= Out8042Command ( IsaIo
, READ_CMD_BYTE
);
228 if ( EFI_ERROR ( Status
)) {
232 Status
= In8042Data ( IsaIo
, & Data
);
233 if ( EFI_ERROR ( Status
)) {
237 // Check keyboard enable or not
239 if (( Data
& CMD_KB_STS
) == CMD_KB_DIS
) {
240 * KeyboardEnable
= FALSE
;
242 * KeyboardEnable
= TRUE
;
250 IN EFI_ISA_IO_PROTOCOL
* IsaIo
256 GC_TODO: Add function description
260 IsaIo - GC_TODO: add argument description
264 EFI_DEVICE_ERROR - GC_TODO: Add description for return value
265 EFI_DEVICE_ERROR - GC_TODO: Add description for return value
266 EFI_SUCCESS - GC_TODO: Add description for return value
273 Status
= Out8042AuxCommand ( IsaIo
, RESET_CMD
, FALSE
);
274 if ( EFI_ERROR ( Status
)) {
278 Status
= In8042AuxData ( IsaIo
, & Data
);
279 if ( EFI_ERROR ( Status
)) {
283 // Check BAT Complete Code
285 if ( Data
!= PS2MOUSE_BAT1
) {
286 return EFI_DEVICE_ERROR
;
289 Status
= In8042AuxData ( IsaIo
, & Data
);
290 if ( EFI_ERROR ( Status
)) {
294 // Check BAT Complete Code
296 if ( Data
!= PS2MOUSE_BAT2
) {
297 return EFI_DEVICE_ERROR
;
304 PS2MouseSetSampleRate (
305 IN EFI_ISA_IO_PROTOCOL
* IsaIo
,
306 IN MOUSE_SR SampleRate
312 GC_TODO: Add function description
316 IsaIo - GC_TODO: add argument description
317 SampleRate - GC_TODO: add argument description
321 GC_TODO: add return values
328 // Send auxiliary command to set mouse sample rate
330 Status
= Out8042AuxCommand ( IsaIo
, SETSR_CMD
, FALSE
);
331 if ( EFI_ERROR ( Status
)) {
335 Status
= Out8042AuxData ( IsaIo
, SampleRateTbl
[ SampleRate
]);
341 PS2MouseSetResolution (
342 IN EFI_ISA_IO_PROTOCOL
* IsaIo
,
343 IN MOUSE_RE Resolution
349 GC_TODO: Add function description
353 IsaIo - GC_TODO: add argument description
354 Resolution - GC_TODO: add argument description
358 GC_TODO: add return values
365 // Send auxiliary command to set mouse resolution
367 Status
= Out8042AuxCommand ( IsaIo
, SETRE_CMD
, FALSE
);
368 if ( EFI_ERROR ( Status
)) {
372 Status
= Out8042AuxData ( IsaIo
, ResolutionTbl
[ Resolution
]);
379 IN EFI_ISA_IO_PROTOCOL
* IsaIo
,
386 GC_TODO: Add function description
390 IsaIo - GC_TODO: add argument description
391 Scaling - GC_TODO: add argument description
395 GC_TODO: add return values
401 Command
= ( UINT8
) ( Scaling
== SF1
? SETSF1_CMD
: SETSF2_CMD
);
404 // Send auxiliary command to set mouse scaling data
406 return Out8042AuxCommand ( IsaIo
, Command
, FALSE
);
411 IN EFI_ISA_IO_PROTOCOL
* IsaIo
417 GC_TODO: Add function description
421 IsaIo - GC_TODO: add argument description
425 GC_TODO: add return values
430 // Send auxiliary command to enable mouse
432 return Out8042AuxCommand ( IsaIo
, ENABLE_CMD
, FALSE
);
437 PS2_MOUSE_DEV
* MouseDev
443 Get mouse packet . Only care first 3 bytes
447 MouseDev - Pointer of PS2 Mouse Private Data Structure
451 EFI_NOT_READY - Mouse Device not ready to input data packet, or some error happened during getting the packet
452 EFI_SUCCESS - The data packet is gotten successfully.
457 BOOLEAN KeyboardEnable
;
458 UINT8 Packet
[ PS2_PACKET_LENGTH
];
462 INT16 RelativeMovementX
;
463 INT16 RelativeMovementY
;
467 KeyboardEnable
= FALSE
;
469 State
= PS2_READ_BYTE_ONE
;
472 // State machine to get mouse packet
477 case PS2_READ_BYTE_ONE
:
479 // Read mouse first byte data, if failed, immediately return
481 KbcDisableAux ( MouseDev
-> IsaIo
);
482 Status
= PS2MouseRead ( MouseDev
-> IsaIo
, & Data
, & Count
, State
);
483 if ( EFI_ERROR ( Status
)) {
484 KbcEnableAux ( MouseDev
-> IsaIo
);
485 return EFI_NOT_READY
;
489 KbcEnableAux ( MouseDev
-> IsaIo
);
490 return EFI_NOT_READY
;
493 if ( IS_PS2_SYNC_BYTE ( Data
)) {
495 State
= PS2_READ_DATA_BYTE
;
497 CheckKbStatus ( MouseDev
-> IsaIo
, & KeyboardEnable
);
498 KbcDisableKb ( MouseDev
-> IsaIo
);
499 KbcEnableAux ( MouseDev
-> IsaIo
);
503 case PS2_READ_DATA_BYTE
:
505 Status
= PS2MouseRead ( MouseDev
-> IsaIo
, ( Packet
+ 1 ), & Count
, State
);
506 if ( EFI_ERROR ( Status
)) {
507 if ( KeyboardEnable
) {
508 KbcEnableKb ( MouseDev
-> IsaIo
);
511 return EFI_NOT_READY
;
515 if ( KeyboardEnable
) {
516 KbcEnableKb ( MouseDev
-> IsaIo
);
519 return EFI_NOT_READY
;
522 State
= PS2_PROCESS_PACKET
;
525 case PS2_PROCESS_PACKET
:
526 if ( KeyboardEnable
) {
527 KbcEnableKb ( MouseDev
-> IsaIo
);
532 RelativeMovementX
= Packet
[ 1 ];
533 RelativeMovementY
= Packet
[ 2 ];
535 // Bit 7 | Bit 6 | Bit 5 | Bit 4 | Bit 3 | Bit 2 | Bit 1 | Bit 0
536 // Byte 0 | Y overflow | X overflow | Y sign bit | X sign bit | Always 1 | Middle Btn | Right Btn | Left Btn
537 // Byte 1 | 8 bit X Movement
538 // Byte 2 | 8 bit Y Movement
540 // 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.
541 // Y sign bit + 8 bit Y Movement : Same as X sign bit + 8 bit X Movement.
544 // First, Clear X and Y high 8 bits
546 RelativeMovementX
= ( INT16
) ( RelativeMovementX
& 0xFF );
547 RelativeMovementY
= ( INT16
) ( RelativeMovementY
& 0xFF );
549 // Second, if the 9-bit signed twos complement integer is negative, set the high 8 bit 0xff
551 if (( Packet
[ 0 ] & 0x10 ) != 0 ) {
552 RelativeMovementX
= ( INT16
) ( RelativeMovementX
| 0xFF00 );
554 if (( Packet
[ 0 ] & 0x20 ) != 0 ) {
555 RelativeMovementY
= ( INT16
) ( RelativeMovementY
| 0xFF00 );
559 RButton
= ( UINT8
) ( Packet
[ 0 ] & 0x2 );
560 LButton
= ( UINT8
) ( Packet
[ 0 ] & 0x1 );
563 // Update mouse state
565 MouseDev
-> State
. RelativeMovementX
+= RelativeMovementX
;
566 MouseDev
-> State
. RelativeMovementY
-= RelativeMovementY
;
567 MouseDev
-> State
. RightButton
= ( UINT8
) ( RButton
? TRUE
: FALSE
);
568 MouseDev
-> State
. LeftButton
= ( UINT8
) ( LButton
? TRUE
: FALSE
);
569 MouseDev
-> StateChanged
= TRUE
;
578 IN EFI_ISA_IO_PROTOCOL
* IsaIo
,
580 IN OUT UINTN
* BufSize
,
587 GC_TODO: Add function description
591 IsaIo - GC_TODO: add argument description
592 Buffer - GC_TODO: add argument description
593 BufSize - GC_TODO: add argument description
594 State - GC_TODO: add argument description
598 GC_TODO: add return values
605 Status
= EFI_SUCCESS
;
608 if ( State
== PS2_READ_BYTE_ONE
) {
610 // Check input for mouse
612 Status
= CheckForInput ( IsaIo
);
614 if ( EFI_ERROR ( Status
)) {
619 while ( BytesRead
< * BufSize
) {
621 Status
= WaitOutputFull ( IsaIo
, TIMEOUT
);
622 if ( EFI_ERROR ( Status
)) {
626 IsaIo
-> Io
. Read ( IsaIo
, EfiIsaIoWidthUint8
, KBC_DATA_PORT
, 1 , Buffer
);
629 Buffer
= ( UINT8
*) Buffer
+ 1 ;
632 // Verify the correct number of bytes read
634 if ( BytesRead
== 0 || BytesRead
!= * BufSize
) {
635 Status
= EFI_NOT_FOUND
;
638 * BufSize
= BytesRead
;
646 IN EFI_ISA_IO_PROTOCOL
* IsaIo
,
653 GC_TODO: Add function description
657 IsaIo - GC_TODO: add argument description
658 Command - GC_TODO: add argument description
662 EFI_SUCCESS - GC_TODO: Add description for return value
670 // Wait keyboard controller input buffer empty
672 Status
= WaitInputEmpty ( IsaIo
, TIMEOUT
);
673 if ( EFI_ERROR ( Status
)) {
680 IsaIo
-> Io
. Write ( IsaIo
, EfiIsaIoWidthUint8
, KBC_CMD_STS_PORT
, 1 , & Data
);
682 Status
= WaitInputEmpty ( IsaIo
, TIMEOUT
);
683 if ( EFI_ERROR ( Status
)) {
692 IN EFI_ISA_IO_PROTOCOL
* IsaIo
,
699 GC_TODO: Add function description
703 IsaIo - GC_TODO: add argument description
704 Data - GC_TODO: add argument description
708 EFI_SUCCESS - GC_TODO: Add description for return value
715 // Wait keyboard controller input buffer empty
717 Status
= WaitInputEmpty ( IsaIo
, TIMEOUT
);
718 if ( EFI_ERROR ( Status
)) {
723 IsaIo
-> Io
. Write ( IsaIo
, EfiIsaIoWidthUint8
, KBC_DATA_PORT
, 1 , & temp
);
725 Status
= WaitInputEmpty ( IsaIo
, TIMEOUT
);
726 if ( EFI_ERROR ( Status
)) {
735 IN EFI_ISA_IO_PROTOCOL
* IsaIo
,
742 GC_TODO: Add function description
746 IsaIo - GC_TODO: add argument description
747 Data - GC_TODO: add argument description
751 EFI_TIMEOUT - GC_TODO: Add description for return value
752 EFI_SUCCESS - GC_TODO: Add description for return value
759 Delay
= TIMEOUT
/ 50 ;
762 IsaIo
-> Io
. Read ( IsaIo
, EfiIsaIoWidthUint8
, KBC_CMD_STS_PORT
, 1 , & temp
);
765 // Check keyboard controller status bit 0(output buffer status)
767 if (( temp
& KBC_OUTB
) == KBC_OUTB
) {
779 IsaIo
-> Io
. Read ( IsaIo
, EfiIsaIoWidthUint8
, KBC_DATA_PORT
, 1 , Data
);
786 IN EFI_ISA_IO_PROTOCOL
* IsaIo
,
794 GC_TODO: Add function description
798 IsaIo - GC_TODO: add argument description
799 Command - GC_TODO: add argument description
800 Resend - GC_TODO: add argument description
804 EFI_SUCCESS - GC_TODO: Add description for return value
805 EFI_DEVICE_ERROR - GC_TODO: Add description for return value
806 EFI_DEVICE_ERROR - GC_TODO: Add description for return value
807 EFI_SUCCESS - GC_TODO: Add description for return value
815 // Wait keyboard controller input buffer empty
817 Status
= WaitInputEmpty ( IsaIo
, TIMEOUT
);
818 if ( EFI_ERROR ( Status
)) {
822 // Send write to auxiliary device command
824 Data
= WRITE_AUX_DEV
;
825 IsaIo
-> Io
. Write ( IsaIo
, EfiIsaIoWidthUint8
, KBC_CMD_STS_PORT
, 1 , & Data
);
827 Status
= WaitInputEmpty ( IsaIo
, TIMEOUT
);
828 if ( EFI_ERROR ( Status
)) {
832 // Send auxiliary device command
834 IsaIo
-> Io
. Write ( IsaIo
, EfiIsaIoWidthUint8
, KBC_DATA_PORT
, 1 , & Command
);
839 Status
= In8042AuxData ( IsaIo
, & Data
);
840 if ( EFI_ERROR ( Status
)) {
844 if ( Data
== PS2_ACK
) {
846 // Receive mouse acknowledge, command send success
854 return EFI_DEVICE_ERROR
;
856 } else if ( Data
== PS2_RESEND
) {
860 Status
= Out8042AuxCommand ( IsaIo
, Command
, TRUE
);
861 if ( EFI_ERROR ( Status
)) {
867 // Invalid return code
869 return EFI_DEVICE_ERROR
;
878 IN EFI_ISA_IO_PROTOCOL
* IsaIo
,
885 GC_TODO: Add function description
889 IsaIo - GC_TODO: add argument description
890 Data - GC_TODO: add argument description
894 EFI_SUCCESS - GC_TODO: Add description for return value
901 // Wait keyboard controller input buffer empty
903 Status
= WaitInputEmpty ( IsaIo
, TIMEOUT
);
904 if ( EFI_ERROR ( Status
)) {
908 // Send write to auxiliary device command
910 Temp
= WRITE_AUX_DEV
;
911 IsaIo
-> Io
. Write ( IsaIo
, EfiIsaIoWidthUint8
, KBC_CMD_STS_PORT
, 1 , & Temp
);
913 Status
= WaitInputEmpty ( IsaIo
, TIMEOUT
);
914 if ( EFI_ERROR ( Status
)) {
919 IsaIo
-> Io
. Write ( IsaIo
, EfiIsaIoWidthUint8
, KBC_DATA_PORT
, 1 , & Temp
);
921 Status
= WaitInputEmpty ( IsaIo
, TIMEOUT
);
922 if ( EFI_ERROR ( Status
)) {
931 IN EFI_ISA_IO_PROTOCOL
* IsaIo
,
938 GC_TODO: Add function description
942 IsaIo - GC_TODO: add argument description
943 Data - GC_TODO: add argument description
947 EFI_SUCCESS - GC_TODO: Add description for return value
954 // wait for output data
956 Status
= WaitOutputFull ( IsaIo
, BAT_TIMEOUT
);
957 if ( EFI_ERROR ( Status
)) {
961 IsaIo
-> Io
. Read ( IsaIo
, EfiIsaIoWidthUint8
, KBC_DATA_PORT
, 1 , Data
);
968 IN EFI_ISA_IO_PROTOCOL
* IsaIo
974 GC_TODO: Add function description
978 IsaIo - GC_TODO: add argument description
982 EFI_NOT_READY - GC_TODO: Add description for return value
983 EFI_SUCCESS - GC_TODO: Add description for return value
989 IsaIo
-> Io
. Read ( IsaIo
, EfiIsaIoWidthUint8
, KBC_CMD_STS_PORT
, 1 , & Data
);
992 // Check keyboard controller status, if it is output buffer full and for auxiliary device
994 if (( Data
& ( KBC_OUTB
| KBC_AUXB
)) != ( KBC_OUTB
| KBC_AUXB
)) {
995 return EFI_NOT_READY
;
1003 IN EFI_ISA_IO_PROTOCOL
* IsaIo
,
1008 Routine Description:
1010 GC_TODO: Add function description
1014 IsaIo - GC_TODO: add argument description
1015 Timeout - GC_TODO: add argument description
1019 EFI_TIMEOUT - GC_TODO: Add description for return value
1020 EFI_SUCCESS - GC_TODO: Add description for return value
1027 Delay
= Timeout
/ 50 ;
1030 IsaIo
-> Io
. Read ( IsaIo
, EfiIsaIoWidthUint8
, KBC_CMD_STS_PORT
, 1 , & Data
);
1033 // Check keyboard controller status bit 1(input buffer status)
1035 if (( Data
& KBC_INPB
) == 0 ) {
1052 IN EFI_ISA_IO_PROTOCOL
* IsaIo
,
1057 Routine Description:
1059 GC_TODO: Add function description
1063 IsaIo - GC_TODO: add argument description
1064 Timeout - GC_TODO: add argument description
1068 EFI_TIMEOUT - GC_TODO: Add description for return value
1069 EFI_SUCCESS - GC_TODO: Add description for return value
1076 Delay
= Timeout
/ 50 ;
1079 IsaIo
-> Io
. Read ( IsaIo
, EfiIsaIoWidthUint8
, KBC_CMD_STS_PORT
, 1 , & Data
);
1082 // Check keyboard controller status bit 0(output buffer status)
1083 // & bit5(output buffer for auxiliary device)
1085 if (( Data
& ( KBC_OUTB
| KBC_AUXB
)) == ( KBC_OUTB
| KBC_AUXB
)) {