]> git.pld-linux.org Git - packages/upower.git/blob - upower-fixes.patch
- detect lg-wireless devices by looking for usbmisc/hiddev entries
[packages/upower.git] / upower-fixes.patch
1 commit 232d70155c45d24afabe47ed37954cc000678295
2 Author: Arkadiusz Miśkiewicz <arekm@maven.pl>
3 Date:   Wed Mar 20 17:51:14 2013 +0100
4
5     Find hidraw devices correctly with systemd udev >= v196.
6     
7     udev v196 libraries changed behaviour of g_udev_device_get_sysfs_attr()
8     by stopping following symlinks for "device" attribute [1]. That change
9     broke hiddev finding for unifying devices. Fix that by getting sysfs
10     path from parent hiddev device.
11     
12     1. http://cgit.freedesktop.org/systemd/systemd/commit/?id=5ae18ddc0d86673520c0dd6b59ccac8afc8aa605
13     
14     Signed-off-by: Arkadiusz Miśkiewicz <arekm@maven.pl>
15     Signed-off-by: Richard Hughes <richard@hughsie.com>
16
17 diff --git a/src/linux/up-device-unifying.c b/src/linux/up-device-unifying.c
18 index c7f0103..4b659c3 100644
19 --- a/src/linux/up-device-unifying.c
20 +++ b/src/linux/up-device-unifying.c
21 @@ -165,7 +165,7 @@ up_device_unifying_coldplug (UpDevice *device)
22         hidraw_list = g_udev_client_query_by_subsystem (client, "hidraw");
23         for (l = hidraw_list; l != NULL; l = l->next) {
24                 if (g_strcmp0 (g_udev_device_get_sysfs_path (parent),
25 -                              g_udev_device_get_sysfs_attr (l->data, "device")) == 0) {
26 +                              g_udev_device_get_sysfs_path(g_udev_device_get_parent(l->data))) == 0) {
27                         receiver = g_object_ref (l->data);
28                         break;
29                 }
30
31 commit 28f396496a90705b0d8823707396731fe60d85bc
32 Author: Arkadiusz Miśkiewicz <arekm@maven.pl>
33 Date:   Wed Mar 20 22:22:54 2013 +0100
34
35     Detection of version 1 hid++ is not returned to the caller
36     
37     HID++ version 1 was properly detected but that information wasn't
38     reaching caller.
39     
40     Signed-off-by: Arkadiusz Miśkiewicz <arekm@maven.pl>
41     Signed-off-by: Richard Hughes <richard@hughsie.com>
42
43 diff --git a/src/linux/hidpp-device.c b/src/linux/hidpp-device.c
44 index 0a27dbf..1bcefab 100644
45 --- a/src/linux/hidpp-device.c
46 +++ b/src/linux/hidpp-device.c
47 @@ -314,9 +314,9 @@ hidpp_device_cmd (HidppDevice       *device,
48             buf[2] == HIDPP_ERR_INVALID_SUBID &&
49             buf[3] == 0x00 &&
50             buf[4] == HIDPP_FEATURE_ROOT_FN_PING) {
51 -               /* HID++ 1.0 ping reply, so fake success  */
52 +               /* HID++ 1.0 ping reply, so fake success with version 1  */
53                 if (buf[5] == HIDPP_ERROR_CODE_UNKNOWN) {
54 -                       buf[0] = 1;
55 +                       response_data[0] = 1;
56                         goto out;
57                 }
58                 if (buf[5] == HIDPP_ERROR_CODE_UNSUPPORTED) {
59
60 commit 972acff14532aa1a495b2ee20f24505cb581291a
61 Author: Arkadiusz Miśkiewicz <arekm@maven.pl>
62 Date:   Wed Mar 20 22:28:11 2013 +0100
63
64     Buffer for HIDPP_REFRESH_FLAGS_KIND not big enough
65     
66     HIDPP_REFRESH_FLAGS_KIND action puts result into 7 bytes buffer and
67     later tries to access 8th element (with index 7). Make buffer bigger,
68     so 8th element will fit.
69     
70     Signed-off-by: Arkadiusz Miśkiewicz <arekm@maven.pl>
71     Signed-off-by: Richard Hughes <richard@hughsie.com>
72
73 diff --git a/src/linux/hidpp-device.c b/src/linux/hidpp-device.c
74 index 1bcefab..58c6e6d 100644
75 --- a/src/linux/hidpp-device.c
76 +++ b/src/linux/hidpp-device.c
77 @@ -560,7 +560,7 @@ hidpp_device_refresh (HidppDevice *device,
78                                                 HIDPP_READ_LONG_REGISTER,
79                                                 0xb5,
80                                                 buf, 3,
81 -                                               buf, 7,
82 +                                               buf, 8,
83                                                 error);
84                         if (!ret)
85                                 goto out;
86
87 commit af24f55c7925c8ea990cb36078b63c17cd671a95
88 Author: Arkadiusz Miśkiewicz <arekm@maven.pl>
89 Date:   Wed Mar 20 22:35:59 2013 +0100
90
91     Invalid request/response for HIDPP_REFRESH_FLAGS_BATTERY in hid++1
92     
93     Version 1 hid++ HIDPP_REFRESH_FLAGS_BATTERY packets were incorrect.
94     
95     Response packets were incorrectly thrown away as invalid. These
96     packets have HIDPP_HEADER_REQUEST (and not HIDPP_HEADER_RESPONSE as code
97     expexted). Fix that by allowing both types.
98     
99     Signed-off-by: Arkadiusz Miśkiewicz <arekm@maven.pl>
100     Signed-off-by: Richard Hughes <richard@hughsie.com>
101
102 diff --git a/src/linux/hidpp-device.c b/src/linux/hidpp-device.c
103 index 58c6e6d..8e861c5 100644
104 --- a/src/linux/hidpp-device.c
105 +++ b/src/linux/hidpp-device.c
106 @@ -327,7 +327,7 @@ hidpp_device_cmd (HidppDevice       *device,
107                         goto out;
108                 }
109         }
110 -       if (buf[0] != HIDPP_HEADER_RESPONSE ||
111 +       if ((buf[0] != HIDPP_HEADER_REQUEST && buf[0] != HIDPP_HEADER_RESPONSE) ||
112             buf[1] != device_idx ||
113             buf[2] != feature_idx ||
114             buf[3] != function_idx) {
115 @@ -662,16 +662,14 @@ hidpp_device_refresh (HidppDevice *device,
116         /* get battery status */
117         if ((refresh_flags & HIDPP_REFRESH_FLAGS_BATTERY) > 0) {
118                 if (priv->version == 1) {
119 -                       buf[0] = HIDPP_READ_SHORT_REGISTER;
120 -                       buf[1] = HIDPP_READ_SHORT_REGISTER_BATTERY;
121 +                       buf[0] = 0x00;
122 +                       buf[1] = 0x00;
123                         buf[2] = 0x00;
124 -                       buf[3] = 0x00;
125 -                       buf[4] = 0x00;
126                         ret = hidpp_device_cmd (device,
127                                                 priv->device_idx,
128 -                                               HIDPP_FEATURE_ROOT_INDEX,
129 -                                               HIDPP_FEATURE_ROOT_FN_PING,
130 -                                               buf, 5,
131 +                                               HIDPP_READ_SHORT_REGISTER,
132 +                                               HIDPP_READ_SHORT_REGISTER_BATTERY,
133 +                                               buf, 3,
134                                                 buf, 1,
135                                                 error);
136                         if (!ret)
137
138 commit e571f840e9fd945c94bc1c5fa494fde9d23fa2ad
139 Author: Arkadiusz Miśkiewicz <arekm@maven.pl>
140 Date:   Thu Mar 21 19:57:26 2013 +0100
141
142     Add support for HIDPP_REFRESH_FLAGS_MODEL in hid++ v1
143     
144     Add support for checking device model name for hid++ v1 protocol
145     version.
146     
147     Signed-off-by: Arkadiusz Miśkiewicz <arekm@maven.pl>
148     Signed-off-by: Richard Hughes <richard@hughsie.com>
149
150 diff --git a/src/linux/hidpp-device.c b/src/linux/hidpp-device.c
151 index 8e861c5..bfc1b5c 100644
152 --- a/src/linux/hidpp-device.c
153 +++ b/src/linux/hidpp-device.c
154 @@ -624,39 +624,60 @@ hidpp_device_refresh (HidppDevice *device,
155  
156         /* get device model string */
157         if ((refresh_flags & HIDPP_REFRESH_FLAGS_MODEL) > 0) {
158 -               buf[0] = 0x00;
159 -               buf[1] = 0x00;
160 -               buf[2] = 0x00;
161 -               map = hidpp_device_map_get_by_feature (device, HIDPP_FEATURE_GET_DEVICE_NAME_TYPE);
162 -               if (map != NULL) {
163 +               if (priv->version == 1) {
164 +                       buf[0] = 0x40 | (priv->device_idx - 1);
165 +                       buf[1] = 0x00;
166 +                       buf[2] = 0x00;
167 +
168                         ret = hidpp_device_cmd (device,
169 +                                       HIDPP_RECEIVER_ADDRESS,
170 +                                       HIDPP_READ_LONG_REGISTER,
171 +                                       0xb5,
172 +                                       buf, 3,
173 +                                       buf, HIDPP_RESPONSE_LONG_LENGTH,
174 +                                       error);
175 +                       if (!ret)
176 +                               goto out;
177 +
178 +                       len = buf[1];
179 +                       name = g_string_new ("");
180 +                       g_string_append_len (name, (gchar *) buf+2, len);
181 +                       priv->model = g_strdup (name->str);
182 +               } else if (priv->version == 2) {
183 +                       buf[0] = 0x00;
184 +                       buf[1] = 0x00;
185 +                       buf[2] = 0x00;
186 +                       map = hidpp_device_map_get_by_feature (device, HIDPP_FEATURE_GET_DEVICE_NAME_TYPE);
187 +                       if (map != NULL) {
188 +                               ret = hidpp_device_cmd (device,
189                                                 priv->device_idx,
190                                                 map->idx,
191                                                 HIDPP_FEATURE_GET_DEVICE_NAME_TYPE_FN_GET_COUNT,
192                                                 buf, 3,
193                                                 buf, 1,
194                                                 error);
195 -                       if (!ret)
196 -                               goto out;
197 -               }
198 -               len = buf[0];
199 -               name = g_string_new ("");
200 -               for (i = 0; i < len; i +=4 ) {
201 -                       buf[0] = i;
202 -                       buf[1] = 0x00;
203 -                       buf[2] = 0x00;
204 -                       ret = hidpp_device_cmd (device,
205 +                               if (!ret)
206 +                                       goto out;
207 +                       }
208 +                       len = buf[0];
209 +                       name = g_string_new ("");
210 +                       for (i = 0; i < len; i +=4 ) {
211 +                               buf[0] = i;
212 +                               buf[1] = 0x00;
213 +                               buf[2] = 0x00;
214 +                               ret = hidpp_device_cmd (device,
215                                                 priv->device_idx,
216                                                 map->idx,
217                                                 HIDPP_FEATURE_GET_DEVICE_NAME_TYPE_FN_GET_NAME,
218                                                 buf, 3,
219                                                 buf, 4,
220                                                 error);
221 -                       if (!ret)
222 -                               goto out;
223 -                       g_string_append_len (name, (gchar *) &buf[0], 4);
224 +                               if (!ret)
225 +                                       goto out;
226 +                               g_string_append_len (name, (gchar *) &buf[0], 4);
227 +                       }
228 +                       priv->model = g_strdup (name->str);
229                 }
230 -               priv->model = g_strdup (name->str);
231         }
232  
233         /* get battery status */
234
235 commit fd0286e871bcf67d29aa622b66ecf362fe2d6ec0
236 Author: Arkadiusz Miśkiewicz <arekm@maven.pl>
237 Date:   Thu Mar 21 20:40:26 2013 +0100
238
239     Repair vendor handling for Logitech Unifying devices
240     
241     Set proper vendor via udev rules for unifying devices and handle
242     that in code.
243     
244     Signed-off-by: Arkadiusz Miśkiewicz <arekm@maven.pl>
245     Signed-off-by: Richard Hughes <richard@hughsie.com>
246
247 diff --git a/rules/95-upower-csr.rules b/rules/95-upower-csr.rules
248 index bd171b2..b8d92fe 100644
249 --- a/rules/95-upower-csr.rules
250 +++ b/rules/95-upower-csr.rules
251 @@ -22,6 +22,7 @@ LABEL="up_csr_end"
252  
253  # Unifying HID++ devices
254  SUBSYSTEM!="hid", GOTO="up_unifying_end"
255 +ATTRS{idVendor}=="046d", ENV{UPOWER_VENDOR}="Logitech, Inc."
256  ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c52b", DRIVER=="logitech-djdevice", ENV{UPOWER_BATTERY_TYPE}="unifying"
257  ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c532", DRIVER=="logitech-djdevice", ENV{UPOWER_BATTERY_TYPE}="unifying"
258  LABEL="up_unifying_end"
259 diff --git a/src/linux/up-device-unifying.c b/src/linux/up-device-unifying.c
260 index 4b659c3..633909f 100644
261 --- a/src/linux/up-device-unifying.c
262 +++ b/src/linux/up-device-unifying.c
263 @@ -123,6 +123,7 @@ up_device_unifying_coldplug (UpDevice *device)
264         const gchar *bus_address;
265         const gchar *device_file;
266         const gchar *type;
267 +       const gchar *vendor;
268         gboolean ret = FALSE;
269         gchar *endptr = NULL;
270         gchar *tmp;
271 @@ -198,9 +199,13 @@ up_device_unifying_coldplug (UpDevice *device)
272                 goto out;
273         }
274  
275 +       vendor = g_udev_device_get_property (native, "UPOWER_VENDOR");
276 +       if (vendor == NULL)
277 +               vendor = g_udev_device_get_property (native, "ID_VENDOR");
278 +
279         /* set some default values */
280         g_object_set (device,
281 -                     "vendor", g_udev_device_get_property (native, "ID_VENDOR"),
282 +                     "vendor", vendor,
283                       "type", up_device_unifying_get_device_kind (unifying),
284                       "model", hidpp_device_get_model (unifying->priv->hidpp_device),
285                       "has-history", TRUE,
286
287 commit 32daed2dfa22196bd4c51fdabad3d333d4839903
288 Author: Arkadiusz Miśkiewicz <arekm@maven.pl>
289 Date:   Fri Mar 22 15:28:11 2013 +0100
290
291     Add support for Logitech Wireless (NonUnifying) devices
292     
293     There are Logitech Wireless devices similar to Unifying ones with the
294     difference that device is paired with single dongle and dongle doesn't
295     support pairing multiple devices.
296     
297     Add support for these. Tested with Wireless Mouse M187 and M185/M225.
298     
299     Signed-off-by: Arkadiusz Miśkiewicz <arekm@maven.pl>
300     Signed-off-by: Richard Hughes <richard@hughsie.com>
301
302 diff --git a/rules/95-upower-csr.rules b/rules/95-upower-csr.rules
303 index b8d92fe..b476660 100644
304 --- a/rules/95-upower-csr.rules
305 +++ b/rules/95-upower-csr.rules
306 @@ -25,4 +25,5 @@ SUBSYSTEM!="hid", GOTO="up_unifying_end"
307  ATTRS{idVendor}=="046d", ENV{UPOWER_VENDOR}="Logitech, Inc."
308  ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c52b", DRIVER=="logitech-djdevice", ENV{UPOWER_BATTERY_TYPE}="unifying"
309  ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c532", DRIVER=="logitech-djdevice", ENV{UPOWER_BATTERY_TYPE}="unifying"
310 +ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c52f", ENV{UPOWER_BATTERY_TYPE}="lg-wireless"
311  LABEL="up_unifying_end"
312 diff --git a/src/linux/up-device-unifying.c b/src/linux/up-device-unifying.c
313 index 633909f..f6636e6 100644
314 --- a/src/linux/up-device-unifying.c
315 +++ b/src/linux/up-device-unifying.c
316 @@ -142,7 +142,7 @@ up_device_unifying_coldplug (UpDevice *device)
317         type = g_udev_device_get_property (native, "UPOWER_BATTERY_TYPE");
318         if (type == NULL)
319                 goto out;
320 -       if (g_strcmp0 (type, "unifying") != 0)
321 +       if ((g_strcmp0 (type, "unifying") != 0) && (g_strcmp0 (type, "lg-wireless") != 0))
322                 goto out;
323  
324         /* get the device index */
325 @@ -153,23 +153,37 @@ up_device_unifying_coldplug (UpDevice *device)
326                 g_debug ("Could not get physical device index");
327                 goto out;
328         }
329 -       hidpp_device_set_index (unifying->priv->hidpp_device,
330 +
331 +       if (g_strcmp0 (type, "lg-wireless") == 0)
332 +               hidpp_device_set_index (unifying->priv->hidpp_device, 1);
333 +       else {
334 +               hidpp_device_set_index (unifying->priv->hidpp_device,
335                                 g_ascii_strtoull (tmp + 1, &endptr, 10));
336 -       if (endptr != NULL && endptr[0] != '\0') {
337 -               g_debug ("HID_PHYS malformed: '%s'", bus_address);
338 -               goto out;
339 +               if (endptr != NULL && endptr[0] != '\0') {
340 +                       g_debug ("HID_PHYS malformed: '%s'", bus_address);
341 +                       goto out;
342 +               }
343         }
344  
345 -       /* find the hidraw device that matches the parent */
346 +       /* find the hidraw device that matches */
347         parent = g_udev_device_get_parent (native);
348         client = g_udev_client_new (NULL);
349         hidraw_list = g_udev_client_query_by_subsystem (client, "hidraw");
350         for (l = hidraw_list; l != NULL; l = l->next) {
351 -               if (g_strcmp0 (g_udev_device_get_sysfs_path (parent),
352 -                              g_udev_device_get_sysfs_path(g_udev_device_get_parent(l->data))) == 0) {
353 -                       receiver = g_object_ref (l->data);
354 -                       break;
355 +               if (g_strcmp0 (type, "lg-wireless") == 0) {
356 +                       if (g_strcmp0 (g_udev_device_get_sysfs_path (native),
357 +                                               g_udev_device_get_sysfs_path(g_udev_device_get_parent(l->data))) != 0)
358 +                               continue;
359 +                       // Ugly way to distinguish receiver itself from mouse/keyboard etc for non-unifying dongles
360 +                       if (g_strcmp0(g_udev_device_get_property(g_udev_device_get_parent (native), "INTERFACE"), "3/0/0") != 0)
361 +                               continue;
362 +               } else {
363 +                       if (g_strcmp0 (g_udev_device_get_sysfs_path (parent),
364 +                                               g_udev_device_get_sysfs_path(g_udev_device_get_parent(l->data))) != 0)
365 +                               continue;
366                 }
367 +               receiver = g_object_ref (l->data);
368 +               break;
369         }
370         if (receiver == NULL) {
371                 g_debug ("Unable to find an hidraw device for Unifying receiver");
372
373 commit fadca8ad7706c15b5fabee2f7be599961fe33240
374 Author: Arkadiusz Miśkiewicz <arekm@maven.pl>
375 Date:   Fri Mar 22 19:46:47 2013 +0100
376
377     Better method of figuring out v1 vs v2 protocol version.
378     
379     Protocol version detection isn't very reliable (especially for
380     hid++ v1).
381     
382     Version 1 checking was potentially happening in every hidpp_device_cmd()
383     call and not only when requested. Improve that to do version checking
384     and priv->version manipulation only when requested by using
385     HIDPP_REFRESH_FLAGS_VERSION.
386     
387     When doing version checking first try v2 protocol command and if it
388     succeeds assume version 2 device. Otherwise try v1 protocol query
389     and if that successds assume version 1 device.
390     
391     v2 devices in unreachable/sleep mode seem to do not respond to v2
392     queries but they respond to v1 queries! Still we want best protocol
393     possible. To do that we are rechecking version when current protocol
394     version is below 2 and we are doing up_device_unifying_refresh() and if
395     recheck succeeds we upgrade protocol to v2.
396     
397     Signed-off-by: Arkadiusz Miśkiewicz <arekm@maven.pl>
398     Signed-off-by: Richard Hughes <richard@hughsie.com>
399
400 diff --git a/src/linux/hidpp-device.c b/src/linux/hidpp-device.c
401 index bfc1b5c..5398a38 100644
402 --- a/src/linux/hidpp-device.c
403 +++ b/src/linux/hidpp-device.c
404 @@ -46,6 +46,7 @@
405  /* HID++ 1.0 */
406  #define HIDPP_READ_SHORT_REGISTER                              0x81
407  #define HIDPP_READ_SHORT_REGISTER_BATTERY                      0x0d
408 +#define HIDPP_READ_SHORT_REGISTER_CONNECTION_STATE             0x02
409  
410  #define HIDPP_READ_LONG_REGISTER                               0x83
411  #define HIDPP_READ_LONG_REGISTER_DEVICE_TYPE                   11
412 @@ -314,11 +315,6 @@ hidpp_device_cmd (HidppDevice      *device,
413             buf[2] == HIDPP_ERR_INVALID_SUBID &&
414             buf[3] == 0x00 &&
415             buf[4] == HIDPP_FEATURE_ROOT_FN_PING) {
416 -               /* HID++ 1.0 ping reply, so fake success with version 1  */
417 -               if (buf[5] == HIDPP_ERROR_CODE_UNKNOWN) {
418 -                       response_data[0] = 1;
419 -                       goto out;
420 -               }
421                 if (buf[5] == HIDPP_ERROR_CODE_UNSUPPORTED) {
422                         /* device offline / unreachable */
423                         g_set_error_literal (error, 1, 0,
424 @@ -533,6 +529,7 @@ hidpp_device_refresh (HidppDevice *device,
425  
426         /* get version */
427         if ((refresh_flags & HIDPP_REFRESH_FLAGS_VERSION) > 0) {
428 +               /* first try v2 packet */
429                 buf[0] = 0x00;
430                 buf[1] = 0x00;
431                 buf[2] = HIDPP_PING_DATA;
432 @@ -543,9 +540,32 @@ hidpp_device_refresh (HidppDevice *device,
433                                         buf, 3,
434                                         buf, 4,
435                                         error);
436 -               if (!ret)
437 -                       goto out;
438 -               priv->version = buf[0];
439 +               if (ret)
440 +                       priv->version = buf[0];
441 +               /* then try v1 packet */
442 +               else {
443 +                       /* discard potential v1 error */
444 +                       g_clear_error (error);
445 +
446 +                       /* checking hid++ v1 packet */
447 +                       buf[0] = 0x00;
448 +                       buf[1] = 0x00;
449 +                       buf[2] = 0x00;
450 +
451 +                       ret = hidpp_device_cmd (device,
452 +                                       HIDPP_RECEIVER_ADDRESS,
453 +                                       HIDPP_READ_SHORT_REGISTER,
454 +                                       HIDPP_READ_SHORT_REGISTER_CONNECTION_STATE,
455 +                                       buf, 3,
456 +                                       buf, 2,
457 +                                       error);
458 +
459 +                       if (!ret)
460 +                               goto out;
461 +
462 +                       priv->version = 1;
463 +               }
464 +
465         }
466  
467         /* get device kind */
468 diff --git a/src/linux/up-device-unifying.c b/src/linux/up-device-unifying.c
469 index f6636e6..ea8b0b3 100644
470 --- a/src/linux/up-device-unifying.c
471 +++ b/src/linux/up-device-unifying.c
472 @@ -52,13 +52,25 @@ up_device_unifying_refresh (UpDevice *device)
473         gboolean ret;
474         GError *error = NULL;
475         GTimeVal timeval;
476 +       HidppRefreshFlags refresh_flags;
477         UpDeviceState state = UP_DEVICE_STATE_UNKNOWN;
478         UpDeviceUnifying *unifying = UP_DEVICE_UNIFYING (device);
479         UpDeviceUnifyingPrivate *priv = unifying->priv;
480  
481 -       /* refresh just the battery stats */
482 +       /* refresh the battery stats */
483 +       refresh_flags = HIDPP_REFRESH_FLAGS_BATTERY;
484 +
485 +       /*
486 +        * Device hid++ v2 when in unreachable mode seems to be able
487 +        * to respond to hid++ v1 queries (but fails to respond to v2
488 +        * queries). When it gets waken up it starts responding
489 +        * to v2 queries, so always try to upgrade protocol to v2
490 +        */
491 +       if (hidpp_device_get_version (priv->hidpp_device) < 2)
492 +               refresh_flags |= HIDPP_REFRESH_FLAGS_VERSION;
493 +
494         ret = hidpp_device_refresh (priv->hidpp_device,
495 -                                   HIDPP_REFRESH_FLAGS_BATTERY,
496 +                                   refresh_flags,
497                                     &error);
498         if (!ret) {
499                 g_warning ("failed to coldplug unifying device: %s",
500 diff --git a/src/linux/hidpp-device.c b/src/linux/hidpp-device.c
501 index 5398a38..1ce48b7 100644
502 --- a/src/linux/hidpp-device.c
503 +++ b/src/linux/hidpp-device.c
504 @@ -46,7 +46,6 @@
505  /* HID++ 1.0 */
506  #define HIDPP_READ_SHORT_REGISTER                              0x81
507  #define HIDPP_READ_SHORT_REGISTER_BATTERY                      0x0d
508 -#define HIDPP_READ_SHORT_REGISTER_CONNECTION_STATE             0x02
509  
510  #define HIDPP_READ_LONG_REGISTER                               0x83
511  #define HIDPP_READ_LONG_REGISTER_DEVICE_TYPE                   11
512 @@ -315,11 +314,10 @@ hidpp_device_cmd (HidppDevice     *device,
513             buf[2] == HIDPP_ERR_INVALID_SUBID &&
514             buf[3] == 0x00 &&
515             buf[4] == HIDPP_FEATURE_ROOT_FN_PING) {
516 -               if (buf[5] == HIDPP_ERROR_CODE_UNSUPPORTED) {
517 -                       /* device offline / unreachable */
518 -                       g_set_error_literal (error, 1, 0,
519 -                                            "device is unreachable");
520 -                       ret = FALSE;
521 +               /* HID++ 1.0 ping reply, so fake success with version 1  */
522 +               if (priv->version < 2 && (buf[5] == HIDPP_ERROR_CODE_UNKNOWN
523 +                                       || buf[5] == HIDPP_ERROR_CODE_UNSUPPORTED)) {
524 +                       response_data[0] = 1;
525                         goto out;
526                 }
527         }
528 @@ -504,32 +502,12 @@ hidpp_device_refresh (HidppDevice *device,
529                         ret = FALSE;
530                         goto out;
531                 }
532 -
533 -               /* add features we are going to use */
534 -//             hidpp_device_map_add (device,
535 -//                                   HIDPP_FEATURE_I_FEATURE_SET,
536 -//                                   "IFeatureSet");
537 -//             hidpp_device_map_add (device,
538 -//                                   HIDPP_FEATURE_I_FIRMWARE_INFO,
539 -//                                   "IFirmwareInfo");
540 -               hidpp_device_map_add (device,
541 -                                     HIDPP_FEATURE_GET_DEVICE_NAME_TYPE,
542 -                                     "GetDeviceNameType");
543 -               hidpp_device_map_add (device,
544 -                                     HIDPP_FEATURE_BATTERY_LEVEL_STATUS,
545 -                                     "BatteryLevelStatus");
546 -//             hidpp_device_map_add (device,
547 -//                                   HIDPP_FEATURE_WIRELESS_DEVICE_STATUS,
548 -//                                   "WirelessDeviceStatus");
549 -               hidpp_device_map_add (device,
550 -                                     HIDPP_FEATURE_SOLAR_DASHBOARD,
551 -                                     "SolarDashboard");
552 -               hidpp_device_map_print (device);
553         }
554  
555         /* get version */
556         if ((refresh_flags & HIDPP_REFRESH_FLAGS_VERSION) > 0) {
557 -               /* first try v2 packet */
558 +               guint version_old = priv->version;
559 +
560                 buf[0] = 0x00;
561                 buf[1] = 0x00;
562                 buf[2] = HIDPP_PING_DATA;
563 @@ -540,34 +518,43 @@ hidpp_device_refresh (HidppDevice *device,
564                                         buf, 3,
565                                         buf, 4,
566                                         error);
567 -               if (ret)
568 -                       priv->version = buf[0];
569 -               /* then try v1 packet */
570 -               else {
571 -                       /* discard potential v1 error */
572 -                       g_clear_error (error);
573 -
574 -                       /* checking hid++ v1 packet */
575 -                       buf[0] = 0x00;
576 -                       buf[1] = 0x00;
577 -                       buf[2] = 0x00;
578 +               if (!ret)
579 +                       goto out;
580  
581 -                       ret = hidpp_device_cmd (device,
582 -                                       HIDPP_RECEIVER_ADDRESS,
583 -                                       HIDPP_READ_SHORT_REGISTER,
584 -                                       HIDPP_READ_SHORT_REGISTER_CONNECTION_STATE,
585 -                                       buf, 3,
586 -                                       buf, 2,
587 -                                       error);
588 +               priv->version = buf[0];
589  
590 -                       if (!ret)
591 -                               goto out;
592 +               if (version_old != priv->version)
593 +                       g_debug("protocol for hid++ device changed from v%d to v%d",
594 +                                       version_old, priv->version);
595  
596 -                       priv->version = 1;
597 -               }
598 +               if (version_old < 2 && priv->version >= 2)
599 +                       refresh_flags |= HIDPP_REFRESH_FLAGS_FEATURES;
600  
601         }
602  
603 +       if ((refresh_flags & HIDPP_REFRESH_FLAGS_FEATURES) > 0) {
604 +               /* add features we are going to use */
605 +//             hidpp_device_map_add (device,
606 +//                                   HIDPP_FEATURE_I_FEATURE_SET,
607 +//                                   "IFeatureSet");
608 +//             hidpp_device_map_add (device,
609 +//                                   HIDPP_FEATURE_I_FIRMWARE_INFO,
610 +//                                   "IFirmwareInfo");
611 +               hidpp_device_map_add (device,
612 +                               HIDPP_FEATURE_GET_DEVICE_NAME_TYPE,
613 +                               "GetDeviceNameType");
614 +               hidpp_device_map_add (device,
615 +                               HIDPP_FEATURE_BATTERY_LEVEL_STATUS,
616 +                               "BatteryLevelStatus");
617 +//             hidpp_device_map_add (device,
618 +//                                   HIDPP_FEATURE_WIRELESS_DEVICE_STATUS,
619 +//                                   "WirelessDeviceStatus");
620 +               hidpp_device_map_add (device,
621 +                               HIDPP_FEATURE_SOLAR_DASHBOARD,
622 +                               "SolarDashboard");
623 +               hidpp_device_map_print (device);
624 +       }
625 +
626         /* get device kind */
627         if ((refresh_flags & HIDPP_REFRESH_FLAGS_KIND) > 0) {
628  
629 diff --git a/src/linux/hidpp-device.h b/src/linux/hidpp-device.h
630 index 935cd07..3f249a8 100644
631 --- a/src/linux/hidpp-device.h
632 +++ b/src/linux/hidpp-device.h
633 @@ -68,7 +68,8 @@ typedef enum {
634         HIDPP_REFRESH_FLAGS_VERSION     = 1,
635         HIDPP_REFRESH_FLAGS_KIND        = 2,
636         HIDPP_REFRESH_FLAGS_BATTERY     = 4,
637 -       HIDPP_REFRESH_FLAGS_MODEL       = 8
638 +       HIDPP_REFRESH_FLAGS_MODEL       = 8,
639 +       HIDPP_REFRESH_FLAGS_FEATURES    = 16
640  } HidppRefreshFlags;
641  
642  GType                   hidpp_device_get_type                  (void);
643
644 diff --git a/src/linux/up-device-unifying.c b/src/linux/up-device-unifying.c
645 index ea8b0b3..9023ac2 100644
646 --- a/src/linux/up-device-unifying.c
647 +++ b/src/linux/up-device-unifying.c
648 @@ -183,11 +188,32 @@ up_device_unifying_coldplug (UpDevice *device)
649         hidraw_list = g_udev_client_query_by_subsystem (client, "hidraw");
650         for (l = hidraw_list; l != NULL; l = l->next) {
651                 if (g_strcmp0 (type, "lg-wireless") == 0) {
652 +                       gboolean receiver_found = FALSE;
653 +                       const gchar *filename;
654 +                       GDir* dir;
655 +
656                         if (g_strcmp0 (g_udev_device_get_sysfs_path (native),
657                                                 g_udev_device_get_sysfs_path(g_udev_device_get_parent(l->data))) != 0)
658                                 continue;
659 -                       // Ugly way to distinguish receiver itself from mouse/keyboard etc for non-unifying dongles
660 -                       if (g_strcmp0(g_udev_device_get_property(g_udev_device_get_parent (native), "INTERFACE"), "3/0/0") != 0)
661 +
662 +                       /* hidraw device which exposes hiddev interface is our receiver */
663 +                       tmp = g_build_filename(g_udev_device_get_sysfs_path (g_udev_device_get_parent(native)),
664 +                                       "usbmisc", NULL);
665 +                       dir = g_dir_open (tmp, 0, &error);
666 +                       g_free(tmp);
667 +                       if (error) {
668 +                               g_clear_error(&error);
669 +                               continue;
670 +                       }
671 +                       while ( (filename = g_dir_read_name(dir)) ) {
672 +                               if (g_ascii_strncasecmp(filename, "hiddev", 6) == 0) {
673 +                                       receiver_found = TRUE;
674 +                                       break;
675 +                               }
676 +                       }
677 +                       g_dir_close(dir);
678 +
679 +                       if (!receiver_found)
680                                 continue;
681                 } else {
682                         if (g_strcmp0 (g_udev_device_get_sysfs_path (parent),
683
684 diff --git a/rules/95-upower-csr.rules b/rules/95-upower-csr.rules
685 index b476660..ffd55b2 100644
686 --- a/rules/95-upower-csr.rules
687 +++ b/rules/95-upower-csr.rules
688 @@ -25,5 +25,6 @@ SUBSYSTEM!="hid", GOTO="up_unifying_end"
689  ATTRS{idVendor}=="046d", ENV{UPOWER_VENDOR}="Logitech, Inc."
690  ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c52b", DRIVER=="logitech-djdevice", ENV{UPOWER_BATTERY_TYPE}="unifying"
691  ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c532", DRIVER=="logitech-djdevice", ENV{UPOWER_BATTERY_TYPE}="unifying"
692 +ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c52e", ENV{UPOWER_BATTERY_TYPE}="lg-wireless"
693  ATTRS{idVendor}=="046d", ATTRS{idProduct}=="c52f", ENV{UPOWER_BATTERY_TYPE}="lg-wireless"
694  LABEL="up_unifying_end"
This page took 0.084636 seconds and 3 git commands to generate.