hid-for-linus-2025082901
-----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEL65usyKPHcrRDEicpmLzj2vtYEkFAmixtiMACgkQpmLzj2vt YEkMhBAAmpdDXi5YyUkU+8qwZpIfPHUR9k+pv6vIfcALNZVy1siaspwZvWdX4GHw ghxQoH/L84rN6bhiHBG/8FrX2TUNizstQro6/wDc4G2EcXde9h0/SZOqqUaszR51 1O09ns4Po9UI4ekHepx9vrCk+mSDDTRTptw0ALSo/RvqtnzeoCR+7EfGRjAVOY+z K2yEk5c6rmYocARHqmNrOWQEiUA94seLjCjKKkJdkzRRb3o9NU+uj1uixIlDsIIh SpxG/c1fqPxETOX+JNMm9L/7PQkTrMigdwtlTxvimj1CFXZtOMB6gDo4V1Qc5kuH yGcgfr+3mO1u3hfQ43nowz9Fuxrnru3qanP9TvY1/uBE+HPuXr4Nz09KEmJAC61l NBz3CqapCAo2tMA+BWHlmjdf3WufwlMQerVSipx0tn5ULfx7qJk3Nn1y4toef3qb 9tDoN/tbFMA/IEfUwe/eHRFy4/Z5YgS7H/mTPp9UEtM0r/MwONwBSuGehY1dV2M9 O9gNoUog8h3NbGbGLy9Fkb+c2Q9wXh4ISkvxJmfRBUJQemGxzEjTOhqk0jUalzo4 AwhpE/BqPNb8dm52PhjZjXLefah8J03sZXN6TIpAS5vuDI9P97Ypa7Z6UGDjB4ao 289r5xLsMRaUV6swTZNcgYoYj5oSEmpHNxody53W9v0Hn5ZjL7s= =WR2w -----END PGP SIGNATURE----- Merge tag 'hid-for-linus-2025082901' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid Pull HID fixes from Jiri Kosina: - fixes for memory corruption in intel-thc-hid, hid-multitouch, hid-mcp2221 and hid-asus (Aaron Ma, Qasim Ijaz, Arnaud Lecomte) - power management/resume fix for intel-ish-hid (Zhang Lixu) - driver reinitialization fix for intel-thc-hid (Even Xu) - ensure that battery level status is reported as soon as possible, which is required at least for some Android use-cases (José Expósito) - quite a few new device ID additions and device-specific quirks * tag 'hid-for-linus-2025082901' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid: HID: quirks: add support for Legion Go dual dinput modes HID: elecom: add support for ELECOM M-DT2DRBK HID: logitech: Add ids for G PRO 2 LIGHTSPEED HID: input: report battery status changes immediately HID: input: rename hidinput_set_battery_charge_status() HID: intel-thc-hid: Intel-quicki2c: Enhance driver re-install flow HID: hid-ntrig: fix unable to handle page fault in ntrig_report_version() HID: asus: fix UAF via HID_CLAIMED_INPUT validation hid: fix I2C read buffer overflow in raw_event() for mcp2221 HID: wacom: Add a new Art Pen 2 HID: multitouch: fix slab out-of-bounds access in mt_report_fixup() HID: Kconfig: Fix spelling mistake "enthropy" -> "entropy" HID: intel-ish-hid: Increase ISHTP resume ack timeout to 300ms HID: intel-thc-hid: intel-thc: Fix incorrect pointer arithmetic in I2C regs save HID: intel-thc-hid: intel-quicki2c: Fix ACPI dsd ICRS/ISUB lengthpull/1334/head
commit
02d6eeedbc
|
|
@ -1243,7 +1243,7 @@ config HID_U2FZERO
|
||||||
|
|
||||||
U2F Zero supports custom commands for blinking the LED
|
U2F Zero supports custom commands for blinking the LED
|
||||||
and getting data from the internal hardware RNG.
|
and getting data from the internal hardware RNG.
|
||||||
The internal hardware can be used to feed the enthropy pool.
|
The internal hardware can be used to feed the entropy pool.
|
||||||
|
|
||||||
U2F Zero only supports blinking its LED, so this driver doesn't
|
U2F Zero only supports blinking its LED, so this driver doesn't
|
||||||
allow setting the brightness to anything but 1, which will
|
allow setting the brightness to anything but 1, which will
|
||||||
|
|
|
||||||
|
|
@ -1213,7 +1213,13 @@ static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!drvdata->input) {
|
/*
|
||||||
|
* Check that input registration succeeded. Checking that
|
||||||
|
* HID_CLAIMED_INPUT is set prevents a UAF when all input devices
|
||||||
|
* were freed during registration due to no usages being mapped,
|
||||||
|
* leaving drvdata->input pointing to freed memory.
|
||||||
|
*/
|
||||||
|
if (!drvdata->input || !(hdev->claimed & HID_CLAIMED_INPUT)) {
|
||||||
hid_err(hdev, "Asus input not registered\n");
|
hid_err(hdev, "Asus input not registered\n");
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto err_stop_hw;
|
goto err_stop_hw;
|
||||||
|
|
|
||||||
|
|
@ -101,6 +101,7 @@ static const __u8 *elecom_report_fixup(struct hid_device *hdev, __u8 *rdesc,
|
||||||
*/
|
*/
|
||||||
mouse_button_fixup(hdev, rdesc, *rsize, 12, 30, 14, 20, 8);
|
mouse_button_fixup(hdev, rdesc, *rsize, 12, 30, 14, 20, 8);
|
||||||
break;
|
break;
|
||||||
|
case USB_DEVICE_ID_ELECOM_M_DT2DRBK:
|
||||||
case USB_DEVICE_ID_ELECOM_M_HT1DRBK_011C:
|
case USB_DEVICE_ID_ELECOM_M_HT1DRBK_011C:
|
||||||
/*
|
/*
|
||||||
* Report descriptor format:
|
* Report descriptor format:
|
||||||
|
|
@ -123,6 +124,7 @@ static const struct hid_device_id elecom_devices[] = {
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT4DRBK) },
|
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT4DRBK) },
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_DT1URBK) },
|
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_DT1URBK) },
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_DT1DRBK) },
|
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_DT1DRBK) },
|
||||||
|
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_DT2DRBK) },
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1URBK_010C) },
|
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1URBK_010C) },
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1URBK_019B) },
|
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1URBK_019B) },
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1DRBK_010D) },
|
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1DRBK_010D) },
|
||||||
|
|
|
||||||
|
|
@ -451,6 +451,7 @@
|
||||||
#define USB_DEVICE_ID_ELECOM_M_XT4DRBK 0x00fd
|
#define USB_DEVICE_ID_ELECOM_M_XT4DRBK 0x00fd
|
||||||
#define USB_DEVICE_ID_ELECOM_M_DT1URBK 0x00fe
|
#define USB_DEVICE_ID_ELECOM_M_DT1URBK 0x00fe
|
||||||
#define USB_DEVICE_ID_ELECOM_M_DT1DRBK 0x00ff
|
#define USB_DEVICE_ID_ELECOM_M_DT1DRBK 0x00ff
|
||||||
|
#define USB_DEVICE_ID_ELECOM_M_DT2DRBK 0x018d
|
||||||
#define USB_DEVICE_ID_ELECOM_M_HT1URBK_010C 0x010c
|
#define USB_DEVICE_ID_ELECOM_M_HT1URBK_010C 0x010c
|
||||||
#define USB_DEVICE_ID_ELECOM_M_HT1URBK_019B 0x019b
|
#define USB_DEVICE_ID_ELECOM_M_HT1URBK_019B 0x019b
|
||||||
#define USB_DEVICE_ID_ELECOM_M_HT1DRBK_010D 0x010d
|
#define USB_DEVICE_ID_ELECOM_M_HT1DRBK_010D 0x010d
|
||||||
|
|
@ -834,6 +835,8 @@
|
||||||
#define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_6019 0x6019
|
#define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_6019 0x6019
|
||||||
#define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_602E 0x602e
|
#define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_602E 0x602e
|
||||||
#define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_6093 0x6093
|
#define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_6093 0x6093
|
||||||
|
#define USB_DEVICE_ID_LENOVO_LEGION_GO_DUAL_DINPUT 0x6184
|
||||||
|
#define USB_DEVICE_ID_LENOVO_LEGION_GO2_DUAL_DINPUT 0x61ed
|
||||||
|
|
||||||
#define USB_VENDOR_ID_LETSKETCH 0x6161
|
#define USB_VENDOR_ID_LETSKETCH 0x6161
|
||||||
#define USB_DEVICE_ID_WP9620N 0x4d15
|
#define USB_DEVICE_ID_WP9620N 0x4d15
|
||||||
|
|
@ -907,6 +910,7 @@
|
||||||
#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_2 0xc534
|
#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_2 0xc534
|
||||||
#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1 0xc539
|
#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1 0xc539
|
||||||
#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_1 0xc53f
|
#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_1 0xc53f
|
||||||
|
#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_2 0xc543
|
||||||
#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_POWERPLAY 0xc53a
|
#define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_POWERPLAY 0xc53a
|
||||||
#define USB_DEVICE_ID_LOGITECH_BOLT_RECEIVER 0xc548
|
#define USB_DEVICE_ID_LOGITECH_BOLT_RECEIVER 0xc548
|
||||||
#define USB_DEVICE_ID_SPACETRAVELLER 0xc623
|
#define USB_DEVICE_ID_SPACETRAVELLER 0xc623
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
#include <kunit/test.h>
|
#include <kunit/test.h>
|
||||||
|
|
||||||
static void hid_test_input_set_battery_charge_status(struct kunit *test)
|
static void hid_test_input_update_battery_charge_status(struct kunit *test)
|
||||||
{
|
{
|
||||||
struct hid_device *dev;
|
struct hid_device *dev;
|
||||||
bool handled;
|
bool handled;
|
||||||
|
|
@ -15,15 +15,15 @@ static void hid_test_input_set_battery_charge_status(struct kunit *test)
|
||||||
dev = kunit_kzalloc(test, sizeof(*dev), GFP_KERNEL);
|
dev = kunit_kzalloc(test, sizeof(*dev), GFP_KERNEL);
|
||||||
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
|
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
|
||||||
|
|
||||||
handled = hidinput_set_battery_charge_status(dev, HID_DG_HEIGHT, 0);
|
handled = hidinput_update_battery_charge_status(dev, HID_DG_HEIGHT, 0);
|
||||||
KUNIT_EXPECT_FALSE(test, handled);
|
KUNIT_EXPECT_FALSE(test, handled);
|
||||||
KUNIT_EXPECT_EQ(test, dev->battery_charge_status, POWER_SUPPLY_STATUS_UNKNOWN);
|
KUNIT_EXPECT_EQ(test, dev->battery_charge_status, POWER_SUPPLY_STATUS_UNKNOWN);
|
||||||
|
|
||||||
handled = hidinput_set_battery_charge_status(dev, HID_BAT_CHARGING, 0);
|
handled = hidinput_update_battery_charge_status(dev, HID_BAT_CHARGING, 0);
|
||||||
KUNIT_EXPECT_TRUE(test, handled);
|
KUNIT_EXPECT_TRUE(test, handled);
|
||||||
KUNIT_EXPECT_EQ(test, dev->battery_charge_status, POWER_SUPPLY_STATUS_DISCHARGING);
|
KUNIT_EXPECT_EQ(test, dev->battery_charge_status, POWER_SUPPLY_STATUS_DISCHARGING);
|
||||||
|
|
||||||
handled = hidinput_set_battery_charge_status(dev, HID_BAT_CHARGING, 1);
|
handled = hidinput_update_battery_charge_status(dev, HID_BAT_CHARGING, 1);
|
||||||
KUNIT_EXPECT_TRUE(test, handled);
|
KUNIT_EXPECT_TRUE(test, handled);
|
||||||
KUNIT_EXPECT_EQ(test, dev->battery_charge_status, POWER_SUPPLY_STATUS_CHARGING);
|
KUNIT_EXPECT_EQ(test, dev->battery_charge_status, POWER_SUPPLY_STATUS_CHARGING);
|
||||||
}
|
}
|
||||||
|
|
@ -63,7 +63,7 @@ static void hid_test_input_get_battery_property(struct kunit *test)
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct kunit_case hid_input_tests[] = {
|
static struct kunit_case hid_input_tests[] = {
|
||||||
KUNIT_CASE(hid_test_input_set_battery_charge_status),
|
KUNIT_CASE(hid_test_input_update_battery_charge_status),
|
||||||
KUNIT_CASE(hid_test_input_get_battery_property),
|
KUNIT_CASE(hid_test_input_get_battery_property),
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -595,13 +595,33 @@ static void hidinput_cleanup_battery(struct hid_device *dev)
|
||||||
dev->battery = NULL;
|
dev->battery = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void hidinput_update_battery(struct hid_device *dev, int value)
|
static bool hidinput_update_battery_charge_status(struct hid_device *dev,
|
||||||
|
unsigned int usage, int value)
|
||||||
|
{
|
||||||
|
switch (usage) {
|
||||||
|
case HID_BAT_CHARGING:
|
||||||
|
dev->battery_charge_status = value ?
|
||||||
|
POWER_SUPPLY_STATUS_CHARGING :
|
||||||
|
POWER_SUPPLY_STATUS_DISCHARGING;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void hidinput_update_battery(struct hid_device *dev, unsigned int usage,
|
||||||
|
int value)
|
||||||
{
|
{
|
||||||
int capacity;
|
int capacity;
|
||||||
|
|
||||||
if (!dev->battery)
|
if (!dev->battery)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (hidinput_update_battery_charge_status(dev, usage, value)) {
|
||||||
|
power_supply_changed(dev->battery);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (value == 0 || value < dev->battery_min || value > dev->battery_max)
|
if (value == 0 || value < dev->battery_min || value > dev->battery_max)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -617,20 +637,6 @@ static void hidinput_update_battery(struct hid_device *dev, int value)
|
||||||
power_supply_changed(dev->battery);
|
power_supply_changed(dev->battery);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool hidinput_set_battery_charge_status(struct hid_device *dev,
|
|
||||||
unsigned int usage, int value)
|
|
||||||
{
|
|
||||||
switch (usage) {
|
|
||||||
case HID_BAT_CHARGING:
|
|
||||||
dev->battery_charge_status = value ?
|
|
||||||
POWER_SUPPLY_STATUS_CHARGING :
|
|
||||||
POWER_SUPPLY_STATUS_DISCHARGING;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#else /* !CONFIG_HID_BATTERY_STRENGTH */
|
#else /* !CONFIG_HID_BATTERY_STRENGTH */
|
||||||
static int hidinput_setup_battery(struct hid_device *dev, unsigned report_type,
|
static int hidinput_setup_battery(struct hid_device *dev, unsigned report_type,
|
||||||
struct hid_field *field, bool is_percentage)
|
struct hid_field *field, bool is_percentage)
|
||||||
|
|
@ -642,15 +648,10 @@ static void hidinput_cleanup_battery(struct hid_device *dev)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static void hidinput_update_battery(struct hid_device *dev, int value)
|
static void hidinput_update_battery(struct hid_device *dev, unsigned int usage,
|
||||||
|
int value)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool hidinput_set_battery_charge_status(struct hid_device *dev,
|
|
||||||
unsigned int usage, int value)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_HID_BATTERY_STRENGTH */
|
#endif /* CONFIG_HID_BATTERY_STRENGTH */
|
||||||
|
|
||||||
static bool hidinput_field_in_collection(struct hid_device *device, struct hid_field *field,
|
static bool hidinput_field_in_collection(struct hid_device *device, struct hid_field *field,
|
||||||
|
|
@ -1515,11 +1516,7 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (usage->type == EV_PWR) {
|
if (usage->type == EV_PWR) {
|
||||||
bool handled = hidinput_set_battery_charge_status(hid, usage->hid, value);
|
hidinput_update_battery(hid, usage->hid, value);
|
||||||
|
|
||||||
if (!handled)
|
|
||||||
hidinput_update_battery(hid, value);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1983,6 +1983,10 @@ static const struct hid_device_id logi_dj_receivers[] = {
|
||||||
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
|
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
|
||||||
USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_1),
|
USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_1),
|
||||||
.driver_data = recvr_type_gaming_hidpp},
|
.driver_data = recvr_type_gaming_hidpp},
|
||||||
|
{ /* Logitech lightspeed receiver (0xc543) */
|
||||||
|
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH,
|
||||||
|
USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_2),
|
||||||
|
.driver_data = recvr_type_gaming_hidpp},
|
||||||
|
|
||||||
{ /* Logitech 27 MHz HID++ 1.0 receiver (0xc513) */
|
{ /* Logitech 27 MHz HID++ 1.0 receiver (0xc513) */
|
||||||
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER),
|
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER),
|
||||||
|
|
|
||||||
|
|
@ -4596,6 +4596,8 @@ static const struct hid_device_id hidpp_devices[] = {
|
||||||
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC094) },
|
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC094) },
|
||||||
{ /* Logitech G Pro X Superlight 2 Gaming Mouse over USB */
|
{ /* Logitech G Pro X Superlight 2 Gaming Mouse over USB */
|
||||||
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC09b) },
|
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xC09b) },
|
||||||
|
{ /* Logitech G PRO 2 LIGHTSPEED Wireless Mouse over USB */
|
||||||
|
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0xc09a) },
|
||||||
|
|
||||||
{ /* G935 Gaming Headset */
|
{ /* G935 Gaming Headset */
|
||||||
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0x0a87),
|
HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, 0x0a87),
|
||||||
|
|
|
||||||
|
|
@ -906,6 +906,10 @@ static int mcp2221_raw_event(struct hid_device *hdev,
|
||||||
}
|
}
|
||||||
if (data[2] == MCP2221_I2C_READ_COMPL ||
|
if (data[2] == MCP2221_I2C_READ_COMPL ||
|
||||||
data[2] == MCP2221_I2C_READ_PARTIAL) {
|
data[2] == MCP2221_I2C_READ_PARTIAL) {
|
||||||
|
if (!mcp->rxbuf || mcp->rxbuf_idx < 0 || data[3] > 60) {
|
||||||
|
mcp->status = -EINVAL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
buf = mcp->rxbuf;
|
buf = mcp->rxbuf;
|
||||||
memcpy(&buf[mcp->rxbuf_idx], &data[4], data[3]);
|
memcpy(&buf[mcp->rxbuf_idx], &data[4], data[3]);
|
||||||
mcp->rxbuf_idx = mcp->rxbuf_idx + data[3];
|
mcp->rxbuf_idx = mcp->rxbuf_idx + data[3];
|
||||||
|
|
|
||||||
|
|
@ -1503,6 +1503,14 @@ static const __u8 *mt_report_fixup(struct hid_device *hdev, __u8 *rdesc,
|
||||||
if (hdev->vendor == I2C_VENDOR_ID_GOODIX &&
|
if (hdev->vendor == I2C_VENDOR_ID_GOODIX &&
|
||||||
(hdev->product == I2C_DEVICE_ID_GOODIX_01E8 ||
|
(hdev->product == I2C_DEVICE_ID_GOODIX_01E8 ||
|
||||||
hdev->product == I2C_DEVICE_ID_GOODIX_01E9)) {
|
hdev->product == I2C_DEVICE_ID_GOODIX_01E9)) {
|
||||||
|
if (*size < 608) {
|
||||||
|
dev_info(
|
||||||
|
&hdev->dev,
|
||||||
|
"GT7868Q fixup: report descriptor is only %u bytes, skipping\n",
|
||||||
|
*size);
|
||||||
|
return rdesc;
|
||||||
|
}
|
||||||
|
|
||||||
if (rdesc[607] == 0x15) {
|
if (rdesc[607] == 0x15) {
|
||||||
rdesc[607] = 0x25;
|
rdesc[607] = 0x25;
|
||||||
dev_info(
|
dev_info(
|
||||||
|
|
|
||||||
|
|
@ -144,6 +144,9 @@ static void ntrig_report_version(struct hid_device *hdev)
|
||||||
struct usb_device *usb_dev = hid_to_usb_dev(hdev);
|
struct usb_device *usb_dev = hid_to_usb_dev(hdev);
|
||||||
unsigned char *data = kmalloc(8, GFP_KERNEL);
|
unsigned char *data = kmalloc(8, GFP_KERNEL);
|
||||||
|
|
||||||
|
if (!hid_is_usb(hdev))
|
||||||
|
return;
|
||||||
|
|
||||||
if (!data)
|
if (!data)
|
||||||
goto err_free;
|
goto err_free;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -124,6 +124,8 @@ static const struct hid_device_id hid_quirks[] = {
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X_V2), HID_QUIRK_MULTI_INPUT },
|
{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_MOUSEPEN_I608X_V2), HID_QUIRK_MULTI_INPUT },
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_PENSKETCH_T609A), HID_QUIRK_MULTI_INPUT },
|
{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_PENSKETCH_T609A), HID_QUIRK_MULTI_INPUT },
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_ODDOR_HANDBRAKE), HID_QUIRK_ALWAYS_POLL },
|
{ HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_ODDOR_HANDBRAKE), HID_QUIRK_ALWAYS_POLL },
|
||||||
|
{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_LEGION_GO_DUAL_DINPUT), HID_QUIRK_MULTI_INPUT },
|
||||||
|
{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_LEGION_GO2_DUAL_DINPUT), HID_QUIRK_MULTI_INPUT },
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_OPTICAL_USB_MOUSE_600E), HID_QUIRK_ALWAYS_POLL },
|
{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_OPTICAL_USB_MOUSE_600E), HID_QUIRK_ALWAYS_POLL },
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_608D), HID_QUIRK_ALWAYS_POLL },
|
{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_608D), HID_QUIRK_ALWAYS_POLL },
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_6019), HID_QUIRK_ALWAYS_POLL },
|
{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_6019), HID_QUIRK_ALWAYS_POLL },
|
||||||
|
|
@ -411,6 +413,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT4DRBK) },
|
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT4DRBK) },
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_DT1URBK) },
|
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_DT1URBK) },
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_DT1DRBK) },
|
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_DT1DRBK) },
|
||||||
|
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_DT2DRBK) },
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1URBK_010C) },
|
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1URBK_010C) },
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1URBK_019B) },
|
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1URBK_019B) },
|
||||||
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1DRBK_010D) },
|
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1DRBK_010D) },
|
||||||
|
|
|
||||||
|
|
@ -264,9 +264,6 @@ static void ish_shutdown(struct pci_dev *pdev)
|
||||||
|
|
||||||
static struct device __maybe_unused *ish_resume_device;
|
static struct device __maybe_unused *ish_resume_device;
|
||||||
|
|
||||||
/* 50ms to get resume response */
|
|
||||||
#define WAIT_FOR_RESUME_ACK_MS 50
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ish_resume_handler() - Work function to complete resume
|
* ish_resume_handler() - Work function to complete resume
|
||||||
* @work: work struct
|
* @work: work struct
|
||||||
|
|
|
||||||
|
|
@ -759,6 +759,9 @@ static void hid_ishtp_cl_resume_handler(struct work_struct *work)
|
||||||
if (ishtp_wait_resume(ishtp_get_ishtp_device(hid_ishtp_cl))) {
|
if (ishtp_wait_resume(ishtp_get_ishtp_device(hid_ishtp_cl))) {
|
||||||
client_data->suspended = false;
|
client_data->suspended = false;
|
||||||
wake_up_interruptible(&client_data->ishtp_resume_wait);
|
wake_up_interruptible(&client_data->ishtp_resume_wait);
|
||||||
|
} else {
|
||||||
|
hid_ishtp_trace(client_data, "hid client: wait for resume timed out");
|
||||||
|
dev_err(cl_data_to_dev(client_data), "wait for resume timed out");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -852,9 +852,6 @@ EXPORT_SYMBOL(ishtp_device);
|
||||||
*/
|
*/
|
||||||
bool ishtp_wait_resume(struct ishtp_device *dev)
|
bool ishtp_wait_resume(struct ishtp_device *dev)
|
||||||
{
|
{
|
||||||
/* 50ms to get resume response */
|
|
||||||
#define WAIT_FOR_RESUME_ACK_MS 50
|
|
||||||
|
|
||||||
/* Waiting to get resume response */
|
/* Waiting to get resume response */
|
||||||
if (dev->resume_flag)
|
if (dev->resume_flag)
|
||||||
wait_event_interruptible_timeout(dev->resume_wait,
|
wait_event_interruptible_timeout(dev->resume_wait,
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,9 @@
|
||||||
|
|
||||||
#define MAX_DMA_DELAY 20
|
#define MAX_DMA_DELAY 20
|
||||||
|
|
||||||
|
/* 300ms to get resume response */
|
||||||
|
#define WAIT_FOR_RESUME_ACK_MS 300
|
||||||
|
|
||||||
/* ISHTP device states */
|
/* ISHTP device states */
|
||||||
enum ishtp_dev_state {
|
enum ishtp_dev_state {
|
||||||
ISHTP_DEV_INITIALIZING = 0,
|
ISHTP_DEV_INITIALIZING = 0,
|
||||||
|
|
|
||||||
|
|
@ -419,6 +419,7 @@ static struct quicki2c_device *quicki2c_dev_init(struct pci_dev *pdev, void __io
|
||||||
*/
|
*/
|
||||||
static void quicki2c_dev_deinit(struct quicki2c_device *qcdev)
|
static void quicki2c_dev_deinit(struct quicki2c_device *qcdev)
|
||||||
{
|
{
|
||||||
|
thc_interrupt_quiesce(qcdev->thc_hw, true);
|
||||||
thc_interrupt_enable(qcdev->thc_hw, false);
|
thc_interrupt_enable(qcdev->thc_hw, false);
|
||||||
thc_ltr_unconfig(qcdev->thc_hw);
|
thc_ltr_unconfig(qcdev->thc_hw);
|
||||||
thc_wot_unconfig(qcdev->thc_hw);
|
thc_wot_unconfig(qcdev->thc_hw);
|
||||||
|
|
|
||||||
|
|
@ -77,6 +77,7 @@ struct quicki2c_subip_acpi_parameter {
|
||||||
u16 device_address;
|
u16 device_address;
|
||||||
u64 connection_speed;
|
u64 connection_speed;
|
||||||
u8 addressing_mode;
|
u8 addressing_mode;
|
||||||
|
u8 reserved;
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -126,6 +127,7 @@ struct quicki2c_subip_acpi_config {
|
||||||
u64 HMTD;
|
u64 HMTD;
|
||||||
u64 HMRD;
|
u64 HMRD;
|
||||||
u64 HMSL;
|
u64 HMSL;
|
||||||
|
u8 reserved;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -1540,7 +1540,7 @@ int thc_i2c_subip_regs_save(struct thc_device *dev)
|
||||||
|
|
||||||
for (int i = 0; i < ARRAY_SIZE(i2c_subip_regs); i++) {
|
for (int i = 0; i < ARRAY_SIZE(i2c_subip_regs); i++) {
|
||||||
ret = thc_i2c_subip_pio_read(dev, i2c_subip_regs[i],
|
ret = thc_i2c_subip_pio_read(dev, i2c_subip_regs[i],
|
||||||
&read_size, (u32 *)&dev->i2c_subip_regs + i);
|
&read_size, &dev->i2c_subip_regs[i]);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
@ -1563,7 +1563,7 @@ int thc_i2c_subip_regs_restore(struct thc_device *dev)
|
||||||
|
|
||||||
for (int i = 0; i < ARRAY_SIZE(i2c_subip_regs); i++) {
|
for (int i = 0; i < ARRAY_SIZE(i2c_subip_regs); i++) {
|
||||||
ret = thc_i2c_subip_pio_write(dev, i2c_subip_regs[i],
|
ret = thc_i2c_subip_pio_write(dev, i2c_subip_regs[i],
|
||||||
write_size, (u32 *)&dev->i2c_subip_regs + i);
|
write_size, &dev->i2c_subip_regs[i]);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -684,6 +684,7 @@ static bool wacom_is_art_pen(int tool_id)
|
||||||
case 0x885: /* Intuos3 Marker Pen */
|
case 0x885: /* Intuos3 Marker Pen */
|
||||||
case 0x804: /* Intuos4/5 13HD/24HD Marker Pen */
|
case 0x804: /* Intuos4/5 13HD/24HD Marker Pen */
|
||||||
case 0x10804: /* Intuos4/5 13HD/24HD Art Pen */
|
case 0x10804: /* Intuos4/5 13HD/24HD Art Pen */
|
||||||
|
case 0x204: /* Art Pen 2 */
|
||||||
is_art_pen = true;
|
is_art_pen = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue