From patchwork Tue Mar 6 18:48:34 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Aaron Armstrong Skomra X-Patchwork-Id: 10262401 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 E94EB60211 for ; Tue, 6 Mar 2018 18:50:53 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DA38A29154 for ; Tue, 6 Mar 2018 18:50:53 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C947629160; Tue, 6 Mar 2018 18:50:53 +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 12CFE2913B for ; Tue, 6 Mar 2018 18:50:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753940AbeCFSut (ORCPT ); Tue, 6 Mar 2018 13:50:49 -0500 Received: from mail-pg0-f67.google.com ([74.125.83.67]:35892 "EHLO mail-pg0-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753928AbeCFSus (ORCPT ); Tue, 6 Mar 2018 13:50:48 -0500 Received: by mail-pg0-f67.google.com with SMTP id i14so8629923pgv.3 for ; Tue, 06 Mar 2018 10:50:48 -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:in-reply-to:references; bh=BTm+5R8yNWOxaRXQan3hYQ5N2v82RY0RAhvGd7fxgF0=; b=uDIU7eKum33CSbCkJLZa7oaEPWCs1Sf+pQvRsralrKuK5udAmiikn1SmL+s8JK/H0B 6LC96lVbocskBDCPo7Y0ZGkCvWoXHWTj65N4sbVObzLzQMvDsu/RLXbY86OTXxczl/Xf /GsvCGMGuZNeCM0mvph6CPFO/tTzFgcvzC1MtgDxwVxauyQ/uqf4hmlB9CxJbjk5L1pe oCGXd7C3yIxNbw/qjiOZJOjvGbtsIWl9UQYUsatRIWXmh9HlDW2dp6uAD8lwtlxu947z a4QSF/RKjVoxaZWqRf3q1ahL4xwZILS5Q/+xoX7dwkIJvnYbAWoyZJCHaP+YLR/iZtON YGAg== 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=BTm+5R8yNWOxaRXQan3hYQ5N2v82RY0RAhvGd7fxgF0=; b=qL3Tc8m9z+EniIo/1Yx5VhiERy4aXrCcvzFgwmYXC/ParN+23wmF5jpAzc/H3R/puj Ul2uiLvG3eWmUUQGoI3VIo0g2tFm7RTElSU7+evZ3axQrxn+y854JIjfPxFbZhae5hx6 4PkkZaWUINvz6WzSkn7hCBGM728xbr4A7o3ndZm8CQJ8k3qR3akPXtQs2m7KlwfJJaNB nnpnmdffhnwnUPUcjwlrxlRw4YW08u/VNTm/B4soglfZd17u37Bivkvf4f82FdXyM7lf 3QTxpILVRUh4crD0ZOVY81UodMBjoChyGv6JJGD89ewCXiuIOFMHQ0eH8khyh+FWB5L8 heWw== X-Gm-Message-State: APf1xPCroV1vQIsBRlR44LbUcz3osswmE6loAEWxJl0zXFlaFopeh9F/ GtoVvBLMxyYFojs9cUCqJMItyQ== X-Google-Smtp-Source: AG47ELuCMstATR0g1hsdCoxRpR+CKXBrVRzQ9G+eGmu9kVZstkyatLlNjWPm9Hn145VARzhCL9ThfQ== X-Received: by 10.98.159.209 with SMTP id v78mr19609513pfk.49.1520362247092; Tue, 06 Mar 2018 10:50:47 -0800 (PST) Received: from juhua.Home (184-100-226-242.ptld.qwest.net. [184.100.226.242]) by smtp.googlemail.com with ESMTPSA id l2sm25503469pgu.46.2018.03.06.10.50.45 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 06 Mar 2018 10:50:46 -0800 (PST) From: Aaron Armstrong Skomra To: linux-input@vger.kernel.org, pinglinux@gmail.com, killertofu@gmail.com, jkosina@suse.cz Cc: Aaron Armstrong Skomra Subject: [PATCH 2/3] HID: wacom: generic: Support multiple tools per report Date: Tue, 6 Mar 2018 10:48:34 -0800 Message-Id: <1520362115-21431-2-git-send-email-skomra@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1520362115-21431-1-git-send-email-skomra@gmail.com> References: <1520362115-21431-1-git-send-email-skomra@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 Some Wacom devices contain contain Pen and Pad usages in the same report. Future devices of this type may utilize HID Descriptors. The generic code path of the Wacom driver previously assumed pen, touch, and pad reports were delivered in separate reports. This patch adds support for processing each collection of a report separately, in order to support reports with multiple tools. Signed-off-by: Aaron Armstrong Skomra Reviewed-by: Ping Cheng Reviewed-by: Jason Gerecke --- drivers/hid/wacom_wac.c | 94 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 68 insertions(+), 26 deletions(-) diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index d532c1ebf2ee..7a0a7f67e7ed 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -2072,7 +2072,7 @@ static void wacom_wac_pad_pre_report(struct hid_device *hdev, } static void wacom_wac_pad_report(struct hid_device *hdev, - struct hid_report *report) + struct hid_report *report, struct hid_field *field) { struct wacom *wacom = hid_get_drvdata(hdev); struct wacom_wac *wacom_wac = &wacom->wacom_wac; @@ -2080,7 +2080,7 @@ static void wacom_wac_pad_report(struct hid_device *hdev, bool active = wacom_wac->hid_data.inrange_state != 0; /* report prox for expresskey events */ - if ((wacom_equivalent_usage(report->field[0]->physical) == HID_DG_TABLETFUNCTIONKEY) && + if ((wacom_equivalent_usage(field->physical) == HID_DG_TABLETFUNCTIONKEY) && wacom_wac->hid_data.pad_input_event_flag) { input_event(input, EV_ABS, ABS_MISC, active ? PAD_DEVICE_ID : 0); input_sync(input); @@ -2627,11 +2627,13 @@ void wacom_wac_event(struct hid_device *hdev, struct hid_field *field, wacom_wac_finger_event(hdev, field, usage, value); } -static void wacom_report_events(struct hid_device *hdev, struct hid_report *report) +static void wacom_report_events(struct hid_device *hdev, + struct hid_report *report, int collection_index, + int field_index) { int r; - for (r = 0; r < report->maxfield; r++) { + for (r = field_index; r < report->maxfield; r++) { struct hid_field *field; unsigned count, n; @@ -2641,30 +2643,23 @@ static void wacom_report_events(struct hid_device *hdev, struct hid_report *repo if (!(HID_MAIN_ITEM_VARIABLE & field->flags)) continue; - for (n = 0; n < count; n++) - wacom_wac_event(hdev, field, &field->usage[n], field->value[n]); + for (n = 0 ; n < count; n++) { + if (field->usage[n].collection_index == collection_index) + wacom_wac_event(hdev, field, &field->usage[n], + field->value[n]); + else + return; + } } } -void wacom_wac_report(struct hid_device *hdev, struct hid_report *report) +int wacom_wac_collection(struct hid_device *hdev, struct hid_report *report, + int collection_index, struct hid_field *field, + int field_index) { struct wacom *wacom = hid_get_drvdata(hdev); - struct wacom_wac *wacom_wac = &wacom->wacom_wac; - struct hid_field *field = report->field[0]; - - if (wacom_wac->features.type != HID_GENERIC) - return; - - wacom_wac_battery_pre_report(hdev, report); - - if (WACOM_PAD_FIELD(field) && wacom->wacom_wac.pad_input) - wacom_wac_pad_pre_report(hdev, report); - else if (WACOM_PEN_FIELD(field) && wacom->wacom_wac.pen_input) - wacom_wac_pen_pre_report(hdev, report); - else if (WACOM_FINGER_FIELD(field) && wacom->wacom_wac.touch_input) - wacom_wac_finger_pre_report(hdev, report); - wacom_report_events(hdev, report); + wacom_report_events(hdev, report, collection_index, field_index); /* * Non-input reports may be sent prior to the device being @@ -2674,16 +2669,63 @@ void wacom_wac_report(struct hid_device *hdev, struct hid_report *report) * processing functions. */ if (report->type != HID_INPUT_REPORT) - return; - - wacom_wac_battery_report(hdev, report); + return -1; if (WACOM_PAD_FIELD(field) && wacom->wacom_wac.pad_input) - wacom_wac_pad_report(hdev, report); + wacom_wac_pad_report(hdev, report, field); else if (WACOM_PEN_FIELD(field) && wacom->wacom_wac.pen_input) wacom_wac_pen_report(hdev, report); else if (WACOM_FINGER_FIELD(field) && wacom->wacom_wac.touch_input) wacom_wac_finger_report(hdev, report); + + return 0; +} + +void wacom_wac_report(struct hid_device *hdev, struct hid_report *report) +{ + struct wacom *wacom = hid_get_drvdata(hdev); + struct wacom_wac *wacom_wac = &wacom->wacom_wac; + struct hid_field *field; + bool pad_in_hid_field = false, pen_in_hid_field = false, + finger_in_hid_field = false; + int r; + int prev_collection = -1; + + if (wacom_wac->features.type != HID_GENERIC) + return; + + for (r = 0; r < report->maxfield; r++) { + field = report->field[r]; + + if (WACOM_PAD_FIELD(field)) + pad_in_hid_field = true; + if (WACOM_PEN_FIELD(field)) + pen_in_hid_field = true; + if (WACOM_FINGER_FIELD(field)) + finger_in_hid_field = true; + } + + wacom_wac_battery_pre_report(hdev, report); + + if (pad_in_hid_field && wacom->wacom_wac.pad_input) + wacom_wac_pad_pre_report(hdev, report); + if (pen_in_hid_field && wacom->wacom_wac.pen_input) + wacom_wac_pen_pre_report(hdev, report); + if (finger_in_hid_field && wacom->wacom_wac.touch_input) + wacom_wac_finger_pre_report(hdev, report); + + for (r = 0; r < report->maxfield; r++) { + field = report->field[r]; + + if (field->usage[0].collection_index != prev_collection) { + if (wacom_wac_collection(hdev, report, + field->usage[0].collection_index, field, r) < 0) + return; + prev_collection = field->usage[0].collection_index; + } + } + + wacom_wac_battery_report(hdev, report); } static int wacom_bpt_touch(struct wacom_wac *wacom)