On Sun, Sep 04, 2016 at 02:25:06PM +0200, Martin Pieuchot wrote:
> >- One bug still left: when the device is attached after X has started,
> > it seems the scaling is done wrongly. I had this problem with the
> > hacked ums driver as well. Most of the time it is fixed by switching
> > between console and X.
Correction: the problem can only be fixed by making sure the device is
plugged in before starting X. After suspend a restart of X is needed to
make scaling work again.
>
> This is a common problem for drivers needing calibration. Does the X driver
> opens your device through /dev/wsmouseN or does it uses the mux?
I think that's weird for this device tough: input is always report from
zero till the maximum values in the driver. No matter how or when you
attach it.
I'm not sure how the X driver opens the device. I've based it off ums(4)
mostly, so it will probably be the same as ums(4) does.
> >- Documentation is still absent, I'll gladly write it when you guys
> > apporve of the code I wrote.
>
> I'll be happy to do so, could you provide a man page for this driver?
Attached a new diff with documentation.
> >What do you guys think? Any comments or suggestions? Any ideas on how to
> >attach to all three uhidevs?
>
> Yes, you have to match the device id. uhidev(4) attaches to the 3 first
> interfaces of your first configuration. And you want a single piece of code
> driving all these interfaces. Do you have some documentation for the device
> you're hacking on? Do you know what you can do with these interfaces? It's
> important to know otherwise you
> might spend as much work refactoring the driver to extend it than you
> spent in the beginning.
Unfortunately I couldn't find any documentation except for the Linux
device driver implementation (but it supports all kinds of Wacom
tablets, so it isn't exactly readable).
I've written this driver by using the broken device descriptor
and reverse-engeneering with commands such as:
cat /dev/uhid6 | hexdump -e '9/1 "%02x " "\n"'
And just moving the pen and seeing which bytes change.
It seems only the first uhidev device actually reports inputs. The last
uhidev device seems to have the most correct descriptor, but never
reports any data. My guess is that it's there for Windows users without
the driver: they can recognize the tablet as a reported generic mouse.
As far as I can understand the Linux driver, they only use the data from
the reportid that my driver uses. For completeness I've attached lsusb
output from a Linux computer as well.
Frank
Bus 004 Device 005: ID 056a:033b Wacom Co., Ltd
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor 0x056a Wacom Co., Ltd
idProduct 0x033b
bcdDevice 1.00
iManufacturer 1 Wacom Co.,Ltd.
iProduct 2 Intuos PS
iSerial 0
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 84
bNumInterfaces 3
bConfigurationValue 1
iConfiguration 0
bmAttributes 0x80
(Bus Powered)
MaxPower 498mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 3 Human Interface Device
bInterfaceSubClass 0 No Subclass
bInterfaceProtocol 0 None
iInterface 0
HID Device Descriptor:
bLength 9
bDescriptorType 33
bcdHID 1.10
bCountryCode 0 Not supported
bNumDescriptors 1
bDescriptorType 34 Report
wDescriptorLength 208
Report Descriptor: (length is 208)
Item(Global): Usage Page, data= [ 0x0d 0xff ] 65293
(null)
Item(Local ): Usage, data= [ 0x01 ] 1
(null)
Item(Main ): Collection, data= [ 0x01 ] 1
Application
Item(Global): Report ID, data= [ 0x10 ] 16
Item(Main ): Collection, data= [ 0x00 ] 0
Physical
Item(Global): Usage Page, data= [ 0x00 0xff ] 65280
(null)
Item(Local ): Usage, data= [ 0x01 ] 1
(null)
Item(Global): Logical Minimum, data= [ 0x00 ] 0
Item(Global): Logical Maximum, data= [ 0xff 0x00 ] 255
Item(Global): Report Size, data= [ 0x08 ] 8
Item(Global): Report Count, data= [ 0x09 ] 9
Item(Main ): Input, data= [ 0x02 ] 2
Data Variable Absolute No_Wrap Linear
Preferred_State No_Null_Position Non_Volatile
Bitfield
Item(Main ): End Collection, data=none
Item(Local ): Usage, data= [ 0x01 ] 1
(null)
Item(Global): Report ID, data= [ 0x02 ] 2
Item(Global): Report Count, data= [ 0x01 ] 1
Item(Main ): Feature, data= [ 0x02 ] 2
Data Variable Absolute No_Wrap Linear
Preferred_State No_Null_Position Non_Volatile
Bitfield
Item(Local ): Usage, data= [ 0x01 ] 1
(null)
Item(Global): Report ID, data= [ 0x03 ] 3
Item(Global): Report Count, data= [ 0x01 ] 1
Item(Main ): Feature, data= [ 0x02 ] 2
Data Variable Absolute No_Wrap Linear
Preferred_State No_Null_Position Non_Volatile
Bitfield
Item(Local ): Usage, data= [ 0x01 ] 1
(null)
Item(Global): Report ID, data= [ 0x04 ] 4
Item(Global): Report Count, data= [ 0x01 ] 1
Item(Main ): Feature, data= [ 0x02 ] 2
Data Variable Absolute No_Wrap Linear
Preferred_State No_Null_Position Non_Volatile
Bitfield
Item(Local ): Usage, data= [ 0x01 ] 1
(null)
Item(Global): Report ID, data= [ 0x05 ] 5
Item(Global): Report Count, data= [ 0x01 ] 1
Item(Main ): Feature, data= [ 0x02 ] 2
Data Variable Absolute No_Wrap Linear
Preferred_State No_Null_Position Non_Volatile
Bitfield
Item(Local ): Usage, data= [ 0x01 ] 1
(null)
Item(Global): Report ID, data= [ 0x10 ] 16
Item(Global): Report Count, data= [ 0x02 ] 2
Item(Main ): Feature, data= [ 0x02 ] 2
Data Variable Absolute No_Wrap Linear
Preferred_State No_Null_Position Non_Volatile
Bitfield
Item(Local ): Usage, data= [ 0x01 ] 1
(null)
Item(Global): Report ID, data= [ 0x11 ] 17
Item(Global): Report Count, data= [ 0x10 ] 16
Item(Main ): Feature, data= [ 0x02 ] 2
Data Variable Absolute No_Wrap Linear
Preferred_State No_Null_Position Non_Volatile
Bitfield
Item(Local ): Usage, data= [ 0x01 ] 1
(null)
Item(Global): Report ID, data= [ 0x13 ] 19
Item(Global): Report Count, data= [ 0x01 ] 1
Item(Main ): Feature, data= [ 0x02 ] 2
Data Variable Absolute No_Wrap Linear
Preferred_State No_Null_Position Non_Volatile
Bitfield
Item(Local ): Usage, data= [ 0x01 ] 1
(null)
Item(Global): Report ID, data= [ 0x07 ] 7
Item(Global): Report Count, data= [ 0x09 ] 9
Item(Main ): Feature, data= [ 0x02 ] 2
Data Variable Absolute No_Wrap Linear
Preferred_State No_Null_Position Non_Volatile
Bitfield
Item(Local ): Usage, data= [ 0x01 ] 1
(null)
Item(Global): Report ID, data= [ 0x08 ] 8
Item(Global): Report Count, data= [ 0x09 ] 9
Item(Main ): Feature, data= [ 0x02 ] 2
Data Variable Absolute No_Wrap Linear
Preferred_State No_Null_Position Non_Volatile
Bitfield
Item(Local ): Usage, data= [ 0x01 ] 1
(null)
Item(Global): Report ID, data= [ 0x20 ] 32
Item(Global): Report Count, data= [ 0x05 ] 5
Item(Main ): Feature, data= [ 0x02 ] 2
Data Variable Absolute No_Wrap Linear
Preferred_State No_Null_Position Non_Volatile
Bitfield
Item(Local ): Usage, data= [ 0x01 ] 1
(null)
Item(Global): Report ID, data= [ 0x21 ] 33
Item(Global): Report Count, data= [ 0x01 ] 1
Item(Main ): Feature, data= [ 0x02 ] 2
Data Variable Absolute No_Wrap Linear
Preferred_State No_Null_Position Non_Volatile
Bitfield
Item(Local ): Usage, data= [ 0x01 ] 1
(null)
Item(Global): Report ID, data= [ 0x22 ] 34
Item(Global): Report Count, data= [ 0x01 ] 1
Item(Main ): Feature, data= [ 0x02 ] 2
Data Variable Absolute No_Wrap Linear
Preferred_State No_Null_Position Non_Volatile
Bitfield
Item(Local ): Usage, data= [ 0x01 ] 1
(null)
Item(Global): Report ID, data= [ 0x23 ] 35
Item(Global): Report Count, data= [ 0x0e ] 14
Item(Main ): Feature, data= [ 0x02 ] 2
Data Variable Absolute No_Wrap Linear
Preferred_State No_Null_Position Non_Volatile
Bitfield
Item(Local ): Usage, data= [ 0x01 ] 1
(null)
Item(Global): Report ID, data= [ 0x14 ] 20
Item(Global): Report Count, data= [ 0x1f ] 31
Item(Main ): Feature, data= [ 0x02 ] 2
Data Variable Absolute No_Wrap Linear
Preferred_State No_Null_Position Non_Volatile
Bitfield
Item(Local ): Usage, data= [ 0x01 ] 1
(null)
Item(Global): Report ID, data= [ 0x40 ] 64
Item(Global): Report Count, data= [ 0x0a ] 10
Item(Main ): Feature, data= [ 0x02 ] 2
Data Variable Absolute No_Wrap Linear
Preferred_State No_Null_Position Non_Volatile
Bitfield
Item(Local ): Usage, data= [ 0x01 ] 1
(null)
Item(Global): Report ID, data= [ 0x30 ] 48
Item(Global): Report Count, data= [ 0x02 0x00 ] 2
Item(Main ): Feature, data= [ 0x02 ] 2
Data Variable Absolute No_Wrap Linear
Preferred_State No_Null_Position Non_Volatile
Bitfield
Item(Local ): Usage, data= [ 0x01 ] 1
(null)
Item(Global): Report ID, data= [ 0x31 ] 49
Item(Global): Report Count, data= [ 0x21 0x00 ] 33
Item(Main ): Feature, data= [ 0x02 ] 2
Data Variable Absolute No_Wrap Linear
Preferred_State No_Null_Position Non_Volatile
Bitfield
Item(Local ): Usage, data= [ 0x01 ] 1
(null)
Item(Global): Report ID, data= [ 0x32 ] 50
Item(Global): Report Count, data= [ 0x21 0x00 ] 33
Item(Main ): Feature, data= [ 0x02 ] 2
Data Variable Absolute No_Wrap Linear
Preferred_State No_Null_Position Non_Volatile
Bitfield
Item(Local ): Usage, data= [ 0x01 ] 1
(null)
Item(Global): Report ID, data= [ 0x33 ] 51
Item(Global): Report Count, data= [ 0x01 ] 1
Item(Main ): Feature, data= [ 0x02 ] 2
Data Variable Absolute No_Wrap Linear
Preferred_State No_Null_Position Non_Volatile
Bitfield
Item(Local ): Usage, data= [ 0x01 ] 1
(null)
Item(Global): Report ID, data= [ 0x24 ] 36
Item(Global): Report Count, data= [ 0x1f ] 31
Item(Main ): Feature, data= [ 0x02 ] 2
Data Variable Absolute No_Wrap Linear
Preferred_State No_Null_Position Non_Volatile
Bitfield
Item(Local ): Usage, data= [ 0x01 ] 1
(null)
Item(Global): Report ID, data= [ 0x25 ] 37
Item(Global): Report Count, data= [ 0x04 ] 4
Item(Main ): Feature, data= [ 0x1f ] 31
Constant Variable Relative Wrap Non_Linear
Preferred_State No_Null_Position Non_Volatile
Bitfield
Item(Global): Report ID, data= [ 0xc0 ] 192
Item(Local ): Usage, data= [ 0x00 ] 0
(null)
Item(Global): Report Count, data= [ 0x09 ] 9
Item(Main ): Input, 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 0x81 EP 1 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0010 1x 16 bytes
bInterval 2
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 3 Human Interface Device
bInterfaceSubClass 0 No Subclass
bInterfaceProtocol 0 None
iInterface 0
HID Device Descriptor:
bLength 9
bDescriptorType 33
bcdHID 1.10
bCountryCode 0 Not supported
bNumDescriptors 1
bDescriptorType 34 Report
wDescriptorLength 38
Report Descriptor: (length is 38)
Item(Global): Usage Page, data= [ 0x00 0xff ] 65280
(null)
Item(Local ): Usage, data= [ 0x80 ] 128
(null)
Item(Main ): Collection, data= [ 0x01 ] 1
Application
Item(Global): Report ID, data= [ 0x02 ] 2
Item(Local ): Usage, data= [ 0x01 ] 1
(null)
Item(Global): Logical Minimum, data= [ 0x00 ] 0
Item(Global): Logical Maximum, data= [ 0xff 0x00 ] 255
Item(Global): Report Size, data= [ 0x08 ] 8
Item(Global): Report Count, data= [ 0x3f ] 63
Item(Main ): Input, data= [ 0x03 ] 3
Constant Variable Absolute No_Wrap Linear
Preferred_State No_Null_Position Non_Volatile
Bitfield
Item(Global): Report ID, data= [ 0x03 ] 3
Item(Local ): Usage, data= [ 0x01 ] 1
(null)
Item(Global): Logical Minimum, data= [ 0x00 ] 0
Item(Global): Logical Maximum, data= [ 0xff 0x00 ] 255
Item(Global): Report Size, data= [ 0x08 ] 8
Item(Global): Report Count, data= [ 0x3f ] 63
Item(Main ): Input, data= [ 0x03 ] 3
Constant 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 0x82 EP 2 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 2
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 2
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.10
bCountryCode 0 Not supported
bNumDescriptors 1
bDescriptorType 34 Report
wDescriptorLength 52
Report Descriptor: (length is 52)
Item(Global): Usage Page, data= [ 0x01 ] 1
Generic Desktop Controls
Item(Local ): Usage, data= [ 0x02 ] 2
Mouse
Item(Main ): Collection, data= [ 0x01 ] 1
Application
Item(Global): Report ID, data= [ 0x01 ] 1
Item(Local ): Usage, data= [ 0x01 ] 1
Pointer
Item(Main ): Collection, data= [ 0x00 ] 0
Physical
Item(Global): Usage Page, data= [ 0x09 ] 9
Buttons
Item(Local ): Usage Minimum, data= [ 0x01 ] 1
Button 1 (Primary)
Item(Local ): Usage Maximum, data= [ 0x05 ] 5
Button 5
Item(Global): Logical Minimum, data= [ 0x00 ] 0
Item(Global): Logical Maximum, data= [ 0x01 ] 1
Item(Global): Report Count, data= [ 0x05 ] 5
Item(Global): Report Size, data= [ 0x01 ] 1
Item(Main ): Input, data= [ 0x02 ] 2
Data Variable Absolute No_Wrap Linear
Preferred_State No_Null_Position Non_Volatile
Bitfield
Item(Global): Report Count, data= [ 0x01 ] 1
Item(Global): Report Size, data= [ 0x03 ] 3
Item(Main ): Input, data= [ 0x01 ] 1
Constant Array Absolute No_Wrap Linear
Preferred_State No_Null_Position Non_Volatile
Bitfield
Item(Global): Usage Page, data= [ 0x01 ] 1
Generic Desktop Controls
Item(Local ): Usage, data= [ 0x30 ] 48
Direction-X
Item(Local ): Usage, data= [ 0x31 ] 49
Direction-Y
Item(Global): Logical Minimum, data= [ 0x81 ] 129
Item(Global): Logical Maximum, data= [ 0x7f ] 127
Item(Global): Report Size, data= [ 0x08 ] 8
Item(Global): Report Count, data= [ 0x02 ] 2
Item(Main ): Input, data= [ 0x06 ] 6
Data Variable Relative No_Wrap Linear
Preferred_State No_Null_Position Non_Volatile
Bitfield
Item(Main ): End Collection, data=none
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 0x0040 1x 64 bytes
bInterval 2
Device Status: 0x0000
(Bus Powered)
Index: share/man/man4/uwacom.4
===================================================================
RCS file: share/man/man4/uwacom.4
diff -N share/man/man4/uwacom.4
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ share/man/man4/uwacom.4 5 Sep 2016 18:36:32 -0000
@@ -0,0 +1,60 @@
+.\" $OpenBSD$
+.\"
+.\" Copyright (c) 2016 Frank Groeneveld <[email protected]>
+.\"
+.\" Permission to use, copy, modify, and distribute this software for any
+.\" purpose with or without fee is hereby granted, provided that the above
+.\" copyright notice and this permission notice appear in all copies.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCAIMS ALL WARRANTIES
+.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+.\"
+.Dd $Mdocdate: September 5 2016 $
+.Dt UWACOM 4
+.Os
+.Sh NAME
+.Nm uwacom
+.Nd Wacom USB tablets
+.Sh SYNOPSIS
+.Cd "uwacom* at uhidev?"
+.Cd "wsmouse* at uwacom? mux 0"
+.Sh DESCRIPTION
+The
+.Nm
+driver provides basic support for Wacom USB tablets.
+Access to these devices is through the
+.Xr wscons 4
+framework.
+.Pp
+Absolute positioning of the mouse cursor can be done by hovering the pen above
the tablet. Touching the tablet with the pen tip will emulate mouse button 0,
while the two pen buttons will emulate button 1 and button 2.
+.Pp
+The
+.Nm
+driver supports the following Wacom tablets:
+.Pp
+.Bl -column "Intuos Draw" "Model Number" -offset 6n
+.It Em Name Ta Model Number
+.It Li Intuos Draw Ta CTL-490
+.Sh SEE ALSO
+.Xr uhidev 4 ,
+.Xr usb 4 ,
+.Xr wsmouse 4
+.Sh HISTORY
+The
+.Nm
+driver
+first appeared in
+.Ox 6.1 .
+.Sh AUTHORS
+.An -nosplit
+The
+.Nm
+driver was written by
+.An Frank Groeneveld [email protected] .
+.Sh BUGS
+To make axis scaling work correctly, the device should be plugged in when X
starts. Advanced features such as pen tip pressure are not supported.
Index: sys/arch/amd64/conf/GENERIC
===================================================================
RCS file: /cvs/src/sys/arch/amd64/conf/GENERIC,v
retrieving revision 1.432
diff -u -p -r1.432 GENERIC
--- sys/arch/amd64/conf/GENERIC 4 Sep 2016 10:22:05 -0000 1.432
+++ sys/arch/amd64/conf/GENERIC 5 Sep 2016 18:36:32 -0000
@@ -244,6 +244,8 @@ umass* at uhub? # USB Mass Storage devi
ubcmtp* at uhub? # Broadcom USB trackpad
wsmouse* at ubcmtp? mux 0
uhidev* at uhub? # Human Interface Devices
+uwacom* at uhidev? # USB Wacom tablet
+wsmouse* at uwacom? mux 0
ums* at uhidev? # USB mouse
wsmouse* at ums? mux 0
uts* at uhub? # USB touchscreen
Index: sys/dev/hid/hid.h
===================================================================
RCS file: /cvs/src/sys/dev/hid/hid.h,v
retrieving revision 1.4
diff -u -p -r1.4 hid.h
--- sys/dev/hid/hid.h 20 Jan 2016 01:26:00 -0000 1.4
+++ sys/dev/hid/hid.h 5 Sep 2016 18:36:32 -0000
@@ -127,6 +127,7 @@ int hid_is_collection(const void *, int,
#define HUP_MICROSOFT 0xff00
/* XXX compat */
#define HUP_APPLE 0x00ff
+#define HUP_WACOM 0xff00
/* Usages, Power Device */
#define HUP_INAME 0x0001
Index: sys/dev/usb/files.usb
===================================================================
RCS file: /cvs/src/sys/dev/usb/files.usb,v
retrieving revision 1.130
diff -u -p -r1.130 files.usb
--- sys/dev/usb/files.usb 3 Sep 2016 13:37:45 -0000 1.130
+++ sys/dev/usb/files.usb 5 Sep 2016 18:36:32 -0000
@@ -435,3 +435,8 @@ file dev/usb/uberry.c uberry
device upd: hid
attach upd at uhidbus
file dev/usb/upd.c upd
+
+# Wacom tablets
+device uwacom: hid, hidms, wsmousedev
+attach uwacom at uhidbus
+file dev/usb/uwacom.c uwacom
Index: sys/dev/usb/usbdevs
===================================================================
RCS file: /cvs/src/sys/dev/usb/usbdevs,v
retrieving revision 1.666
diff -u -p -r1.666 usbdevs
--- sys/dev/usb/usbdevs 1 Jun 2016 09:48:20 -0000 1.666
+++ sys/dev/usb/usbdevs 5 Sep 2016 18:36:32 -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 INTUOS_DRAW 0x033b Intuos Draw (CTL-490)
/* WAGO Kontakttechnik products */
product WAGO SERVICECABLE 0x07a6 Service Cable 750-923
Index: sys/dev/usb/usbdevs.h
===================================================================
RCS file: /cvs/src/sys/dev/usb/usbdevs.h,v
retrieving revision 1.678
diff -u -p -r1.678 usbdevs.h
--- sys/dev/usb/usbdevs.h 1 Jun 2016 09:48:54 -0000 1.678
+++ sys/dev/usb/usbdevs.h 5 Sep 2016 18:36:32 -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_INTUOS_DRAW 0x033b /* Intuos Draw
(CTL-490) */
/* WAGO Kontakttechnik products */
#define USB_PRODUCT_WAGO_SERVICECABLE 0x07a6 /* Service
Cable 750-923 */
Index: sys/dev/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
--- sys/dev/usb/usbdevs_data.h 1 Jun 2016 09:48:54 -0000 1.672
+++ sys/dev/usb/usbdevs_data.h 5 Sep 2016 18:36:32 -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_INTUOS_DRAW,
+ "Intuos Draw (CTL-490)",
},
{
USB_VENDOR_WAGO, USB_PRODUCT_WAGO_SERVICECABLE,
Index: sys/dev/usb/uwacom.c
===================================================================
RCS file: sys/dev/usb/uwacom.c
diff -N sys/dev/usb/uwacom.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ sys/dev/usb/uwacom.c 5 Sep 2016 18:36:32 -0000
@@ -0,0 +1,233 @@
+/* $OpenBSD$ */
+
+/*
+ * Copyright (c) 2016 Frank Groeneveld <[email protected]>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* Driver for USB Wacom tablets */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+
+#include <dev/usb/usb.h>
+#include <dev/usb/usbhid.h>
+
+#include <dev/usb/usbdi.h>
+#include <dev/usb/usbdevs.h>
+#include <dev/usb/uhidev.h>
+
+#include <dev/wscons/wsconsio.h>
+#include <dev/wscons/wsmousevar.h>
+
+#include <dev/hid/hidmsvar.h>
+
+struct uwacom_softc {
+ struct uhidev sc_hdev;
+ struct hidms sc_ms;
+ struct hid_location sc_loc_tip_press;
+};
+
+struct cfdriver uwacom_cd = {
+ NULL, "uwacom", DV_DULL
+};
+
+
+const struct usb_devno uwacom_devs[] = {
+ { USB_VENDOR_WACOM, USB_PRODUCT_WACOM_INTUOS_DRAW }
+};
+
+int uwacom_match(struct device *, void *, void *);
+void uwacom_attach(struct device *, struct device *, void *);
+int uwacom_detach(struct device *, int);
+void uwacom_intr(struct uhidev *, void *, u_int);
+int uwacom_enable(void *);
+void uwacom_disable(void *);
+int uwacom_ioctl(void *, u_long, caddr_t, int, struct proc *);
+
+const struct cfattach uwacom_ca = {
+ sizeof(struct uwacom_softc), uwacom_match, uwacom_attach, uwacom_detach
+};
+
+const struct wsmouse_accessops uwacom_accessops = {
+ uwacom_enable,
+ uwacom_ioctl,
+ uwacom_disable,
+};
+
+int
+uwacom_match(struct device *parent, void *match, void *aux)
+{
+ struct uhidev_attach_arg *uha = aux;
+ int size;
+ void *desc;
+
+ if (usb_lookup(uwacom_devs, uha->uaa->vendor,
+ uha->uaa->product) == NULL)
+ return (UMATCH_NONE);
+
+ uhidev_get_report_desc(uha->parent, &desc, &size);
+
+ if (!hid_locate(desc, size, HID_USAGE2(HUP_WACOM, HUG_POINTER),
+ uha->reportid, hid_input, NULL, NULL))
+ return (UMATCH_NONE);
+
+ return (UMATCH_IFACECLASS);
+}
+
+void
+uwacom_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct uwacom_softc *sc = (struct uwacom_softc *)self;
+ struct hidms *ms = &sc->sc_ms;
+ struct uhidev_attach_arg *uha = (struct uhidev_attach_arg *)aux;
+ struct usb_attach_arg *uaa = uha->uaa;
+ int size, repid;
+ void *desc;
+
+ sc->sc_hdev.sc_intr = uwacom_intr;
+ sc->sc_hdev.sc_parent = uha->parent;
+ sc->sc_hdev.sc_udev = uaa->device;
+ sc->sc_hdev.sc_report_id = uha->reportid;
+
+ uhidev_get_report_desc(uha->parent, &desc, &size);
+ repid = uha->reportid;
+ sc->sc_hdev.sc_isize = hid_report_size(desc, size, hid_input, repid);
+ sc->sc_hdev.sc_osize = hid_report_size(desc, size, hid_output, repid);
+ sc->sc_hdev.sc_fsize = hid_report_size(desc, size, hid_feature, repid);
+
+ ms->sc_device = self;
+ ms->sc_rawmode = 1;
+ ms->sc_flags = HIDMS_ABSX | HIDMS_ABSY;
+ ms->sc_num_buttons = 3;
+ ms->sc_loc_x.pos = 8;
+ ms->sc_loc_x.size = 16;
+ ms->sc_loc_y.pos = 24;
+ ms->sc_loc_y.size = 16;
+
+ ms->sc_tsscale.minx = 0;
+ ms->sc_tsscale.maxx = 7600;
+ ms->sc_tsscale.miny = 0;
+ ms->sc_tsscale.maxy = 4750;
+
+ ms->sc_loc_btn[0].pos = 0;
+ ms->sc_loc_btn[0].size = 1;
+ ms->sc_loc_btn[1].pos = 1;
+ ms->sc_loc_btn[1].size = 1;
+ ms->sc_loc_btn[2].pos = 2;
+ ms->sc_loc_btn[2].size = 1;
+
+ sc->sc_loc_tip_press.pos = 43;
+ sc->sc_loc_tip_press.size = 8;
+
+ hidms_attach(ms, &uwacom_accessops);
+}
+
+int
+uwacom_detach(struct device *self, int flags)
+{
+ struct uwacom_softc *sc = (struct uwacom_softc *)self;
+ struct hidms *ms = &sc->sc_ms;
+
+ return hidms_detach(ms, flags);
+}
+
+void
+uwacom_intr(struct uhidev *addr, void *buf, u_int len)
+{
+ struct uwacom_softc *sc = (struct uwacom_softc *)addr;
+ struct hidms *ms = &sc->sc_ms;
+ u_int32_t buttons = 0;
+ uint8_t *data = (uint8_t *)buf;
+ int i, x, y, pressure;
+
+ if (ms->sc_enabled == 0)
+ return;
+
+ if(!(data[0] & 0xa0) && !(data[0] & 0xe0))
+ return;
+
+ x = be16toh(hid_get_data(data, len, &ms->sc_loc_x));
+ y = be16toh(hid_get_data(data, len, &ms->sc_loc_y));
+ pressure = hid_get_data(data, len, &sc->sc_loc_tip_press);
+
+ for (i = 0; i < ms->sc_num_buttons; i++)
+ if (hid_get_data(data, len, &ms->sc_loc_btn[i]))
+ buttons |= (1 << i);
+
+ /* button 0 reporting is flaky, use tip pressure for it */
+ if (pressure > 10)
+ buttons |= 1;
+ else
+ buttons &= ~1;
+
+ if (x != 0 || y != 0 || buttons != ms->sc_buttons) {
+ wsmouse_set(ms->sc_wsmousedev, WSMOUSE_ABS_X, x, 0);
+ wsmouse_set(ms->sc_wsmousedev, WSMOUSE_ABS_Y, y, 0);
+
+ /* ignore proximity, it will cause invalid button 2 events */
+ if ((data[0] & 0xf0) != 0xc0)
+ WSMOUSE_INPUT(ms->sc_wsmousedev, buttons, 0, 0, 0, 0);
+ }
+}
+
+int
+uwacom_enable(void *v)
+{
+ struct uwacom_softc *sc = v;
+ struct hidms *ms = &sc->sc_ms;
+ int rv;
+
+ if (usbd_is_dying(sc->sc_hdev.sc_udev))
+ return EIO;
+
+ if ((rv = hidms_enable(ms)) != 0)
+ return rv;
+
+ return uhidev_open(&sc->sc_hdev);
+}
+
+void
+uwacom_disable(void *v)
+{
+ struct uwacom_softc *sc = v;
+ struct hidms *ms = &sc->sc_ms;
+
+ hidms_disable(ms);
+ uhidev_close(&sc->sc_hdev);
+}
+
+int
+uwacom_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
+{
+ struct uwacom_softc *sc = v;
+ struct hidms *ms = &sc->sc_ms;
+ int rc;
+
+ rc = uhidev_ioctl(&sc->sc_hdev, cmd, data, flag, p);
+ if (rc != -1)
+ return rc;
+ rc = hidms_ioctl(ms, cmd, data, flag, p);
+ if (rc != -1)
+ return rc;
+
+ switch (cmd) {
+ case WSMOUSEIO_GTYPE:
+ *(u_int *)data = WSMOUSE_TYPE_USB;
+ return 0;
+ default:
+ return -1;
+ }
+}