Skip to content

Commit

Permalink
Merge tag 'for-linus-2024060801' of git://git.kernel.org/pub/scm/linu…
Browse files Browse the repository at this point in the history
…x/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
  • Loading branch information
torvalds committed Jun 8, 2024
2 parents 329f70c + a3a5a37 commit 061d1af
Show file tree
Hide file tree
Showing 15 changed files with 222 additions and 73 deletions.
19 changes: 14 additions & 5 deletions Documentation/devicetree/bindings/input/elan,ekth6915.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,12 @@ allOf:

properties:
compatible:
enum:
- elan,ekth6915
- ilitek,ili2901
oneOf:
- items:
- enum:
- elan,ekth5015m
- const: elan,ekth6915
- const: elan,ekth6915

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

no-reset-on-power-off:
type: boolean
description:
Reset line is wired so that it can (and should) be left deasserted when
the power supply is off.

vcc33-supply:
description: The 3.3V supply to the touchscreen.

Expand All @@ -58,8 +67,8 @@ examples:
#address-cells = <1>;
#size-cells = <0>;
ap_ts: touchscreen@10 {
compatible = "elan,ekth6915";
touchscreen@10 {
compatible = "elan,ekth5015m", "elan,ekth6915";
reg = <0x10>;
interrupt-parent = <&tlmm>;
Expand Down
66 changes: 66 additions & 0 deletions Documentation/devicetree/bindings/input/ilitek,ili2901.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/input/ilitek,ili2901.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

title: Ilitek ILI2901 touchscreen controller

maintainers:
- Jiri Kosina <[email protected]>

description:
Supports the Ilitek ILI2901 touchscreen controller.
This touchscreen controller uses the i2c-hid protocol with a reset GPIO.

allOf:
- $ref: /schemas/input/touchscreen/touchscreen.yaml#

properties:
compatible:
enum:
- ilitek,ili2901

reg:
maxItems: 1

interrupts:
maxItems: 1

panel: true

reset-gpios:
maxItems: 1

vcc33-supply: true

vccio-supply: true

required:
- compatible
- reg
- interrupts
- vcc33-supply

additionalProperties: false

examples:
- |
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/interrupt-controller/irq.h>
i2c {
#address-cells = <1>;
#size-cells = <0>;
touchscreen@41 {
compatible = "ilitek,ili2901";
reg = <0x41>;
interrupt-parent = <&tlmm>;
interrupts = <9 IRQ_TYPE_LEVEL_LOW>;
reset-gpios = <&tlmm 8 GPIO_ACTIVE_LOW>;
vcc33-supply = <&pp3300_ts>;
};
};
4 changes: 2 additions & 2 deletions drivers/hid/hid-asus.c
Original file line number Diff line number Diff line change
Expand Up @@ -1204,8 +1204,8 @@ static __u8 *asus_report_fixup(struct hid_device *hdev, __u8 *rdesc,
}

/* match many more n-key devices */
if (drvdata->quirks & QUIRK_ROG_NKEY_KEYBOARD) {
for (int i = 0; i < *rsize + 1; i++) {
if (drvdata->quirks & QUIRK_ROG_NKEY_KEYBOARD && *rsize > 15) {
for (int i = 0; i < *rsize - 15; i++) {
/* offset to the count from 0x5a report part always 14 */
if (rdesc[i] == 0x85 && rdesc[i + 1] == 0x5a &&
rdesc[i + 14] == 0x95 && rdesc[i + 15] == 0x05) {
Expand Down
1 change: 0 additions & 1 deletion drivers/hid/hid-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1448,7 +1448,6 @@ static void implement(const struct hid_device *hid, u8 *report,
hid_warn(hid,
"%s() called with too large value %d (n: %d)! (%s)\n",
__func__, value, n, current->comm);
WARN_ON(1);
value &= m;
}
}
Expand Down
2 changes: 2 additions & 0 deletions drivers/hid/hid-debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -3366,6 +3366,8 @@ static const char *keys[KEY_MAX + 1] = {
[KEY_CAMERA_ACCESS_ENABLE] = "CameraAccessEnable",
[KEY_CAMERA_ACCESS_DISABLE] = "CameraAccessDisable",
[KEY_CAMERA_ACCESS_TOGGLE] = "CameraAccessToggle",
[KEY_ACCESSIBILITY] = "Accessibility",
[KEY_DO_NOT_DISTURB] = "DoNotDisturb",
[KEY_DICTATE] = "Dictate",
[KEY_MICMUTE] = "MicrophoneMute",
[KEY_BRIGHTNESS_MIN] = "BrightnessMin",
Expand Down
2 changes: 2 additions & 0 deletions drivers/hid/hid-ids.h
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,8 @@
#define I2C_DEVICE_ID_HP_SPECTRE_X360_13_AW0020NG 0x29DF
#define I2C_DEVICE_ID_ASUS_TP420IA_TOUCHSCREEN 0x2BC8
#define I2C_DEVICE_ID_ASUS_GV301RA_TOUCHSCREEN 0x2C82
#define I2C_DEVICE_ID_ASUS_UX3402_TOUCHSCREEN 0x2F2C
#define I2C_DEVICE_ID_ASUS_UX6404_TOUCHSCREEN 0x4116
#define USB_DEVICE_ID_ASUS_UX550VE_TOUCHSCREEN 0x2544
#define USB_DEVICE_ID_ASUS_UX550_TOUCHSCREEN 0x2706
#define I2C_DEVICE_ID_SURFACE_GO_TOUCHSCREEN 0x261A
Expand Down
13 changes: 13 additions & 0 deletions drivers/hid/hid-input.c
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,10 @@ static const struct hid_device_id hid_battery_quirks[] = {
HID_BATTERY_QUIRK_IGNORE },
{ HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_ASUS_GV301RA_TOUCHSCREEN),
HID_BATTERY_QUIRK_IGNORE },
{ HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_ASUS_UX3402_TOUCHSCREEN),
HID_BATTERY_QUIRK_IGNORE },
{ HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_ASUS_UX6404_TOUCHSCREEN),
HID_BATTERY_QUIRK_IGNORE },
{ HID_USB_DEVICE(USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ASUS_UX550_TOUCHSCREEN),
HID_BATTERY_QUIRK_IGNORE },
{ HID_USB_DEVICE(USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ASUS_UX550VE_TOUCHSCREEN),
Expand Down Expand Up @@ -833,9 +837,18 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel
break;
}

if ((usage->hid & 0xf0) == 0x90) { /* SystemControl*/
switch (usage->hid & 0xf) {
case 0xb: map_key_clear(KEY_DO_NOT_DISTURB); break;
default: goto ignore;
}
break;
}

if ((usage->hid & 0xf0) == 0xa0) { /* SystemControl */
switch (usage->hid & 0xf) {
case 0x9: map_key_clear(KEY_MICMUTE); break;
case 0xa: map_key_clear(KEY_ACCESSIBILITY); break;
default: goto ignore;
}
break;
Expand Down
4 changes: 3 additions & 1 deletion drivers/hid/hid-logitech-dj.c
Original file line number Diff line number Diff line change
Expand Up @@ -1284,8 +1284,10 @@ static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev,
*/
msleep(50);

if (retval)
if (retval) {
kfree(dj_report);
return retval;
}
}

/*
Expand Down
1 change: 1 addition & 0 deletions drivers/hid/hid-logitech-hidpp.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "usbhid/usbhid.h"
#include "hid-ids.h"

MODULE_DESCRIPTION("Support for Logitech devices relying on the HID++ specification");
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Benjamin Tissoires <[email protected]>");
MODULE_AUTHOR("Nestor Lopez Casado <[email protected]>");
Expand Down
6 changes: 4 additions & 2 deletions drivers/hid/hid-nintendo.c
Original file line number Diff line number Diff line change
Expand Up @@ -2725,20 +2725,22 @@ static int nintendo_hid_probe(struct hid_device *hdev,
ret = joycon_power_supply_create(ctlr);
if (ret) {
hid_err(hdev, "Failed to create power_supply; ret=%d\n", ret);
goto err_close;
goto err_ida;
}

ret = joycon_input_create(ctlr);
if (ret) {
hid_err(hdev, "Failed to create input device; ret=%d\n", ret);
goto err_close;
goto err_ida;
}

ctlr->ctlr_state = JOYCON_CTLR_STATE_READ;

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

err_ida:
ida_free(&nintendo_player_id_allocator, ctlr->player_id);
err_close:
hid_hw_close(hdev);
err_stop:
Expand Down
4 changes: 3 additions & 1 deletion drivers/hid/hid-nvidia-shield.c
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,9 @@ static struct input_dev *shield_haptics_create(
return haptics;

input_set_capability(haptics, EV_FF, FF_RUMBLE);
input_ff_create_memless(haptics, NULL, play_effect);
ret = input_ff_create_memless(haptics, NULL, play_effect);
if (ret)
goto err;

ret = input_register_device(haptics);
if (ret)
Expand Down
59 changes: 47 additions & 12 deletions drivers/hid/i2c-hid/i2c-hid-of-elan.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ struct i2c_hid_of_elan {
struct regulator *vcc33;
struct regulator *vccio;
struct gpio_desc *reset_gpio;
bool no_reset_on_power_off;
const struct elan_i2c_hid_chip_data *chip_data;
};

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

gpiod_set_value_cansleep(ihid_elan->reset_gpio, 1);

if (ihid_elan->vcc33) {
ret = regulator_enable(ihid_elan->vcc33);
if (ret)
return ret;
goto err_deassert_reset;
}

ret = regulator_enable(ihid_elan->vccio);
if (ret) {
regulator_disable(ihid_elan->vcc33);
return ret;
}
if (ret)
goto err_disable_vcc33;

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

return 0;

err_disable_vcc33:
if (ihid_elan->vcc33)
regulator_disable(ihid_elan->vcc33);
err_deassert_reset:
if (ihid_elan->no_reset_on_power_off)
gpiod_set_value_cansleep(ihid_elan->reset_gpio, 0);

return ret;
}

static void elan_i2c_hid_power_down(struct i2chid_ops *ops)
{
struct i2c_hid_of_elan *ihid_elan =
container_of(ops, struct i2c_hid_of_elan, ops);

gpiod_set_value_cansleep(ihid_elan->reset_gpio, 1);
/*
* Do not assert reset when the hardware allows for it to remain
* deasserted regardless of the state of the (shared) power supply to
* avoid wasting power when the supply is left on.
*/
if (!ihid_elan->no_reset_on_power_off)
gpiod_set_value_cansleep(ihid_elan->reset_gpio, 1);

if (ihid_elan->chip_data->post_gpio_reset_off_delay_ms)
msleep(ihid_elan->chip_data->post_gpio_reset_off_delay_ms);

Expand All @@ -79,6 +96,7 @@ static void elan_i2c_hid_power_down(struct i2chid_ops *ops)
static int i2c_hid_of_elan_probe(struct i2c_client *client)
{
struct i2c_hid_of_elan *ihid_elan;
int ret;

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

ihid_elan->no_reset_on_power_off = of_property_read_bool(client->dev.of_node,
"no-reset-on-power-off");

ihid_elan->vccio = devm_regulator_get(&client->dev, "vccio");
if (IS_ERR(ihid_elan->vccio))
return PTR_ERR(ihid_elan->vccio);
if (IS_ERR(ihid_elan->vccio)) {
ret = PTR_ERR(ihid_elan->vccio);
goto err_deassert_reset;
}

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

if (ihid_elan->chip_data->main_supply_name) {
ihid_elan->vcc33 = devm_regulator_get(&client->dev,
ihid_elan->chip_data->main_supply_name);
if (IS_ERR(ihid_elan->vcc33))
return PTR_ERR(ihid_elan->vcc33);
if (IS_ERR(ihid_elan->vcc33)) {
ret = PTR_ERR(ihid_elan->vcc33);
goto err_deassert_reset;
}
}

return i2c_hid_core_probe(client, &ihid_elan->ops,
ihid_elan->chip_data->hid_descriptor_address, 0);
ret = i2c_hid_core_probe(client, &ihid_elan->ops,
ihid_elan->chip_data->hid_descriptor_address, 0);
if (ret)
goto err_deassert_reset;

return 0;

err_deassert_reset:
if (ihid_elan->no_reset_on_power_off)
gpiod_set_value_cansleep(ihid_elan->reset_gpio, 0);

return ret;
}

static const struct elan_i2c_hid_chip_data elan_ekth6915_chip_data = {
Expand Down
Loading

0 comments on commit 061d1af

Please sign in to comment.