Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/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
This commit is contained in:
Коммит
5e335542de
|
@ -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);
|
||||
|
@ -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),
|
||||
|
|
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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:
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
@ -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,
|
||||
|
|
|
@ -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 }
|
||||
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
Загрузка…
Ссылка в новой задаче