From patchwork Tue Aug 9 21:38:56 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ping Cheng X-Patchwork-Id: 9272213 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 26AA4601C2 for ; Tue, 9 Aug 2016 21:39:15 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 095A828384 for ; Tue, 9 Aug 2016 21:39:15 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id F1B2B283E5; Tue, 9 Aug 2016 21:39:14 +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 0FE8F28384 for ; Tue, 9 Aug 2016 21:39:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932360AbcHIVjL (ORCPT ); Tue, 9 Aug 2016 17:39:11 -0400 Received: from mail-pf0-f195.google.com ([209.85.192.195]:32947 "EHLO mail-pf0-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932338AbcHIVjK (ORCPT ); Tue, 9 Aug 2016 17:39:10 -0400 Received: by mail-pf0-f195.google.com with SMTP id i6so1517360pfe.0 for ; Tue, 09 Aug 2016 14:39:09 -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; bh=qpkidn/hptZbjTyLY+GJTux4chQxkgAnS+AGjcTKUn8=; b=uHDC+ctpbaSjppan9eCyAhDcQuZTv5+cBrxmNdjB+RpOwkm3gbSN0iPFwPGtdW8jE7 WSJ3OUyDuiGwxwOk264egx07yxL6i5lBOAencgq1C83oEXqfCdZCfbua4SS82zPjFrY8 jHcji7s5FQclLkzV7FKE5QUj48DLWmHkT5q7vxdMu7+R7UsjZSA2A9+juhkr9964ND4G OcgFEa5iwaTyaZJdYC2OUD1XbbC1E30cF0TmnYAlMd2HKP2GvSNLlT16ZJZ3HWO+j8jA yustQebQudh6bsnOuolnJ5BSz6gIqV0GZvx0LNjjHf7lyCJFqH2m8kc3MUOgraJIC6kR oMRw== 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; bh=qpkidn/hptZbjTyLY+GJTux4chQxkgAnS+AGjcTKUn8=; b=JTN0V5zajoeSF4FEs31vrSnVrGjPQCntzSCkKKsNi3FiNo+E/gm7rNhgWijn/kpfk5 H+2DZ1A6pPAKh1EkGxFQiR3FeFKtaCXPLIbvTwa8evqOLXli1RK+cJugaJV1NDkXqVWC BI80REYj+PztznSnK/097K4JRDYnx8fWl3AjtJ2wRIuAbQSlWr/I3BVPxS3dhYcKETfT s1PCZSb/uANrD5GZeJjDUUYpa0oC7TgmLqgAJAnWw4WDh85L2mJeu/tXV+7eaZJ3FMWs QUkjeQ7dHx8KAwwseHmnKuDruuWyzFGs2IGaJcruMka/y6z0n2vc11t27gWMxbnhtkLB 3jRA== X-Gm-Message-State: AEkooutw2g1R7Yq9vd4iFFteMa9c/Hu7lOHjdud5JF7F78agKveRmz9/08x3Jl8uxmzbqg== X-Received: by 10.98.91.197 with SMTP id p188mr887410pfb.101.1470778749200; Tue, 09 Aug 2016 14:39:09 -0700 (PDT) Received: from localhost.net (c-24-21-228-48.hsd1.wa.comcast.net. [24.21.228.48]) by smtp.gmail.com with ESMTPSA id v124sm58219798pfb.14.2016.08.09.14.39.08 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 09 Aug 2016 14:39:08 -0700 (PDT) From: Ping Cheng X-Google-Original-From: Ping Cheng To: linux-input@vger.kernel.org, jikos@kernel.org Cc: peter.hutterer@who-t.net, benjamin.tissoires@redhat.com, Ping Cheng Subject: [PATCH v2] HID: wacom - add touch_arbitration parameter to wacom module Date: Tue, 9 Aug 2016 14:38:56 -0700 Message-Id: <1470778736-24721-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 Touch arbitration is always on in wacom.ko. However, there are touch enabled applications use both pen and touch simultaneously. We should provide an option for userland to decide if they want arbitration on or off. This patch sets default touch_arbitration to on since most userland apps are not ready to process pen and touch events simultaneously. In the future, when userland is ready to accept pen and touch events together, we will switch default touch_arbitration to off. Tested-by: Peter Hutterer Signed-off-by: Ping Cheng Reviewed-by: Benjamin Tissoires --- v2: changed inline touch_state() to report_touch_events() and use struct wacom_wac as input for both report_touch_events and delay_pen_events, as suggested by Benjamin. --- drivers/hid/wacom_wac.c | 63 ++++++++++++++++++++++++++++--------------------- 1 file changed, 36 insertions(+), 27 deletions(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 0914667..81b422a 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -34,6 +34,10 @@ */ #define WACOM_CONTACT_AREA_SCALE 2607 +static bool touch_arbitration = 1; +module_param(touch_arbitration, bool, 0644); +MODULE_PARM_DESC(touch_arbitration, " on (Y) off (N)"); + static void wacom_report_numbered_buttons(struct input_dev *input_dev, int button_count, int mask); @@ -882,6 +886,16 @@ static void wacom_remote_status_irq(struct wacom_wac *wacom_wac, size_t len) wacom_schedule_work(wacom_wac, WACOM_WORKER_REMOTE); } +static inline bool report_touch_events(struct wacom_wac *wacom) +{ + return (touch_arbitration ? !wacom->shared->stylus_in_proximity : 1); +} + +static inline bool delay_pen_events(struct wacom_wac *wacom) +{ + return (wacom->shared->touch_down && touch_arbitration); +} + static int wacom_intuos_general(struct wacom_wac *wacom) { struct wacom_features *features = &wacom->features; @@ -895,7 +909,7 @@ static int wacom_intuos_general(struct wacom_wac *wacom) data[0] != WACOM_REPORT_INTUOS_PEN) return 0; - if (wacom->shared->touch_down) + if (delay_pen_events(wacom)) return 1; /* don't report events if we don't know the tool ID */ @@ -1155,7 +1169,7 @@ static int wacom_wac_finger_count_touches(struct wacom_wac *wacom) if (touch_max == 1) return test_bit(BTN_TOUCH, input->key) && - !wacom->shared->stylus_in_proximity; + report_touch_events(wacom); for (i = 0; i < input->mt->num_slots; i++) { struct input_mt_slot *ps = &input->mt->slots[i]; @@ -1196,7 +1210,7 @@ static int wacom_24hdt_irq(struct wacom_wac *wacom) for (i = 0; i < contacts_to_send; i++) { int offset = (byte_per_packet * i) + 1; - bool touch = (data[offset] & 0x1) && !wacom->shared->stylus_in_proximity; + bool touch = (data[offset] & 0x1) && report_touch_events(wacom); int slot = input_mt_get_slot_by_key(input, data[offset + 1]); if (slot < 0) @@ -1260,7 +1274,7 @@ static int wacom_mt_touch(struct wacom_wac *wacom) for (i = 0; i < contacts_to_send; i++) { int offset = (WACOM_BYTES_PER_MT_PACKET + x_offset) * i + 3; - bool touch = (data[offset] & 0x1) && !wacom->shared->stylus_in_proximity; + bool touch = (data[offset] & 0x1) && report_touch_events(wacom); int id = get_unaligned_le16(&data[offset + 1]); int slot = input_mt_get_slot_by_key(input, id); @@ -1294,7 +1308,7 @@ static int wacom_tpc_mt_touch(struct wacom_wac *wacom) for (i = 0; i < 2; i++) { int p = data[1] & (1 << i); - bool touch = p && !wacom->shared->stylus_in_proximity; + bool touch = p && report_touch_events(wacom); input_mt_slot(input, i); input_mt_report_slot_state(input, MT_TOOL_FINGER, touch); @@ -1318,7 +1332,7 @@ static int wacom_tpc_single_touch(struct wacom_wac *wacom, size_t len) { unsigned char *data = wacom->data; struct input_dev *input = wacom->touch_input; - bool prox = !wacom->shared->stylus_in_proximity; + bool prox = report_touch_events(wacom); int x = 0, y = 0; if (wacom->features.touch_max > 1 || len > WACOM_PKGLEN_TPC2FG) @@ -1363,8 +1377,10 @@ static int wacom_tpc_pen(struct wacom_wac *wacom) /* keep pen state for touch events */ wacom->shared->stylus_in_proximity = prox; - /* send pen events only when touch is up or forced out */ - if (!wacom->shared->touch_down) { + /* send pen events only when touch is up or forced out + * or touch arbitration is off + */ + if (!delay_pen_events(wacom)) { input_report_key(input, BTN_STYLUS, data[1] & 0x02); input_report_key(input, BTN_STYLUS2, data[1] & 0x10); input_report_abs(input, ABS_X, le16_to_cpup((__le16 *)&data[2])); @@ -1506,8 +1522,10 @@ static int wacom_wac_pen_event(struct hid_device *hdev, struct hid_field *field, return 0; } - /* send pen events only when touch is up or forced out */ - if (!usage->type || wacom_wac->shared->touch_down) + /* send pen events only when touch is up or forced out + * or touch arbitration is off + */ + if (!usage->type || delay_pen_events(wacom_wac)) return 0; input_event(input, usage->type, usage->code, value); @@ -1537,8 +1555,7 @@ static void wacom_wac_pen_report(struct hid_device *hdev, /* keep pen state for touch events */ wacom_wac->shared->stylus_in_proximity = prox; - /* send pen events only when touch is up or forced out */ - if (!wacom_wac->shared->touch_down) { + if (!delay_pen_events(wacom_wac)) { input_report_key(input, BTN_TOUCH, wacom_wac->hid_data.tipswitch); input_report_key(input, wacom_wac->tool[0], prox); @@ -1609,7 +1626,7 @@ static void wacom_wac_finger_slot(struct wacom_wac *wacom_wac, struct hid_data *hid_data = &wacom_wac->hid_data; bool mt = wacom_wac->features.touch_max > 1; bool prox = hid_data->tipswitch && - !wacom_wac->shared->stylus_in_proximity; + report_touch_events(wacom_wac); wacom_wac->hid_data.num_received++; if (wacom_wac->hid_data.num_received > wacom_wac->hid_data.num_expected) @@ -1835,15 +1852,8 @@ static int wacom_bpt_touch(struct wacom_wac *wacom) for (i = 0; i < 2; i++) { int offset = (data[1] & 0x80) ? (8 * i) : (9 * i); - bool touch = data[offset + 3] & 0x80; - - /* - * Touch events need to be disabled while stylus is - * in proximity because user's hand is resting on touchpad - * and sending unwanted events. User expects tablet buttons - * to continue working though. - */ - touch = touch && !wacom->shared->stylus_in_proximity; + bool touch = report_touch_events(wacom) + && (data[offset + 3] & 0x80); input_mt_slot(input, i); input_mt_report_slot_state(input, MT_TOOL_FINGER, touch); @@ -1880,7 +1890,7 @@ static void wacom_bpt3_touch_msg(struct wacom_wac *wacom, unsigned char *data) if (slot < 0) return; - touch = touch && !wacom->shared->stylus_in_proximity; + touch = touch && report_touch_events(wacom); input_mt_slot(input, slot); input_mt_report_slot_state(input, MT_TOOL_FINGER, touch); @@ -1993,7 +2003,7 @@ static int wacom_bpt_pen(struct wacom_wac *wacom) } wacom->shared->stylus_in_proximity = prox; - if (wacom->shared->touch_down) + if (delay_pen_events(wacom)) return 0; if (prox) { @@ -2087,7 +2097,7 @@ static int wacom_bamboo_pad_touch_event(struct wacom_wac *wacom, for (id = 0; id < wacom->features.touch_max; id++) { valid = !!(prefix & BIT(id)) && - !wacom->shared->stylus_in_proximity; + report_touch_events(wacom); input_mt_slot(input, id); input_mt_report_slot_state(input, MT_TOOL_FINGER, valid); @@ -2109,8 +2119,7 @@ static int wacom_bamboo_pad_touch_event(struct wacom_wac *wacom, input_report_key(input, BTN_RIGHT, prefix & 0x80); /* keep touch state for pen event */ - wacom->shared->touch_down = !!prefix && - !wacom->shared->stylus_in_proximity; + wacom->shared->touch_down = !!prefix && report_touch_events(wacom); return 1; }