Skip to content

Commit a789d5f

Browse files
committed
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid
Pull HID updates from Jiri Kosina: - hid-mcp2221 GPIO support, from Rishi Gupta - MT_CLS_WIN_8_DUAL obsolete quirk removal from hid-multitouch, from Kai-Heng Feng - a bunch of new hardware support to hid-asus driver, from Hans de Goede - other assorted small fixes, cleanups and device-specific quirks * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid: HID: multitouch: Remove MT_CLS_WIN_8_DUAL HID: multitouch: enable multi-input as a quirk for some devices HID: sony: Fix for broken buttons on DS3 USB dongles HID: Add quirks for Trust Panora Graphic Tablet HID: apple: Swap the Fn and Left Control keys on Apple keyboards HID: asus: Add depends on USB_HID to HID_ASUS Kconfig option HID: asus: Fix mute and touchpad-toggle keys on Medion Akoya E1239T HID: asus: Add support for multi-touch touchpad on Medion Akoya E1239T HID: asus: Add report_size to struct asus_touchpad_info HID: asus: Add hid_is_using_ll_driver(usb_hid_driver) check HID: asus: Simplify skipping of mappings for Asus T100CHI keyboard-dock HID: asus: Only set EV_REP if we are adding a mapping HID: i2c-hid: add Schneider SCL142ALM to descriptor override HID: intel-ish-hid: avoid bogus uninitialized-variable warning HID: mcp2221: add GPIO functionality support HID: fix typo in Kconfig HID: logitech: drop outdated references to unifying receivers
2 parents 631d691 + 16ba7e3 commit a789d5f

File tree

12 files changed

+364
-74
lines changed

12 files changed

+364
-74
lines changed

drivers/hid/Kconfig

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ config HIDRAW
4242
---help---
4343
Say Y here if you want to support HID devices (from the USB
4444
specification standpoint) that aren't strictly user interface
45-
devices, like monitor controls and Uninterruptable Power Supplies.
45+
devices, like monitor controls and Uninterruptible Power Supplies.
4646

4747
This module supports these devices separately using a separate
4848
event interface on /dev/hidraw.
@@ -149,6 +149,7 @@ config HID_APPLEIR
149149

150150
config HID_ASUS
151151
tristate "Asus"
152+
depends on USB_HID
152153
depends on LEDS_CLASS
153154
depends on ASUS_WMI || ASUS_WMI=n
154155
select POWER_SUPPLY
@@ -538,14 +539,14 @@ config HID_LOGITECH
538539
Support for Logitech devices that are not fully compliant with HID standard.
539540

540541
config HID_LOGITECH_DJ
541-
tristate "Logitech Unifying receivers full support"
542+
tristate "Logitech receivers full support"
542543
depends on USB_HID
543544
depends on HIDRAW
544545
depends on HID_LOGITECH
545546
select HID_LOGITECH_HIDPP
546547
---help---
547-
Say Y if you want support for Logitech Unifying receivers and devices.
548-
Unifying receivers are capable of pairing up to 6 Logitech compliant
548+
Say Y if you want support for Logitech receivers and devices.
549+
Logitech receivers are capable of pairing multiple Logitech compliant
549550
devices to the same receiver. Without this driver it will be handled by
550551
generic USB_HID driver and all incoming events will be multiplexed
551552
into a single mouse and a single keyboard device.
@@ -1140,7 +1141,7 @@ config HID_SENSOR_CUSTOM_SENSOR
11401141
to decide how to interpret these special sensor ids and process in
11411142
the user space. Currently some manufacturers are using these ids for
11421143
sensor calibration and debugging other sensors. Manufacturers
1143-
should't use these special custom sensor ids to export any of the
1144+
shouldn't use these special custom sensor ids to export any of the
11441145
standard sensors.
11451146
Select this config option for custom/generic sensor support.
11461147

drivers/hid/hid-apple.c

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,12 @@ MODULE_PARM_DESC(swap_opt_cmd, "Swap the Option (\"Alt\") and Command (\"Flag\")
5151
"(For people who want to keep Windows PC keyboard muscle memory. "
5252
"[0] = as-is, Mac layout. 1 = swapped, Windows layout.)");
5353

