summaryrefslogtreecommitdiff
path: root/drivers/hid/wacom_sys.c
diff options
context:
space:
mode:
authorBenjamin Tissoires <benjamin.tissoires@redhat.com>2017-02-15 08:27:18 +0300
committerJiri Kosina <jkosina@suse.cz>2017-03-06 16:07:13 +0300
commit4082da80f46a6683439bb0357faadb18f0f5b2a6 (patch)
tree91cba84acbe582c6fd99fa44d1ef1c12228c0760 /drivers/hid/wacom_sys.c
parent4eb220cb35a9c4f69a2438b987bb3d509d56cc80 (diff)
downloadlinux-4082da80f46a6683439bb0357faadb18f0f5b2a6.tar.xz
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 <benjamin.tissoires@redhat.com> Signed-off-by: Ping Cheng <ping.cheng@wacom.com> Tested-by: Aaron Armstrong Skomra <aaron.skomra@wacom.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid/wacom_sys.c')
-rw-r--r--drivers/hid/wacom_sys.c49
1 files changed, 49 insertions, 0 deletions
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);