Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 2 Jun 2017 16:23:56 +0000 (09:23 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 2 Jun 2017 16:23:56 +0000 (09:23 -0700)
Pull HID fixes from Jiri Kosina:

 - corner-case oops fixes for Asus and Wacom drivers from Carlo Caione
   and Jason Gerecke

 - power management fix (reported on SIS0817 touchscreen) for i2c-hid
   devices from Hans de Goede

 - device-id-specific fixes and quirks from Hans de Goede, Diego Elio
   Pettenò and Che-Liang Chiou

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid:
  HID: asus: Stop underlying hardware on remove
  HID: i2c: Call acpi_device_fix_up_power for ACPI-enumerated devices
  HID: asus: Add support for T100 keyboard
  HID: elecom: extend to fix the descriptor for DEFT trackballs
  HID: magicmouse: Set multi-touch keybits for Magic Mouse
  HID: wacom: Have wacom_tpc_irq guard against possible NULL dereference

drivers/hid/Kconfig
drivers/hid/hid-asus.c
drivers/hid/hid-core.c
drivers/hid/hid-elecom.c
drivers/hid/hid-ids.h
drivers/hid/hid-magicmouse.c
drivers/hid/i2c-hid/i2c-hid.c
drivers/hid/wacom_wac.c

index fe40e5e499dd4122ce0f623d9df776c0a0cf2bdf..687705c5079422a82b9977e5694d0cd45b2a47bc 100644 (file)
@@ -275,10 +275,12 @@ config HID_EMS_FF
         - Trio Linker Plus II
 
 config HID_ELECOM
-       tristate "ELECOM BM084 bluetooth mouse"
+       tristate "ELECOM HID devices"
        depends on HID
        ---help---
-       Support for the ELECOM BM084 (bluetooth mouse).
+       Support for ELECOM devices:
+         - BM084 Bluetooth Mouse
+         - DEFT Trackball (Wired and wireless)
 
 config HID_ELO
        tristate "ELO USB 4000/4500 touchscreen"
index 16df6cc902359ea620de3f079be796d32be4783a..a6268f2f7408a520660c6add3c734a8006474393 100644 (file)
@@ -69,6 +69,7 @@ MODULE_DESCRIPTION("Asus HID Keyboard and TouchPad");
 #define QUIRK_IS_MULTITOUCH            BIT(3)
 #define QUIRK_NO_CONSUMER_USAGES       BIT(4)
 #define QUIRK_USE_KBD_BACKLIGHT                BIT(5)
+#define QUIRK_T100_KEYBOARD            BIT(6)
 
 #define I2C_KEYBOARD_QUIRKS                    (QUIRK_FIX_NOTEBOOK_REPORT | \
                                                 QUIRK_NO_INIT_REPORTS | \
@@ -536,6 +537,8 @@ static void asus_remove(struct hid_device *hdev)
                drvdata->kbd_backlight->removed = true;
                cancel_work_sync(&drvdata->kbd_backlight->work);
        }
+
+       hid_hw_stop(hdev);
 }
 
 static __u8 *asus_report_fixup(struct hid_device *hdev, __u8 *rdesc,
@@ -548,6 +551,12 @@ static __u8 *asus_report_fixup(struct hid_device *hdev, __u8 *rdesc,
                hid_info(hdev, "Fixing up Asus notebook report descriptor\n");
                rdesc[55] = 0xdd;
        }
+       if (drvdata->quirks & QUIRK_T100_KEYBOARD &&
+                *rsize == 76 && rdesc[73] == 0x81 && rdesc[74] == 0x01) {
+               hid_info(hdev, "Fixing up Asus T100 keyb report descriptor\n");
+               rdesc[74] &= ~HID_MAIN_ITEM_CONSTANT;
+       }
+
        return rdesc;
 }
 
@@ -560,6 +569,9 @@ static const struct hid_device_id asus_devices[] = {
                USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD1) },
        { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
                USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD2), QUIRK_USE_KBD_BACKLIGHT },
+       { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
+               USB_DEVICE_ID_ASUSTEK_T100_KEYBOARD),
+         QUIRK_T100_KEYBOARD | QUIRK_NO_CONSUMER_USAGES },
        { }
 };
 MODULE_DEVICE_TABLE(hid, asus_devices);
