Support for Wacom One S (CTL-472) [OpenBSD/uwacom]

Even though more product ids are maintained in usbdevs.h, OpenBSD
currently only supports the Wacom Intuos Draw (CTL-490) tablet.

I extended the support to another tablet, which identifies itself
as CTL-472 and is a more recent (and still available) model.

Index: sys/dev/usb/usbdevs.h
===================================================================
RCS file: /cvs/src/sys/dev/usb/usbdevs.h,v
retrieving revision 1.752
diff -u -p -u -p -r1.752 usbdevs.h
--- sys/dev/usb/usbdevs.h	18 May 2021 14:23:53 -0000	1.752
+++ sys/dev/usb/usbdevs.h	6 Jun 2021 17:27:24 -0000
@@ -4582,6 +4582,7 @@
 #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) */
+#define	USB_PRODUCT_WACOM_ONE_S		0x037a		/* One (CTL-472) */
 #define	USB_PRODUCT_WACOM_INTUOS_PRO_S	0x0392		/* Intuos Pro S */
 
 /* WAGO Kontakttechnik products */
Index: sys/dev/usb/uwacom.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/uwacom.c,v
retrieving revision 1.2
diff -u -p -u -p -r1.2 uwacom.c
--- sys/dev/usb/uwacom.c	23 Aug 2020 11:08:02 -0000	1.2
+++ sys/dev/usb/uwacom.c	6 Jun 2021 17:27:24 -0000
@@ -39,6 +39,8 @@ struct uwacom_softc {
 	struct uhidev		sc_hdev;
 	struct hidms		sc_ms;
 	struct hid_location	sc_loc_tip_press;
+	int			sc_big_endian;
+	int			sc_use_pressure;
 };
 
 struct cfdriver uwacom_cd = {
@@ -47,7 +49,8 @@ struct cfdriver uwacom_cd = {
 
 
 const struct usb_devno uwacom_devs[] = {
-	{ USB_VENDOR_WACOM, USB_PRODUCT_WACOM_INTUOS_DRAW }
+	{ USB_VENDOR_WACOM, USB_PRODUCT_WACOM_INTUOS_DRAW },
+	{ USB_VENDOR_WACOM, USB_PRODUCT_WACOM_ONE_S }
 };
 
 int	uwacom_match(struct device *, void *, void *);
@@ -102,6 +105,8 @@ uwacom_attach(struct device *parent, str
 	sc->sc_hdev.sc_parent = uha->parent;
 	sc->sc_hdev.sc_udev = uaa->device;
 	sc->sc_hdev.sc_report_id = uha->reportid;
+	sc->sc_big_endian = 0;
+	sc->sc_use_pressure = 0;
 
 	usbd_set_idle(uha->parent->sc_udev, uha->parent->sc_ifaceno, 0, 0);
 
@@ -121,9 +126,25 @@ uwacom_attach(struct device *parent, str
 	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;
+	if (uha->uaa->product == USB_PRODUCT_WACOM_ONE_S) {
+		static uByte reportbuf[2];
+		reportbuf[0] = 0x02;
+		reportbuf[1] = 0x02;
+		uhidev_set_report(uha->parent, UHID_FEATURE_REPORT, 2,
+				&reportbuf, 2);
+		ms->sc_tsscale.maxx = 15200;
+		ms->sc_tsscale.maxy = 9500;
+	}
+
+	if (uha->uaa->product == USB_PRODUCT_WACOM_INTUOS_DRAW) {
+		sc->sc_big_endian = 1;
+		sc->sc_use_pressure = 1;
+		sc->sc_loc_tip_press.pos = 43;
+		sc->sc_loc_tip_press.size = 8;
+		ms->sc_tsscale.maxx = 7600;
+		ms->sc_tsscale.maxy = 4750;
+	}
 
 	ms->sc_loc_btn[0].pos = 0;
 	ms->sc_loc_btn[0].size = 1;
@@ -132,9 +153,6 @@ uwacom_attach(struct device *parent, str
 	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);
 }
 
@@ -163,19 +181,26 @@ uwacom_intr(struct uhidev *addr, void *b
 	if ((data[0] & 0xf0) == 0xc0)
 		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);
+	if (sc->sc_big_endian == 1) {
+		x = be16toh(hid_get_data(data, len, &ms->sc_loc_x));
+		y = be16toh(hid_get_data(data, len, &ms->sc_loc_y));
+	} else {
+		x = le16toh(hid_get_data(data, len, &ms->sc_loc_x));
+		y = le16toh(hid_get_data(data, len, &ms->sc_loc_y));
+	}
 
 	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 (sc->sc_use_pressure == 1) {
+		pressure = hid_get_data(data, len, &sc->sc_loc_tip_press);
+		if (pressure > 10)
+			buttons |= 1;
+		else
+			buttons &= ~1;
+	}
 
 	if (x != 0 || y != 0 || buttons != ms->sc_buttons) {
 		wsmouse_position(ms->sc_wsmousedev, x, y);
Index: share/man/man4/uwacom.4
===================================================================
RCS file: /cvs/src/share/man/man4/uwacom.4,v
retrieving revision 1.2
diff -u -p -u -p -r1.2 uwacom.4
--- share/man/man4/uwacom.4	12 Sep 2016 10:39:06 -0000	1.2
+++ share/man/man4/uwacom.4	6 Jun 2021 17:27:24 -0000
@@ -42,6 +42,7 @@ driver supports the following Wacom tabl
 .Bl -column "Intuos Draw" "Model Number" -offset 6n
 .It Em Name Ta Em Model Number
 .It Li Intuos Draw Ta CTL-490
+.It Li One Ta CTL-472
 .El
 .Sh SEE ALSO
 .Xr uhidev 4 ,