Dear tech-kern,

Please find a patch below for a new uintuos driver for two Wacom
Intuos tablets (the Art CTH490 and Intuos M).  The Intuos M also
has a bluetooth mode which I have not looked at.

Linux has extensive support for the Wacom devices, but (in my
opinion) the code is so tangled that it was much easier to work
back from the reports and watching how they changed in response to
physical events.

This means that the Wacom tablet features are not all supported,
but all of the pen features are supported (so it is actually a "pen
driver", rather than a "tablet driver").

I am quite confident that the larger CTH690 should also work,
but I have no device to test with.

-- 
Kind regards,

Yorick Hardy

Index: distrib/sets/lists/man/mi
==================================================================
--- distrib/sets/lists/man/mi
+++ distrib/sets/lists/man/mi
@@ -1875,10 +1875,11 @@
 ./usr/share/man/cat4/uhid.0                    man-sys-catman          .cat
 ./usr/share/man/cat4/uhidev.0                  man-sys-catman          .cat
 ./usr/share/man/cat4/uhmodem.0                 man-sys-catman          .cat
 ./usr/share/man/cat4/uhso.0                    man-sys-catman          .cat
 ./usr/share/man/cat4/uhub.0                    man-sys-catman          .cat
+./usr/share/man/cat4/uintuos.0                 man-sys-catman          .cat
 ./usr/share/man/cat4/uipad.0                   man-sys-catman          .cat
 ./usr/share/man/cat4/uipaq.0                   man-sys-catman          .cat
 ./usr/share/man/cat4/uirda.0                   man-sys-catman          .cat
 ./usr/share/man/cat4/uk.0                      man-sys-catman          .cat
 ./usr/share/man/cat4/ukbd.0                    man-sys-catman          .cat
@@ -4974,10 +4976,11 @@
 ./usr/share/man/html4/uhid.html                        man-sys-htmlman         
html
 ./usr/share/man/html4/uhidev.html              man-sys-htmlman         html
 ./usr/share/man/html4/uhmodem.html             man-sys-htmlman         html
 ./usr/share/man/html4/uhso.html                        man-sys-htmlman         
html
 ./usr/share/man/html4/uhub.html                        man-sys-htmlman         
html
+./usr/share/man/html4/uintuos.html             man-sys-htmlman         html
 ./usr/share/man/html4/uipad.html               man-sys-htmlman         html
 ./usr/share/man/html4/uipaq.html               man-sys-htmlman         html
 ./usr/share/man/html4/uirda.html               man-sys-htmlman         html
 ./usr/share/man/html4/uk.html                  man-sys-htmlman         html
 ./usr/share/man/html4/ukbd.html                        man-sys-htmlman         
html
@@ -7997,10 +8001,11 @@
 ./usr/share/man/man4/uhid.4                    man-sys-man             .man
 ./usr/share/man/man4/uhidev.4                  man-sys-man             .man
 ./usr/share/man/man4/uhmodem.4                 man-sys-man             .man
 ./usr/share/man/man4/uhso.4                    man-sys-man             .man
 ./usr/share/man/man4/uhub.4                    man-sys-man             .man
+./usr/share/man/man4/uintuos.4                 man-sys-man             .man
 ./usr/share/man/man4/uipad.4                   man-sys-man             .man
 ./usr/share/man/man4/uipaq.4                   man-sys-man             .man
 ./usr/share/man/man4/uirda.4                   man-sys-man             .man
 ./usr/share/man/man4/uk.4                      man-sys-man             .man
 ./usr/share/man/man4/ukbd.4                    man-sys-man             .man

Index: share/man/man4/Makefile
==================================================================
--- share/man/man4/Makefile
+++ share/man/man4/Makefile
@@ -80,15 +80,15 @@
        mos.4 mue.4 \
        ohci.4 \
        slhci.4 stuirda.4 u3g.4 ualea.4 uatp.4 uaudio.4 uberry.4 ubsa.4 ubt.4 \
        uchcom.4 \
        ucom.4 ucycom.4 udav.4 udsbr.4 uftdi.4 ugen.4 ugensa.4 uhci.4 uhid.4 \
-       uhidev.4 uhmodem.4 uhso.4 uipad.4 uipaq.4 uirda.4 ukbd.4 ukyopon.4 \
+       uhidev.4 uhmodem.4 uhso.4 uintuos.4 uipad.4 uipaq.4 uirda.4 ukbd.4 
ukyopon.4 \
        ulpt.4 umass.4 umcs.4 umct.4 umidi.4 umodem.4 ums.4 upgt.4 upl.4 \
        uplcom.4 ure.4 urio.4 url.4 urndis.4 urtw.4 urtwn.4 \
        usb.4 usbnet.4 uscanner.4 uslsa.4 usmsc.4 usscanner.4 \
        ustir.4 uthum.4 utoppy.4 uts.4 uvideo.4 uvisor.4 uvscom.4 uyap.4 \
        uyurex.4 \
        xhci.4 \
 
 # Ir devices
 MAN+=  irframe.4 cir.4 irframetty.4 oboe.4

Index: share/man/man4/uhidev.4
==================================================================
--- share/man/man4/uhidev.4
+++ share/man/man4/uhidev.4
@@ -32,16 +32,17 @@
 .Os
 .Sh NAME
 .Nm uhidev
 .Nd USB Human Interface Device support
 .Sh SYNOPSIS
-.Cd "uhidev* at uhub?"
-.Cd "ucycom* at uhidev? reportid ?"
-.Cd "uhid*   at uhidev? reportid ?"
-.Cd "ukbd*   at uhidev? reportid ?"
-.Cd "ums*    at uhidev? reportid ?"
-.Cd "uts*    at uhidev? reportid ?"
+.Cd "uhidev*  at uhub?"
+.Cd "ucycom*  at uhidev? reportid ?"
+.Cd "uhid*    at uhidev? reportid ?"
+.Cd "uintuos* at uhidev? reportid ?"
+.Cd "ukbd*    at uhidev? reportid ?"
+.Cd "ums*     at uhidev? reportid ?"
+.Cd "uts*     at uhidev? reportid ?"
 .Sh DESCRIPTION
 The
 .Nm
 driver handles all Human Interface Devices.
 Each HID device can have several components, e.g., a keyboard and
@@ -55,10 +56,11 @@
 .Nm
 only dispatches data to them based on the report id.
 .Sh SEE ALSO
 .Xr ucycom 4 ,
 .Xr uhid 4 ,
+.Xr uintuos 4 ,
 .Xr ukbd 4 ,
 .Xr ums 4 ,
 .Xr usb 4 ,
 .Xr uts 4
 .Sh HISTORY

Index: share/man/man4/uintuos.4
==================================================================
--- share/man/man4/uintuos.4
+++ share/man/man4/uintuos.4
@@ -0,0 +1,63 @@
+.\" $NetBSD$
+.\"
+.\" Copyright (c) 2019 The NetBSD Foundation, Inc.
+.\" All rights reserved.
+.\"
+.\" This code is derived from software contributed to The NetBSD Foundation
+.\" by Yorick Hardy.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+.\" PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.Dd September 29, 2019
+.Dt UINTUOS 4
+.Os
+.Sh NAME
+.Nm uintuos
+.Nd USB Wacom Intuos Pen
+.Sh SYNOPSIS
+.Cd "uintuos* at uhidev? reportid ?"
+.Cd "wsmouse* at uintuos?"
+.Sh DESCRIPTION
+The
+.Nm
+driver provides support for the stylus of the Wacom Intuos Art CTH-490/K0
+and the Wacom Intuos CTL-6100WL.
+Access to stylus events is through the
+.Xr wsmouse 4
+driver.
+.Sh SEE ALSO
+.Xr uhidev 4 ,
+.Xr wsmouse 4
+.Sh HISTORY
+The
+.Nm
+driver was written by Yorick Hardy for
+.Nx .
+The
+.Nm
+driver appeared in
+.Nx 10.0 .
+.Sh BUGS
+Calibration is only possible at compile time.
+Also, not all
+.Nx Ns -supplied
+X servers support the absolute position events it generates.

Index: sys/dev/DEVNAMES
==================================================================
--- sys/dev/DEVNAMES
+++ sys/dev/DEVNAMES
@@ -1398,10 +1398,11 @@
 uhidbus                        MI              Attribute
 uhidev                 MI
 uhmodem                        MI
 uhso                   MI
 uhub                   MI
+uintuos                        MI
 uipaq                  MI
 uirda                  MI
 uk                     MI
 ukbd                   MI
 ukphy                  MI

Index: sys/dev/usb/files.usb
==================================================================
--- sys/dev/usb/files.usb
+++ sys/dev/usb/files.usb
@@ -187,10 +187,15 @@
 # eGalax USB Touch Panel
 device uep: wsmousedev, tpcalib
 attach uep at usbdevif
 file   dev/usb/uep.c                   uep                     needs-flag
 
+# Wacom Intuos PTS Pen
+device uintuos: wsmousedev, tpcalib
+attach uintuos at uhidbus
+file   dev/usb/uintuos.c                       ums
+
 # Cypress microcontroller based serial adapters
 device ucycom: hid
 attach ucycom at uhidbus
 file   dev/usb/ucycom.c                ucycom                  needs-flag
 
Index: sys/dev/usb/uhidev.c
==================================================================
--- sys/dev/usb/uhidev.c
+++ sys/dev/usb/uhidev.c
@@ -232,10 +232,11 @@
                        descptr = uhid_graphire3_4x5_report_descr;
                        break;
                case USB_PRODUCT_WACOM_GRAPHIRE:
                case USB_PRODUCT_WACOM_GRAPHIRE2:
                case USB_PRODUCT_WACOM_XD0912U:
+               case USB_PRODUCT_WACOM_CTH490K0:
                case USB_PRODUCT_WACOM_CTH690K0:
                        reportbuf[0] = 0x02;
                        reportbuf[1] = 0x02;
                        usbd_set_report(uiaa->uiaa_iface, UHID_FEATURE_REPORT, 
2,
                            &reportbuf, 2);

Index: sys/dev/usb/uintuos.c
==================================================================
--- sys/dev/usb/uintuos.c
+++ sys/dev/usb/uintuos.c
@@ -0,0 +1,397 @@
+/*     $NetBSD$        */
+
+/*
+ * Copyright (c) 2019 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Yorick Hardy.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ *  Wacom Intuos Pen driver.
+ *  (partially based on uep.c and ums.c)
+ */
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+#include <sys/ioctl.h>
+#include <sys/vnode.h>
+
+#include <dev/usb/usb.h>
+#include <dev/usb/usbhid.h>
+
+#include <dev/usb/usbdi.h>
+#include <dev/usb/usbdivar.h>
+#include <dev/usb/usbdi_util.h>
+#include <dev/usb/usbdevs.h>
+#include <dev/usb/uhidev.h>
+
+#include <dev/wscons/wsconsio.h>
+#include <dev/wscons/wsmousevar.h>
+#include <dev/wscons/tpcalibvar.h>
+
+struct uintuos_softc {
+       struct uhidev sc_hdev;
+
+       device_t                sc_wsmousedev;  /* wsmouse device */
+       struct tpcalib_softc    sc_tpcalib;     /* calibration */
+
+       u_char sc_enabled;
+       u_char sc_dying;
+};
+
+Static void uintuos_cth490_intr(struct uhidev *, void *, u_int);
+Static void uintuos_ctl6100_intr(struct uhidev *, void *, u_int);
+
+Static int     uintuos_enable(void *);
+Static void    uintuos_disable(void *);
+Static int     uintuos_ioctl(void *, u_long, void *, int, struct lwp *);
+
+const struct wsmouse_accessops uintuos_accessops = {
+       uintuos_enable,
+       uintuos_ioctl,
+       uintuos_disable,
+};
+
+int uintuos_match(device_t, cfdata_t, void *);
+void uintuos_attach(device_t, device_t, void *);
+void uintuos_childdet(device_t, device_t);
+int uintuos_detach(device_t, int);
+int uintuos_activate(device_t, enum devact);
+
+CFATTACH_DECL2_NEW(uintuos, sizeof(struct uintuos_softc), uintuos_match, 
uintuos_attach,
+    uintuos_detach, uintuos_activate, NULL, uintuos_childdet);
+
+int
+uintuos_match(device_t parent, cfdata_t match, void *aux)
+{
+       struct uhidev_attach_arg *uha = aux;
+
+       if ((uha->uiaa->uiaa_vendor == USB_VENDOR_WACOM) &&
+               (uha->uiaa->uiaa_product == USB_PRODUCT_WACOM_CTH490K0) &&
+               (uha->reportid == 16))
+               return UMATCH_VENDOR_PRODUCT;
+
+       if ((uha->uiaa->uiaa_vendor == USB_VENDOR_WACOM) &&
+               (uha->uiaa->uiaa_product == USB_PRODUCT_WACOM_CTL6100WL) &&
+               (uha->reportid == 16))
+               return UMATCH_VENDOR_PRODUCT;
+
+       return UMATCH_NONE;
+}
+
+void
+uintuos_attach(device_t parent, device_t self, void *aux)
+{
+       struct uintuos_softc *sc = device_private(self);
+       struct uhidev_attach_arg *uha = aux;
+       struct wsmousedev_attach_args a;
+       struct wsmouse_calibcoords default_calib;
+
+       aprint_normal("\n");
+       aprint_naive("\n");
+
+       sc->sc_hdev.sc_dev = self;
+       sc->sc_hdev.sc_parent = uha->parent;
+       sc->sc_hdev.sc_report_id = uha->reportid;
+
+       switch (uha->uiaa->uiaa_product) {
+       case USB_PRODUCT_WACOM_CTH490K0:
+               default_calib.minx = 0,
+               default_calib.miny = 0,
+               default_calib.maxx = 7600,
+               default_calib.maxy = 4750,
+               sc->sc_hdev.sc_intr = uintuos_cth490_intr;
+               break;
+       case USB_PRODUCT_WACOM_CTL6100WL:
+               default_calib.minx = 0,
+               default_calib.miny = 0,
+               default_calib.maxx = 21600,
+               default_calib.maxy = 13471,
+               sc->sc_hdev.sc_intr = uintuos_ctl6100_intr;
+               break;
+       default:
+               sc->sc_hdev.sc_intr = uintuos_cth490_intr;
+               aprint_error_dev(self, "unsupported product\n");
+               break;
+       }
+
+
+       if (!pmf_device_register(self, NULL, NULL))
+               aprint_error_dev(self, "couldn't establish power handler\n");
+
+       a.accessops = &uintuos_accessops;
+       a.accesscookie = sc;
+
+       sc->sc_wsmousedev = config_found(self, &a, wsmousedevprint);
+
+       default_calib.samplelen = WSMOUSE_CALIBCOORDS_RESET,
+       tpcalib_init(&sc->sc_tpcalib);
+       tpcalib_ioctl(&sc->sc_tpcalib, WSMOUSEIO_SCALIBCOORDS,
+               (void *)&default_calib, 0, 0);
+
+       return;
+}
+
+int
+uintuos_detach(device_t self, int flags)
+{
+       struct uintuos_softc *sc = device_private(self);
+       int rv = 0;
+
+       sc->sc_dying = 1;
+
+       if (sc->sc_wsmousedev != NULL)
+               rv = config_detach(sc->sc_wsmousedev, flags);
+
+       pmf_device_deregister(self);
+
+       return rv;
+}
+
+void
+uintuos_childdet(device_t self, device_t child)
+{
+       struct uintuos_softc *sc = device_private(self);
+
+       KASSERT(sc->sc_wsmousedev == child);
+       sc->sc_wsmousedev = NULL;
+}
+
+int
+uintuos_activate(device_t self, enum devact act)
+{
+       struct uintuos_softc *sc = device_private(self);
+
+       switch (act) {
+       case DVACT_DEACTIVATE:
+               sc->sc_dying = 1;
+               return 0;
+       default:
+               return EOPNOTSUPP;
+       }
+}
+
+Static int
+uintuos_enable(void *v)
+{
+       struct uintuos_softc *sc = v;
+       int error;
+
+       if (sc->sc_dying)
+               return EIO;
+
+       if (sc->sc_enabled)
+               return EBUSY;
+
+       sc->sc_enabled = 1;
+
+       error = uhidev_open(&sc->sc_hdev);
+       if (error)
+               sc->sc_enabled = 0;
+
+       return error;
+}
+
+Static void
+uintuos_disable(void *v)
+{
+       struct uintuos_softc *sc = v;
+
+       if (!sc->sc_enabled) {
+               printf("uintuos_disable: not enabled\n");
+               return;
+       }
+
+       sc->sc_enabled = 0;
+       uhidev_close(&sc->sc_hdev);
+}
+
+Static int
+uintuos_ioctl(void *v, u_long cmd, void *data, int flag, struct lwp *l)
+{
+       struct uintuos_softc *sc = v;
+       struct wsmouse_id *id;
+
+       switch (cmd) {
+       case WSMOUSEIO_GTYPE:
+               *(u_int *)data = WSMOUSE_TYPE_TPANEL;
+               return 0;
+
+       case WSMOUSEIO_GETID:
+               id = (struct wsmouse_id *)data;
+               if (id->type != WSMOUSE_ID_TYPE_UIDSTR)
+                       return EINVAL;
+
+               snprintf(id->data, WSMOUSE_ID_MAXLEN, "%s %s %s",
+                       sc->sc_hdev.sc_parent->sc_udev->ud_vendor,
+                       sc->sc_hdev.sc_parent->sc_udev->ud_product,
+                       sc->sc_hdev.sc_parent->sc_udev->ud_serial);
+               id->length = strlen(id->data);
+               return 0;
+
+       case WSMOUSEIO_SCALIBCOORDS:
+       case WSMOUSEIO_GCALIBCOORDS:
+               return tpcalib_ioctl(&sc->sc_tpcalib, cmd, data, flag, l);
+       }
+
+       return EPASSTHROUGH;
+}
+
+void
+uintuos_cth490_intr(struct uhidev *addr, void *ibuf, u_int len)
+{
+       struct uintuos_softc *sc = (struct uintuos_softc *)addr;
+       u_char *p = ibuf;
+       u_int btns = 0;
+       int x = 0, y = 0, z = 0, s;
+
+       if (len != 9) {
+               aprint_error_dev(sc->sc_hdev.sc_dev, "wrong report size - 
ignoring\n");
+               return;
+       }
+
+       /*
+        * Each report package contains 9 bytes as below (guessed by 
inspection):
+        *
+        * Byte 0       ?VR? ?21T
+        * Byte 1       X coordinate (high byte)
+        * Byte 2       X coordinate (low byte)
+        * Byte 3       Y coordinate (high byte)
+        * Byte 4       Y coordinate (low byte) 
+        * Byte 5       Pressure (high byte)
+        * Byte 6       Pressure (low byte)
+        * Byte 7       zero
+        * Byte 8       quality
+        *
+        * V: 1=valid data, 0=don't use
+        * R: 1=in range, 2=cannot sense
+        * 1: barrel button 1, 1=pressed, 0=not pressed
+        * 2: barrel button 2, 1=pressed, 0=not pressed
+        * T: 1=touched, 0=not touched (unreliable?)
+        * quality: 0 - 255, 255 = most reliable?
+        *
+        */
+
+       /* no valid data or not in range */
+       if ((p[0] & 0x40) == 0 || (p[0] & 0x20) == 0)
+               return;
+
+       if (sc->sc_wsmousedev != NULL) {
+               x = (p[1] << 8) | p[2];
+               y = (p[3] << 8) | p[4];
+               z = (p[5] << 8) | p[6];
+
+               /*
+                * The "T" bit seems to require a *lot* of pressure to remain 
"1",
+                * use the pressure value instead (> 255) for button 1
+                *
+                */
+               if (p[5] != 0)
+                       btns |= 1;
+
+               /* barrel button 1 => button 2 */
+               if (p[0] & 0x02)
+                       btns |= 2;
+
+               /* barrel button 2 => button 3 */
+               if (p[0] & 0x04)
+                       btns |= 4;
+
+               tpcalib_trans(&sc->sc_tpcalib, x, y, &x, &y);
+
+               s = spltty();
+               wsmouse_input(sc->sc_wsmousedev, btns, x, y, z, 0,
+                       WSMOUSE_INPUT_ABSOLUTE_X |
+                       WSMOUSE_INPUT_ABSOLUTE_Y |
+                       WSMOUSE_INPUT_ABSOLUTE_Z);
+               splx(s);
+       }
+}
+
+void
+uintuos_ctl6100_intr(struct uhidev *addr, void *ibuf, u_int len)
+{
+       struct uintuos_softc *sc = (struct uintuos_softc *)addr;
+       u_char *p = ibuf;
+       u_int btns = 0;
+       int x = 0, y = 0, z = 0, s;
+
+       if (len != 26) {
+               aprint_error_dev(sc->sc_hdev.sc_dev, "wrong report size - 
ignoring\n");
+               return;
+       }
+
+       /*
+        * Each report package contains 26 bytes as below (guessed by 
inspection):
+        *
+        * Byte 0       ?VR? ?21T
+        * Byte 1       X coordinate (low byte)
+        * Byte 2       X coordinate (high byte)
+        * Byte 3       zero
+        * Byte 4       Y coordinate (low byte)
+        * Byte 5       Y coordinate (high byte) 
+        * Byte 6       zero
+        * Byte 7       Pressure (low byte)
+        * Byte 8       Pressure (high byte)
+        * Byte 9       zero
+        * Byte 10..14  zero
+        * Byte 15      quality?
+        * Byte 16..25  unknown
+        *
+        * V: 1=valid data, 0=don't use
+        * R: 1=in range, 0=cannot sense
+        * 1: barrel button 1, 1=pressed, 0=not pressed
+        * 2: barrel button 2, 1=pressed, 0=not pressed
+        * T: 1=touched, 0=not touched
+        * quality: 0 - 63, 0 = most reliable?
+        *
+        */
+
+       /* no valid data or not in range */
+       if ((p[0] & 0x40) == 0 || (p[0] & 0x20) == 0)
+               return;
+
+       if (sc->sc_wsmousedev != NULL) {
+               x = (p[2] << 8) | p[1];
+               y = (p[5] << 8) | p[4];
+               z = (p[8] << 8) | p[7];
+
+               btns = p[0] & 0x7;
+
+               tpcalib_trans(&sc->sc_tpcalib, x, y, &x, &y);
+
+               s = spltty();
+               wsmouse_input(sc->sc_wsmousedev, btns, x, y, z, 0,
+                       WSMOUSE_INPUT_ABSOLUTE_X |
+                       WSMOUSE_INPUT_ABSOLUTE_Y |
+                       WSMOUSE_INPUT_ABSOLUTE_Z);
+               splx(s);
+       }
+}

Index: sys/dev/usb/usbdevices.config
==================================================================
--- sys/dev/usb/usbdevices.config
+++ sys/dev/usb/usbdevices.config
@@ -34,10 +34,13 @@
 uhidev*        at uhub? port ? configuration ? interface ?
 
 # USB Mice
 ums*   at uhidev? reportid ?
 wsmouse* at ums? mux 0
+
+uintuos*       at uhidev? reportid ?   # Wacom Intuos PTS
+wsmouse* at uintuos? mux 0
 
 # USB Touchscreens
 uts*   at uhidev? reportid ?
 wsmouse* at uts? mux 0
 

Index: sys/dev/usb/usbdevs
==================================================================
--- sys/dev/usb/usbdevs
+++ sys/dev/usb/usbdevs
@@ -3490,11 +3490,13 @@
 product WACOM GRAPHIRE3_6X8    0x0014  Graphire3 6x8
 product WACOM GRAPHIRE4_4X5    0x0015  Graphire4 4x5
 product WACOM INTUOSA5         0x0021  Intuos A5
 product WACOM GD0912U          0x0022  Intuos 9x12 Graphics Tablet
 product WACOM XD0912U          0x0043  Intuos2 A4 i-920 XD-0912-U
+product WACOM CTH490K0         0x033c  Intuos Art CTH-490/K0
 product WACOM CTH690K0         0x033e  Intuos Art CTH-690/K0
+product WACOM CTL6100WL                0x0378  Intuos M
 
 /* Weltrend Semiconductor */
 product WELTREND HID           0x2201  HID Device
 
 /* West Mountain Radio products */

Reply via email to