Skip to content

Commit

Permalink
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/jikos/hid

Pull HID fixes from Jiri Kosina:

 - functional regression fix for sensor-hub driver from Hans de Goede

 - stop doing device reset for i2c-hid devices, which unbreaks some of
   them (and is in line with the specification), from Kai-Heng Feng

 - error handling fix for hid-core from Gustavo A. R. Silva

 - functional regression fix for some Elan panels from Benjamin
   Tissoires

 - a few new device ID additions and misc small fixes

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/hid:
  HID: i2c-hid: Don't reset device upon system resume
  HID: sensor-hub: Restore fixup for Lenovo ThinkPad Helix 2 sensor hub report
  HID: core: fix NULL pointer dereference
  HID: core: fix grouping by application
  HID: multitouch: fix Elan panels with 2 input modes declaration
  HID: hid-saitek: Add device ID for RAT 7 Contagion
  HID: core: fix memory leak on probe
  HID: input: fix leaking custom input node name
  HID: add support for Apple Magic Keyboards
  HID: i2c-hid: Fix flooded incomplete report after S3 on Rayd touchscreen
  HID: intel-ish-hid: Enable Sunrise Point-H ish driver
  • Loading branch information
Linus Torvalds committed Sep 12, 2018
2 parents 28a0ea7 + 52cf93e commit 5e33554
Show file tree
Hide file tree
Showing 11 changed files with 70 additions and 13 deletions.
9 changes: 8 additions & 1 deletion drivers/hid/hid-apple.c
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,8 @@ static int apple_input_mapping(struct hid_device *hdev, struct hid_input *hi,
struct hid_field *field, struct hid_usage *usage,
unsigned long **bit, int *max)
{
if (usage->hid == (HID_UP_CUSTOM | 0x0003)) {
if (usage->hid == (HID_UP_CUSTOM | 0x0003) ||
usage->hid == (HID_UP_MSVENDOR | 0x0003)) {
/* The fn key on Apple USB keyboards */
set_bit(EV_REP, hi->input->evbit);
hid_map_usage_clear(hi, usage, bit, max, EV_KEY, KEY_FN);
Expand Down Expand Up @@ -472,6 +473,12 @@ static const struct hid_device_id apple_devices[] = {
.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_ANSI),
.driver_data = APPLE_HAS_FN },
{ HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_ANSI),
.driver_data = APPLE_HAS_FN },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_ANSI),
.driver_data = APPLE_HAS_FN },
{ HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_ANSI),
.driver_data = APPLE_HAS_FN },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ANSI),
.driver_data = APPLE_HAS_FN },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING_ISO),
Expand Down
5 changes: 4 additions & 1 deletion drivers/hid/hid-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1000,7 +1000,7 @@ int hid_open_report(struct hid_device *device)
parser = vzalloc(sizeof(struct hid_parser));
if (!parser) {
ret = -ENOMEM;
goto err;
goto alloc_err;
}

parser->device = device;
Expand Down Expand Up @@ -1039,6 +1039,7 @@ int hid_open_report(struct hid_device *device)
hid_err(device, "unbalanced delimiter at end of report description\n");
goto err;
}
kfree(parser->collection_stack);
vfree(parser);
device->status |= HID_STAT_PARSED;
return 0;
Expand All @@ -1047,6 +1048,8 @@ int hid_open_report(struct hid_device *device)

hid_err(device, "item fetching failed at offset %d\n", (int)(end - start));
err:
kfree(parser->collection_stack);
alloc_err:
vfree(parser);
hid_close_report(device);
return ret;
Expand Down
6 changes: 3 additions & 3 deletions drivers/hid/hid-ids.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@
#define USB_DEVICE_ID_ANTON_TOUCH_PAD 0x3101

#define USB_VENDOR_ID_APPLE 0x05ac
#define BT_VENDOR_ID_APPLE 0x004c
#define USB_DEVICE_ID_APPLE_MIGHTYMOUSE 0x0304
#define USB_DEVICE_ID_APPLE_MAGICMOUSE 0x030d
#define USB_DEVICE_ID_APPLE_MAGICTRACKPAD 0x030e
Expand Down Expand Up @@ -157,6 +158,7 @@
#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_ISO 0x0256
#define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2011_JIS 0x0257
#define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_ANSI 0x0267
#define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_ANSI 0x026c
#define USB_DEVICE_ID_APPLE_WELLSPRING8_ANSI 0x0290
#define USB_DEVICE_ID_APPLE_WELLSPRING8_ISO 0x0291
#define USB_DEVICE_ID_APPLE_WELLSPRING8_JIS 0x0292
Expand Down Expand Up @@ -528,9 +530,6 @@
#define I2C_VENDOR_ID_HANTICK 0x0911
#define I2C_PRODUCT_ID_HANTICK_5288 0x5288

#define I2C_VENDOR_ID_RAYD 0x2386
#define I2C_PRODUCT_ID_RAYD_3118 0x3118

