OSDN Git Service

HID: wacom: Adding Support for new usages
authorJoshua-Dickens <Joshua@Joshua-Dickens.com>
Tue, 22 Mar 2022 21:33:16 +0000 (14:33 -0700)
committerJiri Kosina <jkosina@suse.cz>
Thu, 21 Apr 2022 07:42:32 +0000 (09:42 +0200)
Added supprt for the following usages:
* HID_DG_SCANTIME to report the timestamp for pen and touch events.
* WACOM_HID_WD_BARRELSWITCH3 to support pens with 3 buttons.
* WACOM_HID_WD_SEQUENCENUMBER to detect and report dropped packets.

Signed-off-by: Joshua Dickens <joshua.dickens@wacom.com>
Reviewed-by: Jason Gerecke <jason.gerecke@wacom.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
drivers/hid/wacom_wac.c
drivers/hid/wacom_wac.h

index a7176fc..64fe573 100644 (file)
@@ -1811,7 +1811,9 @@ int wacom_equivalent_usage(int usage)
                    usage == WACOM_HID_WD_TOUCHSTRIP2 ||
                    usage == WACOM_HID_WD_TOUCHRING ||
                    usage == WACOM_HID_WD_TOUCHRINGSTATUS ||
-                   usage == WACOM_HID_WD_REPORT_VALID) {
+                   usage == WACOM_HID_WD_REPORT_VALID ||
+                   usage == WACOM_HID_WD_BARRELSWITCH3 ||
+                   usage == WACOM_HID_WD_SEQUENCENUMBER) {
                        return usage;
                }
 
@@ -2196,8 +2198,11 @@ static void wacom_set_barrel_switch3_usage(struct wacom_wac *wacom_wac)
        if (!(features->quirks & WACOM_QUIRK_AESPEN) &&
            wacom_wac->hid_data.barrelswitch &&
            wacom_wac->hid_data.barrelswitch2 &&
-           wacom_wac->hid_data.serialhi)
+           wacom_wac->hid_data.serialhi &&
+           !wacom_wac->hid_data.barrelswitch3) {
                input_set_capability(input, EV_KEY, BTN_STYLUS3);
+               features->quirks |= WACOM_QUIRK_PEN_BUTTON3;
+       }
 }
 
 static void wacom_wac_pen_usage_mapping(struct hid_device *hdev,
@@ -2261,6 +2266,9 @@ static void wacom_wac_pen_usage_mapping(struct hid_device *hdev,
                features->quirks |= WACOM_QUIRK_TOOLSERIAL;
                wacom_map_usage(input, usage, field, EV_MSC, MSC_SERIAL, 0);
                break;
+       case HID_DG_SCANTIME:
+               wacom_map_usage(input, usage, field, EV_MSC, MSC_TIMESTAMP, 0);
+               break;
        case WACOM_HID_WD_SENSE:
                features->quirks |= WACOM_QUIRK_SENSE;
                wacom_map_usage(input, usage, field, EV_KEY, BTN_TOOL_PEN, 0);
@@ -2274,6 +2282,11 @@ static void wacom_wac_pen_usage_mapping(struct hid_device *hdev,
                input_set_capability(input, EV_KEY, BTN_TOOL_AIRBRUSH);
                wacom_map_usage(input, usage, field, EV_ABS, ABS_WHEEL, 0);
                break;
+       case WACOM_HID_WD_BARRELSWITCH3:
+               wacom_wac->hid_data.barrelswitch3 = true;
+               wacom_map_usage(input, usage, field, EV_KEY, BTN_STYLUS3, 0);
+               features->quirks &= ~WACOM_QUIRK_PEN_BUTTON3;
+               break;
        }
 }
 
@@ -2390,6 +2403,14 @@ static void wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field
        case WACOM_HID_WD_REPORT_VALID:
                wacom_wac->is_invalid_bt_frame = !value;
                return;
+       case WACOM_HID_WD_BARRELSWITCH3:
+               wacom_wac->hid_data.barrelswitch3 = value;
+               return;
+       case WACOM_HID_WD_SEQUENCENUMBER:
+               if (wacom_wac->hid_data.sequence_number != value)
+                       hid_warn(hdev, "Dropped %hu packets", value - wacom_wac->hid_data.sequence_number);
+               wacom_wac->hid_data.sequence_number = value + 1;
+               return;
        }
 
        /* send pen events only when touch is up or forced out
@@ -2442,12 +2463,15 @@ static void wacom_wac_pen_report(struct hid_device *hdev,
 
        if (!delay_pen_events(wacom_wac) && wacom_wac->tool[0]) {
                int id = wacom_wac->id[0];
-               int sw_state = wacom_wac->hid_data.barrelswitch |
-                              (wacom_wac->hid_data.barrelswitch2 << 1);
-
-               input_report_key(input, BTN_STYLUS, sw_state == 1);
-               input_report_key(input, BTN_STYLUS2, sw_state == 2);
-               input_report_key(input, BTN_STYLUS3, sw_state == 3);
+               if (wacom_wac->features.quirks & WACOM_QUIRK_PEN_BUTTON3 &&
+                   wacom_wac->hid_data.barrelswitch & wacom_wac->hid_data.barrelswitch2) {
+                       wacom_wac->hid_data.barrelswitch = 0;
+                       wacom_wac->hid_data.barrelswitch2 = 0;
+                       wacom_wac->hid_data.barrelswitch3 = 1;
+               }
+               input_report_key(input, BTN_STYLUS, wacom_wac->hid_data.barrelswitch);
+               input_report_key(input, BTN_STYLUS2, wacom_wac->hid_data.barrelswitch2);
+               input_report_key(input, BTN_STYLUS3, wacom_wac->hid_data.barrelswitch3);
 
                /*
                 * Non-USI EMR tools should have their IDs mangled to
@@ -2529,6 +2553,9 @@ static void wacom_wac_finger_usage_mapping(struct hid_device *hdev,
                        field->logical_maximum = 255;
                }
                break;
+       case HID_DG_SCANTIME:
+               wacom_map_usage(input, usage, field, EV_MSC, MSC_TIMESTAMP, 0);
+               break;
        }
 }
 
index 466b62c..fef1538 100644 (file)
@@ -86,6 +86,7 @@
 #define WACOM_QUIRK_AESPEN             0x0004
 #define WACOM_QUIRK_BATTERY            0x0008
 #define WACOM_QUIRK_TOOLSERIAL         0x0010
+#define WACOM_QUIRK_PEN_BUTTON3        0x0020
 
 /* device types */
 #define WACOM_DEVICETYPE_NONE           0x0000
 #define WACOM_HID_WD_DIGITIZERFNKEYS    (WACOM_HID_UP_WACOMDIGITIZER | 0x39)
 #define WACOM_HID_WD_SERIALNUMBER       (WACOM_HID_UP_WACOMDIGITIZER | 0x5b)
 #define WACOM_HID_WD_SERIALHI           (WACOM_HID_UP_WACOMDIGITIZER | 0x5c)
