[v7,3/3] HID: logitech-hidpp: Support WirelessDeviceStatus connect events
diff mbox series

Message ID yqo4xUWK3dmAH59Oyn2JK3cV_xDNVaULp7MRQ0afuT1IDqOPRauLpjRiOaUnTgCNeHvOL_lIL_IHzg4zs6-cHfB3Cz0awCWe2mjvuchYWFk=@protonmail.com
State Superseded
Delegated to: Benjamin Tissoires
Headers show
Series
  • Logitech HID++ Bluetooth LE support
Related show

Commit Message

Mazin Rezk Oct. 20, 2019, 4:43 a.m. UTC
This patch allows hidpp_report_is_connect_event to support
WirelessDeviceStatus connect events.

The WirelessDeviceStatus feature index is stored in hidpp_device when
probed. The connect event's fap feature_index is compared against it if the
device supports it.

Thanks,
Mazin

Signed-off-by: Mazin Rezk <mnrzk@protonmail.com>
---
 drivers/hid/hid-logitech-hidpp.c | 39 ++++++++++++++++++++++++++++----
 1 file changed, 35 insertions(+), 4 deletions(-)

--
2.23.0

Comments

Benjamin Tissoires Oct. 22, 2019, 10:17 a.m. UTC | #1
Hi Mazin

On Sun, Oct 20, 2019 at 6:43 AM Mazin Rezk <mnrzk@protonmail.com> wrote:
>
> This patch allows hidpp_report_is_connect_event to support
> WirelessDeviceStatus connect events.
>
> The WirelessDeviceStatus feature index is stored in hidpp_device when
> probed. The connect event's fap feature_index is compared against it if the
> device supports it.
>
> Thanks,
> Mazin

huh, this "Thanks" bit should be after the first "---", because we
don't want it in the final commit :)

BTW, I haven't been able to trigger this one yet. Patch looks good,
but I'd rather be sure it works on many Logitech devices before we
include it.

Cheers,
Benjamin

