summaryrefslogtreecommitdiff
path: root/drivers/hid
diff options
context:
space:
mode:
authorJiri Kosina <jkosina@suse.cz>2021-09-01 23:04:50 +0300
committerJiri Kosina <jkosina@suse.cz>2021-09-01 23:04:50 +0300
commit2501ce96ecd00f817323c1014a870dc9710ddb82 (patch)
tree5462c7e8bf0f321d31ec554fbb326b0f8cc1a013 /drivers/hid
parentfcbc26eb92545ba5e2828f2dcffd1c4bdd82b373 (diff)
parent9d339fe4cbd5de150f2d9fd554cc7e7213d09f08 (diff)
downloadlinux-2501ce96ecd00f817323c1014a870dc9710ddb82.tar.xz
Merge branch 'for-5.15/wacom' into for-linus
Diffstat (limited to 'drivers/hid')
-rw-r--r--drivers/hid/wacom_sys.c9
-rw-r--r--drivers/hid/wacom_wac.c50
-rw-r--r--drivers/hid/wacom_wac.h2
3 files changed, 48 insertions, 13 deletions
diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c
index 57bfa0ae9836..93f49b766376 100644
--- a/drivers/hid/wacom_sys.c
+++ b/drivers/hid/wacom_sys.c
@@ -2287,7 +2287,13 @@ static void wacom_set_shared_values(struct wacom_wac *wacom_wac)
if (wacom_wac->has_mute_touch_switch) {
wacom_wac->shared->has_mute_touch_switch = true;
- wacom_wac->shared->is_touch_on = true;
+ /* Hardware touch switch may be off. Wait until
+ * we know the switch state to decide is_touch_on.
+ * Softkey state should be initialized to "on" to
+ * match historic default.
+ */
+ if (wacom_wac->is_soft_touch_switch)
+ wacom_wac->shared->is_touch_on = true;
}
if (wacom_wac->shared->has_mute_touch_switch &&
@@ -2791,6 +2797,7 @@ static int wacom_probe(struct hid_device *hdev,
error);
}
+ wacom_wac->probe_complete = true;
return 0;
}
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
index 81ba642adcb7..fd51769d0994 100644
--- a/drivers/hid/wacom_wac.c
+++ b/drivers/hid/wacom_wac.c
@@ -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;
diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h
index 8f16654eca09..8b2d4e5b2303 100644
--- a/drivers/hid/wacom_wac.h
+++ b/drivers/hid/wacom_wac.h
@@ -337,6 +337,7 @@ struct wacom_wac {
int tool[2];
int id[2];
__u64 serial[2];
+ bool probe_complete;
bool reporting_data;
struct wacom_features features;
struct wacom_shared *shared;
@@ -352,6 +353,7 @@ struct wacom_wac {
int mode_value;
struct hid_data hid_data;
bool has_mute_touch_switch;
+ bool is_soft_touch_switch;
bool has_mode_change;
bool is_direct_mode;
bool is_invalid_bt_frame;