#define USB_VENDOR_ID_HANWANG 0x0b57
#define USB_DEVICE_ID_HANWANG_TABLET_FIRST 0x5000
#define USB_DEVICE_ID_HANWANG_TABLET_LAST 0x8fff
Expand Down Expand Up @@ -950,6 +949,7 @@
#define USB_DEVICE_ID_SAITEK_RUMBLEPAD 0xff17
#define USB_DEVICE_ID_SAITEK_PS1000 0x0621
#define USB_DEVICE_ID_SAITEK_RAT7_OLD 0x0ccb
#define USB_DEVICE_ID_SAITEK_RAT7_CONTAGION 0x0ccd
#define USB_DEVICE_ID_SAITEK_RAT7 0x0cd7
#define USB_DEVICE_ID_SAITEK_RAT9 0x0cfa
#define USB_DEVICE_ID_SAITEK_MMO7 0x0cd0
Expand Down
5 changes: 3 additions & 2 deletions drivers/hid/hid-input.c
Original file line number Diff line number Diff line change
Expand Up @@ -1582,6 +1582,7 @@ static struct hid_input *hidinput_allocate(struct hid_device *hid,
input_dev->dev.parent = &hid->dev;

hidinput->input = input_dev;
hidinput->application = application;
list_add_tail(&hidinput->list, &hid->inputs);

INIT_LIST_HEAD(&hidinput->reports);
Expand Down Expand Up @@ -1677,8 +1678,7 @@ static struct hid_input *hidinput_match_application(struct hid_report *report)
struct hid_input *hidinput;

list_for_each_entry(hidinput, &hid->inputs, list) {
if (hidinput->report &&
hidinput->report->application == report->application)
if (hidinput->application == report->application)
return hidinput;
}

Expand Down Expand Up @@ -1815,6 +1815,7 @@ void hidinput_disconnect(struct hid_device *hid)
input_unregister_device(hidinput->input);
else
input_free_device(hidinput->input);
kfree(hidinput->name);
kfree(hidinput);
}

Expand Down
19 changes: 17 additions & 2 deletions drivers/hid/hid-multitouch.c
Original file line number Diff line number Diff line change
Expand Up @@ -1375,7 +1375,8 @@ static bool mt_need_to_apply_feature(struct hid_device *hdev,
struct hid_usage *usage,
enum latency_mode latency,
bool surface_switch,
bool button_switch)
bool button_switch,
bool *inputmode_found)
{
struct mt_device *td = hid_get_drvdata(hdev);
struct mt_class *cls = &td->mtclass;
Expand All @@ -1387,6 +1388,14 @@ static bool mt_need_to_apply_feature(struct hid_device *hdev,

switch (usage->hid) {
case HID_DG_INPUTMODE:
/*
* Some elan panels wrongly declare 2 input mode features,
* and silently ignore when we set the value in the second
* field. Skip the second feature and hope for the best.
*/
if (*inputmode_found)
return false;

if (cls->quirks & MT_QUIRK_FORCE_GET_FEATURE) {
report_len = hid_report_len(report);
buf = hid_alloc_report_buf(report, GFP_KERNEL);
Expand All @@ -1402,6 +1411,7 @@ static bool mt_need_to_apply_feature(struct hid_device *hdev,
}

field->value[index] = td->inputmode_value;
*inputmode_found = true;
return true;

case HID_DG_CONTACTMAX:
Expand Down Expand Up @@ -1439,6 +1449,7 @@ static void mt_set_modes(struct hid_device *hdev, enum latency_mode latency,
struct hid_usage *usage;
int i, j;
bool update_report;
bool inputmode_found = false;

rep_enum = &hdev->report_enum[HID_FEATURE_REPORT];
list_for_each_entry(rep, &rep_enum->report_list, list) {
Expand All @@ -1457,7 +1468,8 @@ static void mt_set_modes(struct hid_device *hdev, enum latency_mode latency,
usage,
latency,
surface_switch,
button_switch))
button_switch,
&inputmode_found))
update_report = true;
}
}
Expand Down Expand Up @@ -1685,6 +1697,9 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
*/
hdev->quirks |= HID_QUIRK_INPUT_PER_APP;

if (id->group != HID_GROUP_MULTITOUCH_WIN_8)
hdev->quirks |= HID_QUIRK_MULTI_INPUT;

timer_setup(&td->release_timer, mt_expired_timeout, 0);

ret = hid_parse(hdev);
Expand Down
2 changes: 2 additions & 0 deletions drivers/hid/hid-saitek.c
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,8 @@ static const struct hid_device_id saitek_devices[] = {
.driver_data = SAITEK_RELEASE_MODE_RAT7 },
{ HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RAT7),
.driver_data = SAITEK_RELEASE_MODE_RAT7 },
{ HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RAT7_CONTAGION),
.driver_data = SAITEK_RELEASE_MODE_RAT7 },
{ HID_USB_DEVICE(USB_VENDOR_ID_SAITEK, USB_DEVICE_ID_SAITEK_RAT9),
.driver_data = SAITEK_RELEASE_MODE_RAT7 },
{ HID_USB_DEVICE(USB_VENDOR_ID_MADCATZ, USB_DEVICE_ID_MADCATZ_RAT9),
Expand Down
23 changes: 23 additions & 0 deletions drivers/hid/hid-sensor-hub.c
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,28 @@ void sensor_hub_device_close(struct hid_sensor_hub_device *hsdev)
}
EXPORT_SYMBOL_GPL(sensor_hub_device_close);

