* Re: [PATCH v2] HID: ft260: validate report size and payload length in raw_event
From: Jiri Kosina @ 2026-04-09 15:50 UTC (permalink / raw)
To: Sebastian Josue Alba Vives
Cc: michael.zaidman, Benjamin Tissoires, linux-i2c, linux-input,
linux-kernel, stable
In-Reply-To: <20260324201858.46591-1-sebasjosue84@gmail.com>
On Tue, 24 Mar 2026, Sebastian Josue Alba Vives wrote:
> ft260_raw_event() casts the raw data buffer to a
> ft260_i2c_input_report struct and accesses its fields without
> validating the size parameter. Since __hid_input_report() invokes
> the driver's raw_event callback before hid_report_raw_event()
> performs its own report-size validation, a device sending a
> truncated HID report can cause out-of-bounds heap reads.
>
> Additionally, even with a full-sized report, a corrupted
> xfer->length field can cause memcpy to read beyond the report
> buffer. The existing check only validates against the destination
> buffer size, not the source data available in the report.
>
> Add two checks: reject reports shorter than FT260_REPORT_MAX_LENGTH,
> and verify that xfer->length does not exceed the actual data
> available in the report. Log warnings to aid debugging.
>
> Cc: stable@vger.kernel.org
> Signed-off-by: Sebastian Josue Alba Vives <sebasjosue84@gmail.com>
> ---
> drivers/hid/hid-ft260.c | 11 +++++++++++
> 1 file changed, 11 insertions(+)
>
> diff --git a/drivers/hid/hid-ft260.c b/drivers/hid/hid-ft260.c
> index 333341e80..68008a423 100644
> --- a/drivers/hid/hid-ft260.c
> +++ b/drivers/hid/hid-ft260.c
> @@ -1068,6 +1068,17 @@ static int ft260_raw_event(struct hid_device *hdev, struct hid_report *report,
> struct ft260_device *dev = hid_get_drvdata(hdev);
> struct ft260_i2c_input_report *xfer = (void *)data;
>
> + if (size < FT260_REPORT_MAX_LENGTH) {
> + hid_warn(hdev, "short report: %d\n", size);
> + return 0;
Michael, can you please confirm whether the device can never legitimately
send shorter than FT260_REPORT_MAX_LENGTH reports?
Thanks,
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: [PATCH] hid: usbhid: fix deadlock in hid_post_reset()
From: Jiri Kosina @ 2026-04-09 15:48 UTC (permalink / raw)
To: Oliver Neukum; +Cc: bentiss, linux-input, linux-usb
In-Reply-To: <036cb81b-ae6e-4dcd-8f97-593e754279d1@suse.com>
On Mon, 30 Mar 2026, Oliver Neukum wrote:
> > Did you find this just by code inspection, or was this reported with a
> > real device?
>
> Pure inspection. We are looking at USB error handling
> in general right now.
OK, thanks. Now queued in hid.git.
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: [PATCH] HID: apple: ensure the keyboard backlight is off if suspending
From: Jiri Kosina @ 2026-04-09 15:46 UTC (permalink / raw)
To: Aditya Garg
Cc: Benjamin Tissoires, linux-input, linux-kernel, stable,
André Eikmeyer
In-Reply-To: <MAUPR01MB115467C51E492BD620ED390B6B85FA@MAUPR01MB11546.INDPRD01.PROD.OUTLOOK.COM>
On Sat, 4 Apr 2026, Aditya Garg wrote:
> Some users reported that upon suspending their keyboard backlight
> remained on. Fix this by adding the missing LED_CORE_SUSPENDRESUME flag.
>
> Cc: stable@vger.kernel.org
> Fixes: 394ba612f941 ("HID: apple: Add support for magic keyboard backlight on T2 Macs")
> Fixes: 9018eacbe623 ("HID: apple: Add support for keyboard backlight on certain T2 Macs.")
> Reported-by: André Eikmeyer <andre.eikmeyer@gmail.com>
> Tested-by: André Eikmeyer <andre.eikmeyer@gmail.com>
> Signed-off-by: Aditya Garg <gargaditya08@live.com>
Applied, thanks.
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: [PATCH] HID: quirks: Set ALWAYS_POLL for LOGITECH_BOLT_RECEIVER
From: Jiri Kosina @ 2026-04-09 15:45 UTC (permalink / raw)
To: Nícolas F. R. A. Prado
Cc: Benjamin Tissoires, kernel, linux-input, linux-kernel
In-Reply-To: <20260407-logi-bolt-hid-quirk-always-poll-v1-1-4dae0fda344e@collabora.com>
On Tue, 7 Apr 2026, Nícolas F. R. A. Prado wrote:
> The Logitech Bolt receiver once connected to a wireless device will
> generate data on interface 2. If this data isn't polled, when the USB
> port it is connected to gets suspended (and if that happens within 5
> minutes of the last input from the wireless device), it will trigger a
> remote wakeup 3 seconds later, which will result in a spurious system
> wakeup if the port was suspended as part of system sleep.
>
> Set the ALWAYS_POLL quirk for this device to ensure interface 2 is
> always polled and this spurious wakeup never happens.
>
> With this change in place the system can be suspended with the receiver
> plugged in and the system can be woken up when an input is sent from the
> wireless device.
>
> Signed-off-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
> ---
> Hi,
>
> Given that the polling only needs to happen before the device goes into
> suspend, I wonder if it might make sense to introduce a new quirk type
> that only does a poll before the device goes into suspend (both for
> system sleep and runtime suspend). It would reduce the extra bit of USB
> traffic that ends up happening in this case with ALWAYS_POLL every time
> a wireless device connects to the receiver.
I don't think it's worth the hassle, but if you feel strongly about it, I
wouldn't object too strongly.
In the meantime, I am applying this one. Thanks,
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: [PATCH] HID: winwing: add support for URSA MINOR combat joysticks
From: Jiri Kosina @ 2026-04-09 15:43 UTC (permalink / raw)
To: René Onier; +Cc: linux-input, bentiss, ivan.gorinov
In-Reply-To: <20260404172641.195619-1-rene.onier@gmail.com>
On Sat, 4 Apr 2026, René Onier wrote:
> Add device IDs for the Winwing URSA MINOR Combat Joystick L (0xbc29)
> and R (0xbc2a). These joysticks declare 128 buttons in their HID
> report descriptor, causing the generic HID driver to reject buttons
> above KEY_MAX (767) with "Invalid code" errors.
>
> The URSA MINOR joysticks use buttons in the 33-64 range for grip
> controls including the index trigger, so map_more_buttons is set
> to 1 to enable the extended KEY_MACRO mapping.
>
> Tested with both left and right URSA MINOR joysticks on kernel 6.19.
>
> Signed-off-by: René Onier <rene.onier@gmail.com>
> ---
> hid-winwing.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/hid-winwing.c b/hid-winwing.c
> index ab65dc1..f3e6ea0 100644
> --- a/hid-winwing.c
> +++ b/hid-winwing.c
Thanks for the patch!
You seem to have generated it however without a full path, so it can't be
applied using standard patch -p1 way ... could you please fix that up and
resend?
Thanks,
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: [PATCH] HID: alps: fix NULL pointer dereference in alps_raw_event()
From: Jiri Kosina @ 2026-04-09 15:37 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: linux-input, linux-kernel, stable, Benjamin Tissoires, Masaki Ota
In-Reply-To: <2026040624-overjoyed-impart-6fa4@gregkh>
On Mon, 6 Apr 2026, Greg Kroah-Hartman wrote:
> Commit ecfa6f34492c ("HID: Add HID_CLAIMED_INPUT guards in raw_event
> callbacks missing them") attempted to fix up the HID drivers that had
> missed the previous fix that was done in 2ff5baa9b527 ("HID: appleir:
> Fix potential NULL dereference at raw event handle"), but the alps
> driver was missed.
>
> Fix this up by properly checking in the hid-alps driver that it had been
> claimed correctly before attempting to process the raw event.
>
> Fixes: 73196ebe134d ("HID: alps: add support for Alps T4 Touchpad device")
> Cc: stable <stable@kernel.org>
> Cc: Jiri Kosina <jikos@kernel.org>
> Cc: Benjamin Tissoires <bentiss@kernel.org>
> Cc: Masaki Ota <masaki.ota@jp.alps.com>
> Cc: linux-input@vger.kernel.org
> Assisted-by: gregkh_clanker_t1000
> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Applied, thanks.
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: [PATCH v2 1/2] HID: logitech-dj: Standardise hid_report_enum variable nomenclature
From: Jiri Kosina @ 2026-04-09 15:36 UTC (permalink / raw)
To: Lee Jones
Cc: Filipe Laíns, Benjamin Tissoires, linux-input, linux-kernel
In-Reply-To: <20260407135955.GQ3795166@google.com>
On Tue, 7 Apr 2026, Lee Jones wrote:
> > Since we will need to differentiate between the two report_enum types
> > soon, let's unify the naming conventions now to save confusion and/or
> > unnecessary/unrelated changes in upcoming commits.
> >
> > {input,output}_report_enum is used in other places to let's conform.
> >
> > Signed-off-by: Lee Jones <lee@kernel.org>
> > ---
> > v1 => v2: New patch
> >
> > drivers/hid/hid-logitech-dj.c | 12 ++++++------
> > 1 file changed, 6 insertions(+), 6 deletions(-)
>
> During a previous submission you indicated that you preferred pings over
> [RESEND]s - so this is it.
>
> This submission was posted 2 weeks ago. Could someone take a look please?
Sorry for the delay. Now applied. Thanks!
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: [PATCH] HID: sony: update module description
From: Jiri Kosina @ 2026-04-09 15:34 UTC (permalink / raw)
To: Rosalie Wanders; +Cc: Benjamin Tissoires, linux-input, linux-kernel
In-Reply-To: <20260402155915.17745-2-rosalie@mailbox.org>
On Thu, 2 Apr 2026, Rosalie Wanders wrote:
> This commit updates the hid-sony module description to make it correct
> with the recent hid-sony changes alongside making it more consistent.
>
> Signed-off-by: Rosalie Wanders <rosalie@mailbox.org>
Applied, thanks.
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: [PATCH] HID: logitech-hidpp: Check bounds when deleting force-feedback effects
From: Jiri Kosina @ 2026-04-09 15:27 UTC (permalink / raw)
To: Günther Noack
Cc: Filipe Laíns, Bastien Nocera, Benjamin Tissoires, Lee Jones,
linux-input, linux-kernel
In-Reply-To: <20260331074052.194064-1-gnoack@google.com>
On Tue, 31 Mar 2026, Günther Noack wrote:
> Without this bounds check, this might otherwise overwrite index -1.
>
> Triggering this condition requires action both from the USB device and from
> userspace, which reduces the scenarios in which it can be exploited.
>
> Cc: Lee Jones <lee@kernel.org>
> Signed-off-by: G=C3=BCnther Noack <gnoack@google.com>
Applied, thanks.
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: [PATCH 2/2] arm64: dts: qcom: sdm845-oneplus: Update compatible to include model
From: David Heidelberg @ 2026-04-09 15:19 UTC (permalink / raw)
To: Konrad Dybcio, Dmitry Torokhov, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jason A. Donenfeld, Matthias Schiffer,
Vincent Huang, Bjorn Andersson, Konrad Dybcio
Cc: linux-input, devicetree, linux-kernel, linux-arm-msm, phone-devel,
Krzysztof Kozlowski
In-Reply-To: <80067706-1857-46a0-a281-7f4ff3937468@oss.qualcomm.com>
On 09/04/2026 14:41, Konrad Dybcio wrote:
> On 4/8/26 7:34 PM, David Heidelberg via B4 Relay wrote:
>> From: David Heidelberg <david@ixit.cz>
>>
>> We know the driver is reporting s3706b, introduce the compatible so we
>
> via Google search AI summary:
> "Bon Chef S3706B is a black dinner fork (Roman Euro Dinner Fork)" - the
> more you know!
Oh no, that's definitely not compatible hardware! Maybe it's some fork... :P
^ permalink raw reply
* Re: [PATCH] Docs: hid: intel-ish-hid: make long URL usable
From: Jonathan Corbet @ 2026-04-09 14:42 UTC (permalink / raw)
To: Randy Dunlap, linux-kernel
Cc: Randy Dunlap, Jiri Kosina, Benjamin Tissoires,
Srinivas Pandruvada, linux-input, Shuah Khan, linux-doc
In-Reply-To: <20260321230934.435020-1-rdunlap@infradead.org>
Randy Dunlap <rdunlap@infradead.org> writes:
> The '\' line continuation character in this long URL
> doesn't help anything. There is no documentation tooling that
> handles the line continuation character to join the 2 lines
> to make a usable URL. Web browsers terminate the URL just
> before the '\' character so that the second line of the URL
> is lost. See:
> https://docs.kernel.org/hid/intel-ish-hid.html
>
> Join the 2 lines together so that the URL is usable.
>
> Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
> ---
> Cc: Jiri Kosina <jikos@kernel.org>
> Cc: Benjamin Tissoires <bentiss@kernel.org>
> Cc: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
> Cc: linux-input@vger.kernel.org
> Cc: Jonathan Corbet <corbet@lwn.net>
> Cc: Shuah Khan <skhan@linuxfoundation.org>
> Cc: linux-doc@vger.kernel.org
>
> Documentation/hid/intel-ish-hid.rst | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> --- linux-next-20260320.orig/Documentation/hid/intel-ish-hid.rst
> +++ linux-next-20260320/Documentation/hid/intel-ish-hid.rst
> @@ -163,8 +163,8 @@ The transport layer is a bi-directional
> - A flow control mechanism to avoid buffer overflows
>
> This protocol resembles bus messages described in the following document:
> -http://www.intel.com/content/dam/www/public/us/en/documents/technical-\
> -specifications/dcmi-hi-1-0-spec.pdf "Chapter 7: Bus Message Layer"
> +http://www.intel.com/content/dam/www/public/us/en/documents/technical-specifications/dcmi-hi-1-0-spec.pdf
> +"Chapter 7: Bus Message Layer".
Applied, thanks.
jon
^ permalink raw reply
* Re: [PATCH 2/2] arm64: dts: qcom: sdm845-oneplus: Update compatible to include model
From: Konrad Dybcio @ 2026-04-09 12:41 UTC (permalink / raw)
To: david, Dmitry Torokhov, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Jason A. Donenfeld, Matthias Schiffer,
Vincent Huang, Bjorn Andersson, Konrad Dybcio
Cc: linux-input, devicetree, linux-kernel, linux-arm-msm, phone-devel,
Krzysztof Kozlowski
In-Reply-To: <20260408-synaptics-rmi4-dt-v1-2-2d32bacce673@ixit.cz>
On 4/8/26 7:34 PM, David Heidelberg via B4 Relay wrote:
> From: David Heidelberg <david@ixit.cz>
>
> We know the driver is reporting s3706b, introduce the compatible so we
via Google search AI summary:
"Bon Chef S3706B is a black dinner fork (Roman Euro Dinner Fork)" - the
more you know!
> can more easily introduce quirks for weird touchscreen replacements in
> followup series.
>
> Signed-off-by: David Heidelberg <david@ixit.cz>
> ---
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Konrad
^ permalink raw reply
* Re: [PATCH 0/2] HID: multitouch: Add support for Dell Pro Rugged 12 Tablet RA02260
From: buingoc67 @ 2026-04-09 5:13 UTC (permalink / raw)
To: jikos; +Cc: bentiss, buingoc67, linux-input, linux-kernel
In-Reply-To: <4op5533p-s086-55sr-oso5-30qsnqpq407n@xreary.bet>
Hi, I don't understand why it take my email "buingoc67" instead
of the git user.name that I set as "hmtheboy154". Is there any way
that I can change this ? Or else I'll submit the changes under my
org email (hmtheboy154@blisslabs.org) if that's ok.
^ permalink raw reply
* Re: [PATCH v4 11/11] arm64: dts: qcom: sdm845-google: Add STM FTS touchscreen support
From: Dmitry Baryshkov @ 2026-04-08 23:56 UTC (permalink / raw)
To: david
Cc: Dmitry Torokhov, Maxime Coquelin, Alexandre Torgue, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Henrik Rydberg,
Bjorn Andersson, Konrad Dybcio, Petr Hodina, linux-input,
linux-stm32, linux-arm-kernel, linux-kernel, Krzysztof Kozlowski,
devicetree, linux-arm-msm, phone-devel, Konrad Dybcio
In-Reply-To: <20260409-stmfts5-v4-11-64fe62027db5@ixit.cz>
On Thu, Apr 09, 2026 at 12:15:54AM +0200, David Heidelberg via B4 Relay wrote:
> From: Petr Hodina <petr.hodina@protonmail.com>
>
> Basic touchscreen connected to second i2c bus.
>
> Signed-off-by: Petr Hodina <petr.hodina@protonmail.com>
> Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
> Co-developed-by: David Heidelberg <david@ixit.cz>
> Signed-off-by: David Heidelberg <david@ixit.cz>
> ---
> arch/arm64/boot/dts/qcom/sdm845-google-blueline.dts | 19 ++++++++++++++++++-
> arch/arm64/boot/dts/qcom/sdm845-google-common.dtsi | 2 +-
> 2 files changed, 19 insertions(+), 2 deletions(-)
>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
--
With best wishes
Dmitry
^ permalink raw reply
* Re: [PATCH v2] HID: sony: add support for more instruments
From: Jiri Kosina @ 2026-04-08 22:44 UTC (permalink / raw)
To: Rosalie
Cc: Benjamin Tissoires, Sanjay Govind, Brenton Simpson, linux-input,
linux-kernel
In-Reply-To: <21996a49-6408-4fbc-b11f-0d9cc503ad10@mailbox.org>
On Thu, 9 Apr 2026, Rosalie wrote:
> It looks fine to me code wise, and it compiles! but you forgot to apply a
> patch you applied earlier to the for-7.1/sony branch, namely 'HID: sony:
> update module description'
Thanks for checking.
Yes, I am aware of that one missing for now, it's in the queue for next
time.
> Other than that, it's fine, and again I apologize for the chaos,
Np. Thanks,
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: [PATCH v2] HID: sony: add support for more instruments
From: Rosalie @ 2026-04-08 22:41 UTC (permalink / raw)
To: Jiri Kosina
Cc: Benjamin Tissoires, Sanjay Govind, Brenton Simpson, linux-input,
linux-kernel
In-Reply-To: <r803963p-778n-84p8-3046-s7118rr376pp@xreary.bet>
On 4/9/26 00:19, Jiri Kosina wrote:
> On Thu, 9 Apr 2026, Rosalie wrote:
>
>> Yes I do apologize, and I'll be mindful of either doing a series, mark
>> dependencies clearly or do a pull request.
>>
>> I didn't expect to be sending this many patches at all in the first place, but
>> one minor annoyance of the code bothers me one day and then another day
>> someone else mentions that e.g a device name is incorrect, so that kinda led
>> to this chaos.
>>
>> Apologies and I'll try preventing it in the future, and thanks for the advice,
>
> No worries. I've just update hid.git#for-7.1/sony and I believe it's now
> in proper state with all the patch dependencies correctly captured. If you
> see any issue there, please let me know.
>
> Thanks,
>
It looks fine to me code wise, and it compiles! but you forgot to apply
a patch you applied earlier to the for-7.1/sony branch, namely 'HID:
sony: update module description'
Other than that, it's fine, and again I apologize for the chaos,
Rosalie
^ permalink raw reply
* Re: [PATCH] HID: apple: Add Niz keyboard dongle to non-apple keyboards list
From: Jiri Kosina @ 2026-04-08 22:25 UTC (permalink / raw)
To: utzcoz; +Cc: Benjamin Tissoires, linux-input, linux-kernel
In-Reply-To: <20260403161806.31908-1-utzcoz@gmail.com>
On Sat, 4 Apr 2026, utzcoz wrote:
> Niz X99 uses a 2.4GHz wireless dongle (Milsky LL Dongle) that
> reports Apple's vendor and product IDs (05ac:0220), causing
> hid-apple to apply Apple function key translation. Since the
> dongle has no Apple Fn key, F1-F12 become unreachable when fnmode
> defaults to media-first behavior.
>
> Add the Milsky LL Dongle to the non_apple_keyboards list so that
> fnmode=3 (auto) correctly resolves to fnmode=2, making F1-F12 work
> as standard function keys.
>
> Signed-off-by: utzcoz <utzcoz@gmail.com>
Thanks a lot for the patches.
I know that the kernel documentation is now a little bit more liberal
about not having to use real names, but "well established identities"
being fine, but stil ... would you mind submitting this under some more
comprehensible authorship? (anonymous submissions are still not allowed,
BTW).
utzcoz doesn't really sound too well established identity to me,
unfortunately ... if it is, I'd be happy to stay corrected.
Thanks again,
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: [PATCH 0/3] HID: apple: reinitialize T2 HID devices after resume
From: Jiri Kosina @ 2026-04-08 22:24 UTC (permalink / raw)
To: deqrocks; +Cc: benjamin.tissoires, linux-input
In-Reply-To: <20260403130620.91999-1-andre@negmaster.com>
On Fri, 3 Apr 2026, deqrocks wrote:
> This series improves suspend and resume handling for Apple T2 based Macs.
>
> On affected systems, Apple T2 HID-backed devices can disappear across suspend and resume and come back with freshly enumerated interfaces. Reusing the pre-suspend device state leaves parts of the stack non-functional after resume, especially keyboard backlight and Touch Bar related devices.
>
> This series adds the required Apple T2 HID identifiers, wires up PM handling for the relevant Apple HID path, and reworks teardown and reprobe handling so stale state is discarded and devices are initialized again after resume.
>
> Tested on: MacBookAir9,1, MacBookPro15,1, MacBookPro16,1, MacBookPro16,2, MacBookPro16,4
Thanks a lot for the patches.
I know that the kernel documentation is now a little bit more liberal
about not having to use real names, but "well established identities"
being fine, but stil ... would you mind submitting this under some more
comprehensible authorship? (anonymous submissions are still not allowed,
BTW).
deqrocks doesn't really sound too well established identity to me,
unfortunately ... if it is, I'd be happy to stay corrected.
Thanks a lot,
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: [PATCH v2] HID: sony: add support for more instruments
From: Jiri Kosina @ 2026-04-08 22:19 UTC (permalink / raw)
To: Rosalie
Cc: Benjamin Tissoires, Sanjay Govind, Brenton Simpson, linux-input,
linux-kernel
In-Reply-To: <cb0617fb-76b0-4241-8fba-982a5ffa4525@mailbox.org>
On Thu, 9 Apr 2026, Rosalie wrote:
> Yes I do apologize, and I'll be mindful of either doing a series, mark
> dependencies clearly or do a pull request.
>
> I didn't expect to be sending this many patches at all in the first place, but
> one minor annoyance of the code bothers me one day and then another day
> someone else mentions that e.g a device name is incorrect, so that kinda led
> to this chaos.
>
> Apologies and I'll try preventing it in the future, and thanks for the advice,
No worries. I've just update hid.git#for-7.1/sony and I believe it's now
in proper state with all the patch dependencies correctly captured. If you
see any issue there, please let me know.
Thanks,
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* [PATCH v4 11/11] arm64: dts: qcom: sdm845-google: Add STM FTS touchscreen support
From: David Heidelberg via B4 Relay @ 2026-04-08 22:15 UTC (permalink / raw)
To: Dmitry Torokhov, Maxime Coquelin, Alexandre Torgue, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Henrik Rydberg,
Bjorn Andersson, Konrad Dybcio
Cc: Petr Hodina, linux-input, linux-stm32, linux-arm-kernel,
linux-kernel, Krzysztof Kozlowski, devicetree, linux-arm-msm,
phone-devel, David Heidelberg, Konrad Dybcio
In-Reply-To: <20260409-stmfts5-v4-0-64fe62027db5@ixit.cz>
From: Petr Hodina <petr.hodina@protonmail.com>
Basic touchscreen connected to second i2c bus.
Signed-off-by: Petr Hodina <petr.hodina@protonmail.com>
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Co-developed-by: David Heidelberg <david@ixit.cz>
Signed-off-by: David Heidelberg <david@ixit.cz>
---
arch/arm64/boot/dts/qcom/sdm845-google-blueline.dts | 19 ++++++++++++++++++-
arch/arm64/boot/dts/qcom/sdm845-google-common.dtsi | 2 +-
2 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/sdm845-google-blueline.dts b/arch/arm64/boot/dts/qcom/sdm845-google-blueline.dts
index fa89be500fb85..8fb988130b551 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-google-blueline.dts
+++ b/arch/arm64/boot/dts/qcom/sdm845-google-blueline.dts
@@ -26,7 +26,24 @@ &i2c2 {
status = "okay";
- /* ST,FTS @ 49 */
+ touchscreen@49 {
+ compatible = "st,stmfts5";
+ reg = <0x49>;
+
+ pinctrl-0 = <&touchscreen_irq_n>, <&touchscreen_reset>;
+ pinctrl-names = "default";
+
+ interrupts-extended = <&tlmm 125 IRQ_TYPE_LEVEL_LOW>;
+
+ mode-switch-gpios = <&tlmm 136 GPIO_ACTIVE_HIGH>;
+ reset-gpios = <&tlmm 99 GPIO_ACTIVE_LOW>;
+
+ avdd-supply = <&vreg_l14a_1p8>;
+ vdd-supply = <&vreg_l19a_3p3>;
+
+ touchscreen-size-x = <1080>;
+ touchscreen-size-y = <2160>;
+ };
};
&mdss_dsi0 {
diff --git a/arch/arm64/boot/dts/qcom/sdm845-google-common.dtsi b/arch/arm64/boot/dts/qcom/sdm845-google-common.dtsi
index 6930066857768..4653c63ec26d2 100644
--- a/arch/arm64/boot/dts/qcom/sdm845-google-common.dtsi
+++ b/arch/arm64/boot/dts/qcom/sdm845-google-common.dtsi
@@ -466,7 +466,7 @@ touchscreen_reset: ts-reset-state {
bias-pull-up;
};
- touchscreen_pins: ts-pins-gpio-state {
+ touchscreen_irq_n: ts-irq-n-gpio-state {
pins = "gpio125";
function = "gpio";
drive-strength = <2>;
--
2.53.0
^ permalink raw reply related
* [PATCH v4 07/11] dt-bindings: input: touchscreen: st,stmfts: Introduce reset GPIO
From: David Heidelberg via B4 Relay @ 2026-04-08 22:15 UTC (permalink / raw)
To: Dmitry Torokhov, Maxime Coquelin, Alexandre Torgue, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Henrik Rydberg,
Bjorn Andersson, Konrad Dybcio
Cc: Petr Hodina, linux-input, linux-stm32, linux-arm-kernel,
linux-kernel, Krzysztof Kozlowski, devicetree, linux-arm-msm,
phone-devel, David Heidelberg
In-Reply-To: <20260409-stmfts5-v4-0-64fe62027db5@ixit.cz>
From: David Heidelberg <david@ixit.cz>
FTS has associated reset GPIO, document it.
Signed-off-by: David Heidelberg <david@ixit.cz>
---
Documentation/devicetree/bindings/input/touchscreen/st,stmfts.yaml | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/Documentation/devicetree/bindings/input/touchscreen/st,stmfts.yaml b/Documentation/devicetree/bindings/input/touchscreen/st,stmfts.yaml
index 12256ae7df90d..64c4f24ea3dd0 100644
--- a/Documentation/devicetree/bindings/input/touchscreen/st,stmfts.yaml
+++ b/Documentation/devicetree/bindings/input/touchscreen/st,stmfts.yaml
@@ -40,6 +40,10 @@ properties:
vdd-supply:
description: Power supply
+ reset-gpios:
+ description: Reset GPIO (active-low)
+ maxItems: 1
+
required:
- compatible
- reg
--
2.53.0
^ permalink raw reply related
* [PATCH v4 09/11] dt-bindings: input: touchscreen: st,stmfts: Introduce STM FTS5
From: David Heidelberg via B4 Relay @ 2026-04-08 22:15 UTC (permalink / raw)
To: Dmitry Torokhov, Maxime Coquelin, Alexandre Torgue, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Henrik Rydberg,
Bjorn Andersson, Konrad Dybcio
Cc: Petr Hodina, linux-input, linux-stm32, linux-arm-kernel,
linux-kernel, Krzysztof Kozlowski, devicetree, linux-arm-msm,
phone-devel, David Heidelberg
In-Reply-To: <20260409-stmfts5-v4-0-64fe62027db5@ixit.cz>
From: David Heidelberg <david@ixit.cz>
Introduce more recent STM FTS5 touchscreen support.
Signed-off-by: David Heidelberg <david@ixit.cz>
---
.../devicetree/bindings/input/touchscreen/st,stmfts.yaml | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/input/touchscreen/st,stmfts.yaml b/Documentation/devicetree/bindings/input/touchscreen/st,stmfts.yaml
index 64c4f24ea3dd0..441fc92b9a4ed 100644
--- a/Documentation/devicetree/bindings/input/touchscreen/st,stmfts.yaml
+++ b/Documentation/devicetree/bindings/input/touchscreen/st,stmfts.yaml
@@ -16,10 +16,19 @@ description:
allOf:
- $ref: touchscreen.yaml#
+ - if:
+ properties:
+ compatible:
+ const: st,stmfts5
+ then:
+ required:
+ - mode-switch-gpios
properties:
compatible:
- const: st,stmfts
+ enum:
+ - st,stmfts
+ - st,stmfts5
reg:
maxItems: 1
@@ -40,6 +49,10 @@ properties:
vdd-supply:
description: Power supply
+ mode-switch-gpios:
+ description: Switch between touchscreen SLPI and AP mode.
+ maxItems: 1
+
reset-gpios:
description: Reset GPIO (active-low)
maxItems: 1
--
2.53.0
^ permalink raw reply related
* [PATCH v4 10/11] Input: stmfts - support FTS5
From: David Heidelberg via B4 Relay @ 2026-04-08 22:15 UTC (permalink / raw)
To: Dmitry Torokhov, Maxime Coquelin, Alexandre Torgue, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Henrik Rydberg,
Bjorn Andersson, Konrad Dybcio
Cc: Petr Hodina, linux-input, linux-stm32, linux-arm-kernel,
linux-kernel, Krzysztof Kozlowski, devicetree, linux-arm-msm,
phone-devel, David Heidelberg
In-Reply-To: <20260409-stmfts5-v4-0-64fe62027db5@ixit.cz>
From: Petr Hodina <petr.hodina@protonmail.com>
FTS support SLPI and AP mode, introduce mode-switch GPIO to switch between
those two. Currently we can handle only full power AP mode, so we just
keep the AP on.
Useful for devices like Pixel 3 (blueline) and many others.
Signed-off-by: Petr Hodina <petr.hodina@protonmail.com>
Co-developed-by: David Heidelberg <david@ixit.cz>
Signed-off-by: David Heidelberg <david@ixit.cz>
---
drivers/input/touchscreen/stmfts.c | 494 ++++++++++++++++++++++++++++++++++---
1 file changed, 466 insertions(+), 28 deletions(-)
diff --git a/drivers/input/touchscreen/stmfts.c b/drivers/input/touchscreen/stmfts.c
index 1e6d9a287cd0c..e613299e37557 100644
--- a/drivers/input/touchscreen/stmfts.c
+++ b/drivers/input/touchscreen/stmfts.c
@@ -1,8 +1,11 @@
// SPDX-License-Identifier: GPL-2.0
-// STMicroelectronics FTS Touchscreen device driver
-//
-// Copyright (c) 2017 Samsung Electronics Co., Ltd.
-// Copyright (c) 2017 Andi Shyti <andi@etezian.org>
+/* STMicroelectronics FTS Touchscreen device driver
+ *
+ * Copyright 2017 Samsung Electronics Co., Ltd.
+ * Copyright 2017 Andi Shyti <andi@etezian.org>
+ * Copyright David Heidelberg <david@ixit.cz>
+ * Copyright Petr Hodina <petr.hodina@protonmail.com>
+ */
#include <linux/delay.h>
#include <linux/i2c.h>
@@ -12,6 +15,7 @@
#include <linux/irq.h>
#include <linux/leds.h>
#include <linux/module.h>
+#include <linux/of_device.h>
#include <linux/pm_runtime.h>
#include <linux/regulator/consumer.h>
@@ -34,6 +38,7 @@
#define STMFTS_FULL_FORCE_CALIBRATION 0xa2
#define STMFTS_MS_CX_TUNING 0xa3
#define STMFTS_SS_CX_TUNING 0xa4
+#define STMFTS5_SET_SCAN_MODE 0xa0
/* events */
#define STMFTS_EV_NO_EVENT 0x00
@@ -51,12 +56,32 @@
#define STMFTS_EV_STATUS 0x16
#define STMFTS_EV_DEBUG 0xdb
+/* events FTS5 */
+#define STMFTS5_EV_CONTROLLER_READY 0x03
+/* FTM5 event IDs (full byte, not masked) */
+#define STMFTS5_EV_MULTI_TOUCH_ENTER 0x13
+#define STMFTS5_EV_MULTI_TOUCH_MOTION 0x23
+#define STMFTS5_EV_MULTI_TOUCH_LEAVE 0x33
+#define STMFTS5_EV_STATUS_UPDATE 0x43
+#define STMFTS5_EV_USER_REPORT 0x53
+#define STMFTS5_EV_DEBUG 0xe3
+#define STMFTS5_EV_ERROR 0xf3
+
/* multi touch related event masks */
#define STMFTS_MASK_EVENT_ID 0x0f
#define STMFTS_MASK_TOUCH_ID 0xf0
#define STMFTS_MASK_LEFT_EVENT 0x0f
#define STMFTS_MASK_X_MSB 0x0f
#define STMFTS_MASK_Y_LSB 0xf0
+#define STMFTS5_MASK_TOUCH_TYPE 0x0f
+
+/* touch type classifications */
+#define STMFTS_TOUCH_TYPE_INVALID 0x00
+#define STMFTS_TOUCH_TYPE_FINGER 0x01
+#define STMFTS_TOUCH_TYPE_GLOVE 0x02
+#define STMFTS_TOUCH_TYPE_STYLUS 0x03
+#define STMFTS_TOUCH_TYPE_PALM 0x04
+#define STMFTS_TOUCH_TYPE_HOVER 0x05
/* key related event masks */
#define STMFTS_MASK_KEY_NO_TOUCH 0x00
@@ -75,9 +100,12 @@ static const struct regulator_bulk_data stmfts_supplies[] = {
};
struct stmfts_data {
+ const struct stmfts_chip_ops *ops;
+
struct i2c_client *client;
struct input_dev *input;
struct gpio_desc *reset_gpio;
+ struct gpio_desc *mode_switch_gpio;
struct led_classdev led_cdev;
struct mutex mutex;
@@ -101,12 +129,27 @@ struct stmfts_data {
struct completion cmd_done;
+ unsigned long touch_id;
+ unsigned long stylus_id;
+
bool use_key;
bool led_status;
bool hover_enabled;
+ bool stylus_enabled;
bool running;
};
+struct stmfts_chip_ops {
+ int (*configure)(struct stmfts_data *sdata);
+ void (*power_off)(struct stmfts_data *sdata);
+ int (*setup_input)(struct stmfts_data *sdata);
+ int (*input_open)(struct input_dev *dev);
+ void (*input_close)(struct input_dev *dev);
+ void (*parse_events)(struct stmfts_data *sdata);
+ int (*set_hover)(struct stmfts_data *sdata, bool enable);
+ int (*runtime_resume)(struct stmfts_data *sdata);
+};
+
static int stmfts_brightness_set(struct led_classdev *led_cdev,
enum led_brightness value)
{
@@ -169,6 +212,7 @@ static int stmfts_read_events(struct stmfts_data *sdata)
return ret == ARRAY_SIZE(msgs) ? 0 : -EIO;
}
+/* FTS4 event handling functions */
static void stmfts_report_contact_event(struct stmfts_data *sdata,
const u8 event[])
{
@@ -204,6 +248,157 @@ static void stmfts_report_contact_release(struct stmfts_data *sdata,
input_sync(sdata->input);
}
+/* FTS5 event handling functions */
+static void stmfts5_report_contact_event(struct stmfts_data *sdata,
+ const u8 event[])
+{
+ u8 area;
+ u8 maj;
+ u8 min;
+ /* FTM5 event format:
+ * event[0] = event ID (0x13/0x23)
+ * event[1] = touch type (low 4 bits) | touch ID (high 4 bits)
+ * event[2] = X LSB
+ * event[3] = X MSB (low 4 bits) | Y MSB (high 4 bits)
+ * event[4] = Y LSB
+ * event[5] = pressure
+ * event[6] = major (low 4 bits) | minor (high 4 bits)
+ * event[7] = minor (high 2 bits)
+ */
+ u8 touch_id = (event[1] & STMFTS_MASK_TOUCH_ID) >> 4;
+ u8 touch_type = event[1] & STMFTS5_MASK_TOUCH_TYPE;
+ int x, y, distance;
+ unsigned int tool = MT_TOOL_FINGER;
+ bool touch_condition = true;
+
+ /* Parse coordinates with better precision */
+ x = (((int)event[3] & STMFTS_MASK_X_MSB) << 8) | event[2];
+ y = ((int)event[4] << 4) | ((event[3] & STMFTS_MASK_Y_LSB) >> 4);
+
+ /* Parse pressure - ensure non-zero for active touch */
+ area = event[5];
+ if (area <= 0 && touch_type != STMFTS_TOUCH_TYPE_HOVER) {
+ /* Should not happen for contact events. Set minimum pressure
+ * to prevent touch from being dropped
+ */
+ dev_warn_once(&sdata->client->dev,
+ "zero pressure on contact event, slot %d\n", touch_id);
+ area = 1;
+ }
+
+ /* Parse touch area with improved bit extraction */
+ maj = (((event[0] & 0x0C) << 2) | ((event[6] & 0xF0) >> 4));
+ min = (((event[7] & 0xC0) >> 2) | (event[6] & 0x0F));
+
+ /* Distance is 0 for touching, max for hovering */
+ distance = 0;
+
+ /* Classify touch type and set appropriate tool and parameters */
+ switch (touch_type) {
+ case STMFTS_TOUCH_TYPE_STYLUS:
+ if (sdata->stylus_enabled) {
+ tool = MT_TOOL_PEN;
+ __set_bit(touch_id, &sdata->stylus_id);
+ __clear_bit(touch_id, &sdata->touch_id);
+ break;
+ }
+ fallthrough; /* Report as finger if stylus not enabled */
+
+ case STMFTS_TOUCH_TYPE_FINGER:
+ case STMFTS_TOUCH_TYPE_GLOVE:
+ tool = MT_TOOL_FINGER;
+ __set_bit(touch_id, &sdata->touch_id);
+ __clear_bit(touch_id, &sdata->stylus_id);
+ break;
+
+ case STMFTS_TOUCH_TYPE_PALM:
+ /* Palm touch - report but can be filtered by userspace */
+ tool = MT_TOOL_PALM;
+ __set_bit(touch_id, &sdata->touch_id);
+ __clear_bit(touch_id, &sdata->stylus_id);
+ break;
+
+ case STMFTS_TOUCH_TYPE_HOVER:
+ tool = MT_TOOL_FINGER;
+ touch_condition = false;
+ area = 0;
+ distance = 255;
+ __set_bit(touch_id, &sdata->touch_id);
+ __clear_bit(touch_id, &sdata->stylus_id);
+ break;
+
+ case STMFTS_TOUCH_TYPE_INVALID:
+ default:
+ dev_warn(&sdata->client->dev,
+ "invalid touch type %d for slot %d\n",
+ touch_type, touch_id);
+ return;
+ }
+
+ /* Boundary check - some devices report max value, adjust */
+ if (x >= sdata->prop.max_x)
+ x = sdata->prop.max_x - 1;
+ if (y >= sdata->prop.max_y)
+ y = sdata->prop.max_y - 1;
+
+ input_mt_slot(sdata->input, touch_id);
+ input_report_key(sdata->input, BTN_TOUCH, touch_condition);
+ input_mt_report_slot_state(sdata->input, tool, true);
+
+ input_report_abs(sdata->input, ABS_MT_POSITION_X, x);
+ input_report_abs(sdata->input, ABS_MT_POSITION_Y, y);
+ input_report_abs(sdata->input, ABS_MT_TOUCH_MAJOR, maj);
+ input_report_abs(sdata->input, ABS_MT_TOUCH_MINOR, min);
+ input_report_abs(sdata->input, ABS_MT_PRESSURE, area);
+ input_report_abs(sdata->input, ABS_MT_DISTANCE, distance);
+
+ input_sync(sdata->input);
+}
+
+static void stmfts5_report_contact_release(struct stmfts_data *sdata,
+ const u8 event[])
+{
+ /* FTM5 format: touch ID is in high 4 bits of event[1] */
+ u8 touch_id = (event[1] & STMFTS_MASK_TOUCH_ID) >> 4;
+ u8 touch_type = event[1] & STMFTS5_MASK_TOUCH_TYPE;
+ unsigned int tool = MT_TOOL_FINGER;
+
+ /* Determine tool type based on touch classification */
+ switch (touch_type) {
+ case STMFTS_TOUCH_TYPE_STYLUS:
+ if (sdata->stylus_enabled) {
+ tool = MT_TOOL_PEN;
+ __clear_bit(touch_id, &sdata->stylus_id);
+ } else {
+ __clear_bit(touch_id, &sdata->touch_id);
+ }
+ break;
+
+ case STMFTS_TOUCH_TYPE_PALM:
+ tool = MT_TOOL_PALM;
+ __clear_bit(touch_id, &sdata->touch_id);
+ break;
+
+ case STMFTS_TOUCH_TYPE_FINGER:
+ case STMFTS_TOUCH_TYPE_GLOVE:
+ case STMFTS_TOUCH_TYPE_HOVER:
+ default:
+ tool = MT_TOOL_FINGER;
+ __clear_bit(touch_id, &sdata->touch_id);
+ break;
+ }
+
+ input_mt_slot(sdata->input, touch_id);
+ input_report_abs(sdata->input, ABS_MT_PRESSURE, 0);
+ input_mt_report_slot_state(sdata->input, tool, false);
+
+ /* Report BTN_TOUCH only if no touches remain */
+ if (!sdata->touch_id && !sdata->stylus_id)
+ input_report_key(sdata->input, BTN_TOUCH, 0);
+
+ input_sync(sdata->input);
+}
+
static void stmfts_report_hover_event(struct stmfts_data *sdata,
const u8 event[])
{
@@ -251,7 +446,6 @@ static void stmfts_parse_events(struct stmfts_data *sdata)
u8 *event = &sdata->data[i * STMFTS_EVENT_SIZE];
switch (event[0]) {
-
case STMFTS_EV_CONTROLLER_READY:
case STMFTS_EV_SLEEP_OUT_CONTROLLER_READY:
case STMFTS_EV_STATUS:
@@ -264,7 +458,6 @@ static void stmfts_parse_events(struct stmfts_data *sdata)
}
switch (event[0] & STMFTS_MASK_EVENT_ID) {
-
case STMFTS_EV_MULTI_TOUCH_ENTER:
case STMFTS_EV_MULTI_TOUCH_MOTION:
stmfts_report_contact_event(sdata, event);
@@ -298,6 +491,45 @@ static void stmfts_parse_events(struct stmfts_data *sdata)
}
}
+static void stmfts5_parse_events(struct stmfts_data *sdata)
+{
+ for (int i = 0; i < STMFTS_STACK_DEPTH; i++) {
+ u8 *event = &sdata->data[i * STMFTS_EVENT_SIZE];
+
+ switch (event[0]) {
+ case STMFTS5_EV_CONTROLLER_READY:
+ complete(&sdata->cmd_done);
+ fallthrough;
+
+ case STMFTS_EV_NO_EVENT:
+ case STMFTS5_EV_STATUS_UPDATE:
+ case STMFTS5_EV_USER_REPORT:
+ case STMFTS5_EV_DEBUG:
+ return;
+
+ case STMFTS5_EV_MULTI_TOUCH_ENTER:
+ case STMFTS5_EV_MULTI_TOUCH_MOTION:
+ stmfts5_report_contact_event(sdata, event);
+ break;
+
+ case STMFTS5_EV_MULTI_TOUCH_LEAVE:
+ stmfts5_report_contact_release(sdata, event);
+ break;
+
+ case STMFTS5_EV_ERROR:
+ dev_warn(&sdata->client->dev,
+ "error code: 0x%x%x%x%x%x%x",
+ event[6], event[5], event[4],
+ event[3], event[2], event[1]);
+ break;
+
+ default:
+ dev_err(&sdata->client->dev,
+ "unknown FTS5 event %#02x\n", event[0]);
+ }
+ }
+}
+
static irqreturn_t stmfts_irq_handler(int irq, void *dev)
{
struct stmfts_data *sdata = dev;
@@ -310,7 +542,7 @@ static irqreturn_t stmfts_irq_handler(int irq, void *dev)
dev_err(&sdata->client->dev,
"failed to read events: %d\n", err);
else
- stmfts_parse_events(sdata);
+ sdata->ops->parse_events(sdata);
return IRQ_HANDLED;
}
@@ -332,6 +564,25 @@ static int stmfts_command(struct stmfts_data *sdata, const u8 cmd)
return 0;
}
+static int stmfts5_set_scan_mode(struct stmfts_data *sdata, const u8 val)
+{
+ int err;
+
+ u8 scan_mode_cmd[3] = { STMFTS5_SET_SCAN_MODE, 0x00, val };
+ struct i2c_msg msg = {
+ .addr = sdata->client->addr,
+ .len = sizeof(scan_mode_cmd),
+ .buf = scan_mode_cmd,
+ };
+
+ err = i2c_transfer(sdata->client->adapter, &msg, 1);
+ if (err != 1)
+ return err < 0 ? err : -EIO;
+
+ return 0;
+
+}
+
static int stmfts_input_open(struct input_dev *dev)
{
struct stmfts_data *sdata = input_get_drvdata(dev);
@@ -371,6 +622,28 @@ static int stmfts_input_open(struct input_dev *dev)
return 0;
}
+static int stmfts5_input_open(struct input_dev *dev)
+{
+ struct stmfts_data *sdata = input_get_drvdata(dev);
+ int err;
+
+ err = pm_runtime_resume_and_get(&sdata->client->dev);
+ if (err)
+ return err;
+
+ mutex_lock(&sdata->mutex);
+ sdata->running = true;
+ mutex_unlock(&sdata->mutex);
+
+ err = stmfts5_set_scan_mode(sdata, 0xff);
+ if (err) {
+ pm_runtime_put_sync(&sdata->client->dev);
+ return err;
+ }
+
+ return 0;
+}
+
static void stmfts_input_close(struct input_dev *dev)
{
struct stmfts_data *sdata = input_get_drvdata(dev);
@@ -404,6 +677,23 @@ static void stmfts_input_close(struct input_dev *dev)
pm_runtime_put_sync(&sdata->client->dev);
}
+static void stmfts5_input_close(struct input_dev *dev)
+{
+ struct stmfts_data *sdata = input_get_drvdata(dev);
+ int err;
+
+ err = stmfts5_set_scan_mode(sdata, 0x00);
+ if (err)
+ dev_warn(&sdata->client->dev,
+ "failed to disable touchscreen: %d\n", err);
+
+ mutex_lock(&sdata->mutex);
+ sdata->running = false;
+ mutex_unlock(&sdata->mutex);
+
+ pm_runtime_put_sync(&sdata->client->dev);
+}
+
static ssize_t stmfts_sysfs_chip_id(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -484,10 +774,8 @@ static ssize_t stmfts_sysfs_hover_enable_write(struct device *dev,
guard(mutex)(&sdata->mutex);
if (hover != sdata->hover_enabled) {
- if (sdata->running) {
- err = i2c_smbus_write_byte(sdata->client,
- value ? STMFTS_SS_HOVER_SENSE_ON :
- STMFTS_SS_HOVER_SENSE_OFF);
+ if (sdata->running && sdata->ops->set_hover) {
+ err = sdata->ops->set_hover(sdata, hover);
if (err)
return err;
}
@@ -612,7 +900,7 @@ static int stmfts_power_on(struct stmfts_data *sdata)
if (sdata->reset_gpio)
stmfts_reset(sdata);
- err = stmfts_configure(sdata);
+ err = sdata->ops->configure(sdata);
if (err)
regulator_bulk_disable(ARRAY_SIZE(stmfts_supplies),
sdata->supplies);
@@ -620,6 +908,29 @@ static int stmfts_power_on(struct stmfts_data *sdata)
return err;
}
+static int stmfts5_configure(struct stmfts_data *sdata)
+{
+ u8 event[STMFTS_EVENT_SIZE];
+ int ret;
+
+ /* Verify I2C communication */
+ ret = i2c_smbus_read_i2c_block_data(sdata->client,
+ STMFTS_READ_ALL_EVENT,
+ sizeof(event), event);
+ if (ret < 0)
+ return ret;
+
+ enable_irq(sdata->client->irq);
+
+ return 0;
+}
+
+static void stmfts5_chip_power_off(struct stmfts_data *sdata)
+{
+ i2c_smbus_write_byte(sdata->client, STMFTS_SLEEP_IN);
+ msleep(20);
+}
+
static void stmfts_power_off(void *data)
{
struct stmfts_data *sdata = data;
@@ -629,10 +940,73 @@ static void stmfts_power_off(void *data)
if (sdata->reset_gpio)
gpiod_set_value_cansleep(sdata->reset_gpio, 1);
+ if (sdata->ops->power_off)
+ sdata->ops->power_off(sdata);
+
regulator_bulk_disable(ARRAY_SIZE(stmfts_supplies),
sdata->supplies);
}
+static int stmfts_setup_input(struct stmfts_data *sdata)
+{
+ struct device *dev = &sdata->client->dev;
+
+ input_set_abs_params(sdata->input, ABS_MT_ORIENTATION, 0, 255, 0, 0);
+ input_set_abs_params(sdata->input, ABS_DISTANCE, 0, 255, 0, 0);
+
+ sdata->use_key = device_property_read_bool(dev, "touch-key-connected");
+ if (sdata->use_key) {
+ input_set_capability(sdata->input, EV_KEY, KEY_MENU);
+ input_set_capability(sdata->input, EV_KEY, KEY_BACK);
+ }
+
+ return input_mt_init_slots(sdata->input, STMFTS_MAX_FINGERS,
+ INPUT_MT_DIRECT);
+}
+
+static int stmfts5_setup_input(struct stmfts_data *sdata)
+{
+ struct device *dev = &sdata->client->dev;
+
+ sdata->mode_switch_gpio = devm_gpiod_get_optional(dev, "mode-switch",
+ GPIOD_OUT_HIGH);
+ if (IS_ERR(sdata->mode_switch_gpio))
+ return dev_err_probe(dev, PTR_ERR(sdata->mode_switch_gpio),
+ "Failed to get GPIO 'switch'\n");
+
+ /* Mark as direct input device for calibration support */
+ __set_bit(INPUT_PROP_DIRECT, sdata->input->propbit);
+
+ /* Set up basic touch capabilities */
+ input_set_capability(sdata->input, EV_KEY, BTN_TOUCH);
+
+ /* Set resolution for accurate calibration */
+ if (!input_abs_get_res(sdata->input, ABS_MT_POSITION_X)) {
+ input_abs_set_res(sdata->input, ABS_MT_POSITION_X, 10);
+ input_abs_set_res(sdata->input, ABS_MT_POSITION_Y, 10);
+ }
+
+ input_set_abs_params(sdata->input, ABS_MT_DISTANCE, 0, 255, 0, 0);
+
+ /* Enable stylus support if requested */
+ sdata->stylus_enabled = device_property_read_bool(dev, "stylus-enabled");
+
+ /* Initialize touch tracking bitmaps */
+ sdata->touch_id = 0;
+ sdata->stylus_id = 0;
+
+ /* Initialize MT slots with support for pen tool type */
+ return input_mt_init_slots(sdata->input, STMFTS_MAX_FINGERS,
+ INPUT_MT_DIRECT | INPUT_MT_DROP_UNUSED);
+}
+
+static int stmfts_set_hover(struct stmfts_data *sdata, bool enable)
+{
+ return i2c_smbus_write_byte(sdata->client,
+ enable ? STMFTS_SS_HOVER_SENSE_ON :
+ STMFTS_SS_HOVER_SENSE_OFF);
+}
+
static int stmfts_enable_led(struct stmfts_data *sdata)
{
int err;
@@ -678,6 +1052,8 @@ static int stmfts_probe(struct i2c_client *client)
mutex_init(&sdata->mutex);
init_completion(&sdata->cmd_done);
+ sdata->ops = of_device_get_match_data(dev);
+
err = devm_regulator_bulk_get_const(dev,
ARRAY_SIZE(stmfts_supplies),
stmfts_supplies,
@@ -697,8 +1073,8 @@ static int stmfts_probe(struct i2c_client *client)
sdata->input->name = STMFTS_DEV_NAME;
sdata->input->id.bustype = BUS_I2C;
- sdata->input->open = stmfts_input_open;
- sdata->input->close = stmfts_input_close;
+ sdata->input->open = sdata->ops->input_open;
+ sdata->input->close = sdata->ops->input_close;
input_set_capability(sdata->input, EV_ABS, ABS_MT_POSITION_X);
input_set_capability(sdata->input, EV_ABS, ABS_MT_POSITION_Y);
@@ -706,19 +1082,9 @@ static int stmfts_probe(struct i2c_client *client)
input_set_abs_params(sdata->input, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
input_set_abs_params(sdata->input, ABS_MT_TOUCH_MINOR, 0, 255, 0, 0);
- input_set_abs_params(sdata->input, ABS_MT_ORIENTATION, 0, 255, 0, 0);
input_set_abs_params(sdata->input, ABS_MT_PRESSURE, 0, 255, 0, 0);
- input_set_abs_params(sdata->input, ABS_DISTANCE, 0, 255, 0, 0);
-
- sdata->use_key = device_property_read_bool(dev,
- "touch-key-connected");
- if (sdata->use_key) {
- input_set_capability(sdata->input, EV_KEY, KEY_MENU);
- input_set_capability(sdata->input, EV_KEY, KEY_BACK);
- }
- err = input_mt_init_slots(sdata->input,
- STMFTS_MAX_FINGERS, INPUT_MT_DIRECT);
+ err = sdata->ops->setup_input(sdata);
if (err)
return err;
@@ -789,13 +1155,62 @@ static int stmfts_runtime_suspend(struct device *dev)
return ret;
}
-static int stmfts_runtime_resume(struct device *dev)
+static int stmfts_chip_runtime_resume(struct stmfts_data *sdata)
+{
+ return i2c_smbus_write_byte(sdata->client, STMFTS_SLEEP_OUT);
+}
+
+static int stmfts5_chip_runtime_resume(struct stmfts_data *sdata)
{
- struct stmfts_data *sdata = dev_get_drvdata(dev);
struct i2c_client *client = sdata->client;
+ struct device *dev = &client->dev;
+ u8 int_enable_cmd[4] = {0xB6, 0x00, 0x2C, 0x01};
+ struct i2c_msg msg = {
+ .addr = client->addr,
+ .len = sizeof(int_enable_cmd),
+ .buf = int_enable_cmd,
+ };
int ret;
ret = i2c_smbus_write_byte(client, STMFTS_SLEEP_OUT);
+ if (ret)
+ return ret;
+
+ msleep(20);
+
+ /* Perform capacitance tuning after wakeup */
+ ret = i2c_smbus_write_byte(client, STMFTS_MS_CX_TUNING);
+ if (ret)
+ dev_warn(dev, "MS_CX_TUNING failed: %d\n", ret);
+ msleep(20);
+
+ ret = i2c_smbus_write_byte(client, STMFTS_SS_CX_TUNING);
+ if (ret)
+ dev_warn(dev, "SS_CX_TUNING failed: %d\n", ret);
+ msleep(20);
+
+ /* Force calibration */
+ ret = i2c_smbus_write_byte(client, STMFTS_FULL_FORCE_CALIBRATION);
+ if (ret)
+ dev_warn(dev, "FORCE_CALIBRATION failed: %d\n", ret);
+ msleep(50);
+
+ /* Enable controller interrupts */
+ ret = i2c_transfer(client->adapter, &msg, 1);
+ if (ret != 1)
+ return ret < 0 ? ret : -EIO;
+
+ msleep(20);
+
+ return 0;
+}
+
+static int stmfts_runtime_resume(struct device *dev)
+{
+ struct stmfts_data *sdata = dev_get_drvdata(dev);
+ int ret;
+
+ ret = sdata->ops->runtime_resume(sdata);
if (ret)
dev_err(dev, "failed to resume device: %d\n", ret);
@@ -824,8 +1239,29 @@ static const struct dev_pm_ops stmfts_pm_ops = {
};
#ifdef CONFIG_OF
+static const struct stmfts_chip_ops stmfts4_ops = {
+ .configure = stmfts_configure,
+ .setup_input = stmfts_setup_input,
+ .input_open = stmfts_input_open,
+ .input_close = stmfts_input_close,
+ .parse_events = stmfts_parse_events,
+ .set_hover = stmfts_set_hover,
+ .runtime_resume = stmfts_chip_runtime_resume,
+};
+
+static const struct stmfts_chip_ops stmfts5_ops = {
+ .configure = stmfts5_configure,
+ .power_off = stmfts5_chip_power_off,
+ .setup_input = stmfts5_setup_input,
+ .input_open = stmfts5_input_open,
+ .input_close = stmfts5_input_close,
+ .parse_events = stmfts5_parse_events,
+ .runtime_resume = stmfts5_chip_runtime_resume,
+};
+
static const struct of_device_id stmfts_of_match[] = {
- { .compatible = "st,stmfts", },
+ { .compatible = "st,stmfts", .data = &stmfts4_ops },
+ { .compatible = "st,stmfts5", .data = &stmfts5_ops },
{ },
};
MODULE_DEVICE_TABLE(of, stmfts_of_match);
@@ -853,5 +1289,7 @@ static struct i2c_driver stmfts_driver = {
module_i2c_driver(stmfts_driver);
MODULE_AUTHOR("Andi Shyti <andi.shyti@samsung.com>");
+MODULE_AUTHOR("David Heidelberg <david@ixit.cz>");
+MODULE_AUTHOR("Petr Hodina <petr.hodina@protonmail.com>");
MODULE_DESCRIPTION("STMicroelectronics FTS Touch Screen");
MODULE_LICENSE("GPL");
--
2.53.0
^ permalink raw reply related
* [PATCH v4 08/11] Input: stmfts - add optional reset GPIO support
From: David Heidelberg via B4 Relay @ 2026-04-08 22:15 UTC (permalink / raw)
To: Dmitry Torokhov, Maxime Coquelin, Alexandre Torgue, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Henrik Rydberg,
Bjorn Andersson, Konrad Dybcio
Cc: Petr Hodina, linux-input, linux-stm32, linux-arm-kernel,
linux-kernel, Krzysztof Kozlowski, devicetree, linux-arm-msm,
phone-devel, David Heidelberg
In-Reply-To: <20260409-stmfts5-v4-0-64fe62027db5@ixit.cz>
From: Petr Hodina <petr.hodina@protonmail.com>
Add support for an optional "reset-gpios" property. If present, the
driver drives the reset line high at probe time and releases it during
power-on, after the regulators have been enabled.
Signed-off-by: Petr Hodina <petr.hodina@protonmail.com>
Co-developed-by: David Heidelberg <david@ixit.cz>
Signed-off-by: David Heidelberg <david@ixit.cz>
---
drivers/input/touchscreen/stmfts.c | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/drivers/input/touchscreen/stmfts.c b/drivers/input/touchscreen/stmfts.c
index b61a19e954296..1e6d9a287cd0c 100644
--- a/drivers/input/touchscreen/stmfts.c
+++ b/drivers/input/touchscreen/stmfts.c
@@ -77,6 +77,7 @@ static const struct regulator_bulk_data stmfts_supplies[] = {
struct stmfts_data {
struct i2c_client *client;
struct input_dev *input;
+ struct gpio_desc *reset_gpio;
struct led_classdev led_cdev;
struct mutex mutex;
@@ -539,6 +540,15 @@ static int stmfts_read_system_info(struct stmfts_data *sdata)
return 0;
}
+static void stmfts_reset(struct stmfts_data *sdata)
+{
+ gpiod_set_value_cansleep(sdata->reset_gpio, 1);
+ msleep(20);
+
+ gpiod_set_value_cansleep(sdata->reset_gpio, 0);
+ msleep(50);
+}
+
static int stmfts_configure(struct stmfts_data *sdata)
{
int err;
@@ -599,6 +609,9 @@ static int stmfts_power_on(struct stmfts_data *sdata)
*/
msleep(20);
+ if (sdata->reset_gpio)
+ stmfts_reset(sdata);
+
err = stmfts_configure(sdata);
if (err)
regulator_bulk_disable(ARRAY_SIZE(stmfts_supplies),
@@ -612,6 +625,10 @@ static void stmfts_power_off(void *data)
struct stmfts_data *sdata = data;
disable_irq(sdata->client->irq);
+
+ if (sdata->reset_gpio)
+ gpiod_set_value_cansleep(sdata->reset_gpio, 1);
+
regulator_bulk_disable(ARRAY_SIZE(stmfts_supplies),
sdata->supplies);
}
@@ -668,6 +685,12 @@ static int stmfts_probe(struct i2c_client *client)
if (err)
return err;
+ sdata->reset_gpio = devm_gpiod_get_optional(dev, "reset",
+ GPIOD_OUT_HIGH);
+ if (IS_ERR(sdata->reset_gpio))
+ return dev_err_probe(dev, PTR_ERR(sdata->reset_gpio),
+ "Failed to get GPIO 'reset'\n");
+
sdata->input = devm_input_allocate_device(dev);
if (!sdata->input)
return -ENOMEM;
--
2.53.0
^ permalink raw reply related
* [PATCH v4 04/11] Input: stmfts - abstract reading information from the firmware
From: David Heidelberg via B4 Relay @ 2026-04-08 22:15 UTC (permalink / raw)
To: Dmitry Torokhov, Maxime Coquelin, Alexandre Torgue, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Henrik Rydberg,
Bjorn Andersson, Konrad Dybcio
Cc: Petr Hodina, linux-input, linux-stm32, linux-arm-kernel,
linux-kernel, Krzysztof Kozlowski, devicetree, linux-arm-msm,
phone-devel, David Heidelberg
In-Reply-To: <20260409-stmfts5-v4-0-64fe62027db5@ixit.cz>
From: David Heidelberg <david@ixit.cz>
Improves readability and makes splitting power on function in following
commit easier.
Signed-off-by: David Heidelberg <david@ixit.cz>
---
drivers/input/touchscreen/stmfts.c | 36 ++++++++++++++++++++++++------------
1 file changed, 24 insertions(+), 12 deletions(-)
diff --git a/drivers/input/touchscreen/stmfts.c b/drivers/input/touchscreen/stmfts.c
index ff884e04ad4c8..71d9b747ccfc5 100644
--- a/drivers/input/touchscreen/stmfts.c
+++ b/drivers/input/touchscreen/stmfts.c
@@ -518,22 +518,11 @@ static struct attribute *stmfts_sysfs_attrs[] = {
};
ATTRIBUTE_GROUPS(stmfts_sysfs);
-static int stmfts_power_on(struct stmfts_data *sdata)
+static int stmfts_read_system_info(struct stmfts_data *sdata)
{
int err;
u8 reg[8];
- err = regulator_bulk_enable(ARRAY_SIZE(stmfts_supplies),
- sdata->supplies);
- if (err)
- return err;
-
- /*
- * The datasheet does not specify the power on time, but considering
- * that the reset time is < 10ms, I sleep 20ms to be sure
- */
- msleep(20);
-
err = i2c_smbus_read_i2c_block_data(sdata->client, STMFTS_READ_INFO,
sizeof(reg), reg);
if (err < 0)
@@ -547,6 +536,29 @@ static int stmfts_power_on(struct stmfts_data *sdata)
sdata->config_id = reg[4];
sdata->config_ver = reg[5];
+ return 0;
+}
+
+static int stmfts_power_on(struct stmfts_data *sdata)
+{
+ int err;
+
+ err = regulator_bulk_enable(ARRAY_SIZE(stmfts_supplies),
+ sdata->supplies);
+ if (err)
+ return err;
+
+ /*
+ * The datasheet does not specify the power on time, but considering
+ * that the reset time is < 10ms, I sleep 20ms to be sure
+ */
+ msleep(20);
+
+
+ err = stmfts_read_system_info(sdata);
+ if (err)
+ return err;
+
enable_irq(sdata->client->irq);
msleep(50);
--
2.53.0
^ permalink raw reply related
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