Skip to content

Commit 061d1af

Browse files
committed
Merge tag 'for-linus-2024060801' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid
Pull HID fixes from Benjamin Tissoires: - fix potential read out of bounds in hid-asus (Andrew Ballance) - fix endian-conversion on little endian systems in intel-ish-hid (Arnd Bergmann) - A couple of new input event codes (Aseda Aboagye) - errors handling fixes in hid-nvidia-shield (Chen Ni), hid-nintendo (Christophe JAILLET), hid-logitech-dj (José Expósito) - current leakage fix while the device is in suspend on a i2c-hid laptop (Johan Hovold) - other assorted smaller fixes and device ID / quirk entry additions * tag 'for-linus-2024060801' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid: HID: Ignore battery for ELAN touchscreens 2F2C and 4116 HID: i2c-hid: elan: fix reset suspend current leakage dt-bindings: HID: i2c-hid: elan: add 'no-reset-on-power-off' property dt-bindings: HID: i2c-hid: elan: add Elan eKTH5015M dt-bindings: HID: i2c-hid: add dedicated Ilitek ILI2901 schema input: Add support for "Do Not Disturb" input: Add event code for accessibility key hid: asus: asus_report_fixup: fix potential read out of bounds HID: logitech-hidpp: add missing MODULE_DESCRIPTION() macro HID: intel-ish-hid: fix endian-conversion HID: nintendo: Fix an error handling path in nintendo_hid_probe() HID: logitech-dj: Fix memory leak in logi_dj_recv_switch_to_dj_mode() HID: core: remove unnecessary WARN_ON() in implement() HID: nvidia-shield: Add missing check for input_ff_create_memless HID: intel-ish-hid: Fix build error for COMPILE_TEST
2 parents 329f70c + a3a5a37 commit 061d1af

File tree

15 files changed

+222
-73
lines changed

15 files changed

+222
-73
lines changed

Documentation/devicetree/bindings/input/elan,ekth6915.yaml

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,12 @@ allOf:
1818

1919
properties:
2020
compatible:
21-
enum:
22-
- elan,ekth6915
23-
- ilitek,ili2901
21+
oneOf:
22+
- items:
23+
- enum:
24+
- elan,ekth5015m
25+
- const: elan,ekth6915
26+
- const: elan,ekth6915
2427

2528
reg:
2629
const: 0x10
@@ -33,6 +36,12 @@ properties:
3336
reset-gpios:
3437
description: Reset GPIO; not all touchscreens using eKTH6915 hook this up.
3538

39+
no-reset-on-power-off:
40+
type: boolean
41+
description:
42+
Reset line is wired so that it can (and should) be left deasserted when
43+
the power supply is off.
44+
3645
vcc33-supply:
3746
description: The 3.3V supply to the touchscreen.
3847

