Bug 244602 - Lack of media key support for WASD keyboard
Summary: Lack of media key support for WASD keyboard
Status: New
Alias: None
Product: Base System
Classification: Unclassified
Component: usb (show other bugs)
Version: 12.1-STABLE
Hardware: Any Any
: --- Affects Only Me
Assignee: freebsd-usb (Nobody)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2020-03-05 01:24 UTC by Henry Hu
Modified: 2020-03-08 00:26 UTC (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Henry Hu 2020-03-05 01:24:53 UTC
There are media keys on the WASD keyboard (https://www.wasdkeyboards.com/). However, they are not recognized by FreeBSD. Pressing them does not result in any keyboard event in X.

The keyboard shows 2 interfaces:
 Configuration index 0

    bLength = 0x0009 
    bDescriptorType = 0x0002 
    wTotalLength = 0x003b 
    bNumInterfaces = 0x0002 
    bConfigurationValue = 0x0001 
    iConfiguration = 0x0000  <no string>
    bmAttributes = 0x00a0 
    bMaxPower = 0x0032 

    Interface 0
      bLength = 0x0009 
      bDescriptorType = 0x0004 
      bInterfaceNumber = 0x0000 
      bAlternateSetting = 0x0000 
      bNumEndpoints = 0x0001 
      bInterfaceClass = 0x0003  <HID device>
      bInterfaceSubClass = 0x0001 
      bInterfaceProtocol = 0x0001 
      iInterface = 0x0000  <no string>

      Additional Descriptor

      bLength = 0x09
      bDescriptorType = 0x21
      bDescriptorSubType = 0x10
       RAW dump: 
       0x00 | 0x09, 0x21, 0x10, 0x01, 0x00, 0x01, 0x22, 0x3e, 
       0x08 | 0x00

     Endpoint 0
        bLength = 0x0007 
        bDescriptorType = 0x0005 
        bEndpointAddress = 0x0081  <IN>
        bmAttributes = 0x0003  <INTERRUPT>
        wMaxPacketSize = 0x0008 
        bInterval = 0x000a 
        bRefresh = 0x0000 
        bSynchAddress = 0x0000 


    Interface 1
      bLength = 0x0009 
      bDescriptorType = 0x0004 
      bInterfaceNumber = 0x0001 
      bAlternateSetting = 0x0000 
      bNumEndpoints = 0x0001 
      bInterfaceClass = 0x0003  <HID device>
      bInterfaceSubClass = 0x0001 
      bInterfaceProtocol = 0x0002 
      iInterface = 0x0000  <no string>

      Additional Descriptor

      bLength = 0x09
      bDescriptorType = 0x21
      bDescriptorSubType = 0x10
       RAW dump: 
       0x00 | 0x09, 0x21, 0x10, 0x01, 0x00, 0x01, 0x22, 0xa6, 
       0x08 | 0x00

     Endpoint 0
        bLength = 0x0007 
        bDescriptorType = 0x0005 
        bEndpointAddress = 0x0082  <IN>
        bmAttributes = 0x0003  <INTERRUPT>
        wMaxPacketSize = 0x0008 
        bInterval = 0x000a 
        bRefresh = 0x0000 
        bSynchAddress = 0x0000 

ukbd attaches to interface 0, and ums attaches to interface 1.
Interface 0's HID report descriptor is a general one:

0x05, 0x01,        // Usage Page (Generic Desktop Ctrls)
0x09, 0x06,        // Usage (Keyboard)
0xA1, 0x01,        // Collection (Application)
0x05, 0x07,        //   Usage Page (Kbrd/Keypad)

// Control/Alt etc.
0x19, 0xE0,        //   Usage Minimum (0xE0)
0x29, 0xE7,        //   Usage Maximum (0xE7)
0x15, 0x00,        //   Logical Minimum (0)
0x25, 0x01,        //   Logical Maximum (1)
0x75, 0x01,        //   Report Size (1)
0x95, 0x08,        //   Report Count (8)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
// Padding
0x95, 0x01,        //   Report Count (1)
0x75, 0x08,        //   Report Size (8)
0x81, 0x01,        //   Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
// LEDs
0x95, 0x03,        //   Report Count (3)
0x75, 0x01,        //   Report Size (1)
0x05, 0x08,        //   Usage Page (LEDs)
0x19, 0x01,        //   Usage Minimum (Num Lock)
0x29, 0x03,        //   Usage Maximum (Scroll Lock)
0x91, 0x02,        //   Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
// Padding
0x95, 0x05,        //   Report Count (5)
0x75, 0x01,        //   Report Size (1)
0x91, 0x01,        //   Output (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
// Key array
0x95, 0x06,        //   Report Count (6)
0x75, 0x08,        //   Report Size (8)
0x26, 0xFF, 0x00,  //   Logical Maximum (255)
0x05, 0x07,        //   Usage Page (Kbrd/Keypad)
0x19, 0x00,        //   Usage Minimum (0x00)
0x29, 0x91,        //   Usage Maximum (0x91)
0x81, 0x00,        //   Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)

0xC0,              // End Collection

// 62 bytes

The interesting keys are in the interface 1:
Report descriptor:
Collection type=Application page=Consumer usage=Consumer_Control
Input   rid=1 pos=0 size=1 count=1 page=Consumer usage=Help, logical range 0..1
Input   rid=1 pos=1 size=1 count=1 page=Consumer usage=Mute, logical range 0..1
Input   rid=1 pos=2 size=1 count=1 page=Consumer usage=Volume_Decrement, logical range 0..1
Input   rid=1 pos=3 size=1 count=1 page=Consumer usage=Volume_Increment, logical range 0..1
Input   rid=1 pos=4 size=1 count=1 page=Consumer usage=AL_Word_Processor, logical range 0..1
Input   rid=1 pos=5 size=1 count=1 page=Consumer usage=AL_Spreadsheet, logical range 0..1
Input   rid=1 pos=6 size=1 count=1 page=Consumer usage=AL_Email_Reader, logical range 0..1
Input   rid=1 pos=7 size=1 count=1 page=Consumer usage=AL_Calendar/Schedule, logical range 0..1
Input   rid=1 pos=8 size=1 count=1 page=Consumer usage=AL_Calculator, logical range 0..1
Input   rid=1 pos=9 size=1 count=1 page=Consumer usage=AL_Logoff, logical range 0..1
Input   rid=1 pos=10 size=1 count=1 page=Consumer usage=AL_Next_Task/Application, logical range 0..1
Input   rid=1 pos=11 size=1 count=1 page=Consumer usage=AL_Previous_Task/Application, logical range 0..1
Input   rid=1 pos=12 size=1 count=1 page=Consumer usage=0x029e, logical range 0..1
Input   rid=1 pos=13 size=1 count=1 page=Consumer usage=AC_Spell_Check, logical range 0..1
Input   rid=1 pos=14 size=1 count=1 page=Consumer usage=AL_File_Browser, logical range 0..1
Input   rid=1 pos=15 size=1 count=1 page=Consumer usage=AC_New, logical range 0..1
Input   rid=1 pos=16 size=1 count=1 page=Consumer usage=AC_Open, logical range 0..1
Input   rid=1 pos=17 size=1 count=1 page=Consumer usage=AC_Close, logical range 0..1
Input   rid=1 pos=18 size=1 count=1 page=Consumer usage=AC_Save, logical range 0..1
Input   rid=1 pos=19 size=1 count=1 page=Consumer usage=AC_Print, logical range 0..1
Input   rid=1 pos=20 size=1 count=1 page=Consumer usage=AC_Undo, logical range 0..1
Input   rid=1 pos=21 size=1 count=1 page=Consumer usage=AC_Copy, logical range 0..1
Input   rid=1 pos=22 size=1 count=1 page=Consumer usage=AC_Cut, logical range 0..1
Input   rid=1 pos=23 size=1 count=1 page=Consumer usage=AC_Paste, logical range 0..1
Input   rid=1 pos=24 size=1 count=1 page=Consumer usage=0x029d, logical range 0..1
Input   rid=1 pos=25 size=1 count=1 page=Consumer usage=AC_Home, logical range 0..1
Input   rid=1 pos=26 size=1 count=1 page=Consumer usage=AC_Back, logical range 0..1
Input   rid=1 pos=27 size=1 count=1 page=Consumer usage=AC_Forward, logical range 0..1
Input   rid=1 pos=28 size=1 count=1 page=Consumer usage=AC_Redo/Repeat, logical range 0..1
Input   rid=1 pos=29 size=1 count=1 page=Consumer usage=AC_Reply, logical range 0..1
Input   rid=1 pos=30 size=1 count=1 page=Consumer usage=AC_Forward_Msg, logical range 0..1
Input   rid=1 pos=31 size=1 count=1 page=Consumer usage=AC_Send, logical range 0..1
Input   rid=1 pos=32 size=1 count=1 page=Consumer usage=Scan_Next_Track, logical range 0..1
Input   rid=1 pos=33 size=1 count=1 page=Consumer usage=Scan_Previous_Track, logical range 0..1
Input   rid=1 pos=34 size=1 count=1 page=Consumer usage=Stop, logical range 0..1
Input   rid=1 pos=35 size=1 count=1 page=Consumer usage=Play/Pause, logical range 0..1
Input   rid=1 pos=36 size=1 count=1 page=Consumer usage=AL_Consumer_Control_Configuration, logical range 0..1
Input   rid=1 pos=37 size=1 count=1 page=Consumer usage=AL_Local_Machine_Browser, logical range 0..1
Input   rid=1 pos=38 size=1 count=1 page=Consumer usage=AC_Search, logical range 0..1
Input   rid=1 pos=39 size=1 count=1 page=Consumer usage=AC_Stop, logical range 0..1
Input   rid=1 pos=40 size=1 count=1 page=Consumer usage=AC_Refresh, logical range 0..1
Input   rid=1 pos=41 size=1 count=1 page=Consumer usage=AC_Bookmarks, logical range 0..1
End collection
Collection type=Application page=Generic_Desktop usage=System_Control
Input   rid=2 pos=0 size=1 count=1 page=Generic_Desktop usage=System_Power_Down, logical range 0..1
Input   rid=2 pos=1 size=1 count=1 page=Generic_Desktop usage=System_Sleep, logical range 0..1
Input   rid=2 pos=2 size=1 count=1 page=Generic_Desktop usage=System_Wake_Up, logical range 0..1
End collection
Total   input size 7 bytes
Total  output size 0 bytes
Total feature size 0 bytes

(detached ums driver by adding UQ_UMS_IGNORE, then dump using usbhidctl -r)

So at least ums should not attach to it, and possibly ukbd or something else should attach to it and handle consumer page.
Comment 1 Henry Hu 2020-03-05 02:21:36 UTC
The key reason seems to be that interface 1 has

      bInterfaceClass = 0x0003  <HID device>
      bInterfaceSubClass = 0x0001 
      bInterfaceProtocol = 0x0002 

0x0001 = UISUBCLASS_BOOT
0x0002 = UIPROTO_MOUSE

Thus it's treated as a mouse, while in this case, it only has some media keys. Maybe ums should not attach if there is no mouse button or axis?
Comment 2 Henry Hu 2020-03-08 00:26:39 UTC
I've got media key support through iichid (https://github.com/wulf7/iichid). Maybe we can close this bug.