forked from Minki/linux
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid
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
This commit is contained in:
commit
6df62e7916
@ -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"
|
||||
|
@ -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);
|
||||
|
@ -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) },
|
||||
|
@ -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>
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -23,15 +21,61 @@
|
||||
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);
|
||||
|
@ -173,6 +173,7 @@
|
||||
#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
|
||||
@ -358,6 +359,8 @@
|
||||
|
||||
#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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
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:
|
||||
switch (len) {
|
||||
case WACOM_PKGLEN_TPC1FG:
|
||||
return wacom_tpc_single_touch(wacom, len);
|
||||
|
||||
case WACOM_REPORT_TPCMT:
|
||||
case WACOM_REPORT_TPCMT2:
|
||||
return wacom_mt_touch(wacom);
|
||||
case WACOM_PKGLEN_TPC2FG:
|
||||
return wacom_tpc_mt_touch(wacom);
|
||||
|
||||
case WACOM_REPORT_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);
|
||||
|
||||
case WACOM_REPORT_TPCMT:
|
||||
case WACOM_REPORT_TPCMT2:
|
||||
return wacom_mt_touch(wacom);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user