>
> Signed-off-by: Mazin Rezk <mnrzk@protonmail.com>
> ---
>  drivers/hid/hid-logitech-hidpp.c | 39 ++++++++++++++++++++++++++++----
>  1 file changed, 35 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c
> index 19b315e4e91b..c8b23568d0b1 100644
> --- a/drivers/hid/hid-logitech-hidpp.c
> +++ b/drivers/hid/hid-logitech-hidpp.c
> @@ -191,6 +191,8 @@ struct hidpp_device {
>
>         struct hidpp_battery battery;
>         struct hidpp_scroll_counter vertical_wheel_counter;
> +
> +       u8 wireless_feature_index;
>  };
>
>  /* HID++ 1.0 error codes */
> @@ -403,10 +405,13 @@ static inline bool hidpp_match_error(struct hidpp_report *question,
>             (answer->fap.params[0] == question->fap.funcindex_clientid);
>  }
>
> -static inline bool hidpp_report_is_connect_event(struct hidpp_report *report)
> +static inline bool hidpp_report_is_connect_event(struct hidpp_device *hidpp,
> +               struct hidpp_report *report)
>  {
> -       return (report->report_id == REPORT_ID_HIDPP_SHORT) &&
> -               (report->rap.sub_id == 0x41);
> +       return (hidpp->wireless_feature_index &&
> +               (report->fap.feature_index == hidpp->wireless_feature_index)) ||
> +               ((report->report_id == REPORT_ID_HIDPP_SHORT) &&
> +               (report->rap.sub_id == 0x41));
>  }
>
>  /**
> @@ -1283,6 +1288,24 @@ static int hidpp_battery_get_property(struct power_supply *psy,
>         return ret;
>  }
>
> +/* -------------------------------------------------------------------------- */
> +/* 0x1d4b: Wireless device status                                             */
> +/* -------------------------------------------------------------------------- */
> +#define HIDPP_PAGE_WIRELESS_DEVICE_STATUS                      0x1d4b
> +
> +static int hidpp_set_wireless_feature_index(struct hidpp_device *hidpp)
> +{
> +       u8 feature_type;
> +       int ret;
> +
> +       ret = hidpp_root_get_feature(hidpp,
> +                                    HIDPP_PAGE_WIRELESS_DEVICE_STATUS,
> +                                    &hidpp->wireless_feature_index,
> +                                    &feature_type);
> +
> +       return ret;
> +}
> +
>  /* -------------------------------------------------------------------------- */
>  /* 0x2120: Hi-resolution scrolling                                            */
>  /* -------------------------------------------------------------------------- */
> @@ -3078,7 +3101,7 @@ static int hidpp_raw_hidpp_event(struct hidpp_device *hidpp, u8 *data,
>                 }
>         }
>
> -       if (unlikely(hidpp_report_is_connect_event(report))) {
> +       if (unlikely(hidpp_report_is_connect_event(hidpp, report))) {
>                 atomic_set(&hidpp->connected,
>                                 !(report->rap.params[0] & (1 << 6)));
>                 if (schedule_work(&hidpp->work) == 0)
> @@ -3628,6 +3651,14 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
>                 hidpp_overwrite_name(hdev);
>         }
>
> +       if (connected && hidpp->protocol_major >= 2) {
> +               ret = hidpp_set_wireless_feature_index(hidpp);
> +               if (ret == -ENOENT)
> +                       hidpp->wireless_feature_index = 0;
> +               else if (ret)
> +                       goto hid_hw_init_fail;
> +       }
> +
>         if (connected && (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP)) {
>                 ret = wtp_get_config(hidpp);
>                 if (ret)
> --
> 2.23.0
>

Patch
diff mbox series

diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c
index 19b315e4e91b..c8b23568d0b1 100644
--- a/drivers/hid/hid-logitech-hidpp.c
+++ b/drivers/hid/hid-logitech-hidpp.c
@@ -191,6 +191,8 @@  struct hidpp_device {

 	struct hidpp_battery battery;
 	struct hidpp_scroll_counter vertical_wheel_counter;
+
+	u8 wireless_feature_index;
 };

 /* HID++ 1.0 error codes */
@@ -403,10 +405,13 @@  static inline bool hidpp_match_error(struct hidpp_report *question,
 	    (answer->fap.params[0] == question->fap.funcindex_clientid);
 }

-static inline bool hidpp_report_is_connect_event(struct hidpp_report *report)
+static inline bool hidpp_report_is_connect_event(struct hidpp_device *hidpp,
+		struct hidpp_report *report)
 {
-	return (report->report_id == REPORT_ID_HIDPP_SHORT) &&
-		(report->rap.sub_id == 0x41);
+	return (hidpp->wireless_feature_index &&
+		(report->fap.feature_index == hidpp->wireless_feature_index)) ||
+		((report->report_id == REPORT_ID_HIDPP_SHORT) &&
+		(report->rap.sub_id == 0x41));
 }

 /**
@@ -1283,6 +1288,24 @@  static int hidpp_battery_get_property(struct power_supply *psy,
 	return ret;
 }

+/* -------------------------------------------------------------------------- */
+/* 0x1d4b: Wireless device status                                             */
+/* -------------------------------------------------------------------------- */
+#define HIDPP_PAGE_WIRELESS_DEVICE_STATUS			0x1d4b
+
+static int hidpp_set_wireless_feature_index(struct hidpp_device *hidpp)
+{
+	u8 feature_type;
+	int ret;
+
+	ret = hidpp_root_get_feature(hidpp,
+				     HIDPP_PAGE_WIRELESS_DEVICE_STATUS,
+				     &hidpp->wireless_feature_index,
+				     &feature_type);
+
+	return ret;
+}
+
 /* -------------------------------------------------------------------------- */
 /* 0x2120: Hi-resolution scrolling                                            */
 /* -------------------------------------------------------------------------- */
@@ -3078,7 +3101,7 @@  static int hidpp_raw_hidpp_event(struct hidpp_device *hidpp, u8 *data,
 		}
 	}

-	if (unlikely(hidpp_report_is_connect_event(report))) {
+	if (unlikely(hidpp_report_is_connect_event(hidpp, report))) {
 		atomic_set(&hidpp->connected,
 				!(report->rap.params[0] & (1 << 6)));
 		if (schedule_work(&hidpp->work) == 0)
@@ -3628,6 +3651,14 @@  static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
 		hidpp_overwrite_name(hdev);
 	}

+	if (connected && hidpp->protocol_major >= 2) {
+		ret = hidpp_set_wireless_feature_index(hidpp);
+		if (ret == -ENOENT)
+			hidpp->wireless_feature_index = 0;
+		else if (ret)
+			goto hid_hw_init_fail;
+	}
+
 	if (connected && (hidpp->quirks & HIDPP_QUIRK_CLASS_WTP)) {
 		ret = wtp_get_config(hidpp);
 		if (ret)