From patchwork Thu Oct 6 21:22:24 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Gerecke, Jason" X-Patchwork-Id: 9365343 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 AEE976077E for ; Thu, 6 Oct 2016 21:23:01 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9987029253 for ; Thu, 6 Oct 2016 21:23:01 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8C61629268; Thu, 6 Oct 2016 21:23:01 +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 0110329253 for ; Thu, 6 Oct 2016 21:23:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S935212AbcJFVXA (ORCPT ); Thu, 6 Oct 2016 17:23:00 -0400 Received: from mail-qt0-f194.google.com ([209.85.216.194]:33395 "EHLO mail-qt0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S935088AbcJFVW7 (ORCPT ); Thu, 6 Oct 2016 17:22:59 -0400 Received: by mail-qt0-f194.google.com with SMTP id m5so836307qtb.0 for ; Thu, 06 Oct 2016 14:22:59 -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=eQ5EZYTwic4Wc1IfzL1nS7str2ae6HjRxUdIGNZrkUA=; b=gDcY0jPgV/wVK4Avkjc5PEr24r1HOeYK+PDBAvrBUHXqZ5KraBMAjhwRE1VcYSy6cu ar5qBIqR8AuXNCBeH8u7PK2V3Sn9BqKW4TlY697tZ9AjTGprvzL9dong6MjnzfSItBkA ZKxyWcwHnEpw/sNHTYxC/mn0J9GTN6skyNyro8uSSvHy4lALaTNi4msD+0pcYo3DR3u0 /Vt+fDOX7BrtdpkWSrCqnIZCIo4ABaJplm1O7iK3/M3cgZ6eqTKsumfGZnn3dxkKQ0HK 21ONij2u2/kajpk9veiVTtOmbCqorBas8dghISNzcx2k+U4lqnzh/cx4OFniVb1zxPQV o5eg== 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=eQ5EZYTwic4Wc1IfzL1nS7str2ae6HjRxUdIGNZrkUA=; b=Cm6KCXIjPhjAAYXkVBR8lYRCJ2iM8AJzrAeAzDfjn3RzkUG1kNzS2aSiyi1toKt7v6 aEjogbbjLCxjnVPfOJH2KGjWD7HInGG2As7cdjkITSqAQ76fpzQJiV/XVFlxsldkQyqf D+1hcSSVJ180m/lLW8BJHmu+sY6i8QuFfkawqSY36K+lxehxiMAC9soJmcrKb5KUIdl9 TOvU7F6faklLskscxKonzj0hjzLSDWg6qW1gdyyorUig6636JJBWPGEwXtH59PLrNr4Y VR9iWjkWEsBE5i4cVLZnxL8ur3ut7NKyoQ0YUVdB3VKLCMZUY+Z+4T9XF5CGv9SLfl2u SCLQ== X-Gm-Message-State: AA6/9Rku55tncONFyI6AULa/58Ezfa1jkkvt/ZAYaWkSXWVWyMIkEtTiDGladTUlLi9//Q== X-Received: by 10.200.36.154 with SMTP id s26mr17452713qts.0.1475788978864; Thu, 06 Oct 2016 14:22:58 -0700 (PDT) Received: from wacom-arch2.corp.onewacom.com ([50.225.60.4]) by smtp.gmail.com with ESMTPSA id m4sm5773714qkf.29.2016.10.06.14.22.57 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 06 Oct 2016 14:22:58 -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 12/19] HID: wacom: generic: Support tool ID and additional tool types Date: Thu, 6 Oct 2016 14:22:24 -0700 Message-Id: <20161006212231.31440-13-killertofu@gmail.com> X-Mailer: git-send-email 2.10.0 In-Reply-To: <20161006212231.31440-1-killertofu@gmail.com> References: <20161006212231.31440-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 Devices following the new Custom HID mode specification (as well as even some recent component sensors which use the same standard HID usage) are capable of reporting tool ID information that we need to relay to userspace. This patch adds support for reading and relaying the tool type information, which is (unfortunately) split across two usages. We also advertise the existence of tool types beyond BTN_TOOL_PEN that might be available. Signed-off-by: Jason Gerecke --- drivers/hid/wacom_wac.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++--- drivers/hid/wacom_wac.h | 4 ++- 2 files changed, 71 insertions(+), 5 deletions(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 60f065b..f2aadc4 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -1450,6 +1450,8 @@ static int wacom_equivalent_usage(int usage) if (subpage == WACOM_HID_SP_DIGITIZER || subpage == WACOM_HID_SP_DIGITIZERINFO || usage == WACOM_HID_WD_SENSE || + usage == WACOM_HID_WD_SERIALHI || + usage == WACOM_HID_WD_TOOLTYPE || usage == WACOM_HID_WD_DISTANCE) { return usage; } @@ -1551,6 +1553,17 @@ static void wacom_wac_pen_usage_mapping(struct hid_device *hdev, features->quirks |= WACOM_QUIRK_SENSE; wacom_map_usage(input, usage, field, EV_KEY, BTN_TOOL_PEN, 0); break; + case WACOM_HID_WD_SERIALHI: + wacom_map_usage(input, usage, field, EV_ABS, ABS_MISC, 0); + set_bit(EV_KEY, input->evbit); + input_set_capability(input, EV_KEY, BTN_TOOL_PEN); + input_set_capability(input, EV_KEY, BTN_TOOL_RUBBER); + input_set_capability(input, EV_KEY, BTN_TOOL_BRUSH); + input_set_capability(input, EV_KEY, BTN_TOOL_PENCIL); + input_set_capability(input, EV_KEY, BTN_TOOL_AIRBRUSH); + input_set_capability(input, EV_KEY, BTN_TOOL_MOUSE); + input_set_capability(input, EV_KEY, BTN_TOOL_LENS); + break; case WACOM_HID_WD_FINGERWHEEL: wacom_map_usage(input, usage, field, EV_ABS, ABS_WHEEL, 0); break; @@ -1587,9 +1600,35 @@ static int wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field, case HID_DG_TIPSWITCH: wacom_wac->hid_data.tipswitch |= value; return 0; + case HID_DG_TOOLSERIALNUMBER: + wacom_wac->serial[0] = (wacom_wac->serial[0] & ~0xFFFFFFFF); + wacom_wac->serial[0] |= value; + return 0; case WACOM_HID_WD_SENSE: wacom_wac->hid_data.sense_state = value; return 0; + case WACOM_HID_WD_SERIALHI: + wacom_wac->serial[0] = (wacom_wac->serial[0] & 0xFFFFFFFF); + wacom_wac->serial[0] |= ((__u64)value) << 32; + /* + * Non-USI EMR devices may contain additional tool type + * information here. See WACOM_HID_WD_TOOLTYPE case for + * more details. + */ + if (value >> 20 == 1) { + wacom_wac->id[0] |= value & 0xFFFFF; + } + return 0; + case WACOM_HID_WD_TOOLTYPE: + /* + * Some devices (MobileStudio Pro, and possibly later + * devices as well) do not return the complete tool + * type in their WACOM_HID_WD_TOOLTYPE usage. Use a + * bitwise OR so the complete value can be built + * up over time :( + */ + wacom_wac->id[0] |= value; + return 0; } /* send pen events only when touch is up or forced out @@ -1622,26 +1661,51 @@ static void wacom_wac_pen_report(struct hid_device *hdev, bool prox = wacom_wac->hid_data.inrange_state; bool range = wacom_wac->hid_data.sense_state; - if (!wacom_wac->tool[0] && prox) /* first in prox */ + if (!wacom_wac->tool[0] && prox) { /* first in prox */ /* Going into proximity select tool */ - wacom_wac->tool[0] = wacom_wac->hid_data.invert_state ? - BTN_TOOL_RUBBER : BTN_TOOL_PEN; + if (wacom_wac->hid_data.invert_state) + wacom_wac->tool[0] = BTN_TOOL_RUBBER; + else if (wacom_wac->id[0]) + wacom_wac->tool[0] = wacom_intuos_get_tool_type(wacom_wac->id[0]); + else + wacom_wac->tool[0] = BTN_TOOL_PEN; + } /* keep pen state for touch events */ wacom_wac->shared->stylus_in_proximity = range; if (!delay_pen_events(wacom_wac) && wacom_wac->tool[0]) { + int id = wacom_wac->id[0]; + + /* + * Non-USI EMR tools should have their IDs mangled to + * match the legacy behavior of wacom_intuos_general + */ + if (wacom_wac->serial[0] >> 52 == 1) + id = wacom_intuos_id_mangle(id); + + /* + * To ensure compatibility with xf86-input-wacom, we should + * report the BTN_TOOL_* event prior to the ABS_MISC or + * MSC_SERIAL events. + */ input_report_key(input, BTN_TOUCH, wacom_wac->hid_data.tipswitch); input_report_key(input, wacom_wac->tool[0], prox); + if (wacom_wac->serial[0]) { + input_event(input, EV_MSC, MSC_SERIAL, wacom_wac->serial[0]); + input_report_abs(input, ABS_MISC, id); + } wacom_wac->hid_data.tipswitch = false; input_sync(input); } - if (!prox) + if (!prox) { wacom_wac->tool[0] = 0; + wacom_wac->id[0] = 0; + } } static void wacom_wac_finger_usage_mapping(struct hid_device *hdev, diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h index e8779c7..3926ff4 100644 --- a/drivers/hid/wacom_wac.h +++ b/drivers/hid/wacom_wac.h @@ -90,6 +90,8 @@ #define WACOM_HID_SP_DIGITIZERINFO 0x00100000 #define WACOM_HID_WD_DIGITIZER (WACOM_HID_UP_WACOMDIGITIZER | 0x01) #define WACOM_HID_WD_SENSE (WACOM_HID_UP_WACOMDIGITIZER | 0x36) +#define WACOM_HID_WD_SERIALHI (WACOM_HID_UP_WACOMDIGITIZER | 0x5c) +#define WACOM_HID_WD_TOOLTYPE (WACOM_HID_UP_WACOMDIGITIZER | 0x77) #define WACOM_HID_WD_DISTANCE (WACOM_HID_UP_WACOMDIGITIZER | 0x0132) #define WACOM_HID_WD_FINGERWHEEL (WACOM_HID_UP_WACOMDIGITIZER | 0x0d03) #define WACOM_HID_WD_DATAMODE (WACOM_HID_UP_WACOMDIGITIZER | 0x1002) @@ -247,7 +249,7 @@ struct wacom_wac { unsigned char data[WACOM_PKGLEN_MAX]; int tool[2]; int id[2]; - __u32 serial[2]; + __u64 serial[2]; bool reporting_data; struct wacom_features features; struct wacom_shared *shared;