Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid
[linux-2.6-microblaze.git] / drivers / hid / wacom_wac.c
index 81ba642..fd51769 100644 (file)
@@ -824,6 +824,13 @@ static int wacom_intuos_inout(struct wacom_wac *wacom)
        return 0;
 }
 
+static inline bool touch_is_muted(struct wacom_wac *wacom_wac)
+{
+       return wacom_wac->probe_complete &&
+              wacom_wac->shared->has_mute_touch_switch &&
+              !wacom_wac->shared->is_touch_on;
+}
+
 static inline bool report_touch_events(struct wacom_wac *wacom)
 {
        return (touch_arbitration ? !wacom->shared->stylus_in_proximity : 1);
@@ -1525,11 +1532,8 @@ static int wacom_24hdt_irq(struct wacom_wac *wacom)
        int byte_per_packet = WACOM_BYTES_PER_24HDT_PACKET;
        int y_offset = 2;
 
-       if (wacom->shared->has_mute_touch_switch &&
-           !wacom->shared->is_touch_on) {
-               if (!wacom->shared->touch_down)
-                       return 0;
-       }
+       if (touch_is_muted(wacom) && !wacom->shared->touch_down)
+               return 0;
 
        if (wacom->features.type == WACOM_27QHDT) {
                current_num_contacts = data[63];
@@ -1987,14 +1991,17 @@ static void wacom_wac_pad_usage_mapping(struct hid_device *hdev,
                features->numbered_buttons++;
                features->device_type |= WACOM_DEVICETYPE_PAD;
                break;
-       case WACOM_HID_WD_TOUCHONOFF:
        case WACOM_HID_WD_MUTE_DEVICE:
+               /* softkey touch switch */
+               wacom_wac->is_soft_touch_switch = true;
+               fallthrough;
+       case WACOM_HID_WD_TOUCHONOFF:
                /*
-                * This usage, which is used to mute touch events, comes
-                * from the pad packet, but is reported on the touch
+                * These two usages, which are used to mute touch events, come
+                * from the pad packet, but are reported on the touch
                 * interface. Because the touch interface may not have
                 * been created yet, we cannot call wacom_map_usage(). In
-                * order to process this usage when we receive it, we set
+                * order to process the usages when we receive them, we set
                 * the usage type and code directly.
                 */
                wacom_wac->has_mute_touch_switch = true;
@@ -2533,8 +2540,7 @@ static void wacom_wac_finger_slot(struct wacom_wac *wacom_wac,
        bool prox = hid_data->tipswitch &&
                    report_touch_events(wacom_wac);
 
-       if (wacom_wac->shared->has_mute_touch_switch &&
-           !wacom_wac->shared->is_touch_on) {
+       if (touch_is_muted(wacom_wac)) {
                if (!wacom_wac->shared->touch_down)
                        return;
                prox = false;
@@ -2548,8 +2554,17 @@ static void wacom_wac_finger_slot(struct wacom_wac *wacom_wac,
                int slot;
 
                slot = input_mt_get_slot_by_key(input, hid_data->id);
-               if (slot < 0)
+               if (slot < 0) {
                        return;
+               } else {
+                       struct input_mt_slot *ps = &input->mt->slots[slot];
+                       int mt_id = input_mt_get_value(ps, ABS_MT_TRACKING_ID);
+
+                       if (!prox && mt_id < 0) {
+                               // No data to send for this slot; short-circuit
+                               return;
+                       }
+               }
 
                input_mt_slot(input, slot);
                input_mt_report_slot_state(input, MT_TOOL_FINGER, prox);
@@ -2581,6 +2596,9 @@ static void wacom_wac_finger_event(struct hid_device *hdev,
        unsigned equivalent_usage = wacom_equivalent_usage(usage->hid);
        struct wacom_features *features = &wacom->wacom_wac.features;
 
+       if (touch_is_muted(wacom_wac) && !wacom_wac->shared->touch_down)
+               return;
+
        if (wacom_wac->is_invalid_bt_frame)
                return;
 
@@ -2630,6 +2648,9 @@ static void wacom_wac_finger_pre_report(struct hid_device *hdev,
        struct hid_data* hid_data = &wacom_wac->hid_data;
        int i;
 
+       if (touch_is_muted(wacom_wac) && !wacom_wac->shared->touch_down)
+               return;
+
        wacom_wac->is_invalid_bt_frame = false;
 
        for (i = 0; i < report->maxfield; i++) {
@@ -2681,6 +2702,10 @@ static void wacom_wac_finger_report(struct hid_device *hdev,
        struct input_dev *input = wacom_wac->touch_input;
        unsigned touch_max = wacom_wac->features.touch_max;
 
+       /* if there was nothing to process, don't send an empty sync */
+       if (wacom_wac->hid_data.num_expected == 0)
+               return;
+
        /* If more packets of data are expected, give us a chance to
         * process them rather than immediately syncing a partial
         * update.
@@ -3835,6 +3860,7 @@ int wacom_setup_touch_input_capabilities(struct input_dev *input_dev,
                        input_dev->evbit[0] |= BIT_MASK(EV_SW);
                        __set_bit(SW_MUTE_DEVICE, input_dev->swbit);
                        wacom_wac->has_mute_touch_switch = true;
+                       wacom_wac->is_soft_touch_switch = true;
                }
                fallthrough;