All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 3/4] HID: logitech: Add feature 0x0001: FeatureSet
@ 2019-10-06  1:04 Mazin Rezk
  2019-10-06 15:25 ` Filipe Laíns
  0 siblings, 1 reply; 4+ messages in thread
From: Mazin Rezk @ 2019-10-06  1:04 UTC (permalink / raw)
  To: linux-input; +Cc: benjamin.tissoires, jikos, linux-kernel, lains, mnrzk

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 <mnrzk@protonmail.com>
---
 drivers/hid/hid-logitech-hidpp.c | 92 ++++++++++++++++++++++++++++++++
 1 file changed, 92 insertions(+)

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)
--
2.23.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2019-10-07  8:07 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-06  1:04 [PATCH v3 3/4] HID: logitech: Add feature 0x0001: FeatureSet Mazin Rezk
2019-10-06 15:25 ` Filipe Laíns
2019-10-06 19:29   ` Mazin Rezk
2019-10-07  8:07     ` Filipe Laíns

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.