+#define WACOM_HID_WD_BARRELSWITCH3      (WACOM_HID_UP_WACOMDIGITIZER | 0x5d)
 #define WACOM_HID_WD_TOOLTYPE           (WACOM_HID_UP_WACOMDIGITIZER | 0x77)
 #define WACOM_HID_WD_DISTANCE           (WACOM_HID_UP_WACOMDIGITIZER | 0x0132)
 #define WACOM_HID_WD_TOUCHSTRIP         (WACOM_HID_UP_WACOMDIGITIZER | 0x0136)
 #define WACOM_HID_WD_TOUCHRING          (WACOM_HID_UP_WACOMDIGITIZER | 0x0138)
 #define WACOM_HID_WD_TOUCHRINGSTATUS    (WACOM_HID_UP_WACOMDIGITIZER | 0x0139)
 #define WACOM_HID_WD_REPORT_VALID       (WACOM_HID_UP_WACOMDIGITIZER | 0x01d0)
+#define WACOM_HID_WD_SEQUENCENUMBER     (WACOM_HID_UP_WACOMDIGITIZER | 0x0220)
 #define WACOM_HID_WD_ACCELEROMETER_X    (WACOM_HID_UP_WACOMDIGITIZER | 0x0401)
 #define WACOM_HID_WD_ACCELEROMETER_Y    (WACOM_HID_UP_WACOMDIGITIZER | 0x0402)
 #define WACOM_HID_WD_ACCELEROMETER_Z    (WACOM_HID_UP_WACOMDIGITIZER | 0x0403)
@@ -300,6 +303,7 @@ struct hid_data {
        bool tipswitch;
        bool barrelswitch;
        bool barrelswitch2;
+       bool barrelswitch3;
        bool serialhi;
        bool confidence;
        int x;
@@ -320,6 +324,7 @@ struct hid_data {
        int bat_connected;
        int ps_connected;
        bool pad_input_event_flag;
+       unsigned short sequence_number;
 };
 
 struct wacom_remote_data {