aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Gerecke <killertofu@gmail.com>2017-12-26 17:53:55 -0500
committerJiri Kosina <jkosina@suse.cz>2018-01-23 09:42:37 -0500
commit403c0f681c1964ff1db8c2fb8de8c4067779d081 (patch)
tree282214a7e164e946032437d5d85051d444095d66
parent791ae273731fa85d3332e45064dab177ae663e80 (diff)
HID: wacom: Fix reporting of touch toggle (WACOM_HID_WD_MUTE_DEVICE) events
Touch toggle softkeys send a '1' while pressed and a '0' while released, requring the kernel to keep track of wether touch should be enabled or disabled. The code does not handle the state transitions properly, however. If the key is pressed repeatedly, the following four states of states are cycled through (assuming touch starts out enabled): Press: shared->is_touch_on => 0, SW_MUTE_DEVICE => 1 Release: shared->is_touch_on => 0, SW_MUTE_DEVICE => 1 Press: shared->is_touch_on => 1, SW_MUTE_DEVICE => 0 Release: shared->is_touch_on => 1, SW_MUTE_DEVICE => 1 The hardware always properly enables/disables touch when the key is pressed but applications that listen for SW_MUTE_DEVICE events to provide feedback about the state will only ever show touch as being enabled while the key is held, and only every-other time. This sequence occurs because the fallthrough WACOM_HID_WD_TOUCHONOFF case is always handled, and it uses the value of the *local* is_touch_on variable as the value to report to userspace. The local value is equal to the shared value when the button is pressed, but equal to zero when the button is released. Reporting the shared value to userspace fixes this problem, but the fallthrough case needs to update the shared value in an incompatible way (which is why the local variable was introduced in the first place). To work around this, we just handle both cases in a single block of code and update the shared variable as appropriate. Fixes: d793ff8187 ("HID: wacom: generic: support touch on/off softkey") Cc: <stable@vger.kernel.org> # v4.12+ Signed-off-by: Jason Gerecke <jason.gerecke@wacom.com> Reviewed-by: Aaron Skomra <aaron.skomra@wacom.com> Tested-by: Aaron Skomra <aaron.skomra@wacom.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r--drivers/hid/wacom_wac.c16
1 files changed, 8 insertions, 8 deletions
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
index 7fa373225d8a..061e4d7a0647 100644
--- a/drivers/hid/wacom_wac.c
+++ b/drivers/hid/wacom_wac.c
@@ -1924,7 +1924,6 @@ static void wacom_wac_pad_event(struct hid_device *hdev, struct hid_field *field
1924 struct wacom_features *features = &wacom_wac->features; 1924 struct wacom_features *features = &wacom_wac->features;
1925 unsigned equivalent_usage = wacom_equivalent_usage(usage->hid); 1925 unsigned equivalent_usage = wacom_equivalent_usage(usage->hid);
1926 int i; 1926 int i;
1927 bool is_touch_on = value;
1928 bool do_report = false; 1927 bool do_report = false;
1929 1928
1930 /* 1929 /*
@@ -1969,16 +1968,17 @@ static void wacom_wac_pad_event(struct hid_device *hdev, struct hid_field *field
1969 break; 1968 break;
1970 1969
1971 case WACOM_HID_WD_MUTE_DEVICE: 1970 case WACOM_HID_WD_MUTE_DEVICE:
1972 if (wacom_wac->shared->touch_input && value) {
1973 wacom_wac->shared->is_touch_on = !wacom_wac->shared->is_touch_on;
1974 is_touch_on = wacom_wac->shared->is_touch_on;
1975 }
1976
1977 /* fall through*/
1978 case WACOM_HID_WD_TOUCHONOFF: 1971 case WACOM_HID_WD_TOUCHONOFF:
1979 if (wacom_wac->shared->touch_input) { 1972 if (wacom_wac->shared->touch_input) {
1973 bool *is_touch_on = &wacom_wac->shared->is_touch_on;
1974
1975 if (equivalent_usage == WACOM_HID_WD_MUTE_DEVICE && value)
1976 *is_touch_on = !(*is_touch_on);
1977 else if (equivalent_usage == WACOM_HID_WD_TOUCHONOFF)
1978 *is_touch_on = value;
1979
1980 input_report_switch(wacom_wac->shared->touch_input, 1980 input_report_switch(wacom_wac->shared->touch_input,
1981 SW_MUTE_DEVICE, !is_touch_on); 1981 SW_MUTE_DEVICE, !(*is_touch_on));
1982 input_sync(wacom_wac->shared->touch_input); 1982 input_sync(wacom_wac->shared->touch_input);
1983 } 1983 }
1984 break; 1984 break;