git: d4a977ce186c - stable/13 - hpen(4): Add support for legacy MS-compatible single touch protocol

Vladimir Kondratyev wulf at FreeBSD.org
Tue Sep 21 23:43:48 UTC 2021


The branch stable/13 has been updated by wulf:

URL: https://cgit.FreeBSD.org/src/commit/?id=d4a977ce186c7cc22b5317bbeb7ee87608fbc920

commit d4a977ce186c7cc22b5317bbeb7ee87608fbc920
Author:     Vladimir Kondratyev <wulf at FreeBSD.org>
AuthorDate: 2021-09-02 19:33:24 +0000
Commit:     Vladimir Kondratyev <wulf at FreeBSD.org>
CommitDate: 2021-09-21 23:41:16 +0000

    hpen(4): Add support for legacy MS-compatible single touch protocol
    
    It is used by many pre- and post- 2014 eGalax touchscreens.
    
    Tested by:      Mark Kane <mark_AT_kane_DOT_mn>
    
    (cherry picked from commit a36bdfc2b6525e814388f38c6862cf4b24dc6bee)
---
 sys/dev/hid/hidmap.h |  2 ++
 sys/dev/hid/hpen.c   | 89 ++++++++++++++++++++++++++++------------------------
 2 files changed, 50 insertions(+), 41 deletions(-)

diff --git a/sys/dev/hid/hidmap.h b/sys/dev/hid/hidmap.h
index f5ce10069e1a..628881092639 100644
--- a/sys/dev/hid/hidmap.h
+++ b/sys/dev/hid/hidmap.h
@@ -62,6 +62,8 @@ typedef int hidmap_cb_t(HIDMAP_CB_ARGS);
 /* These helpers can be used at any stage of any callbacks */
 #define	HIDMAP_CB_GET_STATE(...)					\
 	((hm == NULL) ? HIDMAP_CB_IS_PROBING : hm->cb_state)
+#define	HIDMAP_CB_GET_DEV(...)						\
+	(hm == NULL ? NULL : hm->dev)
 #define	HIDMAP_CB_GET_SOFTC(...)					\
 	(hm == NULL ? NULL : device_get_softc(hm->dev))
 #define	HIDMAP_CB_GET_EVDEV(...)					\
