DIGImend / digimend-kernel-drivers

DIGImend graphics tablet drivers for the Linux kernel
GNU General Public License v2.0
1.17k stars 173 forks source link

XP-Pen G960S Plus support (28bd:0918) #500

Closed massifrg closed 3 years ago

massifrg commented 3 years ago

Hello, I have a XP-Pen G960S Plus and I'm unsatisfied with the driver provided by XP-Pen. I tried collecting tablet diagnostics and I'm posting the resulting output.

Identify original model

VID and PID are 28bd:0918.

Retrieve USB descriptors

lsusb -v -d $T > descriptors.txt ends with:

can't get debug descriptor: Resource temporarily unavailable

but descriptors.txt contains this:

Bus 003 Device 010: ID 28bd:0918  
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               1.10
  bDeviceClass            0 
  bDeviceSubClass         0 
  bDeviceProtocol         0 
  bMaxPacketSize0        64
  idVendor           0x28bd 
  idProduct          0x0918 
  bcdDevice            0.00
  iManufacturer           1 UGTABLET
  iProduct                2 9 inch PenTablet
  iSerial                 3 000000
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength       0x005b
    bNumInterfaces          3
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0xa0
      (Bus Powered)
      Remote Wakeup
    MaxPower               70mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      1 Boot Interface Subclass
      bInterfaceProtocol      2 Mouse
      iInterface              0 
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.00
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength     177
         Report Descriptors: 
           ** UNAVAILABLE **
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0008  1x 8 bytes
        bInterval               4
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      1 Boot Interface Subclass
      bInterfaceProtocol      2 Mouse
      iInterface              0 
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.00
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength     109
         Report Descriptors: 
           ** UNAVAILABLE **
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x82  EP 2 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               4
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        2
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      0 
      bInterfaceProtocol      0 
      iInterface              0 
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.00
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      36
          Report Descriptor: (length is 36)
            Item(Global): Usage Page, data= [ 0x0a 0xff ] 65290
                            (null)
            Item(Local ): Usage, data= [ 0x01 ] 1
                            (null)
            Item(Main  ): Collection, data= [ 0x01 ] 1
                            Application
            Item(Global): Report ID, data= [ 0x02 ] 2
            Item(Local ): Usage, data= [ 0x02 ] 2
                            (null)
            Item(Global): Report Size, data= [ 0x08 ] 8
            Item(Global): Report Count, data= [ 0x0b ] 11
            Item(Global): Logical Minimum, data= [ 0x00 ] 0
            Item(Global): Logical Maximum, data= [ 0xff 0x00 ] 255
            Item(Main  ): Input, data= [ 0x02 ] 2
                            Data Variable Absolute No_Wrap Linear
                            Preferred_State No_Null_Position Non_Volatile Bitfield
            Item(Local ): Usage, data= [ 0x03 ] 3
                            (null)
            Item(Global): Report Size, data= [ 0x08 ] 8
            Item(Global): Report Count, data= [ 0x0b ] 11
            Item(Global): Logical Minimum, data= [ 0x00 ] 0
            Item(Global): Logical Maximum, data= [ 0xff 0x00 ] 255
            Item(Main  ): Output, data= [ 0x02 ] 2
                            Data Variable Absolute No_Wrap Linear
                            Preferred_State No_Null_Position Non_Volatile Bitfield
            Item(Main  ): End Collection, data=none
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x83  EP 3 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x000c  1x 12 bytes
        bInterval               4
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x03  EP 3 OUT
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x000c  1x 12 bytes
        bInterval              10
Device Status:     0x0000
  (Bus Powered)

usbhid-dump -ed -m $T > hid_report_descriptors.txt ends without errors and this is the output in descriptors.txt:

003:010:002:DESCRIPTOR         1609014632.536793
 06 0A FF 09 01 A1 01 85 02 09 02 75 08 95 0B 15
 00 26 FF 00 81 02 09 03 75 08 95 0B 15 00 26 FF
 00 91 02 C0

003:010:001:DESCRIPTOR         1609014632.538762
 05 0D 09 02 A1 01 85 07 09 20 A1 00 09 42 09 44
 09 45 09 3C 15 00 25 01 75 01 95 04 81 02 95 01
 81 03 09 32 95 01 81 02 95 02 81 03 75 10 95 01
 35 00 A4 05 01 09 30 65 13 55 0D 46 28 23 26 FF
 7F 81 02 09 31 46 70 17 26 FF 7F 81 02 B4 09 30
 45 00 26 FF 1F 81 42 09 3D 15 81 25 7F 75 08 95
 01 81 02 09 3E 15 81 25 7F 81 02 C0 C0

