Modules/USB HID - Keyboard support!
[tpg/acess2.git] / KernelLand / Modules / USB / HID / mouse.c
index 233465a..6ca88a5 100644 (file)
@@ -5,7 +5,7 @@
  * mouse.c
  * - USB Mouse driver
  */
-#define DEBUG  1
+#define DEBUG  0
 #include <acess.h>
 #include "hid_reports.h"
 #include <fs_devfs.h>
@@ -24,27 +24,33 @@ struct sHID_Mouse
        tHID_Mouse      *Next;
        tUSB_DataCallback       DataAvail;
 
+       // VFS Node
        tVFS_Node       Node;
-        int    CollectionDepth;
-       
+
+       // Joystick Spec data   
        Uint8   FileData[ FILE_SIZE ];
        tJoystick_FileHeader    *FileHeader;
        tJoystick_Axis  *Axies;
        Uint8   *Buttons;
 
+       // Limits for axis positions
        Uint16  AxisLimits[MAX_AXIES];
        
+       // - Report parsing
         int    nMappings;
        struct {
                Uint8   Dest;   // 0x00-0x7F = Buttons, 0x80-0xFE = Axies, 0xFF = Ignore
                Uint8   BitSize;
        } *Mappings;
+       
+       // - Initialisation only data
+        int    CollectionDepth;
 };
 
 // === PROTOTYES ===
 char   *HID_Mouse_Root_ReadDir(tVFS_Node *Node, int Pos);
 tVFS_Node      *HID_Mouse_Root_FindDir(tVFS_Node *Node, const char *Name);
-Uint64 HID_Mouse_Dev_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer);
+size_t HID_Mouse_Dev_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer);
  int   HID_Mouse_Dev_IOCtl(tVFS_Node *Node, int ID, void *Data);
 void   HID_Mouse_Dev_Reference(tVFS_Node *Node);
 void   HID_Mouse_Dev_Close(tVFS_Node *Node);
@@ -70,7 +76,10 @@ tVFS_NodeType        gHID_Mouse_DevNodeType = {
 };
 tDevFS_Driver  gHID_Mouse_DevFS = {
        .Name = "USBMouse",
-       .RootNode = {.Type = &gHID_Mouse_RootNodeType}
+       .RootNode = {
+               .Type = &gHID_Mouse_RootNodeType,
+               .Flags = VFS_FFLAG_DIRECTORY
+       }
 };
 tHID_ReportCallbacks   gHID_Mouse_ReportCBs = {
        .Collection = HID_Mouse_Report_Collection,
@@ -110,13 +119,17 @@ tVFS_Node *HID_Mouse_Root_FindDir(tVFS_Node *Node, const char *Name)
        // Scan list, locate item
        Mutex_Acquire(&glHID_MouseListLock);
        for( mouse = gpHID_FirstMouse; mouse && ID --; mouse = mouse->Next ) ;
-       mouse->Node.ReferenceCount ++;  
+       if( mouse )
+               mouse->Node.ReferenceCount ++;  
        Mutex_Release(&glHID_MouseListLock);
 
-       return &mouse->Node;
+       if( mouse )
+               return &mouse->Node;
+       else
+               return NULL;
 }
 
