Skip to content

Commit d5530d8

Browse files
committed
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid
Pull HID fixes from Jiri Kosina: - Various functionality / regression fixes for Logitech devices from Hans de Goede - Fix for (recently added) GPIO support in mcp2221 driver from Lars Povlsen - Power management handling fix/quirk in i2c-hid driver for certain BIOSes that have strange aproach to power-cycle from Hans de Goede - a few device ID additions and device-specific quirks * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid: HID: logitech-dj: Fix Dinovo Mini when paired with a MX5x00 receiver HID: logitech-dj: Fix an error in mse_bluetooth_descriptor HID: Add Logitech Dinovo Edge battery quirk HID: logitech-hidpp: Add HIDPP_CONSUMER_VENDOR_KEYS quirk for the Dinovo Edge HID: logitech-dj: Handle quad/bluetooth keyboards with a builtin trackpad HID: add HID_QUIRK_INCREMENT_USAGE_ON_DUPLICATE for Gamevice devices HID: mcp2221: Fix GPIO output handling HID: hid-sensor-hub: Fix issue with devices with no report ID HID: i2c-hid: Put ACPI enumerated devices in D3 on shutdown HID: add support for Sega Saturn HID: cypress: Support Varmilo Keyboards' media hotkeys HID: ite: Replace ABS_MISC 120/121 events with touchpad on/off keypresses HID: logitech-hidpp: Add PID for MX Anywhere 2 HID: uclogic: Add ID for Trust Flex Design Tablet
2 parents f4b936f + b4c00e7 commit d5530d8

12 files changed

+223
-17
lines changed

drivers/hid/hid-cypress.c

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,17 @@
2323
#define CP_2WHEEL_MOUSE_HACK 0x02
2424
#define CP_2WHEEL_MOUSE_HACK_ON 0x04
2525

26+
#define VA_INVAL_LOGICAL_BOUNDARY 0x08
27+
2628
/*
2729
* Some USB barcode readers from cypress have usage min and usage max in
2830
* the wrong order
2931
*/
30-
static __u8 *cp_report_fixup(struct hid_device *hdev, __u8 *rdesc,
32+
static __u8 *cp_rdesc_fixup(struct hid_device *hdev, __u8 *rdesc,
3133
unsigned int *rsize)
3234
{
33-
unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
3435
unsigned int i;
3536

36-
if (!(quirks & CP_RDESC_SWAPPED_MIN_MAX))
37-
return rdesc;
38-
3937
if (*rsize < 4)
4038
return rdesc;
4139

@@ -48,6 +46,40 @@ static __u8 *cp_report_fixup(struct hid_device *hdev, __u8 *rdesc,
4846
return rdesc;
4947
}
5048

49+
static __u8 *va_logical_boundary_fixup(struct hid_device *hdev, __u8 *rdesc,
50+
unsigned int *rsize)
51+
{
52+
/*
53+
* Varmilo VA104M (with VID Cypress and device ID 07B1) incorrectly
54+
* reports Logical Minimum of its Consumer Control device as 572
55+
* (0x02 0x3c). Fix this by setting its Logical Minimum to zero.
56+
*/
57+
if (*rsize == 25 &&
58+
rdesc[0] == 0x05 && rdesc[1] == 0x0c &&
59+
rdesc[2] == 0x09 && rdesc[3] == 0x01 &&
60+
rdesc[6] == 0x19 && rdesc[7] == 0x00 &&
61+
rdesc[11] == 0x16 && rdesc[12] == 0x3c && rdesc[13] == 0x02) {
62+
hid_info(hdev,
63+
"fixing up varmilo VA104M consumer control report descriptor\n");
64+
rdesc[12] = 0x00;
65+
rdesc[13] = 0x00;
66+
}
67+
return rdesc;
68+
}
69+
70+
static __u8 *cp_report_fixup(struct hid_device *hdev, __u8 *rdesc,
71+
unsigned int *rsize)
72+
{
73+
unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
74+
75+
if (quirks & CP_RDESC_SWAPPED_MIN_MAX)
76+
rdesc = cp_rdesc_fixup(hdev, rdesc, rsize);
77+
if (quirks & VA_INVAL_LOGICAL_BOUNDARY)
78+
rdesc = va_logical_boundary_fixup(hdev, rdesc, rsize);
79+
80+
return rdesc;
81+
}
82+
5183
static int cp_input_mapped(struct hid_device *hdev, struct hid_input *hi,
5284
struct hid_field *field, struct hid_usage *usage,
5385
unsigned long **bit, int *max)
@@ -128,6 +160,8 @@ static const struct hid_device_id cp_devices[] = {
128160
.driver_data = CP_RDESC_SWAPPED_MIN_MAX },
129161
{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE),
130162
.driver_data = CP_2WHEEL_MOUSE_HACK },
163+
{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_VARMILO_VA104M_07B1),
164+
.driver_data = VA_INVAL_LOGICAL_BOUNDARY },
131165
{ }
132166
};
133167
MODULE_DEVICE_TABLE(hid, cp_devices);

