* [PATCH v2 1/5] dt-bindings: pinctrl: qcom: Add SM6350 LPI pinctrl
2026-04-30 7:10 [PATCH v2 0/5] Add LPASS LPI pin controller support for SM6350 Luca Weiss
@ 2026-04-30 7:10 ` Luca Weiss
2026-05-03 12:30 ` Krzysztof Kozlowski
2026-04-30 7:10 ` [PATCH v2 2/5] pinctrl: qcom: lpass-lpi: Add ability to use SPARE_1 for slew control Luca Weiss
` (4 subsequent siblings)
5 siblings, 1 reply; 9+ messages in thread
From: Luca Weiss @ 2026-04-30 7:10 UTC (permalink / raw)
To: Bjorn Andersson, Linus Walleij, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Konrad Dybcio, Srinivas Kandagatla
Cc: ~postmarketos/upstreaming, phone-devel, linux-arm-msm, linux-gpio,
devicetree, linux-kernel, Luca Weiss
Add bindings for pin controller in Low Power Audio SubSystem (LPASS).
Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>
---
.../pinctrl/qcom,sm6350-lpass-lpi-pinctrl.yaml | 124 +++++++++++++++++++++
1 file changed, 124 insertions(+)
diff --git a/Documentation/devicetree/bindings/pinctrl/qcom,sm6350-lpass-lpi-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/qcom,sm6350-lpass-lpi-pinctrl.yaml
new file mode 100644
index 000000000000..4903b2d37d89
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/qcom,sm6350-lpass-lpi-pinctrl.yaml
@@ -0,0 +1,124 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/pinctrl/qcom,sm6350-lpass-lpi-pinctrl.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm SM6350 SoC LPASS LPI TLMM
+
+maintainers:
+ - Luca Weiss <luca.weiss@fairphone.com>
+
+description:
+ Top Level Mode Multiplexer pin controller in the Low Power Audio SubSystem
+ (LPASS) Low Power Island (LPI) of Qualcomm SM6350 SoC.
+
+properties:
+ compatible:
+ const: qcom,sm6350-lpass-lpi-pinctrl
+
+ reg:
+ items:
+ - description: LPASS LPI TLMM Control and Status registers
+ - description: LPASS LPI MCC registers
+
+ clocks:
+ items:
+ - description: LPASS Core voting clock
+ - description: LPASS Audio voting clock
+
+ clock-names:
+ items:
+ - const: core
+ - const: audio
+
+patternProperties:
+ "-state$":
+ oneOf:
+ - $ref: "#/$defs/qcom-sm6350-lpass-state"
+ - patternProperties:
+ "-pins$":
+ $ref: "#/$defs/qcom-sm6350-lpass-state"
+ additionalProperties: false
+
+$defs:
+ qcom-sm6350-lpass-state:
+ type: object
+ description:
+ Pinctrl node's client devices use subnodes for desired pin configuration.
+ Client device subnodes use below standard properties.
+ $ref: qcom,lpass-lpi-common.yaml#/$defs/qcom-tlmm-state
+ unevaluatedProperties: false
+
+ properties:
+ pins:
+ description:
+ List of gpio pins affected by the properties specified in this
+ subnode.
+ items:
+ pattern: "^gpio([0-9]|1[0-4])$"
+
+ function:
+ enum: [ dmic1_clk, dmic1_data, dmic2_clk, dmic2_data, dmic3_clk,
+ dmic3_data, gpio, i2s1_clk, i2s1_data, i2s1_ws, i2s2_clk,
+ i2s2_data, i2s2_ws, qua_mi2s_data, qua_mi2s_sclk, qua_mi2s_ws,
+ swr_rx_clk, swr_rx_data, swr_tx_clk, swr_tx_data, wsa_swr_clk,
+ wsa_swr_data ]
+ description:
+ Specify the alternative function to be configured for the specified
+ pins.
+
+allOf:
+ - $ref: qcom,lpass-lpi-common.yaml#
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - clock-names
+
+unevaluatedProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/sound/qcom,q6dsp-lpass-ports.h>
+
+ lpass_tlmm: pinctrl@33c0000 {
+ compatible = "qcom,sm6350-lpass-lpi-pinctrl";
+ reg = <0x033c0000 0x20000>,
+ <0x03550000 0x10000>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ gpio-ranges = <&lpass_tlmm 0 0 15>;
+
+ clocks = <&q6afecc LPASS_HW_MACRO_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
+ <&q6afecc LPASS_HW_DCODEC_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>;
+ clock-names = "core",
+ "audio";
+
+ i2s1_active: i2s1-active-state {
+ clk-pins {
+ pins = "gpio6";
+ function = "i2s1_clk";
+ drive-strength = <8>;
+ bias-disable;
+ output-high;
+ };
+
+ ws-pins {
+ pins = "gpio7";
+ function = "i2s1_ws";
+ drive-strength = <8>;
+ bias-disable;
+ output-high;
+ };
+
+ data-pins {
+ pins = "gpio8", "gpio9";
+ function = "i2s1_data";
+ drive-strength = <8>;
+ bias-disable;
+ output-high;
+ };
+ };
+ };
--
2.54.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH v2 2/5] pinctrl: qcom: lpass-lpi: Add ability to use SPARE_1 for slew control
2026-04-30 7:10 [PATCH v2 0/5] Add LPASS LPI pin controller support for SM6350 Luca Weiss
2026-04-30 7:10 ` [PATCH v2 1/5] dt-bindings: pinctrl: qcom: Add SM6350 LPI pinctrl Luca Weiss
@ 2026-04-30 7:10 ` Luca Weiss
2026-04-30 7:10 ` [PATCH v2 3/5] pinctrl: qcom: Add SM6350 LPASS LPI TLMM Luca Weiss
` (3 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Luca Weiss @ 2026-04-30 7:10 UTC (permalink / raw)
To: Bjorn Andersson, Linus Walleij, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Konrad Dybcio, Srinivas Kandagatla
Cc: ~postmarketos/upstreaming, phone-devel, linux-arm-msm, linux-gpio,
devicetree, linux-kernel, Luca Weiss, Konrad Dybcio
On some platforms like SM6350 (Bitra), some pins have their slew
controlled with the SPARE_1 register. Add support for that.
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>
---
drivers/pinctrl/qcom/pinctrl-lpass-lpi.c | 2 ++
drivers/pinctrl/qcom/pinctrl-lpass-lpi.h | 20 ++++++++++++++++++++
2 files changed, 22 insertions(+)
diff --git a/drivers/pinctrl/qcom/pinctrl-lpass-lpi.c b/drivers/pinctrl/qcom/pinctrl-lpass-lpi.c
index 76aed3296279..15ced5027579 100644
--- a/drivers/pinctrl/qcom/pinctrl-lpass-lpi.c
+++ b/drivers/pinctrl/qcom/pinctrl-lpass-lpi.c
@@ -220,6 +220,8 @@ static int lpi_config_set_slew_rate(struct lpi_pinctrl *pctrl,
if (pctrl->data->flags & LPI_FLAG_SLEW_RATE_SAME_REG)
reg = pctrl->tlmm_base + LPI_TLMM_REG_OFFSET * group + LPI_GPIO_CFG_REG;
+ else if (g->slew_base_spare_1)
+ reg = pctrl->slew_base + LPI_SPARE_1_REG;
else
reg = pctrl->slew_base + LPI_SLEW_RATE_CTL_REG;
diff --git a/drivers/pinctrl/qcom/pinctrl-lpass-lpi.h b/drivers/pinctrl/qcom/pinctrl-lpass-lpi.h
index f48368492861..6ba0c4eba984 100644
--- a/drivers/pinctrl/qcom/pinctrl-lpass-lpi.h
+++ b/drivers/pinctrl/qcom/pinctrl-lpass-lpi.h
@@ -16,6 +16,7 @@ struct platform_device;
struct pinctrl_pin_desc;
#define LPI_SLEW_RATE_CTL_REG 0xa000
+#define LPI_SPARE_1_REG 0xc000
#define LPI_TLMM_REG_OFFSET 0x1000
#define LPI_SLEW_RATE_MAX 0x03
#define LPI_SLEW_BITS_SIZE 0x02
@@ -47,6 +48,7 @@ struct pinctrl_pin_desc;
{ \
.pin = id, \
.slew_offset = soff, \
+ .slew_base_spare_1 = false, \
.funcs = (int[]){ \
LPI_MUX_gpio, \
LPI_MUX_##f1, \
@@ -62,6 +64,7 @@ struct pinctrl_pin_desc;
{ \
.pin = id, \
.slew_offset = soff, \
+ .slew_base_spare_1 = false, \
.funcs = (int[]){ \
LPI_MUX_gpio, \
LPI_MUX_##f1, \
@@ -73,6 +76,22 @@ struct pinctrl_pin_desc;
.pin_offset = poff, \
}
+#define LPI_PINGROUP_SLEW_SPARE_1(id, soff, f1, f2, f3, f4) \
+ { \
+ .pin = id, \
+ .slew_offset = soff, \
+ .slew_base_spare_1 = true, \
+ .funcs = (int[]){ \
+ LPI_MUX_gpio, \
+ LPI_MUX_##f1, \
+ LPI_MUX_##f2, \
+ LPI_MUX_##f3, \
+ LPI_MUX_##f4, \
+ }, \
+ .nfuncs = 5, \
+ .pin_offset = 0, \
+ }
+
/*
* Slew rate control is done in the same register as rest of the
* pin configuration.
@@ -87,6 +106,7 @@ struct lpi_pingroup {
unsigned int *funcs;
unsigned int nfuncs;
unsigned int pin_offset;
+ bool slew_base_spare_1;
};
struct lpi_function {
--
2.54.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH v2 3/5] pinctrl: qcom: Add SM6350 LPASS LPI TLMM
2026-04-30 7:10 [PATCH v2 0/5] Add LPASS LPI pin controller support for SM6350 Luca Weiss
2026-04-30 7:10 ` [PATCH v2 1/5] dt-bindings: pinctrl: qcom: Add SM6350 LPI pinctrl Luca Weiss
2026-04-30 7:10 ` [PATCH v2 2/5] pinctrl: qcom: lpass-lpi: Add ability to use SPARE_1 for slew control Luca Weiss
@ 2026-04-30 7:10 ` Luca Weiss
2026-04-30 7:10 ` [PATCH v2 4/5] arm64: dts: qcom: sm6350: add LPASS LPI pin controller Luca Weiss
` (2 subsequent siblings)
5 siblings, 0 replies; 9+ messages in thread
From: Luca Weiss @ 2026-04-30 7:10 UTC (permalink / raw)
To: Bjorn Andersson, Linus Walleij, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Konrad Dybcio, Srinivas Kandagatla
Cc: ~postmarketos/upstreaming, phone-devel, linux-arm-msm, linux-gpio,
devicetree, linux-kernel, Luca Weiss, Dmitry Baryshkov,
Konrad Dybcio
Add support for the pin controller block on SM6350 Low Power Island.
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Luca Weiss <luca.weiss@fairphone.com>
---
drivers/pinctrl/qcom/Kconfig | 9 ++
drivers/pinctrl/qcom/Makefile | 1 +
drivers/pinctrl/qcom/pinctrl-sm6350-lpass-lpi.c | 149 ++++++++++++++++++++++++
3 files changed, 159 insertions(+)
diff --git a/drivers/pinctrl/qcom/Kconfig b/drivers/pinctrl/qcom/Kconfig
index 80af372a1147..ea7e10149e47 100644
--- a/drivers/pinctrl/qcom/Kconfig
+++ b/drivers/pinctrl/qcom/Kconfig
@@ -118,6 +118,15 @@ config PINCTRL_SM6115_LPASS_LPI
Qualcomm Technologies Inc LPASS (Low Power Audio SubSystem) LPI
(Low Power Island) found on the Qualcomm Technologies Inc SM6115 platform.
+config PINCTRL_SM6350_LPASS_LPI
+ tristate "Qualcomm Technologies Inc SM6350 LPASS LPI pin controller driver"
+ depends on ARM64 || COMPILE_TEST
+ depends on PINCTRL_LPASS_LPI
+ help
+ This is the pinctrl, pinmux, pinconf and gpiolib driver for the
+ Qualcomm Technologies Inc LPASS (Low Power Audio SubSystem) LPI
+ (Low Power Island) found on the Qualcomm Technologies Inc SM6350 platform.
+
config PINCTRL_SM8250_LPASS_LPI
tristate "Qualcomm Technologies Inc SM8250 LPASS LPI pin controller driver"
depends on ARM64 || COMPILE_TEST
diff --git a/drivers/pinctrl/qcom/Makefile b/drivers/pinctrl/qcom/Makefile
index 84bda3ada874..94e23a66ca3e 100644
--- a/drivers/pinctrl/qcom/Makefile
+++ b/drivers/pinctrl/qcom/Makefile
@@ -63,6 +63,7 @@ obj-$(CONFIG_PINCTRL_SM6115) += pinctrl-sm6115.o
obj-$(CONFIG_PINCTRL_SM6115_LPASS_LPI) += pinctrl-sm6115-lpass-lpi.o
obj-$(CONFIG_PINCTRL_SM6125) += pinctrl-sm6125.o
obj-$(CONFIG_PINCTRL_SM6350) += pinctrl-sm6350.o
+obj-$(CONFIG_PINCTRL_SM6350_LPASS_LPI) += pinctrl-sm6350-lpass-lpi.o
obj-$(CONFIG_PINCTRL_SM6375) += pinctrl-sm6375.o
obj-$(CONFIG_PINCTRL_SM7150) += pinctrl-sm7150.o
obj-$(CONFIG_PINCTRL_SM8150) += pinctrl-sm8150.o
diff --git a/drivers/pinctrl/qcom/pinctrl-sm6350-lpass-lpi.c b/drivers/pinctrl/qcom/pinctrl-sm6350-lpass-lpi.c
new file mode 100644
index 000000000000..4d06abcfedfd
--- /dev/null
+++ b/drivers/pinctrl/qcom/pinctrl-sm6350-lpass-lpi.c
@@ -0,0 +1,149 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2026, Luca Weiss <luca.weiss@fairphone.com>
+ */
+
+#include <linux/gpio/driver.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include "pinctrl-lpass-lpi.h"
+
+enum lpass_lpi_functions {
+ LPI_MUX_dmic1_clk,
+ LPI_MUX_dmic1_data,
+ LPI_MUX_dmic2_clk,
+ LPI_MUX_dmic2_data,
+ LPI_MUX_dmic3_clk,
+ LPI_MUX_dmic3_data,
+ LPI_MUX_i2s1_clk,
+ LPI_MUX_i2s1_data,
+ LPI_MUX_i2s1_ws,
+ LPI_MUX_i2s2_clk,
+ LPI_MUX_i2s2_data,
+ LPI_MUX_i2s2_ws,
+ LPI_MUX_qua_mi2s_data,
+ LPI_MUX_qua_mi2s_sclk,
+ LPI_MUX_qua_mi2s_ws,
+ LPI_MUX_swr_rx_clk,
+ LPI_MUX_swr_rx_data,
+ LPI_MUX_swr_tx_clk,
+ LPI_MUX_swr_tx_data,
+ LPI_MUX_wsa_swr_clk,
+ LPI_MUX_wsa_swr_data,
+ LPI_MUX_gpio,
+ LPI_MUX__,
+};
+
+static const struct pinctrl_pin_desc sm6350_lpi_pins[] = {
+ PINCTRL_PIN(0, "gpio0"),
+ PINCTRL_PIN(1, "gpio1"),
+ PINCTRL_PIN(2, "gpio2"),
+ PINCTRL_PIN(3, "gpio3"),
+ PINCTRL_PIN(4, "gpio4"),
+ PINCTRL_PIN(5, "gpio5"),
+ PINCTRL_PIN(6, "gpio6"),
+ PINCTRL_PIN(7, "gpio7"),
+ PINCTRL_PIN(8, "gpio8"),
+ PINCTRL_PIN(9, "gpio9"),
+ PINCTRL_PIN(10, "gpio10"),
+ PINCTRL_PIN(11, "gpio11"),
+ PINCTRL_PIN(12, "gpio12"),
+ PINCTRL_PIN(13, "gpio13"),
+ PINCTRL_PIN(14, "gpio14"),
+};
+
+static const char * const swr_tx_clk_groups[] = { "gpio0" };
+static const char * const swr_tx_data_groups[] = { "gpio1", "gpio2", "gpio14" };
+static const char * const swr_rx_clk_groups[] = { "gpio3" };
+static const char * const swr_rx_data_groups[] = { "gpio4", "gpio5" };
+static const char * const dmic1_clk_groups[] = { "gpio6" };
+static const char * const dmic1_data_groups[] = { "gpio7" };
+static const char * const dmic2_clk_groups[] = { "gpio8" };
+static const char * const dmic2_data_groups[] = { "gpio9" };
+static const char * const i2s2_clk_groups[] = { "gpio10" };
+static const char * const i2s2_ws_groups[] = { "gpio11" };
+static const char * const dmic3_clk_groups[] = { "gpio12" };
+static const char * const dmic3_data_groups[] = { "gpio13" };
+static const char * const qua_mi2s_sclk_groups[] = { "gpio0" };
+static const char * const qua_mi2s_ws_groups[] = { "gpio1" };
+static const char * const qua_mi2s_data_groups[] = { "gpio2", "gpio3", "gpio4", "gpio5" };
+static const char * const i2s1_clk_groups[] = { "gpio6" };
+static const char * const i2s1_ws_groups[] = { "gpio7" };
+static const char * const i2s1_data_groups[] = { "gpio8", "gpio9" };
+static const char * const wsa_swr_clk_groups[] = { "gpio10" };
+static const char * const wsa_swr_data_groups[] = { "gpio11" };
+static const char * const i2s2_data_groups[] = { "gpio12", "gpio13" };
+
+static const struct lpi_pingroup sm6350_groups[] = {
+ LPI_PINGROUP(0, 0, swr_tx_clk, qua_mi2s_sclk, _, _),
+ LPI_PINGROUP(1, 2, swr_tx_data, qua_mi2s_ws, _, _),
+ LPI_PINGROUP(2, 4, swr_tx_data, qua_mi2s_data, _, _),
+ LPI_PINGROUP(3, 8, swr_rx_clk, qua_mi2s_data, _, _),
+ LPI_PINGROUP(4, 10, swr_rx_data, qua_mi2s_data, _, _),
+ LPI_PINGROUP(5, 12, swr_rx_data, _, qua_mi2s_data, _),
+ LPI_PINGROUP(6, LPI_NO_SLEW, dmic1_clk, i2s1_clk, _, _),
+ LPI_PINGROUP(7, LPI_NO_SLEW, dmic1_data, i2s1_ws, _, _),
+ LPI_PINGROUP(8, LPI_NO_SLEW, dmic2_clk, i2s1_data, _, _),
+ LPI_PINGROUP(9, LPI_NO_SLEW, dmic2_data, i2s1_data, _, _),
+ LPI_PINGROUP(10, 16, i2s2_clk, wsa_swr_clk, _, _),
+ LPI_PINGROUP(11, 18, i2s2_ws, wsa_swr_data, _, _),
+ LPI_PINGROUP(12, LPI_NO_SLEW, dmic3_clk, i2s2_data, _, _),
+ LPI_PINGROUP(13, LPI_NO_SLEW, dmic3_data, i2s2_data, _, _),
+ LPI_PINGROUP_SLEW_SPARE_1(14, 0, swr_tx_data, _, _, _),
+};
+
+static const struct lpi_function sm6350_functions[] = {
+ LPI_FUNCTION(dmic1_clk),
+ LPI_FUNCTION(dmic1_data),
+ LPI_FUNCTION(dmic2_clk),
+ LPI_FUNCTION(dmic2_data),
+ LPI_FUNCTION(dmic3_clk),
+ LPI_FUNCTION(dmic3_data),
+ LPI_FUNCTION(i2s1_clk),
+ LPI_FUNCTION(i2s1_data),
+ LPI_FUNCTION(i2s1_ws),
+ LPI_FUNCTION(i2s2_clk),
+ LPI_FUNCTION(i2s2_data),
+ LPI_FUNCTION(i2s2_ws),
+ LPI_FUNCTION(qua_mi2s_data),
+ LPI_FUNCTION(qua_mi2s_sclk),
+ LPI_FUNCTION(qua_mi2s_ws),
+ LPI_FUNCTION(swr_rx_clk),
+ LPI_FUNCTION(swr_rx_data),
+ LPI_FUNCTION(swr_tx_clk),
+ LPI_FUNCTION(swr_tx_data),
+ LPI_FUNCTION(wsa_swr_clk),
+ LPI_FUNCTION(wsa_swr_data),
+};
+
+static const struct lpi_pinctrl_variant_data sm6350_lpi_data = {
+ .pins = sm6350_lpi_pins,
+ .npins = ARRAY_SIZE(sm6350_lpi_pins),
+ .groups = sm6350_groups,
+ .ngroups = ARRAY_SIZE(sm6350_groups),
+ .functions = sm6350_functions,
+ .nfunctions = ARRAY_SIZE(sm6350_functions),
+};
+
+static const struct of_device_id lpi_pinctrl_of_match[] = {
+ {
+ .compatible = "qcom,sm6350-lpass-lpi-pinctrl",
+ .data = &sm6350_lpi_data,
+ },
+ { }
+};
+MODULE_DEVICE_TABLE(of, lpi_pinctrl_of_match);
+
+static struct platform_driver lpi_pinctrl_driver = {
+ .driver = {
+ .name = "qcom-sm6350-lpass-lpi-pinctrl",
+ .of_match_table = lpi_pinctrl_of_match,
+ },
+ .probe = lpi_pinctrl_probe,
+ .remove = lpi_pinctrl_remove,
+};
+
+module_platform_driver(lpi_pinctrl_driver);
+MODULE_DESCRIPTION("Qualcomm SM6350 LPI GPIO pin control driver");
+MODULE_LICENSE("GPL");
--
2.54.0
^ permalink raw reply related [flat|nested] 9+ messages in thread