From patchwork Thu Oct 20 01:03:43 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Gerecke, Jason" X-Patchwork-Id: 9385695 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 E7C83607D0 for ; Thu, 20 Oct 2016 01:04:34 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D60CA28DD7 for ; Thu, 20 Oct 2016 01:04:34 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id CAE16296F3; Thu, 20 Oct 2016 01:04:34 +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.3 required=2.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_SPAM, 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 3242628DD7 for ; Thu, 20 Oct 2016 01:04:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754602AbcJTBEd (ORCPT ); Wed, 19 Oct 2016 21:04:33 -0400 Received: from mail-pf0-f195.google.com ([209.85.192.195]:33904 "EHLO mail-pf0-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754445AbcJTBEc (ORCPT ); Wed, 19 Oct 2016 21:04:32 -0400 Received: by mail-pf0-f195.google.com with SMTP id 128so3847599pfz.1 for ; Wed, 19 Oct 2016 18:04:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=yvVZtMyfmBomSFKoMU6U4IL1PRMGNw6bMMg+0liPa8Y=; b=aDdSKHmsEZmKKA/iI51XpY0vpkIAOJ7/PLx/RBwOmNSHPNTXxq+ULij+ALuiyeN3j7 kPIGej6hFQQ6Xo7+Bgdhq3z/Xw1yScCx0sOYwlL7Rts1bfEOXSiY/sVrtDimcxRZKKp1 RTvNiXaj296xRos/mhfMPoOnokCczMZvnmUPPm/k7bD/huj9fBFyFViwI3TvkqPFCabz /bcpU6bM6B9ZeeWFC1R1qGu5rL7MzxblimKPdL4NyoXMemyBqru79nCkUikWVslnlxwd avWPTm0EPJqArcgIm4tcEICHOpHTXwGM5JhYJPDGMVgN1/6j8PUpK9c22ZLzQru7xG0P j9rg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=yvVZtMyfmBomSFKoMU6U4IL1PRMGNw6bMMg+0liPa8Y=; b=entSRgoNUo10B8K68KiOYmmJxW3g9XF108YFVi15gP0VzBr0QP2Hgp0KTZDo7MDfGK Kf+ORztm+QKr424Zlc6l7W4TNSE5xGUpWKlfIr4nD7LgBu/hJ80OiVN+VEnIqCCdUqf6 +1TKWBLnqukToqzP8U6x4j6TYiAAj1IUeVTDekv1pW9dhx6fKleRLtyzDNEgGrfRq1Ui aPkE2vv2srx951ijDPmqVNKAr5Sq7JvJI0vKhW/FJdBajznSnG10FYnRgkt8OD+NDQ4o VW4XUCcEuyD6H0Jg7ih0t+F0ZsJiTZSVQBvD+wCXZUIubvNg6Vp9FX8cAjGuGa82m62o p9eQ== X-Gm-Message-State: AA6/9RmbPjOtv+K9I0a91tBu9PAsXUxLKbMEI2sjs4noE5cCFT0Rb6WeIjjmN8Z3/KKVtg== X-Received: by 10.98.142.26 with SMTP id k26mr16336072pfe.26.1476925471170; Wed, 19 Oct 2016 18:04:31 -0700 (PDT) Received: from wtc005007.corp.onewacom.com ([50.225.60.4]) by smtp.gmail.com with ESMTPSA id d15sm877372pfl.90.2016.10.19.18.04.26 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 19 Oct 2016 18:04:30 -0700 (PDT) From: Jason Gerecke To: linux-input@vger.kernel.org, Jiri Kosina Cc: Benjamin Tissoires , Ping Cheng , Ping Cheng , Aaron Skomra , Jason Gerecke , Jason Gerecke Subject: [PATCH v3 07/18] HID: wacom: generic: Support and use 'Custom HID' mode and usages Date: Wed, 19 Oct 2016 18:03:43 -0700 Message-Id: <20161020010354.4049-7-killertofu@gmail.com> X-Mailer: git-send-email 2.10.0 In-Reply-To: <20161020010354.4049-1-killertofu@gmail.com> References: <20161006212231.31440-1-killertofu@gmail.com> <20161020010354.4049-1-killertofu@gmail.com> 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 Wacom's new "MobileStudio Pro" tablets are the first devices in their branded product line-up to include a usable HID descriptor for the pen interface. Like prior branded products, the device can operate in one of two modes: 'Standard HID', and 'Wacom Custom HID'. Although the first mode is usable by the HID_GENERIC codepath as-is (huzzah!), it is subject to some restrictions -- most notably pressure being limited to 2048 levels instead of 8192. To ensure tablets that include support for Custom HID mode work optimally, we add support for its usages and switch the device to Custom HID mode if possible. The usages defined for Custom HID mode are often numerically similar to their standard HID equivalents, allowing us to write a simple translation function that takes arbitrary HID usages as input and which returns the corresponding standard HID usage as output (if one exists). Switching on this translated usage instead of the actual usage allows the existing cases to apply to both modes of operation without having to explicitly define every Custom HID usage. Signed-off-by: Jason Gerecke Reviewed-by: Benjamin Tissoires --- drivers/hid/wacom_sys.c | 5 +++++ drivers/hid/wacom_wac.c | 37 +++++++++++++++++++++++++++++++------ drivers/hid/wacom_wac.h | 3 +++ 3 files changed, 39 insertions(+), 6 deletions(-) diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 7b9bff2..b2e2471 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -166,6 +166,11 @@ static void wacom_feature_mapping(struct hid_device *hdev, } break; + case WACOM_HID_WD_DATAMODE: + wacom->wacom_wac.mode_report = field->report->id; + wacom->wacom_wac.mode_value = 2; + break; + case WACOM_HID_UP_G9: case WACOM_HID_UP_G11: if (field->report->id == 0x03 && diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 3f4ba53..6c2f0e4 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -1435,14 +1435,35 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len) return 0; } +static int wacom_equivalent_usage(int usage) +{ + if ((usage & HID_USAGE_PAGE) == WACOM_HID_UP_WACOMDIGITIZER) { + int subpage = (usage & 0xFF00) << 8; + int subusage = (usage & 0xFF); + + if (subpage == WACOM_HID_SP_DIGITIZER || + subpage == WACOM_HID_SP_DIGITIZERINFO) { + return usage; + } + + if (subpage == HID_UP_UNDEFINED) + subpage = HID_UP_DIGITIZER; + + return subpage | subusage; + } + + return usage; +} + static void wacom_map_usage(struct input_dev *input, struct hid_usage *usage, struct hid_field *field, __u8 type, __u16 code, int fuzz) { int fmin = field->logical_minimum; int fmax = field->logical_maximum; + unsigned int equivalent_usage = wacom_equivalent_usage(usage->hid); int resolution_code = code; - if (usage->hid == HID_DG_TWIST) { + if (equivalent_usage == HID_DG_TWIST) { resolution_code = ABS_RZ; } @@ -1472,8 +1493,9 @@ static void wacom_wac_pen_usage_mapping(struct hid_device *hdev, struct wacom *wacom = hid_get_drvdata(hdev); struct wacom_wac *wacom_wac = &wacom->wacom_wac; struct input_dev *input = wacom_wac->pen_input; + unsigned equivalent_usage = wacom_equivalent_usage(usage->hid); - switch (usage->hid) { + switch (equivalent_usage) { case HID_GD_X: wacom_map_usage(input, usage, field, EV_ABS, ABS_X, 4); break; @@ -1524,8 +1546,9 @@ static int wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field, struct wacom *wacom = hid_get_drvdata(hdev); struct wacom_wac *wacom_wac = &wacom->wacom_wac; struct input_dev *input = wacom_wac->pen_input; + unsigned equivalent_usage = wacom_equivalent_usage(usage->hid); - switch (usage->hid) { + switch (equivalent_usage) { case HID_GD_Z: /* * HID_GD_Z "should increase as the control's position is @@ -1597,8 +1620,9 @@ static void wacom_wac_finger_usage_mapping(struct hid_device *hdev, struct wacom_wac *wacom_wac = &wacom->wacom_wac; struct input_dev *input = wacom_wac->touch_input; unsigned touch_max = wacom_wac->features.touch_max; + unsigned equivalent_usage = wacom_equivalent_usage(usage->hid); - switch (usage->hid) { + switch (equivalent_usage) { case HID_GD_X: if (touch_max == 1) wacom_map_usage(input, usage, field, EV_ABS, ABS_X, 4); @@ -1673,8 +1697,9 @@ static int wacom_wac_finger_event(struct hid_device *hdev, { struct wacom *wacom = hid_get_drvdata(hdev); struct wacom_wac *wacom_wac = &wacom->wacom_wac; + unsigned equivalent_usage = wacom_equivalent_usage(usage->hid); - switch (usage->hid) { + switch (equivalent_usage) { case HID_GD_X: wacom_wac->hid_data.x = value; break; @@ -1697,7 +1722,7 @@ static int wacom_wac_finger_event(struct hid_device *hdev, if (usage->usage_index + 1 == field->report_count) { - if (usage->hid == wacom_wac->hid_data.last_slot_field) + if (equivalent_usage == wacom_wac->hid_data.last_slot_field) wacom_wac_finger_slot(wacom_wac, wacom_wac->touch_input); } diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h index d2629c8..ba914ba 100644 --- a/drivers/hid/wacom_wac.h +++ b/drivers/hid/wacom_wac.h @@ -85,7 +85,10 @@ #define WACOM_DEVICETYPE_DIRECT 0x0010 #define WACOM_HID_UP_WACOMDIGITIZER 0xff0d0000 +#define WACOM_HID_SP_DIGITIZER 0x000d0000 +#define WACOM_HID_SP_DIGITIZERINFO 0x00100000 #define WACOM_HID_WD_DIGITIZER (WACOM_HID_UP_WACOMDIGITIZER | 0x01) +#define WACOM_HID_WD_DATAMODE (WACOM_HID_UP_WACOMDIGITIZER | 0x1002) #define WACOM_HID_UP_G9 0xff090000 #define WACOM_HID_G9_PEN (WACOM_HID_UP_G9 | 0x02) #define WACOM_HID_G9_TOUCHSCREEN (WACOM_HID_UP_G9 | 0x11)