static __u8 *sensor_hub_report_fixup(struct hid_device *hdev, __u8 *rdesc,
unsigned int *rsize)
{
/*
* Checks if the report descriptor of Thinkpad Helix 2 has a logical
* minimum for magnetic flux axis greater than the maximum.
*/
if (hdev->product == USB_DEVICE_ID_TEXAS_INSTRUMENTS_LENOVO_YOGA &&
*rsize == 2558 && rdesc[913] == 0x17 && rdesc[914] == 0x40 &&
rdesc[915] == 0x81 && rdesc[916] == 0x08 &&
rdesc[917] == 0x00 && rdesc[918] == 0x27 &&
rdesc[921] == 0x07 && rdesc[922] == 0x00) {
/* Sets negative logical minimum for mag x, y and z */
rdesc[914] = rdesc[935] = rdesc[956] = 0xc0;
rdesc[915] = rdesc[936] = rdesc[957] = 0x7e;
rdesc[916] = rdesc[937] = rdesc[958] = 0xf7;
rdesc[917] = rdesc[938] = rdesc[959] = 0xff;
}

return rdesc;
}

static int sensor_hub_probe(struct hid_device *hdev,
const struct hid_device_id *id)
{
Expand Down Expand Up @@ -743,6 +765,7 @@ static struct hid_driver sensor_hub_driver = {
.probe = sensor_hub_probe,
.remove = sensor_hub_remove,
.raw_event = sensor_hub_raw_event,
.report_fixup = sensor_hub_report_fixup,
#ifdef CONFIG_PM
.suspend = sensor_hub_suspend,
.resume = sensor_hub_resume,
Expand Down
11 changes: 7 additions & 4 deletions drivers/hid/i2c-hid/i2c-hid.c
Original file line number Diff line number Diff line change
Expand Up @@ -170,8 +170,6 @@ static const struct i2c_hid_quirks {
I2C_HID_QUIRK_SET_PWR_WAKEUP_DEV },
{ I2C_VENDOR_ID_HANTICK, I2C_PRODUCT_ID_HANTICK_5288,
I2C_HID_QUIRK_NO_IRQ_AFTER_RESET },
{ I2C_VENDOR_ID_RAYD, I2C_PRODUCT_ID_RAYD_3118,
I2C_HID_QUIRK_RESEND_REPORT_DESCR },
{ USB_VENDOR_ID_SIS_TOUCH, USB_DEVICE_ID_SIS10FB_TOUCH,
I2C_HID_QUIRK_RESEND_REPORT_DESCR },
{ 0, 0 }
Expand Down Expand Up @@ -1235,11 +1233,16 @@ static int i2c_hid_resume(struct device *dev)
pm_runtime_enable(dev);

enable_irq(client->irq);
ret = i2c_hid_hwreset(client);

/* Instead of resetting device, simply powers the device on. This
* solves "incomplete reports" on Raydium devices 2386:3118 and
* 2386:4B33
*/
ret = i2c_hid_set_power(client, I2C_HID_PWR_ON);
if (ret)
return ret;

/* RAYDIUM device (2386:3118) need to re-send report descr cmd
/* Some devices need to re-send report descr cmd
* after resume, after this it will be back normal.
* otherwise it issues too many incomplete reports.
*/
Expand Down
1 change: 1 addition & 0 deletions drivers/hid/intel-ish-hid/ipc/hw-ish.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#define CNL_Ax_DEVICE_ID 0x9DFC
#define GLK_Ax_DEVICE_ID 0x31A2
#define CNL_H_DEVICE_ID 0xA37C
#define SPT_H_DEVICE_ID 0xA135

#define REVISION_ID_CHT_A0 0x6
#define REVISION_ID_CHT_Ax_SI 0x0
Expand Down
1 change: 1 addition & 0 deletions drivers/hid/intel-ish-hid/ipc/pci-ish.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ static const struct pci_device_id ish_pci_tbl[] = {
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, CNL_Ax_DEVICE_ID)},
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, GLK_Ax_DEVICE_ID)},
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, CNL_H_DEVICE_ID)},
{PCI_DEVICE(PCI_VENDOR_ID_INTEL, SPT_H_DEVICE_ID)},
{0, }
};
MODULE_DEVICE_TABLE(pci, ish_pci_tbl);
Expand Down
1 change: 1 addition & 0 deletions include/linux/hid.h
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,7 @@ struct hid_input {
const char *name;
bool registered;
struct list_head reports; /* the list of reports */
unsigned int application; /* application usage for this input */
};

enum hid_type {
Expand Down

0 comments on commit 5e33554

Please sign in to comment.