]> Git Repo - linux.git/commitdiff
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid
authorLinus Torvalds <[email protected]>
Tue, 7 May 2019 15:52:04 +0000 (08:52 -0700)
committerLinus Torvalds <[email protected]>
Tue, 7 May 2019 15:52:04 +0000 (08:52 -0700)
Pull HID updates from Jiri Kosina:

 - support for U2F Zero device, from Andrej Shadura

 - logitech-dj has historically been treating devices behind
   non-unifying receivers as generic devices, using the HID emulation in
   the receiver. That had several shortcomings (special keys handling,
   battery level monitoring, etc). The driver has been reworked to
   enumarate (and directly communicate with) the devices behind the
   receiver, to avoid the (too) generic HID implementation in the
   receiver itself. All the work done by Benjamin Tissoires and Hans de
   Goede.

 - restructuring of intel-ish driver in order to allow for multiple
   clients of the ISH implementation, from Srinivas Pandruvada

 - several other smaller fixes and assorted device ID additions

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid: (68 commits)
  HID: logitech-dj: fix spelling in printk
  HID: input: fix assignment of .value
  HID: input: make sure the wheel high resolution multiplier is set
  HID: logitech-dj: add usbhid dependency in Kconfig
  HID: logitech-hidpp: add support for HID++ 1.0 consumer keys reports
  HID: logitech-hidpp: add support for HID++ 1.0 extra mouse buttons reports
  HID: logitech-hidpp: add support for HID++ 1.0 wheel reports
  HID: logitech-hidpp: make hidpp10_set_register_bit a bit more generic
  HID: logitech-hidpp: add input_device ptr to struct hidpp_device
  HID: logitech-hidpp: do not hardcode very long report length
  HID: logitech-hidpp: handle devices attached to 27MHz wireless receivers
  HID: logitech-hidpp: use RAP instead of FAP to get the protocol version
  HID: logitech-hidpp: remove unused origin_is_hid_core function parameter
  HID: logitech-hidpp: remove double assignment from __hidpp_send_report
  HID: logitech-hidpp: do not make failure to get the name fatal
  HID: logitech-hidpp: ignore very-short or empty names
  HID: logitech-hidpp: make .probe usbhid capable
  HID: logitech-hidpp: allow non HID++ devices to be handled by this module
  HID: logitech-dj: add support for Logitech Bluetooth Mini-Receiver
  HID: logitech-dj: make appending of the HID++ descriptors conditional
  ...

1  2 
drivers/hid/hid-input.c

diff --combined drivers/hid/hid-input.c
index b607286a0bc82f360a133b5dce204a8f2441ff5c,6dd0294e11336f624f68413678bdf98240db11cf..46c6efea1404ee664eb2e44837e09c67553fc5c3
@@@ -680,14 -680,6 +680,14 @@@ static void hidinput_configure_usage(st
                        break;
                }
  
 +              if ((usage->hid & 0xf0) == 0xb0) {      /* SC - Display */
 +                      switch (usage->hid & 0xf) {
 +                      case 0x05: map_key_clear(KEY_SWITCHVIDEOMODE); break;
 +                      default: goto ignore;
 +                      }
 +                      break;
 +              }
 +
                /*
                 * Some lazy vendors declare 255 usages for System Control,
                 * leading to the creation of ABS_X|Y axis and too many others.
                case 0x06a: map_key_clear(KEY_GREEN);           break;
                case 0x06b: map_key_clear(KEY_BLUE);            break;
                case 0x06c: map_key_clear(KEY_YELLOW);          break;
 -              case 0x06d: map_key_clear(KEY_ZOOM);            break;
 +              case 0x06d: map_key_clear(KEY_ASPECT_RATIO);    break;
  
                case 0x06f: map_key_clear(KEY_BRIGHTNESSUP);            break;
                case 0x070: map_key_clear(KEY_BRIGHTNESSDOWN);          break;
                case 0x074: map_key_clear(KEY_BRIGHTNESS_MAX);          break;
                case 0x075: map_key_clear(KEY_BRIGHTNESS_AUTO);         break;
  
 +              case 0x079: map_key_clear(KEY_KBDILLUMUP);      break;
 +              case 0x07a: map_key_clear(KEY_KBDILLUMDOWN);    break;
 +              case 0x07c: map_key_clear(KEY_KBDILLUMTOGGLE);  break;
 +
                case 0x082: map_key_clear(KEY_VIDEO_NEXT);      break;
                case 0x083: map_key_clear(KEY_LAST);            break;
                case 0x084: map_key_clear(KEY_ENTER);           break;
                case 0x22d: map_key_clear(KEY_ZOOMIN);          break;
                case 0x22e: map_key_clear(KEY_ZOOMOUT);         break;
                case 0x22f: map_key_clear(KEY_ZOOMRESET);       break;
 +              case 0x232: map_key_clear(KEY_FULL_SCREEN);     break;
                case 0x233: map_key_clear(KEY_SCROLLUP);        break;
                case 0x234: map_key_clear(KEY_SCROLLDOWN);      break;
                case 0x238: /* AC Pan */
                case 0x2cb: map_key_clear(KEY_KBDINPUTASSIST_ACCEPT);   break;
                case 0x2cc: map_key_clear(KEY_KBDINPUTASSIST_CANCEL);   break;
  
 +              case 0x29f: map_key_clear(KEY_SCALE);           break;
 +
                default: map_key_clear(KEY_UNKNOWN);
                }
                break;
