Commit 993f0d93 authored by Jason Gerecke's avatar Jason Gerecke Committed by Jiri Kosina

HID: wacom: generic: Send MSC_SERIAL and ABS_MISC when leaving prox

The latest generation of pro devices (MobileStudio Pro, 2nd-gen Intuos
Pro, Cintiq Pro) send a serial number of '0' whenever the pen is too far
away for reliable communication. Userspace defines that a serial number
of '0' is invalid, so we need to be careful not to actually forward
this value. Additionally, since EMR ISDv4 devices do not support serial
numbers or tool IDs, we'd like to not send these events if they aren't
necessary.

The existing code achieves these goals by adding a check for a non-zero
serial number within the wacom_wac_pen_report function. The MSC_SERIAL
and ABS_MISC events are only sent if the serial number is non-zero. This
code fails, however when the pen for a pro device leaves proximity. When
the pen leaves prox and the tablet sends a serial of 0, wacom_wac_pen_event
dutifully clears the serial number. When wacom_wac_pen_report is called,
it does not send either the MSC_SERIAL of the exiting tool nor an ABS_MISC
event.

This patch prevents the wacom_wac_pen_event function from clearing an
already-set serial number. This ensures that we have the serial number
handy when exiting proximity, but requires us to manually clear it
afterwards to ensure the driver does not send stale data (e.g. when
switching between AES pens that report a serial nubmer of 0 for the
first few fully in-proximity packets).

Fixes: f85c9dc6 ("HID: wacom: generic: Support tool ID and additional tool types")
Cc: stable # v4.10 <stable@vger.kernel.org>
Signed-off-by: default avatarPing Cheng <ping.cheng@wacom.com>
Signed-off-by: default avatarJason Gerecke <jason.gerecke@wacom.com>
Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
parent 8320caee
...@@ -2141,8 +2141,10 @@ static void wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field ...@@ -2141,8 +2141,10 @@ static void wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field
wacom_wac->hid_data.tipswitch |= value; wacom_wac->hid_data.tipswitch |= value;
return; return;
case HID_DG_TOOLSERIALNUMBER: case HID_DG_TOOLSERIALNUMBER:
wacom_wac->serial[0] = (wacom_wac->serial[0] & ~0xFFFFFFFFULL); if (value) {
wacom_wac->serial[0] |= (__u32)value; wacom_wac->serial[0] = (wacom_wac->serial[0] & ~0xFFFFFFFFULL);
wacom_wac->serial[0] |= (__u32)value;
}
return; return;
case HID_DG_TWIST: case HID_DG_TWIST:
/* /*
...@@ -2156,15 +2158,17 @@ static void wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field ...@@ -2156,15 +2158,17 @@ static void wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field
wacom_wac->hid_data.sense_state = value; wacom_wac->hid_data.sense_state = value;
return; return;
case WACOM_HID_WD_SERIALHI: case WACOM_HID_WD_SERIALHI:
wacom_wac->serial[0] = (wacom_wac->serial[0] & 0xFFFFFFFF); if (value) {
wacom_wac->serial[0] |= ((__u64)value) << 32; wacom_wac->serial[0] = (wacom_wac->serial[0] & 0xFFFFFFFF);
/* wacom_wac->serial[0] |= ((__u64)value) << 32;
* Non-USI EMR devices may contain additional tool type /*
* information here. See WACOM_HID_WD_TOOLTYPE case for * Non-USI EMR devices may contain additional tool type
* more details. * information here. See WACOM_HID_WD_TOOLTYPE case for
*/ * more details.
if (value >> 20 == 1) { */
wacom_wac->id[0] |= value & 0xFFFFF; if (value >> 20 == 1) {
wacom_wac->id[0] |= value & 0xFFFFF;
}
} }
return; return;
case WACOM_HID_WD_TOOLTYPE: case WACOM_HID_WD_TOOLTYPE:
...@@ -2279,6 +2283,7 @@ static void wacom_wac_pen_report(struct hid_device *hdev, ...@@ -2279,6 +2283,7 @@ static void wacom_wac_pen_report(struct hid_device *hdev,
if (!prox) { if (!prox) {
wacom_wac->tool[0] = 0; wacom_wac->tool[0] = 0;
wacom_wac->id[0] = 0; wacom_wac->id[0] = 0;
wacom_wac->serial[0] = 0;
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment