From 4082da80f46a6683439bb0357faadb18f0f5b2a6 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Tue, 14 Feb 2017 21:27:18 -0800 Subject: HID: wacom: generic: add mode change touch key Wacom Cintiq Pro added a touch key to switch the tablet between display and opaque mode. This patch informs the change by removing the old devices and creating new ones with proper properties. Signed-off-by: Benjamin Tissoires Signed-off-by: Ping Cheng Tested-by: Aaron Armstrong Skomra Signed-off-by: Jiri Kosina --- drivers/hid/wacom_sys.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) (limited to 'drivers/hid/wacom_sys.c') diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index be8f7e2a026f..9aec5b3a45bd 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -325,6 +325,13 @@ static void wacom_post_parse_hid(struct hid_device *hdev, if (features->type == HID_GENERIC) { /* Any last-minute generic device setup */ + if (wacom_wac->has_mode_change) { + if (wacom_wac->is_direct_mode) + features->device_type |= WACOM_DEVICETYPE_DIRECT; + else + features->device_type &= ~WACOM_DEVICETYPE_DIRECT; + } + if (features->touch_max > 1) { if (features->device_type & WACOM_DEVICETYPE_DIRECT) input_mt_init_slots(wacom_wac->touch_input, @@ -2488,6 +2495,46 @@ static void wacom_remote_work(struct work_struct *work) } } +static void wacom_mode_change_work(struct work_struct *work) +{ + struct wacom *wacom = container_of(work, struct wacom, mode_change_work); + struct wacom_shared *shared = wacom->wacom_wac.shared; + struct wacom *wacom1 = NULL; + struct wacom *wacom2 = NULL; + bool is_direct = wacom->wacom_wac.is_direct_mode; + int error = 0; + + if (shared->pen) { + wacom1 = hid_get_drvdata(shared->pen); + wacom_release_resources(wacom1); + hid_hw_stop(wacom1->hdev); + wacom1->wacom_wac.has_mode_change = true; + wacom1->wacom_wac.is_direct_mode = is_direct; + } + + if (shared->touch) { + wacom2 = hid_get_drvdata(shared->touch); + wacom_release_resources(wacom2); + hid_hw_stop(wacom2->hdev); + wacom2->wacom_wac.has_mode_change = true; + wacom2->wacom_wac.is_direct_mode = is_direct; + } + + if (wacom1) { + error = wacom_parse_and_register(wacom1, false); + if (error) + return; + } + + if (wacom2) { + error = wacom_parse_and_register(wacom2, false); + if (error) + return; + } + + return; +} + static int wacom_probe(struct hid_device *hdev, const struct hid_device_id *id) { @@ -2532,6 +2579,7 @@ static int wacom_probe(struct hid_device *hdev, INIT_WORK(&wacom->wireless_work, wacom_wireless_work); INIT_WORK(&wacom->battery_work, wacom_battery_work); INIT_WORK(&wacom->remote_work, wacom_remote_work); + INIT_WORK(&wacom->mode_change_work, wacom_mode_change_work); /* ask for the report descriptor to be loaded by HID */ error = hid_parse(hdev); @@ -2574,6 +2622,7 @@ static void wacom_remove(struct hid_device *hdev) cancel_work_sync(&wacom->wireless_work); cancel_work_sync(&wacom->battery_work); cancel_work_sync(&wacom->remote_work); + cancel_work_sync(&wacom->mode_change_work); if (hdev->bus == BUS_BLUETOOTH) device_remove_file(&hdev->dev, &dev_attr_speed); -- cgit v1.2.3 From d793ff81879a5747109f3106bd18e77662cb5187 Mon Sep 17 00:00:00 2001 From: Ping Cheng Date: Tue, 14 Feb 2017 21:27:45 -0800 Subject: HID: wacom: generic: support touch on/off softkey Wacom Cintiq Pro has a softkey to turn touch on/off. Since it is a softkey, hardware/firmware still reports touch events no matter what state the softkey is. We need to ignore touch events when the key is in off mode. Signed-off-by: Ping Cheng Reviewed-by: Benjamin Tissoires Tested-by: Aaron Armstrong Skomra Signed-off-by: Jiri Kosina --- drivers/hid/wacom_sys.c | 4 +++- drivers/hid/wacom_wac.c | 18 +++++++++++++++++- drivers/hid/wacom_wac.h | 2 ++ 3 files changed, 22 insertions(+), 2 deletions(-) (limited to 'drivers/hid/wacom_sys.c') diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 9aec5b3a45bd..037b9c04745a 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -2100,8 +2100,10 @@ static void wacom_set_shared_values(struct wacom_wac *wacom_wac) wacom_wac->shared->touch_input = wacom_wac->touch_input; } - if (wacom_wac->has_mute_touch_switch) + if (wacom_wac->has_mute_touch_switch) { wacom_wac->shared->has_mute_touch_switch = true; + wacom_wac->shared->is_touch_on = true; + } if (wacom_wac->shared->has_mute_touch_switch && wacom_wac->shared->touch_input) { diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 2c399a423957..68fb9e114a0b 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -1739,6 +1739,7 @@ static void wacom_wac_pad_usage_mapping(struct hid_device *hdev, features->device_type |= WACOM_DEVICETYPE_PAD; break; case WACOM_HID_WD_TOUCHONOFF: + case WACOM_HID_WD_MUTE_DEVICE: /* * This usage, which is used to mute touch events, comes * from the pad packet, but is reported on the touch @@ -1831,6 +1832,7 @@ static void wacom_wac_pad_event(struct hid_device *hdev, struct hid_field *field struct wacom_features *features = &wacom_wac->features; unsigned equivalent_usage = wacom_equivalent_usage(usage->hid); int i; + bool is_touch_on = value; /* * Avoid reporting this event and setting inrange_state if this usage @@ -1850,10 +1852,17 @@ 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: + if (wacom_wac->shared->touch_input && value) { + wacom_wac->shared->is_touch_on = !wacom_wac->shared->is_touch_on; + is_touch_on = wacom_wac->shared->is_touch_on; + } + + /* fall through*/ case WACOM_HID_WD_TOUCHONOFF: if (wacom_wac->shared->touch_input) { input_report_switch(wacom_wac->shared->touch_input, - SW_MUTE_DEVICE, !value); + SW_MUTE_DEVICE, !is_touch_on); input_sync(wacom_wac->shared->touch_input); } break; @@ -2212,6 +2221,13 @@ 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 (!wacom_wac->shared->touch_down) + return; + prox = 0; + } + wacom_wac->hid_data.num_received++; if (wacom_wac->hid_data.num_received > wacom_wac->hid_data.num_expected) return; diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h index d9669c6116b7..839bd4b6388c 100644 --- a/drivers/hid/wacom_wac.h +++ b/drivers/hid/wacom_wac.h @@ -121,6 +121,7 @@ #define WACOM_HID_WD_EXPRESSKEY00 (WACOM_HID_UP_WACOMDIGITIZER | 0x0910) #define WACOM_HID_WD_EXPRESSKEYCAP00 (WACOM_HID_UP_WACOMDIGITIZER | 0x0950) #define WACOM_HID_WD_MODE_CHANGE (WACOM_HID_UP_WACOMDIGITIZER | 0x0980) +#define WACOM_HID_WD_MUTE_DEVICE (WACOM_HID_UP_WACOMDIGITIZER | 0x0981) #define WACOM_HID_WD_CONTROLPANEL (WACOM_HID_UP_WACOMDIGITIZER | 0x0982) #define WACOM_HID_WD_ONSCREEN_KEYBOARD (WACOM_HID_UP_WACOMDIGITIZER | 0x0983) #define WACOM_HID_WD_BUTTONCONFIG (WACOM_HID_UP_WACOMDIGITIZER | 0x0986) @@ -274,6 +275,7 @@ struct wacom_shared { struct hid_device *pen; struct hid_device *touch; bool has_mute_touch_switch; + bool is_touch_on; }; struct hid_data { -- cgit v1.2.3