index 37084b6457851ebe0d52361e327db9df07b86b2c..04cee65531d761c18e53775ffc784c3c3d993daa 100644 (file)
@@ -1855,6 +1855,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
        { HID_I2C_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_I2C_TOUCHPAD) },
        { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD1) },
        { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD2) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_T100_KEYBOARD) },
        { HID_USB_DEVICE(USB_VENDOR_ID_AUREAL, USB_DEVICE_ID_AUREAL_W01RN) },
        { HID_USB_DEVICE(USB_VENDOR_ID_BELKIN, USB_DEVICE_ID_FLIP_KVM) },
        { HID_USB_DEVICE(USB_VENDOR_ID_BETOP_2185BFM, 0x2208) },
@@ -1891,6 +1892,8 @@ static const struct hid_device_id hid_have_special_driver[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_DREAM_CHEEKY, USB_DEVICE_ID_DREAM_CHEEKY_WN) },
        { HID_USB_DEVICE(USB_VENDOR_ID_DREAM_CHEEKY, USB_DEVICE_ID_DREAM_CHEEKY_FA) },
        { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_DEFT_WIRED) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_DEFT_WIRELESS) },
        { HID_USB_DEVICE(USB_VENDOR_ID_ELO, 0x0009) },
        { HID_USB_DEVICE(USB_VENDOR_ID_ELO, 0x0030) },
        { HID_USB_DEVICE(USB_VENDOR_ID_ELO, USB_DEVICE_ID_ELO_ACCUTOUCH_2216) },
index 6e3848a8d8dd1416a0091ce0e7d263325dd8910b..e2c7465df69f3ae74c2cb1979c531b02e2934089 100644 (file)
@@ -1,10 +1,8 @@
 /*
- *  HID driver for Elecom BM084 (bluetooth mouse).
- *  Removes a non-existing horizontal wheel from
- *  the HID descriptor.
- *  (This module is based on "hid-ortek".)
- *
+ *  HID driver for ELECOM devices.
  *  Copyright (c) 2010 Richard Nauber <Richard.Nauber@gmail.com>
+ *  Copyright (c) 2016 Yuxuan Shui <yshuiv7@gmail.com>
+ *  Copyright (c) 2017 Diego Elio Pettenò <flameeyes@flameeyes.eu>
  */
 
 /*
 static __u8 *elecom_report_fixup(struct hid_device *hdev, __u8 *rdesc,
                unsigned int *rsize)
 {
-       if (*rsize >= 48 && rdesc[46] == 0x05 && rdesc[47] == 0x0c) {
-               hid_info(hdev, "Fixing up Elecom BM084 report descriptor\n");
-               rdesc[47] = 0x00;
+       switch (hdev->product) {
+       case USB_DEVICE_ID_ELECOM_BM084:
+               /* The BM084 Bluetooth mouse includes a non-existing horizontal
+                * wheel in the HID descriptor. */
+               if (*rsize >= 48 && rdesc[46] == 0x05 && rdesc[47] == 0x0c) {
+                       hid_info(hdev, "Fixing up Elecom BM084 report descriptor\n");
+                       rdesc[47] = 0x00;
+               }
+               break;
+       case USB_DEVICE_ID_ELECOM_DEFT_WIRED:
+       case USB_DEVICE_ID_ELECOM_DEFT_WIRELESS:
+               /* The DEFT trackball has eight buttons, but its descriptor only
+                * reports five, disabling the three Fn buttons on the top of
+                * the mouse.
+                *
+                * Apply the following diff to the descriptor:
+                *
+                * Collection (Physical),              Collection (Physical),
+                *     Report ID (1),                      Report ID (1),
+                *     Report Count (5),           ->      Report Count (8),
+                *     Report Size (1),                    Report Size (1),
+                *     Usage Page (Button),                Usage Page (Button),
+                *     Usage Minimum (01h),                Usage Minimum (01h),
+                *     Usage Maximum (05h),        ->      Usage Maximum (08h),
+                *     Logical Minimum (0),                Logical Minimum (0),
+                *     Logical Maximum (1),                Logical Maximum (1),
+                *     Input (Variable),                   Input (Variable),
+                *     Report Count (1),           ->      Report Count (0),
+                *     Report Size (3),                    Report Size (3),
+                *     Input (Constant),                   Input (Constant),
+                *     Report Size (16),                   Report Size (16),
+                *     Report Count (2),                   Report Count (2),
+                *     Usage Page (Desktop),               Usage Page (Desktop),
+                *     Usage (X),                          Usage (X),
+                *     Usage (Y),                          Usage (Y),
+                *     Logical Minimum (-32768),           Logical Minimum (-32768),
+                *     Logical Maximum (32767),            Logical Maximum (32767),
+                *     Input (Variable, Relative),         Input (Variable, Relative),
+                * End Collection,                     End Collection,
+                */
+               if (*rsize == 213 && rdesc[13] == 5 && rdesc[21] == 5) {
+                       hid_info(hdev, "Fixing up Elecom DEFT Fn buttons\n");
+                       rdesc[13] = 8; /* Button/Variable Report Count */
+                       rdesc[21] = 8; /* Button/Variable Usage Maximum */
+                       rdesc[29] = 0; /* Button/Constant Report Count */
+               }
+               break;
        }
        return rdesc;
 }
 
 static const struct hid_device_id elecom_devices[] = {
-       { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084)},
+       { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_DEFT_WIRED) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_DEFT_WIRELESS) },
        { }
 };
 MODULE_DEVICE_TABLE(hid, elecom_devices);
