diff options
Diffstat (limited to 'MdeModulePkg/Bus/Usb/UsbMouseDxe/MouseHid.c')
-rw-r--r-- | MdeModulePkg/Bus/Usb/UsbMouseDxe/MouseHid.c | 362 |
1 files changed, 362 insertions, 0 deletions
diff --git a/MdeModulePkg/Bus/Usb/UsbMouseDxe/MouseHid.c b/MdeModulePkg/Bus/Usb/UsbMouseDxe/MouseHid.c new file mode 100644 index 0000000000..6490b090c0 --- /dev/null +++ b/MdeModulePkg/Bus/Usb/UsbMouseDxe/MouseHid.c @@ -0,0 +1,362 @@ +/** @file
+
+Copyright (c) 2004, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ Mousehid.c
+
+Abstract:
+ Parse mouse hid descriptor
+
+
+**/
+
+#include "mousehid.h"
+
+
+//
+// Get an item from report descriptor
+//
+
+/**
+ Get Next Item
+
+ @param StartPos Start Position
+ @param EndPos End Position
+ @param HidItem HidItem to return
+
+ @return Position
+
+**/
+STATIC
+UINT8 *
+GetNextItem (
+ IN UINT8 *StartPos,
+ IN UINT8 *EndPos,
+ OUT HID_ITEM *HidItem
+ )
+{
+ UINT8 Temp;
+
+ if ((EndPos - StartPos) <= 0) {
+ return NULL;
+ }
+
+ Temp = *StartPos;
+ StartPos++;
+ //
+ // bit 2,3
+ //
+ HidItem->Type = (UINT8) ((Temp >> 2) & 0x03);
+ //
+ // bit 4-7
+ //
+ HidItem->Tag = (UINT8) ((Temp >> 4) & 0x0F);
+
+ if (HidItem->Tag == HID_ITEM_TAG_LONG) {
+ //
+ // Long Items are not supported by HID rev1.0,
+ // although we try to parse it.
+ //
+ HidItem->Format = HID_ITEM_FORMAT_LONG;
+
+ if ((EndPos - StartPos) >= 2) {
+ HidItem->Size = *StartPos++;
+ HidItem->Tag = *StartPos++;
+
+ if ((EndPos - StartPos) >= HidItem->Size) {
+ HidItem->Data.LongData = StartPos;
+ StartPos += HidItem->Size;
+ return StartPos;
+ }
+ }
+ } else {
+ HidItem->Format = HID_ITEM_FORMAT_SHORT;
+ //
+ // bit 0, 1
+ //
+ HidItem->Size = (UINT8) (Temp & 0x03);
+ switch (HidItem->Size) {
+
+ case 0:
+ //
+ // No data
+ //
+ return StartPos;
+
+ case 1:
+ //
+ // One byte data
+ //
+ if ((EndPos - StartPos) >= 1) {
+ HidItem->Data.U8 = *StartPos++;
+ return StartPos;
+ }
+
+ case 2:
+ //
+ // Two byte data
+ //
+ if ((EndPos - StartPos) >= 2) {
+ CopyMem (&HidItem->Data.U16, StartPos, sizeof (UINT16));
+ StartPos += 2;
+ return StartPos;
+ }
+
+ case 3:
+ //
+ // 4 byte data, adjust size
+ //
+ HidItem->Size++;
+ if ((EndPos - StartPos) >= 4) {
+ CopyMem (&HidItem->Data.U32, StartPos, sizeof (UINT32));
+ StartPos += 4;
+ return StartPos;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+
+/**
+ Get Item Data
+
+ @param HidItem HID_ITEM
+
+ @return HidItem Data
+
+**/
+STATIC
+UINT32
+GetItemData (
+ IN HID_ITEM *HidItem
+ )
+{
+ //
+ // Get Data from HID_ITEM structure
+ //
+ switch (HidItem->Size) {
+
+ case 1:
+ return HidItem->Data.U8;
+
+ case 2:
+ return HidItem->Data.U16;
+
+ case 4:
+ return HidItem->Data.U32;
+ }
+
+ return 0;
+}
+
+
+/**
+ Parse Local Item
+
+ @param UsbMouse USB_MOUSE_DEV
+ @param LocalItem Local Item
+
+
+**/
+STATIC
+VOID
+ParseLocalItem (
+ IN USB_MOUSE_DEV *UsbMouse,
+ IN HID_ITEM *LocalItem
+ )
+{
+ UINT32 Data;
+
+ if (LocalItem->Size == 0) {
+ //
+ // No expected data for local item
+ //
+ return ;
+ }
+
+ Data = GetItemData (LocalItem);
+
+ switch (LocalItem->Tag) {
+
+ case HID_LOCAL_ITEM_TAG_DELIMITER:
+ //
+ // we don't support delimiter here
+ //
+ return ;
+
+ case HID_LOCAL_ITEM_TAG_USAGE:
+ return ;
+
+ case HID_LOCAL_ITEM_TAG_USAGE_MINIMUM:
+ if (UsbMouse->PrivateData.ButtonDetected) {
+ UsbMouse->PrivateData.ButtonMinIndex = (UINT8) Data;
+ }
+
+ return ;
+
+ case HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM:
+ {
+ if (UsbMouse->PrivateData.ButtonDetected) {
+ UsbMouse->PrivateData.ButtonMaxIndex = (UINT8) Data;
+ }
+
+ return ;
+ }
+ }
+}
+
+STATIC
+VOID
+ParseGlobalItem (
+ IN USB_MOUSE_DEV *UsbMouse,
+ IN HID_ITEM *GlobalItem
+ )
+{
+ UINT8 UsagePage;
+
+ switch (GlobalItem->Tag) {
+ case HID_GLOBAL_ITEM_TAG_USAGE_PAGE:
+ {
+ UsagePage = (UINT8) GetItemData (GlobalItem);
+
+ //
+ // We only care Button Page here
+ //
+ if (UsagePage == 0x09) {
+ //
+ // Button Page
+ //
+ UsbMouse->PrivateData.ButtonDetected = TRUE;
+ return ;
+ }
+ break;
+ }
+
+ }
+}
+
+
+
+/**
+ Parse Main Item
+
+ @param UsbMouse TODO: add argument description
+ @param MainItem HID_ITEM to parse
+
+ @return VOID
+
+**/
+STATIC
+VOID
+ParseMainItem (
+ IN USB_MOUSE_DEV *UsbMouse,
+ IN HID_ITEM *MainItem
+ )
+{
+ //
+ // we don't care any main items, just skip
+ //
+ return ;
+}
+
+
+/**
+ Parse Hid Item
+
+ @param UsbMouse USB_MOUSE_DEV
+ @param HidItem HidItem to parse
+
+ @return VOID
+
+**/
+STATIC
+VOID
+ParseHidItem (
+ IN USB_MOUSE_DEV *UsbMouse,
+ IN HID_ITEM *HidItem
+ )
+{
+ switch (HidItem->Type) {
+
+ case HID_ITEM_TYPE_MAIN:
+ //
+ // For Main Item, parse main item
+ //
+ ParseMainItem (UsbMouse, HidItem);
+ break;
+
+ case HID_ITEM_TYPE_GLOBAL:
+ //
+ // For global Item, parse global item
+ //
+ ParseGlobalItem (UsbMouse, HidItem);
+ break;
+
+ case HID_ITEM_TYPE_LOCAL:
+ //
+ // For Local Item, parse local item
+ //
+ ParseLocalItem (UsbMouse, HidItem);
+ break;
+ }
+}
+//
+// A simple parse just read some field we are interested in
+//
+
+/**
+ Parse Mouse Report Descriptor
+
+ @param UsbMouse USB_MOUSE_DEV
+ @param ReportDescriptor Report descriptor to parse
+ @param ReportSize Report descriptor size
+
+ @retval EFI_DEVICE_ERROR Report descriptor error
+ @retval EFI_SUCCESS Success
+
+**/
+EFI_STATUS
+ParseMouseReportDescriptor (
+ IN USB_MOUSE_DEV *UsbMouse,
+ IN UINT8 *ReportDescriptor,
+ IN UINTN ReportSize
+ )
+{
+ UINT8 *DescriptorEnd;
+ UINT8 *ptr;
+ HID_ITEM HidItem;
+
+ DescriptorEnd = ReportDescriptor + ReportSize;
+
+ ptr = GetNextItem (ReportDescriptor, DescriptorEnd, &HidItem);
+
+ while (ptr != NULL) {
+ if (HidItem.Format != HID_ITEM_FORMAT_SHORT) {
+ //
+ // Long Format Item is not supported at current HID revision
+ //
+ return EFI_DEVICE_ERROR;
+ }
+
+ ParseHidItem (UsbMouse, &HidItem);
+
+ ptr = GetNextItem (ptr, DescriptorEnd, &HidItem);
+ }
+
+ UsbMouse->NumberOfButtons = (UINT8) (UsbMouse->PrivateData.ButtonMaxIndex - UsbMouse->PrivateData.ButtonMinIndex + 1);
+ UsbMouse->XLogicMax = UsbMouse->YLogicMax = 127;
+ UsbMouse->XLogicMin = UsbMouse->YLogicMin = -127;
+
+ return EFI_SUCCESS;
+}
|