drivers/hid/hid-ids.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,8 @@
331331
#define USB_DEVICE_ID_CYPRESS_BARCODE_4 0xed81
332332
#define USB_DEVICE_ID_CYPRESS_TRUETOUCH 0xc001
333333

334+
#define USB_DEVICE_ID_CYPRESS_VARMILO_VA104M_07B1 0X07b1
335+
334336
#define USB_VENDOR_ID_DATA_MODUL 0x7374
335337
#define USB_VENDOR_ID_DATA_MODUL_EASYMAXTOUCH 0x1201
336338

@@ -443,6 +445,10 @@
443445
#define USB_VENDOR_ID_FRUCTEL 0x25B6
444446
#define USB_DEVICE_ID_GAMETEL_MT_MODE 0x0002
445447

448+
#define USB_VENDOR_ID_GAMEVICE 0x27F8
449+
#define USB_DEVICE_ID_GAMEVICE_GV186 0x0BBE
450+
#define USB_DEVICE_ID_GAMEVICE_KISHI 0x0BBF
451+
446452
#define USB_VENDOR_ID_GAMERON 0x0810
447453
#define USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR 0x0001
448454
#define USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR 0x0002
@@ -485,6 +491,7 @@
485491
#define USB_DEVICE_ID_PENPOWER 0x00f4
486492

487493
#define USB_VENDOR_ID_GREENASIA 0x0e8f
494+
#define USB_DEVICE_ID_GREENASIA_DUAL_SAT_ADAPTOR 0x3010
488495
#define USB_DEVICE_ID_GREENASIA_DUAL_USB_JOYPAD 0x3013
489496

490497
#define USB_VENDOR_ID_GRETAGMACBETH 0x0971
@@ -743,6 +750,7 @@
743750
#define USB_VENDOR_ID_LOGITECH 0x046d
744751
#define USB_DEVICE_ID_LOGITECH_AUDIOHUB 0x0a0e
745752
#define USB_DEVICE_ID_LOGITECH_T651 0xb00c
753+
#define USB_DEVICE_ID_LOGITECH_DINOVO_EDGE_KBD 0xb309
746754
#define USB_DEVICE_ID_LOGITECH_C007 0xc007
747755
#define USB_DEVICE_ID_LOGITECH_C077 0xc077
748756
#define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101
@@ -1298,6 +1306,7 @@
12981306

12991307
#define USB_VENDOR_ID_UGTIZER 0x2179
13001308
#define USB_DEVICE_ID_UGTIZER_TABLET_GP0610 0x0053
1309+
#define USB_DEVICE_ID_UGTIZER_TABLET_GT5040 0x0077
13011310