003:010:000:DESCRIPTOR         1609014632.540756
 05 01 09 02 A1 01 85 09 09 01 A1 00 05 09 19 01
 29 03 15 00 25 01 95 03 75 01 81 02 95 05 81 01
 05 01 09 30 09 31 26 FF 7F 95 02 75 10 81 02 05
 0D 09 30 26 FF 07 95 01 75 10 81 02 C0 C0 05 01
 09 02 A1 01 09 01 A1 00 85 01 05 09 19 01 29 05
 95 05 75 01 15 00 25 01 81 02 95 03 81 01 05 01
 09 30 09 31 95 02 75 10 16 00 80 26 FF 7F 81 06
 09 38 15 81 25 7F 95 01 75 08 81 06 05 0C 0A 38
 02 95 01 75 08 81 06 C0 C0 05 01 09 06 A1 01 85
 06 05 07 19 E0 29 E7 15 00 25 01 75 01 95 08 81
 02 05 07 19 00 29 FF 26 FF 00 75 08 95 06 81 00
 C0

g960s_plus-raw-input-samples.zip Attempt retrieving UC-Logic parameters

uclogic-probe $BUS $DEVICE | tee probe.txt ends with an error:

Failed to get string descriptor 0xC8: Input/Output Error

but probe.txt contains this:

M 55 00 47 00 54 00 41 00 42 00 4C 00 45 00 54 00
P 39 00 20 00 69 00 6E 00 63 00 68 00 20 00 50 00 65 00 6E 00 54 00 61 00 62 00 6C 00 65 00 74 00
S 64 0E 03 4C 59 88 3B 06 00 FF 1F EC 09 00 00
S 65 04 03 00 67
S 6E 0B 03 00 30 00 03 08 01 00 00 00
S 79 10 03 20 20 20 20 20 20 20 20 20 20 20 20 20 20
S 7A 08 03 00 00 00 00 00 00
S 7B 0C 03 48 00 4B 00 20 00 4F 00 6E 00

Collect raw input samples

See attached files. g960s_plus-diagnostics.zip

massifrg commented 3 years ago

Sorry, I attached the raw input samples in the wrong place, they should be at the end of the text.

massifrg commented 3 years ago

From the hid_report_descriptors.txt file, I made up this array to be added to hid-uclogic-rdesc.c:

