* [PATCH v2 0/2] Implement lid-notifier for lid switch events
@ 2025-11-11 21:34 Jonathan Denose
2025-11-11 21:34 ` [PATCH v2 1/2] Input: Add lid switch notifier Jonathan Denose
2025-11-11 21:34 ` [PATCH v2 2/2] HID: multitouch: Toggle touch surface on Elan touchpad on lid event Jonathan Denose
0 siblings, 2 replies; 10+ messages in thread
From: Jonathan Denose @ 2025-11-11 21:34 UTC (permalink / raw)
To: Dmitry Torokhov, Jiri Kosina, Benjamin Tissoires
Cc: linux-input, linux-kernel, Jonathan Denose
To circumvent a hardware issue where the touchpad is not physically
connected to the lid angle sensor, implement a notifier chain which
broadcasts lid switch events and a notifier_block which can be enabled
via a quirk to listen for those events turning the touchpad surface
on or off based on if the lid is open or closed. This will prevent
issues resulting from interference between the laptop lid and the
touchpad.
Signed-off-by: Jonathan Denose <jdenose@google.com>
---
Changes in v2:
- Remove notifier logic from input core and add lid-notifier module which exposes lid events
- Kconfig: Add CONFIG_INPUT_LID_NOTIFIER option to include lid-notifier
- Link to v1: https://lore.kernel.org/r/20251030-lid-switch-notifier-v1-0-c58dc9b1439d@google.com
---
Jonathan Denose (2):
Input: Add lid switch notifier
HID: multitouch: Toggle touch surface on Elan touchpad on lid event
drivers/hid/hid-multitouch.c | 32 ++++++++++++++-
drivers/input/Kconfig | 11 +++++
drivers/input/Makefile | 1 +
drivers/input/lid-notifier.c | 98 ++++++++++++++++++++++++++++++++++++++++++++
include/linux/input.h | 2 +
5 files changed, 143 insertions(+), 1 deletion(-)
---
base-commit: 3a8660878839faadb4f1a6dd72c3179c1df56787
change-id: 20251014-lid-switch-notifier-1cb9918d675d
Best regards,
--
Jonathan Denose <jdenose@google.com>
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v2 1/2] Input: Add lid switch notifier
2025-11-11 21:34 [PATCH v2 0/2] Implement lid-notifier for lid switch events Jonathan Denose
@ 2025-11-11 21:34 ` Jonathan Denose
2025-11-11 22:34 ` Dmitry Torokhov
2025-11-11 21:34 ` [PATCH v2 2/2] HID: multitouch: Toggle touch surface on Elan touchpad on lid event Jonathan Denose
1 sibling, 1 reply; 10+ messages in thread
From: Jonathan Denose @ 2025-11-11 21:34 UTC (permalink / raw)
To: Dmitry Torokhov, Jiri Kosina, Benjamin Tissoires
Cc: linux-input, linux-kernel, Jonathan Denose
This change creates a new input handler which can be included in the
build via a new Kconfig option CONFIG_INPUT_LID_NOTIFIER. This input
handler listens for lid switch events and publishes them through an
atomic notification chain. Other modules may register for events
through this notification chain with register_lid_notifier.
Signed-off-by: Jonathan Denose <jdenose@google.com>
---
drivers/input/Kconfig | 11 +++++
drivers/input/Makefile | 1 +
drivers/input/lid-notifier.c | 98 ++++++++++++++++++++++++++++++++++++++++++++
include/linux/input.h | 2 +
4 files changed, 112 insertions(+)
diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig
index 88ecdf5218ee9ba35e1efec6341f8605b621bd49..16f6d24fd04ac8cb5af9d36cc47155ea9be0e177 100644
--- a/drivers/input/Kconfig
+++ b/drivers/input/Kconfig
@@ -38,6 +38,17 @@ config INPUT_LEDS
To compile this driver as a module, choose M here: the
module will be called input-leds.
+config INPUT_LID_NOTIFIER
+ tristate "Include notifier for lid switch events"
+ help
+ Say Y here if you would like to create a notifier to publish lid switch
+ events.
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called lid-notifier.
+
config INPUT_FF_MEMLESS
tristate "Support for memoryless force-feedback devices"
help
diff --git a/drivers/input/Makefile b/drivers/input/Makefile
index 2cd6e1c9a77844fe09cd3d99533e5d3efb038c7d..1efdba04f79a97e2a122b9198341b18a1855b4b9 100644
--- a/drivers/input/Makefile
+++ b/drivers/input/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_INPUT_MATRIXKMAP) += matrix-keymap.o
obj-$(CONFIG_INPUT_VIVALDIFMAP) += vivaldi-fmap.o
obj-$(CONFIG_INPUT_LEDS) += input-leds.o
+obj-$(CONFIG_INPUT_LID_NOTIFIER) += lid-notifier.o
obj-$(CONFIG_INPUT_MOUSEDEV) += mousedev.o
obj-$(CONFIG_INPUT_JOYDEV) += joydev.o
obj-$(CONFIG_INPUT_EVDEV) += evdev.o
diff --git a/drivers/input/lid-notifier.c b/drivers/input/lid-notifier.c
new file mode 100644
index 0000000000000000000000000000000000000000..954b9855532dbd0514860e309d0b76982e947673
--- /dev/null
+++ b/drivers/input/lid-notifier.c
@@ -0,0 +1,98 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Lid event notifier
+ *
+ * Copyright (c) 2025 Jonathan Denose <jdenose@google.com>
+ */
+
+#include <linux/device.h>
+#include <linux/input.h>
+#include <linux/notifier.h>
+
+static struct input_handler lid_handler;
+static struct atomic_notifier_head input_notifier_head;
+
+int register_lid_notifier(struct notifier_block *notifier)
+{
+ return atomic_notifier_chain_register(&input_notifier_head, notifier);
+}
+EXPORT_SYMBOL(register_lid_notifier);
+
+static int lid_handler_connect(struct input_handler *handler,
+ struct input_dev *input_dev, const struct input_device_id *id)
+{
+ struct input_handle *handle;
+ int error;
+
+ handle = devm_kzalloc(&input_dev->dev, sizeof(struct input_handle), GFP_KERNEL);
+ if (!handle)
+ return -ENOMEM;
+
+ handle->dev = input_dev;
+ handle->handler = handler;
+ handle->name = "lid";
+
+ error = input_register_handle(handle);
+ if (error)
+ goto err_free_handle;
+
+ error = input_open_device(handle);
+ if (error)
+ goto err_unregister_handle;
+
+ return 0;
+
+ err_unregister_handle:
+ input_unregister_handle(handle);
+ err_free_handle:
+ kfree(handle);
+ return error;
+}
+
+static void lid_handler_disconnect(struct input_handle *handle)
+{
+ input_close_device(handle);
+ input_unregister_handle(handle);
+}
+
+static void lid_handler_event(struct input_handle *handle, unsigned int type,
+ unsigned int code, int value)
+{
+ if (type == EV_SW && code == SW_LID)
+ atomic_notifier_call_chain(&input_notifier_head, value, handle->dev);
+}
+
+static const struct input_device_id lid_handler_ids[] = {
+ {
+ .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_SWBIT
+ | INPUT_DEVICE_ID_MATCH_BUS,
+ .evbit = { BIT_MASK(EV_SW) },
+ .swbit = { [BIT_WORD(SW_LID)] = BIT_MASK(SW_LID) },
+ .bustype = 0x19
+ },
+ { },
+};
+
+static struct input_handler lid_handler = {
+ .connect = lid_handler_connect,
+ .disconnect = lid_handler_disconnect,
+ .event = lid_handler_event,
+ .name = "lid",
+ .id_table = lid_handler_ids
+};
+
+static int __init lid_notifier_init(void)
+{
+ return input_register_handler(&lid_handler);
+}
+module_init(lid_notifier_init);
+
+static void __exit lid_notifier_exit(void)
+{
+ input_unregister_handler(&lid_handler);
+}
+module_exit(lid_notifier_exit);
+
+MODULE_AUTHOR("Jonathan Denose <jdenose@google.com>");
+MODULE_DESCRIPTION("Lid event notifier");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/input.h b/include/linux/input.h
index 7d7cb0593a63e93c4906c49cde430188db2d1ab5..023eb92c77d9e8721d482b9787632a671671de08 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -592,3 +592,5 @@ int input_ff_create_memless(struct input_dev *dev, void *data,
int (*play_effect)(struct input_dev *, void *, struct ff_effect *));
#endif
+
+int register_lid_notifier(struct notifier_block *notifier);
--
2.51.2.1041.gc1ab5b90ca-goog
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v2 2/2] HID: multitouch: Toggle touch surface on Elan touchpad on lid event
2025-11-11 21:34 [PATCH v2 0/2] Implement lid-notifier for lid switch events Jonathan Denose
2025-11-11 21:34 ` [PATCH v2 1/2] Input: Add lid switch notifier Jonathan Denose
@ 2025-11-11 21:34 ` Jonathan Denose
2025-11-11 22:37 ` Dmitry Torokhov
` (2 more replies)
1 sibling, 3 replies; 10+ messages in thread
From: Jonathan Denose @ 2025-11-11 21:34 UTC (permalink / raw)
To: Dmitry Torokhov, Jiri Kosina, Benjamin Tissoires
Cc: linux-input, linux-kernel, Jonathan Denose
Many touchpad modules have a pin which is expected to be connected to the
lid angle sensor in laptops. The pin sends a signal to the touchpad module
about the lid state and each touchpad vendor handles this notification in
their firmware.
The Elan touchpad with VID 323b does not always have this aforementioned
pin, which then causes interference between the lid and the touchpad when
the lid is closed. This interference causes a few seconds delay before the
touchpad works again, or it causes it to be come completely unresponsive.
To circumvent this hardware issue in software, implement a device quirk
which will allow the hid-multitouch driver to register a notifier_block
to listen for lid switch events. When the lid switch closes, the
touchpad surface will be turned off and when the lid switch opens, the
touchpad surgace will be turned on. This triggers recalibration which
resolves interference issues when the lid is closed.
Signed-off-by: Jonathan Denose <jdenose@google.com>
---
drivers/hid/hid-multitouch.c | 32 +++++++++++++++++++++++++++++++-
1 file changed, 31 insertions(+), 1 deletion(-)
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
index 2879e65cf303b1456311ac06115adda5a78a2600..9a89913c193bc110a0a821a901aebd97892c66bd 100644
--- a/drivers/hid/hid-multitouch.c
+++ b/drivers/hid/hid-multitouch.c
@@ -35,6 +35,7 @@
#include <linux/device.h>
#include <linux/hid.h>
#include <linux/module.h>
+#include <linux/notifier.h>
#include <linux/slab.h>
#include <linux/input/mt.h>
#include <linux/jiffies.h>
@@ -76,6 +77,7 @@ MODULE_LICENSE("GPL");
#define MT_QUIRK_DISABLE_WAKEUP BIT(21)
#define MT_QUIRK_ORIENTATION_INVERT BIT(22)
#define MT_QUIRK_APPLE_TOUCHBAR BIT(23)
+#define MT_QUIRK_REGISTER_LID_NOTIFIER BIT(24)
#define MT_INPUTMODE_TOUCHSCREEN 0x02
#define MT_INPUTMODE_TOUCHPAD 0x03
@@ -183,6 +185,8 @@ struct mt_device {
struct list_head reports;
};
+static struct hid_device *lid_notify_hdev;
+
static void mt_post_parse_default_settings(struct mt_device *td,
struct mt_application *app);
static void mt_post_parse(struct mt_device *td, struct mt_application *app);
@@ -227,6 +231,7 @@ static void mt_post_parse(struct mt_device *td, struct mt_application *app);
#define MT_CLS_SMART_TECH 0x0113
#define MT_CLS_APPLE_TOUCHBAR 0x0114
#define MT_CLS_SIS 0x0457
+#define MT_CLS_REGISTER_LID_NOTIFIER 0x0115
#define MT_DEFAULT_MAXCONTACT 10
#define MT_MAX_MAXCONTACT 250
@@ -327,7 +332,9 @@ static const struct mt_class mt_classes[] = {
MT_QUIRK_CONTACT_CNT_ACCURATE |
MT_QUIRK_WIN8_PTP_BUTTONS,
.export_all_inputs = true },
-
+ { .name = MT_CLS_REGISTER_LID_NOTIFIER,
+ .quirks = MT_QUIRK_REGISTER_LID_NOTIFIER,
+ .export_all_inputs = true },
/*
* vendor specific classes
*/
@@ -1840,6 +1847,20 @@ static void mt_expired_timeout(struct timer_list *t)
clear_bit_unlock(MT_IO_FLAGS_RUNNING, &td->mt_io_flags);
}
+static int mt_input_notifier(struct notifier_block *nb, unsigned long action, void *dev)
+{
+ if (action)
+ mt_set_modes(lid_notify_hdev, HID_LATENCY_NORMAL, TOUCHPAD_REPORT_NONE);
+ else if (!action)
+ mt_set_modes(lid_notify_hdev, HID_LATENCY_NORMAL, TOUCHPAD_REPORT_ALL);
+
+ return 0;
+}
+
+static struct notifier_block mt_lid_notifier_block = {
+ .notifier_call = mt_input_notifier
+};
+
static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
{
int ret, i;
@@ -1920,6 +1941,11 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
if (hdev->vendor == USB_VENDOR_ID_SIS_TOUCH)
hdev->quirks |= HID_QUIRK_NOGET;
+ if (mtclass->quirks & MT_CLS_REGISTER_LID_NOTIFIER) {
+ lid_notify_hdev = hdev;
+ register_lid_notifier(&mt_lid_notifier_block);
+ }
+
ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
if (ret)
return ret;
@@ -2150,6 +2176,10 @@ static const struct hid_device_id mt_devices[] = {
HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8,
USB_VENDOR_ID_ELAN, 0x32ae) },
+ { .driver_data = MT_CLS_REGISTER_LID_NOTIFIER,
+ HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8,
+ USB_VENDOR_ID_ELAN, 0x323b) },
+
/* Elitegroup panel */
{ .driver_data = MT_CLS_SERIAL,
MT_USB_DEVICE(USB_VENDOR_ID_ELITEGROUP,
--
2.51.2.1041.gc1ab5b90ca-goog
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH v2 1/2] Input: Add lid switch notifier
2025-11-11 21:34 ` [PATCH v2 1/2] Input: Add lid switch notifier Jonathan Denose
@ 2025-11-11 22:34 ` Dmitry Torokhov
2025-11-12 23:45 ` Jonathan Denose
0 siblings, 1 reply; 10+ messages in thread
From: Dmitry Torokhov @ 2025-11-11 22:34 UTC (permalink / raw)
To: Jonathan Denose
Cc: Jiri Kosina, Benjamin Tissoires, linux-input, linux-kernel
Hi Jonathan,
On Tue, Nov 11, 2025 at 09:34:06PM +0000, Jonathan Denose wrote:
> This change creates a new input handler which can be included in the
> build via a new Kconfig option CONFIG_INPUT_LID_NOTIFIER. This input
> handler listens for lid switch events and publishes them through an
> atomic notification chain. Other modules may register for events
> through this notification chain with register_lid_notifier.
>
> Signed-off-by: Jonathan Denose <jdenose@google.com>
> ---
> drivers/input/Kconfig | 11 +++++
> drivers/input/Makefile | 1 +
> drivers/input/lid-notifier.c | 98 ++++++++++++++++++++++++++++++++++++++++++++
> include/linux/input.h | 2 +
> 4 files changed, 112 insertions(+)
>
> diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig
> index 88ecdf5218ee9ba35e1efec6341f8605b621bd49..16f6d24fd04ac8cb5af9d36cc47155ea9be0e177 100644
> --- a/drivers/input/Kconfig
> +++ b/drivers/input/Kconfig
> @@ -38,6 +38,17 @@ config INPUT_LEDS
> To compile this driver as a module, choose M here: the
> module will be called input-leds.
>
> +config INPUT_LID_NOTIFIER
> + tristate "Include notifier for lid switch events"
> + help
> + Say Y here if you would like to create a notifier to publish lid switch
> + events.
> +
> + If unsure, say N.
> +
> + To compile this driver as a module, choose M here: the
> + module will be called lid-notifier.
I think this better not surfaced to users but rather interested drivers
'select' it.
> +
> config INPUT_FF_MEMLESS
> tristate "Support for memoryless force-feedback devices"
> help
> diff --git a/drivers/input/Makefile b/drivers/input/Makefile
> index 2cd6e1c9a77844fe09cd3d99533e5d3efb038c7d..1efdba04f79a97e2a122b9198341b18a1855b4b9 100644
> --- a/drivers/input/Makefile
> +++ b/drivers/input/Makefile
> @@ -15,6 +15,7 @@ obj-$(CONFIG_INPUT_MATRIXKMAP) += matrix-keymap.o
> obj-$(CONFIG_INPUT_VIVALDIFMAP) += vivaldi-fmap.o
>
> obj-$(CONFIG_INPUT_LEDS) += input-leds.o
> +obj-$(CONFIG_INPUT_LID_NOTIFIER) += lid-notifier.o
> obj-$(CONFIG_INPUT_MOUSEDEV) += mousedev.o
> obj-$(CONFIG_INPUT_JOYDEV) += joydev.o
> obj-$(CONFIG_INPUT_EVDEV) += evdev.o
> diff --git a/drivers/input/lid-notifier.c b/drivers/input/lid-notifier.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..954b9855532dbd0514860e309d0b76982e947673
> --- /dev/null
> +++ b/drivers/input/lid-notifier.c
> @@ -0,0 +1,98 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Lid event notifier
> + *
> + * Copyright (c) 2025 Jonathan Denose <jdenose@google.com>
> + */
> +
> +#include <linux/device.h>
> +#include <linux/input.h>
> +#include <linux/notifier.h>
> +
> +static struct input_handler lid_handler;
> +static struct atomic_notifier_head input_notifier_head;
> +
> +int register_lid_notifier(struct notifier_block *notifier)
> +{
> + return atomic_notifier_chain_register(&input_notifier_head, notifier);
> +}
> +EXPORT_SYMBOL(register_lid_notifier);
I wonder if we want to expose the "raw" notifier or if we want to
provide a higher-level API that would allocate a notifier blocki, set up
the callback, and return a "cookie" that can be used to free notifier
block later. This way we do not need to worry that some enterprising
driver suppresses notifications for the rest by returning NOTIFY_STOP.
> +
> +static int lid_handler_connect(struct input_handler *handler,
> + struct input_dev *input_dev, const struct input_device_id *id)
Proper alignment of the arguments please.
> +{
> + struct input_handle *handle;
> + int error;
> +
> + handle = devm_kzalloc(&input_dev->dev, sizeof(struct input_handle), GFP_KERNEL);
This is not driver probe path so devm_kzalloc must not be used here.
Also "sizeof(*handle)".
> + if (!handle)
> + return -ENOMEM;
> +
> + handle->dev = input_dev;
> + handle->handler = handler;
> + handle->name = "lid";
> +
> + error = input_register_handle(handle);
> + if (error)
> + goto err_free_handle;
> +
> + error = input_open_device(handle);
> + if (error)
> + goto err_unregister_handle;
> +
> + return 0;
> +
> + err_unregister_handle:
> + input_unregister_handle(handle);
> + err_free_handle:
> + kfree(handle);
Just FYI: One must never use kfree() with devm_kalloc()ed memory.
> + return error;
> +}
> +
> +static void lid_handler_disconnect(struct input_handle *handle)
> +{
> + input_close_device(handle);
> + input_unregister_handle(handle);
kfree(handle);
> +}
> +
> +static void lid_handler_event(struct input_handle *handle, unsigned int type,
> + unsigned int code, int value)
> +{
> + if (type == EV_SW && code == SW_LID)
> + atomic_notifier_call_chain(&input_notifier_head, value, handle->dev);
Why do you need to pass the device from which SW_LID originated?
> +}
> +
> +static const struct input_device_id lid_handler_ids[] = {
> + {
> + .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_SWBIT
> + | INPUT_DEVICE_ID_MATCH_BUS,
> + .evbit = { BIT_MASK(EV_SW) },
> + .swbit = { [BIT_WORD(SW_LID)] = BIT_MASK(SW_LID) },
> + .bustype = 0x19
Why do we need to match in bus type? The LID does not have to always
come from ACPI.
> + },
> + { },
> +};
> +
> +static struct input_handler lid_handler = {
> + .connect = lid_handler_connect,
> + .disconnect = lid_handler_disconnect,
> + .event = lid_handler_event,
> + .name = "lid",
> + .id_table = lid_handler_ids
> +};
> +
> +static int __init lid_notifier_init(void)
> +{
> + return input_register_handler(&lid_handler);
> +}
> +module_init(lid_notifier_init);
> +
> +static void __exit lid_notifier_exit(void)
> +{
> + input_unregister_handler(&lid_handler);
> +}
> +module_exit(lid_notifier_exit);
> +
> +MODULE_AUTHOR("Jonathan Denose <jdenose@google.com>");
> +MODULE_DESCRIPTION("Lid event notifier");
> +MODULE_LICENSE("GPL");
> diff --git a/include/linux/input.h b/include/linux/input.h
> index 7d7cb0593a63e93c4906c49cde430188db2d1ab5..023eb92c77d9e8721d482b9787632a671671de08 100644
> --- a/include/linux/input.h
> +++ b/include/linux/input.h
> @@ -592,3 +592,5 @@ int input_ff_create_memless(struct input_dev *dev, void *data,
> int (*play_effect)(struct input_dev *, void *, struct ff_effect *));
>
> #endif
I think this should go into include/linux/lid-notifier.h.
> +
> +int register_lid_notifier(struct notifier_block *notifier);
Thanks.
--
Dmitry
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v2 2/2] HID: multitouch: Toggle touch surface on Elan touchpad on lid event
2025-11-11 21:34 ` [PATCH v2 2/2] HID: multitouch: Toggle touch surface on Elan touchpad on lid event Jonathan Denose
@ 2025-11-11 22:37 ` Dmitry Torokhov
2025-11-12 23:49 ` Jonathan Denose
2025-11-13 4:49 ` kernel test robot
2025-11-13 4:49 ` kernel test robot
2 siblings, 1 reply; 10+ messages in thread
From: Dmitry Torokhov @ 2025-11-11 22:37 UTC (permalink / raw)
To: Jonathan Denose
Cc: Jiri Kosina, Benjamin Tissoires, linux-input, linux-kernel
Hi Jonathan,
On Tue, Nov 11, 2025 at 09:34:07PM +0000, Jonathan Denose wrote:
> Many touchpad modules have a pin which is expected to be connected to the
> lid angle sensor in laptops. The pin sends a signal to the touchpad module
> about the lid state and each touchpad vendor handles this notification in
> their firmware.
>
> The Elan touchpad with VID 323b does not always have this aforementioned
> pin, which then causes interference between the lid and the touchpad when
> the lid is closed. This interference causes a few seconds delay before the
> touchpad works again, or it causes it to be come completely unresponsive.
> To circumvent this hardware issue in software, implement a device quirk
> which will allow the hid-multitouch driver to register a notifier_block
> to listen for lid switch events. When the lid switch closes, the
> touchpad surface will be turned off and when the lid switch opens, the
> touchpad surgace will be turned on. This triggers recalibration which
> resolves interference issues when the lid is closed.
>
> Signed-off-by: Jonathan Denose <jdenose@google.com>
> ---
> drivers/hid/hid-multitouch.c | 32 +++++++++++++++++++++++++++++++-
> 1 file changed, 31 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
> index 2879e65cf303b1456311ac06115adda5a78a2600..9a89913c193bc110a0a821a901aebd97892c66bd 100644
> --- a/drivers/hid/hid-multitouch.c
> +++ b/drivers/hid/hid-multitouch.c
> @@ -35,6 +35,7 @@
> #include <linux/device.h>
> #include <linux/hid.h>
> #include <linux/module.h>
> +#include <linux/notifier.h>
> #include <linux/slab.h>
> #include <linux/input/mt.h>
> #include <linux/jiffies.h>
> @@ -76,6 +77,7 @@ MODULE_LICENSE("GPL");
> #define MT_QUIRK_DISABLE_WAKEUP BIT(21)
> #define MT_QUIRK_ORIENTATION_INVERT BIT(22)
> #define MT_QUIRK_APPLE_TOUCHBAR BIT(23)
> +#define MT_QUIRK_REGISTER_LID_NOTIFIER BIT(24)
>
> #define MT_INPUTMODE_TOUCHSCREEN 0x02
> #define MT_INPUTMODE_TOUCHPAD 0x03
> @@ -183,6 +185,8 @@ struct mt_device {
> struct list_head reports;
> };
>
> +static struct hid_device *lid_notify_hdev;
This should really be per-device.
> +
> static void mt_post_parse_default_settings(struct mt_device *td,
> struct mt_application *app);
> static void mt_post_parse(struct mt_device *td, struct mt_application *app);
> @@ -227,6 +231,7 @@ static void mt_post_parse(struct mt_device *td, struct mt_application *app);
> #define MT_CLS_SMART_TECH 0x0113
> #define MT_CLS_APPLE_TOUCHBAR 0x0114
> #define MT_CLS_SIS 0x0457
> +#define MT_CLS_REGISTER_LID_NOTIFIER 0x0115
>
> #define MT_DEFAULT_MAXCONTACT 10
> #define MT_MAX_MAXCONTACT 250
> @@ -327,7 +332,9 @@ static const struct mt_class mt_classes[] = {
> MT_QUIRK_CONTACT_CNT_ACCURATE |
> MT_QUIRK_WIN8_PTP_BUTTONS,
> .export_all_inputs = true },
> -
> + { .name = MT_CLS_REGISTER_LID_NOTIFIER,
> + .quirks = MT_QUIRK_REGISTER_LID_NOTIFIER,
> + .export_all_inputs = true },
> /*
> * vendor specific classes
> */
> @@ -1840,6 +1847,20 @@ static void mt_expired_timeout(struct timer_list *t)
> clear_bit_unlock(MT_IO_FLAGS_RUNNING, &td->mt_io_flags);
> }
>
> +static int mt_input_notifier(struct notifier_block *nb, unsigned long action, void *dev)
> +{
> + if (action)
> + mt_set_modes(lid_notify_hdev, HID_LATENCY_NORMAL, TOUCHPAD_REPORT_NONE);
> + else if (!action)
> + mt_set_modes(lid_notify_hdev, HID_LATENCY_NORMAL, TOUCHPAD_REPORT_ALL);
> +
> + return 0;
> +}
> +
> +static struct notifier_block mt_lid_notifier_block = {
> + .notifier_call = mt_input_notifier
> +};
> +
> static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
> {
> int ret, i;
> @@ -1920,6 +1941,11 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
> if (hdev->vendor == USB_VENDOR_ID_SIS_TOUCH)
> hdev->quirks |= HID_QUIRK_NOGET;
>
> + if (mtclass->quirks & MT_CLS_REGISTER_LID_NOTIFIER) {
> + lid_notify_hdev = hdev;
> + register_lid_notifier(&mt_lid_notifier_block);
> + }
> +
> ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
> if (ret)
> return ret;
> @@ -2150,6 +2176,10 @@ static const struct hid_device_id mt_devices[] = {
> HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8,
> USB_VENDOR_ID_ELAN, 0x32ae) },
>
> + { .driver_data = MT_CLS_REGISTER_LID_NOTIFIER,
> + HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8,
> + USB_VENDOR_ID_ELAN, 0x323b) },
The need to have special handling of LID events is a quirk of board
design, not quire of a controller. So I think it needs to be triggered
by DMI quirk.
> +
> /* Elitegroup panel */
> { .driver_data = MT_CLS_SERIAL,
> MT_USB_DEVICE(USB_VENDOR_ID_ELITEGROUP,
>
Thanks.
--
Dmitry
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v2 1/2] Input: Add lid switch notifier
2025-11-11 22:34 ` Dmitry Torokhov
@ 2025-11-12 23:45 ` Jonathan Denose
0 siblings, 0 replies; 10+ messages in thread
From: Jonathan Denose @ 2025-11-12 23:45 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: Jiri Kosina, Benjamin Tissoires, linux-input, linux-kernel
Hi Dmitry,
Thanks for your review.
On Tue, Nov 11, 2025 at 4:34 PM Dmitry Torokhov
<dmitry.torokhov@gmail.com> wrote:
>
> Hi Jonathan,
>
> On Tue, Nov 11, 2025 at 09:34:06PM +0000, Jonathan Denose wrote:
> > This change creates a new input handler which can be included in the
> > build via a new Kconfig option CONFIG_INPUT_LID_NOTIFIER. This input
> > handler listens for lid switch events and publishes them through an
> > atomic notification chain. Other modules may register for events
> > through this notification chain with register_lid_notifier.
> >
> > Signed-off-by: Jonathan Denose <jdenose@google.com>
> > ---
> > drivers/input/Kconfig | 11 +++++
> > drivers/input/Makefile | 1 +
> > drivers/input/lid-notifier.c | 98 ++++++++++++++++++++++++++++++++++++++++++++
> > include/linux/input.h | 2 +
> > 4 files changed, 112 insertions(+)
> >
> > diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig
> > index 88ecdf5218ee9ba35e1efec6341f8605b621bd49..16f6d24fd04ac8cb5af9d36cc47155ea9be0e177 100644
> > --- a/drivers/input/Kconfig
> > +++ b/drivers/input/Kconfig
> > @@ -38,6 +38,17 @@ config INPUT_LEDS
> > To compile this driver as a module, choose M here: the
> > module will be called input-leds.
> >
> > +config INPUT_LID_NOTIFIER
> > + tristate "Include notifier for lid switch events"
> > + help
> > + Say Y here if you would like to create a notifier to publish lid switch
> > + events.
> > +
> > + If unsure, say N.
> > +
> > + To compile this driver as a module, choose M here: the
> > + module will be called lid-notifier.
>
> I think this better not surfaced to users but rather interested drivers
> 'select' it.
That makes sense to me, but how could I get the lid-notifier.c file to
compile in that case? That was my only reason for adding it as a
config option.
> > +
> > config INPUT_FF_MEMLESS
> > tristate "Support for memoryless force-feedback devices"
> > help
> > diff --git a/drivers/input/Makefile b/drivers/input/Makefile
> > index 2cd6e1c9a77844fe09cd3d99533e5d3efb038c7d..1efdba04f79a97e2a122b9198341b18a1855b4b9 100644
> > --- a/drivers/input/Makefile
> > +++ b/drivers/input/Makefile
> > @@ -15,6 +15,7 @@ obj-$(CONFIG_INPUT_MATRIXKMAP) += matrix-keymap.o
> > obj-$(CONFIG_INPUT_VIVALDIFMAP) += vivaldi-fmap.o
> >
> > obj-$(CONFIG_INPUT_LEDS) += input-leds.o
> > +obj-$(CONFIG_INPUT_LID_NOTIFIER) += lid-notifier.o
> > obj-$(CONFIG_INPUT_MOUSEDEV) += mousedev.o
> > obj-$(CONFIG_INPUT_JOYDEV) += joydev.o
> > obj-$(CONFIG_INPUT_EVDEV) += evdev.o
> > diff --git a/drivers/input/lid-notifier.c b/drivers/input/lid-notifier.c
> > new file mode 100644
> > index 0000000000000000000000000000000000000000..954b9855532dbd0514860e309d0b76982e947673
> > --- /dev/null
> > +++ b/drivers/input/lid-notifier.c
> > @@ -0,0 +1,98 @@
> > +// SPDX-License-Identifier: GPL-2.0-or-later
> > +/*
> > + * Lid event notifier
> > + *
> > + * Copyright (c) 2025 Jonathan Denose <jdenose@google.com>
> > + */
> > +
> > +#include <linux/device.h>
> > +#include <linux/input.h>
> > +#include <linux/notifier.h>
> > +
> > +static struct input_handler lid_handler;
> > +static struct atomic_notifier_head input_notifier_head;
> > +
> > +int register_lid_notifier(struct notifier_block *notifier)
> > +{
> > + return atomic_notifier_chain_register(&input_notifier_head, notifier);
> > +}
> > +EXPORT_SYMBOL(register_lid_notifier);
>
> I wonder if we want to expose the "raw" notifier or if we want to
> provide a higher-level API that would allocate a notifier blocki, set up
> the callback, and return a "cookie" that can be used to free notifier
> block later. This way we do not need to worry that some enterprising
> driver suppresses notifications for the rest by returning NOTIFY_STOP.
>
> > +
> > +static int lid_handler_connect(struct input_handler *handler,
> > + struct input_dev *input_dev, const struct input_device_id *id)
>
> Proper alignment of the arguments please.
>
> > +{
> > + struct input_handle *handle;
> > + int error;
> > +
> > + handle = devm_kzalloc(&input_dev->dev, sizeof(struct input_handle), GFP_KERNEL);
>
> This is not driver probe path so devm_kzalloc must not be used here.
> Also "sizeof(*handle)".
So in that case, would I just use kzalloc?
> > + if (!handle)
> > + return -ENOMEM;
> > +
> > + handle->dev = input_dev;
> > + handle->handler = handler;
> > + handle->name = "lid";
> > +
> > + error = input_register_handle(handle);
> > + if (error)
> > + goto err_free_handle;
> > +
> > + error = input_open_device(handle);
> > + if (error)
> > + goto err_unregister_handle;
> > +
> > + return 0;
> > +
> > + err_unregister_handle:
> > + input_unregister_handle(handle);
> > + err_free_handle:
> > + kfree(handle);
>
> Just FYI: One must never use kfree() with devm_kalloc()ed memory.
Noted!
> > + return error;
> > +}
> > +
> > +static void lid_handler_disconnect(struct input_handle *handle)
> > +{
> > + input_close_device(handle);
> > + input_unregister_handle(handle);
>
> kfree(handle);
>
> > +}
> > +
> > +static void lid_handler_event(struct input_handle *handle, unsigned int type,
> > + unsigned int code, int value)
> > +{
> > + if (type == EV_SW && code == SW_LID)
> > + atomic_notifier_call_chain(&input_notifier_head, value, handle->dev);
>
> Why do you need to pass the device from which SW_LID originated?
It isn't needed, I'll pass NULL instead.
> > +}
> > +
> > +static const struct input_device_id lid_handler_ids[] = {
> > + {
> > + .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_SWBIT
> > + | INPUT_DEVICE_ID_MATCH_BUS,
> > + .evbit = { BIT_MASK(EV_SW) },
> > + .swbit = { [BIT_WORD(SW_LID)] = BIT_MASK(SW_LID) },
> > + .bustype = 0x19
>
> Why do we need to match in bus type? The LID does not have to always
> come from ACPI.
On the specific chromebook where this touchpad is found, when the lid
switch is opened or closed, `cros_ec_buttons` also sends SW_LID
events, so lid_handler_event was unnecessarily called twice. To
prevent that, I'm filtering on the bus type to get only the events
originating from the lid switch.
> > + },
> > + { },
> > +};
> > +
> > +static struct input_handler lid_handler = {
> > + .connect = lid_handler_connect,
> > + .disconnect = lid_handler_disconnect,
> > + .event = lid_handler_event,
> > + .name = "lid",
> > + .id_table = lid_handler_ids
> > +};
> > +
> > +static int __init lid_notifier_init(void)
> > +{
> > + return input_register_handler(&lid_handler);
> > +}
> > +module_init(lid_notifier_init);
> > +
> > +static void __exit lid_notifier_exit(void)
> > +{
> > + input_unregister_handler(&lid_handler);
> > +}
> > +module_exit(lid_notifier_exit);
> > +
> > +MODULE_AUTHOR("Jonathan Denose <jdenose@google.com>");
> > +MODULE_DESCRIPTION("Lid event notifier");
> > +MODULE_LICENSE("GPL");
> > diff --git a/include/linux/input.h b/include/linux/input.h
> > index 7d7cb0593a63e93c4906c49cde430188db2d1ab5..023eb92c77d9e8721d482b9787632a671671de08 100644
> > --- a/include/linux/input.h
> > +++ b/include/linux/input.h
> > @@ -592,3 +592,5 @@ int input_ff_create_memless(struct input_dev *dev, void *data,
> > int (*play_effect)(struct input_dev *, void *, struct ff_effect *));
> >
> > #endif
>
> I think this should go into include/linux/lid-notifier.h.
>
> > +
> > +int register_lid_notifier(struct notifier_block *notifier);
>
> Thanks.
>
> --
> Dmitry
--
Jonathan
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v2 2/2] HID: multitouch: Toggle touch surface on Elan touchpad on lid event
2025-11-11 22:37 ` Dmitry Torokhov
@ 2025-11-12 23:49 ` Jonathan Denose
2025-11-18 7:12 ` Dmitry Torokhov
0 siblings, 1 reply; 10+ messages in thread
From: Jonathan Denose @ 2025-11-12 23:49 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: Jiri Kosina, Benjamin Tissoires, linux-input, linux-kernel
Hi Dmitry,
Thanks for your review.
On Tue, Nov 11, 2025 at 4:37 PM Dmitry Torokhov
<dmitry.torokhov@gmail.com> wrote:
>
> Hi Jonathan,
>
> On Tue, Nov 11, 2025 at 09:34:07PM +0000, Jonathan Denose wrote:
> > Many touchpad modules have a pin which is expected to be connected to the
> > lid angle sensor in laptops. The pin sends a signal to the touchpad module
> > about the lid state and each touchpad vendor handles this notification in
> > their firmware.
> >
> > The Elan touchpad with VID 323b does not always have this aforementioned
> > pin, which then causes interference between the lid and the touchpad when
> > the lid is closed. This interference causes a few seconds delay before the
> > touchpad works again, or it causes it to be come completely unresponsive.
> > To circumvent this hardware issue in software, implement a device quirk
> > which will allow the hid-multitouch driver to register a notifier_block
> > to listen for lid switch events. When the lid switch closes, the
> > touchpad surface will be turned off and when the lid switch opens, the
> > touchpad surgace will be turned on. This triggers recalibration which
> > resolves interference issues when the lid is closed.
> >
> > Signed-off-by: Jonathan Denose <jdenose@google.com>
> > ---
> > drivers/hid/hid-multitouch.c | 32 +++++++++++++++++++++++++++++++-
> > 1 file changed, 31 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
> > index 2879e65cf303b1456311ac06115adda5a78a2600..9a89913c193bc110a0a821a901aebd97892c66bd 100644
> > --- a/drivers/hid/hid-multitouch.c
> > +++ b/drivers/hid/hid-multitouch.c
> > @@ -35,6 +35,7 @@
> > #include <linux/device.h>
> > #include <linux/hid.h>
> > #include <linux/module.h>
> > +#include <linux/notifier.h>
> > #include <linux/slab.h>
> > #include <linux/input/mt.h>
> > #include <linux/jiffies.h>
> > @@ -76,6 +77,7 @@ MODULE_LICENSE("GPL");
> > #define MT_QUIRK_DISABLE_WAKEUP BIT(21)
> > #define MT_QUIRK_ORIENTATION_INVERT BIT(22)
> > #define MT_QUIRK_APPLE_TOUCHBAR BIT(23)
> > +#define MT_QUIRK_REGISTER_LID_NOTIFIER BIT(24)
> >
> > #define MT_INPUTMODE_TOUCHSCREEN 0x02
> > #define MT_INPUTMODE_TOUCHPAD 0x03
> > @@ -183,6 +185,8 @@ struct mt_device {
> > struct list_head reports;
> > };
> >
> > +static struct hid_device *lid_notify_hdev;
>
> This should really be per-device.
Just to be sure I'm following correctly, the initialization of
lid_notify_hdev should be per-device?
> > +
> > static void mt_post_parse_default_settings(struct mt_device *td,
> > struct mt_application *app);
> > static void mt_post_parse(struct mt_device *td, struct mt_application *app);
> > @@ -227,6 +231,7 @@ static void mt_post_parse(struct mt_device *td, struct mt_application *app);
> > #define MT_CLS_SMART_TECH 0x0113
> > #define MT_CLS_APPLE_TOUCHBAR 0x0114
> > #define MT_CLS_SIS 0x0457
> > +#define MT_CLS_REGISTER_LID_NOTIFIER 0x0115
> >
> > #define MT_DEFAULT_MAXCONTACT 10
> > #define MT_MAX_MAXCONTACT 250
> > @@ -327,7 +332,9 @@ static const struct mt_class mt_classes[] = {
> > MT_QUIRK_CONTACT_CNT_ACCURATE |
> > MT_QUIRK_WIN8_PTP_BUTTONS,
> > .export_all_inputs = true },
> > -
> > + { .name = MT_CLS_REGISTER_LID_NOTIFIER,
> > + .quirks = MT_QUIRK_REGISTER_LID_NOTIFIER,
> > + .export_all_inputs = true },
> > /*
> > * vendor specific classes
> > */
> > @@ -1840,6 +1847,20 @@ static void mt_expired_timeout(struct timer_list *t)
> > clear_bit_unlock(MT_IO_FLAGS_RUNNING, &td->mt_io_flags);
> > }
> >
> > +static int mt_input_notifier(struct notifier_block *nb, unsigned long action, void *dev)
> > +{
> > + if (action)
> > + mt_set_modes(lid_notify_hdev, HID_LATENCY_NORMAL, TOUCHPAD_REPORT_NONE);
> > + else if (!action)
> > + mt_set_modes(lid_notify_hdev, HID_LATENCY_NORMAL, TOUCHPAD_REPORT_ALL);
> > +
> > + return 0;
> > +}
> > +
> > +static struct notifier_block mt_lid_notifier_block = {
> > + .notifier_call = mt_input_notifier
> > +};
> > +
> > static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
> > {
> > int ret, i;
> > @@ -1920,6 +1941,11 @@ static int mt_probe(struct hid_device *hdev, const struct hid_device_id *id)
> > if (hdev->vendor == USB_VENDOR_ID_SIS_TOUCH)
> > hdev->quirks |= HID_QUIRK_NOGET;
> >
> > + if (mtclass->quirks & MT_CLS_REGISTER_LID_NOTIFIER) {
> > + lid_notify_hdev = hdev;
> > + register_lid_notifier(&mt_lid_notifier_block);
> > + }
> > +
> > ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT);
> > if (ret)
> > return ret;
> > @@ -2150,6 +2176,10 @@ static const struct hid_device_id mt_devices[] = {
> > HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8,
> > USB_VENDOR_ID_ELAN, 0x32ae) },
> >
> > + { .driver_data = MT_CLS_REGISTER_LID_NOTIFIER,
> > + HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8,
> > + USB_VENDOR_ID_ELAN, 0x323b) },
>
> The need to have special handling of LID events is a quirk of board
> design, not quire of a controller. So I think it needs to be triggered
> by DMI quirk.
> > +
> > /* Elitegroup panel */
> > { .driver_data = MT_CLS_SERIAL,
> > MT_USB_DEVICE(USB_VENDOR_ID_ELITEGROUP,
> >
>
> Thanks.
>
> --
> Dmitry
--
Jonathan
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v2 2/2] HID: multitouch: Toggle touch surface on Elan touchpad on lid event
2025-11-11 21:34 ` [PATCH v2 2/2] HID: multitouch: Toggle touch surface on Elan touchpad on lid event Jonathan Denose
2025-11-11 22:37 ` Dmitry Torokhov
@ 2025-11-13 4:49 ` kernel test robot
2025-11-13 4:49 ` kernel test robot
2 siblings, 0 replies; 10+ messages in thread
From: kernel test robot @ 2025-11-13 4:49 UTC (permalink / raw)
To: Jonathan Denose, Dmitry Torokhov, Jiri Kosina, Benjamin Tissoires
Cc: oe-kbuild-all, linux-input, linux-kernel, Jonathan Denose
Hi Jonathan,
kernel test robot noticed the following build errors:
[auto build test ERROR on 3a8660878839faadb4f1a6dd72c3179c1df56787]
url: https://github.com/intel-lab-lkp/linux/commits/Jonathan-Denose/Input-Add-lid-switch-notifier/20251112-053559
base: 3a8660878839faadb4f1a6dd72c3179c1df56787
patch link: https://lore.kernel.org/r/20251111-lid-switch-notifier-v2-2-789723d78d89%40google.com
patch subject: [PATCH v2 2/2] HID: multitouch: Toggle touch surface on Elan touchpad on lid event
config: parisc-randconfig-002-20251112 (https://download.01.org/0day-ci/archive/20251112/202511122158.oyGRoKNz-lkp@intel.com/config)
compiler: hppa-linux-gcc (GCC) 8.5.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251112/202511122158.oyGRoKNz-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/202511122158.oyGRoKNz-lkp@intel.com/
All errors (new ones prefixed by >>, old ones prefixed by <<):
>> ERROR: modpost: "register_lid_notifier" [drivers/hid/hid-multitouch.ko] undefined!
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v2 2/2] HID: multitouch: Toggle touch surface on Elan touchpad on lid event
2025-11-11 21:34 ` [PATCH v2 2/2] HID: multitouch: Toggle touch surface on Elan touchpad on lid event Jonathan Denose
2025-11-11 22:37 ` Dmitry Torokhov
2025-11-13 4:49 ` kernel test robot
@ 2025-11-13 4:49 ` kernel test robot
2 siblings, 0 replies; 10+ messages in thread
From: kernel test robot @ 2025-11-13 4:49 UTC (permalink / raw)
To: Jonathan Denose, Dmitry Torokhov, Jiri Kosina, Benjamin Tissoires
Cc: oe-kbuild-all, linux-input, linux-kernel, Jonathan Denose
Hi Jonathan,
kernel test robot noticed the following build errors:
[auto build test ERROR on 3a8660878839faadb4f1a6dd72c3179c1df56787]
url: https://github.com/intel-lab-lkp/linux/commits/Jonathan-Denose/Input-Add-lid-switch-notifier/20251112-053559
base: 3a8660878839faadb4f1a6dd72c3179c1df56787
patch link: https://lore.kernel.org/r/20251111-lid-switch-notifier-v2-2-789723d78d89%40google.com
patch subject: [PATCH v2 2/2] HID: multitouch: Toggle touch surface on Elan touchpad on lid event
config: xtensa-randconfig-002-20251112 (https://download.01.org/0day-ci/archive/20251112/202511122329.Sg4foDAx-lkp@intel.com/config)
compiler: xtensa-linux-gcc (GCC) 8.5.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251112/202511122329.Sg4foDAx-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/202511122329.Sg4foDAx-lkp@intel.com/
All errors (new ones prefixed by >>):
arch/xtensa/kernel/entry.o: in function `fast_syscall_spill_registers':
arch/xtensa/kernel/entry.S:1423:(.exception.text+0x21b): dangerous relocation: windowed longcall crosses 1GB boundary; return may fail: make_task_dead
xtensa-linux-ld: drivers/hid/hid-multitouch.o: in function `mt_touch_report.isra.24':
>> drivers/hid/hid-multitouch.c:1319: undefined reference to `register_lid_notifier'
xtensa-linux-ld: drivers/hid/hid-multitouch.o: in function `mt_touch_report.isra.24':
>> include/linux/input.h:512: undefined reference to `register_lid_notifier'
vim +1319 drivers/hid/hid-multitouch.c
2d93666e70662c Benjamin Tissoires 2011-01-11 1256
8dfe14b3b47ff8 Benjamin Tissoires 2018-07-13 1257 static void mt_touch_report(struct hid_device *hid,
8dfe14b3b47ff8 Benjamin Tissoires 2018-07-13 1258 struct mt_report_data *rdata)
55978fa9dc4c57 Benjamin Tissoires 2013-01-31 1259 {
55978fa9dc4c57 Benjamin Tissoires 2013-01-31 1260 struct mt_device *td = hid_get_drvdata(hid);
8dfe14b3b47ff8 Benjamin Tissoires 2018-07-13 1261 struct hid_report *report = rdata->report;
8dfe14b3b47ff8 Benjamin Tissoires 2018-07-13 1262 struct mt_application *app = rdata->application;
55978fa9dc4c57 Benjamin Tissoires 2013-01-31 1263 struct hid_field *field;
01eaac7e57134c Benjamin Tissoires 2018-07-13 1264 struct input_dev *input;
01eaac7e57134c Benjamin Tissoires 2018-07-13 1265 struct mt_usages *slot;
55746d28d66860 Hans de Goede 2017-11-22 1266 bool first_packet;
55978fa9dc4c57 Benjamin Tissoires 2013-01-31 1267 unsigned count;
f146d1c4d7eafd Benjamin Tissoires 2018-07-13 1268 int r, n;
f146d1c4d7eafd Benjamin Tissoires 2018-07-13 1269 int scantime = 0;
f146d1c4d7eafd Benjamin Tissoires 2018-07-13 1270 int contact_count = -1;
5519cab477b613 Benjamin Tissoires 2011-01-07 1271
4f4001bc76fd1a Benjamin Tissoires 2017-06-15 1272 /* sticky fingers release in progress, abort */
be6e2b5734a425 Andri Yngvason 2022-09-07 1273 if (test_and_set_bit_lock(MT_IO_FLAGS_RUNNING, &td->mt_io_flags))
4f4001bc76fd1a Benjamin Tissoires 2017-06-15 1274 return;
4f4001bc76fd1a Benjamin Tissoires 2017-06-15 1275
01eaac7e57134c Benjamin Tissoires 2018-07-13 1276 scantime = *app->scantime;
01eaac7e57134c Benjamin Tissoires 2018-07-13 1277 app->timestamp = mt_compute_timestamp(app, scantime);
01eaac7e57134c Benjamin Tissoires 2018-07-13 1278 if (app->raw_cc != DEFAULT_ZERO)
01eaac7e57134c Benjamin Tissoires 2018-07-13 1279 contact_count = *app->raw_cc;
01eaac7e57134c Benjamin Tissoires 2018-07-13 1280
c2517f62dac608 Benjamin Tissoires 2013-01-31 1281 /*
c2517f62dac608 Benjamin Tissoires 2013-01-31 1282 * Includes multi-packet support where subsequent
c2517f62dac608 Benjamin Tissoires 2013-01-31 1283 * packets are sent with zero contactcount.
c2517f62dac608 Benjamin Tissoires 2013-01-31 1284 */
01eaac7e57134c Benjamin Tissoires 2018-07-13 1285 if (contact_count >= 0) {
af8dc4d0949092 Hans de Goede 2017-11-22 1286 /*
af8dc4d0949092 Hans de Goede 2017-11-22 1287 * For Win8 PTPs the first packet (td->num_received == 0) may
af8dc4d0949092 Hans de Goede 2017-11-22 1288 * have a contactcount of 0 if there only is a button event.
af8dc4d0949092 Hans de Goede 2017-11-22 1289 * We double check that this is not a continuation packet
af8dc4d0949092 Hans de Goede 2017-11-22 1290 * of a possible multi-packet frame be checking that the
af8dc4d0949092 Hans de Goede 2017-11-22 1291 * timestamp has changed.
af8dc4d0949092 Hans de Goede 2017-11-22 1292 */
3ceb3826448d1e Benjamin Tissoires 2018-07-13 1293 if ((app->quirks & MT_QUIRK_WIN8_PTP_BUTTONS) &&
f146d1c4d7eafd Benjamin Tissoires 2018-07-13 1294 app->num_received == 0 &&
f146d1c4d7eafd Benjamin Tissoires 2018-07-13 1295 app->prev_scantime != scantime)
f146d1c4d7eafd Benjamin Tissoires 2018-07-13 1296 app->num_expected = contact_count;
af8dc4d0949092 Hans de Goede 2017-11-22 1297 /* A non 0 contact count always indicates a first packet */
f146d1c4d7eafd Benjamin Tissoires 2018-07-13 1298 else if (contact_count)
f146d1c4d7eafd Benjamin Tissoires 2018-07-13 1299 app->num_expected = contact_count;
7e3cc447ff8906 Benjamin Tissoires 2013-02-06 1300 }
f146d1c4d7eafd Benjamin Tissoires 2018-07-13 1301 app->prev_scantime = scantime;
c2517f62dac608 Benjamin Tissoires 2013-01-31 1302
f146d1c4d7eafd Benjamin Tissoires 2018-07-13 1303 first_packet = app->num_received == 0;
01eaac7e57134c Benjamin Tissoires 2018-07-13 1304
01eaac7e57134c Benjamin Tissoires 2018-07-13 1305 input = report->field[0]->hidinput->input;
01eaac7e57134c Benjamin Tissoires 2018-07-13 1306
01eaac7e57134c Benjamin Tissoires 2018-07-13 1307 list_for_each_entry(slot, &app->mt_usages, list) {
01eaac7e57134c Benjamin Tissoires 2018-07-13 1308 if (!mt_process_slot(td, input, app, slot))
01eaac7e57134c Benjamin Tissoires 2018-07-13 1309 app->num_received++;
01eaac7e57134c Benjamin Tissoires 2018-07-13 1310 }
01eaac7e57134c Benjamin Tissoires 2018-07-13 1311
55978fa9dc4c57 Benjamin Tissoires 2013-01-31 1312 for (r = 0; r < report->maxfield; r++) {
55978fa9dc4c57 Benjamin Tissoires 2013-01-31 1313 field = report->field[r];
55978fa9dc4c57 Benjamin Tissoires 2013-01-31 1314 count = field->report_count;
55978fa9dc4c57 Benjamin Tissoires 2013-01-31 1315
55978fa9dc4c57 Benjamin Tissoires 2013-01-31 1316 if (!(HID_MAIN_ITEM_VARIABLE & field->flags))
55978fa9dc4c57 Benjamin Tissoires 2013-01-31 1317 continue;
55978fa9dc4c57 Benjamin Tissoires 2013-01-31 1318
55978fa9dc4c57 Benjamin Tissoires 2013-01-31 @1319 for (n = 0; n < count; n++)
01eaac7e57134c Benjamin Tissoires 2018-07-13 1320 mt_process_mt_event(hid, app, field,
01eaac7e57134c Benjamin Tissoires 2018-07-13 1321 &field->usage[n], field->value[n],
01eaac7e57134c Benjamin Tissoires 2018-07-13 1322 first_packet);
55978fa9dc4c57 Benjamin Tissoires 2013-01-31 1323 }
5b62efd8250d6a Benjamin Tissoires 2013-02-27 1324
f146d1c4d7eafd Benjamin Tissoires 2018-07-13 1325 if (app->num_received >= app->num_expected)
01eaac7e57134c Benjamin Tissoires 2018-07-13 1326 mt_sync_frame(td, app, input);
4f4001bc76fd1a Benjamin Tissoires 2017-06-15 1327
4f4001bc76fd1a Benjamin Tissoires 2017-06-15 1328 /*
4f4001bc76fd1a Benjamin Tissoires 2017-06-15 1329 * Windows 8 specs says 2 things:
4f4001bc76fd1a Benjamin Tissoires 2017-06-15 1330 * - once a contact has been reported, it has to be reported in each
4f4001bc76fd1a Benjamin Tissoires 2017-06-15 1331 * subsequent report
4f4001bc76fd1a Benjamin Tissoires 2017-06-15 1332 * - the report rate when fingers are present has to be at least
4f4001bc76fd1a Benjamin Tissoires 2017-06-15 1333 * the refresh rate of the screen, 60 or 120 Hz
4f4001bc76fd1a Benjamin Tissoires 2017-06-15 1334 *
4f4001bc76fd1a Benjamin Tissoires 2017-06-15 1335 * I interprete this that the specification forces a report rate of
4f4001bc76fd1a Benjamin Tissoires 2017-06-15 1336 * at least 60 Hz for a touchscreen to be certified.
4f4001bc76fd1a Benjamin Tissoires 2017-06-15 1337 * Which means that if we do not get a report whithin 16 ms, either
4f4001bc76fd1a Benjamin Tissoires 2017-06-15 1338 * something wrong happens, either the touchscreen forgets to send
4f4001bc76fd1a Benjamin Tissoires 2017-06-15 1339 * a release. Taking a reasonable margin allows to remove issues
4f4001bc76fd1a Benjamin Tissoires 2017-06-15 1340 * with USB communication or the load of the machine.
4f4001bc76fd1a Benjamin Tissoires 2017-06-15 1341 *
4f4001bc76fd1a Benjamin Tissoires 2017-06-15 1342 * Given that Win 8 devices are forced to send a release, this will
4f4001bc76fd1a Benjamin Tissoires 2017-06-15 1343 * only affect laggish machines and the ones that have a firmware
4f4001bc76fd1a Benjamin Tissoires 2017-06-15 1344 * defect.
4f4001bc76fd1a Benjamin Tissoires 2017-06-15 1345 */
3ceb3826448d1e Benjamin Tissoires 2018-07-13 1346 if (app->quirks & MT_QUIRK_STICKY_FINGERS) {
9609827458c37d Benjamin Tissoires 2017-06-15 1347 if (test_bit(MT_IO_FLAGS_PENDING_SLOTS, &td->mt_io_flags))
9609827458c37d Benjamin Tissoires 2017-06-15 1348 mod_timer(&td->release_timer,
9609827458c37d Benjamin Tissoires 2017-06-15 1349 jiffies + msecs_to_jiffies(100));
9609827458c37d Benjamin Tissoires 2017-06-15 1350 else
8fa7292fee5c52 Thomas Gleixner 2025-04-05 1351 timer_delete(&td->release_timer);
9609827458c37d Benjamin Tissoires 2017-06-15 1352 }
4f4001bc76fd1a Benjamin Tissoires 2017-06-15 1353
be6e2b5734a425 Andri Yngvason 2022-09-07 1354 clear_bit_unlock(MT_IO_FLAGS_RUNNING, &td->mt_io_flags);
5519cab477b613 Benjamin Tissoires 2011-01-07 1355 }
5519cab477b613 Benjamin Tissoires 2011-01-07 1356
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v2 2/2] HID: multitouch: Toggle touch surface on Elan touchpad on lid event
2025-11-12 23:49 ` Jonathan Denose
@ 2025-11-18 7:12 ` Dmitry Torokhov
0 siblings, 0 replies; 10+ messages in thread
From: Dmitry Torokhov @ 2025-11-18 7:12 UTC (permalink / raw)
To: Jonathan Denose
Cc: Jiri Kosina, Benjamin Tissoires, linux-input, linux-kernel
On Wed, Nov 12, 2025 at 05:49:53PM -0600, Jonathan Denose wrote:
> Hi Dmitry,
>
> Thanks for your review.
>
> On Tue, Nov 11, 2025 at 4:37 PM Dmitry Torokhov
> <dmitry.torokhov@gmail.com> wrote:
> >
> > Hi Jonathan,
> >
> > On Tue, Nov 11, 2025 at 09:34:07PM +0000, Jonathan Denose wrote:
> > > Many touchpad modules have a pin which is expected to be connected to the
> > > lid angle sensor in laptops. The pin sends a signal to the touchpad module
> > > about the lid state and each touchpad vendor handles this notification in
> > > their firmware.
> > >
> > > The Elan touchpad with VID 323b does not always have this aforementioned
> > > pin, which then causes interference between the lid and the touchpad when
> > > the lid is closed. This interference causes a few seconds delay before the
> > > touchpad works again, or it causes it to be come completely unresponsive.
> > > To circumvent this hardware issue in software, implement a device quirk
> > > which will allow the hid-multitouch driver to register a notifier_block
> > > to listen for lid switch events. When the lid switch closes, the
> > > touchpad surface will be turned off and when the lid switch opens, the
> > > touchpad surgace will be turned on. This triggers recalibration which
> > > resolves interference issues when the lid is closed.
> > >
> > > Signed-off-by: Jonathan Denose <jdenose@google.com>
> > > ---
> > > drivers/hid/hid-multitouch.c | 32 +++++++++++++++++++++++++++++++-
> > > 1 file changed, 31 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
> > > index 2879e65cf303b1456311ac06115adda5a78a2600..9a89913c193bc110a0a821a901aebd97892c66bd 100644
> > > --- a/drivers/hid/hid-multitouch.c
> > > +++ b/drivers/hid/hid-multitouch.c
> > > @@ -35,6 +35,7 @@
> > > #include <linux/device.h>
> > > #include <linux/hid.h>
> > > #include <linux/module.h>
> > > +#include <linux/notifier.h>
> > > #include <linux/slab.h>
> > > #include <linux/input/mt.h>
> > > #include <linux/jiffies.h>
> > > @@ -76,6 +77,7 @@ MODULE_LICENSE("GPL");
> > > #define MT_QUIRK_DISABLE_WAKEUP BIT(21)
> > > #define MT_QUIRK_ORIENTATION_INVERT BIT(22)
> > > #define MT_QUIRK_APPLE_TOUCHBAR BIT(23)
> > > +#define MT_QUIRK_REGISTER_LID_NOTIFIER BIT(24)
> > >
> > > #define MT_INPUTMODE_TOUCHSCREEN 0x02
> > > #define MT_INPUTMODE_TOUCHPAD 0x03
> > > @@ -183,6 +185,8 @@ struct mt_device {
> > > struct list_head reports;
> > > };
> > >
> > > +static struct hid_device *lid_notify_hdev;
> >
> > This should really be per-device.
>
> Just to be sure I'm following correctly, the initialization of
> lid_notify_hdev should be per-device?
Yes. I believe this is the best practice.
Thanks.
--
Dmitry
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2025-11-18 7:12 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-11 21:34 [PATCH v2 0/2] Implement lid-notifier for lid switch events Jonathan Denose
2025-11-11 21:34 ` [PATCH v2 1/2] Input: Add lid switch notifier Jonathan Denose
2025-11-11 22:34 ` Dmitry Torokhov
2025-11-12 23:45 ` Jonathan Denose
2025-11-11 21:34 ` [PATCH v2 2/2] HID: multitouch: Toggle touch surface on Elan touchpad on lid event Jonathan Denose
2025-11-11 22:37 ` Dmitry Torokhov
2025-11-12 23:49 ` Jonathan Denose
2025-11-18 7:12 ` Dmitry Torokhov
2025-11-13 4:49 ` kernel test robot
2025-11-13 4:49 ` kernel test robot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).