@@ -58,8 +67,8 @@ examples:
5867
#address-cells = <1>;
5968
#size-cells = <0>;
6069
61-
ap_ts: touchscreen@10 {
62-
compatible = "elan,ekth6915";
70+
touchscreen@10 {
71+
compatible = "elan,ekth5015m", "elan,ekth6915";
6372
reg = <0x10>;
6473
6574
interrupt-parent = <&tlmm>;
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2+
%YAML 1.2
3+
---
4+
$id: http://devicetree.org/schemas/input/ilitek,ili2901.yaml#
5+
$schema: http://devicetree.org/meta-schemas/core.yaml#
6+
7+
title: Ilitek ILI2901 touchscreen controller
8+
9+
maintainers:
10+
- Jiri Kosina <[email protected]>
11+
12+
description:
13+
Supports the Ilitek ILI2901 touchscreen controller.
14+
This touchscreen controller uses the i2c-hid protocol with a reset GPIO.
15+
16+
allOf:
17+
- $ref: /schemas/input/touchscreen/touchscreen.yaml#
18+
19+
properties:
20+
compatible:
21+
enum:
22+
- ilitek,ili2901
23+
24+
reg:
25+
maxItems: 1
26+
27+
interrupts:
28+
maxItems: 1
29+
30+
panel: true
31+
32+
reset-gpios:
33+
maxItems: 1
34+
35+
vcc33-supply: true
36+
37+
vccio-supply: true
38+
39+
required:
40+
- compatible
41+
- reg
42+
- interrupts
43+
- vcc33-supply
44+
45+
additionalProperties: false
46+
47+
examples:
48+
- |
49+
#include <dt-bindings/gpio/gpio.h>
50+
#include <dt-bindings/interrupt-controller/irq.h>
51+
52+
i2c {
53+
#address-cells = <1>;
54+
#size-cells = <0>;
55+
56+
touchscreen@41 {
57+
compatible = "ilitek,ili2901";
58+
reg = <0x41>;
59+
60+
interrupt-parent = <&tlmm>;
61+
interrupts = <9 IRQ_TYPE_LEVEL_LOW>;
62+
63+
reset-gpios = <&tlmm 8 GPIO_ACTIVE_LOW>;
64+
vcc33-supply = <&pp3300_ts>;
65+
};
66+
};

drivers/hid/hid-asus.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1204,8 +1204,8 @@ static __u8 *asus_report_fixup(struct hid_device *hdev, __u8 *rdesc,
12041204
}
12051205

12061206
/* match many more n-key devices */
1207-
if (drvdata->quirks & QUIRK_ROG_NKEY_KEYBOARD) {
1208-
for (int i = 0; i < *rsize + 1; i++) {
1207+
if (drvdata->quirks & QUIRK_ROG_NKEY_KEYBOARD && *rsize > 15) {
1208+
for (int i = 0; i < *rsize - 15; i++) {
12091209
/* offset to the count from 0x5a report part always 14 */
12101210
if (rdesc[i] == 0x85 && rdesc[i + 1] == 0x5a &&
12111211
rdesc[i + 14] == 0x95 && rdesc[i + 15] == 0x05) {

drivers/hid/hid-core.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1448,7 +1448,6 @@ static void implement(const struct hid_device *hid, u8 *report,
14481448
hid_warn(hid,
14491449
"%s() called with too large value %d (n: %d)! (%s)\n",
14501450
__func__, value, n, current->comm);
1451-
WARN_ON(1);
14521451
value &= m;
14531452
}
14541453
}

drivers/hid/hid-debug.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3366,6 +3366,8 @@ static const char *keys[KEY_MAX + 1] = {
33663366
[KEY_CAMERA_ACCESS_ENABLE] = "CameraAccessEnable",
33673367
[KEY_CAMERA_ACCESS_DISABLE] = "CameraAccessDisable",
33683368
[KEY_CAMERA_ACCESS_TOGGLE] = "CameraAccessToggle",
3369+
[KEY_ACCESSIBILITY] = "Accessibility",
3370+
[KEY_DO_NOT_DISTURB] = "DoNotDisturb",
33693371
[KEY_DICTATE] = "Dictate",
33703372
[KEY_MICMUTE] = "MicrophoneMute",
33713373
[KEY_BRIGHTNESS_MIN] = "BrightnessMin",

drivers/hid/hid-ids.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,8 @@
423423
#define I2C_DEVICE_ID_HP_SPECTRE_X360_13_AW0020NG 0x29DF
424424
#define I2C_DEVICE_ID_ASUS_TP420IA_TOUCHSCREEN 0x2BC8
425425
#define I2C_DEVICE_ID_ASUS_GV301RA_TOUCHSCREEN 0x2C82
426+
#define I2C_DEVICE_ID_ASUS_UX3402_TOUCHSCREEN 0x2F2C
427+
#define I2C_DEVICE_ID_ASUS_UX6404_TOUCHSCREEN 0x4116
426428
#define USB_DEVICE_ID_ASUS_UX550VE_TOUCHSCREEN 0x2544
427429
#define USB_DEVICE_ID_ASUS_UX550_TOUCHSCREEN 0x2706
428430
#define I2C_DEVICE_ID_SURFACE_GO_TOUCHSCREEN 0x261A

drivers/hid/hid-input.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,10 @@ static const struct hid_device_id hid_battery_quirks[] = {
377377
HID_BATTERY_QUIRK_IGNORE },
378378
{ HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_ASUS_GV301RA_TOUCHSCREEN),
379379
HID_BATTERY_QUIRK_IGNORE },
380+
{ HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_ASUS_UX3402_TOUCHSCREEN),
381+
HID_BATTERY_QUIRK_IGNORE },
382+
{ HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_ASUS_UX6404_TOUCHSCREEN),
383+
HID_BATTERY_QUIRK_IGNORE },
380384
{ HID_USB_DEVICE(USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ASUS_UX550_TOUCHSCREEN),
381385
HID_BATTERY_QUIRK_IGNORE },
382386
{ HID_USB_DEVICE(USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ASUS_UX550VE_TOUCHSCREEN),
@@ -833,9 +837,18 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
833837
break;
834838
}
835839

840+
if ((usage->hid & 0xf0) == 0x90) { /* SystemControl*/
841+
switch (usage->hid & 0xf) {
842+
case 0xb: map_key_clear(KEY_DO_NOT_DISTURB); break;
843+
default: goto ignore;
844+
}
845+
break;
846+
}
847+
836848
if ((usage->hid & 0xf0) == 0xa0) { /* SystemControl */
837849
switch (usage->hid & 0xf) {
838850
case 0x9: map_key_clear(KEY_MICMUTE); break;
851+
case 0xa: map_key_clear(KEY_ACCESSIBILITY); break;
839852
default: goto ignore;
840853
}
841854
break;

drivers/hid/hid-logitech-dj.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1284,8 +1284,10 @@ static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev,
12841284
*/
12851285
msleep(50);
12861286

1287-
if (retval)
1287+
if (retval) {
1288+
kfree(dj_report);
12881289
return retval;
1290+
}
12891291
}
12901292

12911293
/*

drivers/hid/hid-logitech-hidpp.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "usbhid/usbhid.h"
2828
#include "hid-ids.h"
2929

30+
MODULE_DESCRIPTION("Support for Logitech devices relying on the HID++ specification");
3031
MODULE_LICENSE("GPL");
3132
MODULE_AUTHOR("Benjamin Tissoires <[email protected]>");
3233
MODULE_AUTHOR("Nestor Lopez Casado <[email protected]>");

drivers/hid/hid-nintendo.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2725,20 +2725,22 @@ static int nintendo_hid_probe(struct hid_device *hdev,
27252725
ret = joycon_power_supply_create(ctlr);
27262726
if (ret) {
27272727
hid_err(hdev, "Failed to create power_supply; ret=%d\n", ret);
2728-
goto err_close;
2728+
goto err_ida;
27292729
}
27302730

27312731
ret = joycon_input_create(ctlr);
27322732
if (ret) {
27332733
hid_err(hdev, "Failed to create input device; ret=%d\n", ret);
2734-
goto err_close;
2734+
goto err_ida;
27352735
}
27362736

27372737
ctlr->ctlr_state = JOYCON_CTLR_STATE_READ;
27382738

27392739
hid_dbg(hdev, "probe - success\n");
27402740
return 0;
27412741

2742+
err_ida:
2743+
ida_free(&nintendo_player_id_allocator, ctlr->player_id);
27422744
err_close:
27432745
hid_hw_close(hdev);
27442746
err_stop:

drivers/hid/hid-nvidia-shield.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,9 @@ static struct input_dev *shield_haptics_create(
283283
return haptics;
284284

285285
input_set_capability(haptics, EV_FF, FF_RUMBLE);
286-
input_ff_create_memless(haptics, NULL, play_effect);
286+
ret = input_ff_create_memless(haptics, NULL, play_effect);
287+
if (ret)
288+
goto err;
287289

288290
ret = input_register_device(haptics);
289291
if (ret)

drivers/hid/i2c-hid/i2c-hid-of-elan.c

Lines changed: 47 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ struct i2c_hid_of_elan {
3131
struct regulator *vcc33;
3232
struct regulator *vccio;
3333
struct gpio_desc *reset_gpio;
34+
bool no_reset_on_power_off;
3435
const struct elan_i2c_hid_chip_data *chip_data;
3536
};
3637

@@ -40,17 +41,17 @@ static int elan_i2c_hid_power_up(struct i2chid_ops *ops)
4041
container_of(ops, struct i2c_hid_of_elan, ops);
4142
int ret;
4243

44+
gpiod_set_value_cansleep(ihid_elan->reset_gpio, 1);
45+
4346
if (ihid_elan->vcc33) {
4447
ret = regulator_enable(ihid_elan->vcc33);
4548
if (ret)
46-
return ret;
49+
goto err_deassert_reset;
4750
}
4851

4952
ret = regulator_enable(ihid_elan->vccio);
50-
if (ret) {
51-
regulator_disable(ihid_elan->vcc33);
52-
return ret;
53-
}
53+
if (ret)
54+
goto err_disable_vcc33;
5455

5556
if (ihid_elan->chip_data->post_power_delay_ms)
5657
msleep(ihid_elan->chip_data->post_power_delay_ms);
@@ -60,14 +61,30 @@ static int elan_i2c_hid_power_up(struct i2chid_ops *ops)
6061
msleep(ihid_elan->chip_data->post_gpio_reset_on_delay_ms);
6162

6263
return 0;
64+
65+
err_disable_vcc33:
66+
if (ihid_elan->vcc33)
67+
regulator_disable(ihid_elan->vcc33);
68+
err_deassert_reset:
69+
if (ihid_elan->no_reset_on_power_off)
70+
gpiod_set_value_cansleep(ihid_elan->reset_gpio, 0);
71+
72+
return ret;
6373
}
6474

6575
static void elan_i2c_hid_power_down(struct i2chid_ops *ops)
6676
{
6777
struct i2c_hid_of_elan *ihid_elan =
6878
container_of(ops, struct i2c_hid_of_elan, ops);
6979

70-
gpiod_set_value_cansleep(ihid_elan->reset_gpio, 1);
80+
/*
81+
* Do not assert reset when the hardware allows for it to remain
82+
* deasserted regardless of the state of the (shared) power supply to
83+
* avoid wasting power when the supply is left on.
84+
*/
85+
if (!ihid_elan->no_reset_on_power_off)
86+
gpiod_set_value_cansleep(ihid_elan->reset_gpio, 1);
87+
7188
if (ihid_elan->chip_data->post_gpio_reset_off_delay_ms)
7289
msleep(ihid_elan->chip_data->post_gpio_reset_off_delay_ms);
7390

@@ -79,6 +96,7 @@ static void elan_i2c_hid_power_down(struct i2chid_ops *ops)
7996
static int i2c_hid_of_elan_probe(struct i2c_client *client)
8097
{
8198
struct i2c_hid_of_elan *ihid_elan;
99+
int ret;
82100

83101
ihid_elan = devm_kzalloc(&client->dev, sizeof(*ihid_elan), GFP_KERNEL);
84102
if (!ihid_elan)
@@ -93,21 +111,38 @@ static int i2c_hid_of_elan_probe(struct i2c_client *client)
93111
if (IS_ERR(ihid_elan->reset_gpio))
94112
return PTR_ERR(ihid_elan->reset_gpio);
95113

114+
ihid_elan->no_reset_on_power_off = of_property_read_bool(client->dev.of_node,
115+
"no-reset-on-power-off");
116+
96117
ihid_elan->vccio = devm_regulator_get(&client->dev, "vccio");
97-
if (IS_ERR(ihid_elan->vccio))
98-
return PTR_ERR(ihid_elan->vccio);
118+
if (IS_ERR(ihid_elan->vccio)) {
119+
ret = PTR_ERR(ihid_elan->vccio);
120+
goto err_deassert_reset;
121+
}
99122

100123
ihid_elan->chip_data = device_get_match_data(&client->dev);
101124

102125
if (ihid_elan->chip_data->main_supply_name) {
103126
ihid_elan->vcc33 = devm_regulator_get(&client->dev,
104127
ihid_elan->chip_data->main_supply_name);
105-
if (IS_ERR(ihid_elan->vcc33))
106-
return PTR_ERR(ihid_elan->vcc33);
128+
if (IS_ERR(ihid_elan->vcc33)) {
129+
ret = PTR_ERR(ihid_elan->vcc33);
130+
goto err_deassert_reset;
131+
}
107132
}
108133

109-
return i2c_hid_core_probe(client, &ihid_elan->ops,
110-
ihid_elan->chip_data->hid_descriptor_address, 0);
134+
ret = i2c_hid_core_probe(client, &ihid_elan->ops,
135+
ihid_elan->chip_data->hid_descriptor_address, 0);
136+
if (ret)
137+
goto err_deassert_reset;
138+
139+
return 0;
140+
141+
err_deassert_reset:
142+
if (ihid_elan->no_reset_on_power_off)
143+
gpiod_set_value_cansleep(ihid_elan->reset_gpio, 0);
144+
145+
return ret;
111146
}
112147

113148
static const struct elan_i2c_hid_chip_data elan_ekth6915_chip_data = {

0 commit comments

Comments
 (0)