13021311
#define USB_VENDOR_ID_VIEWSONIC 0x0543
13031312
#define USB_DEVICE_ID_VIEWSONIC_PD1011 0xe621

drivers/hid/hid-input.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,9 @@ static const struct hid_device_id hid_battery_quirks[] = {
319319
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ASUSTEK,
320320
USB_DEVICE_ID_ASUSTEK_T100CHI_KEYBOARD),
321321
HID_BATTERY_QUIRK_IGNORE },
322+
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH,
323+
USB_DEVICE_ID_LOGITECH_DINOVO_EDGE_KBD),
324+
HID_BATTERY_QUIRK_IGNORE },
322325
{}
323326
};
324327

drivers/hid/hid-ite.c

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,48 @@
1111

1212
#include "hid-ids.h"
1313

14+
#define QUIRK_TOUCHPAD_ON_OFF_REPORT BIT(0)
15+
16+
static __u8 *ite_report_fixup(struct hid_device *hdev, __u8 *rdesc, unsigned int *rsize)
17+
{
18+
unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
19+
20+
if (quirks & QUIRK_TOUCHPAD_ON_OFF_REPORT) {
21+
if (*rsize == 188 && rdesc[162] == 0x81 && rdesc[163] == 0x02) {
22+
hid_info(hdev, "Fixing up ITE keyboard report descriptor\n");
23+
rdesc[163] = HID_MAIN_ITEM_RELATIVE;
24+
}
25+
}
26+
27+
return rdesc;
28+
}
29+
30+
static int ite_input_mapping(struct hid_device *hdev,
31+
struct hid_input *hi, struct hid_field *field,
32+
struct hid_usage *usage, unsigned long **bit,
33+
int *max)
34+
{
35+
36+
unsigned long quirks = (unsigned long)hid_get_drvdata(hdev);
37+
38+
if ((quirks & QUIRK_TOUCHPAD_ON_OFF_REPORT) &&
39+
(usage->hid & HID_USAGE_PAGE) == 0x00880000) {
40+
if (usage->hid == 0x00880078) {
41+
/* Touchpad on, userspace expects F22 for this */
42+
hid_map_usage_clear(hi, usage, bit, max, EV_KEY, KEY_F22);
43+
return 1;
44+
}
45+
if (usage->hid == 0x00880079) {
46+
/* Touchpad off, userspace expects F23 for this */
47+
hid_map_usage_clear(hi, usage, bit, max, EV_KEY, KEY_F23);
48+
return 1;
49+
}
50+
return -1;
51+
}
52+
53+
return 0;
54+
}
55+
1456
static int ite_event(struct hid_device *hdev, struct hid_field *field,
1557
struct hid_usage *usage, __s32 value)
1658
{
@@ -37,13 +79,27 @@ static int ite_event(struct hid_device *hdev, struct hid_field *field,
3779
return 0;
3880
}
3981

82+
static int ite_probe(struct hid_device *hdev, const struct hid_device_id *id)
83+
{
84+
int ret;
85+
86+
hid_set_drvdata(hdev, (void *)id->driver_data);
87+
88+
ret = hid_open_report(hdev);
89+
if (ret)
90+
return ret;
91+
92+
return hid_hw_start(hdev, HID_CONNECT_DEFAULT);
93+
}
94+
4095
static const struct hid_device_id ite_devices[] = {
4196
{ HID_USB_DEVICE(USB_VENDOR_ID_ITE, USB_DEVICE_ID_ITE8595) },
4297
{ HID_USB_DEVICE(USB_VENDOR_ID_258A, USB_DEVICE_ID_258A_6A88) },
4398
/* ITE8595 USB kbd ctlr, with Synaptics touchpad connected to it. */
4499
{ HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
45100
USB_VENDOR_ID_SYNAPTICS,
46-
USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5_012) },
101+
USB_DEVICE_ID_SYNAPTICS_ACER_SWITCH5_012),
102+
.driver_data = QUIRK_TOUCHPAD_ON_OFF_REPORT },
47103
/* ITE8910 USB kbd ctlr, with Synaptics touchpad connected to it. */
48104
{ HID_DEVICE(BUS_USB, HID_GROUP_GENERIC,
49105
USB_VENDOR_ID_SYNAPTICS,
@@ -55,6 +111,9 @@ MODULE_DEVICE_TABLE(hid, ite_devices);
55111
static struct hid_driver ite_driver = {
56112
.name = "itetech",
57113
.id_table = ite_devices,
114+
.probe = ite_probe,
115+
.report_fixup = ite_report_fixup,
116+
.input_mapping = ite_input_mapping,
58117
.event = ite_event,
59118
};
60119
module_hid_driver(ite_driver);

drivers/hid/hid-logitech-dj.c

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ static const char mse_bluetooth_descriptor[] = {
328328
0x25, 0x01, /* LOGICAL_MAX (1) */
329329
0x75, 0x01, /* REPORT_SIZE (1) */
330330
0x95, 0x04, /* REPORT_COUNT (4) */
331-
0x81, 0x06, /* INPUT */
331+
0x81, 0x02, /* INPUT (Data,Var,Abs) */
332332
0xC0, /* END_COLLECTION */
333333
0xC0, /* END_COLLECTION */
334334
};
@@ -866,11 +866,24 @@ static void logi_dj_recv_queue_notification(struct dj_receiver_dev *djrcv_dev,
866866
schedule_work(&djrcv_dev->work);
867867
}
868868

869+
/*
870+
* Some quad/bluetooth keyboards have a builtin touchpad in this case we see
871+
* only 1 paired device with a device_type of REPORT_TYPE_KEYBOARD. For the
872+
* touchpad to work we must also forward mouse input reports to the dj_hiddev
873+
* created for the keyboard (instead of forwarding them to a second paired
874+
* device with a device_type of REPORT_TYPE_MOUSE as we normally would).
875+
*/
876+
static const u16 kbd_builtin_touchpad_ids[] = {
877+
0xb309, /* Dinovo Edge */
878+
0xb30c, /* Dinovo Mini */
879+
};
880+
869881
static void logi_hidpp_dev_conn_notif_equad(struct hid_device *hdev,
870882
struct hidpp_event *hidpp_report,
871883
struct dj_workitem *workitem)
872884
{
873885
struct dj_receiver_dev *djrcv_dev = hid_get_drvdata(hdev);
886+
int i, id;
874887

875888
workitem->type = WORKITEM_TYPE_PAIRED;
876889
workitem->device_type = hidpp_report->params[HIDPP_PARAM_DEVICE_INFO] &
@@ -882,6 +895,13 @@ static void logi_hidpp_dev_conn_notif_equad(struct hid_device *hdev,
882895
workitem->reports_supported |= STD_KEYBOARD | MULTIMEDIA |
883896
POWER_KEYS | MEDIA_CENTER |
884897
HIDPP;
898+
id = (workitem->quad_id_msb << 8) | workitem->quad_id_lsb;
899+
for (i = 0; i < ARRAY_SIZE(kbd_builtin_touchpad_ids); i++) {
900+
if (id == kbd_builtin_touchpad_ids[i]) {
901+
workitem->reports_supported |= STD_MOUSE;
902+
break;
903+
}
904+
}
885905
break;
886906
case REPORT_TYPE_MOUSE:
887907
workitem->reports_supported |= STD_MOUSE | HIDPP;

drivers/hid/hid-logitech-hidpp.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ MODULE_PARM_DESC(disable_tap_to_click,
9393
#define HIDPP_CAPABILITY_BATTERY_LEVEL_STATUS BIT(3)
9494
#define HIDPP_CAPABILITY_BATTERY_VOLTAGE BIT(4)
9595

96+
#define lg_map_key_clear(c) hid_map_usage_clear(hi, usage, bit, max, EV_KEY, (c))
97+
9698
/*
9799
* There are two hidpp protocols in use, the first version hidpp10 is known
98100
* as register access protocol or RAP, the second version hidpp20 is known as
@@ -2950,6 +2952,26 @@ static int g920_get_config(struct hidpp_device *hidpp,
29502952
return g920_ff_set_autocenter(hidpp, data);
29512953
}
29522954

2955+
/* -------------------------------------------------------------------------- */
2956+
/* Logitech Dinovo Mini keyboard with builtin touchpad */
2957+
/* -------------------------------------------------------------------------- */
2958+
#define DINOVO_MINI_PRODUCT_ID 0xb30c
2959+
2960+
static int lg_dinovo_input_mapping(struct hid_device *hdev, struct hid_input *hi,
2961+
struct hid_field *field, struct hid_usage *usage,
2962+
unsigned long **bit, int *max)
2963+
{
2964+
if ((usage->hid & HID_USAGE_PAGE) != HID_UP_LOGIVENDOR)
2965+
return 0;
2966+
2967+
switch (usage->hid & HID_USAGE) {
2968+
case 0x00d: lg_map_key_clear(KEY_MEDIA); break;
2969+
default:
2970+
return 0;
2971+
}
2972+
return 1;
2973+
}
2974+
29532975
/* -------------------------------------------------------------------------- */
29542976
/* HID++1.0 devices which use HID++ reports for their wheels */
29552977
/* -------------------------------------------------------------------------- */
@@ -3185,6 +3207,9 @@ static int hidpp_input_mapping(struct hid_device *hdev, struct hid_input *hi,
31853207
field->application != HID_GD_MOUSE)
31863208
return m560_input_mapping(hdev, hi, field, usage, bit, max);
31873209

3210+
if (hdev->product == DINOVO_MINI_PRODUCT_ID)
3211+
return lg_dinovo_input_mapping(hdev, hi, field, usage, bit, max);
3212+
31883213
return 0;
31893214
}
31903215

@@ -3947,6 +3972,7 @@ static const struct hid_device_id hidpp_devices[] = {
39473972
LDJ_DEVICE(0x405e), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
39483973
{ /* Mouse Logitech MX Anywhere 2 */
39493974
LDJ_DEVICE(0x404a), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
3975+
{ LDJ_DEVICE(0x4072), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
39503976
{ LDJ_DEVICE(0xb013), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
39513977
{ LDJ_DEVICE(0xb018), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
39523978
{ LDJ_DEVICE(0xb01f), .driver_data = HIDPP_QUIRK_HI_RES_SCROLL_X2121 },
@@ -3971,6 +3997,9 @@ static const struct hid_device_id hidpp_devices[] = {
39713997
{ /* Keyboard MX5000 (Bluetooth-receiver in HID proxy mode) */
39723998
LDJ_DEVICE(0xb305),
39733999
.driver_data = HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS },
4000+
{ /* Dinovo Edge (Bluetooth-receiver in HID proxy mode) */
4001+
LDJ_DEVICE(0xb309),
4002+
.driver_data = HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS },
39744003
{ /* Keyboard MX5500 (Bluetooth-receiver in HID proxy mode) */
39754004
LDJ_DEVICE(0xb30b),
39764005
.driver_data = HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS },
@@ -4013,6 +4042,9 @@ static const struct hid_device_id hidpp_devices[] = {
40134042
{ /* MX5000 keyboard over Bluetooth */
40144043
HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb305),
40154044
.driver_data = HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS },
4045+
{ /* Dinovo Edge keyboard over Bluetooth */
4046+
HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb309),
4047+
.driver_data = HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS },
40164048
{ /* MX5500 keyboard over Bluetooth */
40174049
HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb30b),
40184050
.driver_data = HIDPP_QUIRK_HIDPP_CONSUMER_VENDOR_KEYS },

0 commit comments

Comments
 (0)