[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <2b377001-7ee8-449c-b107-1c0164fa54f0@leemhuis.info>
Date: Thu, 9 Oct 2025 16:43:58 +0200
From: Thorsten Leemhuis <linux@...mhuis.info>
To: Jonathan Denose <jdenose@...gle.com>, Jiri Kosina <jikos@...nel.org>,
Benjamin Tissoires <bentiss@...nel.org>,
Dmitry Torokhov <dmitry.torokhov@...il.com>, Jonathan Corbet
<corbet@....net>, Henrik Rydberg <rydberg@...math.org>
Cc: linux-input@...r.kernel.org, linux-kernel@...r.kernel.org,
linux-doc@...r.kernel.org, Angela Czubak <aczubak@...gle.com>,
Sean O'Brien <seobrien@...gle.com>
Subject: Re: [PATCH v3 04/11] HID: haptic: introduce hid_haptic_device
On 8/19/25 01:08, Jonathan Denose wrote:
> From: Angela Czubak <aczubak@...gle.com>
>
> Define a new structure that contains simple haptic device configuration
> as well as current state.
> Add functions that recognize auto trigger and manual trigger reports
> as well as save their addresses.
> Verify that the pressure unit is either grams or newtons.
> Mark the input device as a haptic touchpad if the unit is correct and
> the reports are found.
> [...]
> +config HID_HAPTIC
> + tristate "Haptic touchpad support"
> + default n
> + help
> + Support for touchpads with force sensors and haptic actuators instead of a
> + traditional button.
> + Adds extra parsing and FF device for the hid multitouch driver.
> + It can be used for Elan 2703 haptic touchpad.
> +
> + If unsure, say N.
> +
> menu "Special HID drivers"
I suspect this change is related to a build error I ran into today:
MODPOST Module.symvers
ERROR: modpost: "hid_haptic_init" [drivers/hid/hid-multitouch.ko] undefined!
ERROR: modpost: "hid_haptic_pressure_increase" [drivers/hid/hid-multitouch.ko] undefined!
ERROR: modpost: "hid_haptic_check_pressure_unit" [drivers/hid/hid-multitouch.ko] undefined!
ERROR: modpost: "hid_haptic_input_configured" [drivers/hid/hid-multitouch.ko] undefined!
ERROR: modpost: "hid_haptic_input_mapping" [drivers/hid/hid-multitouch.ko] undefined!
ERROR: modpost: "hid_haptic_feature_mapping" [drivers/hid/hid-multitouch.ko] undefined!
ERROR: modpost: "hid_haptic_pressure_reset" [drivers/hid/hid-multitouch.ko] undefined!
make[3]: *** [/home/thl/var/linux.dev/scripts/Makefile.modpost:147: Module.symvers] Error 1
The config where this occurred had this:
CONFIG_HID=y
CONFIG_HID_MULTITOUCH=m
CONFIG_HID_HAPTIC=m
Changing the latter to "CONFIG_HID_HAPTIC=y" fixed the problem for me.
Ciao, Thorsten
> config HID_A4TECH
> diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
> index 10ae5dedbd84708d988ea1f594d409ccebd85ebb..361a7daedeb85454114def8afb5f58caeab58a00 100644
> --- a/drivers/hid/Makefile
> +++ b/drivers/hid/Makefile
> @@ -4,6 +4,7 @@
> #
> hid-y := hid-core.o hid-input.o hid-quirks.o
> hid-$(CONFIG_DEBUG_FS) += hid-debug.o
> +hid-$(CONFIG_HID_HAPTIC) += hid-haptic.o
>
> obj-$(CONFIG_HID_BPF) += bpf/
>
> diff --git a/drivers/hid/hid-haptic.c b/drivers/hid/hid-haptic.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..d659a430c1a6b06ded31d49efe4bded909671cb6
> --- /dev/null
> +++ b/drivers/hid/hid-haptic.c
> @@ -0,0 +1,72 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * HID Haptic support for Linux
> + *
> + * Copyright (c) 2021 Angela Czubak <acz@...ihalf.com>
> + */
> +
> +#include "hid-haptic.h"
> +
> +void hid_haptic_feature_mapping(struct hid_device *hdev,
> + struct hid_haptic_device *haptic,
> + struct hid_field *field, struct hid_usage *usage)
> +{
> + if (usage->hid == HID_HP_AUTOTRIGGER) {
> + if (usage->usage_index >= field->report_count) {
> + dev_err(&hdev->dev,
> + "HID_HP_AUTOTRIGGER out of range\n");
> + return;
> + }
> +
> + hid_device_io_start(hdev);
> + hid_hw_request(hdev, field->report, HID_REQ_GET_REPORT);
> + hid_hw_wait(hdev);
> + hid_device_io_stop(hdev);
> + haptic->default_auto_trigger =
> + field->value[usage->usage_index];
> + haptic->auto_trigger_report = field->report;
> + }
> +}
> +EXPORT_SYMBOL_GPL(hid_haptic_feature_mapping);
> +
> +bool hid_haptic_check_pressure_unit(struct hid_haptic_device *haptic,
> + struct hid_input *hi, struct hid_field *field)
> +{
> + if (field->unit == HID_UNIT_GRAM || field->unit == HID_UNIT_NEWTON)
> + return true;
> + return false;
> +}
> +EXPORT_SYMBOL_GPL(hid_haptic_check_pressure_unit);
> +
> +int hid_haptic_input_mapping(struct hid_device *hdev,
> + struct hid_haptic_device *haptic,
> + struct hid_input *hi,
> + struct hid_field *field, struct hid_usage *usage,
> + unsigned long **bit, int *max)
> +{
> + if (usage->hid == HID_HP_MANUALTRIGGER) {
> + haptic->manual_trigger_report = field->report;
> + /* we don't really want to map these fields */
> + return -1;
> + }
> +
> + return 0;
> +}
> +EXPORT_SYMBOL_GPL(hid_haptic_input_mapping);
> +
> +int hid_haptic_input_configured(struct hid_device *hdev,
> + struct hid_haptic_device *haptic,
> + struct hid_input *hi)
> +{
> +
> + if (hi->application == HID_DG_TOUCHPAD) {
> + if (haptic->auto_trigger_report &&
> + haptic->manual_trigger_report) {
> + __set_bit(INPUT_PROP_HAPTIC_TOUCHPAD, hi->input->propbit);
> + return 1;
> + }
> + return 0;
> + }
> + return -1;
> +}
> +EXPORT_SYMBOL_GPL(hid_haptic_input_configured);
> diff --git a/drivers/hid/hid-haptic.h b/drivers/hid/hid-haptic.h
> new file mode 100644
> index 0000000000000000000000000000000000000000..2e89addf5ec280d5b9a59d06088cc08bd4f445c1
> --- /dev/null
> +++ b/drivers/hid/hid-haptic.h
> @@ -0,0 +1,101 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/*
> + * HID Haptic support for Linux
> + *
> + * Copyright (c) 2021 Angela Czubak <acz@...ihalf.com>
> + */
> +
> +#include <linux/hid.h>
> +
> +#define HID_HAPTIC_ORDINAL_WAVEFORMNONE 1
> +#define HID_HAPTIC_ORDINAL_WAVEFORMSTOP 2
> +
> +#define HID_HAPTIC_MODE_DEVICE 0
> +#define HID_HAPTIC_MODE_HOST 1
> +
> +struct hid_haptic_effect {
> + u8 *report_buf;
> + struct input_dev *input_dev;
> + struct work_struct work;
> + struct list_head control;
> + struct mutex control_mutex;
> +};
> +
> +struct hid_haptic_effect_node {
> + struct list_head node;
> + struct file *file;
> +};
> +
> +struct hid_haptic_device {
> + struct input_dev *input_dev;
> + struct hid_device *hdev;
> + struct hid_report *auto_trigger_report;
> + struct mutex auto_trigger_mutex;
> + struct workqueue_struct *wq;
> + struct hid_report *manual_trigger_report;
> + struct mutex manual_trigger_mutex;
> + size_t manual_trigger_report_len;
> + int pressed_state;
> + s32 pressure_sum;
> + s32 force_logical_minimum;
> + s32 force_physical_minimum;
> + s32 force_resolution;
> + u32 mode;
> + u32 default_auto_trigger;
> + u32 vendor_page;
> + u32 vendor_id;
> + u32 max_waveform_id;
> + u32 max_duration_id;
> + u16 *hid_usage_map;
> + u32 *duration_map;
> + u16 press_ordinal;
> + u16 release_ordinal;
> + struct hid_haptic_effect *effect;
> + struct hid_haptic_effect stop_effect;
> +};
> +
> +#if IS_ENABLED(CONFIG_HID_HAPTIC)
> +void hid_haptic_feature_mapping(struct hid_device *hdev,
> + struct hid_haptic_device *haptic,
> + struct hid_field *field, struct hid_usage
> + *usage);
> +bool hid_haptic_check_pressure_unit(struct hid_haptic_device *haptic,
> + struct hid_input *hi, struct hid_field *field);
> +int hid_haptic_input_mapping(struct hid_device *hdev,
> + struct hid_haptic_device *haptic,
> + struct hid_input *hi,
> + struct hid_field *field, struct hid_usage *usage,
> + unsigned long **bit, int *max);
> +int hid_haptic_input_configured(struct hid_device *hdev,
> + struct hid_haptic_device *haptic,
> + struct hid_input *hi);
> +#else
> +static inline
> +void hid_haptic_feature_mapping(struct hid_device *hdev,
> + struct hid_haptic_device *haptic,
> + struct hid_field *field, struct hid_usage
> + *usage)
> +{}
> +static inline
> +bool hid_haptic_check_pressure_unit(struct hid_haptic_device *haptic,
> + struct hid_input *hi, struct hid_field *field)
> +{
> + return false;
> +}
> +static inline
> +int hid_haptic_input_mapping(struct hid_device *hdev,
> + struct hid_haptic_device *haptic,
> + struct hid_input *hi,
> + struct hid_field *field, struct hid_usage *usage,
> + unsigned long **bit, int *max)
> +{
> + return 0;
> +}
> +static inline
> +int hid_haptic_input_configured(struct hid_device *hdev,
> + struct hid_haptic_device *haptic,
> + struct hid_input *hi)
> +{
> + return 0;
> +}
> +#endif
>
Powered by blists - more mailing lists