* Re: [PATCH v2] HID: multitouch: Fix Yoga Book 9 14IAH10 touchscreen misclassification
From: Jiri Kosina @ 2026-05-12 15:39 UTC (permalink / raw)
To: Dave Carey; +Cc: linux-input, bentiss
In-Reply-To: <20260413125803.46792-1-carvsdriver@gmail.com>
On Mon, 13 Apr 2026, Dave Carey wrote:
> The Lenovo Yoga Book 9 14IAH10 (83KJ) (17EF:6161) firmware includes a
> HID_DG_TOUCHPAD application collection designed for the Windows inbox HID
> driver's Win8 PTP touchpad mode. On Linux the HID_DG_TOUCHSCREEN
> collections provide the correct direct-touch interface. The presence of
> the touchpad collection causes hid-multitouch to misclassify the
> touchscreen nodes as indirect buttonpads, leaving them non-functional.
>
> Within the touchpad collection:
> - HID_UP_BUTTON usages trigger the touchscreen-with-buttons heuristic
> that sets INPUT_MT_POINTER on the touchscreen applications.
> - The HID_DG_TOUCHPAD application itself sets INPUT_MT_POINTER via
> mt_allocate_application(), propagating to all touchscreen nodes.
> - A HID_DG_BUTTONTYPE feature (report 0x51) returns MT_BUTTONTYPE_CLICKPAD,
> setting td->is_buttonpad = true for the entire device.
>
> Additionally, the firmware resets if any USB control request arrives while
> the CDC-ACM interface is initialising (~1.18 s after enumeration).
> The Win8 compliance blob (0xff00:0xc5) and Contact Count Max feature
> reports in the touchscreen collections trigger GET_REPORT calls at probe
> that hit this window. Surface Switch (0x57) and Button Switch (0x58)
> feature reports are sent by mt_set_modes() on every input-device open and
> close, repeatedly hitting this window throughout device lifetime.
>
> The firmware also leaves a persistent ghost contact in its contact buffer
> (contact ID 2, fixed coordinates, tip always asserted) on every enumeration.
> This ghost occupies a multitouch slot and prevents KWin from seeing a clean
> finger-lift, causing stuck touch state. The ghost is cleared when Input
> Mode is set via HID_REQ_SET_REPORT at probe.
Oh man, what a device.
Applied, thanks.
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: [PATCH v3] HID: pulsar: add driver for Pulsar gaming mice
From: Jiri Kosina @ 2026-05-12 15:37 UTC (permalink / raw)
To: Nikolas Koesling
Cc: Benjamin Tissoires, Lode Willems, linux-input, linux-kernel, Leo
In-Reply-To: <20260412075346.100567-1-nikolas@koesling.info>
On Sun, 12 Apr 2026, Nikolas Koesling wrote:
> Add a HID driver for Pulsar wireless gaming mice (X2 V2, X2H, X2A,
> Xlite V3). The driver exposes battery level, voltage, and charging
> status through the power supply framework. It supports wired, 1kHz,
> and 4kHz wireless dongle connections.
>
> The driver also supports Kysona M600 ATK, VXE R1 SE+ and
> VXE Dragonfly R1 Pro, which use the same protocol for reading
> battery status and availability.
>
> The protocol used by this driver is based on findings from
> python-pulsar-mouse-tool by Andrew Rabert (MIT License):
> https://github.com/andrewrabert/python-pulsar-mouse-tool
>
> ATK vendor and device IDs were provided by Leo <leo@managarm.org>.
> VXE and Kysona vendor and device IDS are from hid-kysona.c by
> Lode Willems <me@lodewillems.com>
>
> Tested-by: Leo <leo@managarm.org>
> Signed-off-by: Nikolas Koesling <nikolas@koesling.info>
> ---
> Changes in v2:
> - Add support for Kysona M600, ATK VXE R1 SE+, and VXE Dragonfly R1 Pro
> - Add device type enum to distinguish vendors and generate proper
> battery names per vendor/model
> - Add mutual exclusion with HID_KYSONA in Kconfig
> - Add ATK and VXE vendor/device IDs to hid-ids.h
> - Refactor model name generation: extract model_pulsar() and add
> model_atk() for vendor-specific battery naming
> - Fall back to hdev->name for battery model when device info read
> fails on non-Pulsar devices (downgrade error to debug log)
> - Remove POWER_SUPPLY_PROP_MANUFACTURER property
> - Pass device type via driver_data in hid_device_id table
>
> Changes in v3:
> - Increase size of battery model name to hid device name size
> ---
> MAINTAINERS | 6 +
> drivers/hid/Kconfig | 15 +
> drivers/hid/Makefile | 1 +
> drivers/hid/hid-ids.h | 15 +
> drivers/hid/hid-pulsar.c | 754 +++++++++++++++++++++++++++++++++++++++
> 5 files changed, 791 insertions(+)
> create mode 100644 drivers/hid/hid-pulsar.c
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index c3fe46d7c4bc..207216632918 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -11352,6 +11352,12 @@ L: linux-input@vger.kernel.org
> S: Supported
> F: drivers/hid/hid-playstation.c
>
> +HID PULSAR DRIVER
> +M: Nikolas Koesling <nikolas@koesling.info>
> +L: linux-input@vger.kernel.org
> +S: Maintained
> +F: drivers/hid/hid-pulsar.c
> +
> HID SENSOR HUB DRIVERS
> M: Jiri Kosina <jikos@kernel.org>
> M: Jonathan Cameron <jic23@kernel.org>
> diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
> index c1d9f7c6a5f2..333d165554ee 100644
> --- a/drivers/hid/Kconfig
> +++ b/drivers/hid/Kconfig
> @@ -511,12 +511,15 @@ config HID_KYE
> config HID_KYSONA
> tristate "Kysona devices"
> depends on USB_HID
> + depends on !HID_PULSAR
> help
> Support for Kysona mice.
>
> Say Y here if you have a Kysona M600 mouse
> and want to be able to read its battery capacity.
>
> + Note: The Kysona M600 is also supported by HID_PULSAR.
> +
I guess that we want to just ditch that driver altogether then?
Thanks,
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: [PATCH] HID: magicmouse: enable battery polling for 2024 Magic Trackpad
From: Jiri Kosina @ 2026-05-12 15:36 UTC (permalink / raw)
To: Dmitri Ollari; +Cc: linux-input
In-Reply-To: <20260411163806.35759-1-dmitri.ollari@protonmail.com>
On Sat, 11 Apr 2026, Dmitri Ollari wrote:
> The 2024 Magic Trackpad USB-C (PID 0x0324) does not report battery
> strength via HID descriptor fields over Bluetooth. Instead it requires
> an explicit HID_REQ_GET_REPORT request to retrieve the battery level.
>
> This patch makes the following changes:
>
> 1. Replace the battery_timer (timer_list) with battery_work (delayed_work)
> so that HID_REQ_GET_REPORT can be issued from a sleepable context.
> Timers run in atomic context and cannot block, which caused deadlocks
> on the Bluetooth transport path.
>
> 2. Extend the fetch guard and probe scheduling block to include the 2024
> Magic Trackpad USB-C when connected over Bluetooth (vendor 0x004C,
> product 0x0324 via BT_VENDOR_ID_APPLE).
>
> 3. Schedule battery_work immediately at probe (delay=0) instead of
> issuing a direct magicmouse_fetch_battery() call. The direct call
> bypassed the cold-start correction logic and could publish a stale
> value before the work handler had a chance to validate it.
>
> 4. Add a cold-start
> double-poll: the device may return a stale battery
> value (e.g. 4%) on the very first GET_REPORT after power-on. On the
> first successful poll battery_validated is set and a second poll is
> scheduled 3 seconds later to obtain the real value. Subsequent polls
> use the normal 60-second interval.
>
> 5. Remove the early-return guard that skipped polling when
> battery_capacity equalled battery_max. This prevented the second
> corrective poll from firing when the first stale response happened
> to equal 100.
>
> Signed-off-by: Dmitri Ollari <dmitri.ollari@protonmail.com>
Dmitri,
thanks for the patch.
It has however been badly line-wrapped and whitespace-damaged by your mail
client.
Can you please look into fixing it and resubmit?
Thanks,
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: [PATCH] HID: sony: use input_dev from sc struct in sony_init_ff()
From: Jiri Kosina @ 2026-05-12 15:34 UTC (permalink / raw)
To: Rosalie Wanders; +Cc: Benjamin Tissoires, linux-input, linux-kernel
In-Reply-To: <20260411155347.101760-2-rosalie@mailbox.org>
On Sat, 11 Apr 2026, Rosalie Wanders wrote:
> This commit makes sony_init_ff() use the input_dev from the sc struct,
> this simplifies the sony_init_ff() function.
>
> Signed-off-by: Rosalie Wanders <rosalie@mailbox.org>
Applied, thank you.
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: [PATCH] HID: usbhid: replace strlcat with better alternatives
From: Jiri Kosina @ 2026-05-12 15:33 UTC (permalink / raw)
To: Mahad Ibrahim
Cc: Benjamin Tissoires, linux-usb, linux-input, linux-hardening,
linux-kernel-mentees, Shuah Khan, linux-kernel
In-Reply-To: <20260410192447.7059-1-mahad.ibrahim.dev@gmail.com>
On Fri, 10 Apr 2026, Mahad Ibrahim wrote:
> In preparation for the removal of the strlcat() API as per the KSPP,
> replace the string concatenation logic in hid-core, usbkbd, and
> usbmouse with struct seq_buf, which tracks the current write position
> and remaining space internally. The changes implemented include:
>
> - Replace device name and phys concatenation with seq_buf_puts().
> - Include Struct seq_buf and its initialization.
> - Include header file of seq_buf.
> - Replace strlen() with seq_buf_used() on the string buffer which was
> tracked by seq_buf to increase speed.
> - Add size_t len in files which did not have it.
> - Use of strscpy with length in place of strlcat.
>
> Testing: This driver was compiled as a module as well as in-built in
> QEMU with the QEMU basic mouse, and QEMU basic keyboard. The testing was
> done in the following steps.
> - Add Hardware Mouse in QEMU checking the usbhid module.
> - Verify dmesg string name of mouse.
> - Blacklist hidusb module from auto-loading, and removing the module via
> rmmod.
> - Load usbmouse module, and reattach QEMU mouse.
> - Verify dmesg string name of mouse.
> - Repeat same procedure on usbkbd module.
>
> This aligns the driver with KSPP security guidelines.
>
> Link: https://github.com/KSPP/linux/issues/370
>
> Signed-off-by: Mahad Ibrahim <mahad.ibrahim.dev@gmail.com>
Applied, thanks.
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: [PATCH] HID: playstation: Add DualSense Edge extra button support
From: Jiri Kosina @ 2026-05-12 15:30 UTC (permalink / raw)
To: Aaron Webster
Cc: Roderick Colenbrander, Benjamin Tissoires, linux-input,
linux-kernel
In-Reply-To: <20260407044008.40222-1-awebster@gmail.com>
On Mon, 6 Apr 2026, Aaron Webster wrote:
> The DualSense Edge controller (product ID 0x0df2) has four additional
> buttons compared to the standard DualSense: two front function buttons
> (Fn1 and Fn2) and two rear paddles (left and right). These are reported
> in bits 4-7 of buttons[2] in the input report.
>
> Map them to BTN_TRIGGER_HAPPY1 through BTN_TRIGGER_HAPPY4 so that
> userspace applications can use these extra inputs. An is_edge flag
> gates the extra button handling based on the product ID.
>
> Signed-off-by: Aaron Webster <awebster@gmail.com>
> ---
> Tested with a DualSense Edge controller (Hardware: 1000208, Firmware:
> 1000087 type 3, Fw version: 20 131082 6, Sw series: 68, Update version:
> 0213, build date Jul 4 2025) on Debian 13 (trixie) with kernel
> 6.12.74+deb13+1-amd64 (x86_64) via Bluetooth.
Applied, thanks.
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: [PATCH v2] HID: rakk: add support for Rakk Dasig X side buttons
From: Jiri Kosina @ 2026-05-12 15:29 UTC (permalink / raw)
To: Karl Cayme; +Cc: bentiss, linux-input, linux-kernel, linuxhid
In-Reply-To: <20260321124759.608492-1-kcayme@gmail.com>
On Sat, 21 Mar 2026, Karl Cayme wrote:
> The Rakk Dasig X gaming mouse has a faulty HID report descriptor that
> declares USAGE_MAXIMUM=3 (buttons 1-3) while actually sending 5 button
> bits (REPORT_COUNT=5). This causes the kernel to ignore side buttons
> (buttons 4 and 5).
>
> Fix by patching the descriptor to set USAGE_MAXIMUM=5 in the
> report_fixup callback.
>
> The mouse uses Telink vendor ID 0x248a with three product IDs for USB
> direct (0xfb01), wireless dongle (0xfa02), and Bluetooth (0x8266)
> connection modes. All three variants have the same bug at byte offset 17.
>
> Suggested-by: Terry Junge <linuxhid@cosmicgizmosystems.com>
> Signed-off-by: Karl Cayme <kcayme@gmail.com>
> ---
> Hi,
>
> Thanks for the feedback. I updated the patch with your suggestion to
> check PIDs.
Applied, thanks.
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: [RFC PATCH] HID: iota-ups: add driver for LattePanda IOTA UPS
From: Jiri Kosina @ 2026-05-12 15:27 UTC (permalink / raw)
To: Andrew Maney; +Cc: linux-input, benjamin.tissoires
In-Reply-To: <20260316072034.56694-1-andrewmaney05@gmail.com>
On Mon, 16 Mar 2026, Andrew Maney wrote:
> This driver exposes the DFRobot LattePanda IOTA UPS board as a standard
> power_supply device, allowing desktop environments and power management
> tools such as UPower and systemd-logind to display battery status,
> remaining capacity, and charging status without any special
> configuration. It also enables automatic suspend or shutdown on low
> battery and power profile configuration via any tool that supports the
> standard power_supply interface.
>
> The UPS presents itself as an Arduino Leonardo HID device running custom
> firmware (VID 0x2341, PID 0x8036). It reports status and capacity via
> HID reports 0x07 and 0x0C respectively.
>
> The charge limit (80% or 100%) is configured via a physical DIP switch
> on the UPS board and cannot be detected automatically. Userspace can
> inform the driver of the configured limit via
> charge_control_end_threshold.
>
> Known issue: the driver occasionally reports 0% capacity briefly on
> initial load before the first valid HID report is received. I am
> investigating the cause.
>
> Signed-off-by: Andrew Maney <andrewmaney05@gmail.com>
> ---
> iota-ups.c | 355 +++++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 355 insertions(+)
> create mode 100644 iota-ups.c
>
> diff --git a/iota-ups.c b/iota-ups.c
> new file mode 100644
> index 0000000..df334b2
> --- /dev/null
> +++ b/iota-ups.c
You seem to have generated this patch in a strange way, so that it can't
be applied on top of the tree (i.e. in a standard 'patch -p1' way that
all the tools default to).
Could you please re-generate it properly and resend?
Thanks,
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: [PATCH] HID: quirks: really enable the intended work around for appledisplay
From: Jiri Kosina @ 2026-05-12 15:24 UTC (permalink / raw)
To: Lukas Bulwahn
Cc: Benjamin Tissoires, René Rebe, linux-input, kernel-janitors,
linux-kernel, Lukas Bulwahn
In-Reply-To: <20260205081131.426899-1-lukas.bulwahn@redhat.com>
On Thu, 5 Feb 2026, Lukas Bulwahn wrote:
> From: Lukas Bulwahn <lukas.bulwahn@redhat.com>
>
> Commit c7fabe4ad921 ("HID: quirks: work around VID/PID conflict for
> appledisplay") intends to add a quirk for kernels built with Apple Cinema
> Display support, but it refers to the non-existing config option
> CONFIG_APPLEDISPLAY, whereas the config option for Apple Cinema Display
> support is named CONFIG_USB_APPLEDISPLAY.
>
> Refer to the intended config option CONFIG_USB_APPLEDISPLAY in the ifdef
> directive.
>
> Fixes: c7fabe4ad921 ("HID: quirks: work around VID/PID conflict for appledisplay")
> Signed-off-by: Lukas Bulwahn <lukas.bulwahn@redhat.com>
Applied, thanks Lukas.
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: [RFC] hid: hid-sjoy: race between init and usage
From: Jiri Kosina @ 2026-05-12 15:23 UTC (permalink / raw)
To: Oliver Neukum; +Cc: bentiss, jussi.kivilinna, linux-input
In-Reply-To: <20260303094906.1214359-1-oneukum@suse.com>
On Tue, 3 Mar 2026, Oliver Neukum wrote:
> The driver uses an initial IO to set the device to a default
> state. That initialization is currently being done after the device
> node has been created. That means that the single buffer used
> for output can be altered while IO is in progress.
> Move the intialization before announcement to user space.
>
> Fixes: fac733f029251 ("HID: force feedback support for SmartJoy PLUS PS2/USB adapter")
> Signed-off-by: Oliver Neukum <oneukum@suse.com>
Applied, thanks.
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: [PATCH v3 0/6] iio: hid-sensor: standardize scan_type initialization
From: Jonathan Cameron @ 2026-05-12 14:48 UTC (permalink / raw)
To: Natália Salvino André
Cc: andy, dlechner, jikos, nuno.sa, srinivas.pandruvada, linux-iio,
linux-input, Zhang, Lixu
In-Reply-To: <20260512012302.20883-1-natalia.andre@ime.usp.br>
On Mon, 11 May 2026 22:16:16 -0300
Natália Salvino André <natalia.andre@ime.usp.br> wrote:
> This series refactors the HID sensor drivers to standardize the
> initialization of the iio_chan_spec scan_type structure.
> Direct initialization using compound literals was used.
>
> This change improves code readability and ensures that all fields
> of the scan_type structure are properly zero-initialized.
> Additionally, for the hid-sensor-accel-3d driver, the channel
> initialization loop was refactored to iterate directly over the
> scan indices, eliminating redundant logic.
Series looks good to me but I'll leave it on the list a while to
both let sashiko catch up and anyone else who wants to can have time
to look. Also ideally get some testing.
Lixu, if you don't mind, please can you give this a test on top
of the more radical refactor patches?
To me it looks safe enough but this is the sort of series that subtle
typos can hide in!
Thanks,
Jonathan
>
> Natália Salvino André (6):
> iio: accel: HID: hid-sensor-accel-3d: Refactor channel initialization
> iio: gyro: HID: hid-sensor-gyro-3d: Refactor channel initialization
> iio: light: HID: hid-sensor-als: Refactor channel initialization
> iio: light: HID: hid-sensor-prox: Refactor channel initialization
> iio: magnetometer: HID: hid-sensor-magn-3d: Refactor channel
> initialization
> iio: pressure: HID: hid-sensor-press: Refactor channel initialization
>
> drivers/iio/accel/hid-sensor-accel-3d.c | 27 +++++++------------
> drivers/iio/gyro/hid-sensor-gyro-3d.c | 24 +++++++----------
> drivers/iio/light/hid-sensor-als.c | 18 +++++--------
> drivers/iio/light/hid-sensor-prox.c | 19 +++++--------
> drivers/iio/magnetometer/hid-sensor-magn-3d.c | 20 +++++---------
> drivers/iio/pressure/hid-sensor-press.c | 19 +++++--------
> 6 files changed, 42 insertions(+), 85 deletions(-)
>
^ permalink raw reply
* Re: [PATCH v3 0/6] iio: hid-sensor: standardize scan_type initialization
From: Jonathan Cameron @ 2026-05-12 14:42 UTC (permalink / raw)
To: Natália Salvino André
Cc: andy, dlechner, jikos, nuno.sa, srinivas.pandruvada, linux-iio,
linux-input
In-Reply-To: <20260512012302.20883-1-natalia.andre@ime.usp.br>
On Mon, 11 May 2026 22:16:16 -0300
Natália Salvino André <natalia.andre@ime.usp.br> wrote:
> This series refactors the HID sensor drivers to standardize the
> initialization of the iio_chan_spec scan_type structure.
> Direct initialization using compound literals was used.
>
> This change improves code readability and ensures that all fields
> of the scan_type structure are properly zero-initialized.
> Additionally, for the hid-sensor-accel-3d driver, the channel
> initialization loop was refactored to iterate directly over the
> scan indices, eliminating redundant logic.
Hi Natália,
I'm a little confused. How is this v3? Where is the change log?
I'll review it as a fresh series.
thanks
Jonathan
>
> Natália Salvino André (6):
> iio: accel: HID: hid-sensor-accel-3d: Refactor channel initialization
> iio: gyro: HID: hid-sensor-gyro-3d: Refactor channel initialization
> iio: light: HID: hid-sensor-als: Refactor channel initialization
> iio: light: HID: hid-sensor-prox: Refactor channel initialization
> iio: magnetometer: HID: hid-sensor-magn-3d: Refactor channel
> initialization
> iio: pressure: HID: hid-sensor-press: Refactor channel initialization
>
> drivers/iio/accel/hid-sensor-accel-3d.c | 27 +++++++------------
> drivers/iio/gyro/hid-sensor-gyro-3d.c | 24 +++++++----------
> drivers/iio/light/hid-sensor-als.c | 18 +++++--------
> drivers/iio/light/hid-sensor-prox.c | 19 +++++--------
> drivers/iio/magnetometer/hid-sensor-magn-3d.c | 20 +++++---------
> drivers/iio/pressure/hid-sensor-press.c | 19 +++++--------
> 6 files changed, 42 insertions(+), 85 deletions(-)
>
^ permalink raw reply
* [PATCH] HID: lenovo: Restore Fn-lock LED state on resume for tp10ubkbd devices
From: Kean @ 2026-05-12 14:22 UTC (permalink / raw)
To: derekjohn.clark, mpearson-lenovo
Cc: jikos, bentiss, linux-input, linux-kernel, Kean
The reset_resume callback only restores trackpoint settings for compact
USB keyboards (CUSBKBD, TPIIUSBKBD) but omits the tp10ubkbd device
family: X12_TAB, X12_TAB2, TP10UBKBD, X1_TAB, X1_TAB2, X1_TAB3.
If these devices lose power during suspend, the Fn-lock state reverts
to the hardware default but the driver's cached state and the keyboard
LED are not restored, causing the LED to show the wrong state after
resume.
Add the missing device cases to restore the Fn-lock LED on resume.
Tested:
This patch works on ThinkPad X12_TAB.
Signed-off-by: Kean <rh_king@163.com>
---
drivers/hid/hid-lenovo.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/drivers/hid/hid-lenovo.c b/drivers/hid/hid-lenovo.c
index a6b73e03c16b..4c9fb163b6d6 100644
--- a/drivers/hid/hid-lenovo.c
+++ b/drivers/hid/hid-lenovo.c
@@ -1424,6 +1424,8 @@ static int lenovo_probe(struct hid_device *hdev,
static int lenovo_reset_resume(struct hid_device *hdev)
{
+ struct lenovo_drvdata *data;
+
switch (hdev->product) {
case USB_DEVICE_ID_LENOVO_CUSBKBD:
case USB_DEVICE_ID_LENOVO_TPIIUSBKBD:
@@ -1431,6 +1433,17 @@ static int lenovo_reset_resume(struct hid_device *hdev)
lenovo_features_set_cptkbd(hdev);
break;
+ case USB_DEVICE_ID_LENOVO_X12_TAB:
+ case USB_DEVICE_ID_LENOVO_X12_TAB2:
+ case USB_DEVICE_ID_LENOVO_TP10UBKBD:
+ case USB_DEVICE_ID_LENOVO_X1_TAB:
+ case USB_DEVICE_ID_LENOVO_X1_TAB2:
+ case USB_DEVICE_ID_LENOVO_X1_TAB3:
+ data = hid_get_drvdata(hdev);
+ if (data)
+ lenovo_led_set_tp10ubkbd(hdev, TP10UBKBD_FN_LOCK_LED,
+ data->fn_lock ? LED_ON : LED_OFF);
+ break;
default:
break;
}
--
2.53.0
^ permalink raw reply related
* Re: [PATCH v2 1/1] HID: magicmouse: Prevent out-of-bounds (OOB) read during DOUBLE_REPORT_ID
From: Lee Jones @ 2026-05-12 14:12 UTC (permalink / raw)
To: Günther Noack
Cc: Jiri Kosina, Benjamin Tissoires, linux-input, linux-kernel
In-Reply-To: <20260430140148.GJ1806155@google.com>
On Thu, 30 Apr 2026, Lee Jones wrote:
> On Thu, 16 Apr 2026, Günther Noack wrote:
>
> > On Thu, Apr 16, 2026 at 02:16:54PM +0100, Lee Jones wrote:
> > > It is currently possible for a malicious or misconfigured USB device to
> > > cause an out-of-bounds (OOB) read when submitting reports using
> > > DOUBLE_REPORT_ID by specifying a large report length and providing a
> > > smaller one.
> > >
> > > Let's prevent that by comparing the specified report length with the
> > > actual size of the data read in from userspace. If the actual data
> > > length ends up being smaller than specified, we'll politely warn the
> > > user and prevent any further processing.
> > >
> > > Signed-off-by: Lee Jones <lee@kernel.org>
> > > ---
> > > v1 => v2: Add more size checks to protect against issues during recursion
> > >
> > > drivers/hid/hid-magicmouse.c | 16 ++++++++++++++++
> > > 1 file changed, 16 insertions(+)
> > >
> > > diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c
> > > index 91f621ceb924..e84e6b21d113 100644
> > > --- a/drivers/hid/hid-magicmouse.c
> > > +++ b/drivers/hid/hid-magicmouse.c
> > > @@ -390,6 +390,10 @@ static int magicmouse_raw_event(struct hid_device *hdev,
> > > struct input_dev *input = msc->input;
> > > int x = 0, y = 0, ii, clicks = 0, npoints;
> > >
> > > + /* Protect against zero sized recursive calls from DOUBLE_REPORT_ID */
> > > + if (size < 1)
> > > + return 0;
> > > +
> > > switch (data[0]) {
> > > case TRACKPAD_REPORT_ID:
> > > case TRACKPAD2_BT_REPORT_ID:
> > > @@ -490,6 +494,18 @@ static int magicmouse_raw_event(struct hid_device *hdev,
> > > /* Sometimes the trackpad sends two touch reports in one
> > > * packet.
> > > */
> > > +
> > > + /* Ensure that we have at least 2 elements (report type and size) */
> > > + if (size < 2)
> > > + return 0;
> > > +
> > > + if (size < data[1] + 2) {
> > > + hid_warn(hdev,
> > > + "received report length (%d) was smaller than specified (%d)",
> > > + size, data[1] + 2);
> > > + return 0;
> > > + }
> > > +
> > > magicmouse_raw_event(hdev, report, data + 2, data[1]);
> > > magicmouse_raw_event(hdev, report, data + 2 + data[1],
> > > size - 2 - data[1]);
> > > --
> > > 2.54.0.rc1.513.gad8abe7a5a-goog
> > >
> >
> > Thank you! This looks correct now.
> >
> > Reviewed-by: Günther Noack <gnoack@google.com>
>
> Contentless ping. =:-)
Biweekly ping on this please - if you'd prefer a [RESEND], let me know.
--
Lee Jones
^ permalink raw reply
* [PATCH] HID: logitech-hidpp: Add support for newer Bluetooth keyboards
From: Alain Michaud @ 2026-05-12 13:22 UTC (permalink / raw)
To: jikos, bentiss
Cc: lains, hadess, ogay, linux-input, linux-kernel, Alain Michaud
Add product IDs (PIDs) for several newer Logitech Bluetooth keyboards
to the hidpp_devices matching table, enabling full HID++ support for
them.
The added keyboards are:
- Logitech Signature K650 & B2B
- Logitech Pebble Keys 2 K380S
- Logitech Casa Pop-Up Desk & B2B
- Logitech Wave Keys & B2B
- Logitech Signature Slim K950 & B2B
- Logitech MX Keys S & B2B
- Logitech Keys-To-Go 2
- Logitech Pop Icon Keys
- Logitech MX Keys Mini & B2B
- Logitech Signature Slim Solar+ K980 B2B
- Logitech Bluetooth Keyboard K250/K251
- Logitech Signature Comfort K880 & B2B
Signed-off-by: Alain Michaud <alainmichaud@google.com>
Reviewed-by: Olivier Gay <ogay@logitech.com>
---
drivers/hid/hid-logitech-hidpp.c | 38 ++++++++++++++++++++++++++++++++
1 file changed, 38 insertions(+)
diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c
index b1330d23bd2d..b740dcd60b2f 100644
--- a/drivers/hid/hid-logitech-hidpp.c
+++ b/drivers/hid/hid-logitech-hidpp.c
@@ -4685,6 +4685,44 @@ static const struct hid_device_id hidpp_devices[] = {
HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb391) },
{ /* MX Master 4 mouse over Bluetooth */
HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb042) },
+ { /* Logitech Signature K650 over Bluetooth */
+ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb36f) },
+ { /* Logitech Signature K650 B2B over Bluetooth */
+ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb370) },
+ { /* Logitech Pebble Keys 2 K380S over Bluetooth */
+ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb377) },
+ { /* Logitech Casa Pop-Up Desk over Bluetooth */
+ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb371) },
+ { /* Logitech Casa Pop-Up Desk B2B over Bluetooth */
+ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb374) },
+ { /* Logitech Wave Keys over Bluetooth */
+ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb383) },
+ { /* Logitech Wave Keys B2B over Bluetooth */
+ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb384) },
+ { /* Logitech Signature Slim K950 over Bluetooth */
+ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb386) },
+ { /* Logitech Signature Slim K950 B2B over Bluetooth */
+ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb388) },
+ { /* Logitech MX Keys S over Bluetooth */
+ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb378) },
+ { /* Logitech MX Keys S B2B over Bluetooth */
+ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb380) },
+ { /* Logitech Keys-To-Go 2 over Bluetooth */
+ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb38c) },
+ { /* Logitech Pop Icon Keys over Bluetooth */
+ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb38f) },
+ { /* Logitech MX Keys Mini over Bluetooth */
+ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb369) },
+ { /* Logitech MX Keys Mini B2B over Bluetooth */
+ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb36e) },
+ { /* Logitech Signature Slim Solar+ K980 B2B over Bluetooth */
+ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb394) },
+ { /* Logitech Bluetooth Keyboard K250/K251 over Bluetooth */
+ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb397) },
+ { /* Logitech Signature Comfort K880 over Bluetooth */
+ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb39c) },
+ { /* Logitech Signature Comfort K880 B2B over Bluetooth */
+ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, 0xb39d) },
{}
};
--
2.54.0.563.g4f69b47b94-goog
^ permalink raw reply related
* Re: [PATCH v5 3/6] dt-bindings: mfd: motorola-cpcap: convert to DT schema
From: Svyatoslav Ryhel @ 2026-05-12 13:00 UTC (permalink / raw)
To: Rob Herring
Cc: Dmitry Torokhov, Krzysztof Kozlowski, Conor Dooley, Lee Jones,
Pavel Machek, David Lechner, Tony Lindgren, linux-input,
devicetree, linux-kernel, linux-leds
In-Reply-To: <20260512125309.GA1476682-robh@kernel.org>
вт, 12 трав. 2026 р. о 15:53 Rob Herring <robh@kernel.org> пише:
>
> On Sun, May 10, 2026 at 02:08:01PM +0300, Svyatoslav Ryhel wrote:
> > Convert devicetree bindings for the Motorola CPCAP MFD from TXT to YAML.
> >
> > Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
> > Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
> > ---
> > .../bindings/mfd/motorola,cpcap.yaml | 414 ++++++++++++++++++
> > .../bindings/mfd/motorola-cpcap.txt | 78 ----
> > 2 files changed, 414 insertions(+), 78 deletions(-)
> > create mode 100644 Documentation/devicetree/bindings/mfd/motorola,cpcap.yaml
> > delete mode 100644 Documentation/devicetree/bindings/mfd/motorola-cpcap.txt
> >
> > diff --git a/Documentation/devicetree/bindings/mfd/motorola,cpcap.yaml b/Documentation/devicetree/bindings/mfd/motorola,cpcap.yaml
> > new file mode 100644
> > index 000000000000..7f257f3a1a5a
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/mfd/motorola,cpcap.yaml
> > @@ -0,0 +1,414 @@
> > +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/mfd/motorola,cpcap.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: Motorola CPCAP PMIC MFD
> > +
> > +maintainers:
> > + - Svyatoslav Ryhel <clamor95@gmail.com>
> > +
> > +allOf:
> > + - $ref: /schemas/spi/spi-peripheral-props.yaml#
> > +
> > +properties:
> > + compatible:
> > + items:
> > + - const: motorola,cpcap
> > + - const: st,6556002
> > +
> > + reg:
> > + maxItems: 1
> > +
> > + interrupts:
> > + maxItems: 1
> > +
> > + interrupt-controller: true
> > +
> > + "#interrupt-cells":
> > + const: 2
> > +
> > + "#address-cells":
> > + const: 1
> > +
> > + "#size-cells":
> > + const: 0
>
> There aren't any child nodes with an address. These 2 can be dropped.
>
I will adjust in v6 if there will be need in one.
> > +
> > + spi-max-frequency:
> > + maximum: 9600000
> > +
> > + spi-cs-high: true
> > + spi-cpol: true
> > + spi-cpha: true
> > +
> > + adc:
> > + $ref: /schemas/iio/adc/motorola,cpcap-adc.yaml#
> > +
> > + audio-codec:
> > + type: object
> > + additionalProperties: false
> > +
> > + properties:
> > + interrupts:
> > + items:
> > + - description: headset detect interrupt
> > + - description: microphone bias 2 detect interrupt
> > +
> > + interrupt-names:
> > + items:
> > + - const: hs
> > + - const: mb2
> > +
> > + "#sound-dai-cells":
> > + const: 1
> > +
> > + VAUDIO-supply:
> > + description:
> > + Codec power supply, usually VAUDIO regulator of CPCAP.
> > +
> > + ports:
> > + $ref: /schemas/graph.yaml#/properties/ports
> > +
> > + properties:
> > + port@0:
> > + $ref: /schemas/graph.yaml#/properties/port
> > + description: port connected to the Stereo HiFi DAC
> > +
> > + port@1:
> > + $ref: /schemas/graph.yaml#/properties/port
> > + description: port connected to the Voice DAC
> > +
> > + required:
> > + - port@0
> > + - port@1
> > +
> > + required:
> > + - interrupts
> > + - interrupt-names
> > + - "#sound-dai-cells"
> > +
> > + battery:
> > + $ref: /schemas/power/supply/cpcap-battery.yaml#
> > +
> > + charger:
> > + $ref: /schemas/power/supply/cpcap-charger.yaml#
> > +
> > + key-power:
> > + $ref: /schemas/input/motorola,cpcap-pwrbutton.yaml#
> > +
> > + phy:
> > + $ref: /schemas/phy/motorola,cpcap-usb-phy.yaml#
> > +
> > + regulator:
> > + $ref: /schemas/regulator/motorola,cpcap-regulator.yaml#
> > +
> > + rtc:
> > + $ref: /schemas/rtc/motorola,cpcap-rtc.yaml#
> > +
> > +patternProperties:
> > + "^led(-[a-z]+)?$":
> > + $ref: /schemas/leds/motorola,cpcap-leds.yaml#
> > +
> > +required:
> > + - compatible
> > + - reg
> > + - interrupts
> > + - interrupt-controller
> > + - "#interrupt-cells"
> > + - spi-max-frequency
> > + - "#address-cells"
> > + - "#size-cells"
> > +
> > +additionalProperties: false
> > +
> > +examples:
> > + - |
> > + #include <dt-bindings/gpio/gpio.h>
> > + #include <dt-bindings/interrupt-controller/irq.h>
> > + #include <dt-bindings/input/linux-event-codes.h>
> > +
> > + spi {
> > + #address-cells = <1>;
> > + #size-cells = <0>;
> > +
> > + cpcap: pmic@0 {
> > + compatible = "motorola,cpcap", "st,6556002";
> > + reg = <0>; /* cs0 */
> > +
> > + interrupt-parent = <&gpio1>;
> > + interrupts = <7 IRQ_TYPE_EDGE_RISING>;
> > +
> > + interrupt-controller;
> > + #interrupt-cells = <2>;
> > +
> > + #address-cells = <1>;
> > + #size-cells = <0>;
> > +
> > + spi-max-frequency = <3000000>;
> > + spi-cs-high;
> > +
> > + spi-cpol;
> > + spi-cpha;
> > +
> > + cpcap_adc: adc {
> > + compatible = "motorola,cpcap-adc";
> > +
> > + interrupt-parent = <&cpcap>;
> > + interrupts = <8 IRQ_TYPE_NONE>;
> > + interrupt-names = "adcdone";
> > +
> > + #io-channel-cells = <1>;
> > + };
> > +
> > + cpcap_audio: audio-codec {
> > + interrupt-parent = <&cpcap>;
> > + interrupts = <9 IRQ_TYPE_NONE>, <10 IRQ_TYPE_NONE>;
> > + interrupt-names = "hs", "mb2";
> > +
> > + VAUDIO-supply = <&vdd_audio>;
> > +
> > + #sound-dai-cells = <1>;
> > +
> > + ports {
> > + #address-cells = <1>;
> > + #size-cells = <0>;
> > +
> > + /* HiFi */
> > + port@0 {
> > + reg = <0>;
> > +
> > + cpcap_audio_codec0: endpoint {
> > + };
> > + };
> > +
> > + /* Voice */
> > + port@1 {
> > + reg = <1>;
> > +
> > + cpcap_audio_codec1: endpoint {
> > + };
> > + };
> > + };
> > + };
> > +
> > + cpcap_battery: battery {
> > + compatible = "motorola,cpcap-battery";
> > +
> > + interrupt-parent = <&cpcap>;
> > + interrupts = <6 IRQ_TYPE_NONE>, <5 IRQ_TYPE_NONE>,
> > + <3 IRQ_TYPE_NONE>, <20 IRQ_TYPE_NONE>,
> > + <54 IRQ_TYPE_NONE>, <57 IRQ_TYPE_NONE>;
> > + interrupt-names = "eol", "lowbph", "lowbpl",
> > + "chrgcurr1", "battdetb", "cccal";
> > +
> > + io-channels = <&cpcap_adc 0>, <&cpcap_adc 1>,
> > + <&cpcap_adc 5>, <&cpcap_adc 6>;
> > + io-channel-names = "battdetb", "battp",
> > + "chg_isense", "batti";
> > + power-supplies = <&cpcap_charger>;
> > + };
> > +
> > + cpcap_charger: charger {
> > + compatible = "motorola,mapphone-cpcap-charger";
> > +
> > + interrupt-parent = <&cpcap>;
> > + interrupts = <13 IRQ_TYPE_NONE>, <12 IRQ_TYPE_NONE>,
> > + <29 IRQ_TYPE_NONE>, <28 IRQ_TYPE_NONE>,
> > + <22 IRQ_TYPE_NONE>, <21 IRQ_TYPE_NONE>,
> > + <20 IRQ_TYPE_NONE>, <19 IRQ_TYPE_NONE>,
> > + <54 IRQ_TYPE_NONE>;
> > + interrupt-names = "chrg_det", "rvrs_chrg", "chrg_se1b",
> > + "se0conn", "rvrs_mode", "chrgcurr2",
> > + "chrgcurr1", "vbusvld", "battdetb";
> > +
> > + mode-gpios = <&gpio3 29 GPIO_ACTIVE_LOW>,
> > + <&gpio3 23 GPIO_ACTIVE_LOW>;
> > +
> > + io-channels = <&cpcap_adc 0>, <&cpcap_adc 1>,
> > + <&cpcap_adc 2>, <&cpcap_adc 5>,
> > + <&cpcap_adc 6>;
> > + io-channel-names = "battdetb", "battp",
> > + "vbus", "chg_isense",
> > + "batti";
> > + };
> > +
> > + key-power {
> > + compatible = "motorola,cpcap-pwrbutton";
> > +
> > + interrupt-parent = <&cpcap>;
> > + interrupts = <23 IRQ_TYPE_NONE>;
> > + };
> > +
> > + led-red {
> > + compatible = "motorola,cpcap-led-red";
> > + vdd-supply = <&vdd_led>;
> > + label = "status-led::red";
> > + };
> > +
> > + led-green {
> > + compatible = "motorola,cpcap-led-green";
> > + vdd-supply = <&vdd_led>;
> > + label = "status-led::green";
> > + };
> > +
> > + led-blue {
> > + compatible = "motorola,cpcap-led-blue";
> > + vdd-supply = <&vdd_led>;
> > + label = "status-led::blue";
> > + };
> > +
> > + cpcap_usb2_phy: phy {
> > + compatible = "motorola,cpcap-usb-phy";
> > +
> > + pinctrl-0 = <&usb_gpio_mux_sel1>, <&usb_gpio_mux_sel2>;
> > + pinctrl-1 = <&usb_ulpi_pins>;
> > + pinctrl-2 = <&usb_utmi_pins>;
> > + pinctrl-3 = <&uart3_pins>;
> > + pinctrl-names = "default", "ulpi", "utmi", "uart";
> > + #phy-cells = <0>;
> > +
> > + interrupts-extended =
> > + <&cpcap 15 IRQ_TYPE_NONE>, <&cpcap 14 IRQ_TYPE_NONE>,
> > + <&cpcap 28 IRQ_TYPE_NONE>, <&cpcap 19 IRQ_TYPE_NONE>,
> > + <&cpcap 18 IRQ_TYPE_NONE>, <&cpcap 17 IRQ_TYPE_NONE>,
> > + <&cpcap 16 IRQ_TYPE_NONE>, <&cpcap 49 IRQ_TYPE_NONE>,
> > + <&cpcap 48 IRQ_TYPE_NONE>;
> > + interrupt-names = "id_ground", "id_float", "se0conn",
> > + "vbusvld", "sessvld", "sessend",
> > + "se1", "dm", "dp";
> > +
> > + mode-gpios = <&gpio2 28 GPIO_ACTIVE_HIGH>,
> > + <&gpio1 0 GPIO_ACTIVE_HIGH>;
> > +
> > + io-channels = <&cpcap_adc 2>, <&cpcap_adc 7>;
> > + io-channel-names = "vbus", "id";
> > +
> > + vusb-supply = <&avdd_usb>;
> > + };
> > +
> > + regulator {
> > + compatible = "motorola,cpcap-regulator";
> > +
> > + regulators {
> > + vdd_cpu: SW1 {
> > + regulator-name = "vdd_cpu";
> > + regulator-min-microvolt = <750000>;
> > + regulator-max-microvolt = <1125000>;
> > + regulator-enable-ramp-delay = <1500>;
> > + regulator-always-on;
> > + regulator-boot-on;
> > + };
> > +
> > + vdd_core: SW2 {
> > + regulator-name = "vdd_core";
> > + regulator-min-microvolt = <950000>;
> > + regulator-max-microvolt = <1300000>;
> > + regulator-enable-ramp-delay = <1500>;
> > + regulator-always-on;
> > + regulator-boot-on;
> > + };
> > +
> > + vdd_1v8_vio: SW3 {
> > + regulator-name = "vdd_1v8_vio";
> > + regulator-min-microvolt = <1800000>;
> > + regulator-max-microvolt = <1800000>;
> > + regulator-enable-ramp-delay = <0>;
> > + regulator-always-on;
> > + regulator-boot-on;
> > + };
> > +
> > + vdd_aon: SW4 {
> > + regulator-name = "vdd_aon";
> > + regulator-min-microvolt = <950000>;
> > + regulator-max-microvolt = <1300000>;
> > + regulator-enable-ramp-delay = <1500>;
> > + regulator-always-on;
> > + regulator-boot-on;
> > + };
> > +
> > + vdd_led: SW5 {
> > + regulator-name = "vdd_led";
> > + regulator-min-microvolt = <5050000>;
> > + regulator-max-microvolt = <5050000>;
> > + regulator-enable-ramp-delay = <1500>;
> > + regulator-boot-on;
> > + };
> > +
> > + vdd_hvio: VHVIO {
> > + regulator-name = "vdd_hvio";
> > + regulator-min-microvolt = <2775000>;
> > + regulator-max-microvolt = <2775000>;
> > + regulator-enable-ramp-delay = <1000>;
> > + };
> > +
> > + vcore_emmc: VSDIO {
> > + regulator-name = "vcore_emmc";
> > + regulator-min-microvolt = <1500000>;
> > + regulator-max-microvolt = <3000000>;
> > + regulator-enable-ramp-delay = <1000>;
> > + regulator-always-on;
> > + regulator-boot-on;
> > + };
> > +
> > + avdd_dsi_csi: VCSI {
> > + regulator-name = "avdd_dsi_csi";
> > + regulator-min-microvolt = <1200000>;
> > + regulator-max-microvolt = <1200000>;
> > + regulator-enable-ramp-delay = <1000>;
> > + regulator-boot-on;
> > + };
> > +
> > + avdd_3v3_periph: VWLAN2 {
> > + regulator-name = "avdd_3v3_periph";
> > + regulator-min-microvolt = <2775000>;
> > + regulator-max-microvolt = <3300000>;
> > + regulator-enable-ramp-delay = <1000>;
> > + regulator-boot-on;
> > + };
> > +
> > + vddio_usd: VSIMCARD {
> > + regulator-name = "vddio_usd";
> > + regulator-min-microvolt = <1800000>;
> > + regulator-max-microvolt = <2900000>;
> > + regulator-enable-ramp-delay = <1000>;
> > + regulator-boot-on;
> > + };
> > +
> > + vdd_haptic: VVIB {
> > + regulator-name = "vdd_haptic";
> > + regulator-min-microvolt = <1300000>;
> > + regulator-max-microvolt = <3000000>;
> > + regulator-enable-ramp-delay = <1000>;
> > + };
> > +
> > + avdd_usb: VUSB {
> > + regulator-name = "avdd_usb";
> > + regulator-min-microvolt = <3300000>;
> > + regulator-max-microvolt = <3300000>;
> > + regulator-enable-ramp-delay = <1000>;
> > + regulator-always-on;
> > + regulator-boot-on;
> > + };
> > +
> > + vdd_audio: VAUDIO {
> > + regulator-name = "vdd_audio";
> > + regulator-min-microvolt = <2775000>;
> > + regulator-max-microvolt = <2775000>;
> > + regulator-enable-ramp-delay = <1000>;
> > + regulator-always-on;
> > + regulator-boot-on;
> > + };
> > + };
> > + };
> > +
> > + cpcap_rtc: rtc {
> > + compatible = "motorola,cpcap-rtc";
> > +
> > + interrupt-parent = <&cpcap>;
> > + interrupts = <39 IRQ_TYPE_NONE>, <26 IRQ_TYPE_NONE>;
> > + };
> > + };
> > + };
> > +
> > +...
> > diff --git a/Documentation/devicetree/bindings/mfd/motorola-cpcap.txt b/Documentation/devicetree/bindings/mfd/motorola-cpcap.txt
> > deleted file mode 100644
> > index 18c3fc26ca93..000000000000
> > --- a/Documentation/devicetree/bindings/mfd/motorola-cpcap.txt
> > +++ /dev/null
> > @@ -1,78 +0,0 @@
> > -Motorola CPCAP PMIC device tree binding
> > -
> > -Required properties:
> > -- compatible : One or both of "motorola,cpcap" or "ste,6556002"
> > -- reg : SPI chip select
> > -- interrupts : The interrupt line the device is connected to
> > -- interrupt-controller : Marks the device node as an interrupt controller
> > -- #interrupt-cells : The number of cells to describe an IRQ, should be 2
> > -- #address-cells : Child device offset number of cells, should be 1
> > -- #size-cells : Child device size number of cells, should be 0
> > -- spi-max-frequency : Typically set to 3000000
> > -- spi-cs-high : SPI chip select direction
> > -
> > -Optional subnodes:
> > -
> > -The sub-functions of CPCAP get their own node with their own compatible values,
> > -which are described in the following files:
> > -
> > -- Documentation/devicetree/bindings/power/supply/cpcap-battery.yaml
> > -- Documentation/devicetree/bindings/power/supply/cpcap-charger.yaml
> > -- Documentation/devicetree/bindings/regulator/cpcap-regulator.txt
> > -- Documentation/devicetree/bindings/phy/motorola,cpcap-usb-phy.yaml
> > -- Documentation/devicetree/bindings/input/cpcap-pwrbutton.txt
> > -- Documentation/devicetree/bindings/rtc/cpcap-rtc.txt
> > -- Documentation/devicetree/bindings/leds/leds-cpcap.txt
> > -- Documentation/devicetree/bindings/iio/adc/motorola,cpcap-adc.yaml
> > -
> > -The only exception is the audio codec. Instead of a compatible value its
> > -node must be named "audio-codec".
> > -
> > -Required properties for the audio-codec subnode:
> > -
> > -- #sound-dai-cells = <1>;
> > -- interrupts : should contain jack detection interrupts, with headset
> > - detect interrupt matching "hs" and microphone bias 2
> > - detect interrupt matching "mb2" in interrupt-names.
> > -- interrupt-names : Contains "hs", "mb2"
> > -
> > -The audio-codec provides two DAIs. The first one is connected to the
> > -Stereo HiFi DAC and the second one is connected to the Voice DAC.
> > -
> > -Example:
> > -
> > -&mcspi1 {
> > - cpcap: pmic@0 {
> > - compatible = "motorola,cpcap", "ste,6556002";
> > - reg = <0>; /* cs0 */
> > - interrupt-parent = <&gpio1>;
> > - interrupts = <7 IRQ_TYPE_EDGE_RISING>;
> > - interrupt-controller;
> > - #interrupt-cells = <2>;
> > - #address-cells = <1>;
> > - #size-cells = <0>;
> > - spi-max-frequency = <3000000>;
> > - spi-cs-high;
> > -
> > - audio-codec {
> > - #sound-dai-cells = <1>;
> > - interrupts-extended = <&cpcap 9 0>, <&cpcap 10 0>;
> > - interrupt-names = "hs", "mb2";
> > -
> > - /* HiFi */
> > - port@0 {
> > - endpoint {
> > - remote-endpoint = <&cpu_dai1>;
> > - };
> > - };
> > -
> > - /* Voice */
> > - port@1 {
> > - endpoint {
> > - remote-endpoint = <&cpu_dai2>;
> > - };
> > - };
> > - };
> > - };
> > -};
> > -
> > --
> > 2.51.0
> >
^ permalink raw reply
* Re: [PATCH v5 3/6] dt-bindings: mfd: motorola-cpcap: convert to DT schema
From: Rob Herring @ 2026-05-12 12:53 UTC (permalink / raw)
To: Svyatoslav Ryhel
Cc: Dmitry Torokhov, Krzysztof Kozlowski, Conor Dooley, Lee Jones,
Pavel Machek, David Lechner, Tony Lindgren, linux-input,
devicetree, linux-kernel, linux-leds
In-Reply-To: <20260510110804.33045-4-clamor95@gmail.com>
On Sun, May 10, 2026 at 02:08:01PM +0300, Svyatoslav Ryhel wrote:
> Convert devicetree bindings for the Motorola CPCAP MFD from TXT to YAML.
>
> Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
> Reviewed-by: Rob Herring (Arm) <robh@kernel.org>
> ---
> .../bindings/mfd/motorola,cpcap.yaml | 414 ++++++++++++++++++
> .../bindings/mfd/motorola-cpcap.txt | 78 ----
> 2 files changed, 414 insertions(+), 78 deletions(-)
> create mode 100644 Documentation/devicetree/bindings/mfd/motorola,cpcap.yaml
> delete mode 100644 Documentation/devicetree/bindings/mfd/motorola-cpcap.txt
>
> diff --git a/Documentation/devicetree/bindings/mfd/motorola,cpcap.yaml b/Documentation/devicetree/bindings/mfd/motorola,cpcap.yaml
> new file mode 100644
> index 000000000000..7f257f3a1a5a
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mfd/motorola,cpcap.yaml
> @@ -0,0 +1,414 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/mfd/motorola,cpcap.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Motorola CPCAP PMIC MFD
> +
> +maintainers:
> + - Svyatoslav Ryhel <clamor95@gmail.com>
> +
> +allOf:
> + - $ref: /schemas/spi/spi-peripheral-props.yaml#
> +
> +properties:
> + compatible:
> + items:
> + - const: motorola,cpcap
> + - const: st,6556002
> +
> + reg:
> + maxItems: 1
> +
> + interrupts:
> + maxItems: 1
> +
> + interrupt-controller: true
> +
> + "#interrupt-cells":
> + const: 2
> +
> + "#address-cells":
> + const: 1
> +
> + "#size-cells":
> + const: 0
There aren't any child nodes with an address. These 2 can be dropped.
> +
> + spi-max-frequency:
> + maximum: 9600000
> +
> + spi-cs-high: true
> + spi-cpol: true
> + spi-cpha: true
> +
> + adc:
> + $ref: /schemas/iio/adc/motorola,cpcap-adc.yaml#
> +
> + audio-codec:
> + type: object
> + additionalProperties: false
> +
> + properties:
> + interrupts:
> + items:
> + - description: headset detect interrupt
> + - description: microphone bias 2 detect interrupt
> +
> + interrupt-names:
> + items:
> + - const: hs
> + - const: mb2
> +
> + "#sound-dai-cells":
> + const: 1
> +
> + VAUDIO-supply:
> + description:
> + Codec power supply, usually VAUDIO regulator of CPCAP.
> +
> + ports:
> + $ref: /schemas/graph.yaml#/properties/ports
> +
> + properties:
> + port@0:
> + $ref: /schemas/graph.yaml#/properties/port
> + description: port connected to the Stereo HiFi DAC
> +
> + port@1:
> + $ref: /schemas/graph.yaml#/properties/port
> + description: port connected to the Voice DAC
> +
> + required:
> + - port@0
> + - port@1
> +
> + required:
> + - interrupts
> + - interrupt-names
> + - "#sound-dai-cells"
> +
> + battery:
> + $ref: /schemas/power/supply/cpcap-battery.yaml#
> +
> + charger:
> + $ref: /schemas/power/supply/cpcap-charger.yaml#
> +
> + key-power:
> + $ref: /schemas/input/motorola,cpcap-pwrbutton.yaml#
> +
> + phy:
> + $ref: /schemas/phy/motorola,cpcap-usb-phy.yaml#
> +
> + regulator:
> + $ref: /schemas/regulator/motorola,cpcap-regulator.yaml#
> +
> + rtc:
> + $ref: /schemas/rtc/motorola,cpcap-rtc.yaml#
> +
> +patternProperties:
> + "^led(-[a-z]+)?$":
> + $ref: /schemas/leds/motorola,cpcap-leds.yaml#
> +
> +required:
> + - compatible
> + - reg
> + - interrupts
> + - interrupt-controller
> + - "#interrupt-cells"
> + - spi-max-frequency
> + - "#address-cells"
> + - "#size-cells"
> +
> +additionalProperties: false
> +
> +examples:
> + - |
> + #include <dt-bindings/gpio/gpio.h>
> + #include <dt-bindings/interrupt-controller/irq.h>
> + #include <dt-bindings/input/linux-event-codes.h>
> +
> + spi {
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + cpcap: pmic@0 {
> + compatible = "motorola,cpcap", "st,6556002";
> + reg = <0>; /* cs0 */
> +
> + interrupt-parent = <&gpio1>;
> + interrupts = <7 IRQ_TYPE_EDGE_RISING>;
> +
> + interrupt-controller;
> + #interrupt-cells = <2>;
> +
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + spi-max-frequency = <3000000>;
> + spi-cs-high;
> +
> + spi-cpol;
> + spi-cpha;
> +
> + cpcap_adc: adc {
> + compatible = "motorola,cpcap-adc";
> +
> + interrupt-parent = <&cpcap>;
> + interrupts = <8 IRQ_TYPE_NONE>;
> + interrupt-names = "adcdone";
> +
> + #io-channel-cells = <1>;
> + };
> +
> + cpcap_audio: audio-codec {
> + interrupt-parent = <&cpcap>;
> + interrupts = <9 IRQ_TYPE_NONE>, <10 IRQ_TYPE_NONE>;
> + interrupt-names = "hs", "mb2";
> +
> + VAUDIO-supply = <&vdd_audio>;
> +
> + #sound-dai-cells = <1>;
> +
> + ports {
> + #address-cells = <1>;
> + #size-cells = <0>;
> +
> + /* HiFi */
> + port@0 {
> + reg = <0>;
> +
> + cpcap_audio_codec0: endpoint {
> + };
> + };
> +
> + /* Voice */
> + port@1 {
> + reg = <1>;
> +
> + cpcap_audio_codec1: endpoint {
> + };
> + };
> + };
> + };
> +
> + cpcap_battery: battery {
> + compatible = "motorola,cpcap-battery";
> +
> + interrupt-parent = <&cpcap>;
> + interrupts = <6 IRQ_TYPE_NONE>, <5 IRQ_TYPE_NONE>,
> + <3 IRQ_TYPE_NONE>, <20 IRQ_TYPE_NONE>,
> + <54 IRQ_TYPE_NONE>, <57 IRQ_TYPE_NONE>;
> + interrupt-names = "eol", "lowbph", "lowbpl",
> + "chrgcurr1", "battdetb", "cccal";
> +
> + io-channels = <&cpcap_adc 0>, <&cpcap_adc 1>,
> + <&cpcap_adc 5>, <&cpcap_adc 6>;
> + io-channel-names = "battdetb", "battp",
> + "chg_isense", "batti";
> + power-supplies = <&cpcap_charger>;
> + };
> +
> + cpcap_charger: charger {
> + compatible = "motorola,mapphone-cpcap-charger";
> +
> + interrupt-parent = <&cpcap>;
> + interrupts = <13 IRQ_TYPE_NONE>, <12 IRQ_TYPE_NONE>,
> + <29 IRQ_TYPE_NONE>, <28 IRQ_TYPE_NONE>,
> + <22 IRQ_TYPE_NONE>, <21 IRQ_TYPE_NONE>,
> + <20 IRQ_TYPE_NONE>, <19 IRQ_TYPE_NONE>,
> + <54 IRQ_TYPE_NONE>;
> + interrupt-names = "chrg_det", "rvrs_chrg", "chrg_se1b",
> + "se0conn", "rvrs_mode", "chrgcurr2",
> + "chrgcurr1", "vbusvld", "battdetb";
> +
> + mode-gpios = <&gpio3 29 GPIO_ACTIVE_LOW>,
> + <&gpio3 23 GPIO_ACTIVE_LOW>;
> +
> + io-channels = <&cpcap_adc 0>, <&cpcap_adc 1>,
> + <&cpcap_adc 2>, <&cpcap_adc 5>,
> + <&cpcap_adc 6>;
> + io-channel-names = "battdetb", "battp",
> + "vbus", "chg_isense",
> + "batti";
> + };
> +
> + key-power {
> + compatible = "motorola,cpcap-pwrbutton";
> +
> + interrupt-parent = <&cpcap>;
> + interrupts = <23 IRQ_TYPE_NONE>;
> + };
> +
> + led-red {
> + compatible = "motorola,cpcap-led-red";
> + vdd-supply = <&vdd_led>;
> + label = "status-led::red";
> + };
> +
> + led-green {
> + compatible = "motorola,cpcap-led-green";
> + vdd-supply = <&vdd_led>;
> + label = "status-led::green";
> + };
> +
> + led-blue {
> + compatible = "motorola,cpcap-led-blue";
> + vdd-supply = <&vdd_led>;
> + label = "status-led::blue";
> + };
> +
> + cpcap_usb2_phy: phy {
> + compatible = "motorola,cpcap-usb-phy";
> +
> + pinctrl-0 = <&usb_gpio_mux_sel1>, <&usb_gpio_mux_sel2>;
> + pinctrl-1 = <&usb_ulpi_pins>;
> + pinctrl-2 = <&usb_utmi_pins>;
> + pinctrl-3 = <&uart3_pins>;
> + pinctrl-names = "default", "ulpi", "utmi", "uart";
> + #phy-cells = <0>;
> +
> + interrupts-extended =
> + <&cpcap 15 IRQ_TYPE_NONE>, <&cpcap 14 IRQ_TYPE_NONE>,
> + <&cpcap 28 IRQ_TYPE_NONE>, <&cpcap 19 IRQ_TYPE_NONE>,
> + <&cpcap 18 IRQ_TYPE_NONE>, <&cpcap 17 IRQ_TYPE_NONE>,
> + <&cpcap 16 IRQ_TYPE_NONE>, <&cpcap 49 IRQ_TYPE_NONE>,
> + <&cpcap 48 IRQ_TYPE_NONE>;
> + interrupt-names = "id_ground", "id_float", "se0conn",
> + "vbusvld", "sessvld", "sessend",
> + "se1", "dm", "dp";
> +
> + mode-gpios = <&gpio2 28 GPIO_ACTIVE_HIGH>,
> + <&gpio1 0 GPIO_ACTIVE_HIGH>;
> +
> + io-channels = <&cpcap_adc 2>, <&cpcap_adc 7>;
> + io-channel-names = "vbus", "id";
> +
> + vusb-supply = <&avdd_usb>;
> + };
> +
> + regulator {
> + compatible = "motorola,cpcap-regulator";
> +
> + regulators {
> + vdd_cpu: SW1 {
> + regulator-name = "vdd_cpu";
> + regulator-min-microvolt = <750000>;
> + regulator-max-microvolt = <1125000>;
> + regulator-enable-ramp-delay = <1500>;
> + regulator-always-on;
> + regulator-boot-on;
> + };
> +
> + vdd_core: SW2 {
> + regulator-name = "vdd_core";
> + regulator-min-microvolt = <950000>;
> + regulator-max-microvolt = <1300000>;
> + regulator-enable-ramp-delay = <1500>;
> + regulator-always-on;
> + regulator-boot-on;
> + };
> +
> + vdd_1v8_vio: SW3 {
> + regulator-name = "vdd_1v8_vio";
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <1800000>;
> + regulator-enable-ramp-delay = <0>;
> + regulator-always-on;
> + regulator-boot-on;
> + };
> +
> + vdd_aon: SW4 {
> + regulator-name = "vdd_aon";
> + regulator-min-microvolt = <950000>;
> + regulator-max-microvolt = <1300000>;
> + regulator-enable-ramp-delay = <1500>;
> + regulator-always-on;
> + regulator-boot-on;
> + };
> +
> + vdd_led: SW5 {
> + regulator-name = "vdd_led";
> + regulator-min-microvolt = <5050000>;
> + regulator-max-microvolt = <5050000>;
> + regulator-enable-ramp-delay = <1500>;
> + regulator-boot-on;
> + };
> +
> + vdd_hvio: VHVIO {
> + regulator-name = "vdd_hvio";
> + regulator-min-microvolt = <2775000>;
> + regulator-max-microvolt = <2775000>;
> + regulator-enable-ramp-delay = <1000>;
> + };
> +
> + vcore_emmc: VSDIO {
> + regulator-name = "vcore_emmc";
> + regulator-min-microvolt = <1500000>;
> + regulator-max-microvolt = <3000000>;
> + regulator-enable-ramp-delay = <1000>;
> + regulator-always-on;
> + regulator-boot-on;
> + };
> +
> + avdd_dsi_csi: VCSI {
> + regulator-name = "avdd_dsi_csi";
> + regulator-min-microvolt = <1200000>;
> + regulator-max-microvolt = <1200000>;
> + regulator-enable-ramp-delay = <1000>;
> + regulator-boot-on;
> + };
> +
> + avdd_3v3_periph: VWLAN2 {
> + regulator-name = "avdd_3v3_periph";
> + regulator-min-microvolt = <2775000>;
> + regulator-max-microvolt = <3300000>;
> + regulator-enable-ramp-delay = <1000>;
> + regulator-boot-on;
> + };
> +
> + vddio_usd: VSIMCARD {
> + regulator-name = "vddio_usd";
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <2900000>;
> + regulator-enable-ramp-delay = <1000>;
> + regulator-boot-on;
> + };
> +
> + vdd_haptic: VVIB {
> + regulator-name = "vdd_haptic";
> + regulator-min-microvolt = <1300000>;
> + regulator-max-microvolt = <3000000>;
> + regulator-enable-ramp-delay = <1000>;
> + };
> +
> + avdd_usb: VUSB {
> + regulator-name = "avdd_usb";
> + regulator-min-microvolt = <3300000>;
> + regulator-max-microvolt = <3300000>;
> + regulator-enable-ramp-delay = <1000>;
> + regulator-always-on;
> + regulator-boot-on;
> + };
> +
> + vdd_audio: VAUDIO {
> + regulator-name = "vdd_audio";
> + regulator-min-microvolt = <2775000>;
> + regulator-max-microvolt = <2775000>;
> + regulator-enable-ramp-delay = <1000>;
> + regulator-always-on;
> + regulator-boot-on;
> + };
> + };
> + };
> +
> + cpcap_rtc: rtc {
> + compatible = "motorola,cpcap-rtc";
> +
> + interrupt-parent = <&cpcap>;
> + interrupts = <39 IRQ_TYPE_NONE>, <26 IRQ_TYPE_NONE>;
> + };
> + };
> + };
> +
> +...
> diff --git a/Documentation/devicetree/bindings/mfd/motorola-cpcap.txt b/Documentation/devicetree/bindings/mfd/motorola-cpcap.txt
> deleted file mode 100644
> index 18c3fc26ca93..000000000000
> --- a/Documentation/devicetree/bindings/mfd/motorola-cpcap.txt
> +++ /dev/null
> @@ -1,78 +0,0 @@
> -Motorola CPCAP PMIC device tree binding
> -
> -Required properties:
> -- compatible : One or both of "motorola,cpcap" or "ste,6556002"
> -- reg : SPI chip select
> -- interrupts : The interrupt line the device is connected to
> -- interrupt-controller : Marks the device node as an interrupt controller
> -- #interrupt-cells : The number of cells to describe an IRQ, should be 2
> -- #address-cells : Child device offset number of cells, should be 1
> -- #size-cells : Child device size number of cells, should be 0
> -- spi-max-frequency : Typically set to 3000000
> -- spi-cs-high : SPI chip select direction
> -
> -Optional subnodes:
> -
> -The sub-functions of CPCAP get their own node with their own compatible values,
> -which are described in the following files:
> -
> -- Documentation/devicetree/bindings/power/supply/cpcap-battery.yaml
> -- Documentation/devicetree/bindings/power/supply/cpcap-charger.yaml
> -- Documentation/devicetree/bindings/regulator/cpcap-regulator.txt
> -- Documentation/devicetree/bindings/phy/motorola,cpcap-usb-phy.yaml
> -- Documentation/devicetree/bindings/input/cpcap-pwrbutton.txt
> -- Documentation/devicetree/bindings/rtc/cpcap-rtc.txt
> -- Documentation/devicetree/bindings/leds/leds-cpcap.txt
> -- Documentation/devicetree/bindings/iio/adc/motorola,cpcap-adc.yaml
> -
> -The only exception is the audio codec. Instead of a compatible value its
> -node must be named "audio-codec".
> -
> -Required properties for the audio-codec subnode:
> -
> -- #sound-dai-cells = <1>;
> -- interrupts : should contain jack detection interrupts, with headset
> - detect interrupt matching "hs" and microphone bias 2
> - detect interrupt matching "mb2" in interrupt-names.
> -- interrupt-names : Contains "hs", "mb2"
> -
> -The audio-codec provides two DAIs. The first one is connected to the
> -Stereo HiFi DAC and the second one is connected to the Voice DAC.
> -
> -Example:
> -
> -&mcspi1 {
> - cpcap: pmic@0 {
> - compatible = "motorola,cpcap", "ste,6556002";
> - reg = <0>; /* cs0 */
> - interrupt-parent = <&gpio1>;
> - interrupts = <7 IRQ_TYPE_EDGE_RISING>;
> - interrupt-controller;
> - #interrupt-cells = <2>;
> - #address-cells = <1>;
> - #size-cells = <0>;
> - spi-max-frequency = <3000000>;
> - spi-cs-high;
> -
> - audio-codec {
> - #sound-dai-cells = <1>;
> - interrupts-extended = <&cpcap 9 0>, <&cpcap 10 0>;
> - interrupt-names = "hs", "mb2";
> -
> - /* HiFi */
> - port@0 {
> - endpoint {
> - remote-endpoint = <&cpu_dai1>;
> - };
> - };
> -
> - /* Voice */
> - port@1 {
> - endpoint {
> - remote-endpoint = <&cpu_dai2>;
> - };
> - };
> - };
> - };
> -};
> -
> --
> 2.51.0
>
^ permalink raw reply
* Re: [PATCH v3 3/9] iio: hid-sensors: introduce device managed API
From: srinivas pandruvada @ 2026-05-12 12:47 UTC (permalink / raw)
To: Sanjay Chitroda, jikos, jic23, Zhang, Lixu
Cc: dlechner, nuno.sa, andy, sakari.ailus, linux-input, linux-iio,
linux-kernel
In-Reply-To: <20260509101040.791404-4-sanjayembedded@gmail.com>
On Sat, 2026-05-09 at 15:40 +0530, Sanjay Chitroda wrote:
> From: Sanjay Chitroda <sanjayembeddedse@gmail.com>
>
> hid_sensor_setup_trigger() is common API used for the HID IIO
> drivers,
> prepare devm API devm_hid_sensor_setup_trigger() to acquire resource
> during setup and release using device managed framework during
> drivers
> fail, unbind or remove path.
>
> Register action with devm_add_action_or_reset() to release resource
> with
> devres framework.
>
> Signed-off-by: Sanjay Chitroda <sanjayembeddedse@gmail.com>
Looks good but we have to test by unbinding ISH PCI device.
Thanks,
Srinivas
> ---
> Changes in v3:
> - Remove cast and update function based on review comment from Andy
> - v2 link ->
> https://lore.kernel.org/all/20260429175918.2541914-3-sanjayembedded@gmail.com/
> ---
> .../common/hid-sensors/hid-sensor-trigger.c | 18
> ++++++++++++++++++
> .../common/hid-sensors/hid-sensor-trigger.h | 2 ++
> 2 files changed, 20 insertions(+)
>
> diff --git a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
> b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
> index 98fadc61a68a..fb6a4587ae03 100644
> --- a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
> +++ b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
> @@ -301,6 +301,24 @@ int hid_sensor_setup_trigger(struct iio_dev
> *indio_dev, const char *name,
> }
> EXPORT_SYMBOL_NS(hid_sensor_setup_trigger, "IIO_HID");
>
> +static void hid_sensor_remove_trigger_action(void *attrb)
> +{
> + hid_sensor_remove_trigger(attrb);
> +}
> +
> +int devm_hid_sensor_setup_trigger(struct device *dev, struct iio_dev
> *indio_dev,
> + const char *name, struct
> hid_sensor_common *attrb)
> +{
> + int ret;
> +
> + ret = hid_sensor_setup_trigger(indio_dev, name, attrb);
> + if (ret)
> + return ret;
> +
> + return devm_add_action_or_reset(dev,
> hid_sensor_remove_trigger_action, attrb);
> +}
> +EXPORT_SYMBOL_NS(devm_hid_sensor_setup_trigger, "IIO_HID");
> +
> static int __maybe_unused hid_sensor_suspend(struct device *dev)
> {
> struct iio_dev *indio_dev = dev_get_drvdata(dev);
> diff --git a/drivers/iio/common/hid-sensors/hid-sensor-trigger.h
> b/drivers/iio/common/hid-sensors/hid-sensor-trigger.h
> index afec46ecbe71..6fd7c39a240d 100644
> --- a/drivers/iio/common/hid-sensors/hid-sensor-trigger.h
> +++ b/drivers/iio/common/hid-sensors/hid-sensor-trigger.h
> @@ -17,6 +17,8 @@ extern const struct dev_pm_ops hid_sensor_pm_ops;
> int hid_sensor_setup_trigger(struct iio_dev *indio_dev, const char
> *name,
> struct hid_sensor_common *attrb);
> void hid_sensor_remove_trigger(struct hid_sensor_common *attrb);
> +int devm_hid_sensor_setup_trigger(struct device *dev, struct iio_dev
> *indio_dev,
> + const char *name, struct
> hid_sensor_common *attrb);
> int hid_sensor_power_state(struct hid_sensor_common *st, bool
> state);
>
> #endif
^ permalink raw reply
* Re: [PATCH v3 2/9] iio: hid-sensors: cleanup codestyle warning
From: srinivas pandruvada @ 2026-05-12 12:39 UTC (permalink / raw)
To: Sanjay Chitroda, jikos, jic23
Cc: dlechner, nuno.sa, andy, sakari.ailus, linux-input, linux-iio,
linux-kernel
In-Reply-To: <20260509101040.791404-3-sanjayembedded@gmail.com>
On Sat, 2026-05-09 at 15:40 +0530, Sanjay Chitroda wrote:
> From: Sanjay Chitroda <sanjayembeddedse@gmail.com>
>
> Reported by checkpatch:
> FILE: drivers/iio/common/hid-sensors/hid-sensor-trigger.c
>
> WARNING: Missing a blank line after declarations
>
> Signed-off-by: Sanjay Chitroda <sanjayembeddedse@gmail.com>
Acked-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
> ---
> drivers/iio/common/hid-sensors/hid-sensor-trigger.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
> b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
> index 28d050b45c74..98fadc61a68a 100644
> --- a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
> +++ b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
> @@ -313,7 +313,9 @@ static int __maybe_unused
> hid_sensor_resume(struct device *dev)
> {
> struct iio_dev *indio_dev = dev_get_drvdata(dev);
> struct hid_sensor_common *attrb =
> iio_device_get_drvdata(indio_dev);
> +
> schedule_work(&attrb->work);
> +
> return 0;
> }
>
> @@ -321,6 +323,7 @@ static int __maybe_unused
> hid_sensor_runtime_resume(struct device *dev)
> {
> struct iio_dev *indio_dev = dev_get_drvdata(dev);
> struct hid_sensor_common *attrb =
> iio_device_get_drvdata(indio_dev);
> +
> return _hid_sensor_power_state(attrb, true);
> }
>
^ permalink raw reply
* Re: [PATCH v3 1/9] iio: hid-sensors: drop redundant iio_dev argument
From: srinivas pandruvada @ 2026-05-12 12:37 UTC (permalink / raw)
To: Sanjay Chitroda, jikos, jic23
Cc: dlechner, nuno.sa, andy, sakari.ailus, linux-input, linux-iio,
linux-kernel
In-Reply-To: <20260509101040.791404-2-sanjayembedded@gmail.com>
On Sat, 2026-05-09 at 15:40 +0530, Sanjay Chitroda wrote:
> From: Sanjay Chitroda <sanjayembeddedse@gmail.com>
>
> hid_sensor_remove_trigger() uses struct hid_sensor_common to release
> resources acquired during trigger setup.
>
> Earlier implementations required struct iio_dev to clean up buffers,
> but with the current code this argument is no longer used and is
> redundant.
>
> Adapt to hid_sensor_remove_trigger() API change across all HID IIO
> drivers to match updated prototype.
>
> Removing it simplifies the API and is a preparatory step toward
> converting the trigger handling to a devm-based API.
>
> Signed-off-by: Sanjay Chitroda <sanjayembeddedse@gmail.com>
Acked-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
> ---
> drivers/iio/accel/hid-sensor-accel-3d.c | 4 ++--
> drivers/iio/common/hid-sensors/hid-sensor-trigger.c | 3 +--
> drivers/iio/common/hid-sensors/hid-sensor-trigger.h | 3 +--
> drivers/iio/gyro/hid-sensor-gyro-3d.c | 4 ++--
> drivers/iio/humidity/hid-sensor-humidity.c | 4 ++--
> drivers/iio/light/hid-sensor-als.c | 4 ++--
> drivers/iio/light/hid-sensor-prox.c | 4 ++--
> drivers/iio/magnetometer/hid-sensor-magn-3d.c | 4 ++--
> drivers/iio/orientation/hid-sensor-incl-3d.c | 4 ++--
> drivers/iio/orientation/hid-sensor-rotation.c | 4 ++--
> drivers/iio/position/hid-sensor-custom-intel-hinge.c | 4 ++--
> drivers/iio/pressure/hid-sensor-press.c | 4 ++--
> drivers/iio/temperature/hid-sensor-temperature.c | 4 ++--
> 13 files changed, 24 insertions(+), 26 deletions(-)
>
> diff --git a/drivers/iio/accel/hid-sensor-accel-3d.c
> b/drivers/iio/accel/hid-sensor-accel-3d.c
> index 2ff591b3458f..a63dae90dadc 100644
> --- a/drivers/iio/accel/hid-sensor-accel-3d.c
> +++ b/drivers/iio/accel/hid-sensor-accel-3d.c
> @@ -416,7 +416,7 @@ static int hid_accel_3d_probe(struct
> platform_device *pdev)
> error_iio_unreg:
> iio_device_unregister(indio_dev);
> error_remove_trigger:
> - hid_sensor_remove_trigger(indio_dev, &accel_state-
> >common_attributes);
> + hid_sensor_remove_trigger(&accel_state->common_attributes);
> return ret;
> }
>
> @@ -429,7 +429,7 @@ static void hid_accel_3d_remove(struct
> platform_device *pdev)
>
> sensor_hub_remove_callback(hsdev, hsdev->usage);
> iio_device_unregister(indio_dev);
> - hid_sensor_remove_trigger(indio_dev, &accel_state-
> >common_attributes);
> + hid_sensor_remove_trigger(&accel_state->common_attributes);
> }
>
> static const struct platform_device_id hid_accel_3d_ids[] = {
> diff --git a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
> b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
> index 417c4ab8c1b2..28d050b45c74 100644
> --- a/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
> +++ b/drivers/iio/common/hid-sensors/hid-sensor-trigger.c
> @@ -218,8 +218,7 @@ static const struct iio_buffer_setup_ops
> hid_sensor_buffer_ops = {
> .predisable = buffer_predisable,
> };
>
> -void hid_sensor_remove_trigger(struct iio_dev *indio_dev,
> - struct hid_sensor_common *attrb)
> +void hid_sensor_remove_trigger(struct hid_sensor_common *attrb)
> {
> if (atomic_read(&attrb->runtime_pm_enable))
> pm_runtime_disable(&attrb->pdev->dev);
> diff --git a/drivers/iio/common/hid-sensors/hid-sensor-trigger.h
> b/drivers/iio/common/hid-sensors/hid-sensor-trigger.h
> index f94fca4f1edf..afec46ecbe71 100644
> --- a/drivers/iio/common/hid-sensors/hid-sensor-trigger.h
> +++ b/drivers/iio/common/hid-sensors/hid-sensor-trigger.h
> @@ -16,8 +16,7 @@ extern const struct dev_pm_ops hid_sensor_pm_ops;
>
> int hid_sensor_setup_trigger(struct iio_dev *indio_dev, const char
> *name,
> struct hid_sensor_common *attrb);
> -void hid_sensor_remove_trigger(struct iio_dev *indio_dev,
> - struct hid_sensor_common *attrb);
> +void hid_sensor_remove_trigger(struct hid_sensor_common *attrb);
> int hid_sensor_power_state(struct hid_sensor_common *st, bool
> state);
>
> #endif
> diff --git a/drivers/iio/gyro/hid-sensor-gyro-3d.c
> b/drivers/iio/gyro/hid-sensor-gyro-3d.c
> index c340cc899a7c..fe663b19e902 100644
> --- a/drivers/iio/gyro/hid-sensor-gyro-3d.c
> +++ b/drivers/iio/gyro/hid-sensor-gyro-3d.c
> @@ -354,7 +354,7 @@ static int hid_gyro_3d_probe(struct
> platform_device *pdev)
> error_iio_unreg:
> iio_device_unregister(indio_dev);
> error_remove_trigger:
> - hid_sensor_remove_trigger(indio_dev, &gyro_state-
> >common_attributes);
> + hid_sensor_remove_trigger(&gyro_state->common_attributes);
> return ret;
> }
>
> @@ -367,7 +367,7 @@ static void hid_gyro_3d_remove(struct
> platform_device *pdev)
>
> sensor_hub_remove_callback(hsdev, HID_USAGE_SENSOR_GYRO_3D);
> iio_device_unregister(indio_dev);
> - hid_sensor_remove_trigger(indio_dev, &gyro_state-
> >common_attributes);
> + hid_sensor_remove_trigger(&gyro_state->common_attributes);
> }
>
> static const struct platform_device_id hid_gyro_3d_ids[] = {
> diff --git a/drivers/iio/humidity/hid-sensor-humidity.c
> b/drivers/iio/humidity/hid-sensor-humidity.c
> index be2338d5f407..e580a2af9562 100644
> --- a/drivers/iio/humidity/hid-sensor-humidity.c
> +++ b/drivers/iio/humidity/hid-sensor-humidity.c
> @@ -255,7 +255,7 @@ static int hid_humidity_probe(struct
> platform_device *pdev)
> error_remove_callback:
> sensor_hub_remove_callback(hsdev,
> HID_USAGE_SENSOR_HUMIDITY);
> error_remove_trigger:
> - hid_sensor_remove_trigger(indio_dev, &humid_st-
> >common_attributes);
> + hid_sensor_remove_trigger(&humid_st->common_attributes);
> return ret;
> }
>
> @@ -268,7 +268,7 @@ static void hid_humidity_remove(struct
> platform_device *pdev)
>
> iio_device_unregister(indio_dev);
> sensor_hub_remove_callback(hsdev,
> HID_USAGE_SENSOR_HUMIDITY);
> - hid_sensor_remove_trigger(indio_dev, &humid_st-
> >common_attributes);
> + hid_sensor_remove_trigger(&humid_st->common_attributes);
> }
>
> static const struct platform_device_id hid_humidity_ids[] = {
> diff --git a/drivers/iio/light/hid-sensor-als.c
> b/drivers/iio/light/hid-sensor-als.c
> index 384572844162..9b57cdced18a 100644
> --- a/drivers/iio/light/hid-sensor-als.c
> +++ b/drivers/iio/light/hid-sensor-als.c
> @@ -432,7 +432,7 @@ static int hid_als_probe(struct platform_device
> *pdev)
> error_iio_unreg:
> iio_device_unregister(indio_dev);
> error_remove_trigger:
> - hid_sensor_remove_trigger(indio_dev, &als_state-
> >common_attributes);
> + hid_sensor_remove_trigger(&als_state->common_attributes);
> return ret;
> }
>
> @@ -445,7 +445,7 @@ static void hid_als_remove(struct platform_device
> *pdev)
>
> sensor_hub_remove_callback(hsdev, hsdev->usage);
> iio_device_unregister(indio_dev);
> - hid_sensor_remove_trigger(indio_dev, &als_state-
> >common_attributes);
> + hid_sensor_remove_trigger(&als_state->common_attributes);
> }
>
> static const struct platform_device_id hid_als_ids[] = {
> diff --git a/drivers/iio/light/hid-sensor-prox.c
> b/drivers/iio/light/hid-sensor-prox.c
> index efa904a70d0e..473c45626487 100644
> --- a/drivers/iio/light/hid-sensor-prox.c
> +++ b/drivers/iio/light/hid-sensor-prox.c
> @@ -340,7 +340,7 @@ static int hid_prox_probe(struct platform_device
> *pdev)
> error_iio_unreg:
> iio_device_unregister(indio_dev);
> error_remove_trigger:
> - hid_sensor_remove_trigger(indio_dev, &prox_state-
> >common_attributes);
> + hid_sensor_remove_trigger(&prox_state->common_attributes);
> return ret;
> }
>
> @@ -353,7 +353,7 @@ static void hid_prox_remove(struct
> platform_device *pdev)
>
> sensor_hub_remove_callback(hsdev, hsdev->usage);
> iio_device_unregister(indio_dev);
> - hid_sensor_remove_trigger(indio_dev, &prox_state-
> >common_attributes);
> + hid_sensor_remove_trigger(&prox_state->common_attributes);
> }
>
> static const struct platform_device_id hid_prox_ids[] = {
> diff --git a/drivers/iio/magnetometer/hid-sensor-magn-3d.c
> b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
> index b01dd53eb100..8be3dfe4dd58 100644
> --- a/drivers/iio/magnetometer/hid-sensor-magn-3d.c
> +++ b/drivers/iio/magnetometer/hid-sensor-magn-3d.c
> @@ -542,7 +542,7 @@ static int hid_magn_3d_probe(struct
> platform_device *pdev)
> error_iio_unreg:
> iio_device_unregister(indio_dev);
> error_remove_trigger:
> - hid_sensor_remove_trigger(indio_dev, &magn_state-
> >magn_flux_attributes);
> + hid_sensor_remove_trigger(&magn_state-
> >magn_flux_attributes);
> return ret;
> }
>
> @@ -555,7 +555,7 @@ static void hid_magn_3d_remove(struct
> platform_device *pdev)
>
> sensor_hub_remove_callback(hsdev,
> HID_USAGE_SENSOR_COMPASS_3D);
> iio_device_unregister(indio_dev);
> - hid_sensor_remove_trigger(indio_dev, &magn_state-
> >magn_flux_attributes);
> + hid_sensor_remove_trigger(&magn_state-
> >magn_flux_attributes);
> }
>
> static const struct platform_device_id hid_magn_3d_ids[] = {
> diff --git a/drivers/iio/orientation/hid-sensor-incl-3d.c
> b/drivers/iio/orientation/hid-sensor-incl-3d.c
> index 4e23a598a3fb..56fd9c53dfc2 100644
> --- a/drivers/iio/orientation/hid-sensor-incl-3d.c
> +++ b/drivers/iio/orientation/hid-sensor-incl-3d.c
> @@ -378,7 +378,7 @@ static int hid_incl_3d_probe(struct
> platform_device *pdev)
> error_iio_unreg:
> iio_device_unregister(indio_dev);
> error_remove_trigger:
> - hid_sensor_remove_trigger(indio_dev, &incl_state-
> >common_attributes);
> + hid_sensor_remove_trigger(&incl_state->common_attributes);
> return ret;
> }
>
> @@ -391,7 +391,7 @@ static void hid_incl_3d_remove(struct
> platform_device *pdev)
>
> sensor_hub_remove_callback(hsdev,
> HID_USAGE_SENSOR_INCLINOMETER_3D);
> iio_device_unregister(indio_dev);
> - hid_sensor_remove_trigger(indio_dev, &incl_state-
> >common_attributes);
> + hid_sensor_remove_trigger(&incl_state->common_attributes);
> }
>
> static const struct platform_device_id hid_incl_3d_ids[] = {
> diff --git a/drivers/iio/orientation/hid-sensor-rotation.c
> b/drivers/iio/orientation/hid-sensor-rotation.c
> index 4a11e4555099..56fdb3412fe3 100644
> --- a/drivers/iio/orientation/hid-sensor-rotation.c
> +++ b/drivers/iio/orientation/hid-sensor-rotation.c
> @@ -353,7 +353,7 @@ static int hid_dev_rot_probe(struct
> platform_device *pdev)
> error_iio_unreg:
> iio_device_unregister(indio_dev);
> error_remove_trigger:
> - hid_sensor_remove_trigger(indio_dev, &rot_state-
> >common_attributes);
> + hid_sensor_remove_trigger(&rot_state->common_attributes);
> return ret;
> }
>
> @@ -366,7 +366,7 @@ static void hid_dev_rot_remove(struct
> platform_device *pdev)
>
> sensor_hub_remove_callback(hsdev, hsdev->usage);
> iio_device_unregister(indio_dev);
> - hid_sensor_remove_trigger(indio_dev, &rot_state-
> >common_attributes);
> + hid_sensor_remove_trigger(&rot_state->common_attributes);
> }
>
> static const struct platform_device_id hid_dev_rot_ids[] = {
> diff --git a/drivers/iio/position/hid-sensor-custom-intel-hinge.c
> b/drivers/iio/position/hid-sensor-custom-intel-hinge.c
> index a26d391661fd..5288b63f4e21 100644
> --- a/drivers/iio/position/hid-sensor-custom-intel-hinge.c
> +++ b/drivers/iio/position/hid-sensor-custom-intel-hinge.c
> @@ -337,7 +337,7 @@ static int hid_hinge_probe(struct platform_device
> *pdev)
> error_remove_callback:
> sensor_hub_remove_callback(hsdev, hsdev->usage);
> error_remove_trigger:
> - hid_sensor_remove_trigger(indio_dev, &st-
> >common_attributes);
> + hid_sensor_remove_trigger(&st->common_attributes);
> return ret;
> }
>
> @@ -350,7 +350,7 @@ static void hid_hinge_remove(struct
> platform_device *pdev)
>
> iio_device_unregister(indio_dev);
> sensor_hub_remove_callback(hsdev, hsdev->usage);
> - hid_sensor_remove_trigger(indio_dev, &st-
> >common_attributes);
> + hid_sensor_remove_trigger(&st->common_attributes);
> }
>
> static const struct platform_device_id hid_hinge_ids[] = {
> diff --git a/drivers/iio/pressure/hid-sensor-press.c
> b/drivers/iio/pressure/hid-sensor-press.c
> index 5f1d6abda3e4..2bf5d055e175 100644
> --- a/drivers/iio/pressure/hid-sensor-press.c
> +++ b/drivers/iio/pressure/hid-sensor-press.c
> @@ -319,7 +319,7 @@ static int hid_press_probe(struct platform_device
> *pdev)
> error_iio_unreg:
> iio_device_unregister(indio_dev);
> error_remove_trigger:
> - hid_sensor_remove_trigger(indio_dev, &press_state-
> >common_attributes);
> + hid_sensor_remove_trigger(&press_state->common_attributes);
> return ret;
> }
>
> @@ -332,7 +332,7 @@ static void hid_press_remove(struct
> platform_device *pdev)
>
> sensor_hub_remove_callback(hsdev,
> HID_USAGE_SENSOR_PRESSURE);
> iio_device_unregister(indio_dev);
> - hid_sensor_remove_trigger(indio_dev, &press_state-
> >common_attributes);
> + hid_sensor_remove_trigger(&press_state->common_attributes);
> }
>
> static const struct platform_device_id hid_press_ids[] = {
> diff --git a/drivers/iio/temperature/hid-sensor-temperature.c
> b/drivers/iio/temperature/hid-sensor-temperature.c
> index 9f628a8e5cfb..60d4fcc8043b 100644
> --- a/drivers/iio/temperature/hid-sensor-temperature.c
> +++ b/drivers/iio/temperature/hid-sensor-temperature.c
> @@ -253,7 +253,7 @@ static int hid_temperature_probe(struct
> platform_device *pdev)
> error_remove_callback:
> sensor_hub_remove_callback(hsdev,
> HID_USAGE_SENSOR_TEMPERATURE);
> error_remove_trigger:
> - hid_sensor_remove_trigger(indio_dev, &temp_st-
> >common_attributes);
> + hid_sensor_remove_trigger(&temp_st->common_attributes);
> return ret;
> }
>
> @@ -265,7 +265,7 @@ static void hid_temperature_remove(struct
> platform_device *pdev)
> struct temperature_state *temp_st = iio_priv(indio_dev);
>
> sensor_hub_remove_callback(hsdev,
> HID_USAGE_SENSOR_TEMPERATURE);
> - hid_sensor_remove_trigger(indio_dev, &temp_st-
> >common_attributes);
> + hid_sensor_remove_trigger(&temp_st->common_attributes);
> }
>
> static const struct platform_device_id hid_temperature_ids[] = {
^ permalink raw reply
* [PATCH v5 2/2] Input: isa1200 - new driver for Imagis ISA1200
From: Svyatoslav Ryhel @ 2026-05-12 10:24 UTC (permalink / raw)
To: Dmitry Torokhov, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Linus Walleij, Svyatoslav Ryhel
Cc: linux-input, devicetree, linux-kernel
In-Reply-To: <20260512102445.55372-1-clamor95@gmail.com>
From: Linus Walleij <linusw@kernel.org>
The ISA1200 is a haptic feedback unit from Imagis Technology using two
motors for haptic feedback in mobile phones. Used in many mobile devices
c. 2012 including Samsung Galxy S Advance GT-I9070 (Janice), Samsung Beam
GT-I8350 (Gavini), LG Optimus 4X P880 and LG Optimus Vu P895.
The exact datasheet for the ISA1200 is not available; all data was modeled
based on available downstream kernel sources for various devices and
fragments of information scattered across the internet.
Tested-by: Linus Walleij <linusw@kernel.org> # GT-I9070 Janice
Signed-off-by: Linus Walleij <linusw@kernel.org>
Co-developed-by: Svyatoslav Ryhel <clamor95@gmail.com>
Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
---
drivers/input/misc/Kconfig | 12 +
drivers/input/misc/Makefile | 1 +
drivers/input/misc/isa1200.c | 524 +++++++++++++++++++++++++++++++++++
3 files changed, 537 insertions(+)
create mode 100644 drivers/input/misc/isa1200.c
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 94a753fcb64f..52f192104ee2 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -852,6 +852,18 @@ config INPUT_IQS7222
To compile this driver as a module, choose M here: the
module will be called iqs7222.
+config INPUT_ISA1200_HAPTIC
+ tristate "Imagis ISA1200 haptic feedback unit"
+ depends on I2C
+ select INPUT_FF_MEMLESS
+ select REGMAP_I2C
+ help
+ Say Y to enable support for the Imagis ISA1200 haptic
+ feedback unit.
+
+ To compile this driver as a module, choose M here: the
+ module will be called isa1200.
+
config INPUT_CMA3000
tristate "VTI CMA3000 Tri-axis accelerometer"
help
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index 415fc4e2918b..d62bf2e9d85f 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -49,6 +49,7 @@ obj-$(CONFIG_INPUT_IMS_PCU) += ims-pcu.o
obj-$(CONFIG_INPUT_IQS269A) += iqs269a.o
obj-$(CONFIG_INPUT_IQS626A) += iqs626a.o
obj-$(CONFIG_INPUT_IQS7222) += iqs7222.o
+obj-$(CONFIG_INPUT_ISA1200_HAPTIC) += isa1200.o
obj-$(CONFIG_INPUT_KEYSPAN_REMOTE) += keyspan_remote.o
obj-$(CONFIG_INPUT_KXTJ9) += kxtj9.o
obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o
diff --git a/drivers/input/misc/isa1200.c b/drivers/input/misc/isa1200.c
new file mode 100644
index 000000000000..ff82252a08e1
--- /dev/null
+++ b/drivers/input/misc/isa1200.c
@@ -0,0 +1,524 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include <linux/array_size.h>
+#include <linux/bitmap.h>
+#include <linux/bits.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/devm-helpers.h>
+#include <linux/err.h>
+#include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/input.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/property.h>
+#include <linux/pwm.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+#include <linux/units.h>
+
+/*
+ * System control (LDO regulator)
+ *
+ * LDO voltage to register mapping is linear, but it is split in two parts:
+ * 2.3V - 3.0V map to 0x08 - 0x0f; 3.1V - 3.8V map to 0x00 - 0x7
+ */
+
+#define ISA1200_SCTRL 0x00
+#define ISA1200_LDO_VOLTAGE_BASE 0x08
+#define ISA1200_LDO_VOLTAGE_STEP 100000
+#define ISA1200_LDO_VOLTAGE_2V3 23
+#define ISA1200_LDO_VOLTAGE_3V1 31
+#define ISA1200_LDO_VOLTAGE_MIN 2300000
+#define ISA1200_LDO_VOLTAGE_MAX 3800000
+
+/*
+ * The output frequency is calculated with this formula:
+ *
+ * base clock frequency
+ * fout = -----------------------------------------
+ * (128 - PWM_FREQ) * 2 * PLLDIV * PWM_PERIOD
+ *
+ * The base clock frequency is the clock frequency provided on the
+ * clock input to the chip, divided by the value in HCTRL0
+ *
+ * PWM_FREQ is configured in register HCTRL4, it is common to set this
+ * to 0 to get only two variables to calculate.
+ *
+ * PLLDIV is configured in register HCTRL3 (bits 7..4, so 0..15)
+ * PWM_PERIOD is configured in register HCTRL6
+ * Further the duty cycle can be configured in HCTRL5
+ */
+
+/*
+ * HCTRL0 configures clock or PWM input and selects the divider for
+ * the clock input.
+ */
+#define ISA1200_HCTRL0 0x30
+#define ISA1200_HCTRL0_HAP_ENABLE BIT(7)
+#define ISA1200_HCTRL0_PWM_GEN_MODE BIT(4)
+#define ISA1200_HCTRL0_PWM_INPUT_MODE BIT(3)
+#define ISA1200_HCTRL0_CLKDIV_128 128
+
+/*
+ * HCTRL1 configures the motor type and clock sourse
+ */
+#define ISA1200_HCTRL1 0x31
+#define ISA1200_HCTRL1_EXT_CLOCK BIT(7)
+#define ISA1200_HCTRL1_DAC_INVERT BIT(6)
+#define ISA1200_HCTRL1_MODE(n) (((n) & 1) << 5)
+
+/* HCTRL2 controls software reset of the chip */
+#define ISA1200_HCTRL2 0x32
+#define ISA1200_HCTRL2_SW_RESET BIT(0)
+
+/*
+ * HCTRL3 controls the PLL divisor
+ *
+ * Bits [0,1] are always set to 1 (we don't know what they are
+ * used for) and bit 4 and upward control the PLL divisor.
+ */
+#define ISA1200_HCTRL3 0x33
+#define ISA1200_HCTRL3_DEFAULT 0x03
+#define ISA1200_HCTRL3_PLLDIV(n) (((n) & 0xf) << 4)
+
+/* HCTRL4 controls the PWM frequency of external channel */
+#define ISA1200_HCTRL4 0x34
+
+/* HCTRL5 controls the PWM high duty cycle of internal channel */
+#define ISA1200_HCTRL5 0x35
+
+/* HCTRL6 controls the PWM period of internal channel */
+#define ISA1200_HCTRL6 0x36
+#define ISA1200_HCTRL6_PERIOD_SCALE 100
+
+/* The use for these registers is unknown but they exist */
+#define ISA1200_HCTRL7 0x37
+#define ISA1200_HCTRL8 0x38
+#define ISA1200_HCTRL9 0x39
+#define ISA1200_HCTRLA 0x3a
+#define ISA1200_HCTRLB 0x3b
+#define ISA1200_HCTRLC 0x3c
+#define ISA1200_HCTRLD 0x3d
+
+#define ISA1200_EN_PINS_MAX 2
+
+static const struct regulator_bulk_data isa1200_supplies[] = {
+ { .supply = "vdd" }, { .supply = "vddp" },
+};
+
+struct isa1200_config {
+ u32 ldo_voltage;
+ u32 mode;
+ u32 clkdiv;
+ u32 plldiv;
+ u32 freq;
+ u32 period;
+ u32 duty;
+};
+
+struct isa1200 {
+ struct input_dev *input;
+ struct regmap *map;
+
+ struct clk *clk;
+ struct pwm_device *pwm;
+ struct gpio_descs *enable_gpios;
+ struct regulator_bulk_data *supplies;
+
+ struct work_struct play_work;
+ struct isa1200_config config;
+
+ bool active;
+ int level;
+};
+
+static const struct regmap_config isa1200_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+ .max_register = ISA1200_HCTRLD,
+};
+
+static void isa1200_start(struct isa1200 *isa)
+{
+ struct isa1200_config *config = &isa->config;
+ struct device *dev = &isa->input->dev;
+ struct pwm_state state;
+ u8 hctrl0 = 0, hctrl1 = 0;
+ DECLARE_BITMAP(values, ISA1200_EN_PINS_MAX);
+ int err;
+
+ if (!isa->active) {
+ err = regulator_bulk_enable(ARRAY_SIZE(isa1200_supplies),
+ isa->supplies);
+ if (err) {
+ dev_err(dev, "failed to enable supplies (%d)\n", err);
+ return;
+ }
+
+ err = clk_prepare_enable(isa->clk);
+ if (err) {
+ dev_err(dev, "failed to enable clock (%d)\n", err);
+ regulator_bulk_disable(ARRAY_SIZE(isa1200_supplies),
+ isa->supplies);
+ return;
+ }
+
+ bitmap_fill(values, ISA1200_EN_PINS_MAX);
+ gpiod_multi_set_value_cansleep(isa->enable_gpios, values);
+
+ usleep_range(200, 300);
+ }
+
+ regmap_write(isa->map, ISA1200_SCTRL, config->ldo_voltage);
+
+ if (isa->clk) {
+ hctrl0 = ISA1200_HCTRL0_PWM_GEN_MODE;
+ hctrl1 = ISA1200_HCTRL1_EXT_CLOCK;
+ }
+
+ if (isa->pwm) {
+ hctrl0 = ISA1200_HCTRL0_PWM_INPUT_MODE;
+ hctrl1 = 0;
+ }
+
+ hctrl0 |= __ffs(config->clkdiv / ISA1200_HCTRL0_CLKDIV_128);
+ hctrl1 |= ISA1200_HCTRL1_DAC_INVERT;
+ hctrl1 |= ISA1200_HCTRL1_MODE(config->mode);
+
+ regmap_write(isa->map, ISA1200_HCTRL0, hctrl0);
+ regmap_write(isa->map, ISA1200_HCTRL1, hctrl1);
+
+ /* Make sure to de-assert software reset */
+ regmap_write(isa->map, ISA1200_HCTRL2, 0x00);
+
+ /* PLL divisor */
+ regmap_write(isa->map, ISA1200_HCTRL3,
+ ISA1200_HCTRL3_PLLDIV(config->plldiv) |
+ ISA1200_HCTRL3_DEFAULT);
+
+ /* Frequency */
+ regmap_write(isa->map, ISA1200_HCTRL4, config->freq);
+ /* Duty cycle */
+ regmap_write(isa->map, ISA1200_HCTRL5, config->period >> 1);
+ /* Period */
+ regmap_write(isa->map, ISA1200_HCTRL6, config->period);
+
+ hctrl0 |= ISA1200_HCTRL0_HAP_ENABLE;
+ regmap_write(isa->map, ISA1200_HCTRL0, hctrl0);
+
+ if (isa->clk)
+ regmap_write(isa->map, ISA1200_HCTRL5, config->duty);
+
+ if (isa->pwm) {
+ pwm_get_state(isa->pwm, &state);
+ state.duty_cycle = config->duty;
+ state.enabled = true;
+ pwm_apply_might_sleep(isa->pwm, &state);
+ }
+
+ isa->active = true;
+}
+
+static void isa1200_stop(struct isa1200 *isa)
+{
+ struct pwm_state state;
+ DECLARE_BITMAP(values, ISA1200_EN_PINS_MAX);
+
+ if (!isa->active)
+ return;
+
+ if (isa->pwm) {
+ pwm_get_state(isa->pwm, &state);
+ state.duty_cycle = 0;
+ state.enabled = false;
+ pwm_apply_might_sleep(isa->pwm, &state);
+ }
+
+ regmap_write(isa->map, ISA1200_HCTRL0, 0x00);
+
+ bitmap_zero(values, ISA1200_EN_PINS_MAX);
+ gpiod_multi_set_value_cansleep(isa->enable_gpios, values);
+
+ clk_disable_unprepare(isa->clk);
+ regulator_bulk_disable(ARRAY_SIZE(isa1200_supplies),
+ isa->supplies);
+
+ isa->active = false;
+ isa->level = 0;
+}
+
+static void isa1200_play_work(struct work_struct *work)
+{
+ struct isa1200 *isa = container_of(work, struct isa1200, play_work);
+
+ if (isa->level)
+ isa1200_start(isa);
+ else
+ isa1200_stop(isa);
+}
+
+static int isa1200_vibrator_play_effect(struct input_dev *input, void *data,
+ struct ff_effect *effect)
+{
+ struct isa1200 *isa = input_get_drvdata(input);
+ int level;
+
+ /*
+ * TODO: we currently only support rumble.
+ * The ISA1200 can control two motors and some devices
+ * also have two motors mounted.
+ */
+ level = effect->u.rumble.strong_magnitude;
+ if (!level)
+ level = effect->u.rumble.weak_magnitude;
+
+ dev_dbg(&input->dev, "FF effect type %d level %d\n",
+ effect->type, level);
+
+ if (isa->level != level) {
+ isa->level = level;
+ schedule_work(&isa->play_work);
+ }
+
+ return 0;
+}
+
+static void isa1200_vibrator_close(struct input_dev *input)
+{
+ struct isa1200 *isa = input_get_drvdata(input);
+
+ cancel_work_sync(&isa->play_work);
+ isa1200_stop(isa);
+}
+
+static int isa1200_of_probe(struct i2c_client *client)
+{
+ struct isa1200 *isa = i2c_get_clientdata(client);
+ struct isa1200_config *config = &isa->config;
+ struct device *dev = &client->dev;
+ struct fwnode_handle *ldo_node;
+ int err;
+
+ isa->clk = devm_clk_get_optional(dev, NULL);
+ if (IS_ERR(isa->clk))
+ return dev_err_probe(dev, PTR_ERR(isa->clk),
+ "failed to get clock\n");
+
+ isa->pwm = devm_pwm_get(dev, NULL);
+ if (IS_ERR(isa->pwm)) {
+ err = PTR_ERR(isa->pwm);
+ if (err == -ENODEV || err == -EINVAL)
+ isa->pwm = NULL;
+ else
+ return dev_err_probe(dev, err, "getting PWM\n");
+ }
+
+ if (!isa->clk && !isa->pwm)
+ return dev_err_probe(dev, -EINVAL,
+ "clock or PWM are required, none were provided\n");
+
+ err = devm_regulator_bulk_get_const(dev, ARRAY_SIZE(isa1200_supplies),
+ isa1200_supplies, &isa->supplies);
+ if (err)
+ return dev_err_probe(dev, err, "failed to get supplies\n");
+
+ isa->enable_gpios = devm_gpiod_get_array_optional(dev, "control",
+ GPIOD_OUT_LOW);
+ if (IS_ERR(isa->enable_gpios))
+ return dev_err_probe(dev, PTR_ERR(isa->enable_gpios),
+ "failed to get enable gpios\n");
+
+ ldo_node = device_get_named_child_node(dev, "ldo");
+ if (!ldo_node)
+ return dev_err_probe(dev, -ENODEV,
+ "failed to get embedded LDO node\n");
+
+ err = fwnode_property_read_u32(ldo_node, "regulator-min-microvolt",
+ &config->ldo_voltage);
+ fwnode_handle_put(ldo_node);
+ if (err)
+ return dev_err_probe(dev, err,
+ "failed to get ldo voltage\n");
+
+ config->ldo_voltage = clamp(config->ldo_voltage,
+ ISA1200_LDO_VOLTAGE_MIN,
+ ISA1200_LDO_VOLTAGE_MAX);
+
+ config->ldo_voltage /= ISA1200_LDO_VOLTAGE_STEP;
+ if (config->ldo_voltage < ISA1200_LDO_VOLTAGE_3V1)
+ config->ldo_voltage = config->ldo_voltage -
+ ISA1200_LDO_VOLTAGE_2V3 +
+ ISA1200_LDO_VOLTAGE_BASE;
+ else
+ config->ldo_voltage -= ISA1200_LDO_VOLTAGE_3V1;
+
+ config->mode = 0; /* LRA_MODE */
+ device_property_read_u32(dev, "imagis,mode", &config->mode);
+
+ config->clkdiv = ISA1200_HCTRL0_CLKDIV_128;
+ device_property_read_u32(dev, "imagis,clk-div", &config->clkdiv);
+ if (!config->clkdiv)
+ return dev_err_probe(dev, -EINVAL, "clk-div cannot be zero\n");
+
+ config->clkdiv = clamp(config->clkdiv, ISA1200_HCTRL0_CLKDIV_128,
+ ISA1200_HCTRL0_CLKDIV_128 << 3);
+
+ err = device_property_read_u32(dev, "imagis,pll-div", &config->plldiv);
+ if (err || !config->plldiv)
+ config->plldiv = 1;
+
+ config->period = 0;
+ config->freq = 0;
+ config->duty = 0;
+
+ if (isa->clk) {
+ err = device_property_read_u32(dev, "imagis,period-ns",
+ &config->period);
+ if (err)
+ return dev_err_probe(dev, err,
+ "failed to get period\n");
+
+ /*
+ * TODO: The scale value is arbitrary, but it fits observations
+ * quite well, and the exact conversion method is unknown.
+ * The period property value returned above is the HCTRL6
+ * register value set by the vendor code, multiplied by 100.
+ */
+ config->period /= ISA1200_HCTRL6_PERIOD_SCALE;
+ config->duty = config->period >> 1;
+ }
+
+ if (isa->pwm) {
+ struct pwm_state state;
+
+ pwm_init_state(isa->pwm, &state);
+
+ if (!state.period)
+ return dev_err_probe(dev, -EINVAL,
+ "PWM period cannot be zero\n");
+
+ config->freq = div64_u64(NANO, state.period * config->clkdiv);
+ config->duty = state.period >> 1;
+
+ err = pwm_apply_might_sleep(isa->pwm, &state);
+ if (err)
+ return dev_err_probe(dev, err,
+ "failed to apply initial PWM state\n");
+ }
+
+ /*
+ * TODO: If device is using a clock, this property should return the
+ * value written to the HCTRL5 register by downstrem code. It likely
+ * needs to be converted into a meaningful duty cycle value, though
+ * unfortunately the exact conversion mechanism is unknown. If the
+ * device uses PWM, this property will return the correct duty cycle
+ * in nanoseconds.
+ */
+ device_property_read_u32(dev, "imagis,duty-cycle-ns", &config->duty);
+
+ return 0;
+}
+
+static int isa1200_probe(struct i2c_client *client)
+{
+ struct isa1200 *isa;
+ struct device *dev = &client->dev;
+ int err;
+
+ isa = devm_kzalloc(dev, sizeof(*isa), GFP_KERNEL);
+ if (!isa)
+ return -ENOMEM;
+
+ isa->input = devm_input_allocate_device(dev);
+ if (!isa->input)
+ return -ENOMEM;
+
+ i2c_set_clientdata(client, isa);
+
+ err = isa1200_of_probe(client);
+ if (err)
+ return err;
+
+ isa->map = devm_regmap_init_i2c(client, &isa1200_regmap_config);
+ if (IS_ERR(isa->map))
+ return dev_err_probe(dev, PTR_ERR(isa->map),
+ "failed to initialize register map\n");
+
+ INIT_WORK(&isa->play_work, isa1200_play_work);
+
+ isa->input->name = "isa1200-haptic";
+ isa->input->id.bustype = BUS_I2C;
+ isa->input->close = isa1200_vibrator_close;
+
+ isa->active = false;
+
+ input_set_drvdata(isa->input, isa);
+
+ /* TODO: this hardware can likely support more than rumble */
+ input_set_capability(isa->input, EV_FF, FF_RUMBLE);
+
+ err = input_ff_create_memless(isa->input, NULL,
+ isa1200_vibrator_play_effect);
+ if (err)
+ return dev_err_probe(dev, err, "failed to create FF dev\n");
+
+ err = input_register_device(isa->input);
+ if (err)
+ return dev_err_probe(dev, err, "failed to register input dev\n");
+
+ return 0;
+}
+
+static int isa1200_suspend(struct device *dev)
+{
+ struct isa1200 *isa = dev_get_drvdata(dev);
+
+ guard(mutex)(&isa->input->mutex);
+
+ if (input_device_enabled(isa->input)) {
+ cancel_work_sync(&isa->play_work);
+ if (isa->level)
+ isa1200_stop(isa);
+ }
+
+ return 0;
+}
+
+static int isa1200_resume(struct device *dev)
+{
+ struct isa1200 *isa = dev_get_drvdata(dev);
+
+ guard(mutex)(&isa->input->mutex);
+
+ if (input_device_enabled(isa->input))
+ if (isa->level)
+ isa1200_start(isa);
+
+ return 0;
+}
+
+static DEFINE_SIMPLE_DEV_PM_OPS(isa1200_pm_ops, isa1200_suspend, isa1200_resume);
+
+static const struct of_device_id isa1200_of_match[] = {
+ { .compatible = "imagis,isa1200" },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, isa1200_of_match);
+
+static struct i2c_driver isa1200_i2c_driver = {
+ .driver = {
+ .name = "isa1200",
+ .of_match_table = isa1200_of_match,
+ .pm = pm_sleep_ptr(&isa1200_pm_ops),
+ },
+ .probe = isa1200_probe,
+};
+module_i2c_driver(isa1200_i2c_driver);
+
+MODULE_AUTHOR("Linus Walleij <linusw@kernel.org>");
+MODULE_AUTHOR("Svyatoslav Ryhel <clamor95@gmail.com>");
+MODULE_DESCRIPTION("Imagis ISA1200 haptic feedback unit");
+MODULE_LICENSE("GPL");
--
2.51.0
^ permalink raw reply related
* [PATCH v5 1/2] dt-bindings: input: Document Imagis ISA1200 haptic motor driver
From: Svyatoslav Ryhel @ 2026-05-12 10:24 UTC (permalink / raw)
To: Dmitry Torokhov, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Linus Walleij, Svyatoslav Ryhel
Cc: linux-input, devicetree, linux-kernel
In-Reply-To: <20260512102445.55372-1-clamor95@gmail.com>
Document the Imagis ISA1200 haptic motor driver, used primarily in mobile
handheld devices and capable of supporting up to two motors.
The exact datasheet for the ISA1200 is not available; all data was modeled
based on available downstream kernel sources for various devices and
fragments of information scattered across the internet.
Signed-off-by: Svyatoslav Ryhel <clamor95@gmail.com>
---
.../bindings/input/imagis,isa1200.yaml | 140 ++++++++++++++++++
1 file changed, 140 insertions(+)
create mode 100644 Documentation/devicetree/bindings/input/imagis,isa1200.yaml
diff --git a/Documentation/devicetree/bindings/input/imagis,isa1200.yaml b/Documentation/devicetree/bindings/input/imagis,isa1200.yaml
new file mode 100644
index 000000000000..bbe6f99d39c1
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/imagis,isa1200.yaml
@@ -0,0 +1,140 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/input/imagis,isa1200.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Imagis ISA1200 haptic motor driver
+
+maintainers:
+ - Svyatoslav Ryhel <clamor95@gmail.com>
+ - Linus Walleij <linusw@kernel.org>
+
+description:
+ The ISA1200 is a high-performance enhanced haptic motor driver designed
+ for mobile hand-held devices. It supports various voltages for both ERM
+ (Eccentric Rotating Mass) and LRA (Linear Resonant Actuator) type
+ actuators. Thanks to an embedded LDO, battery power can be used directly
+ in handheld applications.
+
+properties:
+ compatible:
+ const: imagis,isa1200
+
+ reg:
+ maxItems: 1
+
+ control-gpios:
+ description:
+ One or two GPIOs flagged as active high linked to HEN and LEN pins
+ maxItems: 2
+
+ clocks:
+ maxItems: 1
+
+ pwms:
+ maxItems: 1
+
+ vdd-supply:
+ description:
+ Regulator for 2.4V - 5.5V power supply
+
+ vddp-supply:
+ description:
+ Regulator for 2.4V - 3.6V IO power supply
+
+ imagis,clk-div:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description:
+ Divider for the external input clock/PWM
+ enum: [128, 256, 512, 1024]
+ default: 128
+
+ imagis,pll-div:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description:
+ Divider for the internal PLL clock
+ minimum: 1
+ maximum: 15
+ default: 1
+
+ imagis,mode:
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ Defines the motor type isa1200 drives
+ 0 - LRA (Linear Resonant Actuator)
+ 1 - ERM (Eccentric Rotating Mass)
+ enum: [0, 1]
+ default: 0
+
+ imagis,period-ns:
+ description:
+ Period of the internal PWM channel in nanoseconds.
+ minimum: 10000
+ maximum: 30000
+
+ imagis,duty-cycle-ns:
+ description:
+ Duty cycle of the external/internal PWM channel in nanoseconds,
+ defaults to 50% of the channel's period
+
+ ldo:
+ $ref: /schemas/regulator/regulator.yaml#
+ type: object
+ description:
+ Embedded LDO regulator with voltage range 2.3V - 3.8V
+ unevaluatedProperties: false
+
+ required:
+ - regulator-min-microvolt
+ - regulator-max-microvolt
+
+required:
+ - compatible
+ - reg
+ - ldo
+
+anyOf:
+ - required:
+ - clocks
+ - imagis,period-ns
+ - required:
+ - pwms
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/gpio/gpio.h>
+
+ i2c {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ haptic-engine@49 {
+ compatible = "imagis,isa1200";
+ reg = <0x49>;
+
+ clocks = <&isa1200_refclk>;
+
+ control-gpios = <&gpio 22 GPIO_ACTIVE_HIGH>,
+ <&gpio 23 GPIO_ACTIVE_HIGH>;
+
+ vdd-supply = <&vdd_3v3_vbat>;
+ vddp-supply = <&vdd_2v8_vvib>;
+
+ imagis,clk-div = <256>;
+ imagis,pll-div = <2>;
+
+ imagis,mode = <0>; /* LRA_MODE */
+
+ imagis,period-ns = <13400>;
+ imagis,duty-cycle-ns = <100>;
+
+ ldo {
+ regulator-name = "vdd_vib";
+ regulator-min-microvolt = <2300000>;
+ regulator-max-microvolt = <2300000>;
+ };
+ };
+ };
--
2.51.0
^ permalink raw reply related
* [PATCH v5 0/2] input: misc: add support for Imagis ISA1200 haptic motor driver
From: Svyatoslav Ryhel @ 2026-05-12 10:24 UTC (permalink / raw)
To: Dmitry Torokhov, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Linus Walleij, Svyatoslav Ryhel
Cc: linux-input, devicetree, linux-kernel
The ISA1200 is a haptic feedback unit from Imagis Technology using two
motors for haptic feedback in mobile phones. Used in many mobile devices
c. 2012 including Samsung Galxy S Advance GT-I9070 (Janice), Samsung Beam
GT-I8350 (Gavini), LG Optimus 4X P880 and LG Optimus Vu P895.
The exact datasheet for the ISA1200 is not available; all data was modeled
based on available downstream kernel sources for various devices and
fragments of information scattered across the internet.
---
Changes in v5:
- added supplies to private structure
- clk_on dropped
- ret > err
- added active flag to track status
- all hardware manipulations consolidated in start/stop
- dropped mutex from work
- dropped active check from isa1200_vibrator_close it was
moved to stop directly
- dropped hw maniplations from probe
- bustype set to BUS_I2C
- adjusted error strings
- fixed cancel_work_sync in isa1200_suspend
Changes in v4:
- added INPUT_FF_MEMLESS option selection
- fixed missing clock status set
- guard start/stop calls in isa1200_play_work with lock
- clamp ldo voltages to allowed range
- fixed imagis,pll-div parsing
- dropped Tested-by from schema adding commit
Changes in v3:
- added clock state tracking
- dropped level check in vibrator close
- added clkdiv clamping
- added comments regarding registers 5 and 6
Changes in v2:
- imagis,clk-div switched to accept actual divider value
- dropped DT header
- adjusted imagis,period-ns range
- initiated hctrl0 and hctrl1 values in isa1200_start
- fixed situation when PWM might return -EPROBE_DEFER to be
treated properly
- added chech a clock or PWM is available
- fixed regulator voltages check being off by 10
- added chech if state.period is not zero
- added action call to disable clock and gpios on error
- used managed version of work init
- added work cancel on suspend
- PW calls are done under mutex lock
---
Linus Walleij (1):
Input: isa1200 - new driver for Imagis ISA1200
Svyatoslav Ryhel (1):
dt-bindings: input: Document Imagis ISA1200 haptic motor driver
.../bindings/input/imagis,isa1200.yaml | 140 +++++
drivers/input/misc/Kconfig | 12 +
drivers/input/misc/Makefile | 1 +
drivers/input/misc/isa1200.c | 524 ++++++++++++++++++
4 files changed, 677 insertions(+)
create mode 100644 Documentation/devicetree/bindings/input/imagis,isa1200.yaml
create mode 100644 drivers/input/misc/isa1200.c
--
2.51.0
^ permalink raw reply
* Re: [PATCH v3 0/4] HID: Proper fix for OOM in hid-core
From: Lee Jones @ 2026-05-12 10:17 UTC (permalink / raw)
To: Benjamin Tissoires
Cc: Jiri Kosina, Filipe Laíns, Bastien Nocera, Ping Cheng,
Jason Gerecke, Viresh Kumar, Johan Hovold, Alex Elder,
Greg Kroah-Hartman, Icenowy Zheng, linux-input, linux-kernel,
greybus-dev, linux-staging, linux-usb, stable
In-Reply-To: <20260506091606.GB305027@google.com>
On Wed, 06 May 2026, Lee Jones wrote:
> On Mon, 04 May 2026, Benjamin Tissoires wrote:
>
> > Commit 0a3fe972a7cb ("HID: core: Mitigate potential OOB by removing
> > bogus memset()") enforced the provided data to be at least the size of
> > the declared buffer in the report descriptor to prevent a buffer
> > overflow.
> >
> > We only had corner cases of malicious devices exposing the OOM because
> > in most cases, the buffer provided by the transport layer needs to be
> > allocated at probe time and is large enough to handle all the possible
> > reports.
> >
> > However, the patch from above, which enforces the spec a little bit more
> > introduced both regressions for devices not following the spec (not
> > necesserally malicious), but also a stream of errors for those devices.
> >
> > Let's revert to the old behavior by giving more information to HID core
> > to be able to decide whether it can or not memset the rest of the buffer
> > to 0 and continue the processing.
> >
> > Note that the first commit makes an API change, but the callers are
> > relatively limited, so it should be fine on its own. The second patch
> > can't really make the same kind of API change because we have too many
> > callers in various subsystems. We can switch them one by one to the safe
> > approach when needed.
> >
> > The last 2 patches are small cleanups I initially put together with the
> > 2 first patches, but they can be applied on their own and don't need to
> > be pulled in stable like the first 2.
> >
> > Cheers,
> > Benjamin
> >
> > Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>
> > ---
> > Changes in v3:
> > - fixed ghib -> ghid in greybus
> > - fixed i386 size_t debug size reported by kernel-bot
> > - Link to v2: https://lore.kernel.org/r/20260416-wip-fix-core-v2-0-be92570e5627@kernel.org
> >
> > Changes in v2:
> > - added a small blurb explaining the difference between the safe and the
> > non safe version of hid_safe_input_report
> > - Link to v1: https://lore.kernel.org/r/20260415-wip-fix-core-v1-0-ed3c4c823175@kernel.org
> >
> > ---
> > Benjamin Tissoires (4):
> > HID: pass the buffer size to hid_report_raw_event
> > HID: core: introduce hid_safe_input_report()
> > HID: multitouch: use __free(kfree) to clean up temporary buffers
> > HID: wacom: use __free(kfree) to clean up temporary buffers
> >
> > drivers/hid/bpf/hid_bpf_dispatch.c | 6 ++--
> > drivers/hid/hid-core.c | 67 ++++++++++++++++++++++++++++++--------
> > drivers/hid/hid-gfrm.c | 4 +--
> > drivers/hid/hid-logitech-hidpp.c | 2 +-
> > drivers/hid/hid-multitouch.c | 18 ++++------
> > drivers/hid/hid-primax.c | 2 +-
> > drivers/hid/hid-vivaldi-common.c | 2 +-
> > drivers/hid/i2c-hid/i2c-hid-core.c | 7 ++--
> > drivers/hid/usbhid/hid-core.c | 11 ++++---
> > drivers/hid/wacom_sys.c | 46 +++++++++-----------------
> > drivers/staging/greybus/hid.c | 2 +-
> > include/linux/hid.h | 6 ++--
> > include/linux/hid_bpf.h | 14 +++++---
> > 13 files changed, 109 insertions(+), 78 deletions(-)
>
> What's the plan for this set Benjamin? -rcs or -next?
Are there any updates on this set please?
FYI, this set is still important to us.
Ideally, if all is well, it would go into the -rcs for v7.1.
--
Lee Jones
^ permalink raw reply
* Re: [PATCH] ipv6: addrconf: skip autoconf on unregistering devices
From: Xu Rao @ 2026-05-12 9:24 UTC (permalink / raw)
To: jikos, bentiss; +Cc: linux-input, linux-kernel, raoxu
Hi Eric,
Thanks for the review.
> 1) I presume this targets the net tree, rather than net-next?
Yes, this is intended for the net tree. I will keep the subject as
"[PATCH net v2]".
> 2) Please add a Fixes: tag
I looked for a Fixes target, but I could not identify a single commit
which introduced this exact bug with enough confidence. The path which
can create an IPv6 link-local address from NETDEV_UP/NETDEV_CHANGE is
very old, while the failure depends on an unregister-time race between
rtnetlink flag changes, addrconf autoconfiguration, and netdev teardown.
Because this looks like a long-standing lifecycle gap exposed by this
race rather than a clear regression from one commit, I did not want to
add a misleading Fixes tag. If you prefer a historical Fixes tag for
netdev requirements, I can add the closest addrconf change you think is
appropriate in v2.
> 3) Why READ_ONCE() are needed there?
I used READ_ONCE() in v1 because dev->reg_state is written with
WRITE_ONCE() in the unregister path and netdev_reg_state() also reads it
with READ_ONCE(). However, addrconf_notify() is called from the
netdevice notifier path and does not need lockless access semantics for
this check. I will switch this to a plain dev->reg_state load in v2.
> 4) Make sure in V2 to CC netdev@ mailing list
> 5) Please wait ~24 hours before sending a V2.
I will also make sure to CC netdev@vger.kernel.org on v2 and will wait
about 24 hours before sending it, as requested.
Thanks,
Xu Rao
^ 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