diff options
Diffstat (limited to 'drivers/hid')
-rw-r--r-- | drivers/hid/hid-chicony.c | 55 | ||||
-rw-r--r-- | drivers/hid/hid-core.c | 9 | ||||
-rw-r--r-- | drivers/hid/hid-ids.h | 4 | ||||
-rw-r--r-- | drivers/hid/hid-input.c | 12 | ||||
-rw-r--r-- | drivers/hid/hid-ite.c | 12 | ||||
-rw-r--r-- | drivers/hid/hid-logitech-dj.c | 8 | ||||
-rw-r--r-- | drivers/hid/hid-quirks.c | 25 | ||||
-rw-r--r-- | drivers/hid/hid-roccat-arvo.c | 6 | ||||
-rw-r--r-- | drivers/hid/i2c-hid/i2c-hid-core.c | 2 | ||||
-rw-r--r-- | drivers/hid/intel-ish-hid/ipc/hw-ish.h | 1 | ||||
-rw-r--r-- | drivers/hid/intel-ish-hid/ipc/pci-ish.c | 1 | ||||
-rw-r--r-- | drivers/hid/wacom_sys.c | 2 | ||||
-rw-r--r-- | drivers/hid/wacom_wac.c | 7 |
13 files changed, 121 insertions, 23 deletions
diff --git a/drivers/hid/hid-chicony.c b/drivers/hid/hid-chicony.c index 3f0ed6a95223..ca556d39da2a 100644 --- a/drivers/hid/hid-chicony.c +++ b/drivers/hid/hid-chicony.c @@ -21,6 +21,39 @@ #include "hid-ids.h" +#define CH_WIRELESS_CTL_REPORT_ID 0x11 + +static int ch_report_wireless(struct hid_report *report, u8 *data, int size) +{ + struct hid_device *hdev = report->device; + struct input_dev *input; + + if (report->id != CH_WIRELESS_CTL_REPORT_ID || report->maxfield != 1) + return 0; + + input = report->field[0]->hidinput->input; + if (!input) { + hid_warn(hdev, "can't find wireless radio control's input"); + return 0; + } + + input_report_key(input, KEY_RFKILL, 1); + input_sync(input); + input_report_key(input, KEY_RFKILL, 0); + input_sync(input); + + return 1; +} + +static int ch_raw_event(struct hid_device *hdev, + struct hid_report *report, u8 *data, int size) +{ + if (report->application == HID_GD_WIRELESS_RADIO_CTLS) + return ch_report_wireless(report, data, size); + + return 0; +} + #define ch_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, \ EV_KEY, (c)) static int ch_input_mapping(struct hid_device *hdev, struct hid_input *hi, @@ -77,10 +110,30 @@ static __u8 *ch_switch12_report_fixup(struct hid_device *hdev, __u8 *rdesc, return rdesc; } +static int ch_probe(struct hid_device *hdev, const struct hid_device_id *id) +{ + int ret; + + hdev->quirks |= HID_QUIRK_INPUT_PER_APP; + ret = hid_parse(hdev); + if (ret) { + hid_err(hdev, "Chicony hid parse failed: %d\n", ret); + return ret; + } + + ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); + if (ret) { + hid_err(hdev, "Chicony hw start failed: %d\n", ret); + return ret; + } + + return 0; +} static const struct hid_device_id ch_devices[] = { { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) }, { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS2) }, + { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS3) }, { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_ACER_SWITCH12) }, { } }; @@ -91,6 +144,8 @@ static struct hid_driver ch_driver = { .id_table = ch_devices, .report_fixup = ch_switch12_report_fixup, .input_mapping = ch_input_mapping, + .probe = ch_probe, + .raw_event = ch_raw_event, }; module_hid_driver(ch_driver); diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 56172fe6995c..097cb1ee3126 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -90,7 +90,7 @@ EXPORT_SYMBOL_GPL(hid_register_report); * Register a new field for this report. */ -static struct hid_field *hid_register_field(struct hid_report *report, unsigned usages, unsigned values) +static struct hid_field *hid_register_field(struct hid_report *report, unsigned usages) { struct hid_field *field; @@ -101,7 +101,7 @@ static struct hid_field *hid_register_field(struct hid_report *report, unsigned field = kzalloc((sizeof(struct hid_field) + usages * sizeof(struct hid_usage) + - values * sizeof(unsigned)), GFP_KERNEL); + usages * sizeof(unsigned)), GFP_KERNEL); if (!field) return NULL; @@ -300,7 +300,7 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign usages = max_t(unsigned, parser->local.usage_index, parser->global.report_count); - field = hid_register_field(report, usages, parser->global.report_count); + field = hid_register_field(report, usages); if (!field) return 0; @@ -1307,6 +1307,9 @@ EXPORT_SYMBOL_GPL(hid_open_report); static s32 snto32(__u32 value, unsigned n) { + if (!value || !n) + return 0; + switch (n) { case 8: return ((__s8)value); case 16: return ((__s16)value); diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 5ba0aa1d2335..abe6503ce5a6 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -270,6 +270,7 @@ #define USB_DEVICE_ID_CHICONY_PIXART_USB_OPTICAL_MOUSE 0x1053 #define USB_DEVICE_ID_CHICONY_PIXART_USB_OPTICAL_MOUSE2 0x0939 #define USB_DEVICE_ID_CHICONY_WIRELESS2 0x1123 +#define USB_DEVICE_ID_CHICONY_WIRELESS3 0x1236 #define USB_DEVICE_ID_ASUS_AK1D 0x1125 #define USB_DEVICE_ID_CHICONY_TOSHIBA_WT10A 0x1408 #define USB_DEVICE_ID_CHICONY_ACER_SWITCH12 0x1421 @@ -389,6 +390,7 @@ #define USB_DEVICE_ID_TOSHIBA_CLICK_L9W 0x0401 #define USB_DEVICE_ID_HP_X2 0x074d #define USB_DEVICE_ID_HP_X2_10_COVER 0x0755 +#define I2C_DEVICE_ID_HP_SPECTRE_X360_15 0x2817 #define USB_DEVICE_ID_ASUS_UX550_TOUCHSCREEN 0x2706 #define USB_VENDOR_ID_ELECOM 0x056e @@ -641,6 +643,8 @@ #define USB_DEVICE_ID_INNEX_GENESIS_ATARI 0x4745 #define USB_VENDOR_ID_ITE 0x048d +#define I2C_VENDOR_ID_ITE 0x103c +#define I2C_DEVICE_ID_ITE_VOYO_WINPAD_A15 0x184f #define USB_DEVICE_ID_ITE_LENOVO_YOGA 0x8386 #define USB_DEVICE_ID_ITE_LENOVO_YOGA2 0x8350 #define I2C_DEVICE_ID_ITE_LENOVO_LEGION_Y720 0x837a diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index f23027d2795b..236bccd37760 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -324,6 +324,8 @@ static const struct hid_device_id hid_battery_quirks[] = { HID_BATTERY_QUIRK_IGNORE }, { HID_USB_DEVICE(USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ASUS_UX550_TOUCHSCREEN), HID_BATTERY_QUIRK_IGNORE }, + { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_HP_SPECTRE_X360_15), + HID_BATTERY_QUIRK_IGNORE }, {} }; @@ -1854,6 +1856,16 @@ static struct hid_input *hidinput_match_application(struct hid_report *report) list_for_each_entry(hidinput, &hid->inputs, list) { if (hidinput->application == report->application) return hidinput; + + /* + * Keep SystemControl and ConsumerControl applications together + * with the main keyboard, if present. + */ + if ((report->application == HID_GD_SYSTEM_CONTROL || + report->application == HID_CP_CONSUMER_CONTROL) && + hidinput->application == HID_GD_KEYBOARD) { + return hidinput; + } } return NULL; diff --git a/drivers/hid/hid-ite.c b/drivers/hid/hid-ite.c index 22bfbebceaf4..14fc068affad 100644 --- a/drivers/hid/hid-ite.c +++ b/drivers/hid/hid-ite.c @@ -23,11 +23,16 @@ static __u8 *ite_report_fixup(struct hid_device *hdev, __u8 *rdesc, unsigned int hid_info(hdev, "Fixing up Acer Sw5-012 ITE keyboard report descriptor\n"); rdesc[163] = HID_MAIN_ITEM_RELATIVE; } - /* For Acer One S1002 keyboard-dock */ + /* For Acer One S1002/S1003 keyboard-dock */ if (*rsize == 188 && rdesc[185] == 0x81 && rdesc[186] == 0x02) { - hid_info(hdev, "Fixing up Acer S1002 ITE keyboard report descriptor\n"); + hid_info(hdev, "Fixing up Acer S1002/S1003 ITE keyboard report descriptor\n"); rdesc[186] = HID_MAIN_ITEM_RELATIVE; } + /* For Acer Aspire Switch 10E (SW3-016) keyboard-dock */ + if (*rsize == 210 && rdesc[184] == 0x81 && rdesc[185] == 0x02) { + hid_info(hdev, "Fixing up Acer Aspire Switch 10E (SW3-016) ITE keyboard report descriptor\n"); + rdesc[185] = HID_MAIN_ITEM_RELATIVE; + } } return rdesc; @@ -114,7 +119,8 @@ static const struct hid_device_id ite_devices[] = { /* ITE8910 USB kbd ctlr, with Synaptics touchpad connected to it. */ { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, USB_VENDOR_ID_SYNAPTICS, - USB_DEVICE_ID_SYNAPTICS_ACER_ONE_S1003) }, + USB_DEVICE_ID_SYNAPTICS_ACER_ONE_S1003), + .driver_data = QUIRK_TOUCHPAD_ON_OFF_REPORT }, { } }; MODULE_DEVICE_TABLE(hid, ite_devices); diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c index 45e7e0bdd382..271bd8d24339 100644 --- a/drivers/hid/hid-logitech-dj.c +++ b/drivers/hid/hid-logitech-dj.c @@ -980,6 +980,7 @@ static void logi_hidpp_recv_queue_notif(struct hid_device *hdev, case 0x07: device_type = "eQUAD step 4 Gaming"; logi_hidpp_dev_conn_notif_equad(hdev, hidpp_report, &workitem); + workitem.reports_supported |= STD_KEYBOARD; break; case 0x08: device_type = "eQUAD step 4 for gamepads"; @@ -994,7 +995,12 @@ static void logi_hidpp_recv_queue_notif(struct hid_device *hdev, workitem.reports_supported |= STD_KEYBOARD; break; case 0x0d: - device_type = "eQUAD Lightspeed 1_1"; + device_type = "eQUAD Lightspeed 1.1"; + logi_hidpp_dev_conn_notif_equad(hdev, hidpp_report, &workitem); + workitem.reports_supported |= STD_KEYBOARD; + break; + case 0x0f: + device_type = "eQUAD Lightspeed 1.2"; logi_hidpp_dev_conn_notif_equad(hdev, hidpp_report, &workitem); workitem.reports_supported |= STD_KEYBOARD; break; diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c index d9ca874dffac..15db7522b41e 100644 --- a/drivers/hid/hid-quirks.c +++ b/drivers/hid/hid-quirks.c @@ -1029,7 +1029,7 @@ static DEFINE_MUTEX(dquirks_lock); /* Runtime ("dynamic") quirks manipulation functions */ /** - * hid_exists_dquirk: find any dynamic quirks for a HID device + * hid_exists_dquirk - find any dynamic quirks for a HID device * @hdev: the HID device to match * * Description: @@ -1037,7 +1037,7 @@ static DEFINE_MUTEX(dquirks_lock); * the pointer to the relevant struct hid_device_id if found. * Must be called with a read lock held on dquirks_lock. * - * Returns: NULL if no quirk found, struct hid_device_id * if found. + * Return: NULL if no quirk found, struct hid_device_id * if found. */ static struct hid_device_id *hid_exists_dquirk(const struct hid_device *hdev) { @@ -1061,7 +1061,7 @@ static struct hid_device_id *hid_exists_dquirk(const struct hid_device *hdev) /** - * hid_modify_dquirk: add/replace a HID quirk + * hid_modify_dquirk - add/replace a HID quirk * @id: the HID device to match * @quirks: the unsigned long quirks value to add/replace * @@ -1070,7 +1070,7 @@ static struct hid_device_id *hid_exists_dquirk(const struct hid_device *hdev) * quirks value with what was provided. Otherwise, add the quirk * to the dynamic quirks list. * - * Returns: 0 OK, -error on failure. + * Return: 0 OK, -error on failure. */ static int hid_modify_dquirk(const struct hid_device_id *id, const unsigned long quirks) @@ -1122,7 +1122,7 @@ static int hid_modify_dquirk(const struct hid_device_id *id, } /** - * hid_remove_all_dquirks: remove all runtime HID quirks from memory + * hid_remove_all_dquirks - remove all runtime HID quirks from memory * @bus: bus to match against. Use HID_BUS_ANY if all need to be removed. * * Description: @@ -1146,7 +1146,10 @@ static void hid_remove_all_dquirks(__u16 bus) } /** - * hid_quirks_init: apply HID quirks specified at module load time + * hid_quirks_init - apply HID quirks specified at module load time + * @quirks_param: array of quirks strings (vendor:product:quirks) + * @bus: bus type + * @count: number of quirks to check */ int hid_quirks_init(char **quirks_param, __u16 bus, int count) { @@ -1177,7 +1180,7 @@ int hid_quirks_init(char **quirks_param, __u16 bus, int count) EXPORT_SYMBOL_GPL(hid_quirks_init); /** - * hid_quirks_exit: release memory associated with dynamic_quirks + * hid_quirks_exit - release memory associated with dynamic_quirks * @bus: a bus to match against * * Description: @@ -1194,14 +1197,14 @@ void hid_quirks_exit(__u16 bus) EXPORT_SYMBOL_GPL(hid_quirks_exit); /** - * hid_gets_squirk: return any static quirks for a HID device + * hid_gets_squirk - return any static quirks for a HID device * @hdev: the HID device to match * * Description: * Given a HID device, return a pointer to the quirked hid_device_id entry * associated with that device. * - * Returns: the quirks. + * Return: the quirks. */ static unsigned long hid_gets_squirk(const struct hid_device *hdev) { @@ -1225,13 +1228,13 @@ static unsigned long hid_gets_squirk(const struct hid_device *hdev) } /** - * hid_lookup_quirk: return any quirks associated with a HID device + * hid_lookup_quirk - return any quirks associated with a HID device * @hdev: the HID device to look for * * Description: * Given a HID device, return any quirks associated with that device. * - * Returns: an unsigned long quirks value. + * Return: an unsigned long quirks value. */ unsigned long hid_lookup_quirk(const struct hid_device *hdev) { diff --git a/drivers/hid/hid-roccat-arvo.c b/drivers/hid/hid-roccat-arvo.c index ffcd444ae2ba..4556d2a50f75 100644 --- a/drivers/hid/hid-roccat-arvo.c +++ b/drivers/hid/hid-roccat-arvo.c @@ -42,7 +42,7 @@ static ssize_t arvo_sysfs_show_mode_key(struct device *dev, if (retval) return retval; - return snprintf(buf, PAGE_SIZE, "%d\n", temp_buf.state); + return sysfs_emit(buf, "%d\n", temp_buf.state); } static ssize_t arvo_sysfs_set_mode_key(struct device *dev, @@ -92,7 +92,7 @@ static ssize_t arvo_sysfs_show_key_mask(struct device *dev, if (retval) return retval; - return snprintf(buf, PAGE_SIZE, "%d\n", temp_buf.key_mask); + return sysfs_emit(buf, "%d\n", temp_buf.key_mask); } static ssize_t arvo_sysfs_set_key_mask(struct device *dev, @@ -146,7 +146,7 @@ static ssize_t arvo_sysfs_show_actual_profile(struct device *dev, struct arvo_device *arvo = hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); - return snprintf(buf, PAGE_SIZE, "%d\n", arvo->actual_profile); + return sysfs_emit(buf, "%d\n", arvo->actual_profile); } static ssize_t arvo_sysfs_set_actual_profile(struct device *dev, diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c index bfe716d7ea44..c586acf2fc0b 100644 --- a/drivers/hid/i2c-hid/i2c-hid-core.c +++ b/drivers/hid/i2c-hid/i2c-hid-core.c @@ -171,6 +171,8 @@ 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_ITE, I2C_DEVICE_ID_ITE_VOYO_WINPAD_A15, + I2C_HID_QUIRK_NO_IRQ_AFTER_RESET }, { I2C_VENDOR_ID_RAYDIUM, I2C_PRODUCT_ID_RAYDIUM_3118, I2C_HID_QUIRK_NO_IRQ_AFTER_RESET }, { USB_VENDOR_ID_ELAN, HID_ANY_ID, diff --git a/drivers/hid/intel-ish-hid/ipc/hw-ish.h b/drivers/hid/intel-ish-hid/ipc/hw-ish.h index 1fb294ca463e..21b0e6123754 100644 --- a/drivers/hid/intel-ish-hid/ipc/hw-ish.h +++ b/drivers/hid/intel-ish-hid/ipc/hw-ish.h @@ -27,6 +27,7 @@ #define CMP_H_DEVICE_ID 0x06FC #define EHL_Ax_DEVICE_ID 0x4BB3 #define TGL_LP_DEVICE_ID 0xA0FC +#define TGL_H_DEVICE_ID 0x43FC #define REVISION_ID_CHT_A0 0x6 #define REVISION_ID_CHT_Ax_SI 0x0 diff --git a/drivers/hid/intel-ish-hid/ipc/pci-ish.c b/drivers/hid/intel-ish-hid/ipc/pci-ish.c index c6d48a8648b7..6dea657b7b15 100644 --- a/drivers/hid/intel-ish-hid/ipc/pci-ish.c +++ b/drivers/hid/intel-ish-hid/ipc/pci-ish.c @@ -37,6 +37,7 @@ static const struct pci_device_id ish_pci_tbl[] = { {PCI_DEVICE(PCI_VENDOR_ID_INTEL, CMP_H_DEVICE_ID)}, {PCI_DEVICE(PCI_VENDOR_ID_INTEL, EHL_Ax_DEVICE_ID)}, {PCI_DEVICE(PCI_VENDOR_ID_INTEL, TGL_LP_DEVICE_ID)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, TGL_H_DEVICE_ID)}, {0, } }; MODULE_DEVICE_TABLE(pci, ish_pci_tbl); diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index aa9e48876ced..8328ef155c46 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -1825,7 +1825,7 @@ static ssize_t wacom_show_speed(struct device *dev, struct hid_device *hdev = to_hid_device(dev); struct wacom *wacom = hid_get_drvdata(hdev); - return snprintf(buf, PAGE_SIZE, "%i\n", wacom->wacom_wac.bt_high_speed); + return sysfs_emit(buf, "%i\n", wacom->wacom_wac.bt_high_speed); } static ssize_t wacom_store_speed(struct device *dev, diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 1bd0eb71559c..44d715c12f6a 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c @@ -2600,7 +2600,12 @@ static void wacom_wac_finger_event(struct hid_device *hdev, wacom_wac->is_invalid_bt_frame = !value; return; case HID_DG_CONTACTMAX: - features->touch_max = value; + if (!features->touch_max) { + features->touch_max = value; + } else { + hid_warn(hdev, "%s: ignoring attempt to overwrite non-zero touch_max " + "%d -> %d\n", __func__, features->touch_max, value); + } return; } |