@@@ -1557,52 -1542,71 +1557,71 @@@ static void hidinput_close(struct input
        hid_hw_close(hid);
  }
  
- static void hidinput_change_resolution_multipliers(struct hid_device *hid)
+ static bool __hidinput_change_resolution_multipliers(struct hid_device *hid,
+               struct hid_report *report, bool use_logical_max)
  {
-       struct hid_report_enum *rep_enum;
-       struct hid_report *rep;
        struct hid_usage *usage;
+       bool update_needed = false;
        int i, j;
  
-       rep_enum = &hid->report_enum[HID_FEATURE_REPORT];
-       list_for_each_entry(rep, &rep_enum->report_list, list) {
-               bool update_needed = false;
+       if (report->maxfield == 0)
+               return false;
  
-               if (rep->maxfield == 0)
-                       continue;
+       /*
+        * If we have more than one feature within this report we
+        * need to fill in the bits from the others before we can
+        * overwrite the ones for the Resolution Multiplier.
+        */
+       if (report->maxfield > 1) {
+               hid_hw_request(hid, report, HID_REQ_GET_REPORT);
+               hid_hw_wait(hid);
+       }
  
-               /*
-                * If we have more than one feature within this report we
-                * need to fill in the bits from the others before we can
-                * overwrite the ones for the Resolution Multiplier.
+       for (i = 0; i < report->maxfield; i++) {
+               __s32 value = use_logical_max ?
+                             report->field[i]->logical_maximum :
+                             report->field[i]->logical_minimum;
+               /* There is no good reason for a Resolution
+                * Multiplier to have a count other than 1.
+                * Ignore that case.
                 */
-               if (rep->maxfield > 1) {
-                       hid_hw_request(hid, rep, HID_REQ_GET_REPORT);
-                       hid_hw_wait(hid);
-               }
+               if (report->field[i]->report_count != 1)
+                       continue;
  
-               for (i = 0; i < rep->maxfield; i++) {
-                       __s32 logical_max = rep->field[i]->logical_maximum;
+               for (j = 0; j < report->field[i]->maxusage; j++) {
+                       usage = &report->field[i]->usage[j];
  
-                       /* There is no good reason for a Resolution
-                        * Multiplier to have a count other than 1.
-                        * Ignore that case.
-                        */
-                       if (rep->field[i]->report_count != 1)
+                       if (usage->hid != HID_GD_RESOLUTION_MULTIPLIER)
                                continue;
  
-                       for (j = 0; j < rep->field[i]->maxusage; j++) {
-                               usage = &rep->field[i]->usage[j];
+                       report->field[i]->value[j] = value;
+                       update_needed = true;
+               }
+       }
+       return update_needed;
+ }
  
-                               if (usage->hid != HID_GD_RESOLUTION_MULTIPLIER)
-                                       continue;
+ static void hidinput_change_resolution_multipliers(struct hid_device *hid)
+ {
+       struct hid_report_enum *rep_enum;
+       struct hid_report *rep;
+       int ret;
  
-                               *rep->field[i]->value = logical_max;
-                               update_needed = true;
+       rep_enum = &hid->report_enum[HID_FEATURE_REPORT];
+       list_for_each_entry(rep, &rep_enum->report_list, list) {
+               bool update_needed = __hidinput_change_resolution_multipliers(hid,
+                                                                    rep, true);
+               if (update_needed) {
+                       ret = __hid_request(hid, rep, HID_REQ_SET_REPORT);
+                       if (ret) {
+                               __hidinput_change_resolution_multipliers(hid,
+                                                                   rep, false);
+                               return;
                        }
                }
-               if (update_needed)
-                       hid_hw_request(hid, rep, HID_REQ_SET_REPORT);
        }
  
        /* refresh our structs */
This page took 0.076994 seconds and 4 git commands to generate.