index 643390ba749d96c5ddb5fbde68fda45c38569c3d..8ca1e8ce0af24e325957526c125ccf55d9081eb8 100644 (file)
 #define USB_VENDOR_ID_ASUSTEK          0x0b05
 #define USB_DEVICE_ID_ASUSTEK_LCM      0x1726
 #define USB_DEVICE_ID_ASUSTEK_LCM2     0x175b
+#define USB_DEVICE_ID_ASUSTEK_T100_KEYBOARD    0x17e0
 #define USB_DEVICE_ID_ASUSTEK_I2C_KEYBOARD     0x8585
 #define USB_DEVICE_ID_ASUSTEK_I2C_TOUCHPAD     0x0101
 #define USB_DEVICE_ID_ASUSTEK_ROG_KEYBOARD1 0x1854
 
 #define USB_VENDOR_ID_ELECOM           0x056e
 #define USB_DEVICE_ID_ELECOM_BM084     0x0061
+#define USB_DEVICE_ID_ELECOM_DEFT_WIRED        0x00fe
+#define USB_DEVICE_ID_ELECOM_DEFT_WIRELESS     0x00ff
 
 #define USB_VENDOR_ID_DREAM_CHEEKY     0x1d34
 #define USB_DEVICE_ID_DREAM_CHEEKY_WN  0x0004