/* Fixed report descriptor for XP-Pen Star G960S Plus frame controls */
const __u8 uclogic_rdesc_xppen_g960s_plus_frame_arr[] = {
  /* 002:006:002:DESCRIPTOR         1609165322.263897 */
  0x06, 0x0A, 0xFF, 
  0x09, 0x01,         /*  Usage (Digitizer),                  */
  0xA1, 0x01,         /*  Collection (Application),           */ 
  0x85, 0x02,         /*      Report ID (2),                  */
  0x09, 0x02,         /*      Usage (Mouse),                  */
  0x75, 0x08,         /*      Report Size (8),                */
  0x95, 0x0B,         /*      Report Count (11),              */
  0x15, 0x00,         /*      Logical Minimum (0),            */
  0x26, 0xFF, 0x00,   /*      Logical Maximum (255),          */
  0x81, 0x02,         /*      Input (Variable),               */
  0x09, 0x03,         /*      Usage (3),                      */
  0x75, 0x08,         /*      Report Size (8),                */
  0x95, 0x0B,         /*      Report Count (11),              */
  0x15, 0x00,         /*      Logical Minimum (0),            */
  0x26, 0xFF, 0x00,   /*      Logical Maximum (255),          */
  0x91, 0x02,         /*      ???,                            */
  0xC0,               /*  End Collection                      */
  /* 002:006:001:DESCRIPTOR         1609165322.264693 */
  0x05, 0x0D,         /*  Usage Page (Digitizer),             */
  0x09, 0x02,         /*  Usage (Mouse),                      */
  0xA1, 0x01,         /*  Collection (Application),           */
  0x85, 0x07,         /*      Report ID (7),                  */
  0x09, 0x20,         /*      Usage (Stylus),                 */
  0xA1, 0x00,         /*      Collection (Physical),          */
  0x09, 0x42,         /*          Usage (Tip Switch),         */
  0x09, 0x44,         /*          Usage (Barrel Switch),      */
  0x09, 0x45,         /*          Usage (???),                */
  0x09, 0x3C,         /*          Usage (???),                */
  0x15, 0x00,         /*          Logical Minimum (0),        */
  0x25, 0x01,         /*          Logical Maximum (1),        */
  0x75, 0x01,         /*          Report Size (1),            */
  0x95, 0x04,         /*          Report Count (4),           */
  0x81, 0x02,         /*          Input (Variable),           */
  0x95, 0x01,         /*          Report Count (1),           */
  0x81, 0x03,         /*          Input (Constant, Variable), */
  0x09, 0x32,         /*          Usage (In Range),           */
  0x95, 0x01,         /*          Report Count (1),           */
  0x81, 0x02,         /*          Input (Variable),           */
  0x95, 0x02,         /*          Report Count (2),           */
  0x81, 0x03,         /*          Input (Constant, Variable), */
  0x75, 0x10,         /*          Report Size (16),           */
  0x95, 0x01,         /*          Report Count (1),           */
  0x35, 0x00,         /*          Physical Minimum (0),       */
  0xA4,               /*          Push,                       */
  0x05, 0x01,         /*          Usage Page (Desktop),       */
  0x09, 0x30,         /*          Usage (X),                  */
  0x65, 0x13,         /*          Unit (Inch),                */
  0x55, 0x0D,         /*          Unit Exponent (???),        */
  0x46, 0x28, 0x23,   /*          Physical Maximum (9000),    */
  0x26, 0xFF, 0x7F,   /*          Logical Maximum (32767),    */
  0x81, 0x02,         /*          Input (Variable),           */
  0x09, 0x31,         /*          Usage (Y),                  */
  0x46, 0x70, 0x17,   /*          Physical Maximum (6000),    */
  0x26, 0xFF, 0x7F,   /*          Logical Maximum (32767),    */
  0x81, 0x02,         /*          Input (Variable),           */
  0xB4,               /*          Pop,                        */
  0x09, 0x30,         /*          Usage (Tip Pressure),       */
  0x45, 0x00,         /*          Physical Maximum (0),       */
  0x26, 0xFF, 0x1F,   /*          Logical Maximum (8191),     */
  0x81, 0x42,         /*          Input (???),                */
  0x09, 0x3D,         /*          Usage (X Tilt),             */
  0x15, 0x81,         /*          Logical Minimum (-127),     */
  0x25, 0x7F,         /*          Logical Maximum (127),      */
  0x75, 0x08,         /*          Report Size (8),            */
  0x95, 0x01,         /*          Report Count (1),           */
  0x81, 0x02,         /*          Input (Variable),           */
  0x09, 0x3E,         /*          Usage (Y Tilt),             */
  0x15, 0x81,         /*          Logical Minimum (-127),     */
  0x25, 0x7F,         /*          Logical Maximum (127),      */
  0x81, 0x02,         /*          Input (Variable),           */
  0xC0,               /*      End Collection,                 */
  0xC0,               /*  End Collection                      */
  /* 002:006:000:DESCRIPTOR         1609165322.265824 */
  0x05, 0x01,         /*  Usage Page (Desktop),               */
  0x09, 0x02,         /*  Usage (Mouse),                      */
  0xA1, 0x01,         /*  Collection (Application),           */
  0x85, 0x09,         /*      Report ID (9),                  */
  0x09, 0x01,         /*      Usage (Digitizer),              */
  0xA1, 0x00,         /*      Collection (Physical),          */
  0x05, 0x09,         /*          Usage Page (Button),        */
  0x19, 0x01,         /*          Usage Minimum (01h),        */
  0x29, 0x03,         /*          Usage Maximum (03h),        */
  0x15, 0x00,         /*          Logical Minimum (0),        */ 
  0x25, 0x01,         /*          Logical Maximum (1),        */ 
  0x95, 0x03,         /*          Report Count (3),           */
  0x75, 0x01,         /*          Report Size (1),            */
  0x81, 0x02,         /*          Input (Variable),           */
  0x95, 0x05,         /*          Report Count (5),           */
  0x81, 0x01,         /*          Input (Constant),           */
  0x05, 0x01,         /*          Usage Page (Desktop),       */
  0x09, 0x30,         /*          Usage (X),                  */
  0x09, 0x31,         /*          Usage (Y),                  */
  0x26, 0xFF, 0x7F,   /*          Logical Maximum (32767),    */
  0x95, 0x02,         /*          Report Count (2),           */
  0x75, 0x10,         /*          Report Size (16),           */ 
  0x81, 0x02,         /*          Input (Variable),           */ 
  0x05, 0x0D,         /*          Usage Page (Digitizer),     */
  0x09, 0x30,         /*          Usage (X),                  */
  0x26, 0xFF, 0x07,   /*          Logical Maximum (2047),     */
  0x95, 0x01,         /*          Report Count (1),           */
  0x75, 0x10,         /*          Report Size (16),           */
  0x81, 0x02,         /*          Input (Variable),           */
  0xC0,               /*      End Collection,                 */
  0xC0,               /*  End Collection                      */
  0x05, 0x01,         /*  Usage Page (Desktop),               */
  0x09, 0x02,         /*  Usage (Mouse),                      */
  0xA1, 0x01,         /*  Collection (Application),           */
  0x09, 0x01,         /*      Usage (Digitizer),              */
  0xA1, 0x00,         /*      Collection (Physical),          */
  0x85, 0x01,         /*          Report ID (1),              */
  0x05, 0x09,         /*          Usage Page (Button),        */  
  0x19, 0x01,         /*          Usage Minimum (01h),        */ 
  0x29, 0x05,         /*          Usage Maximum (05h),        */
  0x95, 0x05,         /*          Report Count (5),           */
  0x75, 0x01,         /*          Report Size (1),            */
  0x15, 0x00,         /*          Logical Minimum (0),        */
  0x25, 0x01,         /*          Logical Maximum (1),        */
  0x81, 0x02,         /*          Input (Variable),           */ 
  0x95, 0x03,         /*          Report Count (5),           */
  0x81, 0x01,         /*          Input (Constant),           */
  0x05, 0x01,         /*          Usage Page (Desktop),       */
  0x09, 0x30,         /*          Usage (X),                  */
  0x09, 0x31,         /*          Usage (Y),                  */
  0x95, 0x02,         /*          Report Count (2),           */
  0x75, 0x10,         /*          Report Size (16),           */
  0x16, 0x00, 0x80,   /*          Logical Minimum (-32768),   */
  0x26, 0xFF, 0x7F,   /*          Logical Maximum (32767),    */
  0x81, 0x06,         /*          Input (Variable, Relative), */
  0x09, 0x38,         /*          Usage (Wheel),              */
  0x15, 0x81,         /*          Logical Minimum (-127),     */
  0x25, 0x7F,         /*          Logical Maximum (127),      */
  0x95, 0x01,         /*          Report Count (1),           */
  0x75, 0x08,         /*          Report Size (8),            */
  0x81, 0x06,         /*          Input (Variable, Relative), */
  0x05, 0x0C,         /*          Usage Page (Consumer),      */
  0x0A, 0x38, 0x02,   /*          Usage (AC Pan),             */
  0x95, 0x01,         /*          Report Count (1),           */
  0x75, 0x08,         /*          Report Size (8),            */ 
  0x81, 0x06,         /*          Input (Variable, Relative), */
  0xC0,               /*      End Collection,                 */
  0xC0,               /*  End Collection                      */
  0x05, 0x01,         /*  Usage Page (Desktop),               */
  0x09, 0x06,         /*  Usage (Keyboard),                   */
  0xA1, 0x01,         /*  Collection (Application),           */
  0x85, 0x06,         /*      Report ID (6),                  */
  0x05, 0x07,         /*      Usage Page (Keyboard),          */ 
  0x19, 0xE0,         /*      Usage Minimum (KB Leftcontrol), */
  0x29, 0xE7,         /*      Usage Maximum (KB Right GUI),   */
  0x15, 0x00,         /*      Logical Minimum (0),            */
  0x25, 0x01,         /*      Logical Maximum (1),            */
  0x75, 0x01,         /*      Report Size (1),                */
  0x95, 0x08,         /*      Report Count (8),               */
  0x81, 0x02,         /*      Input (Variable),               */
  0x05, 0x07,         /*      Usage Page (Keyboard),          */
  0x19, 0x00,         /*      Usage Minimum (0h),             */
  0x29, 0xFF,         /*      Usage Maximum (FFh),            */
  0x26, 0xFF, 0x00,   /*      Logical Maximum (255),          */
  0x75, 0x08,         /*      Report Size (8),                */
  0x95, 0x06,         /*      Report Count (6),               */
  0x81, 0x00,         /*      Input (???)                     */
  0xC0                /*  End Collection                      */
};

const size_t uclogic_rdesc_xppen_g960s_plus_frame_size =
            sizeof(uclogic_rdesc_xppen_g960s_plus_frame_arr);

I have no previous knowledge about graphical tablets, so I just tried to emulate what I read in the code. The descriptors file is made of 3 sections, that you find separated by comments in that array (I don't know whether they are all needed).

massifrg commented 3 years ago

I discovered that the tablet is well supported by the wacom driver. I followed the README and wrote:

Section "InputClass"
    Identifier "Tablet"
    Driver "wacom"
    MatchDevicePath "/dev/input/event*"
    MatchUSBID "28bd:0918"
EndSection

in /etc/X11/xorg.conf.d/50-tablet.conf.