* [PATCH] HID: elecom: Add support for ELECOM HUGE Plus M-HT1MRBK
From: David Phillips via B4 Relay @ 2026-01-23 3:56 UTC (permalink / raw)
To: Jiri Kosina, Benjamin Tissoires; +Cc: linux-input, linux-kernel, David Phillips
From: David Phillips <david@profile.sh>
New model in the ELECOM HUGE trackball line that has 8 buttons but the
report descriptor specifies only 5. The HUGE Plus supports connecting via
Bluetooth, 2.4GHz wireless USB dongle, and directly via a USB-C cable.
Each connection type reports a different device id, 01AA for cable,
01AB for USB dongle, and 01AC for Bluetooth.
This patch adds these device IDs and applies the fixups similar to the
other ELECOM devices to get all 8 buttons working for all 3 connection
types.
For reference, the usbhid-dump output:
001:013:001:DESCRIPTOR 1769085639.598405
05 01 09 02 A1 01 85 01 09 01 A1 00 05 09 19 01
29 05 15 00 25 01 75 01 95 05 81 02 75 03 95 01
81 01 05 01 09 30 09 31 16 01 80 26 FF 7F 75 10
95 02 81 06 09 38 15 81 25 7F 75 08 95 01 81 06
05 0C 0A 38 02 15 81 25 7F 75 08 95 01 81 06 C0
C0 05 0C 09 01 A1 01 85 02 15 01 26 8C 02 19 01
2A 8C 02 75 10 95 01 81 00 C0 05 01 09 80 A1 01
85 03 09 82 09 81 09 83 15 00 25 01 19 01 29 03
75 01 95 03 81 02 95 05 81 01 C0 06 01 FF 09 00
A1 01 85 08 09 00 15 00 26 FF 00 75 08 95 07 81
02 C0 06 02 FF 09 02 A1 01 85 06 09 02 15 00 26
FF 00 75 08 95 07 B1 02 C0
Signed-off-by: David Phillips <david@profile.sh>
---
drivers/hid/Kconfig | 1 +
drivers/hid/hid-elecom.c | 16 ++++++++++++++++
drivers/hid/hid-ids.h | 3 +++
drivers/hid/hid-quirks.c | 3 +++
4 files changed, 23 insertions(+)
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index 920a64b66b25..6ff4a3ad34cb 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -369,6 +369,7 @@ config HID_ELECOM
- EX-G Trackballs (M-XT3DRBK, M-XT3URBK)
- DEFT Trackballs (M-DT1DRBK, M-DT1URBK, M-DT2DRBK, M-DT2URBK)
- HUGE Trackballs (M-HT1DRBK, M-HT1URBK)
+ - HUGE Plus Trackball (M-HT1MRBK)
config HID_ELO
tristate "ELO USB 4000/4500 touchscreen"
diff --git a/drivers/hid/hid-elecom.c b/drivers/hid/hid-elecom.c
index 2003d2dcda7c..37d88ce57f67 100644
--- a/drivers/hid/hid-elecom.c
+++ b/drivers/hid/hid-elecom.c
@@ -5,6 +5,7 @@
* - EX-G Trackballs (M-XT3DRBK, M-XT3URBK, M-XT4DRBK)
* - DEFT Trackballs (M-DT1DRBK, M-DT1URBK, M-DT2DRBK, M-DT2URBK)
* - HUGE Trackballs (M-HT1DRBK, M-HT1URBK)
+ * - HUGE Plus Trackball (M-HT1MRBK)
*
* Copyright (c) 2010 Richard Nauber <Richard.Nauber@gmail.com>
* Copyright (c) 2016 Yuxuan Shui <yshuiv7@gmail.com>
@@ -123,12 +124,25 @@ static const __u8 *elecom_report_fixup(struct hid_device *hdev, __u8 *rdesc,
*/
mouse_button_fixup(hdev, rdesc, *rsize, 22, 30, 24, 16, 8);
break;
+ case USB_DEVICE_ID_ELECOM_M_HT1MRBK:
+ case USB_DEVICE_ID_ELECOM_M_HT1MRBK_01AB:
+ case USB_DEVICE_ID_ELECOM_M_HT1MRBK_01AC:
+ /*
+ * Report descriptor format:
+ * 24: button bit count
+ * 28: padding bit count
+ * 22: button report size
+ * 16: button usage maximum
+ */
+ mouse_button_fixup(hdev, rdesc, *rsize, 24, 28, 22, 16, 8);
+ break;
}
return rdesc;
}
static const struct hid_device_id elecom_devices[] = {
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) },
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1MRBK_01AC) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XGL20DLBK) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3URBK_00FB) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3URBK_018F) },
@@ -142,6 +156,8 @@ static const struct hid_device_id elecom_devices[] = {
{ 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_011C) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1MRBK) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1MRBK_01AB) },
{ }
};
MODULE_DEVICE_TABLE(hid, elecom_devices);
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 9c2bf584d9f6..c9b07890a808 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -465,6 +465,9 @@
#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_011C 0x011c
+#define USB_DEVICE_ID_ELECOM_M_HT1MRBK 0x01aa
+#define USB_DEVICE_ID_ELECOM_M_HT1MRBK_01AB 0x01ab
+#define USB_DEVICE_ID_ELECOM_M_HT1MRBK_01AC 0x01ac
#define USB_VENDOR_ID_DREAM_CHEEKY 0x1d34
#define USB_DEVICE_ID_DREAM_CHEEKY_WN 0x0004
diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c
index 11438039cdb7..3217e436c052 100644
--- a/drivers/hid/hid-quirks.c
+++ b/drivers/hid/hid-quirks.c
@@ -420,6 +420,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
#if IS_ENABLED(CONFIG_HID_ELECOM)
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XGL20DLBK) },
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1MRBK_01AC) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3URBK_00FB) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3URBK_018F) },
{ HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_XT3DRBK_00FC) },
@@ -432,6 +433,8 @@ static const struct hid_device_id hid_have_special_driver[] = {
{ 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_011C) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1MRBK) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_M_HT1MRBK_01AB) },
#endif
#if IS_ENABLED(CONFIG_HID_ELO)
{ HID_USB_DEVICE(USB_VENDOR_ID_ELO, 0x0009) },
---
base-commit: 79b95d74470dd97d7d0908d5a3c0734a23e51aa4
change-id: 20260123-hid-elecom-huge-plus-fix-545cf029fd1a
Best regards,
--
David Phillips <david@profile.sh>
^ permalink raw reply related
* Re: [PATCH v12 07/11] platform/x86: asus-wmi: Add support for multiple kbd led handlers
From: Denis Benato @ 2026-01-23 0:20 UTC (permalink / raw)
To: Antheas Kapenekakis, platform-driver-x86, linux-input
Cc: linux-kernel, Jiri Kosina, Benjamin Tissoires, Corentin Chary,
Luke D . Jones, Hans de Goede, Ilpo Järvinen
In-Reply-To: <20260122075044.5070-8-lkml@antheas.dev>
On 1/22/26 08:50, Antheas Kapenekakis wrote:
> Some devices, such as the Z13 have multiple Aura devices connected
> to them by USB. In addition, they might have a WMI interface for
> RGB. In Windows, Armoury Crate exposes a unified brightness slider
> for all of them, with 3 brightness levels.
>
> Therefore, to be synergistic in Linux, and support existing tooling
> such as UPower, allow adding listeners to the RGB device of the WMI
> interface. If WMI does not exist, lazy initialize the interface.
>
> Since hid-asus and asus-wmi can both interact with the led objects
> including from an atomic context, protect the brightness access with a
> spinlock and update the values from a workqueue. Use this workqueue to
> also process WMI keyboard events, so they are handled asynchronously.
Reviewed-by: Denis Benato <benato.denis96@gmail.com>
> Acked-by: Benjamin Tissoires <bentiss@kernel.org>
> Signed-off-by: Antheas Kapenekakis <lkml@antheas.dev>
> ---
> drivers/platform/x86/asus-wmi.c | 183 ++++++++++++++++++---
> include/linux/platform_data/x86/asus-wmi.h | 15 ++
> 2 files changed, 173 insertions(+), 25 deletions(-)
>
> diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
> index 4aec7ec69250..c45846be3f99 100644
> --- a/drivers/platform/x86/asus-wmi.c
> +++ b/drivers/platform/x86/asus-wmi.c
> @@ -31,13 +31,13 @@
> #include <linux/pci.h>
> #include <linux/pci_hotplug.h>
> #include <linux/platform_data/x86/asus-wmi.h>
> -#include <linux/platform_data/x86/asus-wmi-leds-ids.h>
> #include <linux/platform_device.h>
> #include <linux/platform_profile.h>
> #include <linux/power_supply.h>
> #include <linux/rfkill.h>
> #include <linux/seq_file.h>
> #include <linux/slab.h>
> +#include <linux/spinlock.h>
> #include <linux/types.h>
> #include <linux/units.h>
>
> @@ -256,6 +256,9 @@ struct asus_wmi {
> int tpd_led_wk;
> struct led_classdev kbd_led;
> int kbd_led_wk;
> + bool kbd_led_notify;
> + bool kbd_led_avail;
> + bool kbd_led_registered;
> struct led_classdev lightbar_led;
> int lightbar_led_wk;
> struct led_classdev micmute_led;
> @@ -264,6 +267,7 @@ struct asus_wmi {
> struct work_struct tpd_led_work;
> struct work_struct wlan_led_work;
> struct work_struct lightbar_led_work;
> + struct work_struct kbd_led_work;
>
> struct asus_rfkill wlan;
> struct asus_rfkill bluetooth;
> @@ -1615,6 +1619,106 @@ static void asus_wmi_battery_exit(struct asus_wmi *asus)
>
> /* LEDs ***********************************************************************/
>
> +struct asus_hid_ref {
> + struct list_head listeners;
> + struct asus_wmi *asus;
> + /* Protects concurrent access from hid-asus and asus-wmi to leds */
> + spinlock_t lock;
> +};
> +
> +static struct asus_hid_ref asus_ref = {
> + .listeners = LIST_HEAD_INIT(asus_ref.listeners),
> + .asus = NULL,
> + /*
> + * Protects .asus, .asus.kbd_led_{wk,notify}, and .listener refs. Other
> + * asus variables are read-only after .asus is set.
> + *
> + * The led cdev device is not protected because it calls backlight_get
> + * during initialization, which would result in a nested lock attempt.
> + *
> + * The led cdev is safe to access without a lock because if
> + * kbd_led_avail is true it is initialized before .asus is set and never
> + * changed until .asus is dropped. If kbd_led_avail is false, the led
> + * cdev is registered by the workqueue, which is single-threaded and
> + * cancelled before asus-wmi would access the led cdev to unregister it.
> + *
> + * A spinlock is used, because the protected variables can be accessed
> + * from an IRQ context from asus-hid.
> + */
> + .lock = __SPIN_LOCK_UNLOCKED(asus_ref.lock),
> +};
> +
> +/*
> + * Allows registering hid-asus listeners that want to be notified of
> + * keyboard backlight changes.
> + */
> +int asus_hid_register_listener(struct asus_hid_listener *bdev)
> +{
> + struct asus_wmi *asus;
> +
> + guard(spinlock_irqsave)(&asus_ref.lock);
> + list_add_tail(&bdev->list, &asus_ref.listeners);
> + asus = asus_ref.asus;
> + if (asus)
> + queue_work(asus->led_workqueue, &asus->kbd_led_work);
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(asus_hid_register_listener);
> +
> +/*
> + * Allows unregistering hid-asus listeners that were added with
> + * asus_hid_register_listener().
> + */
> +void asus_hid_unregister_listener(struct asus_hid_listener *bdev)
> +{
> + guard(spinlock_irqsave)(&asus_ref.lock);
> + list_del(&bdev->list);
> +}
> +EXPORT_SYMBOL_GPL(asus_hid_unregister_listener);
> +
> +static void do_kbd_led_set(struct led_classdev *led_cdev, int value);
> +
> +static void kbd_led_update_all(struct work_struct *work)
> +{
> + struct asus_wmi *asus;
> + bool registered, notify;
> + int ret, value;
> +
> + asus = container_of(work, struct asus_wmi, kbd_led_work);
> +
> + scoped_guard(spinlock_irqsave, &asus_ref.lock) {
> + registered = asus->kbd_led_registered;
> + value = asus->kbd_led_wk;
> + notify = asus->kbd_led_notify;
> + }
> +
> + if (!registered) {
> + /*
> + * This workqueue runs under asus-wmi, which means probe has
> + * completed and asus-wmi will keep running until it finishes.
> + * Therefore, we can safely register the LED without holding
> + * a spinlock.
> + */
> + ret = devm_led_classdev_register(&asus->platform_device->dev,
> + &asus->kbd_led);
> + if (!ret) {
> + scoped_guard(spinlock_irqsave, &asus_ref.lock)
> + asus->kbd_led_registered = true;
> + } else {
> + pr_warn("Failed to register keyboard backlight LED: %d\n", ret);
> + return;
> + }
> + }
> +
> + if (value >= 0)
> + do_kbd_led_set(&asus->kbd_led, value);
> + if (notify) {
> + scoped_guard(spinlock_irqsave, &asus_ref.lock)
> + asus->kbd_led_notify = false;
> + led_classdev_notify_brightness_hw_changed(&asus->kbd_led, value);
> + }
> +}
> +
> /*
> * These functions actually update the LED's, and are called from a
> * workqueue. By doing this as separate work rather than when the LED
> @@ -1661,7 +1765,8 @@ static void kbd_led_update(struct asus_wmi *asus)
> {
> int ctrl_param = 0;
>
> - ctrl_param = 0x80 | (asus->kbd_led_wk & 0x7F);
> + scoped_guard(spinlock_irqsave, &asus_ref.lock)
> + ctrl_param = 0x80 | (asus->kbd_led_wk & 0x7F);
> asus_wmi_set_devstate(ASUS_WMI_DEVID_KBD_BACKLIGHT, ctrl_param, NULL);
> }
>
> @@ -1694,14 +1799,23 @@ static int kbd_led_read(struct asus_wmi *asus, int *level, int *env)
>
> static void do_kbd_led_set(struct led_classdev *led_cdev, int value)
> {
> + struct asus_hid_listener *listener;
> struct asus_wmi *asus;
> int max_level;
>
> asus = container_of(led_cdev, struct asus_wmi, kbd_led);
> max_level = asus->kbd_led.max_brightness;
>
> - asus->kbd_led_wk = clamp_val(value, 0, max_level);
> - kbd_led_update(asus);
> + scoped_guard(spinlock_irqsave, &asus_ref.lock)
> + asus->kbd_led_wk = clamp_val(value, 0, max_level);
> +
> + if (asus->kbd_led_avail)
> + kbd_led_update(asus);
> +
> + scoped_guard(spinlock_irqsave, &asus_ref.lock) {
> + list_for_each_entry(listener, &asus_ref.listeners, list)
> + listener->brightness_set(listener, asus->kbd_led_wk);
> + }
> }
>
> static int kbd_led_set(struct led_classdev *led_cdev, enum led_brightness value)
> @@ -1716,10 +1830,11 @@ static int kbd_led_set(struct led_classdev *led_cdev, enum led_brightness value)
>
> static void kbd_led_set_by_kbd(struct asus_wmi *asus, enum led_brightness value)
> {
> - struct led_classdev *led_cdev = &asus->kbd_led;
> -
> - do_kbd_led_set(led_cdev, value);
> - led_classdev_notify_brightness_hw_changed(led_cdev, asus->kbd_led_wk);
> + scoped_guard(spinlock_irqsave, &asus_ref.lock) {
> + asus->kbd_led_wk = value;
> + asus->kbd_led_notify = true;
> + }
> + queue_work(asus->led_workqueue, &asus->kbd_led_work);
> }
>
> static enum led_brightness kbd_led_get(struct led_classdev *led_cdev)
> @@ -1729,10 +1844,18 @@ static enum led_brightness kbd_led_get(struct led_classdev *led_cdev)
>
> asus = container_of(led_cdev, struct asus_wmi, kbd_led);
>
> + scoped_guard(spinlock_irqsave, &asus_ref.lock) {
> + if (!asus->kbd_led_avail)
> + return asus->kbd_led_wk;
> + }
> +
> retval = kbd_led_read(asus, &value, NULL);
> if (retval < 0)
> return retval;
>
> + scoped_guard(spinlock_irqsave, &asus_ref.lock)
> + asus->kbd_led_wk = value;
> +
> return value;
> }
>
> @@ -1844,7 +1967,9 @@ static int camera_led_set(struct led_classdev *led_cdev,
>
> static void asus_wmi_led_exit(struct asus_wmi *asus)
> {
> - led_classdev_unregister(&asus->kbd_led);
> + scoped_guard(spinlock_irqsave, &asus_ref.lock)
> + asus_ref.asus = NULL;
> +
> led_classdev_unregister(&asus->tpd_led);
> led_classdev_unregister(&asus->wlan_led);
> led_classdev_unregister(&asus->lightbar_led);
> @@ -1882,22 +2007,26 @@ static int asus_wmi_led_init(struct asus_wmi *asus)
> goto error;
> }
>
> - if (!kbd_led_read(asus, &led_val, NULL) && !dmi_check_system(asus_use_hid_led_dmi_ids)) {
> - pr_info("using asus-wmi for asus::kbd_backlight\n");
> - asus->kbd_led_wk = led_val;
> - asus->kbd_led.name = "asus::kbd_backlight";
> - asus->kbd_led.flags = LED_BRIGHT_HW_CHANGED;
> - asus->kbd_led.brightness_set_blocking = kbd_led_set;
> - asus->kbd_led.brightness_get = kbd_led_get;
> - asus->kbd_led.max_brightness = 3;
> + asus->kbd_led.name = "asus::kbd_backlight";
> + asus->kbd_led.flags = LED_BRIGHT_HW_CHANGED;
> + asus->kbd_led.brightness_set_blocking = kbd_led_set;
> + asus->kbd_led.brightness_get = kbd_led_get;
> + asus->kbd_led.max_brightness = 3;
> + asus->kbd_led_avail = !kbd_led_read(asus, &led_val, NULL);
> + INIT_WORK(&asus->kbd_led_work, kbd_led_update_all);
>
> + if (asus->kbd_led_avail) {
> + asus->kbd_led_wk = led_val;
> if (num_rgb_groups != 0)
> asus->kbd_led.groups = kbd_rgb_mode_groups;
> + } else {
> + asus->kbd_led_wk = -1;
> + }
>
> - rv = led_classdev_register(&asus->platform_device->dev,
> - &asus->kbd_led);
> - if (rv)
> - goto error;
> + scoped_guard(spinlock_irqsave, &asus_ref.lock) {
> + asus_ref.asus = asus;
> + if (asus->kbd_led_avail || !list_empty(&asus_ref.listeners))
> + queue_work(asus->led_workqueue, &asus->kbd_led_work);
> }
>
> if (asus_wmi_dev_is_present(asus, ASUS_WMI_DEVID_WIRELESS_LED)
> @@ -4372,6 +4501,7 @@ static int asus_wmi_get_event_code(union acpi_object *obj)
>
> static void asus_wmi_handle_event_code(int code, struct asus_wmi *asus)
> {
> + enum led_brightness led_value;
> unsigned int key_value = 1;
> bool autorelease = 1;
>
> @@ -4388,19 +4518,22 @@ static void asus_wmi_handle_event_code(int code, struct asus_wmi *asus)
> return;
> }
>
> + scoped_guard(spinlock_irqsave, &asus_ref.lock)
> + led_value = asus->kbd_led_wk;
> +
> if (code == NOTIFY_KBD_BRTUP) {
> - kbd_led_set_by_kbd(asus, asus->kbd_led_wk + 1);
> + kbd_led_set_by_kbd(asus, led_value + 1);
> return;
> }
> if (code == NOTIFY_KBD_BRTDWN) {
> - kbd_led_set_by_kbd(asus, asus->kbd_led_wk - 1);
> + kbd_led_set_by_kbd(asus, led_value - 1);
> return;
> }
> if (code == NOTIFY_KBD_BRTTOGGLE) {
> - if (asus->kbd_led_wk == asus->kbd_led.max_brightness)
> + if (led_value >= asus->kbd_led.max_brightness)
> kbd_led_set_by_kbd(asus, 0);
> else
> - kbd_led_set_by_kbd(asus, asus->kbd_led_wk + 1);
> + kbd_led_set_by_kbd(asus, led_value + 1);
> return;
> }
>
> diff --git a/include/linux/platform_data/x86/asus-wmi.h b/include/linux/platform_data/x86/asus-wmi.h
> index 419491d4abca..d347cffd05d5 100644
> --- a/include/linux/platform_data/x86/asus-wmi.h
> +++ b/include/linux/platform_data/x86/asus-wmi.h
> @@ -172,12 +172,20 @@ enum asus_ally_mcu_hack {
> ASUS_WMI_ALLY_MCU_HACK_DISABLED,
> };
>
> +/* Used to notify hid-asus when asus-wmi changes keyboard backlight */
> +struct asus_hid_listener {
> + struct list_head list;
> + void (*brightness_set)(struct asus_hid_listener *listener, int brightness);
> +};
> +
> #if IS_REACHABLE(CONFIG_ASUS_WMI)
> void set_ally_mcu_hack(enum asus_ally_mcu_hack status);
> void set_ally_mcu_powersave(bool enabled);
> int asus_wmi_get_devstate_dsts(u32 dev_id, u32 *retval);
> int asus_wmi_set_devstate(u32 dev_id, u32 ctrl_param, u32 *retval);
> int asus_wmi_evaluate_method(u32 method_id, u32 arg0, u32 arg1, u32 *retval);
> +int asus_hid_register_listener(struct asus_hid_listener *cdev);
> +void asus_hid_unregister_listener(struct asus_hid_listener *cdev);
> #else
> static inline void set_ally_mcu_hack(enum asus_ally_mcu_hack status)
> {
> @@ -198,6 +206,13 @@ static inline int asus_wmi_evaluate_method(u32 method_id, u32 arg0, u32 arg1,
> {
> return -ENODEV;
> }
> +static inline int asus_hid_register_listener(struct asus_hid_listener *bdev)
> +{
> + return -ENODEV;
> +}
> +static inline void asus_hid_unregister_listener(struct asus_hid_listener *bdev)
> +{
> +}
> #endif
>
> #endif /* __PLATFORM_DATA_X86_ASUS_WMI_H */
^ permalink raw reply
* Re: [PATCH v12 02/11] HID: asus: initialize additional endpoints only for certain devices
From: Denis Benato @ 2026-01-23 0:18 UTC (permalink / raw)
To: Antheas Kapenekakis, platform-driver-x86, linux-input
Cc: linux-kernel, Jiri Kosina, Benjamin Tissoires, Corentin Chary,
Luke D . Jones, Hans de Goede, Ilpo Järvinen
In-Reply-To: <20260122075044.5070-3-lkml@antheas.dev>
On 1/22/26 08:50, Antheas Kapenekakis wrote:
> Currently, ID1/ID2 initializations are performed for all NKEY devices.
> However, ID1 initializations are only required for RGB control and are
> only supported for RGB capable devices. ID2 initializations are only
> required for initializing the Anime display endpoint which is only
> supported on devices with an Anime display. Both of these
> initializations are for functionality that is not present on this driver
> and are performed for devices which might not support them.
>
> At the same time, there are older NKEY devices that have only been
> tested with these initializations in the kernel and it is not possible
> to recheck them. There is a possibility that especially with the ID1
> initialization, certain laptop models might have their shortcuts stop
> working (currently unproven).
>
> To avoid sending unnecessary commands, change to only initialize ID1/ID2
> for those NKEY devices suspected to be problematic without them by
> introducing a quirk for them and replacing the NKEY quirk in the block
> that performs the inits with that. Therefore, new devices that do not
> need (and some do not support) these initializations will not have
> them performed.
>
> In addition, as these initializations might not be supported by the
> affected devices, change the function to not bail if they fail.
Reviewed-by: Denis Benato <benato.denis96@gmail.com>
> Acked-by: Benjamin Tissoires <bentiss@kernel.org>
> Signed-off-by: Antheas Kapenekakis <lkml@antheas.dev>
> ---
> drivers/hid/hid-asus.c | 16 ++++++----------
> 1 file changed, 6 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c
> index 323e6302bac5..92904b5a700c 100644
> --- a/drivers/hid/hid-asus.c
> +++ b/drivers/hid/hid-asus.c
> @@ -90,6 +90,7 @@ MODULE_DESCRIPTION("Asus HID Keyboard and TouchPad");
> #define QUIRK_ROG_NKEY_KEYBOARD BIT(11)
> #define QUIRK_ROG_CLAYMORE_II_KEYBOARD BIT(12)
> #define QUIRK_ROG_ALLY_XPAD BIT(13)
> +#define QUIRK_ROG_NKEY_ID1ID2_INIT BIT(14)
>
> #define I2C_KEYBOARD_QUIRKS (QUIRK_FIX_NOTEBOOK_REPORT | \
> QUIRK_NO_INIT_REPORTS | \
> @@ -652,14 +653,9 @@ static int asus_kbd_register_leds(struct hid_device *hdev)
> if (!(kbd_func & SUPPORT_KBD_BACKLIGHT))
> return -ENODEV;
>
> - if (drvdata->quirks & QUIRK_ROG_NKEY_KEYBOARD) {
> - ret = asus_kbd_init(hdev, FEATURE_KBD_LED_REPORT_ID1);
> - if (ret < 0)
> - return ret;
> -
> - ret = asus_kbd_init(hdev, FEATURE_KBD_LED_REPORT_ID2);
> - if (ret < 0)
> - return ret;
> + if (drvdata->quirks & QUIRK_ROG_NKEY_ID1ID2_INIT) {
> + asus_kbd_init(hdev, FEATURE_KBD_LED_REPORT_ID1);
> + asus_kbd_init(hdev, FEATURE_KBD_LED_REPORT_ID2);
> }
>
> if (dmi_match(DMI_PRODUCT_FAMILY, "ProArt P16")) {
> @@ -1376,10 +1372,10 @@ static const struct hid_device_id asus_devices[] = {
> QUIRK_USE_KBD_BACKLIGHT },
> { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
> USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD),
> - QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD },
> + QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD | QUIRK_ROG_NKEY_ID1ID2_INIT },
> { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
> USB_DEVICE_ID_ASUSTEK_ROG_NKEY_KEYBOARD2),
> - QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD },
> + QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD | QUIRK_ROG_NKEY_ID1ID2_INIT },
> { HID_USB_DEVICE(USB_VENDOR_ID_ASUSTEK,
> USB_DEVICE_ID_ASUSTEK_ROG_Z13_LIGHTBAR),
> QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD },
^ permalink raw reply
* Re: [PATCH v1 1/1] dt-bindings: input: touchscreen: tsc2007: document '#io-channel-cells'
From: Rob Herring (Arm) @ 2026-01-22 23:34 UTC (permalink / raw)
To: Svyatoslav Ryhel
Cc: Fabio Estevam, Andreas Kemnade, Krzysztof Kozlowski, Frank Li,
Dmitry Torokhov, Conor Dooley, linux-input, linux-kernel,
devicetree
In-Reply-To: <20260122193549.29858-2-clamor95@gmail.com>
On Thu, 22 Jan 2026 21:35:49 +0200, Svyatoslav Ryhel wrote:
> The tsc2007 can be used not only as resistive touchscreen controller but
> also as a ADC IIO sensor. The second use case requires '#io-channel-cells'
> property, hence add it.
>
> Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
> ---
> .../devicetree/bindings/input/touchscreen/ti,tsc2007.yaml | 3 +++
> 1 file changed, 3 insertions(+)
>
Acked-by: Rob Herring (Arm) <robh@kernel.org>
^ permalink raw reply
* Re: [PATCH 1/1] Adding support for aXiom touchscreen controller
From: Marco Felsch @ 2026-01-22 22:09 UTC (permalink / raw)
To: AThomas63
Cc: dmitry.torokhov, linux-input, linux-kernel, mark.satterthwaite,
kamel.bouhara, kernel
In-Reply-To: <20260122124819.273188-2-andrew.thomas@touchnetix.com>
The git-subject seems wrong, this should be:
"Input: Add support for ...."
also you miss a proper commit description.
On 26-01-22, AThomas63 wrote:
> Signed-off-by: AThomas63 <andrew.thomas@touchnetix.com>
> ---
> drivers/input/touchscreen/Kconfig | 30 ++
> drivers/input/touchscreen/Makefile | 3 +
> drivers/input/touchscreen/axiom_core.c | 482 +++++++++++++++++++++++++
> drivers/input/touchscreen/axiom_core.h | 128 +++++++
> drivers/input/touchscreen/axiom_i2c.c | 152 ++++++++
> drivers/input/touchscreen/axiom_spi.c | 159 ++++++++
> 6 files changed, 954 insertions(+)
> create mode 100644 drivers/input/touchscreen/axiom_core.c
> create mode 100644 drivers/input/touchscreen/axiom_core.h
> create mode 100644 drivers/input/touchscreen/axiom_i2c.c
> create mode 100644 drivers/input/touchscreen/axiom_spi.c
>
> diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
> index 7d5b72ee07fa..f2b4fb317bdd 100644
> --- a/drivers/input/touchscreen/Kconfig
> +++ b/drivers/input/touchscreen/Kconfig
> @@ -162,6 +162,36 @@ config TOUCHSCREEN_AUO_PIXCIR
> To compile this driver as a module, choose M here: the
> module will be called auo-pixcir-ts.
>
> +config TOUCHSCREEN_AXIOM_CORE
> + tristate "TouchNetix Axiom touchscreen"
Nack, the spi or i2c should select the core.
> + help
> + Say Y here if you have an Axiom touchscreen connected
> + to your system. You will also need to select appropriate
> + bus connection below.
> +
> + If unsure, say N.
> +
> + To compile this driver as a module, choose M here: the
> + module will be called axiom_core.
> +
> +config TOUCHSCREEN_AXIOM_I2C
> + tristate "support I2C bus connection"
> + depends on TOUCHSCREEN_AXIOM_CORE && I2C
> + help
> + Say Y here if the touchscreen is connected via I2C bus.
> +
> + To compile this driver as a module, choose M here: the
> + module will be called axiom_spi.
> +
> +config TOUCHSCREEN_AXIOM_SPI
> + tristate "support SPI bus connection"
> + depends on TOUCHSCREEN_AXIOM_CORE && SPI
> + help
> + Say Y here if the touchscreen is connected via SPI bus.
> +
> + To compile this driver as a module, choose M here: the
> + module will be called axiom_spi.
> +
> config TOUCHSCREEN_BU21013
> tristate "BU21013 based touch panel controllers"
> depends on I2C
> diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
> index ab9abd151078..9b7d572c4589 100644
> --- a/drivers/input/touchscreen/Makefile
> +++ b/drivers/input/touchscreen/Makefile
> @@ -19,6 +19,9 @@ obj-$(CONFIG_TOUCHSCREEN_APPLE_Z2) += apple_z2.o
> obj-$(CONFIG_TOUCHSCREEN_AR1021_I2C) += ar1021_i2c.o
> obj-$(CONFIG_TOUCHSCREEN_ATMEL_MXT) += atmel_mxt_ts.o
> obj-$(CONFIG_TOUCHSCREEN_AUO_PIXCIR) += auo-pixcir-ts.o
> +obj-$(CONFIG_TOUCHSCREEN_AXIOM_CORE) += axiom_core.o
> +obj-$(CONFIG_TOUCHSCREEN_AXIOM_I2C) += axiom_i2c.o
> +obj-$(CONFIG_TOUCHSCREEN_AXIOM_SPI) += axiom_spi.o
> obj-$(CONFIG_TOUCHSCREEN_BU21013) += bu21013_ts.o
> obj-$(CONFIG_TOUCHSCREEN_BU21029) += bu21029_ts.o
> obj-$(CONFIG_TOUCHSCREEN_CHIPONE_ICN8318) += chipone_icn8318.o
> diff --git a/drivers/input/touchscreen/axiom_core.c b/drivers/input/touchscreen/axiom_core.c
> new file mode 100644
> index 000000000000..7983effe40f7
> --- /dev/null
> +++ b/drivers/input/touchscreen/axiom_core.c
> @@ -0,0 +1,482 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * TouchNetix aXiom Touchscreen Driver
> + *
> + * Copyright (C) 2020-2026 TouchNetix Ltd.
> + *
> + * Author(s): Mark Satterthwaite <mark.satterthwaite@touchnetix.com>
> + * Pedro Torruella <pedro.torruella@touchnetix.com>
> + * Bart Prescott <bartp@baasheep.co.uk>
> + * Hannah Rossiter <hannah.rossiter@touchnetix.com>
> + * Andrew Thomas <andrew.thomas@touchnetix.com>
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License as published by the
> + * Free Software Foundation; either version 2 of the License, or (at your
> + * option) any later version.
> + *
> + */
> +
> +// #define DEBUG // Enable debug messages
remove this
> +
> +#include <linux/device.h>
> +#include <linux/input/mt.h>
> +#include <linux/crc16.h>
> +#include <linux/property.h>
> +#include <linux/interrupt.h>
> +#include <linux/unaligned.h>
> +#include "axiom_core.h"
> +
> +/* u31 device info masks */
> +#define AX_DEV_ID_MASK GENMASK(14, 0)
> +#define AX_MODE BIT(15)
> +#define AX_FW_REV_MINOR_MASK GENMASK(7, 0)
> +#define AX_FW_REV_MAJOR_MASK GENMASK(15, 8)
> +#define AX_VARIANT_MASK GENMASK(5, 0)
> +#define AX_FW_STATUS BIT(7)
> +#define AX_TCP_REV_MASK GENMASK(15, 8)
> +#define AX_BOOT_REV_MINOR_MASK GENMASK(7, 0)
> +#define AX_BOOT_REV_MAJOR_MASK GENMASK(15, 8)
> +#define AX_NUM_USAGES_MASK GENMASK(7, 0)
> +#define AX_SILICON_REV_MASK GENMASK(11, 8)
> +#define AX_RUNTIME_FW_PATCH_MASK GENMASK(15, 12)
> +
> +/* u31 usage table entry masks */
> +#define AX_U31_USAGE_NUM_MASK GENMASK(7, 0)
> +#define AX_U31_START_PAGE_MASK GENMASK(15, 8)
> +#define AX_U31_NUM_PAGES_MASK GENMASK(7, 0)
> +#define AX_U31_MAX_OFFSET_MASK GENMASK(14, 8)
> +#define AX_U31_OFFSET_TYPE_BIT BIT(15)
> +#define AX_U31_UIF_REV_MASK GENMASK(7, 0)
> +#define AX_U31_USAGE_TYPE_MASK GENMASK(15, 8)
> +
> +/* u34 report masks */
> +#define AX_U34_LEN_MASK GENMASK(6, 0)
> +#define AX_U34_OVERFLOW BIT(7)
> +#define AX_U34_USAGE_MASK GENMASK(15, 8)
> +#define AX_U34_PAYLOAD_BUFFER 2
> +
> +/* u41 report masks */
> +#define AX_U41_PRESENT_MASK GENMASK(9, 0)
> +#define U41_X_Y_OFFSET (2)
> +#define U41_COORD_SIZE (4)
> +#define U41_Z_OFFSET (42)
Align your defines.
> +
> +static const char *const fw_variants[] = { "3D", "2D", "FORCE",
> + "0D", "XL", "TOUCHPAD" };
Check your code against the kernel coding style, this applies to many
code parts, I won't list them all.
> +
> +static int axiom_set_capabilities(struct input_dev *input_dev)
> +{
> + input_dev->name = "TouchNetix aXiom Touchscreen";
> + input_dev->phys = "input/axiom_ts";
> +
> + // Single Touch
Coding style.
> + input_set_abs_params(input_dev, ABS_X, 0, 65535, 0, 0);
> + input_set_abs_params(input_dev, ABS_Y, 0, 65535, 0, 0);
> +
> + // Multi Touch
> + // Min, Max, Fuzz (expected noise in px, try 4?) and Flat
> + input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, 65535, 0, 0);
> + // Min, Max, Fuzz (expected noise in px, try 4?) and Flat
> + input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, 65535, 0, 0);
> + input_set_abs_params(input_dev, ABS_MT_TOOL_TYPE, 0, MT_TOOL_MAX, 0, 0);
> + input_set_abs_params(input_dev, ABS_MT_DISTANCE, 0, 127, 0, 0);
> + input_set_abs_params(input_dev, ABS_MT_PRESSURE, 0, 127, 0, 0);
Max values are coming from the firmware.
> +
> + input_mt_init_slots(input_dev, U41_MAX_TARGETS, INPUT_MT_DIRECT);
num-targets can be configured via firmware config IIRC, so nack.
> +
> + return 0;
> +}
> +
> +static struct u31_usage_entry *usage_find_entry(struct axiom *ax, u16 usage)
> +{
> + u16 i;
> +
> + for (i = 0; i < ax->dev_info.num_usages; i++) {
> + if (ax->usage_table[i].usage_num == usage)
> + return &ax->usage_table[i];
> + }
> +
> + pr_err("aXiom-core: Usage u%02x not found in usage table\n", usage);
> + return ERR_PTR(-EINVAL);
> +}
> +
> +static void axiom_unpack_device_info(const u8 *buf,
> + struct axiom_device_info *info)
> +{
> + u16 w;
> +
> + w = get_unaligned_le16(buf);
> + info->device_id = FIELD_GET(AX_DEV_ID_MASK, w);
> + info->mode = !!(w & AX_MODE);
> +
> + w = get_unaligned_le16(buf + 2);
> + info->runtime_fw_rev_minor = FIELD_GET(AX_FW_REV_MINOR_MASK, w);
> + info->runtime_fw_rev_major = FIELD_GET(AX_FW_REV_MAJOR_MASK, w);
> +
> + w = get_unaligned_le16(buf + 4);
> + info->device_build_variant = FIELD_GET(AX_VARIANT_MASK, w);
> + info->runtime_fw_status = !!(w & AX_FW_STATUS);
> + info->tcp_revision = FIELD_GET(AX_TCP_REV_MASK, w);
> +
> + w = get_unaligned_le16(buf + 6);
> + info->bootloader_fw_rev_minor = FIELD_GET(AX_BOOT_REV_MINOR_MASK, w);
> + info->bootloader_fw_rev_major = FIELD_GET(AX_BOOT_REV_MAJOR_MASK, w);
> +
> + info->jedec_id = get_unaligned_le16(buf + 8);
> +
> + w = get_unaligned_le16(buf + 10);
> + info->num_usages = FIELD_GET(AX_NUM_USAGES_MASK, w);
> + info->silicon_revision = FIELD_GET(AX_SILICON_REV_MASK, w);
> + info->runtime_fw_rev_patch = FIELD_GET(AX_RUNTIME_FW_PATCH_MASK, w);
> +}
> +
> +static void axiom_unpack_usage_table(u8 *buf, struct axiom *ax)
> +{
> + u8 *ptr;
> + struct u31_usage_entry *entry;
> + int i;
> + u16 w;
> + u16 report_len;
> +
> + for (i = 0; i < ax->dev_info.num_usages && i < U31_MAX_USAGES; i++) {
> + entry = &ax->usage_table[i];
> + /* Calculate offset for this specific entry */
> + ptr = buf + (i * SIZE_U31_USAGE_ENTRY);
> +
> + w = get_unaligned_le16(ptr);
> + entry->usage_num = FIELD_GET(AX_U31_USAGE_NUM_MASK, w);
> + entry->start_page = FIELD_GET(AX_U31_START_PAGE_MASK, w);
> +
> + w = get_unaligned_le16(ptr + 2);
> + entry->num_pages = FIELD_GET(AX_U31_NUM_PAGES_MASK, w);
> + entry->max_offset = FIELD_GET(AX_U31_MAX_OFFSET_MASK, w);
> + entry->offset_type = !!(w & AX_U31_OFFSET_TYPE_BIT);
> +
> + w = get_unaligned_le16(ptr + 4);
> + entry->uifrevision = FIELD_GET(AX_U31_UIF_REV_MASK, w);
> + entry->usage_type = FIELD_GET(AX_U31_USAGE_TYPE_MASK, w);
> +
> + // Convert words to bytes
> + report_len = (entry->max_offset + 1) * 2;
> + if ((entry->usage_type == REPORT) &&
> + (report_len > ax->max_report_len)) {
> + ax->max_report_len = report_len;
> + }
> + }
> +}
> +
> +static int axiom_init_dev_info(struct axiom *ax)
> +{
> + int i;
> + struct u31_usage_entry *u;
> + int err;
> + const char *variant_str;
> +
> + /* Read page 0 of u31 */
> + err = ax->bus_ops->read(ax->dev, 0x0, SIZE_U31_DEVICE_INFO,
> + ax->read_buf);
No need for custom accessors, use regmap API.
> + if (err)
> + return -EIO;
> +
> + axiom_unpack_device_info(ax->read_buf, &ax->dev_info);
> +
> + if (ax->dev_info.device_build_variant < ARRAY_SIZE(fw_variants)) {
> + variant_str = fw_variants[ax->dev_info.device_build_variant];
> + } else {
> + variant_str = "UNKNOWN";
> + }
> + char silicon_rev = (char)(0x41 + ax->dev_info.silicon_revision);
> +
> + dev_info(ax->dev, "Firmware Info:\n");
> + dev_info(ax->dev, " BL Mode : %u\n", ax->dev_info.mode);
> + dev_info(ax->dev, " Device ID : %04x\n", ax->dev_info.device_id);
> + dev_info(ax->dev, " FW Revision : %u.%u.%u-%s %s\n",
> + ax->dev_info.runtime_fw_rev_major,
> + ax->dev_info.runtime_fw_rev_minor,
> + ax->dev_info.runtime_fw_rev_patch,
> + (ax->dev_info.runtime_fw_status == 0) ? "eng" : "prod",
> + variant_str);
> + dev_info(ax->dev, " BL Revision : %02x.%02x\n",
> + ax->dev_info.bootloader_fw_rev_major,
> + ax->dev_info.bootloader_fw_rev_minor);
> + dev_info(ax->dev, " Silicon : 0x%04X (Rev %c)\n",
> + ax->dev_info.jedec_id, silicon_rev);
> + dev_info(ax->dev, " Num Usages : %u\n", ax->dev_info.num_usages);
Why always dev_info()?
> +
> + if (ax->dev_info.num_usages > U31_MAX_USAGES) {
> + dev_err(ax->dev,
> + "Num usages (%u) exceeds maximum supported (%u)\n",
> + ax->dev_info.num_usages, U31_MAX_USAGES);
> + return -EINVAL;
> + }
> +
> + /* Read the second page of u31 to get the usage table */
> + err = ax->bus_ops->read(ax->dev, 0x100,
> + sizeof(ax->usage_table[0]) *
> + ax->dev_info.num_usages,
> + ax->read_buf);
You don't check if the device is bootloader-mode so this may fail
depending on the device state.
> + if (err)
> + return -EIO;
> +
> + axiom_unpack_usage_table(ax->read_buf, ax);
> +
> + dev_info(ax->dev, "Usage Table:\n");
> + for (i = 0; i < ax->dev_info.num_usages; i++) {
> + u = &ax->usage_table[i];
> +
> + dev_info(
> + ax->dev,
> + " Usage: u%02x Rev: %3u Page: 0x%02x00 Num Pages: %3u\n",
> + u->usage_num, u->uifrevision, u->start_page,
> + u->num_pages);
> + }
> + dev_info(ax->dev, "Max Report Length: %u\n", ax->max_report_len);
> +
> + if (ax->max_report_len > AXIOM_MAX_READ_SIZE) {
> + dev_err(ax->dev,
> + "aXiom maximum report length (%u) greater than allocated buffer size (%u).",
> + ax->max_report_len, AXIOM_MAX_READ_SIZE);
> + return -EINVAL;
> + }
> +
> + /* Set u34 address to allow direct access to report reading address */
> + u = usage_find_entry(ax, 0x34);
> + if (IS_ERR(u))
> + return PTR_ERR(u);
> + ax->u34_address = u->start_page << 8;
> +
> + return 0;
> +}
> +
> +static int axiom_process_u41_report(struct axiom *ax, u8 *report)
> +{
> + int i;
> + u16 target_present;
> + bool active;
> + u8 offset;
> + enum u41_target_state_e state;
> + u16 x;
> + u16 y;
> + s8 z;
> +
> + target_present =
> + FIELD_GET(AX_U41_PRESENT_MASK, get_unaligned_le16(&report[0]));
> +
> + for (i = 0; i < U41_MAX_TARGETS; i++) {
> + active = !!((target_present >> i) & 1);
> +
> + offset = U41_X_Y_OFFSET + (i * U41_COORD_SIZE);
> + x = get_unaligned_le16(&report[offset]);
> + y = get_unaligned_le16(&report[offset + 2]);
> + z = report[U41_Z_OFFSET + i];
> +
> + if (!active)
> + state = Target_State_Not_Present;
> + else if (z >= 0)
> + state = Target_State_Touching;
> + else if ((z > U41_PROX_LEVEL) && (z < 0))
> + state = Target_State_Hover;
> + else if (z == U41_PROX_LEVEL)
> + state = Target_State_Prox;
> + else
> + state = Target_State_Not_Present;
> +
> + dev_dbg(ax->dev, "Target %d: x=%u y=%u z=%d present=%d\n", i, x,
> + y, z, active);
> +
> + switch (state) {
> + case Target_State_Not_Present:
> + case Target_State_Prox:
> +
> + input_mt_slot(ax->input, i);
> + input_mt_report_slot_inactive(ax->input);
> + break;
> +
> + case Target_State_Hover:
> + case Target_State_Touching:
> +
> + input_mt_slot(ax->input, i);
> + input_report_abs(ax->input, ABS_MT_TRACKING_ID, i);
> + input_report_abs(ax->input, ABS_MT_POSITION_X, x);
> + input_report_abs(ax->input, ABS_MT_POSITION_Y, y);
> +
> + if (state == Target_State_Touching) {
> + input_report_abs(ax->input, ABS_MT_DISTANCE, 0);
> + input_report_abs(ax->input, ABS_MT_PRESSURE, z);
> + } else { /* Hover */
> + input_report_abs(ax->input, ABS_MT_DISTANCE, -z);
> + input_report_abs(ax->input, ABS_MT_PRESSURE, 0);
> + }
> + break;
> +
> + default:
> + break;
> + }
> + }
> +
> + input_mt_sync_frame(ax->input);
> + input_sync(ax->input);
> +
> + return 0;
> +}
> +
> +static int axiom_process_report(struct axiom *ax, u8 *report)
> +{
> + int err;
> + struct u34_report_header hdr;
> + u16 crc_calc;
> + u16 crc_report;
> + u8 len;
> + u16 hdr_buf = get_unaligned_le16(&report[0]);
> +
> + dev_dbg(ax->dev, "Payload Data %*ph\n", ax->max_report_len, report);
> +
> + hdr.report_length = FIELD_GET(AX_U34_LEN_MASK, hdr_buf);
> + hdr.overflow = !!(hdr_buf & AX_U34_OVERFLOW);
> + hdr.report_usage = FIELD_GET(AX_U34_USAGE_MASK, hdr_buf);
> +
> + len = hdr.report_length << 1;
> + if (hdr.report_length == 0) {
> + dev_err(ax->dev, "Zero length report discarded.\n");
> + return -EIO;
> + }
> +
> + // Length is 16 bit words and remove the size of the CRC16 itself
> + crc_report = (report[len - 1] << 8) | (report[len - 2]);
> + crc_calc = crc16(0, report, (len - 2));
> +
> + if (crc_calc != crc_report) {
> + dev_err(ax->dev,
> + "CRC mismatch! Expected: %04X, Calculated CRC: %04X. Report discarded.\n",
> + crc_report, crc_calc);
> + return -EIO;
> + }
> +
> + switch (hdr.report_usage) {
> + case AX_2DCTS_REPORT_ID:
> + err = axiom_process_u41_report(ax,
> + &report[AX_U34_PAYLOAD_BUFFER]);
May I ask why you guys write in your programming manual, that the host
needs to check the usage-revision and you completely ignore this?
> + break;
> +
> + default:
> + break;
> + }
> +
> + return err;
> +}
> +
> +static void axiom_poll(struct input_dev *input_dev)
> +{
> + struct axiom *ax = input_get_drvdata(input_dev);
> + int err;
> +
> + /* Read touch reports from u34 */
> + err = ax->bus_ops->read(ax->dev, ax->u34_address, ax->max_report_len,
> + ax->read_buf);
> + if (err)
> + return;
> +
> + err = axiom_process_report(ax, ax->read_buf);
> + if (err)
> + dev_err(ax->dev, "Failed to process report: %d\n", err);
> +}
> +
> +static irqreturn_t axiom_irq(int irq, void *handle)
> +{
> + struct axiom *ax = handle;
> + int err;
> +
> + /* Read touch reports from u34 */
> + err = ax->bus_ops->read(ax->dev, ax->u34_address, ax->max_report_len,
> + ax->read_buf);
> + if (err)
> + goto out;
> +
> + err = axiom_process_report(ax, ax->read_buf);
> + if (err)
> + dev_err(ax->dev, "Failed to process report: %d\n", err);
> +
> +out:
> + return IRQ_HANDLED;
> +}
> +
> +struct axiom *axiom_probe(const struct axiom_bus_ops *bus_ops,
> + struct device *dev, int irq)
> +{
> + struct axiom *ax;
> + struct input_dev *input_dev;
> + int err;
> + bool poll_enable = false;
> + u8 poll_period = 0;
Reverse christmas tree, coding style.
> +
> + ax = devm_kzalloc(dev, sizeof(*ax), GFP_KERNEL);
> + if (!ax)
> + return ERR_PTR(-ENOMEM);
> +
> + input_dev = devm_input_allocate_device(dev);
> + if (!input_dev) {
> + pr_err("ERROR: aXiom-core: Failed to allocate memory for input device!\n");
> + return ERR_PTR(-ENOMEM);
> + }
> +
> + poll_enable = device_property_read_bool(dev, "axiom,poll-enable");
There is common dt-property for poll.
> +
> + device_property_read_u8(dev, "axiom,poll-period", &poll_period);
> + if (!poll_period)
> + poll_period = AX_POLLING_PERIOD_MS;
> +
> + ax->dev = dev;
> + ax->input = input_dev;
> + ax->bus_ops = bus_ops;
> + ax->irq = irq;
You allocate absolute no ext. resources like regulators or reset-gpios.
> +
> + dev_info(dev, "aXiom Probe\n");
> + if (poll_enable)
> + dev_info(dev, "Polling Period : %u\n", poll_period);
> + else
> + dev_info(dev, "Device IRQ : %u\n", ax->irq);
Useless dev_info()'s
> +
> + axiom_set_capabilities(input_dev);
Capabilities should be set after you know which firmware you're running
on, e.g. if the firmware supports 3D touchevents.
I will stop now. As said, I'm very surprised why you guys went this way
instead of just adding the SPI support to my patchset?
Your driver is missing the basics like checking the usage-revision which
is clearly written within your programming-guide. Also this driver is
missing the fw-update and cfg-update mechanism as well as basic resource
handling like ext. power-supplies.
I'd really appreciate if you guys could provide feedback to the driver
I've send so we can fix some "Downstream" comments :)
Regards,
Marco
> +
> + err = axiom_init_dev_info(ax);
> + if (err) {
> + dev_err(ax->dev, "Failed to read device info, err: %d\n", err);
> + return ERR_PTR(err);
> + }
> +
> + if (poll_enable) {
> + err = input_setup_polling(input_dev, axiom_poll);
> + if (err) {
> + dev_err(ax->dev, "could not set up polling mode, %d\n",
> + err);
> + return ERR_PTR(err);
> + }
> +
> + input_set_poll_interval(input_dev, poll_period);
> + } else {
> + err = devm_request_threaded_irq(ax->dev, ax->irq, NULL,
> + axiom_irq,
> + IRQF_TRIGGER_LOW | IRQF_ONESHOT,
> + "axiom_irq", ax);
> + if (err)
> + return ERR_PTR(err);
> + }
> +
> + err = input_register_device(input_dev);
> + if (err) {
> + dev_err(ax->dev, "Failed to register input device: %d\n", err);
> + return ERR_PTR(err);
> + }
> +
> + input_set_drvdata(input_dev, ax);
> +
> + return ax;
> +}
> +EXPORT_SYMBOL_GPL(axiom_probe);
> +
> +MODULE_AUTHOR("TouchNetix <support@touchnetix.com>");
> +MODULE_DESCRIPTION("aXiom touchscreen core logic");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS("axiom");
> +MODULE_VERSION("1.0.0");
> diff --git a/drivers/input/touchscreen/axiom_core.h b/drivers/input/touchscreen/axiom_core.h
> new file mode 100644
> index 000000000000..ca77f9038cb1
> --- /dev/null
> +++ b/drivers/input/touchscreen/axiom_core.h
> @@ -0,0 +1,128 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * TouchNetix aXiom Touchscreen Driver
> + *
> + * Copyright (C) 2020-2026 TouchNetix Ltd.
> + *
> + * Author(s): Mark Satterthwaite <mark.satterthwaite@touchnetix.com>
> + * Pedro Torruella <pedro.torruella@touchnetix.com>
> + * Bart Prescott <bartp@baasheep.co.uk>
> + * Hannah Rossiter <hannah.rossiter@touchnetix.com>
> + * Andrew Thomas <andrew.thomas@touchnetix.com>
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License as published by the
> + * Free Software Foundation; either version 2 of the License, or (at your
> + * option) any later version.
> + *
> + */
> +
> +#ifndef __AXIOM_CORE_H
> +#define __AXIOM_CORE_H
> +
> +#include <linux/input.h>
> +
> +#define AX_POLLING_PERIOD_MS (10)
> +
> +#define AXIOM_USE_TOUCHSCREEN_INTERFACE // registers the axiom device as a touch screen instead of as a mouse pointer
> +#define U46_ENABLE_RAW_FORCE_DATA // enables the raw data for up to 4 force channels to be sent to the input subsystem
> +
> +#define AXIOM_PAGE_SIZE (256)
> +// u31 has 2 pages for usage table entries. (2 * PAGE_SIZE) / U31_BYTES_PER_USAGE = 85
> +#define AXIOM_MAX_READ_SIZE (2 * AXIOM_PAGE_SIZE)
> +#define SIZE_U31_DEVICE_INFO (12)
> +#define SIZE_U31_USAGE_ENTRY (6)
> +#define U31_MAX_USAGES (85U)
> +#define U41_MAX_TARGETS (10U)
> +#define U41_PROX_LEVEL (-128)
> +#define AXIOM_HOLDOFF_DELAY_US (40)
> +
> +enum ax_comms_op_e { AX_WR_OP = 0, AX_RD_OP = 1 };
> +
> +enum report_ids_e {
> + AX_2DCTS_REPORT_ID = 0x41,
> +};
> +
> +enum axiom_mode_e {
> + AX_RUNTIME_STATE = 0,
> + AX_BOOTLOADER_STATE = 1,
> +};
> +
> +enum usage_type_e {
> + UNKNOWN = 0,
> + OTHER = 1,
> + REPORT = 2,
> + REGISTER = 3,
> + REGISTER_READ_ONLY_ = 4,
> + CDU = 5,
> + CDU_READ_ONLY_ = 6,
> +};
> +
> +struct axiom_device_info {
> + u16 device_id;
> + u8 mode;
> + u8 runtime_fw_rev_minor;
> + u8 runtime_fw_rev_major;
> + u8 device_build_variant;
> + u8 runtime_fw_status;
> + u8 tcp_revision;
> + u8 bootloader_fw_rev_minor;
> + u8 bootloader_fw_rev_major;
> + u8 jedec_id;
> + u8 num_usages;
> + u8 silicon_revision;
> + u8 runtime_fw_rev_patch;
> +};
> +
> +struct u31_usage_entry {
> + u8 usage_num;
> + u8 start_page;
> + u8 num_pages;
> + u8 max_offset;
> + u8 offset_type;
> + u8 uifrevision;
> + u8 usage_type;
> +};
> +
> +struct axiom_cmd_header {
> + u16 target_address;
> + u16 length : 15;
> + u16 rd_wr : 1;
> +};
> +
> +struct axiom_bus_ops {
> + u16 bustype;
> + int (*write)(struct device *dev, u16 addr, u16 length, void *values);
> + int (*read)(struct device *dev, u16 addr, u16 length, void *values);
> +};
> +
> +enum u41_target_state_e {
> + Target_State_Not_Present = 0,
> + Target_State_Prox = 1,
> + Target_State_Hover = 2,
> + Target_State_Touching = 3,
> +};
> +
> +struct axiom {
> + struct device *dev;
> + int irq;
> + struct input_dev *input;
> + const struct axiom_bus_ops *bus_ops;
> + struct axiom_device_info dev_info;
> + struct u31_usage_entry usage_table[U31_MAX_USAGES];
> + u16 max_report_len;
> + u16 u34_address;
> +
> + u8 read_buf[AXIOM_MAX_READ_SIZE];
> +};
> +
> +struct u34_report_header {
> + u8 report_length;
> + u8 overflow;
> + u8 report_usage;
> +};
> +
> +struct axiom *axiom_probe(const struct axiom_bus_ops *bus_ops,
> + struct device *dev, int irq);
> +
> +#endif /* __AXIOM_CORE_H */
> diff --git a/drivers/input/touchscreen/axiom_i2c.c b/drivers/input/touchscreen/axiom_i2c.c
> new file mode 100644
> index 000000000000..66071cc0f7b3
> --- /dev/null
> +++ b/drivers/input/touchscreen/axiom_i2c.c
> @@ -0,0 +1,152 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * TouchNetix aXiom Touchscreen Driver
> + *
> + * Copyright (C) 2020-2026 TouchNetix Ltd.
> + *
> + * Author(s): Bart Prescott <bartp@baasheep.co.uk>
> + * Pedro Torruella <pedro.torruella@touchnetix.com>
> + * Mark Satterthwaite <mark.satterthwaite@touchnetix.com>
> + * Hannah Rossiter <hannah.rossiter@touchnetix.com>
> + * Andrew Thomas <andrew.thomas@touchnetix.com>
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License as published by the
> + * Free Software Foundation; either version 2 of the License, or (at your
> + * option) any later version.
> + *
> + */
> +
> +// #define DEBUG // Enable debug messages
> +
> +#include <linux/i2c.h>
> +#include <linux/kernel.h>
> +#include <linux/delay.h>
> +#include <linux/module.h>
> +#include <linux/input.h>
> +#include "axiom_core.h"
> +
> +static int axiom_i2c_read_block_data(struct device *dev, u16 addr, u16 length,
> + void *values)
> +{
> + int error;
> + struct i2c_client *client = to_i2c_client(dev);
> + struct axiom_cmd_header cmd_header = { .target_address = addr,
> + .length = length,
> + .rd_wr = AX_RD_OP };
> +
> + struct i2c_msg msgs[] = {
> + {
> + .addr = client->addr,
> + .flags = 0,
> + .len = sizeof(cmd_header),
> + .buf = (u8 *)&cmd_header,
> + },
> + {
> + .addr = client->addr,
> + .flags = I2C_M_RD,
> + .len = length,
> + .buf = values,
> + },
> + };
> +
> + error = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
> + if (error < 0) {
> + dev_err(dev, "I2C transfer error: %d\n", error);
> + return error;
> + }
> +
> + udelay(AXIOM_HOLDOFF_DELAY_US);
> +
> + return error != ARRAY_SIZE(msgs) ? -EIO : 0;
> +}
> +
> +static int axiom_i2c_write_block_data(struct device *dev, u16 addr, u16 length,
> + void *values)
> +{
> + int error;
> + struct i2c_client *client = to_i2c_client(dev);
> + struct axiom_cmd_header cmd_header = { .target_address = addr,
> + .length = length,
> + .rd_wr = AX_WR_OP };
> +
> + struct i2c_msg msgs[] = {
> + {
> + .addr = client->addr,
> + .flags = 0,
> + .len = sizeof(cmd_header),
> + .buf = (u8 *)&cmd_header,
> + },
> + {
> + .addr = client->addr,
> + .flags = 0,
> + .len = length,
> + .buf = values,
> + },
> + };
> +
> + error = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
> + if (error < 0) {
> + dev_err(dev, "I2C transfer error: %d\n", error);
> + return error;
> + }
> +
> + udelay(AXIOM_HOLDOFF_DELAY_US);
> +
> + return error != ARRAY_SIZE(msgs) ? -EIO : 0;
> +}
> +
> +static const struct axiom_bus_ops axiom_i2c_bus_ops = {
> + .bustype = BUS_I2C,
> + .write = axiom_i2c_write_block_data,
> + .read = axiom_i2c_read_block_data,
> +};
> +
> +static int axiom_i2c_probe(struct i2c_client *client)
> +{
> + struct axiom *axiom;
> +
> + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
> + dev_err(&client->dev, "I2C functionality not Supported\n");
> + return -EIO;
> + }
> +
> + axiom = axiom_probe(&axiom_i2c_bus_ops, &client->dev, client->irq);
> + if (IS_ERR(axiom))
> + return dev_err_probe(&client->dev, PTR_ERR(axiom),
> + "failed to register input device\n");
> +
> + return 0;
> +}
> +
> +static const struct i2c_device_id axiom_i2c_id_table[] = {
> + { "axiom-i2c" },
> + {},
> +};
> +MODULE_DEVICE_TABLE(i2c, axiom_i2c_id_table);
> +
> +static const struct of_device_id axiom_i2c_dt_ids[] = {
> + {
> + .compatible = "tnx,axiom-i2c",
> + .data = "axiom",
> + },
> + {}
> +};
> +MODULE_DEVICE_TABLE(of, axiom_i2c_dt_ids);
> +
> +static struct i2c_driver axiom_i2c_driver = {
> + .driver = {
> + .name = "axiom_i2c",
> + .of_match_table = of_match_ptr(axiom_i2c_dt_ids),
> + },
> + .id_table = axiom_i2c_id_table,
> + .probe = axiom_i2c_probe,
> +};
> +
> +module_i2c_driver(axiom_i2c_driver);
> +
> +MODULE_AUTHOR("TouchNetix <support@touchnetix.com>");
> +MODULE_DESCRIPTION("aXiom touchscreen I2C bus driver");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS("axiom");
> +MODULE_VERSION("1.0.0");
> diff --git a/drivers/input/touchscreen/axiom_spi.c b/drivers/input/touchscreen/axiom_spi.c
> new file mode 100644
> index 000000000000..a67ad3645689
> --- /dev/null
> +++ b/drivers/input/touchscreen/axiom_spi.c
> @@ -0,0 +1,159 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * TouchNetix aXiom Touchscreen Driver
> + *
> + * Copyright (C) 2018-2023 TouchNetix Ltd.
> + *
> + * Author(s): Mark Satterthwaite <mark.satterthwaite@touchnetix.com>
> + * Bart Prescott <bartp@baasheep.co.uk>
> + * Hannah Rossiter <hannah.rossiter@touchnetix.com>
> + * Andrew Thomas <andrew.thomas@touchnetix.com>
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License as published by the
> + * Free Software Foundation; either version 2 of the License, or (at your
> + * option) any later version.
> + *
> + */
> +
> +// #define DEBUG // Enable debug messages
> +
> +#include <linux/of.h>
> +#include <linux/kernel.h>
> +#include <linux/delay.h>
> +#include <linux/module.h>
> +#include <linux/spi/spi.h>
> +#include <linux/input.h>
> +#include "axiom_core.h"
> +
> +#define SPI_PADDING_LEN 32
> +
> +static int axiom_spi_transfer(struct device *dev, enum ax_comms_op_e op,
> + u16 addr, u16 length, void *values)
> +{
> + int ret;
> + struct spi_device *spi = to_spi_device(dev);
> + struct spi_transfer xfr_header;
> + struct spi_transfer xfr_padding;
> + struct spi_transfer xfr_payload;
> + struct spi_message msg;
> + struct axiom_cmd_header cmd_header = { .target_address = addr,
> + .length = length,
> + .rd_wr = op };
> + u8 pad_buf[SPI_PADDING_LEN] = { 0 };
> +
> + memset(&xfr_header, 0, sizeof(xfr_header));
> + memset(&xfr_padding, 0, sizeof(xfr_padding));
> + memset(&xfr_payload, 0, sizeof(xfr_payload));
> +
> + /* Setup the SPI transfer operations */
> + xfr_header.tx_buf = &cmd_header;
> + xfr_header.len = sizeof(cmd_header);
> +
> + xfr_padding.tx_buf = pad_buf;
> + xfr_padding.len = sizeof(pad_buf);
> +
> + switch (op) {
> + case AX_WR_OP:
> + xfr_payload.tx_buf = values;
> + break;
> + case AX_RD_OP:
> + xfr_payload.rx_buf = values;
> + break;
> + default:
> + dev_err(dev, "%s: invalid operation: %d\n", __func__, op);
> + return -EINVAL;
> + }
> + xfr_payload.len = length;
> +
> + spi_message_init(&msg);
> + spi_message_add_tail(&xfr_header, &msg);
> + spi_message_add_tail(&xfr_padding, &msg);
> + spi_message_add_tail(&xfr_payload, &msg);
> +
> + ret = spi_sync(spi, &msg);
> + if (ret < 0) {
> + dev_err(&spi->dev, "Failed to SPI transfer, error: %d\n", ret);
> + return ret;
> + }
> +
> + udelay(AXIOM_HOLDOFF_DELAY_US);
> +
> + return 0;
> +}
> +
> +static int axiom_spi_read_block_data(struct device *dev, u16 addr, u16 length,
> + void *values)
> +{
> + return axiom_spi_transfer(dev, AX_RD_OP, addr, length, values);
> +}
> +
> +static int axiom_spi_write_block_data(struct device *dev, u16 addr, u16 length,
> + void *values)
> +{
> + return axiom_spi_transfer(dev, AX_WR_OP, addr, length, values);
> +}
> +
> +static const struct axiom_bus_ops axiom_spi_bus_ops = {
> + .bustype = BUS_SPI,
> + .write = axiom_spi_write_block_data,
> + .read = axiom_spi_read_block_data,
> +};
> +
> +static int axiom_spi_probe(struct spi_device *spi)
> +{
> + struct axiom *axiom;
> + int error;
> +
> + /* Set up SPI */
> + spi->bits_per_word = 8;
> + spi->mode = SPI_MODE_0;
> + spi->max_speed_hz = 4000000;
> +
> + if (spi->irq == 0)
> + dev_err(&spi->dev, "No IRQ specified!\n");
> +
> + error = spi_setup(spi);
> + if (error < 0) {
> + dev_err(&spi->dev, "%s: SPI setup error %d\n", __func__, error);
> + return error;
> + }
> + axiom = axiom_probe(&axiom_spi_bus_ops, &spi->dev, spi->irq);
> + if (IS_ERR(axiom))
> + return dev_err_probe(&spi->dev, PTR_ERR(axiom),
> + "failed to register input device\n");
> +
> + return 0;
> +}
> +
> +static const struct spi_device_id axiom_spi_id_table[] = {
> + { "axiom-spi" },
> + {},
> +};
> +MODULE_DEVICE_TABLE(spi, axiom_spi_id_table);
> +
> +static const struct of_device_id axiom_spi_dt_ids[] = {
> + {
> + .compatible = "tnx,axiom-spi",
> + .data = "axiom",
> + },
> + {}
> +};
> +MODULE_DEVICE_TABLE(of, axiom_spi_dt_ids);
> +
> +static struct spi_driver axiom_spi_driver = {
> + .id_table = axiom_spi_id_table,
> + .driver = {
> + .name = "axiom_spi",
> + .of_match_table = of_match_ptr(axiom_spi_dt_ids),
> + },
> + .probe = axiom_spi_probe,
> +};
> +
> +module_spi_driver(axiom_spi_driver);
> +
> +MODULE_AUTHOR("TouchNetix <support@touchnetix.com>");
> +MODULE_DESCRIPTION("aXiom touchscreen SPI bus driver");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS("axiom");
> +MODULE_VERSION("1.0.0");
> --
> 2.43.0
>
>
--
#gernperDu
#CallMeByMyFirstName
Pengutronix e.K. | |
Steuerwalder Str. 21 | https://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-9 |
^ permalink raw reply
* Re: [PATCH 0/1] Input: Add TouchNetix aXiom touchscreen driver
From: Marco Felsch @ 2026-01-22 21:41 UTC (permalink / raw)
To: AThomas63
Cc: dmitry.torokhov, linux-input, linux-kernel, mark.satterthwaite,
kamel.bouhara, kernel
In-Reply-To: <20260122124819.273188-1-andrew.thomas@touchnetix.com>
Hi Andrew,
thanks for your patch.
A few words prior doing a very rough review. I don't like the idea of
posting two complete different patchsets, furthermore if you could have
added the missing SPI support on-top of my patchset very easily since I
used the regmap-API.
Most of my patches already got the r-b tags and I received a very good
review from Dmitry recently which I currently integrating to send a new
version.
On 26-01-22, AThomas63 wrote:
> A Summary of the added features:
> - Add input driver support for TouchNetix aXiom touchscreen controller
> using either I2C or SPI.
> - Support ABS_MT touch reports in axiom_process_u41_report().
> - Support both polling and interrupt mode (trigger low).
> - Add basic documentation and provide example device tree bindings.
> - Provide the basic structure to add firmware and config download in
> the future via both I2C and SPI.
>
> I understand the process is already under way to add a driver to support
> aXiom by Marco at Pengutronix.
> I think it would be most useful for us to attempt to combine this patch
> in order to support both his changes for config/firmware download and
> the patch here for SPI support along with I2C. I would be happy to help
> with this process.
> This would allow TouchNetix to support a broader range of users of the
> aXiom device family.
>
> I also have a device tree binding however I have not added it sincec
> from my understanding this should go in a different patch:
> Documentation/devicetree/bindings/input/touchscreen/tnx,axiom.yaml
>
> My apologies if there are any obvious mistakes in this patch, this is the
> first patch that I have submitted.
That's not a problem at least not for me, but there are contriubtion
guidelines which you could have read first.
Also I'm a bit surprised that you have sent a driver for the same device
family which is less capable than mine. Your driver is missing the
complete fw-update mechanism and therefore needs still your downstream
python tooling. The fw-update logic is a huge part, since this was hard
to get it right.
There are a few other parts, you're doing wrong (please see the patch
review).
Regards,
Marco
>
> Many thanks for your time,
> Andrew Thomas
>
> AThomas63 (1):
> Adding support for aXiom touchscreen controller
>
> drivers/input/touchscreen/Kconfig | 30 ++
> drivers/input/touchscreen/Makefile | 3 +
> drivers/input/touchscreen/axiom_core.c | 482 +++++++++++++++++++++++++
> drivers/input/touchscreen/axiom_core.h | 128 +++++++
> drivers/input/touchscreen/axiom_i2c.c | 152 ++++++++
> drivers/input/touchscreen/axiom_spi.c | 159 ++++++++
> 6 files changed, 954 insertions(+)
> create mode 100644 drivers/input/touchscreen/axiom_core.c
> create mode 100644 drivers/input/touchscreen/axiom_core.h
> create mode 100644 drivers/input/touchscreen/axiom_i2c.c
> create mode 100644 drivers/input/touchscreen/axiom_spi.c
>
> --
> 2.43.0
>
>
--
#gernperDu
#CallMeByMyFirstName
Pengutronix e.K. | |
Steuerwalder Str. 21 | https://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-9 |
^ permalink raw reply
* [dtor-input:next] BUILD SUCCESS 8a8e63fedbe433b888143fcb7ff55b7a87fa3163
From: kernel test robot @ 2026-01-22 21:10 UTC (permalink / raw)
To: Dmitry Torokhov; +Cc: linux-input
tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git next
branch HEAD: 8a8e63fedbe433b888143fcb7ff55b7a87fa3163 Input: appletouch - fix potential race between resume and open
elapsed time: 1319m
configs tested: 289
configs skipped: 6
The following configs have been built successfully.
More configs may be tested in the coming days.
tested configs:
alpha allnoconfig gcc-15.2.0
alpha allyesconfig gcc-15.2.0
alpha defconfig gcc-15.2.0
arc allmodconfig clang-16
arc allnoconfig gcc-15.2.0
arc allyesconfig clang-22
arc allyesconfig gcc-15.2.0
arc defconfig gcc-15.2.0
arc nsimosci_hs_defconfig gcc-15.2.0
arc randconfig-001-20260122 gcc-15.2.0
arc randconfig-001-20260123 gcc-10.5.0
arc randconfig-002-20260122 gcc-15.2.0
arc randconfig-002-20260123 gcc-10.5.0
arc tb10x_defconfig gcc-15.2.0
arc vdk_hs38_smp_defconfig gcc-15.2.0
arm allnoconfig clang-22
arm allnoconfig gcc-15.2.0
arm allyesconfig clang-16
arm defconfig gcc-15.2.0
arm gemini_defconfig clang-22
arm mmp2_defconfig clang-22
arm mv78xx0_defconfig gcc-15.2.0
arm nhk8815_defconfig clang-22
arm omap1_defconfig clang-22
arm pxa910_defconfig gcc-15.2.0
arm randconfig-001-20260122 gcc-15.2.0
arm randconfig-001-20260123 gcc-10.5.0
arm randconfig-002-20260122 gcc-15.2.0
arm randconfig-002-20260123 gcc-10.5.0
arm randconfig-003-20260122 gcc-15.2.0
arm randconfig-003-20260123 gcc-10.5.0
arm randconfig-004-20260122 gcc-15.2.0
arm randconfig-004-20260123 gcc-10.5.0
arm sama7_defconfig clang-22
arm versatile_defconfig clang-22
arm64 allmodconfig clang-19
arm64 allmodconfig clang-22
arm64 allnoconfig gcc-15.2.0
arm64 defconfig gcc-15.2.0
arm64 randconfig-001-20260122 gcc-15.2.0
arm64 randconfig-001-20260123 gcc-15.2.0
arm64 randconfig-002-20260122 gcc-15.2.0
arm64 randconfig-002-20260123 gcc-15.2.0
arm64 randconfig-003-20260122 gcc-15.2.0
arm64 randconfig-003-20260123 gcc-15.2.0
arm64 randconfig-004-20260122 gcc-15.2.0
arm64 randconfig-004-20260123 gcc-15.2.0
csky allmodconfig gcc-15.2.0
csky allnoconfig gcc-15.2.0
csky defconfig gcc-15.2.0
csky randconfig-001-20260122 gcc-15.2.0
csky randconfig-001-20260123 gcc-15.2.0
csky randconfig-002-20260122 gcc-15.2.0
csky randconfig-002-20260123 gcc-15.2.0
hexagon allmodconfig clang-17
hexagon allmodconfig gcc-15.2.0
hexagon allnoconfig clang-22
hexagon allnoconfig gcc-15.2.0
hexagon defconfig gcc-15.2.0
hexagon randconfig-001-20260122 gcc-15.2.0
hexagon randconfig-001-20260123 gcc-12.5.0
hexagon randconfig-002-20260122 gcc-15.2.0
hexagon randconfig-002-20260123 gcc-12.5.0
i386 allmodconfig clang-20
i386 allmodconfig gcc-14
i386 allnoconfig gcc-14
i386 allnoconfig gcc-15.2.0
i386 allyesconfig clang-20
i386 allyesconfig gcc-14
i386 buildonly-randconfig-001-20260122 clang-20
i386 buildonly-randconfig-001-20260123 clang-20
i386 buildonly-randconfig-002-20260122 clang-20
i386 buildonly-randconfig-002-20260123 clang-20
i386 buildonly-randconfig-003-20260122 clang-20
i386 buildonly-randconfig-003-20260123 clang-20
i386 buildonly-randconfig-004-20260122 clang-20
i386 buildonly-randconfig-004-20260123 clang-20
i386 buildonly-randconfig-005-20260122 clang-20
i386 buildonly-randconfig-005-20260123 clang-20
i386 buildonly-randconfig-006-20260122 clang-20
i386 buildonly-randconfig-006-20260123 clang-20
i386 defconfig gcc-15.2.0
i386 randconfig-001-20260122 gcc-14
i386 randconfig-002-20260122 gcc-14
i386 randconfig-003-20260122 gcc-14
i386 randconfig-004-20260122 gcc-14
i386 randconfig-005-20260122 gcc-14
i386 randconfig-006-20260122 gcc-14
i386 randconfig-007-20260122 gcc-14
i386 randconfig-011-20260122 clang-20
i386 randconfig-011-20260123 clang-20
i386 randconfig-012-20260122 clang-20
i386 randconfig-012-20260123 clang-20
i386 randconfig-013-20260122 clang-20
i386 randconfig-013-20260123 clang-20
i386 randconfig-014-20260122 clang-20
i386 randconfig-014-20260123 clang-20
i386 randconfig-015-20260122 clang-20
i386 randconfig-015-20260123 clang-20
i386 randconfig-016-20260122 clang-20
i386 randconfig-016-20260123 clang-20
i386 randconfig-017-20260122 clang-20
i386 randconfig-017-20260123 clang-20
loongarch allmodconfig clang-19
loongarch allmodconfig clang-22
loongarch allnoconfig clang-22
loongarch allnoconfig gcc-15.2.0
loongarch defconfig clang-19
loongarch randconfig-001-20260122 gcc-15.2.0
loongarch randconfig-001-20260123 gcc-12.5.0
loongarch randconfig-002-20260122 gcc-15.2.0
loongarch randconfig-002-20260123 gcc-12.5.0
m68k allmodconfig gcc-15.2.0
m68k allnoconfig gcc-15.2.0
m68k allyesconfig clang-16
m68k amiga_defconfig gcc-15.2.0
m68k defconfig clang-19
m68k m5275evb_defconfig clang-22
m68k mvme147_defconfig gcc-15.2.0
microblaze allnoconfig gcc-15.2.0
microblaze allyesconfig gcc-15.2.0
microblaze defconfig clang-19
mips allmodconfig gcc-15.2.0
mips allnoconfig gcc-15.2.0
mips allyesconfig gcc-15.2.0
mips ath25_defconfig clang-22
mips cu1000-neo_defconfig gcc-15.2.0
mips cu1830-neo_defconfig gcc-15.2.0
mips decstation_defconfig gcc-15.2.0
mips eyeq5_defconfig clang-22
nios2 allmodconfig clang-22
nios2 allmodconfig gcc-11.5.0
nios2 allnoconfig clang-22
nios2 allnoconfig gcc-11.5.0
nios2 defconfig clang-19
nios2 randconfig-001-20260122 gcc-15.2.0
nios2 randconfig-001-20260123 gcc-12.5.0
nios2 randconfig-002-20260122 gcc-15.2.0
nios2 randconfig-002-20260123 gcc-12.5.0
openrisc allmodconfig clang-22
openrisc allmodconfig gcc-15.2.0
openrisc allnoconfig clang-22
openrisc allnoconfig gcc-15.2.0
openrisc defconfig gcc-15.2.0
parisc alldefconfig gcc-15.2.0
parisc allmodconfig gcc-15.2.0
parisc allnoconfig clang-22
parisc allnoconfig gcc-15.2.0
parisc allyesconfig clang-19
parisc defconfig gcc-15.2.0
parisc randconfig-001-20260122 gcc-10.5.0
parisc randconfig-001-20260123 gcc-12.5.0
parisc randconfig-002-20260122 gcc-10.5.0
parisc randconfig-002-20260123 gcc-12.5.0
parisc64 defconfig clang-19
powerpc allmodconfig gcc-15.2.0
powerpc allnoconfig clang-22
powerpc allnoconfig gcc-15.2.0
powerpc eiger_defconfig gcc-15.2.0
powerpc fsp2_defconfig gcc-15.2.0
powerpc lite5200b_defconfig gcc-15.2.0
powerpc mpc5200_defconfig clang-22
powerpc mpc834x_itx_defconfig gcc-15.2.0
powerpc powernv_defconfig clang-22
powerpc ps3_defconfig gcc-15.2.0
powerpc randconfig-001-20260122 gcc-10.5.0
powerpc randconfig-001-20260123 gcc-12.5.0
powerpc randconfig-002-20260122 gcc-10.5.0
powerpc randconfig-002-20260123 gcc-12.5.0
powerpc tqm8541_defconfig gcc-15.2.0
powerpc64 randconfig-001-20260122 gcc-10.5.0
powerpc64 randconfig-001-20260123 gcc-12.5.0
powerpc64 randconfig-002-20260122 gcc-10.5.0
powerpc64 randconfig-002-20260123 gcc-12.5.0
riscv alldefconfig gcc-15.2.0
riscv allmodconfig clang-22
riscv allnoconfig clang-22
riscv allnoconfig gcc-15.2.0
riscv allyesconfig clang-16
riscv defconfig gcc-15.2.0
riscv randconfig-001-20260122 clang-18
riscv randconfig-001-20260123 clang-22
riscv randconfig-002-20260122 clang-18
riscv randconfig-002-20260123 clang-22
s390 allmodconfig clang-19
s390 allnoconfig clang-22
s390 allyesconfig gcc-15.2.0
s390 defconfig gcc-15.2.0
s390 randconfig-001-20260122 clang-18
s390 randconfig-001-20260123 clang-22
s390 randconfig-002-20260122 clang-18
s390 randconfig-002-20260123 clang-22
sh allmodconfig gcc-15.2.0
sh allnoconfig clang-22
sh allnoconfig gcc-15.2.0
sh allyesconfig clang-19
sh defconfig gcc-14
sh dreamcast_defconfig gcc-15.2.0
sh r7780mp_defconfig clang-22
sh randconfig-001-20260122 clang-18
sh randconfig-001-20260123 clang-22
sh randconfig-002-20260122 clang-18
sh randconfig-002-20260123 clang-22
sh sdk7786_defconfig clang-22
sh se7206_defconfig clang-22
sh se7343_defconfig gcc-15.2.0
sh se7721_defconfig gcc-15.2.0
sh sh03_defconfig clang-22
sh sh7724_generic_defconfig gcc-15.2.0
sparc alldefconfig clang-22
sparc allnoconfig clang-22
sparc allnoconfig gcc-15.2.0
sparc defconfig gcc-15.2.0
sparc randconfig-001-20260122 gcc-8.5.0
sparc randconfig-001-20260123 gcc-13.4.0
sparc randconfig-002-20260122 gcc-8.5.0
sparc randconfig-002-20260123 gcc-13.4.0
sparc64 alldefconfig gcc-15.2.0
sparc64 allmodconfig clang-22
sparc64 defconfig gcc-14
sparc64 randconfig-001-20260122 gcc-8.5.0
sparc64 randconfig-001-20260123 gcc-13.4.0
sparc64 randconfig-002-20260122 gcc-8.5.0
sparc64 randconfig-002-20260123 gcc-13.4.0
um allmodconfig clang-19
um allnoconfig clang-22
um allyesconfig gcc-14
um allyesconfig gcc-15.2.0
um defconfig gcc-14
um i386_defconfig gcc-14
um randconfig-001-20260122 gcc-8.5.0
um randconfig-001-20260123 gcc-13.4.0
um randconfig-002-20260122 gcc-8.5.0
um randconfig-002-20260123 gcc-13.4.0
um x86_64_defconfig gcc-14
x86_64 alldefconfig gcc-15.2.0
x86_64 allmodconfig clang-20
x86_64 allnoconfig clang-20
x86_64 allnoconfig clang-22
x86_64 allyesconfig clang-20
x86_64 buildonly-randconfig-001-20260122 clang-20
x86_64 buildonly-randconfig-002-20260122 clang-20
x86_64 buildonly-randconfig-003-20260122 clang-20
x86_64 buildonly-randconfig-004-20260122 clang-20
x86_64 buildonly-randconfig-005-20260122 clang-20
x86_64 buildonly-randconfig-006-20260122 clang-20
x86_64 defconfig gcc-14
x86_64 kexec clang-20
x86_64 randconfig-001-20260122 clang-20
x86_64 randconfig-002-20260122 clang-20
x86_64 randconfig-003-20260122 clang-20
x86_64 randconfig-004-20260122 clang-20
x86_64 randconfig-005-20260122 clang-20
x86_64 randconfig-006-20260122 clang-20
x86_64 randconfig-011-20260122 clang-20
x86_64 randconfig-011-20260123 gcc-14
x86_64 randconfig-012-20260122 clang-20
x86_64 randconfig-012-20260123 gcc-14
x86_64 randconfig-013-20260122 clang-20
x86_64 randconfig-013-20260123 gcc-14
x86_64 randconfig-014-20260122 clang-20
x86_64 randconfig-014-20260123 gcc-14
x86_64 randconfig-015-20260122 clang-20
x86_64 randconfig-015-20260123 gcc-14
x86_64 randconfig-016-20260122 clang-20
x86_64 randconfig-016-20260123 gcc-14
x86_64 randconfig-071-20260122 clang-20
x86_64 randconfig-072-20260122 clang-20
x86_64 randconfig-073-20260122 clang-20
x86_64 randconfig-074-20260122 clang-20
x86_64 randconfig-075-20260122 clang-20
x86_64 randconfig-076-20260122 clang-20
x86_64 rhel-9.4 clang-20
x86_64 rhel-9.4-bpf gcc-14
x86_64 rhel-9.4-func clang-20
x86_64 rhel-9.4-kselftests clang-20
x86_64 rhel-9.4-kunit gcc-14
x86_64 rhel-9.4-ltp gcc-14
x86_64 rhel-9.4-rust clang-20
xtensa allnoconfig clang-22
xtensa allnoconfig gcc-15.2.0
xtensa allyesconfig clang-22
xtensa cadence_csp_defconfig gcc-15.2.0
xtensa iss_defconfig gcc-15.2.0
xtensa nommu_kc705_defconfig gcc-15.2.0
xtensa randconfig-001-20260122 gcc-8.5.0
xtensa randconfig-001-20260123 gcc-13.4.0
xtensa randconfig-002-20260122 gcc-8.5.0
xtensa randconfig-002-20260123 gcc-13.4.0
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply
* Re: [PATCH 1/2] linux/interrupt.h: allow "guard" notation to disable and reenable IRQ with valid IRQ check
From: Dmitry Torokhov @ 2026-01-22 18:38 UTC (permalink / raw)
To: Geert Uytterhoeven
Cc: Sebastian Andrzej Siewior, Marek Vasut, linux-input,
Peter Zijlstra (Intel), Cheng-Yang Chou, Frank Li,
Geert Uytterhoeven, Jinjie Ruan, Krzysztof Kozlowski,
Marc Zyngier, Thomas Gleixner, linux-kernel, linux-renesas-soc
In-Reply-To: <CAMuHMdVs_ODx3eByHkU03vopUuLuY7=uRnfTKuai65jNr+xMhA@mail.gmail.com>
On Thu, Jan 22, 2026 at 05:31:42PM +0100, Geert Uytterhoeven wrote:
> Hi Sebastian,
>
> On Thu, 22 Jan 2026 at 17:22, Sebastian Andrzej Siewior
> <bigeasy@linutronix.de> wrote:
> > On 2026-01-22 00:23:47 [+0100], Marek Vasut wrote:
> > > @@ -242,6 +242,21 @@ extern void irq_wake_thread(unsigned int irq, void *dev_id);
> > > DEFINE_LOCK_GUARD_1(disable_irq, int,
> > > disable_irq(*_T->lock), enable_irq(*_T->lock))
> > >
> > > +static inline void disable_valid_irq(unsigned int irq)
> > > +{
> > > + if (irq > 0)
> > > + disable_irq(irq);
> > > +}
> >
> > | $ grep " 0:" /proc/interrupts
> > | 0: 43 0 IO-APIC 2-edge timer
> >
> > in other words, interrupt 0 is valid.
>
> AFAIK, the x86 legacy timer interrupt is the sole remaining valid user
> of interrupt number zero.
> Nowadays lots of code assumes valid interrupt numbers are non-zero
> positive numbers.
Quoting an oldie but goodie:
"This has come up before. For example: for an IRQ, 0 means "does not
exist", it does _not_ mean "physical irq 0", and we test for whether a
device has a valid irq by doing "if (dev->irq)" rather than having some
insane architecture-specific "IRQ_NONE". And if you validly really have an
irq at the hardware level that is zero, then that just means that the irq
numbers you should tell the kernel should be translated some way.
(On a PC, hardware irq 0 is a real irq too, but it's a _special_ irq, and
it is set up by architecture-specific code. So as far as the generic
kernel and all devices are concerned, "!dev->irq" means that the irq
doesn't exist or hasn't been mapped for that device yet)."
https://lore.kernel.org/all/Pine.LNX.4.64.0701250940220.25027@woody.linux-foundation.org/
Thanks.
--
Dmitry
^ permalink raw reply
* [PATCH v1 1/1] dt-bindings: input: touchscreen: tsc2007: document '#io-channel-cells'
From: Svyatoslav Ryhel @ 2026-01-22 19:35 UTC (permalink / raw)
To: Dmitry Torokhov, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Svyatoslav Ryhel, Frank Li, Fabio Estevam, Andreas Kemnade
Cc: linux-input, devicetree, linux-kernel
In-Reply-To: <20260122193549.29858-1-clamor95@gmail.com>
The tsc2007 can be used not only as resistive touchscreen controller but
also as a ADC IIO sensor. The second use case requires '#io-channel-cells'
property, hence add it.
Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
---
.../devicetree/bindings/input/touchscreen/ti,tsc2007.yaml | 3 +++
1 file changed, 3 insertions(+)
diff --git a/Documentation/devicetree/bindings/input/touchscreen/ti,tsc2007.yaml b/Documentation/devicetree/bindings/input/touchscreen/ti,tsc2007.yaml
index a595df3ea802..d9cb53e86512 100644
--- a/Documentation/devicetree/bindings/input/touchscreen/ti,tsc2007.yaml
+++ b/Documentation/devicetree/bindings/input/touchscreen/ti,tsc2007.yaml
@@ -53,6 +53,9 @@ properties:
how much time to wait (in milliseconds) before reading again the
values from the tsc2007.
+ "#io-channel-cells":
+ const: 1
+
required:
- compatible
- reg
--
2.51.0
^ permalink raw reply related
* [PATCH v1 0/1] dt-bindings: input: touchscreen: tsc2007: document '#io-channel-cells'
From: Svyatoslav Ryhel @ 2026-01-22 19:35 UTC (permalink / raw)
To: Dmitry Torokhov, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Svyatoslav Ryhel, Frank Li, Fabio Estevam, Andreas Kemnade
Cc: linux-input, devicetree, linux-kernel
The tsc2007 can be used not only as resistive touchscreen controller but
also as a ADC IIO sensor. The second use case requires '#io-channel-cells'
property, hence add it.
Svyatoslav Ryhel (1):
dt-bindings: input: touchscreen: tsc2007: document '#io-channel-cells'
.../devicetree/bindings/input/touchscreen/ti,tsc2007.yaml | 3 +++
1 file changed, 3 insertions(+)
--
2.51.0
^ permalink raw reply
* Re: [PATCH 1/2] linux/interrupt.h: allow "guard" notation to disable and reenable IRQ with valid IRQ check
From: Marek Vasut @ 2026-01-22 19:11 UTC (permalink / raw)
To: Frank Li, Marek Vasut
Cc: linux-input, Peter Zijlstra (Intel), Cheng-Yang Chou,
Dmitry Torokhov, Geert Uytterhoeven, Jinjie Ruan,
Krzysztof Kozlowski, Marc Zyngier, Sebastian Andrzej Siewior,
Thomas Gleixner, linux-kernel, linux-renesas-soc
In-Reply-To: <aXJEaTPIhDGFb11C@lizhi-Precision-Tower-5810>
On 1/22/26 4:38 PM, Frank Li wrote:
> On Thu, Jan 22, 2026 at 12:23:47AM +0100, Marek Vasut wrote:
>> Introduce disable_valid_irq scoped guard. This is an extension
>> of disable_irq scoped guard, which disables and enables IRQs
>> around a scope. The disable_valid_irq scoped guard does almost
>> the same, except it handles the case where IRQ is not valid,
>> in which case it does not do anything. This is meant to be used
>> by for example touch controller drivers, which can do both IRQ
>> driven and polling mode of operation, and this makes their code
>> slighly simpler.
>
> I think it'd better to give simple example here.
Patch 2/2 is that example , but I can also include it in the commit
message if this 1/2 is even acceptable.
^ permalink raw reply
* Re: [PATCH 1/1] Adding support for aXiom touchscreen controller
From: kernel test robot @ 2026-01-22 19:03 UTC (permalink / raw)
To: AThomas63, dmitry.torokhov
Cc: oe-kbuild-all, linux-input, linux-kernel, mark.satterthwaite,
andrew.thomas, m.felsch, kamel.bouhara
In-Reply-To: <20260122124819.273188-2-andrew.thomas@touchnetix.com>
Hi AThomas63,
kernel test robot noticed the following build errors:
[auto build test ERROR on dtor-input/next]
[also build test ERROR on dtor-input/for-linus hid/for-next linus/master v6.19-rc6 next-20260122]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/AThomas63/Adding-support-for-aXiom-touchscreen-controller/20260122-212452
base: https://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git next
patch link: https://lore.kernel.org/r/20260122124819.273188-2-andrew.thomas%40touchnetix.com
patch subject: [PATCH 1/1] Adding support for aXiom touchscreen controller
config: sh-randconfig-r072-20260123 (https://download.01.org/0day-ci/archive/20260123/202601230252.ZlyhNYe2-lkp@intel.com/config)
compiler: sh4-linux-gcc (GCC) 14.3.0
smatch version: v0.5.0-8994-gd50c5a4c
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260123/202601230252.ZlyhNYe2-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202601230252.ZlyhNYe2-lkp@intel.com/
All errors (new ones prefixed by >>):
drivers/input/touchscreen/axiom_core.c: In function 'axiom_unpack_device_info':
>> drivers/input/touchscreen/axiom_core.c:110:27: error: implicit declaration of function 'FIELD_GET' [-Wimplicit-function-declaration]
110 | info->device_id = FIELD_GET(AX_DEV_ID_MASK, w);
| ^~~~~~~~~
vim +/FIELD_GET +110 drivers/input/touchscreen/axiom_core.c
103
104 static void axiom_unpack_device_info(const u8 *buf,
105 struct axiom_device_info *info)
106 {
107 u16 w;
108
109 w = get_unaligned_le16(buf);
> 110 info->device_id = FIELD_GET(AX_DEV_ID_MASK, w);
111 info->mode = !!(w & AX_MODE);
112
113 w = get_unaligned_le16(buf + 2);
114 info->runtime_fw_rev_minor = FIELD_GET(AX_FW_REV_MINOR_MASK, w);
115 info->runtime_fw_rev_major = FIELD_GET(AX_FW_REV_MAJOR_MASK, w);
116
117 w = get_unaligned_le16(buf + 4);
118 info->device_build_variant = FIELD_GET(AX_VARIANT_MASK, w);
119 info->runtime_fw_status = !!(w & AX_FW_STATUS);
120 info->tcp_revision = FIELD_GET(AX_TCP_REV_MASK, w);
121
122 w = get_unaligned_le16(buf + 6);
123 info->bootloader_fw_rev_minor = FIELD_GET(AX_BOOT_REV_MINOR_MASK, w);
124 info->bootloader_fw_rev_major = FIELD_GET(AX_BOOT_REV_MAJOR_MASK, w);
125
126 info->jedec_id = get_unaligned_le16(buf + 8);
127
128 w = get_unaligned_le16(buf + 10);
129 info->num_usages = FIELD_GET(AX_NUM_USAGES_MASK, w);
130 info->silicon_revision = FIELD_GET(AX_SILICON_REV_MASK, w);
131 info->runtime_fw_rev_patch = FIELD_GET(AX_RUNTIME_FW_PATCH_MASK, w);
132 }
133
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply
* Re: [PATCH 1/2] linux/interrupt.h: allow "guard" notation to disable and reenable IRQ with valid IRQ check
From: Sergey Shtylyov @ 2026-01-22 18:57 UTC (permalink / raw)
To: Geert Uytterhoeven, Sebastian Andrzej Siewior
Cc: Marek Vasut, linux-input, Peter Zijlstra (Intel), Cheng-Yang Chou,
Dmitry Torokhov, Frank Li, Geert Uytterhoeven, Jinjie Ruan,
Krzysztof Kozlowski, Marc Zyngier, Thomas Gleixner, linux-kernel,
linux-renesas-soc
In-Reply-To: <CAMuHMdVs_ODx3eByHkU03vopUuLuY7=uRnfTKuai65jNr+xMhA@mail.gmail.com>
On 1/22/26 7:31 PM, Geert Uytterhoeven wrote:
[...]
>>> @@ -242,6 +242,21 @@ extern void irq_wake_thread(unsigned int irq, void *dev_id);
>>> DEFINE_LOCK_GUARD_1(disable_irq, int,
>>> disable_irq(*_T->lock), enable_irq(*_T->lock))
>>>
>>> +static inline void disable_valid_irq(unsigned int irq)
>>> +{
>>> + if (irq > 0)
>>> + disable_irq(irq);
>>> +}
>>
>> | $ grep " 0:" /proc/interrupts
>> | 0: 43 0 IO-APIC 2-edge timer
>>
>> in other words, interrupt 0 is valid.
>
> AFAIK, the x86 legacy timer interrupt is the sole remaining valid user
> of interrupt number zero.
> Nowadays lots of code assumes valid interrupt numbers are non-zero
> positive numbers.
Makes me remember this commit:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=ce753ad1549cbe9ccaea4c06a1f5fa47432c8289
> Gr{oetje,eeting}s,
>
> Geert
MBR, Sergey
^ permalink raw reply
* Re: [PATCH 1/2] linux/interrupt.h: allow "guard" notation to disable and reenable IRQ with valid IRQ check
From: Geert Uytterhoeven @ 2026-01-22 16:31 UTC (permalink / raw)
To: Sebastian Andrzej Siewior
Cc: Marek Vasut, linux-input, Peter Zijlstra (Intel), Cheng-Yang Chou,
Dmitry Torokhov, Frank Li, Geert Uytterhoeven, Jinjie Ruan,
Krzysztof Kozlowski, Marc Zyngier, Thomas Gleixner, linux-kernel,
linux-renesas-soc
In-Reply-To: <20260122162206.9wrHkrTZ@linutronix.de>
Hi Sebastian,
On Thu, 22 Jan 2026 at 17:22, Sebastian Andrzej Siewior
<bigeasy@linutronix.de> wrote:
> On 2026-01-22 00:23:47 [+0100], Marek Vasut wrote:
> > @@ -242,6 +242,21 @@ extern void irq_wake_thread(unsigned int irq, void *dev_id);
> > DEFINE_LOCK_GUARD_1(disable_irq, int,
> > disable_irq(*_T->lock), enable_irq(*_T->lock))
> >
> > +static inline void disable_valid_irq(unsigned int irq)
> > +{
> > + if (irq > 0)
> > + disable_irq(irq);
> > +}
>
> | $ grep " 0:" /proc/interrupts
> | 0: 43 0 IO-APIC 2-edge timer
>
> in other words, interrupt 0 is valid.
AFAIK, the x86 legacy timer interrupt is the sole remaining valid user
of interrupt number zero.
Nowadays lots of code assumes valid interrupt numbers are non-zero
positive numbers.
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
^ permalink raw reply
* Re: [PATCH 1/2] linux/interrupt.h: allow "guard" notation to disable and reenable IRQ with valid IRQ check
From: Sebastian Andrzej Siewior @ 2026-01-22 16:22 UTC (permalink / raw)
To: Marek Vasut
Cc: linux-input, Peter Zijlstra (Intel), Cheng-Yang Chou,
Dmitry Torokhov, Frank Li, Geert Uytterhoeven, Jinjie Ruan,
Krzysztof Kozlowski, Marc Zyngier, Thomas Gleixner, linux-kernel,
linux-renesas-soc
In-Reply-To: <20260121232522.154771-1-marek.vasut+renesas@mailbox.org>
On 2026-01-22 00:23:47 [+0100], Marek Vasut wrote:
> @@ -242,6 +242,21 @@ extern void irq_wake_thread(unsigned int irq, void *dev_id);
> DEFINE_LOCK_GUARD_1(disable_irq, int,
> disable_irq(*_T->lock), enable_irq(*_T->lock))
>
> +static inline void disable_valid_irq(unsigned int irq)
> +{
> + if (irq > 0)
> + disable_irq(irq);
> +}
| $ grep " 0:" /proc/interrupts
| 0: 43 0 IO-APIC 2-edge timer
in other words, interrupt 0 is valid.
Sebastian
^ permalink raw reply
* [PATCH v2 4/4] ALSA: hda/conexant: Add headset mic fix for MECHREVO Wujie 15X Pro
From: gongqi @ 2026-01-22 15:55 UTC (permalink / raw)
To: rafael, dmitry.torokhov, Shyam-sundar.S-k, hansg, ilpo.jarvinen,
perex, tiwai
Cc: linux-acpi, linux-input, platform-driver-x86, linux-sound,
linux-kernel, 550230171hxy
In-Reply-To: <20260122155501.376199-1-550230171hxy@gmail.com>
The headset microphone on the MECHREVO Wujie 15X Pro requires the
CXT_FIXUP_HEADSET_MIC quirk to function properly. Add the PCI SSID
(0x1d05:0x3012) to the quirk table.
Signed-off-by: gongqi <550230171hxy@gmail.com>
---
sound/hda/codecs/conexant.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/sound/hda/codecs/conexant.c b/sound/hda/codecs/conexant.c
index 5fcbc1312c697..2384e64eada36 100644
--- a/sound/hda/codecs/conexant.c
+++ b/sound/hda/codecs/conexant.c
@@ -1123,6 +1123,7 @@ static const struct hda_quirk cxt5066_fixups[] = {
SND_PCI_QUIRK_VENDOR(0x17aa, "Thinkpad/Ideapad", CXT_FIXUP_LENOVO_XPAD_ACPI),
SND_PCI_QUIRK(0x1c06, 0x2011, "Lemote A1004", CXT_PINCFG_LEMOTE_A1004),
SND_PCI_QUIRK(0x1c06, 0x2012, "Lemote A1205", CXT_PINCFG_LEMOTE_A1205),
+ SND_PCI_QUIRK(0x1d05, 0x3012, "MECHREVO Wujie 15X Pro", CXT_FIXUP_HEADSET_MIC),
HDA_CODEC_QUIRK(0x2782, 0x12c3, "Sirius Gen1", CXT_PINCFG_TOP_SPEAKER),
HDA_CODEC_QUIRK(0x2782, 0x12c5, "Sirius Gen2", CXT_PINCFG_TOP_SPEAKER),
{}
--
2.43.0
^ permalink raw reply related
* [PATCH v2 3/4] platform/x86/amd/pmc: Add quirk for MECHREVO Wujie 15X Pro
From: gongqi @ 2026-01-22 15:55 UTC (permalink / raw)
To: rafael, dmitry.torokhov, Shyam-sundar.S-k, hansg, ilpo.jarvinen,
perex, tiwai
Cc: linux-acpi, linux-input, platform-driver-x86, linux-sound,
linux-kernel, 550230171hxy
In-Reply-To: <20260122155501.376199-1-550230171hxy@gmail.com>
The MECHREVO Wujie 15X Pro suffers from spurious IRQ issues related to
the AMD PMC. Add it to the quirk list to use the spurious_8042 fix.
Signed-off-by: gongqi <550230171hxy@gmail.com>
---
drivers/platform/x86/amd/pmc/pmc-quirks.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/platform/x86/amd/pmc/pmc-quirks.c b/drivers/platform/x86/amd/pmc/pmc-quirks.c
index 404e62ad293a9..ed285afaf9b0d 100644
--- a/drivers/platform/x86/amd/pmc/pmc-quirks.c
+++ b/drivers/platform/x86/amd/pmc/pmc-quirks.c
@@ -302,6 +302,13 @@ static const struct dmi_system_id fwbug_list[] = {
DMI_MATCH(DMI_BOARD_NAME, "XxKK4NAx_XxSP4NAx"),
}
},
+ {
+ .ident = "MECHREVO Wujie 15X Pro",
+ .driver_data = &quirk_spurious_8042,
+ .matches = {
+ DMI_MATCH(DMI_BOARD_NAME, "WUJIE Series-X5SP4NAG"),
+ }
+ },
{}
};
--
2.43.0
^ permalink raw reply related
* [PATCH v2 2/4] Input: i8042: Add quirks for MECHREVO Wujie 15X Pro
From: gongqi @ 2026-01-22 15:54 UTC (permalink / raw)
To: rafael, dmitry.torokhov, Shyam-sundar.S-k, hansg, ilpo.jarvinen,
perex, tiwai
Cc: linux-acpi, linux-input, platform-driver-x86, linux-sound,
linux-kernel, 550230171hxy
In-Reply-To: <20260122155501.376199-1-550230171hxy@gmail.com>
The MECHREVO Wujie 15X Pro requires several i8042 quirks to function
correctly. Specifically, NOMUX, RESET_ALWAYS, NOLOOP, and NOPNP are
needed to ensure the keyboard and touchpad work reliably.
Signed-off-by: gongqi <550230171hxy@gmail.com>
---
drivers/input/serio/i8042-acpipnpio.h | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/input/serio/i8042-acpipnpio.h b/drivers/input/serio/i8042-acpipnpio.h
index 654771275ce87..4cd09560c5bfb 100644
--- a/drivers/input/serio/i8042-acpipnpio.h
+++ b/drivers/input/serio/i8042-acpipnpio.h
@@ -1176,6 +1176,13 @@ static const struct dmi_system_id i8042_dmi_quirk_table[] __initconst = {
.driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
},
+ {
+ .matches = {
+ DMI_MATCH(DMI_BOARD_NAME, "WUJIE Series-X5SP4NAG"),
+ },
+ .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
+ SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
+ },
/*
* A lot of modern Clevo barebones have touchpad and/or keyboard issues
* after suspend fixable with the forcenorestore quirk.
--
2.43.0
^ permalink raw reply related
* [PATCH v2 1/4] ACPI: resource: Add IRQ override quirk for MECHREVO Wujie 15X Pro
From: gongqi @ 2026-01-22 15:54 UTC (permalink / raw)
To: rafael, dmitry.torokhov, Shyam-sundar.S-k, hansg, ilpo.jarvinen,
perex, tiwai
Cc: linux-acpi, linux-input, platform-driver-x86, linux-sound,
linux-kernel, 550230171hxy
In-Reply-To: <20260122155501.376199-1-550230171hxy@gmail.com>
On the MECHREVO Wujie 15X Pro (Board Name: WUJIE Series-X5SP4NAG), the
keyboard does not function properly without an IRQ override. Add a DMI
entry to force IRQ1 to edge_low.
Signed-off-by: gongqi <550230171hxy@gmail.com>
---
drivers/acpi/resource.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c
index d16906f46484d..2ec5472aa0763 100644
--- a/drivers/acpi/resource.c
+++ b/drivers/acpi/resource.c
@@ -674,6 +674,12 @@ static const struct dmi_system_id irq1_edge_low_force_override[] = {
DMI_MATCH(DMI_BOARD_NAME, "GMxHGxx"),
},
},
+ {
+ /* MECHREVO Wujie 15X Pro */
+ .matches = {
+ DMI_MATCH(DMI_BOARD_NAME, "WUJIE Series-X5SP4NAG"),
+ },
+ },
{
/* MACHENIKE L16P/L16P */
.matches = {
--
2.43.0
^ permalink raw reply related
* [PATCH v2 0/4] Add quirks for MECHREVO Wujie 15X Pro laptop
From: gongqi @ 2026-01-22 15:54 UTC (permalink / raw)
To: rafael, dmitry.torokhov, Shyam-sundar.S-k, hansg, ilpo.jarvinen,
perex, tiwai
Cc: linux-acpi, linux-input, platform-driver-x86, linux-sound,
linux-kernel, 550230171hxy
This series adds several quirks for the MECHREVO Wujie 15X Pro
(AMD Ryzen AI 9 H 365) laptop to fix issues with the keyboard,
touchpad, power management, and headset microphone.
The laptop requires:
- ACPI IRQ override for the keyboard.
- i8042 quirks for keyboard/touchpad stability.
- AMD PMC quirk to fix spurious IRQs during suspend.
- Conexant codec quirk for the headset microphone.
Changes in v2:
- Added Missing Signed-off-by to all patches.
- Wrapped commit messages at 72 columns.
- Unified author and committer email to 550230171hxy@gmail.com.
- Properly formatted cover letter to improve threading.
gongqi (4):
ACPI: resource: Add IRQ override quirk for MECHREVO Wujie 15X Pro
Input: i8042: Add quirks for MECHREVO Wujie 15X Pro
platform/x86/amd/pmc: Add quirk for MECHREVO Wujie 15X Pro
ALSA: hda/conexant: Add headset mic fix for MECHREVO Wujie 15X Pro
drivers/acpi/resource.c | 6 ++++++
drivers/input/serio/i8042-acpipnpio.h | 7 +++++++
drivers/platform/x86/amd/pmc/pmc-quirks.c | 7 +++++++
sound/pci/hda/patch_conexant.c | 1 +
4 files changed, 21 insertions(+)
--
2.43.0
^ permalink raw reply
* Re: [PATCH 1/2] linux/interrupt.h: allow "guard" notation to disable and reenable IRQ with valid IRQ check
From: Frank Li @ 2026-01-22 15:38 UTC (permalink / raw)
To: Marek Vasut
Cc: linux-input, Peter Zijlstra (Intel), Cheng-Yang Chou,
Dmitry Torokhov, Geert Uytterhoeven, Jinjie Ruan,
Krzysztof Kozlowski, Marc Zyngier, Sebastian Andrzej Siewior,
Thomas Gleixner, linux-kernel, linux-renesas-soc
In-Reply-To: <20260121232522.154771-1-marek.vasut+renesas@mailbox.org>
On Thu, Jan 22, 2026 at 12:23:47AM +0100, Marek Vasut wrote:
> Introduce disable_valid_irq scoped guard. This is an extension
> of disable_irq scoped guard, which disables and enables IRQs
> around a scope. The disable_valid_irq scoped guard does almost
> the same, except it handles the case where IRQ is not valid,
> in which case it does not do anything. This is meant to be used
> by for example touch controller drivers, which can do both IRQ
> driven and polling mode of operation, and this makes their code
> slighly simpler.
I think it'd better to give simple example here.
Frank
>
> Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
> ---
> Cc: "Peter Zijlstra (Intel)" <peterz@infradead.org>
> Cc: Cheng-Yang Chou <yphbchou0911@gmail.com>
> Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
> Cc: Frank Li <Frank.Li@nxp.com>
> Cc: Geert Uytterhoeven <geert+renesas@glider.be>
> Cc: Jinjie Ruan <ruanjinjie@huawei.com>
> Cc: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
> Cc: Marc Zyngier <maz@kernel.org>
> Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> Cc: Thomas Gleixner <tglx@kernel.org>
> Cc: linux-input@vger.kernel.org
> Cc: linux-kernel@vger.kernel.org
> Cc: linux-renesas-soc@vger.kernel.org
> ---
> include/linux/interrupt.h | 15 +++++++++++++++
> 1 file changed, 15 insertions(+)
>
> diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
> index 00c01b0a43be1..becbeab4a7473 100644
> --- a/include/linux/interrupt.h
> +++ b/include/linux/interrupt.h
> @@ -242,6 +242,21 @@ extern void irq_wake_thread(unsigned int irq, void *dev_id);
> DEFINE_LOCK_GUARD_1(disable_irq, int,
> disable_irq(*_T->lock), enable_irq(*_T->lock))
>
> +static inline void disable_valid_irq(unsigned int irq)
> +{
> + if (irq > 0)
> + disable_irq(irq);
> +}
> +
> +static inline void enable_valid_irq(unsigned int irq)
> +{
> + if (irq > 0)
> + enable_irq(irq);
> +}
> +
> +DEFINE_LOCK_GUARD_1(disable_valid_irq, int,
> + disable_valid_irq(*_T->lock), enable_valid_irq(*_T->lock))
> +
> extern void disable_nmi_nosync(unsigned int irq);
> extern void disable_percpu_nmi(unsigned int irq);
> extern void enable_nmi(unsigned int irq);
> --
> 2.51.0
>
^ permalink raw reply
* Re: [PATCH 2/4] Input: i8042: Add quirks for MECHREVO Wujie 15X Pro
From: Dmitry Torokhov @ 2026-01-22 15:33 UTC (permalink / raw)
To: gongqi; +Cc: linux-input, linux-kernel, gongqi
In-Reply-To: <20260122120640.3471876-1-550230171hxy@gmail.com>
Hi,
On Thu, Jan 22, 2026 at 08:06:40PM +0800, gongqi wrote:
> From: gongqi <550230171@qq.com>
>
> The MECHREVO Wujie 15X Pro requires several i8042 quirks to function correctly. Specifically, NOMUX, RESET_ALWAYS, NOLOOP, and NOPNP are needed to ensure the keyboard and touchpad work reliably.
Please wrap commit messages at ~70-75 column. I will also need your
"Signed-off-by: " to be able to apply the patch.
By the way, where are the patches 1, 3, and 4?
> ---
> drivers/input/serio/i8042-acpipnpio.h | 7 +++++++
> 1 file changed, 7 insertions(+)
>
> diff --git a/drivers/input/serio/i8042-acpipnpio.h b/drivers/input/serio/i8042-acpipnpio.h
> index 654771275ce87..4cd09560c5bfb 100644
> --- a/drivers/input/serio/i8042-acpipnpio.h
> +++ b/drivers/input/serio/i8042-acpipnpio.h
> @@ -1176,6 +1176,13 @@ static const struct dmi_system_id i8042_dmi_quirk_table[] __initconst = {
> .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
> SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
> },
> + {
> + .matches = {
> + DMI_MATCH(DMI_BOARD_NAME, "WUJIE Series-X5SP4NAG"),
> + },
> + .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
> + SERIO_QUIRK_NOLOOP | SERIO_QUIRK_NOPNP)
> + },
> /*
> * A lot of modern Clevo barebones have touchpad and/or keyboard issues
> * after suspend fixable with the forcenorestore quirk.
Thanks.
--
Dmitry
^ permalink raw reply
* Re: [PATCH v1] Input: pf1550 - Remove "defined but unused" warning
From: Dmitry Torokhov @ 2026-01-22 15:25 UTC (permalink / raw)
To: Samuel Kayode; +Cc: Vaibhav Gupta, imx, linux-input, linux-kernel
In-Reply-To: <aXIhp_c0zjS9dfWQ@sam-fedora>
On Thu, Jan 22, 2026 at 08:09:59AM -0500, Samuel Kayode wrote:
> On Sat, Dec 13, 2025 at 01:38:57AM -0800, Dmitry Torokhov wrote:
> > On Wed, Dec 10, 2025 at 09:11:41PM +0000, Vaibhav Gupta wrote:
> > > If 'CONFIG_PM_SLEEP' is not set, compiler throws warning for *suspend() and
> > > *resume() function for this driver. Using new 'DEFINE_SIMPLE_DEV_PM_OPS'
> > > fixes it.
> > >
> > > Signed-off-by: Vaibhav Gupta <vaibhavgupta40@gmail.com>
> >
> > Applied, thank you.
> >
> I think this patch was dropped.
I see it in my 'next' branch so it should be in linux-next.
Thanks.
--
Dmitry
^ permalink raw reply
* [PATCH v1] dt-bindings: input: Add TouchNetix aXiom touchscreen driver
From: AThomas63 @ 2026-01-22 14:40 UTC (permalink / raw)
To: dmitry.torokhov
Cc: linux-input, linux-kernel, mark.satterthwaite, andrew.thomas,
m.felsch, kamel.bouhara
In-Reply-To: <20260122124819.273188-1-andrew.thomas@touchnetix.com>
Add extra changes referenced in the previous patch:
- Add device tree documentation for axiom giving examples for SPI and I2C.
- Add tnx vendor prefix.
---
.../bindings/input/touchscreen/tnx,axiom.yaml | 90 +++++++++++++++++++
.../devicetree/bindings/vendor-prefixes.yaml | 2 +
2 files changed, 92 insertions(+)
create mode 100644 Documentation/devicetree/bindings/input/touchscreen/tnx,axiom.yaml
diff --git a/Documentation/devicetree/bindings/input/touchscreen/tnx,axiom.yaml b/Documentation/devicetree/bindings/input/touchscreen/tnx,axiom.yaml
new file mode 100644
index 000000000000..dc2ea62999b8
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/touchscreen/tnx,axiom.yaml
@@ -0,0 +1,90 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/input/touchscreen/tnx,axiom.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: TouchNetix aXiom Touchscreen Controller
+
+maintainers:
+ - Andrew Thomas <andrew.thomas@touchnetix.com>
+
+description: |
+ The TouchNetix aXiom series are high-performance touchscreen controllers
+ supporting various interface methods including I2C and SPI.
+
+properties:
+ compatible:
+ enum:
+ - tnx,axiom-i2c
+ - tnx,axiom-spi
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ axiom,poll-enable:
+ type: boolean
+ description: Enable aXiom polling mode instead of interrupt-driven
+ reporting.
+
+ axiom,poll-period:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ default: 10
+ description: Set the polling period in milliseconds.
+
+ # Required for SPI
+ spi-max-frequency: true
+
+ # Common touchscreen properties
+ touchscreen-size-x: true
+ touchscreen-size-y: true
+ touchscreen-inverted-x: true
+ touchscreen-inverted-y: true
+ touchscreen-swapped-x-y: true
+
+required:
+ - compatible
+ - reg
+ - interrupts
+
+allOf:
+ - $ref: touchscreen.yaml#
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/irq.h>
+
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ touchscreen@66 {
+ compatible = "touchnetix,axiom-i2c";
+ reg = <0x66>;
+ interrupt-parent = <&gpio>;
+ interrupts = <24 IRQ_TYPE_LEVEL_LOW>;
+ axiom,poll-enable;
+ axiom,poll-period = <15>;
+ };
+ };
+
+ - |
+ #include <dt-bindings/interrupt-controller/irq.h>
+
+ spi {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ touchscreen@0 {
+ compatible = "touchnetix,axiom-spi";
+ reg = <0>;
+ spi-max-frequency = <4000000>;
+ interrupt-parent = <&gpio>;
+ interrupts = <24 IRQ_TYPE_LEVEL_LOW>;
+ };
+ };
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml
index f1d1882009ba..dadfc7036ed7 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.yaml
+++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -1636,6 +1636,8 @@ patternProperties:
description: Trusted Logic Mobility
"^tmt,.*":
description: Tecon Microprocessor Technologies, LLC.
+ "^tnx,.*":
+ description: TouchNetix
"^topeet,.*":
description: Topeet
"^topic,.*":
--
2.43.0
^ permalink raw reply related
* Re: [PATCH v4 3/3] arm64: dts: qcom: sm6125-xiaomi-laurel-sprout: Add Focaltech FT3518 touchscreen
From: Konrad Dybcio @ 2026-01-22 13:52 UTC (permalink / raw)
To: yedaya.ka, Kamil Gołda, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Bjorn Andersson, Konrad Dybcio
Cc: linux-input, devicetree, linux-kernel, linux-arm-msm
In-Reply-To: <20260120-touchscreen-patches-v4-3-30145da9d6d3@gmail.com>
On 1/20/26 10:40 PM, Yedaya Katsman via B4 Relay wrote:
> From: Yedaya Katsman <yedaya.ka@gmail.com>
>
> Add device tree node for the Focaltech FT3518 touchscreen on
> Xiaomi Mi A3 (laurel-sprout).
>
> Note that gpio pin 83 for the regulator isn't documented downstream
> except in the touchscreen node so it's not defined in the tlmm.
>
> Enable qupv3_id_0 and i2c2 bus that the touchscreen is on.
>
> Downstream references:
> Link: https://github.com/MiCode/Xiaomi_Kernel_OpenSource/blob/laurel-r-oss/arch/arm64/boot/dts/qcom/trinket-pinctrl.dtsi
> Link: https://github.com/MiCode/Xiaomi_Kernel_OpenSource/blob/laurel-r-oss/arch/arm64/boot/dts/qcom/laurel_sprout-qrd.dtsi
>
> Co-developed-by: Kamil Gołda <kamil.golda@protonmail.com>
> Signed-off-by: Kamil Gołda <kamil.golda@protonmail.com>
> Signed-off-by: Yedaya Katsman <yedaya.ka@gmail.com>
> ---
> .../boot/dts/qcom/sm6125-xiaomi-laurel-sprout.dts | 65 ++++++++++++++++++++++
> 1 file changed, 65 insertions(+)
>
> diff --git a/arch/arm64/boot/dts/qcom/sm6125-xiaomi-laurel-sprout.dts b/arch/arm64/boot/dts/qcom/sm6125-xiaomi-laurel-sprout.dts
> index 994fb0412fcbdf5466f87a325c48b697a37b514b..ea9dbc6927a14ca66da818b81aeb0c95ec3c2e7a 100644
> --- a/arch/arm64/boot/dts/qcom/sm6125-xiaomi-laurel-sprout.dts
> +++ b/arch/arm64/boot/dts/qcom/sm6125-xiaomi-laurel-sprout.dts
> @@ -82,6 +82,18 @@ key-volume-up {
> };
> };
>
> + ts_vdd_supply: regulator-ts-vdd {
> + compatible = "regulator-fixed";
> + regulator-name = "ts_vdd_supply";
> + regulator-min-microvolt = <3300000>;
> + regulator-max-microvolt = <3300000>;
> +
> + gpio = <&tlmm 83 GPIO_ACTIVE_HIGH>;
> + enable-active-high;
Ideally you'd add a pin config for gpio83 too
[...]
> + touchscreen@38 {
> + compatible = "focaltech,ft3518";
> + reg = <0x38>;
> + interrupts-extended = <&tlmm 88 IRQ_TYPE_EDGE_FALLING>;
> +
> + vcc-supply = <&ts_vdd_supply>;
> +
> + pinctrl-names = "default","sleep";
> + pinctrl-0 = <&ts_int_active &ts_reset_active>;
> + pinctrl-1 = <&ts_int_suspend &ts_reset_suspend>;
property-n
property-names
in this order specifically, please
lgtm otherwise
Konrad
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox