From c08ce255033a31440219b7d3dffedf37057f2444 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filipe=20La=C3=ADns?= Date: Sun, 12 Jan 2020 23:50:09 +0000 Subject: [PATCH 01/17] HID: logitech: drop outdated references to unifying receivers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The hid-logitech-{dj,hidpp} were originally developed for unifying receivers but since then they have evolved and now support other types of receivers and devices. This patch adjusts the original descriptions with this in mind. Signed-off-by: Filipe LaĆ­ns Signed-off-by: Jiri Kosina --- drivers/hid/Kconfig | 6 +++--- drivers/hid/hid-logitech-dj.c | 4 ++-- drivers/hid/hid-logitech-hidpp.c | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 7c89edbd6c5a..c5b0bd5283fa 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -538,14 +538,14 @@ config HID_LOGITECH Support for Logitech devices that are not fully compliant with HID standard. config HID_LOGITECH_DJ - tristate "Logitech Unifying receivers full support" + tristate "Logitech receivers full support" depends on USB_HID depends on HIDRAW depends on HID_LOGITECH select HID_LOGITECH_HIDPP ---help--- - Say Y if you want support for Logitech Unifying receivers and devices. - Unifying receivers are capable of pairing up to 6 Logitech compliant + Say Y if you want support for Logitech receivers and devices. + Logitech receivers are capable of pairing multiple Logitech compliant devices to the same receiver. Without this driver it will be handled by generic USB_HID driver and all incoming events will be multiplexed into a single mouse and a single keyboard device. diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c index ed9b1c1f460d..48dff5d6b605 100644 --- a/drivers/hid/hid-logitech-dj.c +++ b/drivers/hid/hid-logitech-dj.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * HID driver for Logitech Unifying receivers + * HID driver for Logitech receivers * * Copyright (c) 2011 Logitech */ @@ -701,7 +701,7 @@ static void logi_dj_recv_add_djhid_device(struct dj_receiver_dev *djrcv_dev, type_str, dj_hiddev->product); } else { snprintf(dj_hiddev->name, sizeof(dj_hiddev->name), - "Logitech Unifying Device. Wireless PID:%04x", + "Logitech Wireless Device PID:%04x", dj_hiddev->product); } diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c index 094f4f1b6555..1e1cf8eae649 100644 --- a/drivers/hid/hid-logitech-hidpp.c +++ b/drivers/hid/hid-logitech-hidpp.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * HIDPP protocol for Logitech Unifying receivers + * HIDPP protocol for Logitech receivers * * Copyright (c) 2011 Logitech (c) * Copyright (c) 2012-2013 Google (c) From 16863fbc1cf2618f5d35b37cb23119d09b8cc3b2 Mon Sep 17 00:00:00 2001 From: Christophe JAILLET Date: Sun, 12 Apr 2020 11:07:43 +0200 Subject: [PATCH 02/17] HID: fix typo in Kconfig Fix 2 typos: s/Uninterruptable/Uninterruptible/ s/should't/shouldn't/ Signed-off-by: Christophe JAILLET Signed-off-by: Jiri Kosina --- drivers/hid/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 7c89edbd6c5a..364328665f00 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -42,7 +42,7 @@ config HIDRAW ---help--- Say Y here if you want to support HID devices (from the USB specification standpoint) that aren't strictly user interface - devices, like monitor controls and Uninterruptable Power Supplies. + devices, like monitor controls and Uninterruptible Power Supplies. This module supports these devices separately using a separate event interface on /dev/hidraw. @@ -1140,7 +1140,7 @@ config HID_SENSOR_CUSTOM_SENSOR to decide how to interpret these special sensor ids and process in the user space. Currently some manufacturers are using these ids for sensor calibration and debugging other sensors. Manufacturers - should't use these special custom sensor ids to export any of the + shouldn't use these special custom sensor ids to export any of the standard sensors. Select this config option for custom/generic sensor support. From 328de1c519c5c0925151cae47944a1c1a0333bcd Mon Sep 17 00:00:00 2001 From: Rishi Gupta Date: Tue, 14 Apr 2020 22:18:14 +0530 Subject: [PATCH 03/17] HID: mcp2221: add GPIO functionality support MCP2221 has 4 pins that can be used as GPIO or configured for alternate functionality such as clock generation and IRQ detection. This patch adds support for GPIO functionality. To set direction of a pin or to toggle its state after it has been configured as GPIO, driver sends command to mcp2221 and parses response received from mcp2221. Based on this response either 0 or appropriate error code is returned to GPIO framework. To get the direction or current state of a pin, driver sends command and read response from the device. Based on the response received from device direction or value is sent to the GPIO framework. Command from driver to mcp2221 device are output report. Response received from mcp2221 is input report. Datasheet (page 45-48) contains details about how to decode the response received from device: http://ww1.microchip.com/downloads/en/DeviceDoc/20005565B.pdf Signed-off-by: Rishi Gupta Reviewed-by: Linus Walleij Signed-off-by: Jiri Kosina --- drivers/hid/hid-mcp2221.c | 169 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 169 insertions(+) diff --git a/drivers/hid/hid-mcp2221.c b/drivers/hid/hid-mcp2221.c index d958475f8c81..e1b93ce32e01 100644 --- a/drivers/hid/hid-mcp2221.c +++ b/drivers/hid/hid-mcp2221.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "hid-ids.h" /* Commands codes in a raw output report */ @@ -27,6 +28,8 @@ enum { MCP2221_I2C_PARAM_OR_STATUS = 0x10, MCP2221_I2C_SET_SPEED = 0x20, MCP2221_I2C_CANCEL = 0x10, + MCP2221_GPIO_SET = 0x50, + MCP2221_GPIO_GET = 0x51, }; /* Response codes in a raw input report */ @@ -42,6 +45,8 @@ enum { MCP2221_I2C_WRADDRL_SEND = 0x21, MCP2221_I2C_ADDR_NACK = 0x25, MCP2221_I2C_READ_COMPL = 0x55, + MCP2221_ALT_F_NOT_GPIOV = 0xEE, + MCP2221_ALT_F_NOT_GPIOD = 0xEF, }; /* @@ -59,6 +64,9 @@ struct mcp2221 { int rxbuf_idx; int status; u8 cur_i2c_clk_div; + struct gpio_chip *gc; + u8 gp_idx; + u8 gpio_dir; }; /* @@ -526,6 +534,110 @@ static const struct i2c_algorithm mcp_i2c_algo = { .functionality = mcp_i2c_func, }; +static int mcp_gpio_get(struct gpio_chip *gc, + unsigned int offset) +{ + int ret; + struct mcp2221 *mcp = gpiochip_get_data(gc); + + mcp->txbuf[0] = MCP2221_GPIO_GET; + + mcp->gp_idx = (offset + 1) * 2; + + mutex_lock(&mcp->lock); + ret = mcp_send_data_req_status(mcp, mcp->txbuf, 1); + mutex_unlock(&mcp->lock); + + return ret; +} + +static void mcp_gpio_set(struct gpio_chip *gc, + unsigned int offset, int value) +{ + struct mcp2221 *mcp = gpiochip_get_data(gc); + + memset(mcp->txbuf, 0, 18); + mcp->txbuf[0] = MCP2221_GPIO_SET; + + mcp->gp_idx = ((offset + 1) * 4) - 1; + + mcp->txbuf[mcp->gp_idx - 1] = 1; + mcp->txbuf[mcp->gp_idx] = !!value; + + mutex_lock(&mcp->lock); + mcp_send_data_req_status(mcp, mcp->txbuf, 18); + mutex_unlock(&mcp->lock); +} + +static int mcp_gpio_dir_set(struct mcp2221 *mcp, + unsigned int offset, u8 val) +{ + memset(mcp->txbuf, 0, 18); + mcp->txbuf[0] = MCP2221_GPIO_SET; + + mcp->gp_idx = (offset + 1) * 5; + + mcp->txbuf[mcp->gp_idx - 1] = 1; + mcp->txbuf[mcp->gp_idx] = val; + + return mcp_send_data_req_status(mcp, mcp->txbuf, 18); +} + +static int mcp_gpio_direction_input(struct gpio_chip *gc, + unsigned int offset) +{ + int ret; + struct mcp2221 *mcp = gpiochip_get_data(gc); + + mutex_lock(&mcp->lock); + ret = mcp_gpio_dir_set(mcp, offset, 0); + mutex_unlock(&mcp->lock); + + return ret; +} + +static int mcp_gpio_direction_output(struct gpio_chip *gc, + unsigned int offset, int value) +{ + int ret; + struct mcp2221 *mcp = gpiochip_get_data(gc); + + mutex_lock(&mcp->lock); + ret = mcp_gpio_dir_set(mcp, offset, 1); + mutex_unlock(&mcp->lock); + + /* Can't configure as output, bailout early */ + if (ret) + return ret; + + mcp_gpio_set(gc, offset, value); + + return 0; +} + +static int mcp_gpio_get_direction(struct gpio_chip *gc, + unsigned int offset) +{ + int ret; + struct mcp2221 *mcp = gpiochip_get_data(gc); + + mcp->txbuf[0] = MCP2221_GPIO_GET; + + mcp->gp_idx = (offset + 1) * 2; + + mutex_lock(&mcp->lock); + ret = mcp_send_data_req_status(mcp, mcp->txbuf, 1); + mutex_unlock(&mcp->lock); + + if (ret) + return ret; + + if (mcp->gpio_dir) + return GPIO_LINE_DIRECTION_IN; + + return GPIO_LINE_DIRECTION_OUT; +} + /* Gives current state of i2c engine inside mcp2221 */ static int mcp_get_i2c_eng_state(struct mcp2221 *mcp, u8 *data, u8 idx) @@ -638,6 +750,39 @@ static int mcp2221_raw_event(struct hid_device *hdev, complete(&mcp->wait_in_report); break; + case MCP2221_GPIO_GET: + switch (data[1]) { + case MCP2221_SUCCESS: + if ((data[mcp->gp_idx] == MCP2221_ALT_F_NOT_GPIOV) || + (data[mcp->gp_idx + 1] == MCP2221_ALT_F_NOT_GPIOD)) { + mcp->status = -ENOENT; + } else { + mcp->status = !!data[mcp->gp_idx]; + mcp->gpio_dir = !!data[mcp->gp_idx + 1]; + } + break; + default: + mcp->status = -EAGAIN; + } + complete(&mcp->wait_in_report); + break; + + case MCP2221_GPIO_SET: + switch (data[1]) { + case MCP2221_SUCCESS: + if ((data[mcp->gp_idx] == MCP2221_ALT_F_NOT_GPIOV) || + (data[mcp->gp_idx - 1] == MCP2221_ALT_F_NOT_GPIOV)) { + mcp->status = -ENOENT; + } else { + mcp->status = 0; + } + break; + default: + mcp->status = -EAGAIN; + } + complete(&mcp->wait_in_report); + break; + default: mcp->status = -EIO; complete(&mcp->wait_in_report); @@ -702,8 +847,32 @@ static int mcp2221_probe(struct hid_device *hdev, } i2c_set_adapdata(&mcp->adapter, mcp); + /* Setup GPIO chip */ + mcp->gc = devm_kzalloc(&hdev->dev, sizeof(*mcp->gc), GFP_KERNEL); + if (!mcp->gc) { + ret = -ENOMEM; + goto err_gc; + } + + mcp->gc->label = "mcp2221_gpio"; + mcp->gc->direction_input = mcp_gpio_direction_input; + mcp->gc->direction_output = mcp_gpio_direction_output; + mcp->gc->get_direction = mcp_gpio_get_direction; + mcp->gc->set = mcp_gpio_set; + mcp->gc->get = mcp_gpio_get; + mcp->gc->ngpio = 4; + mcp->gc->base = -1; + mcp->gc->can_sleep = 1; + mcp->gc->parent = &hdev->dev; + + ret = devm_gpiochip_add_data(&hdev->dev, mcp->gc, mcp); + if (ret) + goto err_gc; + return 0; +err_gc: + i2c_del_adapter(&mcp->adapter); err_i2c: hid_hw_close(mcp->hdev); err_hstop: From 0b66fb3e6b7a53688f8e20945ac78cd3d832c65f Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 28 Apr 2020 23:53:29 +0200 Subject: [PATCH 04/17] HID: intel-ish-hid: avoid bogus uninitialized-variable warning Older compilers like gcc-4.8 don't see that the variable is initialized when it is used: In file included from include/linux/compiler_types.h:68:0, from :0: drivers/hid/intel-ish-hid/ishtp-fw-loader.c: In function 'load_fw_from_host': include/linux/compiler-gcc.h:75:45: warning: 'fw_info.ldr_capability.max_dma_buf_size' may be used uninitialized in this function [-Wmaybe-uninitialized] #define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__) ^ drivers/hid/intel-ish-hid/ishtp-fw-loader.c:770:22: note: 'fw_info.ldr_capability.max_dma_buf_size' was declared here struct shim_fw_info fw_info; ^ Make sure to initialize it before returning an error from ish_query_loader_prop(). Fixes: 91b228107da3 ("HID: intel-ish-hid: ISH firmware loader client driver") Signed-off-by: Arnd Bergmann Acked-by: Srinivas Pandruvada Signed-off-by: Jiri Kosina --- drivers/hid/intel-ish-hid/ishtp-fw-loader.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/hid/intel-ish-hid/ishtp-fw-loader.c b/drivers/hid/intel-ish-hid/ishtp-fw-loader.c index aa2dbed30fc3..6cf59fd26ad7 100644 --- a/drivers/hid/intel-ish-hid/ishtp-fw-loader.c +++ b/drivers/hid/intel-ish-hid/ishtp-fw-loader.c @@ -480,6 +480,7 @@ static int ish_query_loader_prop(struct ishtp_cl_data *client_data, sizeof(ldr_xfer_query_resp)); if (rv < 0) { client_data->flag_retry = true; + *fw_info = (struct shim_fw_info){}; return rv; } @@ -489,6 +490,7 @@ static int ish_query_loader_prop(struct ishtp_cl_data *client_data, "data size %d is not equal to size of loader_xfer_query_response %zu\n", rv, sizeof(struct loader_xfer_query_response)); client_data->flag_retry = true; + *fw_info = (struct shim_fw_info){}; return -EMSGSIZE; } From 6507ef10660efdfee93f0f3b9fac24b5e4d83e56 Mon Sep 17 00:00:00 2001 From: Julian Sax Date: Tue, 5 May 2020 17:10:42 +0200 Subject: [PATCH 05/17] HID: i2c-hid: add Schneider SCL142ALM to descriptor override This device uses the SIPODEV SP1064 touchpad, which does not supply descriptors, so it has to be added to the override list. Cc: stable@vger.kernel.org Signed-off-by: Julian Sax Signed-off-by: Jiri Kosina --- drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c b/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c index a66f08041a1a..ec142bc8c1da 100644 --- a/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c +++ b/drivers/hid/i2c-hid/i2c-hid-dmi-quirks.c @@ -389,6 +389,14 @@ static const struct dmi_system_id i2c_hid_dmi_desc_override_table[] = { }, .driver_data = (void *)&sipodev_desc }, + { + .ident = "Schneider SCL142ALM", + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "SCHNEIDER"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "SCL142ALM"), + }, + .driver_data = (void *)&sipodev_desc + }, { } /* Terminate list */ }; From 4e4c60f826772dfeaacdf718f64afa38f46b6875 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 28 Apr 2020 16:22:49 +0200 Subject: [PATCH 06/17] HID: asus: Only set EV_REP if we are adding a mapping Make asus_input_mapping() only set EV_REP if we are adding a mapping. The T100CHI bluetooth keyboard dock has a few input reports for which we do not create any mappings (these input-reports are present in the descriptors but never send). The hid-asus code relies on the HID core not creating input devices for input-reports without any mappings. But the present of the EV_REP but counts as a mapping causing 6 /dev/input/event# nodes to be created for the T100CHI bluetooth keyboard dock. This change brings the amount of created /dev/input/event# nodes / input-devices down to 4. Signed-off-by: Hans de Goede Signed-off-by: Jiri Kosina --- drivers/hid/hid-asus.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c index e6e4c841fb06..ac224c32eeb6 100644 --- a/drivers/hid/hid-asus.c +++ b/drivers/hid/hid-asus.c @@ -694,7 +694,6 @@ static int asus_input_mapping(struct hid_device *hdev, /* ASUS-specific keyboard hotkeys */ if ((usage->hid & HID_USAGE_PAGE) == 0xff310000) { - set_bit(EV_REP, hi->input->evbit); switch (usage->hid & HID_USAGE) { case 0x10: asus_map_key_clear(KEY_BRIGHTNESSDOWN); break; case 0x20: asus_map_key_clear(KEY_BRIGHTNESSUP); break; @@ -737,11 +736,11 @@ static int asus_input_mapping(struct hid_device *hdev, if (drvdata->quirks & QUIRK_USE_KBD_BACKLIGHT) drvdata->enable_backlight = true; + set_bit(EV_REP, hi->input->evbit); return 1; } if ((usage->hid & HID_USAGE_PAGE) == HID_UP_MSVENDOR) { - set_bit(EV_REP, hi->input->evbit); switch (usage->hid & HID_USAGE) { case 0xff01: asus_map_key_clear(BTN_1); break; case 0xff02: asus_map_key_clear(BTN_2); break; @@ -764,6 +763,7 @@ static int asus_input_mapping(struct hid_device *hdev, return 0; } + set_bit(EV_REP, hi->input->evbit); return 1; } From a80b2f309883cb021ac05f992f785f15d7d748cf Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 28 Apr 2020 16:22:50 +0200 Subject: [PATCH 07/17] HID: asus: Simplify skipping of mappings for Asus T100CHI keyboard-dock Before this commit the code was trying to keep the mapping for the left mouse-button, do avoid the hidinput_has_been_populated() check in hid-input.c from triggering and causing the touchpad input_dev ro get cleaned up. But the hidinput_has_been_populated() check happens after the input_configured callback which sets up all the input bit for the touchpad, so there is no need to preserve the left button mapping. Signed-off-by: Hans de Goede Signed-off-by: Jiri Kosina --- drivers/hid/hid-asus.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c index ac224c32eeb6..b3292ff3f61a 100644 --- a/drivers/hid/hid-asus.c +++ b/drivers/hid/hid-asus.c @@ -677,20 +677,13 @@ static int asus_input_mapping(struct hid_device *hdev, * This avoids a bunch of non-functional hid_input devices getting * created because of the T100CHI using HID_QUIRK_MULTI_INPUT. */ - if (drvdata->quirks & (QUIRK_T100CHI | QUIRK_T90CHI)) { - if (field->application == (HID_UP_GENDESK | 0x0080) || - usage->hid == (HID_UP_GENDEVCTRLS | 0x0024) || - usage->hid == (HID_UP_GENDEVCTRLS | 0x0025) || - usage->hid == (HID_UP_GENDEVCTRLS | 0x0026)) - return -1; - /* - * We use the hid_input for the mouse report for the touchpad, - * keep the left button, to avoid the core removing it. - */ - if (field->application == HID_GD_MOUSE && - usage->hid != (HID_UP_BUTTON | 1)) - return -1; - } + if ((drvdata->quirks & (QUIRK_T100CHI | QUIRK_T90CHI)) && + (field->application == (HID_UP_GENDESK | 0x0080) || + field->application == HID_GD_MOUSE || + usage->hid == (HID_UP_GENDEVCTRLS | 0x0024) || + usage->hid == (HID_UP_GENDEVCTRLS | 0x0025) || + usage->hid == (HID_UP_GENDEVCTRLS | 0x0026))) + return -1; /* ASUS-specific keyboard hotkeys */ if ((usage->hid & HID_USAGE_PAGE) == 0xff310000) { From 4bc43a421218b6cebc7c926fea001b166ea3677c Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 28 Apr 2020 16:22:51 +0200 Subject: [PATCH 08/17] HID: asus: Add hid_is_using_ll_driver(usb_hid_driver) check Add a hid_is_using_ll_driver(usb_hid_driver) check to ensure that the parent device is an usb_interface, before casting the parent device pointer to an usb_interface pointer with to_usb_interface(). Signed-off-by: Hans de Goede Signed-off-by: Jiri Kosina --- drivers/hid/hid-asus.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c index b3292ff3f61a..719eff589f92 100644 --- a/drivers/hid/hid-asus.c +++ b/drivers/hid/hid-asus.c @@ -842,7 +842,8 @@ static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id) if (drvdata->quirks & QUIRK_IS_MULTITOUCH) drvdata->tp = &asus_i2c_tp; - if (drvdata->quirks & QUIRK_T100_KEYBOARD) { + if ((drvdata->quirks & QUIRK_T100_KEYBOARD) && + hid_is_using_ll_driver(hdev, &usb_hid_driver)) { struct usb_interface *intf = to_usb_interface(hdev->dev.parent); if (intf->altsetting->desc.bInterfaceNumber == T100_TPAD_INTF) { From a61f9e428bf092349fdfebeee37ddefedd3f0fd1 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 28 Apr 2020 16:22:52 +0200 Subject: [PATCH 09/17] HID: asus: Add report_size to struct asus_touchpad_info Add the report_size to struct asus_touchpad_info instead of calculating it. This is a preparation patch for adding support for the multi-touch touchpad found on the Medion Akoya E1239T's keyboard-dock, which uses the same custom multi-touch protocol as the Asus keyboard-docks (same chipset vendor, Integrated Technology Express / ITE). The only difference in that the Akoya E1239T keyboard-dock's input-reports have a 5 byte footer instead of a 1 byte footer, which requires the report_size to be configurable per touchpad-model. Signed-off-by: Hans de Goede Signed-off-by: Jiri Kosina --- drivers/hid/hid-asus.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c index 719eff589f92..6d97dbbcc287 100644 --- a/drivers/hid/hid-asus.c +++ b/drivers/hid/hid-asus.c @@ -102,6 +102,7 @@ struct asus_touchpad_info { int res_y; int contact_size; int max_contacts; + int report_size; }; struct asus_drvdata { @@ -126,6 +127,7 @@ static const struct asus_touchpad_info asus_i2c_tp = { .max_y = 1758, .contact_size = 5, .max_contacts = 5, + .report_size = 28 /* 2 byte header + 5 * 5 + 1 byte footer */, }; static const struct asus_touchpad_info asus_t100ta_tp = { @@ -135,6 +137,7 @@ static const struct asus_touchpad_info asus_t100ta_tp = { .res_y = 27, /* units/mm */ .contact_size = 5, .max_contacts = 5, + .report_size = 28 /* 2 byte header + 5 * 5 + 1 byte footer */, }; static const struct asus_touchpad_info asus_t100ha_tp = { @@ -144,6 +147,7 @@ static const struct asus_touchpad_info asus_t100ha_tp = { .res_y = 29, /* units/mm */ .contact_size = 5, .max_contacts = 5, + .report_size = 28 /* 2 byte header + 5 * 5 + 1 byte footer */, }; static const struct asus_touchpad_info asus_t200ta_tp = { @@ -153,6 +157,7 @@ static const struct asus_touchpad_info asus_t200ta_tp = { .res_y = 28, /* units/mm */ .contact_size = 5, .max_contacts = 5, + .report_size = 28 /* 2 byte header + 5 * 5 + 1 byte footer */, }; static const struct asus_touchpad_info asus_t100chi_tp = { @@ -162,6 +167,7 @@ static const struct asus_touchpad_info asus_t100chi_tp = { .res_y = 29, /* units/mm */ .contact_size = 3, .max_contacts = 4, + .report_size = 15 /* 2 byte header + 3 * 4 + 1 byte footer */, }; static void asus_report_contact_down(struct asus_drvdata *drvdat, @@ -229,7 +235,7 @@ static int asus_report_input(struct asus_drvdata *drvdat, u8 *data, int size) int i, toolType = MT_TOOL_FINGER; u8 *contactData = data + 2; - if (size != 3 + drvdat->tp->contact_size * drvdat->tp->max_contacts) + if (size != drvdat->tp->report_size) return 0; for (i = 0; i < drvdat->tp->max_contacts; i++) { From e271f6c2df78d60dd4873c790a51dba40e6dfb72 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 28 Apr 2020 16:22:53 +0200 Subject: [PATCH 10/17] HID: asus: Add support for multi-touch touchpad on Medion Akoya E1239T The multi-touch touchpad found on the Medion Akoya E1239T's keyboard-dock, uses the same custom multi-touch protocol as the Asus keyboard-docks (same chipset vendor, Integrated Technology Express / ITE). Add support for this using the existing multi-touch touchpad support in the hid-asus driver. Signed-off-by: Hans de Goede Signed-off-by: Jiri Kosina --- drivers/hid/hid-asus.c | 26 +++++++++++++++++++++++++- drivers/hid/hid-ids.h | 1 + 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c index 6d97dbbcc287..317d7392ca8b 100644 --- a/drivers/hid/hid-asus.c +++ b/drivers/hid/hid-asus.c @@ -40,6 +40,7 @@ MODULE_AUTHOR("Frederik Wenigwieser "); MODULE_DESCRIPTION("Asus HID Keyboard and TouchPad"); #define T100_TPAD_INTF 2 +#define MEDION_E1239T_TPAD_INTF 1 #define T100CHI_MOUSE_REPORT_ID 0x06 #define FEATURE_REPORT_ID 0x0d @@ -77,6 +78,7 @@ MODULE_DESCRIPTION("Asus HID Keyboard and TouchPad"); #define QUIRK_G752_KEYBOARD BIT(8) #define QUIRK_T101HA_DOCK BIT(9) #define QUIRK_T90CHI BIT(10) +#define QUIRK_MEDION_E1239T BIT(11) #define I2C_KEYBOARD_QUIRKS (QUIRK_FIX_NOTEBOOK_REPORT | \ QUIRK_NO_INIT_REPORTS | \ @@ -170,6 +172,16 @@ static const struct asus_touchpad_info asus_t100chi_tp = { .report_size = 15 /* 2 byte header + 3 * 4 + 1 byte footer */, }; +static const struct asus_touchpad_info medion_e1239t_tp = { + .max_x = 2640, + .max_y = 1380, + .res_x = 29, /* units/mm */ + .res_y = 28, /* units/mm */ + .contact_size = 5, + .max_contacts = 5, + .report_size = 32 /* 2 byte header + 5 * 5 + 5 byte footer */, +}; + static void asus_report_contact_down(struct asus_drvdata *drvdat, int toolType, u8 *data) { @@ -877,6 +889,17 @@ static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id) drvdata->tp = &asus_t100chi_tp; } + if ((drvdata->quirks & QUIRK_MEDION_E1239T) && + hid_is_using_ll_driver(hdev, &usb_hid_driver)) { + struct usb_host_interface *alt = + to_usb_interface(hdev->dev.parent)->altsetting; + + if (alt->desc.bInterfaceNumber == MEDION_E1239T_TPAD_INTF) { + drvdata->quirks |= QUIRK_SKIP_INPUT_MAPPING; + drvdata->tp = &medion_e1239t_tp; + } + } + if (drvdata->quirks & QUIRK_NO_INIT_REPORTS) hdev->quirks |= HID_QUIRK_NO_INIT_REPORTS; @@ -1056,7 +1079,8 @@ static const struct hid_device_id asus_devices[] = { { HID_USB_DEVICE(USB_VENDOR_ID_JESS, USB_DEVICE_ID_ASUS_MD_5112) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_T100CHI_KEYBOARD), QUIRK_T100CHI }, - + { HID_USB_DEVICE(USB_VENDOR_ID_ITE, USB_DEVICE_ID_ITE_MEDION_E1239T), + QUIRK_MEDION_E1239T }, { } }; MODULE_DEVICE_TABLE(hid, asus_devices); diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 1c71a1aa76b2..09eb3d8b7981 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -640,6 +640,7 @@ #define I2C_DEVICE_ID_ITE_LENOVO_LEGION_Y720 0x837a #define USB_DEVICE_ID_ITE_LENOVO_YOGA900 0x8396 #define USB_DEVICE_ID_ITE8595 0x8595 +#define USB_DEVICE_ID_ITE_MEDION_E1239T 0xce50 #define USB_VENDOR_ID_JABRA 0x0b0e #define USB_DEVICE_ID_JABRA_SPEAK_410 0x0412 From 350bd245fc180032b442633d40ab37ff8e60e8eb Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Tue, 28 Apr 2020 16:22:54 +0200 Subject: [PATCH 11/17] HID: asus: Fix mute and touchpad-toggle keys on Medion Akoya E1239T The mute key, is broken. All the consumer keys on the keyboard USB interface work normally, except for mute which only sends press events and never sends release events. The touchpad key sends the otherwise unused input report with a report-id of 5 on the touchpad interface. It too only sends press events. This also requires extra special handling since the multi-touch touchpad events and the KEY_F21 events for the touchpad toggle must not be send from the same input_dev (userspace cannot handle this). This commit adds special handlig for both, fixing these keys not working. Signed-off-by: Hans de Goede Signed-off-by: Jiri Kosina --- drivers/hid/hid-asus.c | 60 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c index 317d7392ca8b..c183caf89d49 100644 --- a/drivers/hid/hid-asus.c +++ b/drivers/hid/hid-asus.c @@ -42,6 +42,7 @@ MODULE_DESCRIPTION("Asus HID Keyboard and TouchPad"); #define T100_TPAD_INTF 2 #define MEDION_E1239T_TPAD_INTF 1 +#define E1239T_TP_TOGGLE_REPORT_ID 0x05 #define T100CHI_MOUSE_REPORT_ID 0x06 #define FEATURE_REPORT_ID 0x0d #define INPUT_REPORT_ID 0x5d @@ -111,6 +112,7 @@ struct asus_drvdata { unsigned long quirks; struct hid_device *hdev; struct input_dev *input; + struct input_dev *tp_kbd_input; struct asus_kbd_leds *kbd_backlight; const struct asus_touchpad_info *tp; bool enable_backlight; @@ -275,6 +277,34 @@ static int asus_report_input(struct asus_drvdata *drvdat, u8 *data, int size) return 1; } +static int asus_e1239t_event(struct asus_drvdata *drvdat, u8 *data, int size) +{ + if (size != 3) + return 0; + + /* Handle broken mute key which only sends press events */ + if (!drvdat->tp && + data[0] == 0x02 && data[1] == 0xe2 && data[2] == 0x00) { + input_report_key(drvdat->input, KEY_MUTE, 1); + input_sync(drvdat->input); + input_report_key(drvdat->input, KEY_MUTE, 0); + input_sync(drvdat->input); + return 1; + } + + /* Handle custom touchpad toggle key which only sends press events */ + if (drvdat->tp_kbd_input && + data[0] == 0x05 && data[1] == 0x02 && data[2] == 0x28) { + input_report_key(drvdat->tp_kbd_input, KEY_F21, 1); + input_sync(drvdat->tp_kbd_input); + input_report_key(drvdat->tp_kbd_input, KEY_F21, 0); + input_sync(drvdat->tp_kbd_input); + return 1; + } + + return 0; +} + static int asus_event(struct hid_device *hdev, struct hid_field *field, struct hid_usage *usage, __s32 value) { @@ -299,6 +329,9 @@ static int asus_raw_event(struct hid_device *hdev, if (drvdata->tp && data[0] == INPUT_REPORT_ID) return asus_report_input(drvdata, data, size); + if (drvdata->quirks & QUIRK_MEDION_E1239T) + return asus_e1239t_event(drvdata, data, size); + return 0; } @@ -633,6 +666,21 @@ static int asus_input_configured(struct hid_device *hdev, struct hid_input *hi) hi->report->id != T100CHI_MOUSE_REPORT_ID) return 0; + /* Handle MULTI_INPUT on E1239T mouse/touchpad USB interface */ + if (drvdata->tp && (drvdata->quirks & QUIRK_MEDION_E1239T)) { + switch (hi->report->id) { + case E1239T_TP_TOGGLE_REPORT_ID: + input_set_capability(input, EV_KEY, KEY_F21); + input->name = "Asus Touchpad Keys"; + drvdata->tp_kbd_input = input; + return 0; + case INPUT_REPORT_ID: + break; /* Touchpad report, handled below */ + default: + return 0; /* Ignore other reports */ + } + } + if (drvdata->tp) { int ret; @@ -793,6 +841,16 @@ static int asus_input_mapping(struct hid_device *hdev, } } + /* + * The mute button is broken and only sends press events, we + * deal with this in our raw_event handler, so do not map it. + */ + if ((drvdata->quirks & QUIRK_MEDION_E1239T) && + usage->hid == (HID_UP_CONSUMER | 0xe2)) { + input_set_capability(hi->input, EV_KEY, KEY_MUTE); + return -1; + } + return 0; } @@ -895,6 +953,8 @@ static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id) to_usb_interface(hdev->dev.parent)->altsetting; if (alt->desc.bInterfaceNumber == MEDION_E1239T_TPAD_INTF) { + /* For separate input-devs for tp and tp toggle key */ + hdev->quirks |= HID_QUIRK_MULTI_INPUT; drvdata->quirks |= QUIRK_SKIP_INPUT_MAPPING; drvdata->tp = &medion_e1239t_tp; } From c4f0126d487f3c68ab19ccb7c561e8fbf3ea2247 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 7 May 2020 11:53:34 +0200 Subject: [PATCH 12/17] HID: asus: Add depends on USB_HID to HID_ASUS Kconfig option Since commit 4bc43a421218 ("HID: asus: Add hid_is_using_ll_driver(usb_hid_driver) check") the hid-asus.c depends on the usb_hid_driver symbol. Add a depends on USB_HID to Kconfig to fix missing symbols errors in hid-asus when USB_HID is not enabled. Fixes: 4bc43a421218 ("HID: asus: Add hid_is_using_ll_driver(usb_hid_driver) check") Reported-by: kbuild test robot Signed-off-by: Hans de Goede Signed-off-by: Jiri Kosina --- drivers/hid/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 34f07371716d..b1111407b2f8 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -149,6 +149,7 @@ config HID_APPLEIR config HID_ASUS tristate "Asus" + depends on USB_HID depends on LEDS_CLASS depends on ASUS_WMI || ASUS_WMI=n select POWER_SUPPLY From 346338ef00d35bf8338ded171f9abeb9b10b43df Mon Sep 17 00:00:00 2001 From: free5lot Date: Fri, 15 May 2020 13:14:00 +0700 Subject: [PATCH 13/17] HID: apple: Swap the Fn and Left Control keys on Apple keyboards This patch allows users to swap the Fn and left Control keys on all Apple keyboards: internal (e.g. Macbooks) and external (both wired and wireless). The patch adds a new hid-apple module param: swap_fn_leftctrl (off by default). Signed-off-by: Zakhar Semenov Signed-off-by: Jiri Kosina --- drivers/hid/hid-apple.c | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c index d732d1d10caf..359bdfbe3701 100644 --- a/drivers/hid/hid-apple.c +++ b/drivers/hid/hid-apple.c @@ -51,6 +51,12 @@ MODULE_PARM_DESC(swap_opt_cmd, "Swap the Option (\"Alt\") and Command (\"Flag\") "(For people who want to keep Windows PC keyboard muscle memory. " "[0] = as-is, Mac layout. 1 = swapped, Windows layout.)"); +static unsigned int swap_fn_leftctrl; +module_param(swap_fn_leftctrl, uint, 0644); +MODULE_PARM_DESC(swap_fn_leftctrl, "Swap the Fn and left Control keys. " + "(For people who want to keep PC keyboard muscle memory. " + "[0] = as-is, Mac layout, 1 = swapped, PC layout)"); + struct apple_sc { unsigned long quirks; unsigned int fn_on; @@ -162,6 +168,11 @@ static const struct apple_key_translation swapped_option_cmd_keys[] = { { } }; +static const struct apple_key_translation swapped_fn_leftctrl_keys[] = { + { KEY_FN, KEY_LEFTCTRL }, + { } +}; + static const struct apple_key_translation *apple_find_translation( const struct apple_key_translation *table, u16 from) { @@ -183,9 +194,11 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input, bool do_translate; u16 code = 0; - if (usage->code == KEY_FN) { + u16 fn_keycode = (swap_fn_leftctrl) ? (KEY_LEFTCTRL) : (KEY_FN); + + if (usage->code == fn_keycode) { asc->fn_on = !!value; - input_event(input, usage->type, usage->code, value); + input_event(input, usage->type, KEY_FN, value); return 1; } @@ -270,6 +283,14 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input, } } + if (swap_fn_leftctrl) { + trans = apple_find_translation(swapped_fn_leftctrl_keys, usage->code); + if (trans) { + input_event(input, usage->type, trans->to, value); + return 1; + } + } + return 0; } @@ -333,6 +354,11 @@ static void apple_setup_input(struct input_dev *input) for (trans = apple_iso_keyboard; trans->from; trans++) set_bit(trans->to, input->keybit); + + if (swap_fn_leftctrl) { + for (trans = swapped_fn_leftctrl_keys; trans->from; trans++) + set_bit(trans->to, input->keybit); + } } static int apple_input_mapping(struct hid_device *hdev, struct hid_input *hi, From fb68ada81e65d593b51544fa43c284322107a742 Mon Sep 17 00:00:00 2001 From: Cristian Klein Date: Fri, 8 May 2020 17:26:04 +0200 Subject: [PATCH 14/17] HID: Add quirks for Trust Panora Graphic Tablet The Trust Panora Graphic Tablet has two interfaces. Interface zero reports pen movement, pen pressure and pen buttons. Interface one reports tablet buttons and tablet scroll. Both use the mouse protocol. Without these quirks, libinput gets confused about what device it talks to. For completeness, here is the usbhid-dump: ``` $ sudo usbhid-dump -d 145f:0212 003:013:001:DESCRIPTOR 1588949402.559961 05 0D 09 01 A1 01 85 07 A1 02 09 00 75 08 95 07 81 02 C0 C0 09 0E A1 01 85 05 09 23 A1 02 09 52 09 53 25 0A 75 08 95 02 B1 02 C0 C0 05 0C 09 36 A1 00 85 06 05 09 19 01 29 20 15 00 25 01 95 20 75 01 81 02 C0 003:013:000:DESCRIPTOR 1588949402.563942 05 01 09 02 A1 01 85 08 09 01 A1 00 05 09 19 01 29 03 15 00 25 01 95 03 75 01 81 02 95 05 81 01 05 01 09 30 09 31 09 38 09 00 15 81 25 7F 75 08 95 04 81 06 C0 C0 05 01 09 02 A1 01 85 09 09 01 A1 00 05 09 19 01 29 03 15 00 25 01 95 03 75 01 81 02 95 05 81 01 05 01 09 30 09 31 26 FF 7F 95 02 75 10 81 02 05 0D 09 30 26 FF 03 95 01 75 10 81 02 C0 C0 05 01 09 00 A1 01 85 04 A1 00 26 FF 00 09 00 75 08 95 07 B1 02 C0 C0 ``` Signed-off-by: Cristian Klein Signed-off-by: Jiri Kosina --- drivers/hid/hid-ids.h | 3 +++ drivers/hid/hid-quirks.c | 1 + 2 files changed, 4 insertions(+) diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 1c71a1aa76b2..f03f1cc913ce 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -1157,6 +1157,9 @@ #define USB_DEVICE_ID_TPV_OPTICAL_TOUCHSCREEN_8882 0x8882 #define USB_DEVICE_ID_TPV_OPTICAL_TOUCHSCREEN_8883 0x8883 +#define USB_VENDOR_ID_TRUST 0x145f +#define USB_DEVICE_ID_TRUST_PANORA_TABLET 0x0212 + #define USB_VENDOR_ID_TURBOX 0x062a #define USB_DEVICE_ID_TURBOX_KEYBOARD 0x0201 #define USB_DEVICE_ID_ASUS_MD_5110 0x5110 diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c index e4cb543de0cd..ca8b5c261c7c 100644 --- a/drivers/hid/hid-quirks.c +++ b/drivers/hid/hid-quirks.c @@ -168,6 +168,7 @@ static const struct hid_device_id hid_quirks[] = { { HID_USB_DEVICE(USB_VENDOR_ID_TOUCHPACK, USB_DEVICE_ID_TOUCHPACK_RTS), HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_TPV, USB_DEVICE_ID_TPV_OPTICAL_TOUCHSCREEN_8882), HID_QUIRK_NOGET }, { HID_USB_DEVICE(USB_VENDOR_ID_TPV, USB_DEVICE_ID_TPV_OPTICAL_TOUCHSCREEN_8883), HID_QUIRK_NOGET }, + { HID_USB_DEVICE(USB_VENDOR_ID_TRUST, USB_DEVICE_ID_TRUST_PANORA_TABLET), HID_QUIRK_MULTI_INPUT | HID_QUIRK_HIDINPUT_FORCE }, { HID_USB_DEVICE(USB_VENDOR_ID_TURBOX, USB_DEVICE_ID_TURBOX_KEYBOARD), HID_QUIRK_NOGET }, { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_KNA5), HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC, USB_DEVICE_ID_UCLOGIC_TABLET_TWA60), HID_QUIRK_MULTI_INPUT }, From e72455b898ac678667c5674668186b4670d87d11 Mon Sep 17 00:00:00 2001 From: Scott Shumate Date: Wed, 13 May 2020 13:39:26 -0500 Subject: [PATCH 15/17] HID: sony: Fix for broken buttons on DS3 USB dongles Fix for non-working buttons on knock-off USB dongles for Sony controllers. These USB dongles are used to connect older Sony DA/DS1/DS2 controllers via USB and are common on Amazon, AliExpress, etc. Without the patch, the square, X, and circle buttons do not function. These dongles used to work prior to kernel 4.10 but removing the global DS3 report fixup in commit e19a267b9987 ("HID: sony: DS3 comply to Linux gamepad spec") exposed the problem. Many people reported the problem on the Ubuntu forums and are working around the problem by falling back to the 4.9 hid-sony driver. The problem stems from these dongles incorrectly reporting their button count as 13 instead of 16. This patch fixes up the report descriptor by changing the button report count to 16 and removing 3 padding bits. Cc: stable@vger.kernel.org Fixes: e19a267b9987 ("HID: sony: DS3 comply to Linux gamepad spec") Signed-off-by: Scott Shumate Signed-off-by: Jiri Kosina --- drivers/hid/hid-sony.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index 4c6ed6ef31f1..2f073f536070 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -867,6 +867,23 @@ static u8 *sony_report_fixup(struct hid_device *hdev, u8 *rdesc, if (sc->quirks & PS3REMOTE) return ps3remote_fixup(hdev, rdesc, rsize); + /* + * Some knock-off USB dongles incorrectly report their button count + * as 13 instead of 16 causing three non-functional buttons. + */ + if ((sc->quirks & SIXAXIS_CONTROLLER_USB) && *rsize >= 45 && + /* Report Count (13) */ + rdesc[23] == 0x95 && rdesc[24] == 0x0D && + /* Usage Maximum (13) */ + rdesc[37] == 0x29 && rdesc[38] == 0x0D && + /* Report Count (3) */ + rdesc[43] == 0x95 && rdesc[44] == 0x03) { + hid_info(hdev, "Fixing up USB dongle report descriptor\n"); + rdesc[24] = 0x10; + rdesc[38] = 0x10; + rdesc[44] = 0x00; + } + return rdesc; } From 40d5bb87377a599d0405af765290f28aaa6abb1e Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Tue, 26 May 2020 17:07:17 +0200 Subject: [PATCH 16/17] HID: multitouch: enable multi-input as a quirk for some devices Two touchpad/trackstick combos are currently not behaving properly. They define a mouse emulation collection, as per Win8 requirements, but also define a separate mouse collection for the trackstick. The way the kernel currently treat the collections is that it merges both in one device. However, given that the first mouse collection already defines X,Y and left, right buttons, when mapping the events from the second mouse collection, hid-multitouch sees that these events are already mapped, and simply ignores them. To be able to report events from the tracktick, add a new quirked class for it, and manually add the 2 devices we know about. Link: https://bugzilla.kernel.org/show_bug.cgi?id=207235 Cc: stable@vger.kernel.org Tested-by: Kai-Heng Feng Signed-off-by: Benjamin Tissoires --- drivers/hid/hid-multitouch.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 03c720b47306..39e4da7468e1 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -69,6 +69,7 @@ MODULE_LICENSE("GPL"); #define MT_QUIRK_ASUS_CUSTOM_UP BIT(17) #define MT_QUIRK_WIN8_PTP_BUTTONS BIT(18) #define MT_QUIRK_SEPARATE_APP_REPORT BIT(19) +#define MT_QUIRK_FORCE_MULTI_INPUT BIT(20) #define MT_INPUTMODE_TOUCHSCREEN 0x02 #define MT_INPUTMODE_TOUCHPAD 0x03 @@ -189,6 +190,7 @@ static void mt_post_parse(struct mt_device *td, struct mt_application *app); #define MT_CLS_WIN_8 0x0012 #define MT_CLS_EXPORT_ALL_INPUTS 0x0013 #define MT_CLS_WIN_8_DUAL 0x0014 +#define MT_CLS_WIN_8_FORCE_MULTI_INPUT 0x0015 /* vendor specific classes */ #define MT_CLS_3M 0x0101 @@ -279,6 +281,15 @@ static const struct mt_class mt_classes[] = { MT_QUIRK_CONTACT_CNT_ACCURATE | MT_QUIRK_WIN8_PTP_BUTTONS, .export_all_inputs = true }, + { .name = MT_CLS_WIN_8_FORCE_MULTI_INPUT, + .quirks = MT_QUIRK_ALWAYS_VALID | + MT_QUIRK_IGNORE_DUPLICATES | + MT_QUIRK_HOVERING | + MT_QUIRK_CONTACT_CNT_ACCURATE | + MT_QUIRK_STICKY_FINGERS | + MT_QUIRK_WIN8_PTP_BUTTONS | + MT_QUIRK_FORCE_MULTI_INPUT, + .export_all_inputs = true }, /* * vendor specific classes @@ -1714,6 +1725,11 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id) if (id->group != HID_GROUP_MULTITOUCH_WIN_8) hdev->quirks |= HID_QUIRK_MULTI_INPUT; + if (mtclass->quirks & MT_QUIRK_FORCE_MULTI_INPUT) { + hdev->quirks &= ~HID_QUIRK_INPUT_PER_APP; + hdev->quirks |= HID_QUIRK_MULTI_INPUT; + } + timer_setup(&td->release_timer, mt_expired_timeout, 0); ret = hid_parse(hdev); @@ -1926,6 +1942,11 @@ static const struct hid_device_id mt_devices[] = { MT_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_C002) }, + /* Elan devices */ + { .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT, + HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, + USB_VENDOR_ID_ELAN, 0x313a) }, + /* Elitegroup panel */ { .driver_data = MT_CLS_SERIAL, MT_USB_DEVICE(USB_VENDOR_ID_ELITEGROUP, @@ -2056,6 +2077,11 @@ static const struct hid_device_id mt_devices[] = { MT_USB_DEVICE(USB_VENDOR_ID_STANTUM_STM, USB_DEVICE_ID_MTP_STM)}, + /* Synaptics devices */ + { .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT, + HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, + USB_VENDOR_ID_SYNAPTICS, 0xce08) }, + /* TopSeed panels */ { .driver_data = MT_CLS_TOPSEED, MT_USB_DEVICE(USB_VENDOR_ID_TOPSEED2, From 27a6f70173ac996d891e622c69730bd6c1f82a5e Mon Sep 17 00:00:00 2001 From: Kai-Heng Feng Date: Tue, 14 Apr 2020 17:18:42 +0800 Subject: [PATCH 17/17] HID: multitouch: Remove MT_CLS_WIN_8_DUAL After commit c23e2043d5f7 ("HID: multitouch: do not filter mice nodes"), MT_CLS_WIN_8 also supports mouse nodes, hence make MT_CLS_WIN_8_DUAL redundant. Remove MT_CLS_WIN_8_DUAL accordingly. Signed-off-by: Kai-Heng Feng Signed-off-by: Benjamin Tissoires --- drivers/hid/hid-ids.h | 8 ------- drivers/hid/hid-multitouch.c | 44 ++---------------------------------- 2 files changed, 2 insertions(+), 50 deletions(-) diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 1c71a1aa76b2..5942e7556c7f 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -76,12 +76,9 @@ #define USB_VENDOR_ID_ALPS_JP 0x044E #define HID_DEVICE_ID_ALPS_U1_DUAL 0x120B -#define HID_DEVICE_ID_ALPS_U1_DUAL_PTP 0x121F -#define HID_DEVICE_ID_ALPS_U1_DUAL_3BTN_PTP 0x1220 #define HID_DEVICE_ID_ALPS_U1 0x1215 #define HID_DEVICE_ID_ALPS_U1_UNICORN_LEGACY 0x121E #define HID_DEVICE_ID_ALPS_T4_BTNLESS 0x120C -#define HID_DEVICE_ID_ALPS_1222 0x1222 #define USB_VENDOR_ID_AMI 0x046b #define USB_DEVICE_ID_AMI_VIRT_KEYBOARD_AND_MOUSE 0xff10 @@ -281,9 +278,6 @@ #define USB_VENDOR_ID_CIDC 0x1677 -#define I2C_VENDOR_ID_CIRQUE 0x0488 -#define I2C_PRODUCT_ID_CIRQUE_121F 0x121F - #define USB_VENDOR_ID_CJTOUCH 0x24b8 #define USB_DEVICE_ID_CJTOUCH_MULTI_TOUCH_0020 0x0020 #define USB_DEVICE_ID_CJTOUCH_MULTI_TOUCH_0040 0x0040 @@ -730,8 +724,6 @@ #define USB_DEVICE_ID_LENOVO_SCROLLPOINT_OPTICAL 0x6049 #define USB_DEVICE_ID_LENOVO_TPPRODOCK 0x6067 #define USB_DEVICE_ID_LENOVO_X1_COVER 0x6085 -#define USB_DEVICE_ID_LENOVO_X1_TAB 0x60a3 -#define USB_DEVICE_ID_LENOVO_X1_TAB3 0x60b5 #define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_608D 0x608d #define USB_VENDOR_ID_LG 0x1fd2 diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 39e4da7468e1..35c8c174a0ce 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c @@ -189,7 +189,7 @@ static void mt_post_parse(struct mt_device *td, struct mt_application *app); /* reserved 0x0011 */ #define MT_CLS_WIN_8 0x0012 #define MT_CLS_EXPORT_ALL_INPUTS 0x0013 -#define MT_CLS_WIN_8_DUAL 0x0014 +/* reserved 0x0014 */ #define MT_CLS_WIN_8_FORCE_MULTI_INPUT 0x0015 /* vendor specific classes */ @@ -274,13 +274,6 @@ static const struct mt_class mt_classes[] = { .quirks = MT_QUIRK_ALWAYS_VALID | MT_QUIRK_CONTACT_CNT_ACCURATE, .export_all_inputs = true }, - { .name = MT_CLS_WIN_8_DUAL, - .quirks = MT_QUIRK_ALWAYS_VALID | - MT_QUIRK_IGNORE_DUPLICATES | - MT_QUIRK_HOVERING | - MT_QUIRK_CONTACT_CNT_ACCURATE | - MT_QUIRK_WIN8_PTP_BUTTONS, - .export_all_inputs = true }, { .name = MT_CLS_WIN_8_FORCE_MULTI_INPUT, .quirks = MT_QUIRK_ALWAYS_VALID | MT_QUIRK_IGNORE_DUPLICATES | @@ -765,8 +758,7 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi, MT_STORE_FIELD(inrange_state); return 1; case HID_DG_CONFIDENCE: - if ((cls->name == MT_CLS_WIN_8 || - cls->name == MT_CLS_WIN_8_DUAL) && + if (cls->name == MT_CLS_WIN_8 && (field->application == HID_DG_TOUCHPAD || field->application == HID_DG_TOUCHSCREEN)) app->quirks |= MT_QUIRK_CONFIDENCE; @@ -1802,32 +1794,6 @@ static const struct hid_device_id mt_devices[] = { MT_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M3266) }, - /* Alps devices */ - { .driver_data = MT_CLS_WIN_8_DUAL, - HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, - USB_VENDOR_ID_ALPS_JP, - HID_DEVICE_ID_ALPS_U1_DUAL_PTP) }, - { .driver_data = MT_CLS_WIN_8_DUAL, - HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, - USB_VENDOR_ID_ALPS_JP, - HID_DEVICE_ID_ALPS_U1_DUAL_3BTN_PTP) }, - { .driver_data = MT_CLS_WIN_8_DUAL, - HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, - USB_VENDOR_ID_ALPS_JP, - HID_DEVICE_ID_ALPS_1222) }, - - /* Lenovo X1 TAB Gen 2 */ - { .driver_data = MT_CLS_WIN_8_DUAL, - HID_DEVICE(BUS_USB, HID_GROUP_MULTITOUCH_WIN_8, - USB_VENDOR_ID_LENOVO, - USB_DEVICE_ID_LENOVO_X1_TAB) }, - - /* Lenovo X1 TAB Gen 3 */ - { .driver_data = MT_CLS_WIN_8_DUAL, - HID_DEVICE(BUS_USB, HID_GROUP_MULTITOUCH_WIN_8, - USB_VENDOR_ID_LENOVO, - USB_DEVICE_ID_LENOVO_X1_TAB3) }, - /* Anton devices */ { .driver_data = MT_CLS_EXPORT_ALL_INPUTS, MT_USB_DEVICE(USB_VENDOR_ID_ANTON, @@ -1862,12 +1828,6 @@ static const struct hid_device_id mt_devices[] = { MT_USB_DEVICE(USB_VENDOR_ID_CHUNGHWAT, USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH) }, - /* Cirque devices */ - { .driver_data = MT_CLS_WIN_8_DUAL, - HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, - I2C_VENDOR_ID_CIRQUE, - I2C_PRODUCT_ID_CIRQUE_121F) }, - /* CJTouch panels */ { .driver_data = MT_CLS_NSMU, MT_USB_DEVICE(USB_VENDOR_ID_CJTOUCH,