Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1572385 > unrolled thread
| Started by | Benjamin Tissoires <benjamin.tissoires@redhat.com> |
|---|---|
| First post | 2017-02-02 15:20 +0100 |
| Last post | 2017-02-02 15:20 +0100 |
| Articles | 14 — 2 participants |
Back to article view | Back to linux.kernel
[PATCH v2 00/15] Report power supply from hid-logitech-hidpp Benjamin Tissoires <benjamin.tissoires@redhat.com> - 2017-02-02 15:20 +0100
[PATCH v2 08/15] HID: logitech-hidpp: add support for battery status for the K750 Benjamin Tissoires <benjamin.tissoires@redhat.com> - 2017-02-02 15:20 +0100
[PATCH v2 13/15] HID: logitech-hidpp: rework probe path for unifying devices Benjamin Tissoires <benjamin.tissoires@redhat.com> - 2017-02-02 15:20 +0100
[PATCH v2 05/15] HID: logitech-hidpp: forward device info in power_supply Benjamin Tissoires <benjamin.tissoires@redhat.com> - 2017-02-02 15:20 +0100
Re: [PATCH v2 05/15] HID: logitech-hidpp: forward device info in power_supply Bastien Nocera <hadess@hadess.net> - 2017-02-03 16:10 +0100
Re: [PATCH v2 05/15] HID: logitech-hidpp: forward device info in power_supply Benjamin Tissoires <benjamin.tissoires@redhat.com> - 2017-02-07 09:40 +0100
[PATCH v2 12/15] HID: logitech-hidpp: do not query the name through HID++ for 1.0 devices Benjamin Tissoires <benjamin.tissoires@redhat.com> - 2017-02-02 15:20 +0100
[PATCH v2 15/15] HID: logitech-hidpp: rework hidpp_connect_event() Benjamin Tissoires <benjamin.tissoires@redhat.com> - 2017-02-02 15:20 +0100
[PATCH v2 06/15] HID: logitech-hidpp: create the battery for all types of HID++ devices Benjamin Tissoires <benjamin.tissoires@redhat.com> - 2017-02-02 15:20 +0100
[PATCH v2 10/15] HID: logitech-hidpp: notify battery on connect Benjamin Tissoires <benjamin.tissoires@redhat.com> - 2017-02-02 15:20 +0100
[PATCH v2 01/15] HID: logitech-dj: allow devices to request full pairing information Benjamin Tissoires <benjamin.tissoires@redhat.com> - 2017-02-02 15:20 +0100
[PATCH v2 14/15] HID: logitech-hidpp: retrieve the HID++ device name when available Benjamin Tissoires <benjamin.tissoires@redhat.com> - 2017-02-02 15:20 +0100
[PATCH v2 09/15] HID: logitech-hidpp: enable HID++ 1.0 battery reporting Benjamin Tissoires <benjamin.tissoires@redhat.com> - 2017-02-02 15:20 +0100
[PATCH v2 07/15] HID: logitech-hidpp: return an error if the feature is not present Benjamin Tissoires <benjamin.tissoires@redhat.com> - 2017-02-02 15:20 +0100
| From | Benjamin Tissoires <benjamin.tissoires@redhat.com> |
|---|---|
| Date | 2017-02-02 15:20 +0100 |
| Subject | [PATCH v2 00/15] Report power supply from hid-logitech-hidpp |
| Message-ID | <t6qoV-58b-3@gated-at.bofh.it> |
Hi,
This is the v2 of the series which aims at adding kernel support for the
power_supply reporting of the HID++ devices.
I updated the series with the comments from Bastien:
- fixed K750 battery state
- fixed the model names of the devices
I also stripped out the less than optimal patches that added plain HID++ for
USB devices (need to work on that later), and I fixed a couple of issues
along the road.
Cheers,
Benjamin
Bastien Nocera (1):
HID: logitech-hidpp: Add scope to battery
Benjamin Tissoires (14):
HID: logitech-dj: allow devices to request full pairing information
HID: logitech-hidpp: make sure we only register one battery per device
HID: logitech-hidpp: battery: remove overloads and provide ONLINE
HID: logitech-hidpp: forward device info in power_supply
HID: logitech-hidpp: create the battery for all types of HID++ devices
HID: logitech-hidpp: return an error if the feature is not present
HID: logitech-hidpp: add support for battery status for the K750
HID: logitech-hidpp: enable HID++ 1.0 battery reporting
HID: logitech-hidpp: notify battery on connect
HID: logitech-hidpp: add a sysfs file to tell we support power_supply
HID: logitech-hidpp: do not query the name through HID++ for 1.0
devices
HID: logitech-hidpp: rework probe path for unifying devices
HID: logitech-hidpp: retrieve the HID++ device name when available
HID: logitech-hidpp: rework hidpp_connect_event()
drivers/hid/hid-logitech-dj.c | 17 +-
drivers/hid/hid-logitech-hidpp.c | 554 +++++++++++++++++++++++++++++++++------
2 files changed, 480 insertions(+), 91 deletions(-)
--
2.9.3
[toc] | [next] | [standalone]
| From | Benjamin Tissoires <benjamin.tissoires@redhat.com> |
|---|---|
| Date | 2017-02-02 15:20 +0100 |
| Subject | [PATCH v2 08/15] HID: logitech-hidpp: add support for battery status for the K750 |
| Message-ID | <t6qoX-58b-33@gated-at.bofh.it> |
| In reply to | #1572385 |
The Solar Keyboard uses a different feature to report the battery level.
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
---
changes in v2:
* update state according to lux information
* do not update Lux if the event does not contain lux information
---
drivers/hid/hid-logitech-hidpp.c | 97 +++++++++++++++++++++++++++++++++++++++-
1 file changed, 95 insertions(+), 2 deletions(-)
diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c
index f7b2589..ec3f47c 100644
--- a/drivers/hid/hid-logitech-hidpp.c
+++ b/drivers/hid/hid-logitech-hidpp.c
@@ -56,6 +56,7 @@ MODULE_PARM_DESC(disable_tap_to_click,
#define HIDPP_QUIRK_CLASS_M560 BIT(1)
#define HIDPP_QUIRK_CLASS_K400 BIT(2)
#define HIDPP_QUIRK_CLASS_G920 BIT(3)
+#define HIDPP_QUIRK_CLASS_K750 BIT(4)
/* bits 2..20 are reserved for classes */
/* #define HIDPP_QUIRK_CONNECT_EVENTS BIT(21) disabled */
@@ -113,6 +114,7 @@ struct hidpp_report {
struct hidpp_battery {
u8 feature_index;
+ u8 solar_feature_index;
struct power_supply_desc desc;
struct power_supply *ps;
char name[64];
@@ -704,7 +706,7 @@ static int hidpp20_query_battery_info(struct hidpp_device *hidpp)
int ret;
int status, level, next_level;
- if (hidpp->battery.feature_index == 0) {
+ if (hidpp->battery.feature_index == 0xff) {
ret = hidpp_root_get_feature(hidpp,
HIDPP_PAGE_BATTERY_LEVEL_STATUS,
&hidpp->battery.feature_index,
@@ -810,6 +812,83 @@ static int hidpp_battery_get_property(struct power_supply *psy,
}
/* -------------------------------------------------------------------------- */
+/* 0x4301: Solar Keyboard */
+/* -------------------------------------------------------------------------- */
+
+#define HIDPP_PAGE_SOLAR_KEYBOARD 0x4301
+
+#define CMD_SOLAR_SET_LIGHT_MEASURE 0x00
+
+#define EVENT_SOLAR_BATTERY_BROADCAST 0x00
+#define EVENT_SOLAR_BATTERY_LIGHT_MEASURE 0x10
+#define EVENT_SOLAR_CHECK_LIGHT_BUTTON 0x20
+
+static int hidpp_solar_request_battery_event(struct hidpp_device *hidpp)
+{
+ struct hidpp_report response;
+ u8 params[2] = { 1, 1 };
+ u8 feature_type;
+ int ret;
+
+ if (hidpp->battery.feature_index == 0xff) {
+ ret = hidpp_root_get_feature(hidpp,
+ HIDPP_PAGE_SOLAR_KEYBOARD,
+ &hidpp->battery.solar_feature_index,
+ &feature_type);
+ if (ret)
+ return ret;
+ }
+
+ ret = hidpp_send_fap_command_sync(hidpp,
+ hidpp->battery.solar_feature_index,
+ CMD_SOLAR_SET_LIGHT_MEASURE,
+ params, 2, &response);
+ if (ret > 0) {
+ hid_err(hidpp->hid_dev, "%s: received protocol error 0x%02x\n",
+ __func__, ret);
+ return -EPROTO;
+ }
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int hidpp_solar_battery_event(struct hidpp_device *hidpp,
+ u8 *data, int size)
+{
+ struct hidpp_report *report = (struct hidpp_report *)data;
+ int level, lux, status;
+
+ if (report->fap.feature_index != hidpp->battery.solar_feature_index ||
+ !(report->fap.funcindex_clientid == EVENT_SOLAR_BATTERY_BROADCAST ||
+ report->fap.funcindex_clientid == EVENT_SOLAR_BATTERY_LIGHT_MEASURE ||
+ report->fap.funcindex_clientid == EVENT_SOLAR_CHECK_LIGHT_BUTTON))
+ return 0;
+
+ level = report->fap.params[0];
+
+ if (report->fap.funcindex_clientid == EVENT_SOLAR_BATTERY_LIGHT_MEASURE) {
+ lux = (report->fap.params[1] << 8) | report->fap.params[2];
+ if (lux > 200)
+ status = POWER_SUPPLY_STATUS_CHARGING;
+ else
+ status = POWER_SUPPLY_STATUS_DISCHARGING;
+ } else {
+ status = hidpp->battery.status;
+ }
+
+ if (level != hidpp->battery.level || status != hidpp->battery.status) {
+ hidpp->battery.level = level;
+ hidpp->battery.status = status;
+ if (hidpp->battery.ps)
+ power_supply_changed(hidpp->battery.ps);
+ }
+
+ return 0;
+}
+
+/* -------------------------------------------------------------------------- */
/* 0x6010: Touchpad FW items */
/* -------------------------------------------------------------------------- */
@@ -2256,6 +2335,9 @@ static int hidpp_raw_event(struct hid_device *hdev, struct hid_report *report,
ret = hidpp20_battery_event(hidpp, data, size);
if (ret != 0)
return ret;
+ ret = hidpp_solar_battery_event(hidpp, data, size);
+ if (ret != 0)
+ return ret;
}
if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP)
@@ -2278,8 +2360,15 @@ static int hidpp_initialize_battery(struct hidpp_device *hidpp)
if (hidpp->battery.ps)
return 0;
+ hidpp->battery.feature_index = 0xff;
+ hidpp->battery.solar_feature_index = 0xff;
+
if (hidpp->protocol_major >= 2) {
- ret = hidpp20_query_battery_info(hidpp);
+ if (hidpp->quirks & HIDPP_QUIRK_CLASS_K750)
+ ret = hidpp_solar_request_battery_event(hidpp);
+ else
+ ret = hidpp20_query_battery_info(hidpp);
+
if (ret)
return ret;
hidpp->quirks |= HIDPP_QUIRK_HIDPP20_BATTERY;
@@ -2608,6 +2697,10 @@ static const struct hid_device_id hidpp_devices[] = {
HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE,
USB_VENDOR_ID_LOGITECH, 0x4024),
.driver_data = HIDPP_QUIRK_CLASS_K400 },
+ { /* Solar Keyboard Logitech K750 */
+ HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE,
+ USB_VENDOR_ID_LOGITECH, 0x4002),
+ .driver_data = HIDPP_QUIRK_CLASS_K750 },
{ HID_DEVICE(BUS_USB, HID_GROUP_LOGITECH_DJ_DEVICE,
USB_VENDOR_ID_LOGITECH, HID_ANY_ID)},
--
2.9.3
[toc] | [prev] | [next] | [standalone]
| From | Benjamin Tissoires <benjamin.tissoires@redhat.com> |
|---|---|
| Date | 2017-02-02 15:20 +0100 |
| Subject | [PATCH v2 13/15] HID: logitech-hidpp: rework probe path for unifying devices |
| Message-ID | <t6qoW-58b-21@gated-at.bofh.it> |
| In reply to | #1572385 |
Unifying devices are different from others because they can probed
while not connected. So we need to talk to the receiver to get some
extra information like the device name and the serial.
Instead of having conditionals while attempting to read the device name
from HID++ 2.0, have a special init path for them.
Store the retrieved serial in hdev->uniq.
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
---
changes in v2:
* only overwrite the name when the input is delayed (was causing different
name depending of the connect stat of the device while probing)
---
drivers/hid/hid-logitech-hidpp.c | 84 +++++++++++++++++++++++++++++++---------
1 file changed, 65 insertions(+), 19 deletions(-)
diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c
index 225cf96..416d9e6 100644
--- a/drivers/hid/hid-logitech-hidpp.c
+++ b/drivers/hid/hid-logitech-hidpp.c
@@ -65,6 +65,7 @@ MODULE_PARM_DESC(disable_tap_to_click,
#define HIDPP_QUIRK_FORCE_OUTPUT_REPORTS BIT(24)
#define HIDPP_QUIRK_HIDPP20_BATTERY BIT(25)
#define HIDPP_QUIRK_HIDPP10_BATTERY BIT(26)
+#define HIDPP_QUIRK_UNIFYING BIT(27)
#define HIDPP_QUIRK_DELAYED_INIT HIDPP_QUIRK_NO_HIDINPUT
@@ -586,14 +587,14 @@ static int hidpp10_battery_event(struct hidpp_device *hidpp, u8 *data, int size)
}
#define HIDPP_REG_PAIRING_INFORMATION 0xB5
-#define DEVICE_NAME 0x40
+#define HIDPP_EXTENDED_PAIRING 0x30
+#define HIDPP_DEVICE_NAME 0x40
-static char *hidpp_get_unifying_name(struct hidpp_device *hidpp_dev)
+static char *hidpp_unifying_get_name(struct hidpp_device *hidpp_dev)
{
struct hidpp_report response;
int ret;
- /* hid-logitech-dj is in charge of setting the right device index */
- u8 params[1] = { DEVICE_NAME };
+ u8 params[1] = { HIDPP_DEVICE_NAME };
char *name;
int len;
@@ -622,6 +623,52 @@ static char *hidpp_get_unifying_name(struct hidpp_device *hidpp_dev)
return name;
}
+static u32 hidpp_unifying_get_serial(struct hidpp_device *hidpp)
+{
+ struct hidpp_report response;
+ int ret;
+ u8 params[1] = { HIDPP_EXTENDED_PAIRING };
+
+ ret = hidpp_send_rap_command_sync(hidpp,
+ REPORT_ID_HIDPP_SHORT,
+ HIDPP_GET_LONG_REGISTER,
+ HIDPP_REG_PAIRING_INFORMATION,
+ params, 1, &response);
+ if (ret)
+ return 0;
+
+ /*
+ * We don't care about LE or BE, we will output it as a string
+ * with %4phD, so we need to keep the order.
+ */
+ return *((u32 *)&response.rap.params[1]);
+}
+
+static int hidpp_unifying_init(struct hidpp_device *hidpp)
+{
+ struct hid_device *hdev = hidpp->hid_dev;
+ const char *name;
+ u32 serial;
+
+ serial = hidpp_unifying_get_serial(hidpp);
+ if (serial == 0)
+ return -EIO;
+
+ name = hidpp_unifying_get_name(hidpp);
+ if (!name)
+ return -EIO;
+
+ snprintf(hdev->name, sizeof(hdev->name), "%s", name);
+ dbg_hid("HID++ Unifying: Got name: %s\n", name);
+
+ snprintf(hdev->uniq, sizeof(hdev->uniq), "%04x-%4phD",
+ hdev->product, &serial);
+ dbg_hid("HID++ Unifying: Got serial: %s\n", hdev->uniq);
+
+ kfree(name);
+ return 0;
+}
+
/* -------------------------------------------------------------------------- */
/* 0x0000: Root */
/* -------------------------------------------------------------------------- */
@@ -2602,22 +2649,15 @@ static int hidpp_initialize_battery(struct hidpp_device *hidpp)
return ret;
}
-static void hidpp_overwrite_name(struct hid_device *hdev, bool use_unifying)
+static void hidpp_overwrite_name(struct hid_device *hdev)
{
struct hidpp_device *hidpp = hid_get_drvdata(hdev);
char *name;
- if (use_unifying)
- /*
- * the device is connected through an Unifying receiver, and
- * might not be already connected.
- * Ask the receiver for its name.
- */
- name = hidpp_get_unifying_name(hidpp);
- else if (hidpp->protocol_major < 2)
+ if (hidpp->protocol_major < 2)
return;
- else
- name = hidpp_get_device_name(hidpp);
+
+ name = hidpp_get_device_name(hidpp);
if (!name) {
hid_err(hdev, "unable to retrieve the name of the device");
@@ -2781,6 +2821,9 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
hidpp->quirks = id->driver_data;
+ if (id->group == HID_GROUP_LOGITECH_DJ_DEVICE)
+ hidpp->quirks |= HIDPP_QUIRK_UNIFYING;
+
if (disable_raw_mode) {
hidpp->quirks &= ~HIDPP_QUIRK_CLASS_WTP;
hidpp->quirks &= ~HIDPP_QUIRK_NO_HIDINPUT;
@@ -2838,8 +2881,12 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
/* Allow incoming packets */
hid_device_io_start(hdev);
+ if (hidpp->quirks & HIDPP_QUIRK_UNIFYING)
+ hidpp_unifying_init(hidpp);
+
connected = hidpp_is_connected(hidpp);
- if (id->group != HID_GROUP_LOGITECH_DJ_DEVICE) {
+ atomic_set(&hidpp->connected, connected);
+ if (!(hidpp->quirks & HIDPP_QUIRK_UNIFYING)) {
if (!connected) {
ret = -ENODEV;
hid_err(hdev, "Device not connected");
@@ -2848,10 +2895,9 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
hid_info(hdev, "HID++ %u.%u device connected.\n",
hidpp->protocol_major, hidpp->protocol_minor);
- }
- hidpp_overwrite_name(hdev, id->group == HID_GROUP_LOGITECH_DJ_DEVICE);
- atomic_set(&hidpp->connected, connected);
+ hidpp_overwrite_name(hdev);
+ }
if (connected && (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP)) {
ret = wtp_get_config(hidpp);
--
2.9.3
[toc] | [prev] | [next] | [standalone]
| From | Benjamin Tissoires <benjamin.tissoires@redhat.com> |
|---|---|
| Date | 2017-02-02 15:20 +0100 |
| Subject | [PATCH v2 05/15] HID: logitech-hidpp: forward device info in power_supply |
| Message-ID | <t6qoW-58b-23@gated-at.bofh.it> |
| In reply to | #1572385 |
Better forwarding the device name, manufacturer and serial to upower.
Note that serial is still empty, it will be filled in a later patch
in this series.
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
---
changes in v2:
* model stripped of Logitech
* vendor Logitech -> Logitech, Inc.
* use hidpp->name for the power_supply name (so that it can be overloaded)
---
drivers/hid/hid-logitech-hidpp.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c
index 3c57886..6124481 100644
--- a/drivers/hid/hid-logitech-hidpp.c
+++ b/drivers/hid/hid-logitech-hidpp.c
@@ -758,6 +758,9 @@ static enum power_supply_property hidpp_battery_props[] = {
POWER_SUPPLY_PROP_STATUS,
POWER_SUPPLY_PROP_CAPACITY,
POWER_SUPPLY_PROP_SCOPE,
+ POWER_SUPPLY_PROP_MODEL_NAME,
+ POWER_SUPPLY_PROP_MANUFACTURER,
+ POWER_SUPPLY_PROP_SERIAL_NUMBER,
};
static int hidpp_battery_get_property(struct power_supply *psy,
@@ -783,6 +786,18 @@ static int hidpp_battery_get_property(struct power_supply *psy,
hidpp->battery.status ==
POWER_SUPPLY_STATUS_FULL;
break;
+ case POWER_SUPPLY_PROP_MODEL_NAME:
+ if (!strncmp(hidpp->name, "Logitech ", 9))
+ val->strval = hidpp->name + 9;
+ else
+ val->strval = hidpp->name;
+ break;
+ case POWER_SUPPLY_PROP_MANUFACTURER:
+ val->strval = "Logitech, Inc.";
+ break;
+ case POWER_SUPPLY_PROP_SERIAL_NUMBER:
+ val->strval = hidpp->hid_dev->uniq;
+ break;
default:
ret = -EINVAL;
break;
--
2.9.3
[toc] | [prev] | [next] | [standalone]
| From | Bastien Nocera <hadess@hadess.net> |
|---|---|
| Date | 2017-02-03 16:10 +0100 |
| Subject | Re: [PATCH v2 05/15] HID: logitech-hidpp: forward device info in power_supply |
| Message-ID | <t6NES-38j-29@gated-at.bofh.it> |
| In reply to | #1572389 |
On Thu, 2017-02-02 at 15:12 +0100, Benjamin Tissoires wrote: > + case POWER_SUPPLY_PROP_MANUFACTURER: > + val->strval = "Logitech, Inc."; I don't like this change. I'd prefer the concatenated manufacturer and model strings leading to user-friendly strings, and "Logitech T650" is better than "Logitech, Inc. T650".
[toc] | [prev] | [next] | [standalone]
| From | Benjamin Tissoires <benjamin.tissoires@redhat.com> |
|---|---|
| Date | 2017-02-07 09:40 +0100 |
| Subject | Re: [PATCH v2 05/15] HID: logitech-hidpp: forward device info in power_supply |
| Message-ID | <t89tD-rN-19@gated-at.bofh.it> |
| In reply to | #1573140 |
Hi Bastien, On Feb 03 2017 or thereabouts, Bastien Nocera wrote: > On Thu, 2017-02-02 at 15:12 +0100, Benjamin Tissoires wrote: > > + case POWER_SUPPLY_PROP_MANUFACTURER: > > + val->strval = "Logitech, Inc."; > > I don't like this change. I'd prefer the concatenated manufacturer and > model strings leading to user-friendly strings, and "Logitech T650" is > better than "Logitech, Inc. T650". Is this the only problematic issue? We are at rc7 already so I would like to have the final version ready ASAP. Cheers, Benjamin
[toc] | [prev] | [next] | [standalone]
| From | Benjamin Tissoires <benjamin.tissoires@redhat.com> |
|---|---|
| Date | 2017-02-02 15:20 +0100 |
| Subject | [PATCH v2 12/15] HID: logitech-hidpp: do not query the name through HID++ for 1.0 devices |
| Message-ID | <t6qoX-58b-37@gated-at.bofh.it> |
| In reply to | #1572385 |
Unless they are connected through unifying, they don't support it, so remove one error in the logs. Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> --- no changes in v2 --- drivers/hid/hid-logitech-hidpp.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c index f62cf5f..225cf96 100644 --- a/drivers/hid/hid-logitech-hidpp.c +++ b/drivers/hid/hid-logitech-hidpp.c @@ -2614,6 +2614,8 @@ static void hidpp_overwrite_name(struct hid_device *hdev, bool use_unifying) * Ask the receiver for its name. */ name = hidpp_get_unifying_name(hidpp); + else if (hidpp->protocol_major < 2) + return; else name = hidpp_get_device_name(hidpp); -- 2.9.3
[toc] | [prev] | [next] | [standalone]
| From | Benjamin Tissoires <benjamin.tissoires@redhat.com> |
|---|---|
| Date | 2017-02-02 15:20 +0100 |
| Subject | [PATCH v2 15/15] HID: logitech-hidpp: rework hidpp_connect_event() |
| Message-ID | <t6qoW-58b-29@gated-at.bofh.it> |
| In reply to | #1572385 |
Looks like all users don't care about a disconnect.
Simplify the various variant_connect() and put the connect state check
at the beginning.
For delayed input devices, make sure we go through all other connect
values (protocol, battery) before bailing out.
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
---
new in v2
---
drivers/hid/hid-logitech-hidpp.c | 19 +++++--------------
1 file changed, 5 insertions(+), 14 deletions(-)
diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c
index 28ce443..5aff454 100644
--- a/drivers/hid/hid-logitech-hidpp.c
+++ b/drivers/hid/hid-logitech-hidpp.c
@@ -2120,9 +2120,6 @@ static int wtp_connect(struct hid_device *hdev, bool connected)
struct wtp_data *wd = hidpp->private_data;
int ret;
- if (!connected)
- return 0;
-
if (!wd->x_size) {
ret = wtp_get_config(hidpp);
if (ret) {
@@ -2190,9 +2187,6 @@ static int m560_send_config_command(struct hid_device *hdev, bool connected)
hidpp_dev = hid_get_drvdata(hdev);
- if (!connected)
- return -ENODEV;
-
return hidpp_send_rap_command_sync(
hidpp_dev,
REPORT_ID_HIDPP_SHORT,
@@ -2396,9 +2390,6 @@ static int k400_connect(struct hid_device *hdev, bool connected)
{
struct hidpp_device *hidpp = hid_get_drvdata(hdev);
- if (!connected)
- return 0;
-
if (!disable_tap_to_click)
return 0;
@@ -2715,6 +2706,9 @@ static void hidpp_connect_event(struct hidpp_device *hidpp)
struct input_dev *input;
char *name, *devm_name;
+ if (!connected)
+ return;
+
if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP) {
ret = wtp_connect(hdev, connected);
if (ret)
@@ -2729,9 +2723,6 @@ static void hidpp_connect_event(struct hidpp_device *hidpp)
return;
}
- if (!connected || hidpp->delayed_input)
- return;
-
/* the device is already connected, we can ask for its name and
* protocol */
if (!hidpp->protocol_major) {
@@ -2773,8 +2764,8 @@ static void hidpp_connect_event(struct hidpp_device *hidpp)
if (hidpp->battery.ps)
power_supply_changed(hidpp->battery.ps);
- if (!(hidpp->quirks & HIDPP_QUIRK_NO_HIDINPUT))
- /* if HID created the input nodes for us, we can stop now */
+ if (!(hidpp->quirks & HIDPP_QUIRK_NO_HIDINPUT) || hidpp->delayed_input)
+ /* if the input nodes are already created, we can stop now */
return;
input = hidpp_allocate_input(hdev);
--
2.9.3
[toc] | [prev] | [next] | [standalone]
| From | Benjamin Tissoires <benjamin.tissoires@redhat.com> |
|---|---|
| Date | 2017-02-02 15:20 +0100 |
| Subject | [PATCH v2 06/15] HID: logitech-hidpp: create the battery for all types of HID++ devices |
| Message-ID | <t6qoX-58b-39@gated-at.bofh.it> |
| In reply to | #1572385 |
The creation of the power_supply should not be in a HID++ 2.0 specific
function.
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
---
no changes in v2
---
drivers/hid/hid-logitech-hidpp.c | 94 ++++++++++++++++++----------------------
1 file changed, 43 insertions(+), 51 deletions(-)
diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c
index 6124481..ef7ef9e 100644
--- a/drivers/hid/hid-logitech-hidpp.c
+++ b/drivers/hid/hid-logitech-hidpp.c
@@ -806,57 +806,6 @@ static int hidpp_battery_get_property(struct power_supply *psy,
return ret;
}
-static int hidpp20_initialize_battery(struct hidpp_device *hidpp)
-{
- static atomic_t battery_no = ATOMIC_INIT(0);
- struct power_supply_config cfg = { .drv_data = hidpp };
- struct power_supply_desc *desc = &hidpp->battery.desc;
- struct hidpp_battery *battery;
- unsigned long n;
- int ret;
-
- ret = hidpp20_query_battery_info(hidpp);
- if (ret)
- return ret;
-
- battery = &hidpp->battery;
-
- n = atomic_inc_return(&battery_no) - 1;
- desc->properties = hidpp_battery_props;
- desc->num_properties = ARRAY_SIZE(hidpp_battery_props);
- desc->get_property = hidpp_battery_get_property;
- sprintf(battery->name, "hidpp_battery_%ld", n);
- desc->name = battery->name;
- desc->type = POWER_SUPPLY_TYPE_BATTERY;
- desc->use_for_apm = 0;
-
- battery->ps = devm_power_supply_register(&hidpp->hid_dev->dev,
- &battery->desc,
- &cfg);
- if (IS_ERR(battery->ps))
- return PTR_ERR(battery->ps);
-
- power_supply_powers(battery->ps, &hidpp->hid_dev->dev);
-
- return 0;
-}
-
-static int hidpp_initialize_battery(struct hidpp_device *hidpp)
-{
- int ret;
-
- if (hidpp->battery.ps)
- return 0;
-
- if (hidpp->protocol_major >= 2) {
- ret = hidpp20_initialize_battery(hidpp);
- if (ret == 0)
- hidpp->quirks |= HIDPP_QUIRK_HIDPP20_BATTERY;
- }
-
- return ret;
-}
-
/* -------------------------------------------------------------------------- */
/* 0x6010: Touchpad FW items */
/* -------------------------------------------------------------------------- */
@@ -2314,6 +2263,49 @@ static int hidpp_raw_event(struct hid_device *hdev, struct hid_report *report,
return 0;
}
+static int hidpp_initialize_battery(struct hidpp_device *hidpp)
+{
+ static atomic_t battery_no = ATOMIC_INIT(0);
+ struct power_supply_config cfg = { .drv_data = hidpp };
+ struct power_supply_desc *desc = &hidpp->battery.desc;
+ struct hidpp_battery *battery;
+ unsigned long n;
+ int ret;
+
+ if (hidpp->battery.ps)
+ return 0;
+
+ if (hidpp->protocol_major >= 2) {
+ ret = hidpp20_query_battery_info(hidpp);
+ if (ret)
+ return ret;
+ hidpp->quirks |= HIDPP_QUIRK_HIDPP20_BATTERY;
+ } else {
+ return -ENOENT;
+ }
+
+ battery = &hidpp->battery;
+
+ n = atomic_inc_return(&battery_no) - 1;
+ desc->properties = hidpp_battery_props;
+ desc->num_properties = ARRAY_SIZE(hidpp_battery_props);
+ desc->get_property = hidpp_battery_get_property;
+ sprintf(battery->name, "hidpp_battery_%ld", n);
+ desc->name = battery->name;
+ desc->type = POWER_SUPPLY_TYPE_BATTERY;
+ desc->use_for_apm = 0;
+
+ battery->ps = devm_power_supply_register(&hidpp->hid_dev->dev,
+ &battery->desc,
+ &cfg);
+ if (IS_ERR(battery->ps))
+ return PTR_ERR(battery->ps);
+
+ power_supply_powers(battery->ps, &hidpp->hid_dev->dev);
+
+ return ret;
+}
+
static void hidpp_overwrite_name(struct hid_device *hdev, bool use_unifying)
{
struct hidpp_device *hidpp = hid_get_drvdata(hdev);
--
2.9.3
[toc] | [prev] | [next] | [standalone]
| From | Benjamin Tissoires <benjamin.tissoires@redhat.com> |
|---|---|
| Date | 2017-02-02 15:20 +0100 |
| Subject | [PATCH v2 10/15] HID: logitech-hidpp: notify battery on connect |
| Message-ID | <t6qoX-58b-35@gated-at.bofh.it> |
| In reply to | #1572385 |
When a device reconnects, there is a high chance its power supply has
been changed (for a battery replacement for instance). Just forward
the battery state here.
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
---
no changes in v2
---
drivers/hid/hid-logitech-hidpp.c | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c
index 1d7dde9..09581c2 100644
--- a/drivers/hid/hid-logitech-hidpp.c
+++ b/drivers/hid/hid-logitech-hidpp.c
@@ -2571,9 +2571,6 @@ static int hidpp_initialize_battery(struct hidpp_device *hidpp)
return ret;
hidpp->quirks |= HIDPP_QUIRK_HIDPP20_BATTERY;
} else {
- ret = hidpp10_enable_battery_reporting(hidpp);
- if (ret)
- return -ENOENT;
ret = hidpp10_query_battery_status(hidpp);
if (ret) {
ret = hidpp10_query_battery_mileage(hidpp);
@@ -2707,6 +2704,17 @@ static void hidpp_connect_event(struct hidpp_device *hidpp)
hidpp_initialize_battery(hidpp);
+ /* forward current battery state */
+ if (hidpp->quirks & HIDPP_QUIRK_HIDPP10_BATTERY) {
+ hidpp10_enable_battery_reporting(hidpp);
+ hidpp10_query_battery_status(hidpp);
+ hidpp10_query_battery_mileage(hidpp);
+ } else if (hidpp->quirks & HIDPP_QUIRK_HIDPP20_BATTERY) {
+ hidpp20_query_battery_info(hidpp);
+ }
+ if (hidpp->battery.ps)
+ power_supply_changed(hidpp->battery.ps);
+
if (!(hidpp->quirks & HIDPP_QUIRK_NO_HIDINPUT))
/* if HID created the input nodes for us, we can stop now */
return;
--
2.9.3
[toc] | [prev] | [next] | [standalone]
| From | Benjamin Tissoires <benjamin.tissoires@redhat.com> |
|---|---|
| Date | 2017-02-02 15:20 +0100 |
| Subject | [PATCH v2 01/15] HID: logitech-dj: allow devices to request full pairing information |
| Message-ID | <t6qoX-58b-43@gated-at.bofh.it> |
| In reply to | #1572385 |
Register 0xB5 should be handled specially no matter what function is
used. This allows to retrieve the serial and the Quad ID from
hid-logitech-hidpp directly.
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
---
no changes in v2
---
drivers/hid/hid-logitech-dj.c | 17 ++++++++++-------
1 file changed, 10 insertions(+), 7 deletions(-)
diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c
index 5bc6d80..71ce4ca 100644
--- a/drivers/hid/hid-logitech-dj.c
+++ b/drivers/hid/hid-logitech-dj.c
@@ -692,8 +692,12 @@ static void logi_dj_ll_close(struct hid_device *hid)
dbg_hid("%s:%s\n", __func__, hid->phys);
}
-static u8 unifying_name_query[] = {0x10, 0xff, 0x83, 0xb5, 0x40, 0x00, 0x00};
-static u8 unifying_name_answer[] = {0x11, 0xff, 0x83, 0xb5};
+/*
+ * Register 0xB5 is "pairing information". It is solely intended for the
+ * receiver, so do not overwrite the device index.
+ */
+static u8 unifying_pairing_query[] = {0x10, 0xff, 0x83, 0xb5};
+static u8 unifying_pairing_answer[] = {0x11, 0xff, 0x83, 0xb5};
static int logi_dj_ll_raw_request(struct hid_device *hid,
unsigned char reportnum, __u8 *buf,
@@ -712,8 +716,8 @@ static int logi_dj_ll_raw_request(struct hid_device *hid,
/* special case where we should not overwrite
* the device_index */
- if (count == 7 && !memcmp(buf, unifying_name_query,
- sizeof(unifying_name_query)))
+ if (count == 7 && !memcmp(buf, unifying_pairing_query,
+ sizeof(unifying_pairing_query)))
buf[4] |= djdev->device_index - 1;
else
buf[1] = djdev->device_index;
@@ -911,9 +915,8 @@ static int logi_dj_hidpp_event(struct hid_device *hdev,
/* special case were the device wants to know its unifying
* name */
if (size == HIDPP_REPORT_LONG_LENGTH &&
- !memcmp(data, unifying_name_answer,
- sizeof(unifying_name_answer)) &&
- ((data[4] & 0xF0) == 0x40))
+ !memcmp(data, unifying_pairing_answer,
+ sizeof(unifying_pairing_answer)))
device_index = (data[4] & 0x0F) + 1;
else
return false;
--
2.9.3
[toc] | [prev] | [next] | [standalone]
| From | Benjamin Tissoires <benjamin.tissoires@redhat.com> |
|---|---|
| Date | 2017-02-02 15:20 +0100 |
| Subject | [PATCH v2 14/15] HID: logitech-hidpp: retrieve the HID++ device name when available |
| Message-ID | <t6qoX-58b-47@gated-at.bofh.it> |
| In reply to | #1572385 |
hidpp->name can't be null.
Only HID++ 2.0 and above device supports the query.
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
---
new in v2
---
drivers/hid/hid-logitech-hidpp.c | 32 ++++++++++++++++----------------
1 file changed, 16 insertions(+), 16 deletions(-)
diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c
index 416d9e6..28ce443 100644
--- a/drivers/hid/hid-logitech-hidpp.c
+++ b/drivers/hid/hid-logitech-hidpp.c
@@ -2744,6 +2744,22 @@ static void hidpp_connect_event(struct hidpp_device *hidpp)
hidpp->protocol_major, hidpp->protocol_minor);
}
+ if (hidpp->name == hdev->name && hidpp->protocol_major >= 2) {
+ name = hidpp_get_device_name(hidpp);
+ if (!name) {
+ hid_err(hdev,
+ "unable to retrieve the name of the device");
+ return;
+ }
+
+ devm_name = devm_kasprintf(&hdev->dev, GFP_KERNEL, "%s", name);
+ kfree(name);
+ if (!devm_name)
+ return;
+
+ hidpp->name = devm_name;
+ }
+
hidpp_initialize_battery(hidpp);
/* forward current battery state */
@@ -2761,22 +2777,6 @@ static void hidpp_connect_event(struct hidpp_device *hidpp)
/* if HID created the input nodes for us, we can stop now */
return;
- if (!hidpp->name || hidpp->name == hdev->name) {
- name = hidpp_get_device_name(hidpp);
- if (!name) {
- hid_err(hdev,
- "unable to retrieve the name of the device");
- return;
- }
-
- devm_name = devm_kasprintf(&hdev->dev, GFP_KERNEL, "%s", name);
- kfree(name);
- if (!devm_name)
- return;
-
- hidpp->name = devm_name;
- }
-
input = hidpp_allocate_input(hdev);
if (!input) {
hid_err(hdev, "cannot allocate new input device: %d\n", ret);
--
2.9.3
[toc] | [prev] | [next] | [standalone]
| From | Benjamin Tissoires <benjamin.tissoires@redhat.com> |
|---|---|
| Date | 2017-02-02 15:20 +0100 |
| Subject | [PATCH v2 09/15] HID: logitech-hidpp: enable HID++ 1.0 battery reporting |
| Message-ID | <t6qoX-58b-51@gated-at.bofh.it> |
| In reply to | #1572385 |
Also enable battery reporting for HID++ 1.0 devices through 2 registers:
0x07: battery status -> reports only 4 levels (critical, low, good, full)
0x0D: battery mileage -> reports true pourcentage
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
---
no changes in v2
---
drivers/hid/hid-logitech-hidpp.c | 209 ++++++++++++++++++++++++++++++++++++++-
1 file changed, 208 insertions(+), 1 deletion(-)
diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c
index ec3f47c..1d7dde9 100644
--- a/drivers/hid/hid-logitech-hidpp.c
+++ b/drivers/hid/hid-logitech-hidpp.c
@@ -393,6 +393,198 @@ static void hidpp_prefix_name(char **name, int name_length)
#define HIDPP_SET_LONG_REGISTER 0x82
#define HIDPP_GET_LONG_REGISTER 0x83
+#define HIDPP_REG_GENERAL 0x00
+
+static int hidpp10_enable_battery_reporting(struct hidpp_device *hidpp_dev)
+{
+ struct hidpp_report response;
+ int ret;
+ u8 params[3] = { 0 };
+
+ ret = hidpp_send_rap_command_sync(hidpp_dev,
+ REPORT_ID_HIDPP_SHORT,
+ HIDPP_GET_REGISTER,
+ HIDPP_REG_GENERAL,
+ NULL, 0, &response);
+ if (ret)
+ return ret;
+
+ memcpy(params, response.rap.params, 3);
+
+ /* Set the battery bit */
+ params[0] |= BIT(4);
+
+ return hidpp_send_rap_command_sync(hidpp_dev,
+ REPORT_ID_HIDPP_SHORT,
+ HIDPP_SET_REGISTER,
+ HIDPP_REG_GENERAL,
+ params, 3, &response);
+}
+
+#define HIDPP_REG_BATTERY_STATUS 0x07
+
+static int hidpp10_battery_status_map_level(u8 param)
+{
+ int level;
+
+ switch (param) {
+ case 1 ... 2:
+ level = 5;
+ break;
+ case 3 ... 4:
+ level = 20;
+ break;
+ case 5 ... 6:
+ level = 55;
+ break;
+ case 7:
+ level = 90;
+ break;
+ default:
+ level = 0;
+ }
+
+ return level;
+}
+
+static int hidpp10_battery_status_map_status(u8 param)
+{
+ int status;
+
+ switch (param) {
+ case 0x00:
+ /* discharging (in use) */
+ status = POWER_SUPPLY_STATUS_DISCHARGING;
+ break;
+ case 0x21: /* (standard) charging */
+ case 0x24: /* fast charging */
+ case 0x25: /* slow charging */
+ status = POWER_SUPPLY_STATUS_CHARGING;
+ break;
+ case 0x26: /* topping charge */
+ case 0x22: /* charge complete */
+ status = POWER_SUPPLY_STATUS_FULL;
+ break;
+ /*
+ * 0x01...0x1F = reserved (not charging)
+ * 0x20 = unknown
+ * 0x23 = charging error
+ * 0x27..0xff = reserved
+ */
+ default:
+ status = POWER_SUPPLY_STATUS_NOT_CHARGING;
+ break;
+ }
+
+ return status;
+}
+
+static int hidpp10_query_battery_status(struct hidpp_device *hidpp)
+{
+ struct hidpp_report response;
+ int ret;
+
+ ret = hidpp_send_rap_command_sync(hidpp,
+ REPORT_ID_HIDPP_SHORT,
+ HIDPP_GET_REGISTER,
+ HIDPP_REG_BATTERY_STATUS,
+ NULL, 0, &response);
+ if (ret)
+ return ret;
+
+ hidpp->battery.level =
+ hidpp10_battery_status_map_level(response.rap.params[0]);
+
+ hidpp->battery.status =
+ hidpp10_battery_status_map_status(response.rap.params[1]);
+
+ return 0;
+}
+
+#define HIDPP_REG_BATTERY_MILEAGE 0x0D
+
+static int hidpp10_battery_mileage_map_status(u8 param)
+{
+ int status;
+
+ switch (param >> 6) {
+ case 0x00:
+ /* discharging (in use) */
+ status = POWER_SUPPLY_STATUS_DISCHARGING;
+ break;
+ case 0x01: /* charging */
+ status = POWER_SUPPLY_STATUS_CHARGING;
+ break;
+ case 0x02: /* charge complete */
+ status = POWER_SUPPLY_STATUS_FULL;
+ break;
+ /*
+ * 0x03 = charging error
+ */
+ default:
+ status = POWER_SUPPLY_STATUS_NOT_CHARGING;
+ break;
+ }
+
+ return status;
+}
+
+static int hidpp10_query_battery_mileage(struct hidpp_device *hidpp)
+{
+ struct hidpp_report response;
+ int ret;
+
+ ret = hidpp_send_rap_command_sync(hidpp,
+ REPORT_ID_HIDPP_SHORT,
+ HIDPP_GET_REGISTER,
+ HIDPP_REG_BATTERY_MILEAGE,
+ NULL, 0, &response);
+ if (ret)
+ return ret;
+
+ hidpp->battery.level = response.rap.params[0];
+
+ hidpp->battery.status =
+ hidpp10_battery_mileage_map_status(response.rap.params[2]);
+
+ return 0;
+}
+
+static int hidpp10_battery_event(struct hidpp_device *hidpp, u8 *data, int size)
+{
+ struct hidpp_report *report = (struct hidpp_report *)data;
+ int status, level;
+ bool changed;
+
+ if (report->report_id != REPORT_ID_HIDPP_SHORT)
+ return 0;
+
+ switch (report->rap.reg_address) {
+ case HIDPP_REG_BATTERY_STATUS:
+ level = hidpp10_battery_status_map_level(report->rap.params[0]);
+ status = hidpp10_battery_status_map_status(report->rap.params[1]);
+ break;
+ case HIDPP_REG_BATTERY_MILEAGE:
+ level = report->rap.params[0];
+ status = hidpp10_battery_mileage_map_status(report->rap.params[2]);
+ break;
+ default:
+ return 0;
+ }
+
+ changed = level != hidpp->battery.level ||
+ status != hidpp->battery.status;
+
+ if (changed) {
+ hidpp->battery.level = level;
+ hidpp->battery.status = status;
+ if (hidpp->battery.ps)
+ power_supply_changed(hidpp->battery.ps);
+ }
+
+ return 0;
+}
+
#define HIDPP_REG_PAIRING_INFORMATION 0xB5
#define DEVICE_NAME 0x40
@@ -2340,6 +2532,12 @@ static int hidpp_raw_event(struct hid_device *hdev, struct hid_report *report,
return ret;
}
+ if (hidpp->quirks & HIDPP_QUIRK_HIDPP10_BATTERY) {
+ ret = hidpp10_battery_event(hidpp, data, size);
+ if (ret != 0)
+ return ret;
+ }
+
if (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP)
return wtp_raw_event(hdev, data, size);
else if (hidpp->quirks & HIDPP_QUIRK_CLASS_M560)
@@ -2373,7 +2571,16 @@ static int hidpp_initialize_battery(struct hidpp_device *hidpp)
return ret;
hidpp->quirks |= HIDPP_QUIRK_HIDPP20_BATTERY;
} else {
- return -ENOENT;
+ ret = hidpp10_enable_battery_reporting(hidpp);
+ if (ret)
+ return -ENOENT;
+ ret = hidpp10_query_battery_status(hidpp);
+ if (ret) {
+ ret = hidpp10_query_battery_mileage(hidpp);
+ if (ret)
+ return -ENOENT;
+ }
+ hidpp->quirks |= HIDPP_QUIRK_HIDPP10_BATTERY;
}
battery = &hidpp->battery;
--
2.9.3
[toc] | [prev] | [next] | [standalone]
| From | Benjamin Tissoires <benjamin.tissoires@redhat.com> |
|---|---|
| Date | 2017-02-02 15:20 +0100 |
| Subject | [PATCH v2 07/15] HID: logitech-hidpp: return an error if the feature is not present |
| Message-ID | <t6qoX-58b-49@gated-at.bofh.it> |
| In reply to | #1572385 |
Or the device just answers a valid feature '0'. Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> --- no changes in v2 --- drivers/hid/hid-logitech-hidpp.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c index ef7ef9e..f7b2589 100644 --- a/drivers/hid/hid-logitech-hidpp.c +++ b/drivers/hid/hid-logitech-hidpp.c @@ -452,6 +452,9 @@ static int hidpp_root_get_feature(struct hidpp_device *hidpp, u16 feature, if (ret) return ret; + if (response.fap.params[0] == 0) + return -ENOENT; + *feature_index = response.fap.params[0]; *feature_type = response.fap.params[1]; -- 2.9.3
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web