HID: wacom: Don't register pad_input for touch switch
authorPing Cheng <pinglinux@gmail.com>
Fri, 13 May 2022 21:52:37 +0000 (14:52 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 17 Aug 2022 12:22:47 +0000 (14:22 +0200)
commit d6b675687a4ab4dba684716d97c8c6f81bf10905 upstream.

Touch switch state is received through WACOM_PAD_FIELD. However, it
is reported by touch_input. Don't register pad_input if no other pad
events require the interface.

Cc: stable@vger.kernel.org
Signed-off-by: Ping Cheng <ping.cheng@wacom.com>
Reviewed-by: Jason Gerecke <jason.gerecke@wacom.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/hid/wacom_sys.c
drivers/hid/wacom_wac.c

index b1bbf29..7e67c41 100644 (file)
@@ -2124,7 +2124,7 @@ static int wacom_register_inputs(struct wacom *wacom)
 
        error = wacom_setup_pad_input_capabilities(pad_input_dev, wacom_wac);
        if (error) {
-               /* no pad in use on this interface */
+               /* no pad events using this interface */
                input_free_device(pad_input_dev);
                wacom_wac->pad_input = NULL;
                pad_input_dev = NULL;
index 87ea70d..c454231 100644 (file)
@@ -2017,7 +2017,6 @@ static void wacom_wac_pad_usage_mapping(struct hid_device *hdev,
                wacom_wac->has_mute_touch_switch = true;
                usage->type = EV_SW;
                usage->code = SW_MUTE_DEVICE;
-               features->device_type |= WACOM_DEVICETYPE_PAD;
                break;
        case WACOM_HID_WD_TOUCHSTRIP:
                wacom_map_usage(input, usage, field, EV_ABS, ABS_RX, 0);
@@ -2097,6 +2096,30 @@ static void wacom_wac_pad_event(struct hid_device *hdev, struct hid_field *field
                        wacom_wac->hid_data.inrange_state |= value;
        }
 
+       /* Process touch switch state first since it is reported through touch interface,
+        * which is indepentent of pad interface. In the case when there are no other pad
+        * events, the pad interface will not even be created.
+        */
+       if ((equivalent_usage == WACOM_HID_WD_MUTE_DEVICE) ||
+          (equivalent_usage == WACOM_HID_WD_TOUCHONOFF)) {
+               if (wacom_wac->shared->touch_input) {
+                       bool *is_touch_on = &wacom_wac->shared->is_touch_on;
+
+                       if (equivalent_usage == WACOM_HID_WD_MUTE_DEVICE && value)
+                               *is_touch_on = !(*is_touch_on);
+                       else if (equivalent_usage == WACOM_HID_WD_TOUCHONOFF)
+                               *is_touch_on = value;
+
+                       input_report_switch(wacom_wac->shared->touch_input,
+                                           SW_MUTE_DEVICE, !(*is_touch_on));
+                       input_sync(wacom_wac->shared->touch_input);
+               }
+               return;
+       }
+
+       if (!input)
+               return;
+
        switch (equivalent_usage) {
        case WACOM_HID_WD_TOUCHRING:
                /*
@@ -2132,22 +2155,6 @@ static void wacom_wac_pad_event(struct hid_device *hdev, struct hid_field *field
                        input_event(input, usage->type, usage->code, 0);
                break;
 
-       case WACOM_HID_WD_MUTE_DEVICE:
-       case WACOM_HID_WD_TOUCHONOFF:
-               if (wacom_wac->shared->touch_input) {
-                       bool *is_touch_on = &wacom_wac->shared->is_touch_on;
-
-                       if (equivalent_usage == WACOM_HID_WD_MUTE_DEVICE && value)
-                               *is_touch_on = !(*is_touch_on);
-                       else if (equivalent_usage == WACOM_HID_WD_TOUCHONOFF)
-                               *is_touch_on = value;
-
-                       input_report_switch(wacom_wac->shared->touch_input,
-                                           SW_MUTE_DEVICE, !(*is_touch_on));
-                       input_sync(wacom_wac->shared->touch_input);
-               }
-               break;
-
        case WACOM_HID_WD_MODE_CHANGE:
                if (wacom_wac->is_direct_mode != value) {
                        wacom_wac->is_direct_mode = value;
@@ -2808,7 +2815,7 @@ void wacom_wac_event(struct hid_device *hdev, struct hid_field *field,
        /* usage tests must precede field tests */
        if (WACOM_BATTERY_USAGE(usage))
                wacom_wac_battery_event(hdev, field, usage, value);
-       else if (WACOM_PAD_FIELD(field) && wacom->wacom_wac.pad_input)
+       else if (WACOM_PAD_FIELD(field))
                wacom_wac_pad_event(hdev, field, usage, value);
        else if (WACOM_PEN_FIELD(field) && wacom->wacom_wac.pen_input)
                wacom_wac_pen_event(hdev, field, usage, value);