HID: wacom: bluetooth: send exit report for recent Bluetooth devices
authorAaron Armstrong Skomra <skomra@gmail.com>
Wed, 4 Apr 2018 21:24:11 +0000 (14:24 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 24 Apr 2018 07:36:37 +0000 (09:36 +0200)
commit 619d3a2922ce623ca2eca443cc936810d328317c upstream.

The code path for recent Bluetooth devices omits an exit report which
resets all the values of the device.

Fixes: 4922cd26f0 ("HID: wacom: Support 2nd-gen Intuos Pro's Bluetooth classic interface")
Cc: <stable@vger.kernel.org> # 4.11
Signed-off-by: Aaron Armstrong Skomra <aaron.skomra@wacom.com>
Reviewed-by: Ping Cheng <ping.cheng@wacom.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/hid/wacom_wac.c

index 70cbe1e5a3d2064690ba8a87674f6c909508f049..c401b5b63f4c59c696acfcd21c6943b00b75ae54 100644 (file)
@@ -689,6 +689,45 @@ static int wacom_intuos_get_tool_type(int tool_id)
        return tool_type;
 }
 
+static void wacom_exit_report(struct wacom_wac *wacom)
+{
+       struct input_dev *input = wacom->pen_input;
+       struct wacom_features *features = &wacom->features;
+       unsigned char *data = wacom->data;
+       int idx = (features->type == INTUOS) ? (data[1] & 0x01) : 0;
+
+       /*
+        * Reset all states otherwise we lose the initial states
+        * when in-prox next time
+        */
+       input_report_abs(input, ABS_X, 0);
+       input_report_abs(input, ABS_Y, 0);
+       input_report_abs(input, ABS_DISTANCE, 0);
+       input_report_abs(input, ABS_TILT_X, 0);
+       input_report_abs(input, ABS_TILT_Y, 0);
+       if (wacom->tool[idx] >= BTN_TOOL_MOUSE) {
+               input_report_key(input, BTN_LEFT, 0);
+               input_report_key(input, BTN_MIDDLE, 0);
+               input_report_key(input, BTN_RIGHT, 0);
+               input_report_key(input, BTN_SIDE, 0);
+               input_report_key(input, BTN_EXTRA, 0);
+               input_report_abs(input, ABS_THROTTLE, 0);
+               input_report_abs(input, ABS_RZ, 0);
+       } else {
+               input_report_abs(input, ABS_PRESSURE, 0);
+               input_report_key(input, BTN_STYLUS, 0);
+               input_report_key(input, BTN_STYLUS2, 0);
+               input_report_key(input, BTN_TOUCH, 0);
+               input_report_abs(input, ABS_WHEEL, 0);
+               if (features->type >= INTUOS3S)
+                       input_report_abs(input, ABS_Z, 0);
+       }
+       input_report_key(input, wacom->tool[idx], 0);
+       input_report_abs(input, ABS_MISC, 0); /* reset tool id */
+       input_event(input, EV_MSC, MSC_SERIAL, wacom->serial[idx]);
+       wacom->id[idx] = 0;
+}
+
 static int wacom_intuos_inout(struct wacom_wac *wacom)
 {
        struct wacom_features *features = &wacom->features;
@@ -741,36 +780,7 @@ static int wacom_intuos_inout(struct wacom_wac *wacom)
                if (!wacom->id[idx])
                        return 1;
 
-               /*
-                * Reset all states otherwise we lose the initial states
-                * when in-prox next time
-                */
-               input_report_abs(input, ABS_X, 0);
-               input_report_abs(input, ABS_Y, 0);
-               input_report_abs(input, ABS_DISTANCE, 0);
-               input_report_abs(input, ABS_TILT_X, 0);
-               input_report_abs(input, ABS_TILT_Y, 0);
-               if (wacom->tool[idx] >= BTN_TOOL_MOUSE) {
-                       input_report_key(input, BTN_LEFT, 0);
-                       input_report_key(input, BTN_MIDDLE, 0);
-                       input_report_key(input, BTN_RIGHT, 0);
-                       input_report_key(input, BTN_SIDE, 0);
-                       input_report_key(input, BTN_EXTRA, 0);
-                       input_report_abs(input, ABS_THROTTLE, 0);
-                       input_report_abs(input, ABS_RZ, 0);
-               } else {
-                       input_report_abs(input, ABS_PRESSURE, 0);
-                       input_report_key(input, BTN_STYLUS, 0);
-                       input_report_key(input, BTN_STYLUS2, 0);
-                       input_report_key(input, BTN_TOUCH, 0);
-                       input_report_abs(input, ABS_WHEEL, 0);
-                       if (features->type >= INTUOS3S)
-                               input_report_abs(input, ABS_Z, 0);
-               }
-               input_report_key(input, wacom->tool[idx], 0);
-               input_report_abs(input, ABS_MISC, 0); /* reset tool id */
-               input_event(input, EV_MSC, MSC_SERIAL, wacom->serial[idx]);
-               wacom->id[idx] = 0;
+               wacom_exit_report(wacom);
                return 2;
        }
 
@@ -1226,6 +1236,12 @@ static void wacom_intuos_pro2_bt_pen(struct wacom_wac *wacom)
                if (!valid)
                        continue;
 
+               if (!prox) {
+                       wacom->shared->stylus_in_proximity = false;
+                       wacom_exit_report(wacom);
+                       input_sync(pen_input);
+                       return;
+               }
                if (range) {
                        /* Fix rotation alignment: userspace expects zero at left */
                        int16_t rotation = (int16_t)get_unaligned_le16(&frame[9]);