From patchwork Wed Aug 30 22:13:26 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Gerecke X-Patchwork-Id: 9930913 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 858296032A for ; Wed, 30 Aug 2017 22:13:35 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 77B2E287CD for ; Wed, 30 Aug 2017 22:13:35 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6C78E287D5; Wed, 30 Aug 2017 22:13:35 +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 D9456287CD for ; Wed, 30 Aug 2017 22:13:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751100AbdH3WNd (ORCPT ); Wed, 30 Aug 2017 18:13:33 -0400 Received: from mail-qk0-f196.google.com ([209.85.220.196]:37203 "EHLO mail-qk0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750980AbdH3WNc (ORCPT ); Wed, 30 Aug 2017 18:13:32 -0400 Received: by mail-qk0-f196.google.com with SMTP id m4so6434956qke.4; Wed, 30 Aug 2017 15:13:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=mLNzfP/HKoYdpHZkgNUt0afDAwuLEWMxw4aPfoLvYns=; b=o54vX7t+l8r9vgTLGBURQhNIlS7JgdjUP1nLgToPbKx4tDp+R8QIj9vywnfs13UoeW EcCqohB46Y1sqcxbUhPWoR8LsGJpvvvjsnjpOkK6zZQiFDdnceZGDvMeFg0jkS7M+lui qtzV81JEZVF1Ka8F3ha1w07wZUUy0aEGII9hFiAO1uNOGMQPnPu0eggJtqRAg3JSRV9w tCWUjg5+ir0NHqk2WtjYJtN+QbcYQTEQtD8yeWjFOaKqre8u2IgqMuM5lz4W1HCyLiup mn/0zXNtBmwlt2XQ67vbz3v4z2aJJq9qNOExkJlfrfA+l5AidQonjYQc59iiaSBZNM3s AKBg== 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:in-reply-to :references; bh=mLNzfP/HKoYdpHZkgNUt0afDAwuLEWMxw4aPfoLvYns=; b=JHTCb2oiD4i+MKNVx8ddEaRqLqsp1BpD8oYwqgRwt9ln/50drP8eL3yGTpjmTrzRBl m2F1m6FOsRVEyInoO7CkCJnU5xcYjvHVhoYN8XzL2ANNN8+W6DSLXai8Vg0xcWqpJmoa HQOB4FU+4eqIBd0qPGdVI7E6eYxotpI/TxfU40/NEuvmUEU5kU0i3skY8dp27Bf0mXK3 cdUvzlGpB6xegaGdUFy+m2ctrTiTkBFLIW6vGNDoaPaaMARlGCdxDYuIfchirFuIsUBq FDaQ+SlTaayTA8vX/3u3oO5BZiNFAHUvsO06m32ngBCoWEpUS4rXckGLattmDcKJHLTc /1cA== X-Gm-Message-State: AHPjjUjxNQZqjiabSy7eW5LmEDTwfx5BRmAwYa2alnlxuZLr1zDgK/m7 23qEUgCr9LJehhPa4fg= X-Received: by 10.233.235.69 with SMTP id b66mr1182677qkg.200.1504131211067; Wed, 30 Aug 2017 15:13:31 -0700 (PDT) Received: from wacom-arch2.corp.onewacom.com ([50.225.60.4]) by smtp.gmail.com with ESMTPSA id 137sm733018qkl.18.2017.08.30.15.13.29 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 30 Aug 2017 15:13:30 -0700 (PDT) From: Jason Gerecke To: linux-input@vger.kernel.org, Jiri Kosina Cc: stable@vger.kernel.org, Ping Cheng , Aaron Skomra , Benjamin Tissoires , Jason Gerecke , Jason Gerecke Subject: [PATCH v2 2/2] HID: wacom: Correct coordinate system of touchring and pen twist Date: Wed, 30 Aug 2017 15:13:26 -0700 Message-Id: <20170830221326.15877-2-killertofu@gmail.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20170830221326.15877-1-killertofu@gmail.com> References: <20170830221326.15877-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 The MobileStudio Pro, Cintiq Pro, and 2nd-gen Intuos Pro devices use a different coordinate system for their touchring and pen twist than prior devices. Prior devices had zero aligned to the tablet's left and would increase clockwise. Userspace expects data from the kernel to be in this old coordinate space, so adjustments are necessary. While the coordinate system for pen twist is formally defined by the HID standard, no such definition existed for the touchring at the time these tablets were introduced. Future tablets are expected to report touchring data using the same "zero-up clockwise-increasing" coordinate system defined for twist. Fixes: 50066a042d ("HID: wacom: generic: Add support for height, tilt, and twist usages") Fixes: 4922cd26f0 ("HID: wacom: Support 2nd-gen Intuos Pro's Bluetooth classic interface") Fixes: 60a2218698 ("HID: wacom: generic: add support for touchring") Cc: stable@vger.kernel.org # 4.10, 4.11 Signed-off-by: Jason Gerecke Reviewed-by: Ping Cheng --- Changes from v1: * Applied fixes to bluetooth codepath as well drivers/hid/wacom_wac.c | 73 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 68 insertions(+), 5 deletions(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index d7ca1eb9d559..d1bac66108e2 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -1227,11 +1227,17 @@ static void wacom_intuos_pro2_bt_pen(struct wacom_wac *wacom) continue; if (range) { + /* Fix rotation alignment: userspace expects zero at left */ + int16_t rotation = (int16_t)get_unaligned_le16(&frame[9]); + rotation += 1800/4; + if (rotation > 899) + rotation -= 1800; + input_report_abs(pen_input, ABS_X, get_unaligned_le16(&frame[1])); input_report_abs(pen_input, ABS_Y, get_unaligned_le16(&frame[3])); input_report_abs(pen_input, ABS_TILT_X, (char)frame[7]); input_report_abs(pen_input, ABS_TILT_Y, (char)frame[8]); - input_report_abs(pen_input, ABS_Z, (int16_t)get_unaligned_le16(&frame[9])); + input_report_abs(pen_input, ABS_Z, rotation); input_report_abs(pen_input, ABS_WHEEL, get_unaligned_le16(&frame[11])); } input_report_abs(pen_input, ABS_PRESSURE, get_unaligned_le16(&frame[5])); @@ -1319,12 +1325,19 @@ static void wacom_intuos_pro2_bt_pad(struct wacom_wac *wacom) unsigned char *data = wacom->data; int buttons = (data[282] << 1) | ((data[281] >> 6) & 0x01); - int ring = data[285]; - int prox = buttons | (ring & 0x80); + int ring = data[285] & 0x7F; + bool ringstatus = data[285] & 0x80; + bool prox = buttons || ringstatus; + + /* Fix touchring data: userspace expects 0 at left and increasing clockwise */ + ring = 71 - ring; + ring += 3*72/16; + if (ring > 71) + ring -= 72; wacom_report_numbered_buttons(pad_input, 9, buttons); - input_report_abs(pad_input, ABS_WHEEL, (ring & 0x80) ? (ring & 0x7f) : 0); + input_report_abs(pad_input, ABS_WHEEL, ringstatus ? ring : 0); input_report_key(pad_input, wacom->tool[1], prox ? 1 : 0); input_report_abs(pad_input, ABS_MISC, prox ? PAD_DEVICE_ID : 0); @@ -1616,6 +1629,20 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len) return 0; } +static int wacom_offset_rotation(struct input_dev *input, struct hid_usage *usage, + int value, int num, int denom) +{ + struct input_absinfo *abs = &input->absinfo[usage->code]; + int range = (abs->maximum - abs->minimum + 1); + + value += num*range/denom; + if (value > abs->maximum) + value -= range; + else if (value < abs->minimum) + value += range; + return value; +} + int wacom_equivalent_usage(int usage) { if ((usage & HID_USAGE_PAGE) == WACOM_HID_UP_WACOMDIGITIZER) { @@ -1898,6 +1925,7 @@ static void wacom_wac_pad_event(struct hid_device *hdev, struct hid_field *field unsigned equivalent_usage = wacom_equivalent_usage(usage->hid); int i; bool is_touch_on = value; + bool do_report = false; /* * Avoid reporting this event and setting inrange_state if this usage @@ -1912,6 +1940,29 @@ static void wacom_wac_pad_event(struct hid_device *hdev, struct hid_field *field } switch (equivalent_usage) { + case WACOM_HID_WD_TOUCHRING: + /* + * Userspace expects touchrings to increase in value with + * clockwise gestures and have their zero point at the + * tablet's left. HID events "should" be clockwise- + * increasing and zero at top, though the MobileStudio + * Pro and 2nd-gen Intuos Pro don't do this... + */ + if (hdev->vendor == 0x56a && + (hdev->product == 0x34d || hdev->product == 0x34e || /* MobileStudio Pro */ + hdev->product == 0x357 || hdev->product == 0x358)) { /* Intuos Pro 2 */ + value = (field->logical_maximum - value); + + if (hdev->product == 0x357 || hdev->product == 0x358) + value = wacom_offset_rotation(input, usage, value, 3, 16); + else if (hdev->product == 0x34d || hdev->product == 0x34e) + value = wacom_offset_rotation(input, usage, value, 1, 2); + } + else { + value = wacom_offset_rotation(input, usage, value, 1, 4); + } + do_report = true; + break; case WACOM_HID_WD_TOUCHRINGSTATUS: if (!value) input_event(input, usage->type, usage->code, 0); @@ -1945,10 +1996,14 @@ static void wacom_wac_pad_event(struct hid_device *hdev, struct hid_field *field value, i); /* fall through*/ default: + do_report = true; + break; + } + + if (do_report) { input_event(input, usage->type, usage->code, value); if (value) wacom_wac->hid_data.pad_input_event_flag = true; - break; } } @@ -2089,6 +2144,14 @@ static void wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field wacom_wac->serial[0] = (wacom_wac->serial[0] & ~0xFFFFFFFFULL); wacom_wac->serial[0] |= (__u32)value; return; + case HID_DG_TWIST: + /* + * Userspace expects pen twist to have its zero point when + * the buttons/finger is on the tablet's left. HID values + * are zero when buttons are toward the top. + */ + value = wacom_offset_rotation(input, usage, value, 1, 4); + break; case WACOM_HID_WD_SENSE: wacom_wac->hid_data.sense_state = value; return;