Synchronize up to trunk's revision r57784.
[reactos.git] / drivers / input / i8042prt / ps2pp.c
1 /*
2 * PROJECT: ReactOS i8042 (ps/2 keyboard-mouse controller) driver
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: drivers/input/i8042prt/ps2pp.c
5 * PURPOSE: ps2pp protocol handling
6 * PROGRAMMERS: Copyright Martijn Vernooij (o112w8r02@sneakemail.com)
7 * Copyright 2006-2007 Hervé Poussineau (hpoussin@reactos.org)
8 */
9
10 /* INCLUDES ****************************************************************/
11
12 #include "i8042prt.h"
13
14 /* FUNCTIONS *****************************************************************/
15
16 VOID
17 i8042MouHandlePs2pp(
18 IN PI8042_MOUSE_EXTENSION DeviceExtension,
19 IN UCHAR Input)
20 {
21 UCHAR PktType;
22 PMOUSE_INPUT_DATA MouseInput;
23
24 MouseInput = DeviceExtension->MouseBuffer + DeviceExtension->MouseInBuffer;
25
26 /* First, collect 3 bytes for a packet
27 * We can detect out-of-sync only by checking
28 * the whole packet anyway.
29 *
30 * If bit 7 and 8 of the first byte are 0, its
31 * a normal packet.
32 *
33 * Otherwise, the packet is different, like this:
34 * 1: E 1 b3 b2 1 x x x
35 * 2: x x b1 b0 x1 x0 1 0
36 * 3: x x x x x x x1 x0
37 *
38 * b3-0 form a code that specifies the packet type:
39 *
40 * 0 Device Type
41 * 1 Rollers and buttons
42 * 2 Reserved
43 * 3 Reserved
44 * 4 Device ID
45 * 5 Channel & Battery
46 * 6 Wireless notifications
47 * 7 Reserved
48 * 8 ShortID LSB (ShortID is a number that is supposed to differentiate
49 * 9 ShortID MSB between your mouse and your neighbours')
50 * 10 Reserved
51 * 11 Mouse capabilities
52 * 12 Remote control LSB
53 * 13 Remote control MSB
54 * 14 Reserved
55 * 15 Extended packet
56 */
57
58 switch (DeviceExtension->MouseState)
59 {
60 case MouseIdle:
61 case XMovement:
62 DeviceExtension->MouseLogiBuffer[DeviceExtension->MouseState] = Input;
63 DeviceExtension->MouseState++;
64 break;
65
66 case YMovement:
67 DeviceExtension->MouseLogiBuffer[2] = Input;
68 DeviceExtension->MouseState = MouseIdle;
69
70 /* first check if it's a normal packet */
71
72 if (!(DeviceExtension->MouseLogiBuffer[0] & 0xC0))
73 {
74 DeviceExtension->MouseState = MouseIdle;
75 i8042MouHandle(DeviceExtension, DeviceExtension->MouseLogiBuffer[0]);
76 i8042MouHandle(DeviceExtension, DeviceExtension->MouseLogiBuffer[1]);
77 i8042MouHandle(DeviceExtension, DeviceExtension->MouseLogiBuffer[2]);
78 /* We could care about wether MouseState really
79 * advances, but we don't need to because we're
80 * only doing three bytes anyway, so the packet
81 * will never complete if it's broken.
82 */
83 return;
84 }
85
86 /* sanity check */
87 if (((DeviceExtension->MouseLogiBuffer[0] & 0x48) != 0x48) ||
88 (((DeviceExtension->MouseLogiBuffer[1] & 0x0C) >> 2) !=
89 (DeviceExtension->MouseLogiBuffer[2] & 0x03)))
90 {
91 WARN_(I8042PRT, "Ps2pp packet fails sanity checks\n");
92 return;
93 }
94
95 /* Now get the packet type */
96 PktType = ((DeviceExtension->MouseLogiBuffer[0] & 0x30) >> 2) |
97 ((DeviceExtension->MouseLogiBuffer[1] & 0x30) >> 4);
98
99 switch (PktType)
100 {
101 case 0:
102 /* The packet contains the device ID, but we
103 * already read that in the initialization
104 * sequence. Ignore it.
105 */
106 return;
107 case 1:
108 RtlZeroMemory(MouseInput, sizeof(MOUSE_INPUT_DATA));
109 if (DeviceExtension->MouseLogiBuffer[2] & 0x10)
110 MouseInput->RawButtons |= MOUSE_BUTTON_4_DOWN;
111
112 if (DeviceExtension->MouseLogiBuffer[2] & 0x20)
113 MouseInput->RawButtons |= MOUSE_BUTTON_5_DOWN;
114
115 if (DeviceExtension->MouseLogiBuffer[2] & 0x0F)
116 {
117 MouseInput->ButtonFlags |= MOUSE_WHEEL;
118 if (DeviceExtension->MouseLogiBuffer[2] & 0x08)
119 MouseInput->ButtonData = (DeviceExtension->MouseLogiBuffer[2] & 0x07) - 8;
120 else
121 MouseInput->ButtonData = DeviceExtension->MouseLogiBuffer[2] & 0x07;
122 }
123 i8042MouHandleButtons(
124 DeviceExtension,
125 MOUSE_BUTTON_4_DOWN | MOUSE_BUTTON_5_DOWN);
126 DeviceExtension->MouseHook.QueueMousePacket(DeviceExtension->MouseHook.CallContext);
127 return;
128 default:
129 /* These are for things that would probably
130 * be handled by logitechs own driver.
131 */
132 return;
133 }
134
135 default:
136 WARN_(I8042PRT, "Unexpected input state for ps2pp!\n");
137 }
138 }