-Uint64 HID_Mouse_Dev_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *Buffer)
+size_t HID_Mouse_Dev_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer)
 {
        tHID_Mouse      *info = Node->ImplPtr;
        
@@ -127,15 +140,37 @@ Uint64 HID_Mouse_Dev_Read(tVFS_Node *Node, Uint64 Offset, Uint64 Length, void *B
 
        memcpy( Buffer, info->FileData + Offset, Length );
 
+       VFS_MarkAvaliable( &info->Node, 0 );
+       
        return Length;
 }
 
 static const char *csaDevIOCtls[] = {DRV_IOCTLNAMES, DRV_JOY_IOCTLNAMES, NULL};
 int HID_Mouse_Dev_IOCtl(tVFS_Node *Node, int ID, void *Data)
 {
+       tJoystick_NumValue      *numval = Data;
+       tHID_Mouse      *info = Node->ImplPtr;
        switch(ID)
        {
        BASE_IOCTLS(DRV_TYPE_JOYSTICK, "USBMouse", 0x050, csaDevIOCtls);
+       
+       case JOY_IOCTL_GETSETAXISLIMIT:
+               if( !numval || !CheckMem(numval, sizeof(*numval)) )
+                       return -1;
+               if(numval->Num < 0 || numval->Num >= MAX_AXIES)
+                       return 0;
+               if(numval->Value != -1)
+                       info->AxisLimits[numval->Num] = numval->Value;
+               return info->AxisLimits[numval->Num];
+
+       case JOY_IOCTL_GETSETAXISPOSITION:
+               if( !numval || !CheckMem(numval, sizeof(*numval)) )
+                       return -1;
+               if(numval->Num < 0 || numval->Num >= MAX_AXIES)
+                       return 0;
+               if(numval->Value != -1)
+                       info->Axies[numval->Num].CursorPos = numval->Value;
+               return info->Axies[numval->Num].CursorPos;
        }
        return -1;
 }
@@ -151,12 +186,23 @@ void HID_Mouse_Dev_Close(tVFS_Node *Node)
 // ----------------------------------------------------------------------------
 // Data input / Update
 // ----------------------------------------------------------------------------
+/**
+ * \brief Read a set amounts of bits from a stream
+ * \param Data Base of data
+ * \param Offset       Bit offset
+ * \param Length       Number of bits to read
+ * \return Sign-extended value
+ */
 Sint32 _ReadBits(void *Data, int Offset, int Length)
 {
         int    dest_ofs = 0;
+        int    rem = Length;
        Uint32  rv = 0;
        Uint8   *bytes = (Uint8*)Data + Offset / 8;
-       
+
+       // Sanity please        
+       if( Length > 32 )       return 0;
+
        // Leading byte
        if( Offset & 7 )
        {
@@ -169,23 +215,22 @@ Sint32 _ReadBits(void *Data, int Offset, int Length)
                rv = (*bytes >> Offset);
                
                dest_ofs = Offset & 7;
-               Length -= Offset & 7;
+               rem = Length - (Offset & 7);
                bytes ++;
        }
 
        // Body bytes
-       while( Length >= 8 )
+       while( rem >= 8 )
        {
                rv |= *bytes << dest_ofs;
                dest_ofs += 8;
-               Length -= 8;
+               rem -= 8;
                bytes ++;
        }
        
-       if( Length )
+       if( rem )
        {
-               rv |= (*bytes & ((1 << Length)-1)) << dest_ofs;
-               
+               rv |= (*bytes & ((1 << rem)-1)) << dest_ofs;
        }
        
        // Do sign extension
@@ -195,6 +240,9 @@ _ext:
        return rv;
 }
 
+/**
+ * \brief Handle an update from the device
+ */
 void HID_Mouse_DataAvail(tUSBInterface *Dev, int EndPt, int Length, void *Data)
 {
        tHID_Mouse      *info;
@@ -203,8 +251,6 @@ void HID_Mouse_DataAvail(tUSBInterface *Dev, int EndPt, int Length, void *Data)
        info = USB_GetDeviceDataPtr(Dev);
        if( !info )     return ;
 
-       Log_Debug("USBMouse", "info = %p", info);       
-       
        ofs = 0;
        for( int i = 0; i < info->nMappings; i ++ )
        {
@@ -215,6 +261,7 @@ void HID_Mouse_DataAvail(tUSBInterface *Dev, int EndPt, int Length, void *Data)
                        return ;
 
                value = _ReadBits(Data, ofs, info->Mappings[i].BitSize);
+               LOG("%i+%i: value = %i", ofs, info->Mappings[i].BitSize, value);
                ofs += info->Mappings[i].BitSize;
                
                if( dest == 0xFF )      continue ;
@@ -223,11 +270,13 @@ void HID_Mouse_DataAvail(tUSBInterface *Dev, int EndPt, int Length, void *Data)
                {
                        // Axis
                        info->Axies[ dest & 0x7F ].CurValue = value;
+                       LOG("Axis %i = %i", dest & 0x7F, info->Axies[dest & 0x7F].CurValue);
                }
                else
                {
                        // Button
                        info->Buttons[ dest & 0x7F ] = (value == 0) ? 0 : 0xFF;
+                       LOG("Button %i = %x", dest & 0x7F, info->Buttons[dest & 0x7F]);
                }
        }
        
@@ -244,15 +293,17 @@ void HID_Mouse_DataAvail(tUSBInterface *Dev, int EndPt, int Length, void *Data)
                
                info->Axies[i].CursorPos = newpos;
        }
-       Log_Debug("USBMouse", "New Pos (%i,%i,%i)",
-               info->Axies[0].CursorPos, info->Axies[1].CursorPos, info->Axies[2].CursorPos
-               );
+//     Log_Debug("USBMouse", "New Pos (%i,%i,%i)",
+//             info->Axies[0].CursorPos, info->Axies[1].CursorPos, info->Axies[2].CursorPos
+//             );
+       VFS_MarkAvaliable( &info->Node, 1 );
 }
 
 // ----------------------------------------------------------------------------
 // Device initialisation
 // ----------------------------------------------------------------------------
 /**
+ * \brief Handle the opening of a collection
  */
 tHID_ReportCallbacks *HID_Mouse_Report_Collection(
        tUSBInterface *Dev,
@@ -274,6 +325,14 @@ tHID_ReportCallbacks *HID_Mouse_Report_Collection(
                info->FileHeader = (void*)info->FileData;
                info->Axies = (void*)(info->FileHeader + 1);
                info->Buttons = (void*)(info->Axies + MAX_AXIES);
+               info->FileHeader->NAxies = MAX_AXIES;
+               info->FileHeader->NButtons = MAX_BUTTONS;
+
+               for( int i = 0; i < MAX_AXIES; i ++ ) {
+                       info->Axies[i].MinValue = -10;
+                       info->Axies[i].MaxValue = 10;
+               }
+               
        
                LOG("Initialised new mouse at %p", info);
                
@@ -287,6 +346,9 @@ tHID_ReportCallbacks *HID_Mouse_Report_Collection(
        return &gHID_Mouse_ReportCBs;
 }
 
+/**
+ * \brief Handle the end of a collection
+ */
 void HID_Mouse_Report_EndCollection(tUSBInterface *Dev)
 {
        tHID_Mouse      *info;
@@ -312,6 +374,9 @@ void HID_Mouse_Report_EndCollection(tUSBInterface *Dev)
        }
 }
 
+/**
+ * \brief Add a new input mapping
+ */
 void HID_int_AddInput(tUSBInterface *Dev, Uint32 Usage, Uint8 Size, Uint32 Min, Uint32 Max)
 {
        Uint8   tag;
@@ -323,6 +388,7 @@ void HID_int_AddInput(tUSBInterface *Dev, Uint32 Usage, Uint8 Size, Uint32 Min,
                return ;
        }
 
+       // --- Get the destination for the field ---
        switch(Usage)
        {
        case 0x00010030:        tag = 0x80;     break;  // Generic Desktop - X
@@ -336,13 +402,17 @@ void HID_int_AddInput(tUSBInterface *Dev, Uint32 Usage, Uint8 Size, Uint32 Min,
        default:        tag = 0xFF;     break;
        }
        
+       LOG("Usage = 0x%08x, tag = 0x%2x", Usage, tag);
+
+       // --- Add to list of mappings ---
        info->nMappings ++;
        info->Mappings = realloc(info->Mappings, info->nMappings * sizeof(info->Mappings[0]));
        // TODO: NULL check
-       
        info->Mappings[ info->nMappings - 1].Dest = tag;
        info->Mappings[ info->nMappings - 1].BitSize = Size;
        
+       // --- Update Min/Max for Axies ---
+       // TODO: DPI too
        if( tag != 0xFF && (tag & 0x80) )
        {
                info->Axies[ tag & 0x7F ].MinValue = Min;
@@ -350,6 +420,9 @@ void HID_int_AddInput(tUSBInterface *Dev, Uint32 Usage, Uint8 Size, Uint32 Min,
        }
 }
 
+/**
+ * \brief Handle an input item in a report
+ */
 void HID_Mouse_Report_Input(
        tUSBInterface *Dev,
        tHID_ReportGlobalState *Global, tHID_ReportLocalState *Local,
@@ -357,10 +430,14 @@ void HID_Mouse_Report_Input(
        )
 {
        Uint32  usage = 0;
+       LOG("Local->Usages.nItems = %i", Local->Usages.nItems);
        for( int i = 0; i < Global->ReportCount; i ++ )
        {
+               // - Update usage
                if( i < Local->Usages.nItems )
                        usage = Local->Usages.Items[i];
+               LOG("%i: usage = %x", i, usage);
+               // - Add to list
                HID_int_AddInput(Dev, usage, Global->ReportSize, Global->LogMin, Global->LogMax);
        }
 }

UCC git Repository :: git.ucc.asn.au