]>
git.proxmox.com Git - mirror_edk2.git/blob - IntelFrameworkModulePkg/Bus/Isa/Ps2MouseDxe/CommPs2.c
2 PS2 Mouse Communication Interface
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
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.
18 UINT8 SampleRateTbl
[ MAX_SR
] = { 0xa , 0x14 , 0x28 , 0x3c , 0x50 , 0x64 , 0xc8 };
20 UINT8 ResolutionTbl
[ MAX_CMR
] = { 0 , 1 , 2 , 3 };
24 IN EFI_ISA_IO_PROTOCOL
* IsaIo
30 GC_TODO: Add function description
34 IsaIo - GC_TODO: add argument description
38 EFI_DEVICE_ERROR - GC_TODO: Add description for return value
39 EFI_SUCCESS - GC_TODO: Add description for return value
47 // Keyboard controller self test
49 Status
= Out8042Command ( IsaIo
, SELF_TEST
);
50 if ( EFI_ERROR ( Status
)) {
56 Status
= In8042Data ( IsaIo
, & Data
);
57 if ( EFI_ERROR ( Status
)) {
62 return EFI_DEVICE_ERROR
;
67 Status
= Out8042Command ( IsaIo
, READ_CMD_BYTE
);
68 if ( EFI_ERROR ( Status
)) {
72 Status
= In8042Data ( IsaIo
, & Data
);
73 if ( EFI_ERROR ( Status
)) {
77 Status
= Out8042Command ( IsaIo
, WRITE_CMD_BYTE
);
78 if ( EFI_ERROR ( Status
)) {
83 Status
= Out8042Data ( IsaIo
, Data
);
84 if ( EFI_ERROR ( Status
)) {
93 IN EFI_ISA_IO_PROTOCOL
* IsaIo
99 GC_TODO: Add function description
103 IsaIo - GC_TODO: add argument description
107 GC_TODO: add return values
112 // Send 8042 enable mouse command
114 return Out8042Command ( IsaIo
, ENABLE_AUX
);
119 IN EFI_ISA_IO_PROTOCOL
* IsaIo
125 GC_TODO: Add function description
129 IsaIo - GC_TODO: add argument description
133 GC_TODO: add return values
138 // Send 8042 disable mouse command
140 return Out8042Command ( IsaIo
, DISABLE_AUX
);
145 IN EFI_ISA_IO_PROTOCOL
* IsaIo
151 GC_TODO: Add function description
155 IsaIo - GC_TODO: add argument description
159 GC_TODO: add return values
164 // Send 8042 enable keyboard command
166 return Out8042Command ( IsaIo
, ENABLE_KB
);
171 IN EFI_ISA_IO_PROTOCOL
* IsaIo
177 GC_TODO: Add function description
181 IsaIo - GC_TODO: add argument description
185 GC_TODO: add return values
190 // Send 8042 disable keyboard command
192 return Out8042Command ( IsaIo
, DISABLE_KB
);
197 IN EFI_ISA_IO_PROTOCOL
* IsaIo
,
198 OUT BOOLEAN
* KeyboardEnable
204 GC_TODO: Add function description
208 IsaIo - GC_TODO: add argument description
209 KeyboardEnable - GC_TODO: add argument description
213 EFI_SUCCESS - GC_TODO: Add description for return value
221 // Send command to read KBC command byte
223 Status
= Out8042Command ( IsaIo
, READ_CMD_BYTE
);
224 if ( EFI_ERROR ( Status
)) {
228 Status
= In8042Data ( IsaIo
, & Data
);
229 if ( EFI_ERROR ( Status
)) {
233 // Check keyboard enable or not
235 if (( Data
& CMD_KB_STS
) == CMD_KB_DIS
) {
236 * KeyboardEnable
= FALSE
;
238 * KeyboardEnable
= TRUE
;
246 IN EFI_ISA_IO_PROTOCOL
* IsaIo
252 GC_TODO: Add function description
256 IsaIo - GC_TODO: add argument description
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
269 Status
= Out8042AuxCommand ( IsaIo
, RESET_CMD
, FALSE
);
270 if ( EFI_ERROR ( Status
)) {
274 Status
= In8042AuxData ( IsaIo
, & Data
);
275 if ( EFI_ERROR ( Status
)) {
279 // Check BAT Complete Code
281 if ( Data
!= PS2MOUSE_BAT1
) {
282 return EFI_DEVICE_ERROR
;
285 Status
= In8042AuxData ( IsaIo
, & Data
);
286 if ( EFI_ERROR ( Status
)) {
290 // Check BAT Complete Code
292 if ( Data
!= PS2MOUSE_BAT2
) {
293 return EFI_DEVICE_ERROR
;
300 PS2MouseSetSampleRate (
301 IN EFI_ISA_IO_PROTOCOL
* IsaIo
,
302 IN MOUSE_SR SampleRate
308 GC_TODO: Add function description
312 IsaIo - GC_TODO: add argument description
313 SampleRate - GC_TODO: add argument description
317 GC_TODO: add return values
324 // Send auxiliary command to set mouse sample rate
326 Status
= Out8042AuxCommand ( IsaIo
, SETSR_CMD
, FALSE
);
327 if ( EFI_ERROR ( Status
)) {
331 Status
= Out8042AuxData ( IsaIo
, SampleRateTbl
[ SampleRate
]);
337 PS2MouseSetResolution (
338 IN EFI_ISA_IO_PROTOCOL
* IsaIo
,
339 IN MOUSE_RE Resolution
345 GC_TODO: Add function description
349 IsaIo - GC_TODO: add argument description
350 Resolution - GC_TODO: add argument description
354 GC_TODO: add return values
361 // Send auxiliary command to set mouse resolution
363 Status
= Out8042AuxCommand ( IsaIo
, SETRE_CMD
, FALSE
);
364 if ( EFI_ERROR ( Status
)) {
368 Status
= Out8042AuxData ( IsaIo
, ResolutionTbl
[ Resolution
]);
375 IN EFI_ISA_IO_PROTOCOL
* IsaIo
,
382 GC_TODO: Add function description
386 IsaIo - GC_TODO: add argument description
387 Scaling - GC_TODO: add argument description
391 GC_TODO: add return values
397 Command
= ( UINT8
) ( Scaling
== SF1
? SETSF1_CMD
: SETSF2_CMD
);
400 // Send auxiliary command to set mouse scaling data
402 return Out8042AuxCommand ( IsaIo
, Command
, FALSE
);
407 IN EFI_ISA_IO_PROTOCOL
* IsaIo
413 GC_TODO: Add function description
417 IsaIo - GC_TODO: add argument description
421 GC_TODO: add return values
426 // Send auxiliary command to enable mouse
428 return Out8042AuxCommand ( IsaIo
, ENABLE_CMD
, FALSE
);
433 PS2_MOUSE_DEV
* MouseDev
439 Get mouse packet . Only care first 3 bytes
443 MouseDev - Pointer of PS2 Mouse Private Data Structure
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.
453 BOOLEAN KeyboardEnable
;
454 UINT8 Packet
[ PS2_PACKET_LENGTH
];
458 INT16 RelativeMovementX
;
459 INT16 RelativeMovementY
;
463 KeyboardEnable
= FALSE
;
465 State
= PS2_READ_BYTE_ONE
;
468 // State machine to get mouse packet
473 case PS2_READ_BYTE_ONE
:
475 // Read mouse first byte data, if failed, immediately return
477 KbcDisableAux ( MouseDev
-> IsaIo
);
478 Status
= PS2MouseRead ( MouseDev
-> IsaIo
, & Data
, & Count
, State
);
479 if ( EFI_ERROR ( Status
)) {
480 KbcEnableAux ( MouseDev
-> IsaIo
);
481 return EFI_NOT_READY
;
485 KbcEnableAux ( MouseDev
-> IsaIo
);
486 return EFI_NOT_READY
;
489 if ( IS_PS2_SYNC_BYTE ( Data
)) {
491 State
= PS2_READ_DATA_BYTE
;
493 CheckKbStatus ( MouseDev
-> IsaIo
, & KeyboardEnable
);
494 KbcDisableKb ( MouseDev
-> IsaIo
);
495 KbcEnableAux ( MouseDev
-> IsaIo
);
499 case PS2_READ_DATA_BYTE
:
501 Status
= PS2MouseRead ( MouseDev
-> IsaIo
, ( Packet
+ 1 ), & Count
, State
);
502 if ( EFI_ERROR ( Status
)) {
503 if ( KeyboardEnable
) {
504 KbcEnableKb ( MouseDev
-> IsaIo
);
507 return EFI_NOT_READY
;
511 if ( KeyboardEnable
) {
512 KbcEnableKb ( MouseDev
-> IsaIo
);
515 return EFI_NOT_READY
;
518 State
= PS2_PROCESS_PACKET
;
521 case PS2_PROCESS_PACKET
:
522 if ( KeyboardEnable
) {
523 KbcEnableKb ( MouseDev
-> IsaIo
);
528 RelativeMovementX
= Packet
[ 1 ];
529 RelativeMovementY
= Packet
[ 2 ];
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
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.
540 // First, Clear X and Y high 8 bits
542 RelativeMovementX
= ( INT16
) ( RelativeMovementX
& 0xFF );
543 RelativeMovementY
= ( INT16
) ( RelativeMovementY
& 0xFF );
545 // Second, if the 9-bit signed twos complement integer is negative, set the high 8 bit 0xff
547 if (( Packet
[ 0 ] & 0x10 ) != 0 ) {
548 RelativeMovementX
= ( INT16
) ( RelativeMovementX
| 0xFF00 );
550 if (( Packet
[ 0 ] & 0x20 ) != 0 ) {
551 RelativeMovementY
= ( INT16
) ( RelativeMovementY
| 0xFF00 );
555 RButton
= ( UINT8
) ( Packet
[ 0 ] & 0x2 );
556 LButton
= ( UINT8
) ( Packet
[ 0 ] & 0x1 );
559 // Update mouse state
561 MouseDev
-> State
. RelativeMovementX
+= RelativeMovementX
;
562 MouseDev
-> State
. RelativeMovementY
-= RelativeMovementY
;
563 MouseDev
-> State
. RightButton
= ( UINT8
) ( RButton
? TRUE
: FALSE
);
564 MouseDev
-> State
. LeftButton
= ( UINT8
) ( LButton
? TRUE
: FALSE
);
565 MouseDev
-> StateChanged
= TRUE
;
574 IN EFI_ISA_IO_PROTOCOL
* IsaIo
,
576 IN OUT UINTN
* BufSize
,
583 GC_TODO: Add function description
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
594 GC_TODO: add return values
601 Status
= EFI_SUCCESS
;
604 if ( State
== PS2_READ_BYTE_ONE
) {
606 // Check input for mouse
608 Status
= CheckForInput ( IsaIo
);
610 if ( EFI_ERROR ( Status
)) {
615 while ( BytesRead
< * BufSize
) {
617 Status
= WaitOutputFull ( IsaIo
, TIMEOUT
);
618 if ( EFI_ERROR ( Status
)) {
622 IsaIo
-> Io
. Read ( IsaIo
, EfiIsaIoWidthUint8
, KBC_DATA_PORT
, 1 , Buffer
);
625 Buffer
= ( UINT8
*) Buffer
+ 1 ;
628 // Verify the correct number of bytes read
630 if ( BytesRead
== 0 || BytesRead
!= * BufSize
) {
631 Status
= EFI_NOT_FOUND
;
634 * BufSize
= BytesRead
;
642 IN EFI_ISA_IO_PROTOCOL
* IsaIo
,
649 GC_TODO: Add function description
653 IsaIo - GC_TODO: add argument description
654 Command - GC_TODO: add argument description
658 EFI_SUCCESS - GC_TODO: Add description for return value
666 // Wait keyboard controller input buffer empty
668 Status
= WaitInputEmpty ( IsaIo
, TIMEOUT
);
669 if ( EFI_ERROR ( Status
)) {
676 IsaIo
-> Io
. Write ( IsaIo
, EfiIsaIoWidthUint8
, KBC_CMD_STS_PORT
, 1 , & Data
);
678 Status
= WaitInputEmpty ( IsaIo
, TIMEOUT
);
679 if ( EFI_ERROR ( Status
)) {
688 IN EFI_ISA_IO_PROTOCOL
* IsaIo
,
695 GC_TODO: Add function description
699 IsaIo - GC_TODO: add argument description
700 Data - GC_TODO: add argument description
704 EFI_SUCCESS - GC_TODO: Add description for return value
711 // Wait keyboard controller input buffer empty
713 Status
= WaitInputEmpty ( IsaIo
, TIMEOUT
);
714 if ( EFI_ERROR ( Status
)) {
719 IsaIo
-> Io
. Write ( IsaIo
, EfiIsaIoWidthUint8
, KBC_DATA_PORT
, 1 , & temp
);
721 Status
= WaitInputEmpty ( IsaIo
, TIMEOUT
);
722 if ( EFI_ERROR ( Status
)) {
731 IN EFI_ISA_IO_PROTOCOL
* IsaIo
,
738 GC_TODO: Add function description
742 IsaIo - GC_TODO: add argument description
743 Data - GC_TODO: add argument description
747 EFI_TIMEOUT - GC_TODO: Add description for return value
748 EFI_SUCCESS - GC_TODO: Add description for return value
755 Delay
= TIMEOUT
/ 50 ;
758 IsaIo
-> Io
. Read ( IsaIo
, EfiIsaIoWidthUint8
, KBC_CMD_STS_PORT
, 1 , & temp
);
761 // Check keyboard controller status bit 0(output buffer status)
763 if (( temp
& KBC_OUTB
) == KBC_OUTB
) {
775 IsaIo
-> Io
. Read ( IsaIo
, EfiIsaIoWidthUint8
, KBC_DATA_PORT
, 1 , Data
);
782 IN EFI_ISA_IO_PROTOCOL
* IsaIo
,
790 GC_TODO: Add function description
794 IsaIo - GC_TODO: add argument description
795 Command - GC_TODO: add argument description
796 Resend - GC_TODO: add argument description
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
811 // Wait keyboard controller input buffer empty
813 Status
= WaitInputEmpty ( IsaIo
, TIMEOUT
);
814 if ( EFI_ERROR ( Status
)) {
818 // Send write to auxiliary device command
820 Data
= WRITE_AUX_DEV
;
821 IsaIo
-> Io
. Write ( IsaIo
, EfiIsaIoWidthUint8
, KBC_CMD_STS_PORT
, 1 , & Data
);
823 Status
= WaitInputEmpty ( IsaIo
, TIMEOUT
);
824 if ( EFI_ERROR ( Status
)) {
828 // Send auxiliary device command
830 IsaIo
-> Io
. Write ( IsaIo
, EfiIsaIoWidthUint8
, KBC_DATA_PORT
, 1 , & Command
);
835 Status
= In8042AuxData ( IsaIo
, & Data
);
836 if ( EFI_ERROR ( Status
)) {
840 if ( Data
== PS2_ACK
) {
842 // Receive mouse acknowledge, command send success
850 return EFI_DEVICE_ERROR
;
852 } else if ( Data
== PS2_RESEND
) {
856 Status
= Out8042AuxCommand ( IsaIo
, Command
, TRUE
);
857 if ( EFI_ERROR ( Status
)) {
863 // Invalid return code
865 return EFI_DEVICE_ERROR
;
874 IN EFI_ISA_IO_PROTOCOL
* IsaIo
,
881 GC_TODO: Add function description
885 IsaIo - GC_TODO: add argument description
886 Data - GC_TODO: add argument description
890 EFI_SUCCESS - GC_TODO: Add description for return value
897 // Wait keyboard controller input buffer empty
899 Status
= WaitInputEmpty ( IsaIo
, TIMEOUT
);
900 if ( EFI_ERROR ( Status
)) {
904 // Send write to auxiliary device command
906 Temp
= WRITE_AUX_DEV
;
907 IsaIo
-> Io
. Write ( IsaIo
, EfiIsaIoWidthUint8
, KBC_CMD_STS_PORT
, 1 , & Temp
);
909 Status
= WaitInputEmpty ( IsaIo
, TIMEOUT
);
910 if ( EFI_ERROR ( Status
)) {
915 IsaIo
-> Io
. Write ( IsaIo
, EfiIsaIoWidthUint8
, KBC_DATA_PORT
, 1 , & Temp
);
917 Status
= WaitInputEmpty ( IsaIo
, TIMEOUT
);
918 if ( EFI_ERROR ( Status
)) {
927 IN EFI_ISA_IO_PROTOCOL
* IsaIo
,
934 GC_TODO: Add function description
938 IsaIo - GC_TODO: add argument description
939 Data - GC_TODO: add argument description
943 EFI_SUCCESS - GC_TODO: Add description for return value
950 // wait for output data
952 Status
= WaitOutputFull ( IsaIo
, BAT_TIMEOUT
);
953 if ( EFI_ERROR ( Status
)) {
957 IsaIo
-> Io
. Read ( IsaIo
, EfiIsaIoWidthUint8
, KBC_DATA_PORT
, 1 , Data
);
964 IN EFI_ISA_IO_PROTOCOL
* IsaIo
970 GC_TODO: Add function description
974 IsaIo - GC_TODO: add argument description
978 EFI_NOT_READY - GC_TODO: Add description for return value
979 EFI_SUCCESS - GC_TODO: Add description for return value
985 IsaIo
-> Io
. Read ( IsaIo
, EfiIsaIoWidthUint8
, KBC_CMD_STS_PORT
, 1 , & Data
);
988 // Check keyboard controller status, if it is output buffer full and for auxiliary device
990 if (( Data
& ( KBC_OUTB
| KBC_AUXB
)) != ( KBC_OUTB
| KBC_AUXB
)) {
991 return EFI_NOT_READY
;
999 IN EFI_ISA_IO_PROTOCOL
* IsaIo
,
1004 Routine Description:
1006 GC_TODO: Add function description
1010 IsaIo - GC_TODO: add argument description
1011 Timeout - GC_TODO: add argument description
1015 EFI_TIMEOUT - GC_TODO: Add description for return value
1016 EFI_SUCCESS - GC_TODO: Add description for return value
1023 Delay
= Timeout
/ 50 ;
1026 IsaIo
-> Io
. Read ( IsaIo
, EfiIsaIoWidthUint8
, KBC_CMD_STS_PORT
, 1 , & Data
);
1029 // Check keyboard controller status bit 1(input buffer status)
1031 if (( Data
& KBC_INPB
) == 0 ) {
1048 IN EFI_ISA_IO_PROTOCOL
* IsaIo
,
1053 Routine Description:
1055 GC_TODO: Add function description
1059 IsaIo - GC_TODO: add argument description
1060 Timeout - GC_TODO: add argument description
1064 EFI_TIMEOUT - GC_TODO: Add description for return value
1065 EFI_SUCCESS - GC_TODO: Add description for return value
1072 Delay
= Timeout
/ 50 ;
1075 IsaIo
-> Io
. Read ( IsaIo
, EfiIsaIoWidthUint8
, KBC_CMD_STS_PORT
, 1 , & Data
);
1078 // Check keyboard controller status bit 0(output buffer status)
1079 // & bit5(output buffer for auxiliary device)
1081 if (( Data
& ( KBC_OUTB
| KBC_AUXB
)) == ( KBC_OUTB
| KBC_AUXB
)) {