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