index 20b40ad2632503754685b84cc07d8787a4a44515..1d6c997b300149269367d00fb5db66b7c2ea25b7 100644 (file)
@@ -349,6 +349,7 @@ static int magicmouse_raw_event(struct hid_device *hdev,
 
        if (input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE) {
                magicmouse_emit_buttons(msc, clicks & 3);
+               input_mt_report_pointer_emulation(input, true);
                input_report_rel(input, REL_X, x);
                input_report_rel(input, REL_Y, y);
        } else { /* USB_DEVICE_ID_APPLE_MAGICTRACKPAD */
@@ -388,16 +389,16 @@ static int magicmouse_setup_input(struct input_dev *input, struct hid_device *hd
                __clear_bit(BTN_RIGHT, input->keybit);
                __clear_bit(BTN_MIDDLE, input->keybit);
                __set_bit(BTN_MOUSE, input->keybit);
-               __set_bit(BTN_TOOL_FINGER, input->keybit);
-               __set_bit(BTN_TOOL_DOUBLETAP, input->keybit);
-               __set_bit(BTN_TOOL_TRIPLETAP, input->keybit);
-               __set_bit(BTN_TOOL_QUADTAP, input->keybit);
-               __set_bit(BTN_TOOL_QUINTTAP, input->keybit);
-               __set_bit(BTN_TOUCH, input->keybit);
-               __set_bit(INPUT_PROP_POINTER, input->propbit);
                __set_bit(INPUT_PROP_BUTTONPAD, input->propbit);
        }
 
+       __set_bit(BTN_TOOL_FINGER, input->keybit);
+       __set_bit(BTN_TOOL_DOUBLETAP, input->keybit);
+       __set_bit(BTN_TOOL_TRIPLETAP, input->keybit);
+       __set_bit(BTN_TOOL_QUADTAP, input->keybit);
+       __set_bit(BTN_TOOL_QUINTTAP, input->keybit);
+       __set_bit(BTN_TOUCH, input->keybit);
+       __set_bit(INPUT_PROP_POINTER, input->propbit);
 
        __set_bit(EV_ABS, input->evbit);
 
index 8daa8ce64ebba51e91e57ec801fa7e702fb2a072..fb55fb4c39fcfecaca55c0b8720d28d2f9717678 100644 (file)
@@ -897,6 +897,15 @@ static int i2c_hid_acpi_pdata(struct i2c_client *client,
        return 0;
 }
 
+static void i2c_hid_acpi_fix_up_power(struct device *dev)
+{
+       acpi_handle handle = ACPI_HANDLE(dev);
+       struct acpi_device *adev;
+
+       if (handle && acpi_bus_get_device(handle, &adev) == 0)
+               acpi_device_fix_up_power(adev);
+}
+
 static const struct acpi_device_id i2c_hid_acpi_match[] = {
        {"ACPI0C50", 0 },
        {"PNP0C50", 0 },
@@ -909,6 +918,8 @@ static inline int i2c_hid_acpi_pdata(struct i2c_client *client,
 {
        return -ENODEV;
 }
+
+static inline void i2c_hid_acpi_fix_up_power(struct device *dev) {}
 #endif
 
 #ifdef CONFIG_OF
@@ -1030,6 +1041,8 @@ static int i2c_hid_probe(struct i2c_client *client,
        if (ret < 0)
                goto err_regulator;
 
+       i2c_hid_acpi_fix_up_power(&client->dev);
+
        pm_runtime_get_noresume(&client->dev);
        pm_runtime_set_active(&client->dev);
        pm_runtime_enable(&client->dev);
index 4b225fb19a16842f635026d1b1023d5d1cf5068e..e274c9dc32f3a211d97d02f2b6477f20c9121fac 100644 (file)
@@ -1571,37 +1571,38 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len)
 {
        unsigned char *data = wacom->data;
 
-       if (wacom->pen_input)
+       if (wacom->pen_input) {
                dev_dbg(wacom->pen_input->dev.parent,
                        "%s: received report #%d\n", __func__, data[0]);
-       else if (wacom->touch_input)
+
+               if (len == WACOM_PKGLEN_PENABLED ||
+                   data[0] == WACOM_REPORT_PENABLED)
+                       return wacom_tpc_pen(wacom);
+       }
+       else if (wacom->touch_input) {
                dev_dbg(wacom->touch_input->dev.parent,
                        "%s: received report #%d\n", __func__, data[0]);
 
-       switch (len) {
-       case WACOM_PKGLEN_TPC1FG:
-               return wacom_tpc_single_touch(wacom, len);
+               switch (len) {
+               case WACOM_PKGLEN_TPC1FG:
+                       return wacom_tpc_single_touch(wacom, len);
 
-       case WACOM_PKGLEN_TPC2FG:
-               return wacom_tpc_mt_touch(wacom);
+               case WACOM_PKGLEN_TPC2FG:
+                       return wacom_tpc_mt_touch(wacom);
 
-       case WACOM_PKGLEN_PENABLED:
-               return wacom_tpc_pen(wacom);
+               default:
+                       switch (data[0]) {
+                       case WACOM_REPORT_TPC1FG:
+                       case WACOM_REPORT_TPCHID:
+                       case WACOM_REPORT_TPCST:
+                       case WACOM_REPORT_TPC1FGE:
+                               return wacom_tpc_single_touch(wacom, len);
 
-       default:
-               switch (data[0]) {
-               case WACOM_REPORT_TPC1FG:
-               case WACOM_REPORT_TPCHID:
-               case WACOM_REPORT_TPCST:
-               case WACOM_REPORT_TPC1FGE:
-                       return wacom_tpc_single_touch(wacom, len);
-
-               case WACOM_REPORT_TPCMT:
-               case WACOM_REPORT_TPCMT2:
-                       return wacom_mt_touch(wacom);
+                       case WACOM_REPORT_TPCMT:
+                       case WACOM_REPORT_TPCMT2:
+                               return wacom_mt_touch(wacom);
 
-               case WACOM_REPORT_PENABLED:
-                       return wacom_tpc_pen(wacom);
+                       }
                }
        }