54+
static unsigned int swap_fn_leftctrl;
55+
module_param(swap_fn_leftctrl, uint, 0644);
56+
MODULE_PARM_DESC(swap_fn_leftctrl, "Swap the Fn and left Control keys. "
57+
"(For people who want to keep PC keyboard muscle memory. "
58+
"[0] = as-is, Mac layout, 1 = swapped, PC layout)");
59+
5460
struct apple_sc {
5561
unsigned long quirks;
5662
unsigned int fn_on;
@@ -162,6 +168,11 @@ static const struct apple_key_translation swapped_option_cmd_keys[] = {
162168
{ }
163169
};
164170

171+
static const struct apple_key_translation swapped_fn_leftctrl_keys[] = {
172+
{ KEY_FN, KEY_LEFTCTRL },
173+
{ }
174+
};
175+
165176
static const struct apple_key_translation *apple_find_translation(
166177
const struct apple_key_translation *table, u16 from)
167178
{
@@ -183,9 +194,11 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
183194
bool do_translate;
184195
u16 code = 0;
185196

186-
if (usage->code == KEY_FN) {
197+
u16 fn_keycode = (swap_fn_leftctrl) ? (KEY_LEFTCTRL) : (KEY_FN);
198+
199+
if (usage->code == fn_keycode) {
187200
asc->fn_on = !!value;
188-
input_event(input, usage->type, usage->code, value);
201+
input_event(input, usage->type, KEY_FN, value);
189202
return 1;
190203
}
191204

@@ -270,6 +283,14 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
270283
}
271284
}
272285

286+
if (swap_fn_leftctrl) {
287+
trans = apple_find_translation(swapped_fn_leftctrl_keys, usage->code);
288+
if (trans) {
289+
input_event(input, usage->type, trans->to, value);
290+
return 1;
291+
}
292+
}
293+
273294
return 0;
274295
}
275296

@@ -333,6 +354,11 @@ static void apple_setup_input(struct input_dev *input)
333354

334355
for (trans = apple_iso_keyboard; trans->from; trans++)
335356
set_bit(trans->to, input->keybit);
357+
358+
if (swap_fn_leftctrl) {
359+
for (trans = swapped_fn_leftctrl_keys; trans->from; trans++)
360+
set_bit(trans->to, input->keybit);
361+
}
336362
}
337363

