]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - drivers/hid/wacom_wac.c
Merge tag 'amlogic-fixes' of https://git.kernel.org/pub/scm/linux/kernel/git/khilman...
[linux.git] / drivers / hid / wacom_wac.c
index 1f1ed276e388262e3d1a5e4367c4abab610f0cdc..43f6da35716599be1b823fcdd1670f755433f331 100644 (file)
@@ -1232,13 +1232,13 @@ static void wacom_intuos_pro2_bt_pen(struct wacom_wac *wacom)
                /* Add back in missing bits of ID for non-USI pens */
                wacom->id[0] |= (wacom->serial[0] >> 32) & 0xFFFFF;
        }
-       wacom->tool[0]   = wacom_intuos_get_tool_type(wacom_intuos_id_mangle(wacom->id[0]));
 
        for (i = 0; i < pen_frames; i++) {
                unsigned char *frame = &data[i*pen_frame_len + 1];
                bool valid = frame[0] & 0x80;
                bool prox = frame[0] & 0x40;
                bool range = frame[0] & 0x20;
+               bool invert = frame[0] & 0x10;
 
                if (!valid)
                        continue;
@@ -1247,9 +1247,24 @@ static void wacom_intuos_pro2_bt_pen(struct wacom_wac *wacom)
                        wacom->shared->stylus_in_proximity = false;
                        wacom_exit_report(wacom);
                        input_sync(pen_input);
+
+                       wacom->tool[0] = 0;
+                       wacom->id[0] = 0;
+                       wacom->serial[0] = 0;
                        return;
                }
+
                if (range) {
+                       if (!wacom->tool[0]) { /* first in range */
+                               /* Going into range select tool */
+                               if (invert)
+                                       wacom->tool[0] = BTN_TOOL_RUBBER;
+                               else if (wacom->id[0])
+                                       wacom->tool[0] = wacom_intuos_get_tool_type(wacom->id[0]);
+                               else
+                                       wacom->tool[0] = BTN_TOOL_PEN;
+                       }
+
                        input_report_abs(pen_input, ABS_X, get_unaligned_le16(&frame[1]));
                        input_report_abs(pen_input, ABS_Y, get_unaligned_le16(&frame[3]));
 
@@ -1271,23 +1286,26 @@ static void wacom_intuos_pro2_bt_pen(struct wacom_wac *wacom)
                                                 get_unaligned_le16(&frame[11]));
                        }
                }
-               input_report_abs(pen_input, ABS_PRESSURE, get_unaligned_le16(&frame[5]));
-               if (wacom->features.type == INTUOSP2_BT) {
-                       input_report_abs(pen_input, ABS_DISTANCE,
-                                        range ? frame[13] : wacom->features.distance_max);
-               } else {
-                       input_report_abs(pen_input, ABS_DISTANCE,
-                                        range ? frame[7] : wacom->features.distance_max);
-               }
 
-               input_report_key(pen_input, BTN_TOUCH, frame[0] & 0x01);
-               input_report_key(pen_input, BTN_STYLUS, frame[0] & 0x02);
-               input_report_key(pen_input, BTN_STYLUS2, frame[0] & 0x04);
+               if (wacom->tool[0]) {
+                       input_report_abs(pen_input, ABS_PRESSURE, get_unaligned_le16(&frame[5]));
+                       if (wacom->features.type == INTUOSP2_BT) {
+                               input_report_abs(pen_input, ABS_DISTANCE,
+                                                range ? frame[13] : wacom->features.distance_max);
+                       } else {
+                               input_report_abs(pen_input, ABS_DISTANCE,
+                                                range ? frame[7] : wacom->features.distance_max);
+                       }
 
-               input_report_key(pen_input, wacom->tool[0], prox);
-               input_event(pen_input, EV_MSC, MSC_SERIAL, wacom->serial[0]);
-               input_report_abs(pen_input, ABS_MISC,
-                                wacom_intuos_id_mangle(wacom->id[0])); /* report tool id */
+                       input_report_key(pen_input, BTN_TOUCH, frame[0] & 0x09);
+                       input_report_key(pen_input, BTN_STYLUS, frame[0] & 0x02);
+                       input_report_key(pen_input, BTN_STYLUS2, frame[0] & 0x04);
+
+                       input_report_key(pen_input, wacom->tool[0], prox);
+                       input_event(pen_input, EV_MSC, MSC_SERIAL, wacom->serial[0]);
+                       input_report_abs(pen_input, ABS_MISC,
+                                        wacom_intuos_id_mangle(wacom->id[0])); /* report tool id */
+               }
 
                wacom->shared->stylus_in_proximity = prox;
 
@@ -1349,11 +1367,17 @@ static void wacom_intuos_pro2_bt_touch(struct wacom_wac *wacom)
                if (wacom->num_contacts_left <= 0) {
                        wacom->num_contacts_left = 0;
                        wacom->shared->touch_down = wacom_wac_finger_count_touches(wacom);
+                       input_sync(touch_input);
                }
        }
 
-       input_report_switch(touch_input, SW_MUTE_DEVICE, !(data[281] >> 7));
-       input_sync(touch_input);
+       if (wacom->num_contacts_left == 0) {
+               // Be careful that we don't accidentally call input_sync with
+               // only a partial set of fingers of processed
+               input_report_switch(touch_input, SW_MUTE_DEVICE, !(data[281] >> 7));
+               input_sync(touch_input);
+       }
+
 }
 
 static void wacom_intuos_pro2_bt_pad(struct wacom_wac *wacom)
@@ -1361,7 +1385,7 @@ static void wacom_intuos_pro2_bt_pad(struct wacom_wac *wacom)
        struct input_dev *pad_input = wacom->pad_input;
        unsigned char *data = wacom->data;
 
-       int buttons = (data[282] << 1) | ((data[281] >> 6) & 0x01);
+       int buttons = data[282] | ((data[281] & 0x40) << 2);
        int ring = data[285] & 0x7F;
        bool ringstatus = data[285] & 0x80;
        bool prox = buttons || ringstatus;
@@ -3810,7 +3834,7 @@ static void wacom_24hd_update_leds(struct wacom *wacom, int mask, int group)
 static bool wacom_is_led_toggled(struct wacom *wacom, int button_count,
                                 int mask, int group)
 {
-       int button_per_group;
+       int group_button;
 
        /*
         * 21UX2 has LED group 1 to the left and LED group 0
@@ -3820,9 +3844,12 @@ static bool wacom_is_led_toggled(struct wacom *wacom, int button_count,
        if (wacom->wacom_wac.features.type == WACOM_21UX2)
                group = 1 - group;
 
-       button_per_group = button_count/wacom->led.count;
+       group_button = group * (button_count/wacom->led.count);
+
+       if (wacom->wacom_wac.features.type == INTUOSP2_BT)
+               group_button = 8;
 
-       return mask & (1 << (group * button_per_group));
+       return mask & (1 << group_button);
 }
 
 static void wacom_update_led(struct wacom *wacom, int button_count, int mask,