Merge tag 'powerpc-5.17-6' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc...
[linux-2.6-microblaze.git] / drivers / hid / wacom_wac.c
index 2a4cc39..a7176fc 100644 (file)
@@ -2588,6 +2588,24 @@ static void wacom_wac_finger_slot(struct wacom_wac *wacom_wac,
        }
 }
 
+static bool wacom_wac_slot_is_active(struct input_dev *dev, int key)
+{
+       struct input_mt *mt = dev->mt;
+       struct input_mt_slot *s;
+
+       if (!mt)
+               return false;
+
+       for (s = mt->slots; s != mt->slots + mt->num_slots; s++) {
+               if (s->key == key &&
+                       input_mt_get_value(s, ABS_MT_TRACKING_ID) >= 0) {
+                       return true;
+               }
+       }
+
+       return false;
+}
+
 static void wacom_wac_finger_event(struct hid_device *hdev,
                struct hid_field *field, struct hid_usage *usage, __s32 value)
 {
@@ -2638,9 +2656,14 @@ static void wacom_wac_finger_event(struct hid_device *hdev,
        }
 
        if (usage->usage_index + 1 == field->report_count) {
-               if (equivalent_usage == wacom_wac->hid_data.last_slot_field &&
-                   wacom_wac->hid_data.confidence)
-                       wacom_wac_finger_slot(wacom_wac, wacom_wac->touch_input);
+               if (equivalent_usage == wacom_wac->hid_data.last_slot_field) {
+                       bool touch_removed = wacom_wac_slot_is_active(wacom_wac->touch_input,
+                               wacom_wac->hid_data.id) && !wacom_wac->hid_data.tipswitch;
+
+                       if (wacom_wac->hid_data.confidence || touch_removed) {
+                               wacom_wac_finger_slot(wacom_wac, wacom_wac->touch_input);
+                       }
+               }
        }
 }
 
@@ -2659,6 +2682,10 @@ static void wacom_wac_finger_pre_report(struct hid_device *hdev,
 
        hid_data->confidence = true;
 
+       hid_data->cc_report = 0;
+       hid_data->cc_index = -1;
+       hid_data->cc_value_index = -1;
+
        for (i = 0; i < report->maxfield; i++) {
                struct hid_field *field = report->field[i];
                int j;
@@ -2692,11 +2719,14 @@ static void wacom_wac_finger_pre_report(struct hid_device *hdev,
            hid_data->cc_index >= 0) {
                struct hid_field *field = report->field[hid_data->cc_index];
                int value = field->value[hid_data->cc_value_index];
-               if (value)
+               if (value) {
                        hid_data->num_expected = value;
+                       hid_data->num_received = 0;
+               }
        }
        else {
                hid_data->num_expected = wacom_wac->features.touch_max;
+               hid_data->num_received = 0;
        }
 }
 
@@ -2724,6 +2754,7 @@ static void wacom_wac_finger_report(struct hid_device *hdev,
 
        input_sync(input);
        wacom_wac->hid_data.num_received = 0;
+       wacom_wac->hid_data.num_expected = 0;
 
        /* keep touch state for pen event */
        wacom_wac->shared->touch_down = wacom_wac_finger_count_touches(wacom_wac);