* [PATCH v2 3/3] arm64: tegra: Add GTE nodes for Tegra264
From: Suneel Garapati @ 2026-04-08 21:24 UTC (permalink / raw)
To: dipenp, jonathanh, thierry.reding, krzk+dt, conor+dt, amhetre,
sheetal, kkartik, robh, pshete, timestamp, devicetree,
linux-tegra, linux-kernel
Cc: Suneel Garapati
In-Reply-To: <20260408212413.217692-1-suneelg@nvidia.com>
Add AON GPIO and system LIC GTE instances for Tegra264.
Signed-off-by: Suneel Garapati <suneelg@nvidia.com>
---
arch/arm64/boot/dts/nvidia/tegra264.dtsi | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/arch/arm64/boot/dts/nvidia/tegra264.dtsi b/arch/arm64/boot/dts/nvidia/tegra264.dtsi
index 06d8357bdf52..c6630733d5e3 100644
--- a/arch/arm64/boot/dts/nvidia/tegra264.dtsi
+++ b/arch/arm64/boot/dts/nvidia/tegra264.dtsi
@@ -3207,6 +3207,15 @@ agic_page5: interrupt-controller@99b0000 {
};
};
+ hte_lic: hardware-timestamp@8380000 {
+ compatible = "nvidia,tegra264-gte-lic";
+ reg = <0x0 0x08380000 0x0 0x10000>;
+ interrupts = <GIC_SPI 0x00000268 IRQ_TYPE_LEVEL_HIGH>;
+ nvidia,int-threshold = <1>;
+ #timestamp-cells = <1>;
+ status = "disabled";
+ };
+
gpcdma: dma-controller@8400000 {
compatible = "nvidia,tegra264-gpcdma", "nvidia,tegra186-gpcdma";
reg = <0x0 0x08400000 0x0 0x210000>;
@@ -3267,6 +3276,16 @@ hsp_top: hsp@8800000 {
#mbox-cells = <2>;
};
+ hte_aon: hardware-timestamp@c2b0000 {
+ compatible = "nvidia,tegra264-gte-aon";
+ reg = <0x0 0x0c2b0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 0x00000226 IRQ_TYPE_LEVEL_HIGH>;
+ nvidia,int-threshold = <1>;
+ #timestamp-cells = <1>;
+ nvidia,gpio-controller = <&gpio_aon>;
+ status = "disabled";
+ };
+
rtc: rtc@c2c0000 {
compatible = "nvidia,tegra264-rtc", "nvidia,tegra20-rtc";
reg = <0x0 0x0c2c0000 0x0 0x10000>;
--
2.34.1
^ permalink raw reply related
* Re: [PATCH v3 3/3] dt-bindings: i3c: Add AST2600 I3C global registers
From: Rob Herring (Arm) @ 2026-04-08 21:35 UTC (permalink / raw)
To: Dawid Glazik
Cc: Andrew Jeffery, Krzysztof Kozlowski, Joel Stanley,
linux-arm-kernel, Frank Li, Conor Dooley, linux-i3c,
Maciej Lawniczak, Alexandre Belloni, linux-aspeed, devicetree
In-Reply-To: <7f55458097ef651b4fc46650254afd3fa7b87348.1775679285.git.dawid.glazik@linux.intel.com>
On Wed, 08 Apr 2026 22:34:35 +0200, Dawid Glazik wrote:
> Introduce the device-tree bindings for I3C global registers found on
> AST2600 SoCs.
>
> Signed-off-by: Dawid Glazik <dawid.glazik@linux.intel.com>
> ---
> I wasn't sure if I should add newline at the end of the
> file or not so I took
> https://github.com/torvalds/linux/tree/master/Documentation/devicetree/bindings/i3c
> as an example.
> ---
> .../i3c/aspeed,ast2600-i3c-global.yaml | 55 +++++++++++++++++++
> 1 file changed, 55 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/i3c/aspeed,ast2600-i3c-global.yaml
>
My bot found errors running 'make dt_binding_check' on your patch:
yamllint warnings/errors:
./Documentation/devicetree/bindings/i3c/aspeed,ast2600-i3c-global.yaml:55:4: [error] no new line character at the end of file (new-line-at-end-of-file)
dtschema/dtc warnings/errors:
Lexical error: Documentation/devicetree/bindings/i3c/aspeed,ast2600-i3c-global.example.dts:27.35-55 Unexpected 'ASPEED_RESET_I3C_DMA'
FATAL ERROR: Syntax error parsing input tree
make[2]: *** [scripts/Makefile.dtbs:140: Documentation/devicetree/bindings/i3c/aspeed,ast2600-i3c-global.example.dtb] Error 1
make[2]: *** Waiting for unfinished jobs....
make[1]: *** [/builds/robherring/dt-review-ci/linux/Makefile:1597: dt_binding_check] Error 2
make: *** [Makefile:248: __sub-make] Error 2
doc reference errors (make refcheckdocs):
See https://patchwork.kernel.org/project/devicetree/patch/7f55458097ef651b4fc46650254afd3fa7b87348.1775679285.git.dawid.glazik@linux.intel.com
The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.
If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:
pip3 install dtschema --upgrade
Please check and re-submit after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.
^ permalink raw reply
* Re: [PATCH 2/2] drm/panel: simple: Add EDT ETML1010G0DKA panel
From: Dominik Haller @ 2026-04-08 21:45 UTC (permalink / raw)
To: neil.armstrong@linaro.org, Frank.li@nxp.com
Cc: dri-devel@lists.freedesktop.org, devicetree@vger.kernel.org,
krzysztof.kozlowski+dt@linaro.org, sam@ravnborg.org,
upstream@phytec.de, robh+dt@kernel.org, thierry.reding@gmail.com
In-Reply-To: <adRw6sNItxMNEfK6@lizhi-Precision-Tower-5810>
On Mo, 2026-04-06 at 22:50 -0400, Frank Li wrote:
> On Mon, Feb 06, 2023 at 02:20:31PM +0000, Dominik Haller wrote:
> > Hello,
>
> Neil Armstrong:
>
> It is quite old. Any reason why not pick this patch?
Hi,
this panel is eol and we've switched to etml1010g3dra and
ph128800t006-zhc01 in our kits.
So this patch can be dropped.
Dominik
>
> Frank
> >
> > ping here, this one got forgotten.
> > It still applies on drm-misc-next and v6.2-rc7
> >
> >
> > On 18.08.22 14:45, Dominik Haller wrote:
> > > Add support for the EDT ETML1010G0DKA 10.1" 1280x800 LVDS panel.
> > >
> > > Signed-off-by: Dominik Haller <d.haller@phytec.de>
> > > ---
> > > drivers/gpu/drm/panel/panel-simple.c | 29
> > > ++++++++++++++++++++++++++++
> > > 1 file changed, 29 insertions(+)
> > >
> > > diff --git a/drivers/gpu/drm/panel/panel-simple.c
> > > b/drivers/gpu/drm/panel/panel-simple.c
> > > index f9e1f85daef7..9314db24ab51 100644
> > > --- a/drivers/gpu/drm/panel/panel-simple.c
> > > +++ b/drivers/gpu/drm/panel/panel-simple.c
> > > @@ -1779,6 +1779,32 @@ static const struct panel_desc
> > > edt_etml0700y5dha = {
> > > .connector_type = DRM_MODE_CONNECTOR_LVDS,
> > > };
> > >
> > > +static const struct drm_display_mode edt_etml1010g0dka_mode = {
> > > + .clock = 70000,
> > > + .hdisplay = 1280,
> > > + .hsync_start = 1280 + 100,
> > > + .hsync_end = 1280 + 100 + 19,
> > > + .htotal = 1280 + 100 + 19 + 41,
> > > + .vdisplay = 800,
> > > + .vsync_start = 800 + 4,
> > > + .vsync_end = 800 + 4 + 4,
> > > + .vtotal = 800 + 4 + 4 + 15,
> > > + .flags = DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC,
> > > +};
> > > +
> > > +static const struct panel_desc edt_etml1010g0dka = {
> > > + .modes = &edt_etml1010g0dka_mode,
> > > + .num_modes = 1,
> > > + .bpc = 8,
> > > + .size = {
> > > + .width = 216,
> > > + .height = 135,
> > > + },
> > > + .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
> > > + .bus_flags = DRM_BUS_FLAG_DE_HIGH,
> > > + .connector_type = DRM_MODE_CONNECTOR_LVDS,
> > > +};
> > > +
> > > static const struct drm_display_mode edt_etmv570g2dhu_mode = {
> > > .clock = 25175,
> > > .hdisplay = 640,
> > > @@ -4057,6 +4083,9 @@ static const struct of_device_id
> > > platform_of_match[] = {
> > > }, {
> > > .compatible = "edt,etml0700y5dha",
> > > .data = &edt_etml0700y5dha,
> > > + }, {
> > > + .compatible = "edt,etml1010g0dka",
> > > + .data = &edt_etml1010g0dka,
> > > }, {
> > > .compatible = "edt,etmv570g2dhu",
> > > .data = &edt_etmv570g2dhu,
> >
> >
> > --
> > PHYTEC Messtechnik GmbH | Barcelona-Allee 1 | 55129 Mainz, Germany
> >
> > Geschäftsführer: Dipl.-Ing. Michael Mitezki, Dipl.-Ing. Bodo Huber
> > |
> > Handelsregister Mainz HRB 4656 | Finanzamt Mainz-Mitte | St.Nr.
> > 266500608, DE 149059855
> >
^ permalink raw reply
* Re: [PATCH v5 5/6] clk: fsl-sai: Extract clock setup into fsl_sai_clk_register()
From: Brian Masney @ 2026-04-08 21:58 UTC (permalink / raw)
To: Marek Vasut
Cc: linux-clk, Conor Dooley, Krzysztof Kozlowski, Michael Turquette,
Michael Walle, Rob Herring, Stephen Boyd, devicetree,
linux-kernel
In-Reply-To: <20260407211123.77602-5-marex@nabladev.com>
Hi Marek,
On Tue, Apr 07, 2026 at 11:10:02PM +0200, Marek Vasut wrote:
> Create helper function fsl_sai_clk_register() to set up and register
> SAI clock. Rename BCLK specific struct fsl_sai_clk members with bclk_
> prefix. Use of_node_full_name(dev->of_node) and clock name to register
> uniquely named clock. This is done in preparation for the follow up
> patch, which adds MCLK support.
>
> Signed-off-by: Marek Vasut <marex@nabladev.com>
> ---
> Cc: Brian Masney <bmasney@redhat.com>
> Cc: Conor Dooley <conor+dt@kernel.org>
> Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
> Cc: Michael Turquette <mturquette@baylibre.com>
> Cc: Michael Walle <michael@walle.cc>
> Cc: Rob Herring <robh@kernel.org>
> Cc: Stephen Boyd <sboyd@kernel.org>
> Cc: devicetree@vger.kernel.org
> Cc: linux-clk@vger.kernel.org
> Cc: linux-kernel@vger.kernel.org
> ---
> V4: New patch
> V5: - Include fsl_sai_of_clk_get() which returns only BCLK in here already
> - s/hw/chw/ in fsl_sai_clk_register
> ---
> drivers/clk/clk-fsl-sai.c | 90 +++++++++++++++++++++++++++------------
> 1 file changed, 63 insertions(+), 27 deletions(-)
>
> diff --git a/drivers/clk/clk-fsl-sai.c b/drivers/clk/clk-fsl-sai.c
> index 27925893c4c27..01c5e26f55517 100644
> --- a/drivers/clk/clk-fsl-sai.c
> +++ b/drivers/clk/clk-fsl-sai.c
> @@ -26,20 +26,71 @@ struct fsl_sai_data {
> };
>
> struct fsl_sai_clk {
> - struct clk_divider div;
> - struct clk_gate gate;
> + struct clk_divider bclk_div;
> + struct clk_gate bclk_gate;
> + struct clk_hw *bclk_hw;
> spinlock_t lock;
> };
>
> +static struct clk_hw *
> +fsl_sai_of_clk_get(struct of_phandle_args *clkspec, void *data)
> +{
> + struct fsl_sai_clk *sai_clk = data;
> +
> + return sai_clk->bclk_hw;
> +}
> +
> +static int fsl_sai_clk_register(struct device *dev, void __iomem *base,
> + spinlock_t *lock, struct clk_divider *div,
> + struct clk_gate *gate, struct clk_hw **hw,
> + const int gate_bit, const int dir_bit,
> + const int div_reg, char *name)
> +{
> + const struct fsl_sai_data *data = device_get_match_data(dev);
> + struct clk_parent_data pdata = { .index = 0 };
> + struct clk_hw *chw;
> + char *cname;
> +
> + gate->reg = base + data->offset + I2S_CSR;
> + gate->bit_idx = gate_bit;
> + gate->lock = lock;
> +
> + div->reg = base + div_reg;
> + div->shift = CR2_DIV_SHIFT;
> + div->width = CR2_DIV_WIDTH;
> + div->lock = lock;
> +
> + cname = devm_kasprintf(dev, GFP_KERNEL, "%s.%s",
> + of_node_full_name(dev->of_node), name);
Sashiko has the following feedback:
https://sashiko.dev/#/patchset/20260407211123.77602-1-marex%40nabladev.com
Does using of_node_full_name() break debugfs directory creation?
The full node name usually contains slashes (e.g., soc/bus@1000/sai@2000),
which causes lookup_one_len() to reject the name with -EACCES when the CCF
tries to create the directories.
Also, if the device is instantiated without Device Tree, this evaluates to
"<no-node>", potentially causing collisions if multiple instances exist.
Would dev_name(dev) be more appropriate here?
> + if (!cname)
> + return -ENOMEM;
> +
> + chw = devm_clk_hw_register_composite_pdata(dev, cname,
> + &pdata, 1, NULL, NULL,
> + &div->hw,
> + &clk_divider_ops,
> + &gate->hw,
> + &clk_gate_ops,
> + CLK_SET_RATE_GATE);
> + if (IS_ERR(chw))
> + return PTR_ERR(chw);
> +
> + *hw = chw;
> +
> + /* Set clock direction */
> + writel(dir_bit, base + div_reg);
Sashiko also has the following feedback:
Is it safe to initialize the hardware register after registering the clock
with the CCF?
During devm_clk_hw_register_composite_pdata(), the Common Clock Framework
inspects the hardware to calculate and cache the initial clock rate based on
the existing divider value.
The subsequent writel() completely overwrites the 32-bit register, setting
the direction bit and zeroing out the divider bits. Because this occurs
after registration, the CCF is completely unaware of the change, leaving its
cached rate stale and mismatched with the hardware.
Additionally, since the clock is already exposed to the system, could this
lockless writel() race with concurrent clock operations like clk_set_rate()
and clobber new divider configurations?
The original code safely performed this initialization before registration.
Brian
^ permalink raw reply
* Re: [PATCH v5 5/6] clk: fsl-sai: Extract clock setup into fsl_sai_clk_register()
From: Brian Masney @ 2026-04-08 22:12 UTC (permalink / raw)
To: Marek Vasut
Cc: linux-clk, Conor Dooley, Krzysztof Kozlowski, Michael Turquette,
Michael Walle, Rob Herring, Stephen Boyd, devicetree,
linux-kernel
In-Reply-To: <20260407211123.77602-5-marex@nabladev.com>
Hi Marek,
On Tue, Apr 07, 2026 at 11:10:02PM +0200, Marek Vasut wrote:
> Create helper function fsl_sai_clk_register() to set up and register
> SAI clock. Rename BCLK specific struct fsl_sai_clk members with bclk_
> prefix. Use of_node_full_name(dev->of_node) and clock name to register
> uniquely named clock. This is done in preparation for the follow up
> patch, which adds MCLK support.
>
> Signed-off-by: Marek Vasut <marex@nabladev.com>
> ---
> Cc: Brian Masney <bmasney@redhat.com>
> Cc: Conor Dooley <conor+dt@kernel.org>
> Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
> Cc: Michael Turquette <mturquette@baylibre.com>
> Cc: Michael Walle <michael@walle.cc>
> Cc: Rob Herring <robh@kernel.org>
> Cc: Stephen Boyd <sboyd@kernel.org>
> Cc: devicetree@vger.kernel.org
> Cc: linux-clk@vger.kernel.org
> Cc: linux-kernel@vger.kernel.org
> ---
> V4: New patch
> V5: - Include fsl_sai_of_clk_get() which returns only BCLK in here already
> - s/hw/chw/ in fsl_sai_clk_register
> ---
> drivers/clk/clk-fsl-sai.c | 90 +++++++++++++++++++++++++++------------
> 1 file changed, 63 insertions(+), 27 deletions(-)
>
> diff --git a/drivers/clk/clk-fsl-sai.c b/drivers/clk/clk-fsl-sai.c
> index 27925893c4c27..01c5e26f55517 100644
> --- a/drivers/clk/clk-fsl-sai.c
> +++ b/drivers/clk/clk-fsl-sai.c
> @@ -26,20 +26,71 @@ struct fsl_sai_data {
> };
>
> struct fsl_sai_clk {
> - struct clk_divider div;
> - struct clk_gate gate;
> + struct clk_divider bclk_div;
> + struct clk_gate bclk_gate;
> + struct clk_hw *bclk_hw;
> spinlock_t lock;
> };
>
> +static struct clk_hw *
> +fsl_sai_of_clk_get(struct of_phandle_args *clkspec, void *data)
> +{
> + struct fsl_sai_clk *sai_clk = data;
> +
> + return sai_clk->bclk_hw;
> +}
> +
> +static int fsl_sai_clk_register(struct device *dev, void __iomem *base,
> + spinlock_t *lock, struct clk_divider *div,
> + struct clk_gate *gate, struct clk_hw **hw,
> + const int gate_bit, const int dir_bit,
> + const int div_reg, char *name)
> +{
> + const struct fsl_sai_data *data = device_get_match_data(dev);
> + struct clk_parent_data pdata = { .index = 0 };
> + struct clk_hw *chw;
> + char *cname;
> +
> + gate->reg = base + data->offset + I2S_CSR;
> + gate->bit_idx = gate_bit;
> + gate->lock = lock;
> +
> + div->reg = base + div_reg;
> + div->shift = CR2_DIV_SHIFT;
> + div->width = CR2_DIV_WIDTH;
> + div->lock = lock;
> +
> + cname = devm_kasprintf(dev, GFP_KERNEL, "%s.%s",
> + of_node_full_name(dev->of_node), name);
> + if (!cname)
> + return -ENOMEM;
> +
> + chw = devm_clk_hw_register_composite_pdata(dev, cname,
> + &pdata, 1, NULL, NULL,
> + &div->hw,
> + &clk_divider_ops,
> + &gate->hw,
> + &clk_gate_ops,
> + CLK_SET_RATE_GATE);
> + if (IS_ERR(chw))
> + return PTR_ERR(chw);
> +
> + *hw = chw;
> +
> + /* Set clock direction */
> + writel(dir_bit, base + div_reg);
> +
> + return 0;
> +}
> +
> static int fsl_sai_clk_probe(struct platform_device *pdev)
> {
> struct device *dev = &pdev->dev;
> const struct fsl_sai_data *data = device_get_match_data(dev);
> struct fsl_sai_clk *sai_clk;
> - struct clk_parent_data pdata = { .index = 0 };
> struct clk *clk_bus;
> void __iomem *base;
> - struct clk_hw *hw;
> + int ret;
>
> sai_clk = devm_kzalloc(dev, sizeof(*sai_clk), GFP_KERNEL);
> if (!sai_clk)
> @@ -55,29 +106,14 @@ static int fsl_sai_clk_probe(struct platform_device *pdev)
>
> spin_lock_init(&sai_clk->lock);
>
> - sai_clk->gate.reg = base + data->offset + I2S_CSR;
> - sai_clk->gate.bit_idx = CSR_BCE_BIT;
> - sai_clk->gate.lock = &sai_clk->lock;
> -
> - sai_clk->div.reg = base + data->offset + I2S_CR2;
> - sai_clk->div.shift = CR2_DIV_SHIFT;
> - sai_clk->div.width = CR2_DIV_WIDTH;
> - sai_clk->div.lock = &sai_clk->lock;
> -
> - /* set clock direction, we are the BCLK master */
> - writel(CR2_BCD, base + data->offset + I2S_CR2);
> -
> - hw = devm_clk_hw_register_composite_pdata(dev, dev->of_node->name,
> - &pdata, 1, NULL, NULL,
> - &sai_clk->div.hw,
> - &clk_divider_ops,
> - &sai_clk->gate.hw,
> - &clk_gate_ops,
> - CLK_SET_RATE_GATE);
> - if (IS_ERR(hw))
> - return PTR_ERR(hw);
> -
> - return devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, hw);
> + ret = fsl_sai_clk_register(dev, base, &sai_clk->lock,
> + &sai_clk->bclk_div, &sai_clk->bclk_gate,
> + &sai_clk->bclk_hw, CSR_BCE_BIT, CR2_BCD,
> + data->offset + I2S_CR2, "BCLK");
^^^^^^^^^^^^^^^^^^^^^^
Sashiko reports the following:
https://sashiko.dev/#/patchset/20260407211123.77602-1-marex%40nabladev.com
For MCLK, this evaluates to writel(MCR_MOE, base + I2S_MCR). Does this
overwrite the entire register and clear all other bits to 0? This could zero
out fields like the MCLK Divider Enable and Clock Source Select, breaking
the MCLK hardware divider.
It's the same behavior as what was there previously. There's a lot more
to the comment. Can you look and see if there's anything else valid in
Sashiko's comment that should be addressed while changes are being made
here?
Otherwise, based on what was there previously, this looks good to me.
Brian
^ permalink raw reply
* [PATCH v4 00/11] Input: support for 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, Konrad Dybcio
Used on various phones. Minimal viable driver.
Includes device-tree enabling touchscreen on Pixel 3.
What is missing:
- switching between AP and SLPI mode (to be able to wake up phone by touch)
- firmware loading
- anything above basic touch
Signed-off-by: David Heidelberg <david@ixit.cz>
---
Changes in v4:
- Wrap everything below enabling the supplies into stmfts_configure()
to avoid bunch of gotos to power off on error (Dmitry T.)
- Finished chip specific ops and removed is_fts5. (Dmitry T.)
- Link to v3: https://lore.kernel.org/r/20260403-stmfts5-v3-0-5da768cfd201@ixit.cz
Changes in v3:
- s/touchscreen_pins/touchscreen_irq_n. (Konrad)
- Use interrupts-extended. (Konrad)
- Fixed rebase conflict against 8665ceb926ec ("Input: stmfts - use guard notation when acquiring mutex")
- Rename switch-gpios to mode-switch-gpios.
- Do not define properties in if:then: branches. (Krzysztof)
- Link to v2: https://lore.kernel.org/r/20260315-stmfts5-v2-0-70bc83ee9591@ixit.cz
Changes in v2:
- Fix typo in the binding s/switch-gpio/switch-gpios/.
- Deduplacate allOf. (Rob yamllint)
- Add missing S-off-by. (Dmitry B.)
- Dropped irq-gpios as it's not needed. (Konrad)
- Correct x and y touchscreen area size. (Konrad)
- Correct reset introduction commit description. (Krzysztof)
- Partially implemented chip specific ops. (Dmitry T.)
- Separeted license naming cleanup into separate commit (Dmitry T.)
- Link to v1: https://lore.kernel.org/r/20260301-stmfts5-v1-0-22c458b9ac68@ixit.cz
---
David Heidelberg (7):
Input: stmfts - Fix the MODULE_LICENSE() string
Input: stmfts - Use dev struct directly
Input: stmfts - Switch to devm_regulator_bulk_get_const
Input: stmfts - abstract reading information from the firmware
Input: stmfts - disable regulators when power on fails
dt-bindings: input: touchscreen: st,stmfts: Introduce reset GPIO
dt-bindings: input: touchscreen: st,stmfts: Introduce STM FTS5
Petr Hodina (4):
Input: stmfts - use client to make future code cleaner
Input: stmfts - add optional reset GPIO support
Input: stmfts - support FTS5
arm64: dts: qcom: sdm845-google: Add STM FTS touchscreen support
.../bindings/input/touchscreen/st,stmfts.yaml | 19 +-
.../arm64/boot/dts/qcom/sdm845-google-blueline.dts | 19 +-
arch/arm64/boot/dts/qcom/sdm845-google-common.dtsi | 2 +-
drivers/input/touchscreen/stmfts.c | 601 +++++++++++++++++++--
4 files changed, 580 insertions(+), 61 deletions(-)
---
base-commit: db7efce4ae23ad5e42f5f55428f529ff62b86fab
change-id: 20260214-stmfts5-b47311fbd732
Best regards,
--
David Heidelberg <david@ixit.cz>
^ permalink raw reply
* [PATCH v4 01/11] Input: stmfts - Fix the MODULE_LICENSE() string
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>
Replace the bogus "GPL v2" with "GPL" as MODULE_LICNSE() string. The
value does not declare the module's exact license, but only lets the
module loader test whether the module is Free Software or not.
See commit bf7fbeeae6db ("module: Cure the MODULE_LICENSE "GPL" vs.
"GPL v2" bogosity") in the details of the issue. The fix is to use
"GPL" for all modules under any variant of the GPL.
Signed-off-by: David Heidelberg <david@ixit.cz>
---
drivers/input/touchscreen/stmfts.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/input/touchscreen/stmfts.c b/drivers/input/touchscreen/stmfts.c
index 8af87d0b6eb64..def6bd0c8e059 100644
--- a/drivers/input/touchscreen/stmfts.c
+++ b/drivers/input/touchscreen/stmfts.c
@@ -807,4 +807,4 @@ module_i2c_driver(stmfts_driver);
MODULE_AUTHOR("Andi Shyti <andi.shyti@samsung.com>");
MODULE_DESCRIPTION("STMicroelectronics FTS Touch Screen");
-MODULE_LICENSE("GPL v2");
+MODULE_LICENSE("GPL");
--
2.53.0
^ permalink raw reply related
* [PATCH v4 02/11] Input: stmfts - Use dev struct directly
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>
Makes the code better readable and noticably shorter.
Signed-off-by: David Heidelberg <david@ixit.cz>
---
drivers/input/touchscreen/stmfts.c | 21 +++++++++++----------
1 file changed, 11 insertions(+), 10 deletions(-)
diff --git a/drivers/input/touchscreen/stmfts.c b/drivers/input/touchscreen/stmfts.c
index def6bd0c8e059..7b1e975a85668 100644
--- a/drivers/input/touchscreen/stmfts.c
+++ b/drivers/input/touchscreen/stmfts.c
@@ -619,6 +619,7 @@ static int stmfts_enable_led(struct stmfts_data *sdata)
static int stmfts_probe(struct i2c_client *client)
{
+ struct device *dev = &client->dev;
int err;
struct stmfts_data *sdata;
@@ -627,7 +628,7 @@ static int stmfts_probe(struct i2c_client *client)
I2C_FUNC_SMBUS_I2C_BLOCK))
return -ENODEV;
- sdata = devm_kzalloc(&client->dev, sizeof(*sdata), GFP_KERNEL);
+ sdata = devm_kzalloc(dev, sizeof(*sdata), GFP_KERNEL);
if (!sdata)
return -ENOMEM;
@@ -639,13 +640,13 @@ static int stmfts_probe(struct i2c_client *client)
sdata->regulators[STMFTS_REGULATOR_VDD].supply = "vdd";
sdata->regulators[STMFTS_REGULATOR_AVDD].supply = "avdd";
- err = devm_regulator_bulk_get(&client->dev,
+ err = devm_regulator_bulk_get(dev,
ARRAY_SIZE(sdata->regulators),
sdata->regulators);
if (err)
return err;
- sdata->input = devm_input_allocate_device(&client->dev);
+ sdata->input = devm_input_allocate_device(dev);
if (!sdata->input)
return -ENOMEM;
@@ -664,7 +665,7 @@ static int stmfts_probe(struct i2c_client *client)
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(&client->dev,
+ sdata->use_key = device_property_read_bool(dev,
"touch-key-connected");
if (sdata->use_key) {
input_set_capability(sdata->input, EV_KEY, KEY_MENU);
@@ -685,20 +686,20 @@ static int stmfts_probe(struct i2c_client *client)
* interrupts. To be on the safe side it's better to not enable
* the interrupts during their request.
*/
- err = devm_request_threaded_irq(&client->dev, client->irq,
+ err = devm_request_threaded_irq(dev, client->irq,
NULL, stmfts_irq_handler,
IRQF_ONESHOT | IRQF_NO_AUTOEN,
"stmfts_irq", sdata);
if (err)
return err;
- dev_dbg(&client->dev, "initializing ST-Microelectronics FTS...\n");
+ dev_dbg(dev, "initializing ST-Microelectronics FTS...\n");
err = stmfts_power_on(sdata);
if (err)
return err;
- err = devm_add_action_or_reset(&client->dev, stmfts_power_off, sdata);
+ err = devm_add_action_or_reset(dev, stmfts_power_off, sdata);
if (err)
return err;
@@ -715,13 +716,13 @@ static int stmfts_probe(struct i2c_client *client)
* without LEDs. The ledvdd regulator pointer will be
* used as a flag.
*/
- dev_warn(&client->dev, "unable to use touchkey leds\n");
+ dev_warn(dev, "unable to use touchkey leds\n");
sdata->ledvdd = NULL;
}
}
- pm_runtime_enable(&client->dev);
- device_enable_async_suspend(&client->dev);
+ pm_runtime_enable(dev);
+ device_enable_async_suspend(dev);
return 0;
}
--
2.53.0
^ permalink raw reply related
* [PATCH v4 03/11] Input: stmfts - Switch to devm_regulator_bulk_get_const
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>
Switch to devm_regulator_bulk_get_const() to stop setting the supplies
list in probe(), and move the regulator_bulk_data struct in static const.
Signed-off-by: David Heidelberg <david@ixit.cz>
---
drivers/input/touchscreen/stmfts.c | 25 ++++++++++++-------------
1 file changed, 12 insertions(+), 13 deletions(-)
diff --git a/drivers/input/touchscreen/stmfts.c b/drivers/input/touchscreen/stmfts.c
index 7b1e975a85668..ff884e04ad4c8 100644
--- a/drivers/input/touchscreen/stmfts.c
+++ b/drivers/input/touchscreen/stmfts.c
@@ -69,9 +69,9 @@
#define STMFTS_MAX_FINGERS 10
#define STMFTS_DEV_NAME "stmfts"
-enum stmfts_regulators {
- STMFTS_REGULATOR_VDD,
- STMFTS_REGULATOR_AVDD,
+static const struct regulator_bulk_data stmfts_supplies[] = {
+ { .supply = "vdd" },
+ { .supply = "avdd" },
};
struct stmfts_data {
@@ -82,7 +82,7 @@ struct stmfts_data {
struct touchscreen_properties prop;
- struct regulator_bulk_data regulators[2];
+ struct regulator_bulk_data *supplies;
/*
* Presence of ledvdd will be used also to check
@@ -523,8 +523,8 @@ static int stmfts_power_on(struct stmfts_data *sdata)
int err;
u8 reg[8];
- err = regulator_bulk_enable(ARRAY_SIZE(sdata->regulators),
- sdata->regulators);
+ err = regulator_bulk_enable(ARRAY_SIZE(stmfts_supplies),
+ sdata->supplies);
if (err)
return err;
@@ -589,8 +589,8 @@ static void stmfts_power_off(void *data)
struct stmfts_data *sdata = data;
disable_irq(sdata->client->irq);
- regulator_bulk_disable(ARRAY_SIZE(sdata->regulators),
- sdata->regulators);
+ regulator_bulk_disable(ARRAY_SIZE(stmfts_supplies),
+ sdata->supplies);
}
static int stmfts_enable_led(struct stmfts_data *sdata)
@@ -638,11 +638,10 @@ static int stmfts_probe(struct i2c_client *client)
mutex_init(&sdata->mutex);
init_completion(&sdata->cmd_done);
- sdata->regulators[STMFTS_REGULATOR_VDD].supply = "vdd";
- sdata->regulators[STMFTS_REGULATOR_AVDD].supply = "avdd";
- err = devm_regulator_bulk_get(dev,
- ARRAY_SIZE(sdata->regulators),
- sdata->regulators);
+ err = devm_regulator_bulk_get_const(dev,
+ ARRAY_SIZE(stmfts_supplies),
+ stmfts_supplies,
+ &sdata->supplies);
if (err)
return err;
--
2.53.0
^ permalink raw reply related
* [PATCH v4 05/11] Input: stmfts - disable regulators when power on fails
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>
We must power off regulators after failing at power on phase.
Create stmfts_configure function, so we don't have to use goto.
Signed-off-by: David Heidelberg <david@ixit.cz>
---
drivers/input/touchscreen/stmfts.c | 37 ++++++++++++++++++++++++-------------
1 file changed, 24 insertions(+), 13 deletions(-)
diff --git a/drivers/input/touchscreen/stmfts.c b/drivers/input/touchscreen/stmfts.c
index 71d9b747ccfc5..290511dd69437 100644
--- a/drivers/input/touchscreen/stmfts.c
+++ b/drivers/input/touchscreen/stmfts.c
@@ -539,22 +539,10 @@ static int stmfts_read_system_info(struct stmfts_data *sdata)
return 0;
}
-static int stmfts_power_on(struct stmfts_data *sdata)
+static int stmfts_configure(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;
@@ -596,6 +584,29 @@ static int stmfts_power_on(struct stmfts_data *sdata)
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_configure(sdata);
+ if (err)
+ regulator_bulk_disable(ARRAY_SIZE(stmfts_supplies),
+ sdata->supplies);
+
+ return err;
+}
+
static void stmfts_power_off(void *data)
{
struct stmfts_data *sdata = data;
--
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 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 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
* [PATCH v4 06/11] Input: stmfts - use client to make future code cleaner
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>
Make code cleaner, compiler will optimize it away anyway.
Preparation for FTM5 support, where more steps are needed.
Signed-off-by: Petr Hodina <petr.hodina@protonmail.com>
Signed-off-by: David Heidelberg <david@ixit.cz>
---
drivers/input/touchscreen/stmfts.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/input/touchscreen/stmfts.c b/drivers/input/touchscreen/stmfts.c
index 290511dd69437..b61a19e954296 100644
--- a/drivers/input/touchscreen/stmfts.c
+++ b/drivers/input/touchscreen/stmfts.c
@@ -769,9 +769,10 @@ static int stmfts_runtime_suspend(struct device *dev)
static int stmfts_runtime_resume(struct device *dev)
{
struct stmfts_data *sdata = dev_get_drvdata(dev);
+ struct i2c_client *client = sdata->client;
int ret;
- ret = i2c_smbus_write_byte(sdata->client, STMFTS_SLEEP_OUT);
+ ret = i2c_smbus_write_byte(client, STMFTS_SLEEP_OUT);
if (ret)
dev_err(dev, "failed to resume device: %d\n", ret);
--
2.53.0
^ permalink raw reply related
* [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 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
* 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 v5 5/6] clk: fsl-sai: Extract clock setup into fsl_sai_clk_register()
From: Marek Vasut @ 2026-04-09 0:13 UTC (permalink / raw)
To: Brian Masney
Cc: linux-clk, Conor Dooley, Krzysztof Kozlowski, Michael Turquette,
Michael Walle, Rob Herring, Stephen Boyd, devicetree,
linux-kernel
In-Reply-To: <adbPlFzI7jrU9pCq@redhat.com>
On 4/8/26 11:58 PM, Brian Masney wrote:
Hi,
>> +static int fsl_sai_clk_register(struct device *dev, void __iomem *base,
>> + spinlock_t *lock, struct clk_divider *div,
>> + struct clk_gate *gate, struct clk_hw **hw,
>> + const int gate_bit, const int dir_bit,
>> + const int div_reg, char *name)
>> +{
>> + const struct fsl_sai_data *data = device_get_match_data(dev);
>> + struct clk_parent_data pdata = { .index = 0 };
>> + struct clk_hw *chw;
>> + char *cname;
>> +
>> + gate->reg = base + data->offset + I2S_CSR;
>> + gate->bit_idx = gate_bit;
>> + gate->lock = lock;
>> +
>> + div->reg = base + div_reg;
>> + div->shift = CR2_DIV_SHIFT;
>> + div->width = CR2_DIV_WIDTH;
>> + div->lock = lock;
>> +
>> + cname = devm_kasprintf(dev, GFP_KERNEL, "%s.%s",
>> + of_node_full_name(dev->of_node), name);
>
> Sashiko has the following feedback:
> https://sashiko.dev/#/patchset/20260407211123.77602-1-marex%40nabladev.com
>
> Does using of_node_full_name() break debugfs directory creation?
>
> The full node name usually contains slashes (e.g., soc/bus@1000/sai@2000),
> which causes lookup_one_len() to reject the name with -EACCES when the CCF
> tries to create the directories.
This is nonsense, the node name is clock-controller@12340000 or
something like that .
> Also, if the device is instantiated without Device Tree, this evaluates to
> "<no-node>", potentially causing collisions if multiple instances exist.
> Would dev_name(dev) be more appropriate here?
This driver is always instantiated from DT.
>> + if (!cname)
>> + return -ENOMEM;
>> +
>> + chw = devm_clk_hw_register_composite_pdata(dev, cname,
>> + &pdata, 1, NULL, NULL,
>> + &div->hw,
>> + &clk_divider_ops,
>> + &gate->hw,
>> + &clk_gate_ops,
>> + CLK_SET_RATE_GATE);
>> + if (IS_ERR(chw))
>> + return PTR_ERR(chw);
>> +
>> + *hw = chw;
>> +
>> + /* Set clock direction */
>> + writel(dir_bit, base + div_reg);
>
> Sashiko also has the following feedback:
>
> Is it safe to initialize the hardware register after registering the clock
> with the CCF?
The BCD/MOE/DIVEN/DIV fields of the CR2/MCR registers are all zeroes, so
yes, either order is safe.
^ permalink raw reply
* Re: [PATCH v5 5/6] clk: fsl-sai: Extract clock setup into fsl_sai_clk_register()
From: Marek Vasut @ 2026-04-09 0:24 UTC (permalink / raw)
To: Brian Masney
Cc: linux-clk, Conor Dooley, Krzysztof Kozlowski, Michael Turquette,
Michael Walle, Rob Herring, Stephen Boyd, devicetree,
linux-kernel
In-Reply-To: <adbSxmeJDf14EtS0@redhat.com>
On 4/9/26 12:12 AM, Brian Masney wrote:
Hi,
>> - hw = devm_clk_hw_register_composite_pdata(dev, dev->of_node->name,
>> - &pdata, 1, NULL, NULL,
>> - &sai_clk->div.hw,
>> - &clk_divider_ops,
>> - &sai_clk->gate.hw,
>> - &clk_gate_ops,
>> - CLK_SET_RATE_GATE);
>> - if (IS_ERR(hw))
>> - return PTR_ERR(hw);
>> -
>> - return devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, hw);
>> + ret = fsl_sai_clk_register(dev, base, &sai_clk->lock,
>> + &sai_clk->bclk_div, &sai_clk->bclk_gate,
>> + &sai_clk->bclk_hw, CSR_BCE_BIT, CR2_BCD,
>> + data->offset + I2S_CR2, "BCLK");
> ^^^^^^^^^^^^^^^^^^^^^^
> Sashiko reports the following:
> https://sashiko.dev/#/patchset/20260407211123.77602-1-marex%40nabladev.com
>
> For MCLK, this evaluates to writel(MCR_MOE, base + I2S_MCR). Does this
> overwrite the entire register and clear all other bits to 0? This could zero
> out fields like the MCLK Divider Enable and Clock Source Select, breaking
> the MCLK hardware divider.
>
> It's the same behavior as what was there previously. There's a lot more
> to the comment. Can you look and see if there's anything else valid in
> Sashiko's comment that should be addressed while changes are being made
> here?
>
> Otherwise, based on what was there previously, this looks good to me.
I'll move the writel() before devm_clk_hw_register_composite_pdata()
even if it makes no difference in this particular case.
^ permalink raw reply
* Re: [PATCH v2 2/3] remoteproc: imx_rproc: Pass bootaddr to SM CPU/LMM reset vector
From: Peng Fan @ 2026-04-09 0:30 UTC (permalink / raw)
To: Mathieu Poirier
Cc: Peng Fan, Bjorn Andersson, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Frank Li, Sascha Hauer, Pengutronix Kernel Team,
Fabio Estevam, Daniel Baluta, linux-remoteproc@vger.kernel.org,
devicetree@vger.kernel.org, imx@lists.linux.dev,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org
In-Reply-To: <adZ4WIaC6WN97JhR@p14s>
On Wed, Apr 08, 2026 at 09:46:32AM -0600, Mathieu Poirier wrote:
>On Wed, Apr 08, 2026 at 01:30:16AM +0000, Peng Fan wrote:
>> > Subject: Re: [PATCH v2 2/3] remoteproc: imx_rproc: Pass bootaddr to
>> > SM CPU/LMM reset vector
>> >
>> [...]
>> >
>> > >
>> > > Aligning the ELF entry point with the hardware reset base on
>> > Cortex‑M
>> > > systems is possible, but it comes with several risks.
>> >
>> > I'm not asking to align the ELF entry point with the hardware reset base.
>> > All I want is to have the correct start address embedded in the ELF file
>> > to avoid having to use a mask.
>>
>> I see, per my understanding:
>> FreeRTOS typically exposes __isr_vector, which corresponds to the hardware
>> reset / vector table base.
>> Zephyr (Cortex‑M) exposes _vector_table, which serves the same purpose.
>> I am not certain about other RTOSes, but the pattern seems consistent:
>> the vector table base is already available as a named ELF symbol.
>>
>> Given that, if the preferred approach is to parse the ELF and explicitly
>> retrieve the hardware reset base, I can update the implementation accordingly.
>> If you prefer to parse the elf file to get the hardware reset base,
>> I could update to use them.
>>
>> Options1: Something as below:
>> 1. Include rproc_elf_find_symbol in remoteproc_elf_loader.c
>> 2. Use below in imx_rproc.c
>> ret = rproc_elf_find_symbol(rproc, fw, "__isr_vector", &vector_base);
>> if (ret)
>> ret = rproc_elf_find_symbol(rproc, fw, "__vector_table", &vector_base);
>>
>> if (!ret)
>> rproc->bootaddr = vector_base
>> else
>> dev_info(dev, "no __isr_vector or __vector_table\n")
>
>No
If your concern is about rproc->bootaddr, I could introduce
imx_rproc->vector_base for i.MX. Please help detail a bit.
>
>>
>> This makes the hardware reset base explicit, avoids masking e_entry.
>>
>> Option 2: User‑provided reset symbol via sysfs
>> As an alternative, we could expose a sysfs attribute,
>> e.g. reset_symbol, allowing users to specify the symbol name
>> to be used as the reset base:
>>
>> echo __isr_vector > /sys/class/remoteproc/remoteprocX/reset_symbol
>>
>
>Definitely not.
>
>The definition of e_entry in the specification is clear, i.e "the address of the
>entry point from where the process starts executing". If masking is required
>because the tool that puts the image together gets the wrong address, then it
>should be fixed.
The hardware reset base is the address from which the hardware fetches the
initial stack pointer and program counter values and loads them into the SP
and PC registers. In contrast, bootaddr (i.e. e_entry) represents the address
at which the CPU starts executing code (the PC value after reset). As you
pointed out earlier, this distinction is clear.
In our case, we need to obtain the hardware reset base and pass that value to
the system firmware. However, e_entry should not be set to the hardware reset
base. Doing so would introduce the issues I described in [1]. This means we
should not modify the Zephyr or FreeRTOS build outputs to make e_entry equal
to the hardware reset base.
Given these constraints, the feasible solutions I can see are either:
- option 1 (explicitly retrieving the hardware reset base), or
- continuing to use masking.
Please suggest.
[1] https://lore.kernel.org/all/acs2PAZq2k3zjmDW@shlinux89/
Thanks,
Peng
>
>> The remoteproc core would then resolve that symbol from
>> the ELF and set rproc->bootaddr accordingly.
>> This provides maximum flexibility but does introduce a new user‑visible ABI,
>> so I see it more as an opt‑in or fallback mechanism.
>>
>> Please let me know which approach you prefer, and I will update
>> this series accordingly in v3..
>>
>> Thanks,
>> Peng.
>>
>>
>> >
>> > > 1, Semantic mismatch (ELF vs. hardware behavior) 2, Debuggers may
>> > > attempt to set breakpoints or start execution at the entry symbol
>> > >
^ permalink raw reply
* [PATCH v6 1/6] dt-bindings: clock: fsl-sai: Document i.MX8M support
From: Marek Vasut @ 2026-04-09 0:29 UTC (permalink / raw)
To: linux-clk
Cc: Marek Vasut, Conor Dooley, Brian Masney, Conor Dooley,
Krzysztof Kozlowski, Michael Turquette, Michael Walle,
Rob Herring, Stephen Boyd, devicetree, linux-kernel
The i.MX8M/Mini/Nano/Plus variant of the SAI IP has control registers
shifted by +8 bytes and requires additional bus clock. Document support
for the i.MX8M variant of the IP with this register shift and additional
clock. Update the description slightly.
Acked-by: Conor Dooley <conor.dooley@microchip.com>
Signed-off-by: Marek Vasut <marex@nabladev.com>
---
Cc: Brian Masney <bmasney@redhat.com>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Michael Turquette <mturquette@baylibre.com>
Cc: Michael Walle <michael@walle.cc>
Cc: Rob Herring <robh@kernel.org>
Cc: Stephen Boyd <sboyd@kernel.org>
Cc: devicetree@vger.kernel.org
Cc: linux-clk@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
V2: No change
V3: - Rebase on current next, update mail address
- Pick ancient AB from Conor, although this may be outdated
https://patchwork.kernel.org/project/alsa-devel/patch/20241226162234.40141-1-marex@denx.de/
- Invert the allOf conditional to match on VF610 and limit
the clocks/clock-names there. MX8M can have one or two
input clock, "bus" is mandatory and "mclk1" is optional.
The "mclk1" are used by the driver in 4/4 .
V4: No change
V5: No change
V6: No change
---
.../bindings/clock/fsl,sai-clock.yaml | 41 ++++++++++++++++---
1 file changed, 35 insertions(+), 6 deletions(-)
diff --git a/Documentation/devicetree/bindings/clock/fsl,sai-clock.yaml b/Documentation/devicetree/bindings/clock/fsl,sai-clock.yaml
index 3bca9d11c148f..90799b3b505ee 100644
--- a/Documentation/devicetree/bindings/clock/fsl,sai-clock.yaml
+++ b/Documentation/devicetree/bindings/clock/fsl,sai-clock.yaml
@@ -10,10 +10,10 @@ maintainers:
- Michael Walle <michael@walle.cc>
description: |
- It is possible to use the BCLK pin of a SAI module as a generic clock
- output. Some SoC are very constrained in their pin multiplexer
- configuration. Eg. pins can only be changed groups. For example, on the
- LS1028A SoC you can only enable SAIs in pairs. If you use only one SAI,
+ It is possible to use the BCLK pin of a SAI module as a generic
+ clock output. Some SoC are very constrained in their pin multiplexer
+ configuration. E.g. pins can only be changed in groups. For example, on
+ the LS1028A SoC you can only enable SAIs in pairs. If you use only one SAI,
the second pins are wasted. Using this binding it is possible to use the
clock of the second SAI as a MCLK clock for an audio codec, for example.
@@ -21,17 +21,46 @@ description: |
properties:
compatible:
- const: fsl,vf610-sai-clock
+ oneOf:
+ - items:
+ - enum:
+ - fsl,imx8mm-sai-clock
+ - fsl,imx8mn-sai-clock
+ - fsl,imx8mp-sai-clock
+ - const: fsl,imx8mq-sai-clock
+ - items:
+ - enum:
+ - fsl,imx8mq-sai-clock
+ - fsl,vf610-sai-clock
reg:
maxItems: 1
clocks:
- maxItems: 1
+ minItems: 1
+ maxItems: 2
+
+ clock-names:
+ minItems: 1
+ items:
+ - const: bus
+ - const: mclk1
'#clock-cells':
const: 0
+allOf:
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: fsl,vf610-sai-clock
+ then:
+ properties:
+ clocks:
+ maxItems: 1
+ clock-names: false
+
required:
- compatible
- reg
--
2.53.0
^ permalink raw reply related
* [PATCH v6 2/6] clk: fsl-sai: Sort the headers
From: Marek Vasut @ 2026-04-09 0:29 UTC (permalink / raw)
To: linux-clk
Cc: Marek Vasut, Brian Masney, Conor Dooley, Krzysztof Kozlowski,
Michael Turquette, Michael Walle, Rob Herring, Stephen Boyd,
devicetree, linux-kernel
In-Reply-To: <20260409002952.319668-1-marex@nabladev.com>
Sort the headers. No functional change.
Reviewed-by: Brian Masney <bmasney@redhat.com>
Signed-off-by: Marek Vasut <marex@nabladev.com>
---
Cc: Brian Masney <bmasney@redhat.com>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Michael Turquette <mturquette@baylibre.com>
Cc: Michael Walle <michael@walle.cc>
Cc: Rob Herring <robh@kernel.org>
Cc: Stephen Boyd <sboyd@kernel.org>
Cc: devicetree@vger.kernel.org
Cc: linux-clk@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
V4: New patch
V5: - Reorder this into 2/6 position
- Add RB from Brian
V6: No change
---
drivers/clk/clk-fsl-sai.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/clk/clk-fsl-sai.c b/drivers/clk/clk-fsl-sai.c
index cba45e07562da..c59ddd519f9f5 100644
--- a/drivers/clk/clk-fsl-sai.c
+++ b/drivers/clk/clk-fsl-sai.c
@@ -5,12 +5,12 @@
* Copyright 2020 Michael Walle <michael@walle.cc>
*/
-#include <linux/module.h>
-#include <linux/platform_device.h>
#include <linux/clk-provider.h>
#include <linux/err.h>
+#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
+#include <linux/platform_device.h>
#include <linux/slab.h>
#define I2S_CSR 0x00
--
2.53.0
^ permalink raw reply related
* [PATCH v6 3/6] clk: fsl-sai: Add i.MX8M support with 8 byte register offset
From: Marek Vasut @ 2026-04-09 0:29 UTC (permalink / raw)
To: linux-clk
Cc: Marek Vasut, Brian Masney, Peng Fan, Conor Dooley,
Krzysztof Kozlowski, Michael Turquette, Michael Walle,
Rob Herring, Stephen Boyd, devicetree, linux-kernel
In-Reply-To: <20260409002952.319668-1-marex@nabladev.com>
The i.MX8M/Mini/Nano/Plus variant of the SAI IP has control registers
shifted by +8 bytes and requires additional bus clock. Add support for
the i.MX8M variant of the IP with this register shift and additional
clock.
Reviewed-by: Brian Masney <bmasney@redhat.com>
Reviewed-by: Peng Fan <peng.fan@nxp.com>
Signed-off-by: Marek Vasut <marex@nabladev.com>
---
Cc: Brian Masney <bmasney@redhat.com>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Michael Turquette <mturquette@baylibre.com>
Cc: Michael Walle <michael@walle.cc>
Cc: Rob Herring <robh@kernel.org>
Cc: Stephen Boyd <sboyd@kernel.org>
Cc: devicetree@vger.kernel.org
Cc: linux-clk@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
V2: Update commit message, align it with the bindings one
V3: - Rebase on current next, update mail address
- Pick ancient RB from Peng, although this may be outdated
https://patchwork.kernel.org/project/alsa-devel/patch/20241226162234.40141-2-marex@denx.de/
- Optionally enable "bus" clock, which are needed on MX8M to operate
register file
V4: Add RB from Brian
V5: Include clk.h
V6: No change
---
drivers/clk/Kconfig | 2 +-
drivers/clk/clk-fsl-sai.c | 28 ++++++++++++++++++++++++----
2 files changed, 25 insertions(+), 5 deletions(-)
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index cc8743b11bb1f..9f7f391a5615a 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -255,7 +255,7 @@ config COMMON_CLK_FSL_FLEXSPI
config COMMON_CLK_FSL_SAI
bool "Clock driver for BCLK of Freescale SAI cores"
- depends on ARCH_LAYERSCAPE || COMPILE_TEST
+ depends on ARCH_LAYERSCAPE || ARCH_MXC || COMPILE_TEST
help
This driver supports the Freescale SAI (Synchronous Audio Interface)
to be used as a generic clock output. Some SoCs have restrictions
diff --git a/drivers/clk/clk-fsl-sai.c b/drivers/clk/clk-fsl-sai.c
index c59ddd519f9f5..27925893c4c27 100644
--- a/drivers/clk/clk-fsl-sai.c
+++ b/drivers/clk/clk-fsl-sai.c
@@ -6,6 +6,7 @@
*/
#include <linux/clk-provider.h>
+#include <linux/clk.h>
#include <linux/err.h>
#include <linux/module.h>
#include <linux/of.h>
@@ -20,6 +21,10 @@
#define CR2_DIV_SHIFT 0
#define CR2_DIV_WIDTH 8
+struct fsl_sai_data {
+ unsigned int offset; /* Register offset */
+};
+
struct fsl_sai_clk {
struct clk_divider div;
struct clk_gate gate;
@@ -29,8 +34,10 @@ struct fsl_sai_clk {
static int fsl_sai_clk_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
+ const struct fsl_sai_data *data = device_get_match_data(dev);
struct fsl_sai_clk *sai_clk;
struct clk_parent_data pdata = { .index = 0 };
+ struct clk *clk_bus;
void __iomem *base;
struct clk_hw *hw;
@@ -42,19 +49,23 @@ static int fsl_sai_clk_probe(struct platform_device *pdev)
if (IS_ERR(base))
return PTR_ERR(base);
+ clk_bus = devm_clk_get_optional_enabled(dev, "bus");
+ if (IS_ERR(clk_bus))
+ return PTR_ERR(clk_bus);
+
spin_lock_init(&sai_clk->lock);
- sai_clk->gate.reg = base + I2S_CSR;
+ sai_clk->gate.reg = base + data->offset + I2S_CSR;
sai_clk->gate.bit_idx = CSR_BCE_BIT;
sai_clk->gate.lock = &sai_clk->lock;
- sai_clk->div.reg = base + I2S_CR2;
+ sai_clk->div.reg = base + data->offset + I2S_CR2;
sai_clk->div.shift = CR2_DIV_SHIFT;
sai_clk->div.width = CR2_DIV_WIDTH;
sai_clk->div.lock = &sai_clk->lock;
/* set clock direction, we are the BCLK master */
- writel(CR2_BCD, base + I2S_CR2);
+ writel(CR2_BCD, base + data->offset + I2S_CR2);
hw = devm_clk_hw_register_composite_pdata(dev, dev->of_node->name,
&pdata, 1, NULL, NULL,
@@ -69,8 +80,17 @@ static int fsl_sai_clk_probe(struct platform_device *pdev)
return devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, hw);
}
+static const struct fsl_sai_data fsl_sai_vf610_data = {
+ .offset = 0,
+};
+
+static const struct fsl_sai_data fsl_sai_imx8mq_data = {
+ .offset = 8,
+};
+
static const struct of_device_id of_fsl_sai_clk_ids[] = {
- { .compatible = "fsl,vf610-sai-clock" },
+ { .compatible = "fsl,vf610-sai-clock", .data = &fsl_sai_vf610_data },
+ { .compatible = "fsl,imx8mq-sai-clock", .data = &fsl_sai_imx8mq_data },
{ }
};
MODULE_DEVICE_TABLE(of, of_fsl_sai_clk_ids);
--
2.53.0
^ permalink raw reply related
* [PATCH v6 4/6] dt-bindings: clock: fsl-sai: Document clock-cells = <1> support
From: Marek Vasut @ 2026-04-09 0:29 UTC (permalink / raw)
To: linux-clk
Cc: Marek Vasut, Conor Dooley, Brian Masney, Conor Dooley,
Krzysztof Kozlowski, Michael Turquette, Michael Walle,
Rob Herring, Stephen Boyd, devicetree, linux-kernel
In-Reply-To: <20260409002952.319668-1-marex@nabladev.com>
The driver now supports generation of both BCLK and MCLK, document
support for #clock-cells = <0> for legacy case and #clock-cells = <1>
for the new case which can differentiate between BCLK and MCLK.
Acked-by: Conor Dooley <conor.dooley@microchip.com>
Signed-off-by: Marek Vasut <marex@nabladev.com>
---
Cc: Brian Masney <bmasney@redhat.com>
Cc: Conor Dooley <conor+dt@kernel.org>
Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
Cc: Michael Turquette <mturquette@baylibre.com>
Cc: Michael Walle <michael@walle.cc>
Cc: Rob Herring <robh@kernel.org>
Cc: Stephen Boyd <sboyd@kernel.org>
Cc: devicetree@vger.kernel.org
Cc: linux-clk@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
---
V2: Update commit message, align it with the bindings one
V3: - Rebase on current next, update mail address
- Pick ancient AB from Conor, although this may be outdated
https://patchwork.kernel.org/project/alsa-devel/patch/20241226162234.40141-3-marex@denx.de/
V4: No change
V5: No change
V6: No change
---
Documentation/devicetree/bindings/clock/fsl,sai-clock.yaml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Documentation/devicetree/bindings/clock/fsl,sai-clock.yaml b/Documentation/devicetree/bindings/clock/fsl,sai-clock.yaml
index 90799b3b505ee..041a63fa2d2b0 100644
--- a/Documentation/devicetree/bindings/clock/fsl,sai-clock.yaml
+++ b/Documentation/devicetree/bindings/clock/fsl,sai-clock.yaml
@@ -10,7 +10,7 @@ maintainers:
- Michael Walle <michael@walle.cc>
description: |
- It is possible to use the BCLK pin of a SAI module as a generic
+ It is possible to use the BCLK or MCLK pin of a SAI module as a generic
clock output. Some SoC are very constrained in their pin multiplexer
configuration. E.g. pins can only be changed in groups. For example, on
the LS1028A SoC you can only enable SAIs in pairs. If you use only one SAI,
@@ -47,7 +47,7 @@ properties:
- const: mclk1
'#clock-cells':
- const: 0
+ maximum: 1
allOf:
- if:
--
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