From patchwork Wed Feb 15 05:27:18 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ping Cheng X-Patchwork-Id: 9573385 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 5AA7A60209 for ; Wed, 15 Feb 2017 05:27:29 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4BD54283F4 for ; Wed, 15 Feb 2017 05:27:29 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 3FDFE2842B; Wed, 15 Feb 2017 05:27:29 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 93A8F283F4 for ; Wed, 15 Feb 2017 05:27:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1750820AbdBOF12 (ORCPT ); Wed, 15 Feb 2017 00:27:28 -0500 Received: from mail-pg0-f65.google.com ([74.125.83.65]:33308 "EHLO mail-pg0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750732AbdBOF11 (ORCPT ); Wed, 15 Feb 2017 00:27:27 -0500 Received: by mail-pg0-f65.google.com with SMTP id 16so529057pgg.0 for ; Tue, 14 Feb 2017 21:27:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=qpGbWs55tQ0f9AzLMpSvADpnNaRwKsjwpSJMPDf5p2w=; b=fReaLeOCpJIX1rW4O+XZ6unWerwuqPnJDJfSYiTPwkzY3eWutxZzbVcYHYyzY9+Hpk tFefj9dmGXwadzOY/XB4X1PMzABKQD9qZfwvJntNnB6K05hi6w+77y/SeBGKWvyQHlxm jsZWTMJso0oyjKRHzzCkAhSDKJZydOk4ERAXjDMTAN1AA5jdpwEACnzH2srSSeStgU+E o6xGhfL6jwJtE2zkjwwpxHwtS+iuUNYoOq+/9tzRguTXRBqPbFA3aQK7s9WddtKcPyWe QTcRqix0rVtEIIh3Zu2m63i8qY59ZaLC9QewKbsbFhzWsrkEZmcvR+9rdsv8T4jiKjx7 uA6A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=qpGbWs55tQ0f9AzLMpSvADpnNaRwKsjwpSJMPDf5p2w=; b=WGTqRFcNJ8d8Wc2o7FrN2xo+m5F1OclXUvY1bKeuw0StvMAA0VhOaEB5S32uWP9mbt sq0l4rH88JkTyiEAD2IVSxfStgY2F0jP8PxSXr5VFi5lIwkJLbYQH7QKsfYkc6sDZTZE ZuvhFqMNzDZCXFvaSaeVP08jAEyEpqcKuJhGIu4AT+mVy7/Ie+qHBvjH1HT9wC5UTDKr e4i78NP6rTzSeqjcdxUjytqU/BhbwPAG43QQLsiOCN/V1Yet0LDwVqh9icJ8T8TCA+9u xu3H+rHHWkWjNOCDPW+r3naXtjzFxpWoiQdwWv7VmgQE6DufGOP2thtUut8nHSo4daT+ 3LWg== X-Gm-Message-State: AMke39mN1oUBBIm8URSris3bfwPQUfvqlnh00H0AWsZm0JAn0TsxUcfGP/GIGTdXiAvYNQ== X-Received: by 10.84.216.93 with SMTP id f29mr21086767plj.10.1487136446695; Tue, 14 Feb 2017 21:27:26 -0800 (PST) Received: from localhost.net (c-24-21-228-48.hsd1.wa.comcast.net. [24.21.228.48]) by smtp.gmail.com with ESMTPSA id j192sm4315857pfc.60.2017.02.14.21.27.25 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 14 Feb 2017 21:27:26 -0800 (PST) From: Ping Cheng X-Google-Original-From: Ping Cheng To: linux-input@vger.kernel.org Cc: jikos@kernel.org, benjamin.tissoires@gmail.com, dmitry.torokhov@gmail.com, Benjamin Tissoires , Ping Cheng Subject: [PATCH 2/3] HID: wacom: generic: add mode change touch key Date: Tue, 14 Feb 2017 21:27:18 -0800 Message-Id: <1487136438-5210-1-git-send-email-pingc@wacom.com> X-Mailer: git-send-email 1.8.3.1 Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Benjamin Tissoires 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 --- drivers/hid/wacom.h | 5 +++++ drivers/hid/wacom_sys.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ drivers/hid/wacom_wac.c | 17 ++++++++++++++++- drivers/hid/wacom_wac.h | 4 ++++ 4 files changed, 74 insertions(+), 1 deletion(-) diff --git a/drivers/hid/wacom.h b/drivers/hid/wacom.h index d0d7dc1..ee8e95b 100644 --- a/drivers/hid/wacom.h +++ b/drivers/hid/wacom.h @@ -111,6 +111,7 @@ enum wacom_worker { WACOM_WORKER_WIRELESS, WACOM_WORKER_BATTERY, WACOM_WORKER_REMOTE, + WACOM_WORKER_MODE_CHANGE, }; struct wacom; @@ -168,6 +169,7 @@ struct wacom { struct work_struct remote_work; struct delayed_work init_work; struct wacom_remote *remote; + struct work_struct mode_change_work; bool generic_has_leds; struct wacom_leds { struct wacom_group_leds *groups; @@ -197,6 +199,9 @@ static inline void wacom_schedule_work(struct wacom_wac *wacom_wac, case WACOM_WORKER_REMOTE: schedule_work(&wacom->remote_work); break; + case WACOM_WORKER_MODE_CHANGE: + schedule_work(&wacom->mode_change_work); + break; } } diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 3586acb..b3272c6 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); diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index a0135ac..0c544e7 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -1773,6 +1773,14 @@ static void wacom_wac_pad_usage_mapping(struct hid_device *hdev, wacom_map_usage(input, usage, field, EV_KEY, KEY_CONTROLPANEL, 0); features->device_type |= WACOM_DEVICETYPE_PAD; break; + case WACOM_HID_WD_MODE_CHANGE: + /* do not overwrite previous data */ + if (!wacom_wac->has_mode_change) { + wacom_wac->has_mode_change = true; + wacom_wac->is_direct_mode = true; + } + features->device_type |= WACOM_DEVICETYPE_PAD; + break; } switch (equivalent_usage & 0xfffffff0) { @@ -1821,7 +1829,7 @@ static void wacom_wac_pad_event(struct hid_device *hdev, struct hid_field *field * Avoid reporting this event and setting inrange_state if this usage * hasn't been mapped. */ - if (!usage->type) + if (!usage->type && equivalent_usage != WACOM_HID_WD_MODE_CHANGE) return; if (wacom_equivalent_usage(field->physical) == HID_DG_TABLETFUNCTIONKEY) { @@ -1843,6 +1851,13 @@ static void wacom_wac_pad_event(struct hid_device *hdev, struct hid_field *field } break; + case WACOM_HID_WD_MODE_CHANGE: + if (wacom_wac->is_direct_mode != value) { + wacom_wac->is_direct_mode = value; + wacom_schedule_work(&wacom->wacom_wac, WACOM_WORKER_MODE_CHANGE); + } + break; + case WACOM_HID_WD_BUTTONCENTER: for (i = 0; i < wacom->led.count; i++) wacom_update_led(wacom, features->numbered_buttons, diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h index 5eba31d..d9669c6 100644 --- a/drivers/hid/wacom_wac.h +++ b/drivers/hid/wacom_wac.h @@ -120,6 +120,7 @@ #define WACOM_HID_WD_BATTERY_LEVEL (WACOM_HID_UP_WACOMDIGITIZER | 0x043b) #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_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) @@ -330,6 +331,9 @@ struct wacom_wac { int mode_value; struct hid_data hid_data; bool has_mute_touch_switch; + bool has_mode_change; + bool is_direct_mode; + }; #endif