diff --git a/sys/dev/hid/hpen.c b/sys/dev/hid/hpen.c
index 1d505e14089f..8a86b95b1020 100644
--- a/sys/dev/hid/hpen.c
+++ b/sys/dev/hid/hpen.c
@@ -72,44 +72,43 @@ static hidmap_cb_t	hpen_final_pen_cb;
 	HIDMAP_ABS_CB(HUP_DIGITIZERS, HUD_##usage, &cb)
 
 /* Generic map digitizer page map according to hut1_12v2.pdf */
-static const struct hidmap_item hpen_map_digi[] = {
+static const struct hidmap_item hpen_map_pen[] = {
     { HPEN_MAP_ABS_GD(X,		ABS_X),		  .required = true },
     { HPEN_MAP_ABS_GD(Y,		ABS_Y),		  .required = true },
     { HPEN_MAP_ABS(   TIP_PRESSURE,	ABS_PRESSURE) },
     { HPEN_MAP_ABS(   X_TILT,		ABS_TILT_X) },
     { HPEN_MAP_ABS(   Y_TILT,		ABS_TILT_Y) },
+    { HPEN_MAP_ABS(   CONTACTID,	0), 		  .forbidden = true },
+    { HPEN_MAP_ABS(   CONTACTCOUNT,	0), 		  .forbidden = true },
     { HPEN_MAP_ABS_CB(BATTERY_STRENGTH,	hpen_battery_strenght_cb) },
     { HPEN_MAP_BUT(   TOUCH,		BTN_TOUCH) },
     { HPEN_MAP_BUT(   TIP_SWITCH,	BTN_TOUCH) },
     { HPEN_MAP_BUT(   SEC_TIP_SWITCH,	BTN_TOUCH) },
-    { HPEN_MAP_BUT(   IN_RANGE,		BTN_TOOL_PEN) },
     { HPEN_MAP_BUT(   BARREL_SWITCH,	BTN_STYLUS) },
     { HPEN_MAP_BUT(   INVERT,		BTN_TOOL_RUBBER) },
     { HPEN_MAP_BUT(   ERASER,		BTN_TOUCH) },
     { HPEN_MAP_BUT(   TABLET_PICK,	BTN_STYLUS2) },
     { HPEN_MAP_BUT(   SEC_BARREL_SWITCH,BTN_STYLUS2) },
-    { HIDMAP_FINAL_CB(			&hpen_final_digi_cb) },
+    { HIDMAP_FINAL_CB(			&hpen_final_pen_cb) },
 };
 
-/* Microsoft-standardized pen support */
-static const struct hidmap_item hpen_map_pen[] = {
-    { HPEN_MAP_ABS_GD(X,		ABS_X),		  .required = true },
-    { HPEN_MAP_ABS_GD(Y,		ABS_Y),		  .required = true },
-    { HPEN_MAP_ABS(   TIP_PRESSURE,	ABS_PRESSURE),	  .required = true },
-    { HPEN_MAP_ABS(   X_TILT,		ABS_TILT_X) },
-    { HPEN_MAP_ABS(   Y_TILT,		ABS_TILT_Y) },
-    { HPEN_MAP_ABS_CB(BATTERY_STRENGTH,	hpen_battery_strenght_cb) },
-    { HPEN_MAP_BUT(   TIP_SWITCH,	BTN_TOUCH),	  .required = true },
-    { HPEN_MAP_BUT(   IN_RANGE,		BTN_TOOL_PEN),	  .required = true },
-    { HPEN_MAP_BUT(   BARREL_SWITCH,	BTN_STYLUS) },
-    { HPEN_MAP_BUT(   INVERT,		BTN_TOOL_RUBBER), .required = true },
-    { HPEN_MAP_BUT(   ERASER,		BTN_TOUCH),	  .required = true },
-    { HIDMAP_FINAL_CB(			&hpen_final_pen_cb) },
+static const struct hidmap_item hpen_map_stylus[] = {
+    { HPEN_MAP_BUT(   IN_RANGE,		BTN_TOOL_PEN) },
+};
+static const struct hidmap_item hpen_map_finger[] = {
+    { HPEN_MAP_BUT(   IN_RANGE,		BTN_TOOL_FINGER) },
 };
 
 static const struct hid_device_id hpen_devs[] = {
 	{ HID_TLC(HUP_DIGITIZERS, HUD_DIGITIZER) },
 	{ HID_TLC(HUP_DIGITIZERS, HUD_PEN) },
+	{ HID_TLC(HUP_DIGITIZERS, HUD_TOUCHSCREEN),
+	  HID_BVP(BUS_USB, USB_VENDOR_EGALAX, USB_PRODUCT_EGALAX_TPANEL) },
+};
+
+/* Do not autoload legacy pen driver for all touchscreen */
+static const struct hid_device_id hpen_devs_no_load[] = {
+	{ HID_TLC(HUP_DIGITIZERS, HUD_TOUCHSCREEN) },
 };
 
 static int
@@ -134,25 +133,18 @@ hpen_battery_strenght_cb(HIDMAP_CB_ARGS)
 	return (0);
 }
 
-static int
-hpen_final_digi_cb(HIDMAP_CB_ARGS)
-{
-	struct evdev_dev *evdev = HIDMAP_CB_GET_EVDEV();
-
-	if (HIDMAP_CB_GET_STATE() == HIDMAP_CB_IS_ATTACHING)
-		evdev_support_prop(evdev, INPUT_PROP_POINTER);
-
-	/* Do not execute callback at interrupt handler and detach */
-	return (ENOSYS);
-}
-
 static int
 hpen_final_pen_cb(HIDMAP_CB_ARGS)
 {
 	struct evdev_dev *evdev = HIDMAP_CB_GET_EVDEV();
 
-	if (HIDMAP_CB_GET_STATE() == HIDMAP_CB_IS_ATTACHING)
-		evdev_support_prop(evdev, INPUT_PROP_DIRECT);
+	if (HIDMAP_CB_GET_STATE() == HIDMAP_CB_IS_ATTACHING) {
+		if (hidbus_get_usage(HIDMAP_CB_GET_DEV()) ==
+		    HID_USAGE2(HUP_DIGITIZERS, HUD_DIGITIZER))
+			evdev_support_prop(evdev, INPUT_PROP_POINTER);
+		else
+			evdev_support_prop(evdev, INPUT_PROP_DIRECT);
+	}
 
 	/* Do not execute callback at interrupt handler and detach */
 	return (ENOSYS);
@@ -185,24 +177,39 @@ static int
 hpen_probe(device_t dev)
 {
 	struct hidmap *hm = device_get_softc(dev);
+	const char *desc;
+	void *d_ptr;
+	hid_size_t d_len;
 	int error;
-	bool is_pen;
 
-	error = HIDBUS_LOOKUP_DRIVER_INFO(dev, hpen_devs);
-	if (error != 0)
-		return (error);
+	if (HIDBUS_LOOKUP_DRIVER_INFO(dev, hpen_devs_no_load) != 0) {
+		error = HIDBUS_LOOKUP_DRIVER_INFO(dev, hpen_devs);
+		if (error != 0)
+			return (error);
+	}
 
 	hidmap_set_dev(hm, dev);
 
-	/* Check if report descriptor belongs to a HID tablet device */
-	is_pen = hidbus_get_usage(dev) == HID_USAGE2(HUP_DIGITIZERS, HUD_PEN);
-	error = is_pen
-	    ? HIDMAP_ADD_MAP(hm, hpen_map_pen, NULL)
-	    : HIDMAP_ADD_MAP(hm, hpen_map_digi, NULL);
+	/* Check if report descriptor belongs to a HID pen device */
+	error = HIDMAP_ADD_MAP(hm, hpen_map_pen, NULL);
 	if (error != 0)
 		return (error);
 
-	hidbus_set_desc(dev, is_pen ? "Pen" : "Digitizer");
+	if (hid_get_report_descr(dev, &d_ptr, &d_len) != 0)
+		return (ENXIO);
+
+	if (hidbus_is_collection(d_ptr, d_len,
+	    HID_USAGE2(HUP_DIGITIZERS, HUD_FINGER), hidbus_get_index(dev))) {
+		HIDMAP_ADD_MAP(hm, hpen_map_finger, NULL);
+		desc = "TouchScreen";
+	} else {
+		HIDMAP_ADD_MAP(hm, hpen_map_stylus, NULL);
+		desc = "Pen";
+	}
+	if (hidbus_get_usage(dev) == HID_USAGE2(HUP_DIGITIZERS, HUD_DIGITIZER))
+		desc = "Digitizer";
+
+	hidbus_set_desc(dev, desc);
 
 	return (BUS_PROBE_DEFAULT);
 }


More information about the dev-commits-src-branches mailing list