From patchwork Sun Oct 6 01:04:39 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mazin Rezk X-Patchwork-Id: 11175959 X-Patchwork-Delegate: jikos@jikos.cz Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id DA36615AB for ; Sun, 6 Oct 2019 01:04:49 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id B962B222CA for ; Sun, 6 Oct 2019 01:04:49 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=protonmail.com header.i=@protonmail.com header.b="ZmB+A7gP" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726987AbfJFBEt (ORCPT ); Sat, 5 Oct 2019 21:04:49 -0400 Received: from mail-40133.protonmail.ch ([185.70.40.133]:31767 "EHLO mail-40133.protonmail.ch" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726984AbfJFBEt (ORCPT ); Sat, 5 Oct 2019 21:04:49 -0400 Date: Sun, 06 Oct 2019 01:04:39 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com; s=default; t=1570323885; bh=lucdwIXyrI3acF9pa/XY2PlrAhFkzNyslqQIMc4ZvqA=; h=Date:To:From:Cc:Reply-To:Subject:Feedback-ID:From; b=ZmB+A7gPusQeDsS5vcpM4Rqaij4o+ROfPmEBCS02oNWn2cDnbHjjUgCXCpghxvhRs lXr88dv0H5ex3u9Tn6JLgB3ljd+BRIucAw95SzD5F4WHfMRHEkSPjiL0JhIxR1nzhV SxFlbTRfFb+3CZl75dBYx39bEdtmG1QwQfNFc9uY= To: "linux-input@vger.kernel.org" From: Mazin Rezk Cc: "benjamin.tissoires@redhat.com" , "jikos@kernel.org" , "linux-kernel@vger.kernel.org" , "lains@archlinux.org" , "mnrzk@protonmail.com" Reply-To: Mazin Rezk Subject: [PATCH v3 3/4] HID: logitech: Add feature 0x0001: FeatureSet Message-ID: Feedback-ID: 18B_FC5q-t32TXzMsVp9BgkgrdNH3iwklfW8WOrHrcxZA0WRj7JodCh5VXKxs6A3OaiHK0QNd8wi3SImKex8yQ==:Ext:ProtonMail MIME-Version: 1.0 X-Spam-Status: No, score=-0.2 required=7.0 tests=ALL_TRUSTED,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,HK_RANDOM_REPLYTO autolearn=no autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mail.protonmail.ch Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org This patch adds support for the 0x0001 (FeatureSet) feature. This feature is used to look up the feature ID of a feature index on a device and list the total count of features on the device. I also added the hidpp20_get_features function which iterates through all feature indexes on the device and stores a map of them in features an hidpp_device struct. This function runs when an HID++ 2.0 device is probed. Signed-off-by: Mazin Rezk --- drivers/hid/hid-logitech-hidpp.c | 92 ++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) -- 2.23.0 diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c index a0efa8a43213..64ac94c581aa 100644 --- a/drivers/hid/hid-logitech-hidpp.c +++ b/drivers/hid/hid-logitech-hidpp.c @@ -190,6 +190,9 @@ struct hidpp_device { struct hidpp_battery battery; struct hidpp_scroll_counter vertical_wheel_counter; + + u16 *features; + u8 feature_count; }; /* HID++ 1.0 error codes */ @@ -911,6 +914,84 @@ static int hidpp_root_get_protocol_version(struct hidpp_device *hidpp) return 0; } +/* -------------------------------------------------------------------------- */ +/* 0x0001: FeatureSet */ +/* -------------------------------------------------------------------------- */ + +#define HIDPP_PAGE_FEATURESET 0x0001 + +#define CMD_FEATURESET_GET_COUNT 0x00 +#define CMD_FEATURESET_GET_FEATURE 0x11 + +static int hidpp20_featureset_get_feature(struct hidpp_device *hidpp, + u8 featureset_index, u8 feature_index, u16 *feature_id) +{ + struct hidpp_report response; + int ret; + + ret = hidpp_send_fap_command_sync(hidpp, featureset_index, + CMD_FEATURESET_GET_FEATURE, &feature_index, 1, &response); + + if (ret) + return ret; + + *feature_id = (response.fap.params[0] << 8) | response.fap.params[1]; + + return ret; +} + +static int hidpp20_featureset_get_count(struct hidpp_device *hidpp, + u8 feature_index, u8 *count) +{ + struct hidpp_report response; + int ret; + + ret = hidpp_send_fap_command_sync(hidpp, feature_index, + CMD_FEATURESET_GET_COUNT, NULL, 0, &response); + + if (ret) + return ret; + + *count = response.fap.params[0]; + + return ret; +} + +static int hidpp20_get_features(struct hidpp_device *hidpp) +{ + int ret; + u8 featureset_index, featureset_type; + u8 i; + + hidpp->feature_count = 0; + + ret = hidpp_root_get_feature(hidpp, HIDPP_PAGE_FEATURESET, + &featureset_index, &featureset_type); + + if (ret == -ENOENT) { + hid_warn(hidpp->hid_dev, "Unable to retrieve feature set."); + return 0; + } + + if (ret) + return ret; + + ret = hidpp20_featureset_get_count(hidpp, featureset_index, + &hidpp->feature_count); + + if (ret) + return ret; + + hidpp->features = devm_kzalloc(&hidpp->hid_dev->dev, + hidpp->feature_count * sizeof(u16), GFP_KERNEL); + + for (i = 0; i < hidpp->feature_count && !ret; i++) + ret = hidpp20_featureset_get_feature(hidpp, featureset_index, + i, &(hidpp->features[i])); + + return ret; +} + /* -------------------------------------------------------------------------- */ /* 0x0005: GetDeviceNameType */ /* -------------------------------------------------------------------------- */ @@ -3625,6 +3706,17 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) hidpp_overwrite_name(hdev); } + /* Cache feature indexes and IDs to check reports faster */ + if (hidpp->protocol_major >= 2) { + if (hidpp20_get_features(hidpp)) { + hid_err(hdev, "%s:hidpp20_get_features returned error\n", + __func__); + goto hid_hw_init_fail; + } + } else { + hidpp->feature_count = 0; + } + if (connected && (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP)) { ret = wtp_get_config(hidpp); if (ret)