338364
static int apple_input_mapping(struct hid_device *hdev, struct hid_input *hi,

drivers/hid/hid-asus.c

Lines changed: 103 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,9 @@ MODULE_AUTHOR("Frederik Wenigwieser <[email protected]>");
4040
MODULE_DESCRIPTION("Asus HID Keyboard and TouchPad");
4141

4242
#define T100_TPAD_INTF 2
43+
#define MEDION_E1239T_TPAD_INTF 1
4344

45+
#define E1239T_TP_TOGGLE_REPORT_ID 0x05
4446
#define T100CHI_MOUSE_REPORT_ID 0x06
4547
#define FEATURE_REPORT_ID 0x0d
4648
#define INPUT_REPORT_ID 0x5d
@@ -77,6 +79,7 @@ MODULE_DESCRIPTION("Asus HID Keyboard and TouchPad");
7779
#define QUIRK_G752_KEYBOARD BIT(8)
7880
#define QUIRK_T101HA_DOCK BIT(9)
7981
#define QUIRK_T90CHI BIT(10)
82+
#define QUIRK_MEDION_E1239T BIT(11)
8083

8184
#define I2C_KEYBOARD_QUIRKS (QUIRK_FIX_NOTEBOOK_REPORT | \
8285
QUIRK_NO_INIT_REPORTS | \
@@ -102,12 +105,14 @@ struct asus_touchpad_info {
102105
int res_y;
103106
int contact_size;
104107
int max_contacts;
108+
int report_size;
105109
};
106110

107111
struct asus_drvdata {
108112
unsigned long quirks;
109113
struct hid_device *hdev;
110114
struct input_dev *input;
115+
struct input_dev *tp_kbd_input;
111116
struct asus_kbd_leds *kbd_backlight;
112117
const struct asus_touchpad_info *tp;
113118
bool enable_backlight;
@@ -126,6 +131,7 @@ static const struct asus_touchpad_info asus_i2c_tp = {
126131
.max_y = 1758,
127132
.contact_size = 5,
128133
.max_contacts = 5,
134+
.report_size = 28 /* 2 byte header + 5 * 5 + 1 byte footer */,
129135
};
130136

131137
static const struct asus_touchpad_info asus_t100ta_tp = {
@@ -135,6 +141,7 @@ static const struct asus_touchpad_info asus_t100ta_tp = {
135141
.res_y = 27, /* units/mm */
136142
.contact_size = 5,
137143
.max_contacts = 5,
144+
.report_size = 28 /* 2 byte header + 5 * 5 + 1 byte footer */,
138145
};
139146

140147
static const struct asus_touchpad_info asus_t100ha_tp = {
@@ -144,6 +151,7 @@ static const struct asus_touchpad_info asus_t100ha_tp = {
144151
.res_y = 29, /* units/mm */
145152
.contact_size = 5,
146153
.max_contacts = 5,
154+
.report_size = 28 /* 2 byte header + 5 * 5 + 1 byte footer */,
147155
};
148156

149157
static const struct asus_touchpad_info asus_t200ta_tp = {
@@ -153,6 +161,7 @@ static const struct asus_touchpad_info asus_t200ta_tp = {
153161
.res_y = 28, /* units/mm */
154162
.contact_size = 5,
155163
.max_contacts = 5,
164+
.report_size = 28 /* 2 byte header + 5 * 5 + 1 byte footer */,
156165
};
157166

158167
static const struct asus_touchpad_info asus_t100chi_tp = {
@@ -162,6 +171,17 @@ static const struct asus_touchpad_info asus_t100chi_tp = {
162171
.res_y = 29, /* units/mm */
163172
.contact_size = 3,
164173
.max_contacts = 4,
174+
.report_size = 15 /* 2 byte header + 3 * 4 + 1 byte footer */,
175+
};
176+
177+
static const struct asus_touchpad_info medion_e1239t_tp = {
178+
.max_x = 2640,
179+
.max_y = 1380,
180+
.res_x = 29, /* units/mm */
181+
.res_y = 28, /* units/mm */
182+
.contact_size = 5,
183+
.max_contacts = 5,
184+
.report_size = 32 /* 2 byte header + 5 * 5 + 5 byte footer */,
165185
};
166186

167187
static void asus_report_contact_down(struct asus_drvdata *drvdat,
@@ -229,7 +249,7 @@ static int asus_report_input(struct asus_drvdata *drvdat, u8 *data, int size)
229249
int i, toolType = MT_TOOL_FINGER;
230250
u8 *contactData = data + 2;
231251

232-
if (size != 3 + drvdat->tp->contact_size * drvdat->tp->max_contacts)
252+
if (size != drvdat->tp->report_size)
233253
return 0;
234254

235255
for (i = 0; i < drvdat->tp->max_contacts; i++) {
@@ -257,6 +277,34 @@ static int asus_report_input(struct asus_drvdata *drvdat, u8 *data, int size)
257277
return 1;
258278
}
259279

280+
static int asus_e1239t_event(struct asus_drvdata *drvdat, u8 *data, int size)
281+
{
282+
if (size != 3)
283+
return 0;
284+
285+
/* Handle broken mute key which only sends press events */
286+
if (!drvdat->tp &&
287+
data[0] == 0x02 && data[1] == 0xe2 && data[2] == 0x00) {
288+
input_report_key(drvdat->input, KEY_MUTE, 1);
289+
input_sync(drvdat->input);
290+
input_report_key(drvdat->input, KEY_MUTE, 0);
291+
input_sync(drvdat->input);
292+
return 1;
293+
}
294+
295+
/* Handle custom touchpad toggle key which only sends press events */
296+
if (drvdat->tp_kbd_input &&
297+
data[0] == 0x05 && data[1] == 0x02 && data[2] == 0x28) {
298+
input_report_key(drvdat->tp_kbd_input, KEY_F21, 1);
299+
input_sync(drvdat->tp_kbd_input);
300+
input_report_key(drvdat->tp_kbd_input, KEY_F21, 0);
301+
input_sync(drvdat->tp_kbd_input);
302+
return 1;
303+
}
304+
305+
return 0;
306+
}
307+
260308
static int asus_event(struct hid_device *hdev, struct hid_field *field,
261309
struct hid_usage *usage, __s32 value)
262310
{
@@ -281,6 +329,9 @@ static int asus_raw_event(struct hid_device *hdev,
281329
if (drvdata->tp && data[0] == INPUT_REPORT_ID)
282330
return asus_report_input(drvdata, data, size);
283331

332+
if (drvdata->quirks & QUIRK_MEDION_E1239T)
333+
return asus_e1239t_event(drvdata, data, size);
334+
284335
return 0;
285336
}
286337

@@ -615,6 +666,21 @@ static int asus_input_configured(struct hid_device *hdev, struct hid_input *hi)
615666
hi->report->id != T100CHI_MOUSE_REPORT_ID)
616667
return 0;
617668

669+
/* Handle MULTI_INPUT on E1239T mouse/touchpad USB interface */
670+
if (drvdata->tp && (drvdata->quirks & QUIRK_MEDION_E1239T)) {
671+
switch (hi->report->id) {
672+
case E1239T_TP_TOGGLE_REPORT_ID:
673+
input_set_capability(input, EV_KEY, KEY_F21);
674+
input->name = "Asus Touchpad Keys";
675+
drvdata->tp_kbd_input = input;
676+
return 0;
677+
case INPUT_REPORT_ID:
678+
break; /* Touchpad report, handled below */
679+
default:
680+
return 0; /* Ignore other reports */
681+
}
682+
}
683+
618684
if (drvdata->tp) {
619685
int ret;
620686

@@ -677,24 +743,16 @@ static int asus_input_mapping(struct hid_device *hdev,
677743
* This avoids a bunch of non-functional hid_input devices getting
678744
* created because of the T100CHI using HID_QUIRK_MULTI_INPUT.
679745
*/
680-
if (drvdata->quirks & (QUIRK_T100CHI | QUIRK_T90CHI)) {
681-
if (field->application == (HID_UP_GENDESK | 0x0080) ||
682-
usage->hid == (HID_UP_GENDEVCTRLS | 0x0024) ||
683-
usage->hid == (HID_UP_GENDEVCTRLS | 0x0025) ||
684-
usage->hid == (HID_UP_GENDEVCTRLS | 0x0026))
685-
return -1;
686-
/*
687-
* We use the hid_input for the mouse report for the touchpad,
688-
* keep the left button, to avoid the core removing it.
689-
*/
690-
if (field->application == HID_GD_MOUSE &&
691-
usage->hid != (HID_UP_BUTTON | 1))
692-
return -1;
693-
}
746+
if ((drvdata->quirks & (QUIRK_T100CHI | QUIRK_T90CHI)) &&
747+
(field->application == (HID_UP_GENDESK | 0x0080) ||
748+
field->application == HID_GD_MOUSE ||
749+
usage->hid == (HID_UP_GENDEVCTRLS | 0x0024) ||
750+
usage->hid == (HID_UP_GENDEVCTRLS | 0x0025) ||
751+
usage->hid == (HID_UP_GENDEVCTRLS | 0x0026)))
752+
return -1;
694753

695754
/* ASUS-specific keyboard hotkeys */
696755
if ((usage->hid & HID_USAGE_PAGE) == 0xff310000) {
697-
set_bit(EV_REP, hi->input->evbit);
698756
switch (usage->hid & HID_USAGE) {
699757
case 0x10: asus_map_key_clear(KEY_BRIGHTNESSDOWN); break;
700758
case 0x20: asus_map_key_clear(KEY_BRIGHTNESSUP); break;
@@ -737,11 +795,11 @@ static int asus_input_mapping(struct hid_device *hdev,
737795
if (drvdata->quirks & QUIRK_USE_KBD_BACKLIGHT)
738796
drvdata->enable_backlight = true;
739797

798+
set_bit(EV_REP, hi->input->evbit);
740799
return 1;
741800
}
742801

743802
if ((usage->hid & HID_USAGE_PAGE) == HID_UP_MSVENDOR) {
744-
set_bit(EV_REP, hi->input->evbit);
745803
switch (usage->hid & HID_USAGE) {
746804
case 0xff01: asus_map_key_clear(BTN_1); break;
747805
case 0xff02: asus_map_key_clear(BTN_2); break;
@@ -764,6 +822,7 @@ static int asus_input_mapping(struct hid_device *hdev,
764822
return 0;
765823
}
766824

825+
set_bit(EV_REP, hi->input->evbit);
767826
return 1;
768827
}
769828

@@ -782,6 +841,16 @@ static int asus_input_mapping(struct hid_device *hdev,
782841
}
783842
}
784843

844+
/*
845+
* The mute button is broken and only sends press events, we
846+
* deal with this in our raw_event handler, so do not map it.
847+
*/
848+
if ((drvdata->quirks & QUIRK_MEDION_E1239T) &&
849+
usage->hid == (HID_UP_CONSUMER | 0xe2)) {
850+
input_set_capability(hi->input, EV_KEY, KEY_MUTE);
851+
return -1;
852+
}
853+
785854
return 0;
786855
}
787856

@@ -849,7 +918,8 @@ static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id)
849918
if (drvdata->quirks & QUIRK_IS_MULTITOUCH)
850919
drvdata->tp = &asus_i2c_tp;
851920

852-
if (drvdata->quirks & QUIRK_T100_KEYBOARD) {
921+
if ((drvdata->quirks & QUIRK_T100_KEYBOARD) &&
922+
hid_is_using_ll_driver(hdev, &usb_hid_driver)) {
853923
struct usb_interface *intf = to_usb_interface(hdev->dev.parent);
854924

855925
if (intf->altsetting->desc.bInterfaceNumber == T100_TPAD_INTF) {
@@ -877,6 +947,19 @@ static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id)
877947
drvdata->tp = &asus_t100chi_tp;
878948
}
879949

950+
if ((drvdata->quirks & QUIRK_MEDION_E1239T) &&
951+
hid_is_using_ll_driver(hdev, &usb_hid_driver)) {
952+
struct usb_host_interface *alt =
953+
to_usb_interface(hdev->dev.parent)->altsetting;
954+
955+
if (alt->desc.bInterfaceNumber == MEDION_E1239T_TPAD_INTF) {
956+
/* For separate input-devs for tp and tp toggle key */
957+
hdev->quirks |= HID_QUIRK_MULTI_INPUT;
958+
drvdata->quirks |= QUIRK_SKIP_INPUT_MAPPING;
959+
drvdata->tp = &medion_e1239t_tp;
960+
}
961+
}
962+
880963
if (drvdata->quirks & QUIRK_NO_INIT_REPORTS)
881964
hdev->quirks |= HID_QUIRK_NO_INIT_REPORTS;
882965

@@ -1056,7 +1139,8 @@ static const struct hid_device_id asus_devices[] = {
10561139
{ HID_USB_DEVICE(USB_VENDOR_ID_JESS, USB_DEVICE_ID_ASUS_MD_5112) },
10571140
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ASUSTEK,
10581141
USB_DEVICE_ID_ASUSTEK_T100CHI_KEYBOARD), QUIRK_T100CHI },
1059-
1142+
{ HID_USB_DEVICE(USB_VENDOR_ID_ITE, USB_DEVICE_ID_ITE_MEDION_E1239T),
1143+
QUIRK_MEDION_E1239T },
10601144
{ }
10611145
};
10621146
MODULE_DEVICE_TABLE(hid, asus_devices);

0 commit comments

Comments
 (0)