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,