Merge branch 'for-4.15/wacom' into for-linus
authorJiri Kosina <jkosina@suse.cz>
Wed, 15 Nov 2017 10:14:23 +0000 (11:14 +0100)
committerJiri Kosina <jkosina@suse.cz>
Wed, 15 Nov 2017 10:14:23 +0000 (11:14 +0100)
- High resolution mode for DEll canvas support, from Benjamin Tissoires
- A lot of improvements to pen handling in the Wacom driver, from Jason Gerecke

Signed-off-by: Jiri Kosina <jkosina@suse.cz>
drivers/hid/wacom_sys.c
drivers/hid/wacom_wac.c
drivers/hid/wacom_wac.h
include/uapi/linux/input-event-codes.h

index 906e654fb0ba42fe85b49e3813beebabe86d7b3e..ee71ad9b6cc1693e14a585848ca9ad3289f06454 100644 (file)
@@ -196,6 +196,13 @@ static void wacom_feature_mapping(struct hid_device *hdev,
                kfree(data);
                break;
        }
+
+       if (hdev->vendor == USB_VENDOR_ID_WACOM &&
+           hdev->product == 0x4200 /* Dell Canvas 27 */ &&
+           field->application == HID_UP_MSVENDOR) {
+               wacom->wacom_wac.mode_report = field->report->id;
+               wacom->wacom_wac.mode_value = 2;
+       }
 }
 
 /*
index aa692e28b2cd60e52bbae7dcb93454fa145ee69a..16af6886e82887982054cc8e75cc02de1a39ad08 100644 (file)
@@ -2140,6 +2140,12 @@ static void wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field
        case HID_DG_TIPSWITCH:
                wacom_wac->hid_data.tipswitch |= value;
                return;
+       case HID_DG_BARRELSWITCH:
+               wacom_wac->hid_data.barrelswitch = value;
+               return;
+       case HID_DG_BARRELSWITCH2:
+               wacom_wac->hid_data.barrelswitch2 = value;
+               return;
        case HID_DG_TOOLSERIALNUMBER:
                if (value) {
                        wacom_wac->serial[0] = (wacom_wac->serial[0] & ~0xFFFFFFFFULL);
@@ -2217,11 +2223,11 @@ static void wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field
        if (!usage->type || delay_pen_events(wacom_wac))
                return;
 
-       /* send pen events only when the pen is in/entering/leaving proximity */
-       if (!wacom_wac->hid_data.inrange_state && !wacom_wac->tool[0])
-               return;
-
-       input_event(input, usage->type, usage->code, value);
+       /* send pen events only when the pen is in range */
+       if (wacom_wac->hid_data.inrange_state)
+               input_event(input, usage->type, usage->code, value);
+       else if (wacom_wac->shared->stylus_in_proximity && !wacom_wac->hid_data.sense_state)
+               input_event(input, usage->type, usage->code, 0);
 }
 
 static void wacom_wac_pen_pre_report(struct hid_device *hdev,
@@ -2236,11 +2242,11 @@ static void wacom_wac_pen_report(struct hid_device *hdev,
        struct wacom *wacom = hid_get_drvdata(hdev);
        struct wacom_wac *wacom_wac = &wacom->wacom_wac;
        struct input_dev *input = wacom_wac->pen_input;
-       bool prox = wacom_wac->hid_data.inrange_state;
-       bool range = wacom_wac->hid_data.sense_state;
+       bool range = wacom_wac->hid_data.inrange_state;
+       bool sense = wacom_wac->hid_data.sense_state;
 
-       if (!wacom_wac->tool[0] && prox) { /* first in prox */
-               /* Going into proximity select tool */
+       if (!wacom_wac->tool[0] && range) { /* first in range */
+               /* Going into range select tool */
                if (wacom_wac->hid_data.invert_state)
                        wacom_wac->tool[0] = BTN_TOOL_RUBBER;
                else if (wacom_wac->id[0])
@@ -2250,10 +2256,16 @@ static void wacom_wac_pen_report(struct hid_device *hdev,
        }
 
        /* keep pen state for touch events */
-       wacom_wac->shared->stylus_in_proximity = range;
+       wacom_wac->shared->stylus_in_proximity = sense;
 
        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);
 
                /*
                 * Non-USI EMR tools should have their IDs mangled to
@@ -2269,10 +2281,10 @@ static void wacom_wac_pen_report(struct hid_device *hdev,
                 */
                input_report_key(input, BTN_TOUCH,
                                wacom_wac->hid_data.tipswitch);
-               input_report_key(input, wacom_wac->tool[0], prox);
+               input_report_key(input, wacom_wac->tool[0], sense);
                if (wacom_wac->serial[0]) {
                        input_event(input, EV_MSC, MSC_SERIAL, wacom_wac->serial[0]);
-                       input_report_abs(input, ABS_MISC, prox ? id : 0);
+                       input_report_abs(input, ABS_MISC, sense ? id : 0);
                }
 
                wacom_wac->hid_data.tipswitch = false;
@@ -2280,7 +2292,7 @@ static void wacom_wac_pen_report(struct hid_device *hdev,
                input_sync(input);
        }
 
-       if (!prox) {
+       if (!sense) {
                wacom_wac->tool[0] = 0;
                wacom_wac->id[0] = 0;
                wacom_wac->serial[0] = 0;
@@ -3300,9 +3312,11 @@ int wacom_setup_pen_input_capabilities(struct input_dev *input_dev,
        else
                __set_bit(INPUT_PROP_POINTER, input_dev->propbit);
 
-       if (features->type == HID_GENERIC)
-               /* setup has already been done */
+       if (features->type == HID_GENERIC) {
+               /* setup has already been done; apply otherwise-undetectible quirks */
+               input_set_capability(input_dev, EV_KEY, BTN_STYLUS3);
                return 0;
+       }
 
        __set_bit(BTN_TOUCH, input_dev->keybit);
        __set_bit(ABS_MISC, input_dev->absbit);
index feb62fd4dfc3ecff1ba43ee46fc7f70ec9b3c6d2..64d8f014602ea0dae29830bd4259e6a1dba42f7e 100644 (file)
@@ -292,6 +292,8 @@ struct hid_data {
        bool inrange_state;
        bool invert_state;
        bool tipswitch;
+       bool barrelswitch;
+       bool barrelswitch2;
        int x;
        int y;
        int pressure;
index 179891074b3c24780bb10e5a9a4f8d2183d2c684..9b3a522f50d15e1ed98ff33f9d74142b15f2de03 100644 (file)
 #define BTN_TOOL_MOUSE         0x146
 #define BTN_TOOL_LENS          0x147
 #define BTN_TOOL_QUINTTAP      0x148   /* Five fingers on trackpad */
+#define BTN_STYLUS3            0x149
 #define BTN_TOUCH              0x14a
 #define BTN_STYLUS             0x14b
 #define BTN_STYLUS2            0x14c