I recently acquired a new Wacom drawing tablet: an Intuos Draw, which seems to be called an Intuos S 2 internally. I couldn't get this tablet to work in OpenBSD. One of the HID descriptors describes a mouse, so ums(4) attaches to it, but no data is ever registered. After digging around in the Linux driver, it appears that the actual data is reported in a different descriptor, one that is (possibly on purpose) incorrect.
After writing a correct device descriptor I had to work around two other problems: - X & Y data is reported in big endian format. - Mouse button 1 data is flakey, the linux driver uses pressure to work around this. To get the tablet to function correctly, I chose to implement quirks for this in hidms(4). Attached patch makes the tablet function with mouse movement and all three stylus events (tip touch and 2 buttons) without any needed configuration. This is enough functionality for for me, I just use it as a mouse replacement to avoid getting RSI. Example dmesg output on attachment: uhidev0 at uhub3 port 2 configuration 1 interface 0 "Wacom Co.,Ltd. Intuos PS" rev 2.00/1.00 addr 3 uhidev0: iclass 3/0, 192 report ids ums0 at uhidev0 reportid 16: 3 buttons wsmouse1 at ums0 mux 0 uhid0 at uhidev0 reportid 192: input=4, output=0, feature=0 uhidev1 at uhub3 port 2 configuration 1 interface 1 "Wacom Co.,Ltd. Intuos PS" rev 2.00/1.00 addr 3 uhidev1: iclass 3/0, 3 report ids uhid1 at uhidev1 reportid 2: input=63, output=0, feature=0 uhid2 at uhidev1 reportid 3: input=63, output=0, feature=0 uhidev2 at uhub3 port 2 configuration 1 interface 2 "Wacom Co.,Ltd. Intuos PS" rev 2.00/1.00 addr 3 uhidev2: iclass 3/1, 1 report id ums1 at uhidev2 reportid 1: 5 buttons wsmouse2 at ums1 mux 0 The first tattached umse is the functioning one that is added by this patch. Is the attached patch acceptable? Or would it be better to write a seperate driver, such as uwacom, that does the same as ums, except that it doesn't call hidms_input, but implements that itself? Frank
Index: hid/hidms.c =================================================================== RCS file: /cvs/src/sys/dev/hid/hidms.c,v retrieving revision 1.3 diff -u -p -r1.3 hidms.c --- hid/hidms.c 22 May 2016 22:06:11 -0000 1.3 +++ hid/hidms.c 2 Aug 2016 19:15:09 -0000 @@ -109,6 +109,9 @@ hidms_setup(struct device *self, struct return ENXIO; } + hid_locate(desc, dlen, HID_USAGE2(HUP_DIGITIZERS, HUD_TIP_PRESSURE), + id, hid_input, &ms->sc_loc_tip_press, &flags); + /* * Try to guess the Z activator: check WHEEL, TWHEEL, and Z, * in that order. @@ -368,6 +371,11 @@ hidms_input(struct hidms *ms, uint8_t *d dz = -dz; if (ms->sc_flags & HIDMS_REVW) dw = -dw; + if (ms->sc_flags & HIDMS_BE16_X) + dx = be16toh(dx); + if (ms->sc_flags & HIDMS_BE16_Y) + dy = be16toh(dy); + if (ms->sc_tsscale.swapxy && !ms->sc_rawmode) { int tmp = dx; @@ -388,6 +396,13 @@ hidms_input(struct hidms *ms, uint8_t *d for (i = 0; i < ms->sc_num_buttons; i++) if (hid_get_data(data, len, &ms->sc_loc_btn[i])) buttons |= (1 << HIDMS_BUT(i)); + + if (ms->sc_flags & HIDMS_USE_TIP_PRESS) { + if (hid_get_data(data, len, &ms->sc_loc_tip_press) > 10) + buttons |= (1 << HIDMS_BUT(0)); + else + buttons &= ~(1 << HIDMS_BUT(0)); + } if (dx != 0 || dy != 0 || dz != 0 || dw != 0 || buttons != ms->sc_buttons) { Index: hid/hidmsvar.h =================================================================== RCS file: /cvs/src/sys/dev/hid/hidmsvar.h,v retrieving revision 1.1 diff -u -p -r1.1 hidmsvar.h --- hid/hidmsvar.h 8 Jan 2016 15:54:13 -0000 1.1 +++ hid/hidmsvar.h 2 Aug 2016 19:15:09 -0000 @@ -43,18 +43,21 @@ struct tsscale { struct hidms { int sc_enabled; int sc_flags; /* device configuration */ -#define HIDMS_SPUR_BUT_UP 0x001 /* spurious button up events */ -#define HIDMS_Z 0x002 /* Z direction available */ -#define HIDMS_REVZ 0x004 /* Z-axis is reversed */ -#define HIDMS_W 0x008 /* W direction available */ -#define HIDMS_REVW 0x010 /* W-axis is reversed */ -#define HIDMS_LEADINGBYTE 0x020 /* Unknown leading byte */ -#define HIDMS_ABSX 0x040 /* X-axis is absolute */ -#define HIDMS_ABSY 0x080 /* Y-axis is absolute */ -#define HIDMS_TIP 0x100 /* Tip switch on a digitiser pen */ -#define HIDMS_BARREL 0x200 /* Barrel switch on a digitiser pen */ -#define HIDMS_ERASER 0x400 /* Eraser switch on a digitiser pen */ -#define HIDMS_MS_BAD_CLASS 0x800 /* Mouse doesn't identify properly */ +#define HIDMS_SPUR_BUT_UP 0x0001 /* spurious button up events */ +#define HIDMS_Z 0x0002 /* Z direction available */ +#define HIDMS_REVZ 0x0004 /* Z-axis is reversed */ +#define HIDMS_W 0x0008 /* W direction available */ +#define HIDMS_REVW 0x0010 /* W-axis is reversed */ +#define HIDMS_LEADINGBYTE 0x0020 /* Unknown leading byte */ +#define HIDMS_ABSX 0x0040 /* X-axis is absolute */ +#define HIDMS_ABSY 0x0080 /* Y-axis is absolute */ +#define HIDMS_TIP 0x0100 /* Tip switch on a digitiser pen */ +#define HIDMS_BARREL 0x0200 /* Barrel switch on a digitiser pen */ +#define HIDMS_ERASER 0x0400 /* Eraser switch on a digitiser pen */ +#define HIDMS_MS_BAD_CLASS 0x0800 /* Mouse doesn't identify properly */ +#define HIDMS_BE16_X 0x1000 /* X-axis in 16 bit big endian */ +#define HIDMS_BE16_Y 0x2000 /* Y-axis in 16 bit big endian */ +#define HIDMS_USE_TIP_PRESS 0x4000 /* Use tip pressure for button 0 */ int sc_num_buttons; u_int32_t sc_buttons; /* mouse button status */ @@ -68,6 +71,7 @@ struct hidms { struct hid_location sc_loc_z; struct hid_location sc_loc_w; struct hid_location sc_loc_btn[MAX_BUTTONS]; + struct hid_location sc_loc_tip_press; struct tsscale sc_tsscale; int sc_rawmode; Index: usb/uhid_rdesc.h =================================================================== RCS file: /cvs/src/sys/dev/usb/uhid_rdesc.h,v retrieving revision 1.1 diff -u -p -r1.1 uhid_rdesc.h --- usb/uhid_rdesc.h 25 Oct 2013 03:09:59 -0000 1.1 +++ usb/uhid_rdesc.h 2 Aug 2016 19:15:09 -0000 @@ -273,3 +273,55 @@ static const uByte uhid_xb360gp_report_d 0x81, 0x01, /* INPUT (Constant) */ 0xc0, /* END COLLECTION */ }; + +static uByte uhid_intuos_s2_report_descr[] = { + 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */ + 0x09, 0x02, /* USAGE (Mouse) */ + 0xa1, 0x01, /* COLLECTION (Application) */ + 0x85, 0x10, /* REPORT_ID (16) */ + 0x09, 0x01, /* USAGE (Pointer) */ + 0xa1, 0x00, /* COLLECTION (Physical) */ + 0x05, 0x09, /* USAGE_PAGE (Button) */ + 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ + 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */ + 0x09, 0x01, /* USAGE (Button 1) */ + 0x09, 0x03, /* USAGE (Button 3) */ + 0x09, 0x02, /* USAGE (Button 2) */ + 0x95, 0x03, /* REPORT_COUNT (3) */ + 0x75, 0x01, /* REPORT_SIZE (1) */ + 0x81, 0x02, /* INPUT (Data,Var,Abs) */ + 0x95, 0x01, /* REPORT_COUNT (1) */ + 0x75, 0x05, /* REPORT_SIZE (5) */ + 0x81, 0x01, /* INPUT (Cnst,Ary,Abs) */ + 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */ + 0x09, 0x30, /* USAGE (X) */ + 0x26, 0xb0, 0x1d, /* LOGICAL_MAXIMUM (7600) */ + 0x75, 0x10, /* REPORT_SIZE (16) */ + 0x95, 0x01, /* REPORT_COUNT (1) */ + 0x81, 0x02, /* INPUT (Data,Var,Abs) */ + 0x09, 0x31, /* USAGE (Y) */ + 0x26, 0x8e, 0x12, /* LOGICAL_MAXIMUM (4750) */ + 0x75, 0x10, /* REPORT_SIZE (16) */ + 0x95, 0x01, /* REPORT_COUNT (1) */ + 0x81, 0x02, /* INPUT (Data,Var,Abs) */ + 0x75, 0x01, /* REPORT SIZE (1) */ + 0x95, 0x03, /* REPORT COUNT (3) */ + 0x81, 0x01, /* INPUT (Cnst,Ary,Abs) */ + 0x05, 0x0d, /* USAGE_PAGE (Digitizers) */ + 0x09, 0x30, /* USAGE (Tip Pressure) */ + 0x26, 0xff, 0x00, /* LOGICAL_MAXIMUM (255) */ + 0x95, 0x01, /* REPORT_COUNT (1) */ + 0x75, 0x08, /* REPORT_SIZE (8) */ + 0x81, 0x02, /* INPUT (Data,Var,Abs) */ + 0x75, 0x01, /* REPORT SIZE (1) */ + 0x95, 0x1d, /* REPORT COUNT (29) */ + 0x81, 0x01, /* INPUT (Cnst,Ary,Abs) */ + 0xc0, /* END_COLLECTION */ + 0xc0, /* END_COLLECTION */ + 0x05, 0x00, /* USAGE_PAGE (Undefined) */ + 0x09, 0x00, /* USAGE (Undefined) */ + 0xa1, 0x01, /* COLLECTION (Application) */ + 0x85, 0xc0, /* REPORT_ID (192) */ + 0x81, 0x01, /* INPUT (Cnst,Ary,Abs) */ + 0xc0 /* END_COLLECTION */ +}; Index: usb/uhidev.c =================================================================== RCS file: /cvs/src/sys/dev/usb/uhidev.c,v retrieving revision 1.74 diff -u -p -r1.74 uhidev.c --- usb/uhidev.c 13 Jun 2016 10:15:03 -0000 1.74 +++ usb/uhidev.c 2 Aug 2016 19:15:09 -0000 @@ -298,6 +298,12 @@ uhidev_use_rdesc(struct uhidev_softc *sc size = sizeof(uhid_graphire3_4x5_report_descr); descptr = uhid_graphire3_4x5_report_descr; break; + case USB_PRODUCT_WACOM_INTUOSS2: + if (sc->sc_ifaceno == 0) { + size = sizeof(uhid_intuos_s2_report_descr); + descptr = uhid_intuos_s2_report_descr; + } + break; default: break; } Index: usb/ums.c =================================================================== RCS file: /cvs/src/sys/dev/usb/ums.c,v retrieving revision 1.43 diff -u -p -r1.43 ums.c --- usb/ums.c 12 Jan 2016 19:16:21 -0000 1.43 +++ usb/ums.c 2 Aug 2016 19:15:10 -0000 @@ -143,6 +143,12 @@ ums_attach(struct device *parent, struct qflags |= HIDMS_MS_BAD_CLASS; if (quirks & UQ_MS_LEADING_BYTE) qflags |= HIDMS_LEADINGBYTE; + if (quirks & UQ_BE16_X) + qflags |= HIDMS_BE16_X; + if (quirks & UQ_BE16_Y) + qflags |= HIDMS_BE16_Y; + if (quirks & UQ_USE_TIP_PRESS) + qflags |= HIDMS_USE_TIP_PRESS; if (hidms_setup(self, ms, qflags, uha->reportid, desc, size) != 0) return; Index: usb/usb_quirks.c =================================================================== RCS file: /cvs/src/sys/dev/usb/usb_quirks.c,v retrieving revision 1.74 diff -u -p -r1.74 usb_quirks.c --- usb/usb_quirks.c 27 Nov 2015 10:59:32 -0000 1.74 +++ usb/usb_quirks.c 2 Aug 2016 19:15:10 -0000 @@ -150,6 +150,9 @@ const struct usbd_quirk_entry { { USB_VENDOR_MICROSOFT, USB_PRODUCT_MICROSOFT_WLNOTEBOOK2, ANY, { UQ_MS_BAD_CLASS | UQ_MS_LEADING_BYTE }}, + { USB_VENDOR_WACOM, USB_PRODUCT_WACOM_INTUOSS2, + ANY, { UQ_BE16_X | UQ_BE16_Y | UQ_USE_TIP_PRESS }}, + { 0, 0, 0, { 0 } } }; Index: usb/usb_quirks.h =================================================================== RCS file: /cvs/src/sys/dev/usb/usb_quirks.h,v retrieving revision 1.16 diff -u -p -r1.16 usb_quirks.h --- usb/usb_quirks.h 19 Jul 2010 05:08:37 -0000 1.16 +++ usb/usb_quirks.h 2 Aug 2016 19:15:10 -0000 @@ -49,6 +49,10 @@ struct usbd_quirks { #define UQ_MS_LEADING_BYTE 0x00010000 /* mouse sends unknown leading byte */ #define UQ_EHCI_NEEDTO_DISOWN 0x00020000 /* must hand device over to USB 1.1 if attached to EHCI */ +#define UQ_BE16_X 0x00040000 /* mouse reports x in big endian 16 */ +#define UQ_BE16_Y 0x00080000 /* mouse reports x in big endian 16 */ +#define UQ_USE_TIP_PRESS 0x00100000 /* use mouse reported pressure for + button 0 */ }; extern const struct usbd_quirks usbd_no_quirk; Index: usb/usbdevs =================================================================== RCS file: /cvs/src/sys/dev/usb/usbdevs,v retrieving revision 1.666 diff -u -p -r1.666 usbdevs --- usb/usbdevs 1 Jun 2016 09:48:20 -0000 1.666 +++ usb/usbdevs 2 Aug 2016 19:15:10 -0000 @@ -4397,6 +4397,7 @@ product WACOM GRAPHIRE 0x0010 Graphire product WACOM GRAPHIRE3_4X5 0x0013 Graphire3 4x5 product WACOM GRAPHIRE4_4X5 0x0015 Graphire4 Classic A6 product WACOM INTUOSA5 0x0021 Intuos A5 +product WACOM INTUOSS2 0x033b Intuos S 2 /* WAGO Kontakttechnik products */ product WAGO SERVICECABLE 0x07a6 Service Cable 750-923 Index: usb/usbdevs.h =================================================================== RCS file: /cvs/src/sys/dev/usb/usbdevs.h,v retrieving revision 1.678 diff -u -p -r1.678 usbdevs.h --- usb/usbdevs.h 1 Jun 2016 09:48:54 -0000 1.678 +++ usb/usbdevs.h 2 Aug 2016 19:15:11 -0000 @@ -1,4 +1,4 @@ -/* $OpenBSD: usbdevs.h,v 1.678 2016/06/01 09:48:54 mglocker Exp $ */ +/* $OpenBSD$ */ /* * THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. @@ -4404,6 +4404,7 @@ #define USB_PRODUCT_WACOM_GRAPHIRE3_4X5 0x0013 /* Graphire3 4x5 */ #define USB_PRODUCT_WACOM_GRAPHIRE4_4X5 0x0015 /* Graphire4 Classic A6 */ #define USB_PRODUCT_WACOM_INTUOSA5 0x0021 /* Intuos A5 */ +#define USB_PRODUCT_WACOM_INTUOSS2 0x033b /* Intuos S 2 */ /* WAGO Kontakttechnik products */ #define USB_PRODUCT_WAGO_SERVICECABLE 0x07a6 /* Service Cable 750-923 */ Index: usb/usbdevs_data.h =================================================================== RCS file: /cvs/src/sys/dev/usb/usbdevs_data.h,v retrieving revision 1.672 diff -u -p -r1.672 usbdevs_data.h --- usb/usbdevs_data.h 1 Jun 2016 09:48:54 -0000 1.672 +++ usb/usbdevs_data.h 2 Aug 2016 19:15:12 -0000 @@ -1,4 +1,4 @@ -/* $OpenBSD: usbdevs_data.h,v 1.672 2016/06/01 09:48:54 mglocker Exp $ */ +/* $OpenBSD$ */ /* * THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. @@ -11208,6 +11208,10 @@ const struct usb_known_product usb_known { USB_VENDOR_WACOM, USB_PRODUCT_WACOM_INTUOSA5, "Intuos A5", + }, + { + USB_VENDOR_WACOM, USB_PRODUCT_WACOM_INTUOSS2, + "Intuos S 2", }, { USB_VENDOR_WAGO, USB_PRODUCT_WAGO_SERVICECABLE,