All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/2] ASoC: codecs: twl4030: external mute GPIO lookup fix and binding update
@ 2026-10-27 21:32 Dmitry Torokhov
  2026-10-27 21:32 ` [PATCH v2 1/2] ASoC: codecs: twl4030: fix external mute GPIO lookup Dmitry Torokhov
  2026-10-27 21:32 ` [PATCH v2 2/2] dt-bindings: mfd: twl4030-audio: document preferred name for external mute Dmitry Torokhov
  0 siblings, 2 replies; 5+ messages in thread
From: Dmitry Torokhov @ 2026-10-27 21:32 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown, Jaroslav Kysela, Takashi Iwai,
	Peng Fan, Linus Walleij, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Peter Ujfalusi
  Cc: linux-sound, linux-kernel, devicetree

This series fixes external mute GPIO lookup for the TWL4030 codec driver
and updates the corresponding device tree binding.

The twl4030-codec platform device created by the twl4030-audio MFD does
not have its own of_node or fwnode assigned, as its DT properties reside
in the "codec" child node of the parent MFD device. Consequently,
standard devm_gpiod_get_optional() calls on the codec device never
succeed. Fix this by looking up the GPIO descriptor directly from the
codec child firmware node. Also update the device tree binding to
document the standard "ti,hs_extmute-gpios" property name.

Note that to fully restore external mute GPIO lookup on existing device
trees that still use the legacy "ti,hs_extmute_gpio" property name (with
an underscore), the companion gpiolib OF quirk [1] is also needed at
runtime. There is no build-time dependency between the two changes, so
they can be merged independently via the ASoC and GPIO trees.

[1] https://lore.kernel.org/r/20261022-gpiolib-of-v3-3-42c3b6439fba@gmail.com

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
Changes in v2:
- Drop redundant $ref on ti,hs_extmute-gpios and add deprecated: true
  to ti,hs_extmute_gpio in DT binding schema.
- Link to v1: https://patch.msgid.link/20261022-twl4030-extmute-v1-0-3d2dbe260df9@gmail.com

---
Dmitry Torokhov (2):
      ASoC: codecs: twl4030: fix external mute GPIO lookup
      dt-bindings: mfd: twl4030-audio: document preferred name for external mute

 .../bindings/sound/ti,twl4030-audio.yaml           |   8 +-
 sound/soc/codecs/twl4030.c                         | 108 +++++++++++----------
 2 files changed, 62 insertions(+), 54 deletions(-)
---
base-commit: f1ac44c32cba88ad65dcecd4a279661d14e93651
change-id: 20261022-twl4030-extmute-59e516f0e056

Thanks.

-- 
Dmitry


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v2 1/2] ASoC: codecs: twl4030: fix external mute GPIO lookup
  2026-10-27 21:32 [PATCH v2 0/2] ASoC: codecs: twl4030: external mute GPIO lookup fix and binding update Dmitry Torokhov
@ 2026-10-27 21:32 ` Dmitry Torokhov
  2026-10-27 21:40   ` sashiko-bot
  2026-10-27 21:32 ` [PATCH v2 2/2] dt-bindings: mfd: twl4030-audio: document preferred name for external mute Dmitry Torokhov
  1 sibling, 1 reply; 5+ messages in thread
From: Dmitry Torokhov @ 2026-10-27 21:32 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown, Jaroslav Kysela, Takashi Iwai,
	Peng Fan, Linus Walleij, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Peter Ujfalusi
  Cc: linux-sound, linux-kernel, devicetree

The twl4030-codec platform device instantiated by the twl4030-audio MFD
core does not have its own of_node or fwnode assigned; its device tree
properties reside in the "codec" child node of the parent MFD device
node.

Because of this, devm_gpiod_get_optional() called on the codec device
never locates the external mute GPIO. Furthermore, previous board param
handling only marked external mute active when the legacy
"ti,hs_extmute_gpio" property was present, ignoring the standard
"ti,hs_extmute-gpios" property when "ti,hs_extmute" was absent, and set
hs_extmute even if GPIO acquisition subsequently failed.

Switch to fwnode APIs to parse board properties directly inside
twl4030_get_board_params(), fold the helper function into it, and
acquire the GPIO descriptor directly from the "codec" child firmware
node using devm_fwnode_gpiod_get_optional() with the "ti,hs_extmute"
connection ID, removing the redundant legacy property check.

Fixes: 178c169a30b0 ("ASoC: codec: twl4030: Convert to GPIO descriptors")
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 sound/soc/codecs/twl4030.c | 108 +++++++++++++++++++++++----------------------
 1 file changed, 55 insertions(+), 53 deletions(-)

diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index 7117af5a1a56..9541c8a5a24e 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -6,6 +6,7 @@
  */
 
 #include <linux/delay.h>
+#include <linux/err.h>
 #include <linux/gpio/consumer.h>
 #include <linux/i2c.h>
 #include <linux/init.h>
@@ -13,9 +14,9 @@
 #include <linux/mfd/twl4030-audio.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
-#include <linux/of.h>
 #include <linux/pm.h>
 #include <linux/platform_device.h>
+#include <linux/property.h>
 #include <linux/slab.h>
 #include <sound/core.h>
 #include <sound/initval.h>
@@ -198,41 +199,53 @@ static void twl4030_codec_enable(struct snd_soc_component *component, int enable
 	udelay(10);
 }
 
-static void
-twl4030_get_board_param_values(struct twl4030_board_params *board_params,
-			       struct device_node *node)
+static struct twl4030_board_params *twl4030_get_board_params(struct device *dev)
 {
-	of_property_read_u32(node, "ti,digimic_delay", &board_params->digimic_delay);
-	of_property_read_u32(node, "ti,ramp_delay_value", &board_params->ramp_delay_value);
-	of_property_read_u32(node, "ti,offset_cncl_path", &board_params->offset_cncl_path);
-	board_params->hs_extmute = of_property_read_bool(node, "ti,hs_extmute");
+	struct twl4030_board_params *params;
+	int error;
 
-	if (of_property_present(node, "ti,hs_extmute_gpio"))
-		board_params->hs_extmute = 1;
-}
+	struct fwnode_handle *codec_node __free(fwnode_handle) =
+		device_get_named_child_node(dev->parent, "codec");
+	if (!codec_node)
+		return NULL;
 
-static struct twl4030_board_params*
-twl4030_get_board_params(struct device *dev)
-{
-	struct twl4030_board_params *board_params = NULL;
-	struct device_node *twl4030_codec_node = NULL;
-
-	twl4030_codec_node = of_get_child_by_name(dev->parent->of_node,
-						  "codec");
-
-	if (twl4030_codec_node) {
-		board_params = devm_kzalloc(dev,
-					    sizeof(struct twl4030_board_params),
-					    GFP_KERNEL);
-		if (!board_params) {
-			of_node_put(twl4030_codec_node);
-			return ERR_PTR(-ENOMEM);
-		}
-		twl4030_get_board_param_values(board_params, twl4030_codec_node);
-		of_node_put(twl4030_codec_node);
+	params = devm_kzalloc(dev, sizeof(*params), GFP_KERNEL);
+	if (!params)
+		return ERR_PTR(-ENOMEM);
+
+	fwnode_property_read_u32(codec_node, "ti,digimic_delay",
+				 &params->digimic_delay);
+	fwnode_property_read_u32(codec_node, "ti,ramp_delay_value",
+				 &params->ramp_delay_value);
+	fwnode_property_read_u32(codec_node, "ti,offset_cncl_path",
+				 &params->offset_cncl_path);
+
+	/*
+	 * Headset external mute can be controlled either via TWL4030's
+	 * dedicated GPIO6/EXTMUTE pin (enabled by the boolean "ti,hs_extmute"
+	 * property) or via a separate GPIO line ("ti,hs_extmute-gpios" or
+	 * legacy "ti,hs_extmute_gpio"), which implies external mute is active.
+	 */
+	params->hs_extmute = fwnode_property_read_bool(codec_node, "ti,hs_extmute");
+
+	/*
+	 * This will attempt to parse "ti,hs_extmute-gpios" or
+	 * "ti,hs_extmute_gpio".
+	 */
+	params->hs_extmute_gpio = devm_fwnode_gpiod_get_optional(dev, codec_node,
+								 "ti,hs_extmute",
+								 GPIOD_OUT_LOW,
+								 "hs_extmute");
+	error = PTR_ERR_OR_ZERO(params->hs_extmute_gpio);
+	if (error) {
+		dev_err_probe(dev, error, "Failed to get hs_extmute GPIO\n");
+		return ERR_PTR(error);
 	}
 
-	return board_params;
+	if (params->hs_extmute_gpio)
+		params->hs_extmute = 1;
+
+	return params;
 }
 
 static int twl4030_get_hw_params(struct device *dev,
@@ -244,30 +257,19 @@ static int twl4030_get_hw_params(struct device *dev,
 	if (IS_ERR(board_params))
 		return PTR_ERR(board_params);
 
-	if (board_params && board_params->hs_extmute) {
-		board_params->hs_extmute_gpio = devm_gpiod_get_optional(dev,
-									"ti,hs_extmute",
-									GPIOD_OUT_LOW);
-		if (IS_ERR(board_params->hs_extmute_gpio))
-			return dev_err_probe(dev,
-					     PTR_ERR(board_params->hs_extmute_gpio),
-					     "Failed to get hs_extmute GPIO\n");
-
-		if (board_params->hs_extmute_gpio) {
-			gpiod_set_consumer_name(board_params->hs_extmute_gpio, "hs_extmute");
-		} else {
-			u8 pin_mux;
+	if (board_params && board_params->hs_extmute &&
+	    !board_params->hs_extmute_gpio) {
+		u8 pin_mux;
 
-			dev_info(dev, "use TWL4030 GPIO6\n");
+		dev_info(dev, "use TWL4030 GPIO6\n");
 
-			/* Set TWL4030 GPIO6 as EXTMUTE signal */
-			twl_i2c_read_u8(TWL4030_MODULE_INTBR, &pin_mux,
-					TWL4030_PMBR1_REG);
-			pin_mux &= ~TWL4030_GPIO6_PWM0_MUTE(0x03);
-			pin_mux |= TWL4030_GPIO6_PWM0_MUTE(0x02);
-			twl_i2c_write_u8(TWL4030_MODULE_INTBR, pin_mux,
-					 TWL4030_PMBR1_REG);
-		}
+		/* Set TWL4030 GPIO6 as EXTMUTE signal */
+		twl_i2c_read_u8(TWL4030_MODULE_INTBR, &pin_mux,
+				TWL4030_PMBR1_REG);
+		pin_mux &= ~TWL4030_GPIO6_PWM0_MUTE(0x03);
+		pin_mux |= TWL4030_GPIO6_PWM0_MUTE(0x02);
+		twl_i2c_write_u8(TWL4030_MODULE_INTBR, pin_mux,
+				 TWL4030_PMBR1_REG);
 	}
 
 	twl4030->board_params = board_params;

-- 
2.56.0.307.g5fe7bd680c-goog


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v2 2/2] dt-bindings: mfd: twl4030-audio: document preferred name for external mute
  2026-10-27 21:32 [PATCH v2 0/2] ASoC: codecs: twl4030: external mute GPIO lookup fix and binding update Dmitry Torokhov
  2026-10-27 21:32 ` [PATCH v2 1/2] ASoC: codecs: twl4030: fix external mute GPIO lookup Dmitry Torokhov
@ 2026-10-27 21:32 ` Dmitry Torokhov
  2026-10-27 21:39   ` sashiko-bot
  1 sibling, 1 reply; 5+ messages in thread
From: Dmitry Torokhov @ 2026-10-27 21:32 UTC (permalink / raw)
  To: Liam Girdwood, Mark Brown, Jaroslav Kysela, Takashi Iwai,
	Peng Fan, Linus Walleij, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Peter Ujfalusi
  Cc: linux-sound, linux-kernel, devicetree

Proper names for GPIOs should use "-gpios" suffix. Now that the
twl4030 codec driver has been converted to use GPIO descriptors in
commit 178c169a30b0 ("ASoC: codec: twl4030: Convert to GPIO
descriptors"), update the binding documentation to list
"ti,hs_extmute-gpios" as the preferred property name and mark
"ti,hs_extmute_gpio" as deprecated.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
---
 Documentation/devicetree/bindings/sound/ti,twl4030-audio.yaml | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/sound/ti,twl4030-audio.yaml b/Documentation/devicetree/bindings/sound/ti,twl4030-audio.yaml
index c9c3f7513ad4..399693bed077 100644
--- a/Documentation/devicetree/bindings/sound/ti,twl4030-audio.yaml
+++ b/Documentation/devicetree/bindings/sound/ti,twl4030-audio.yaml
@@ -39,10 +39,16 @@ properties:
         description:
           Enable the use of an external mute for headset pop reduction.
 
+      ti,hs_extmute-gpios:
+        description:
+          The GPIO specifier for the external mute control.
+        maxItems: 1
+
       ti,hs_extmute_gpio:
         $ref: /schemas/types.yaml#/definitions/phandle-array
         description:
-          The GPIO specifier for the external mute control.
+          Deprecated legacy name for ti,hs_extmute-gpios.
+        deprecated: true
         maxItems: 1
 
       ti,offset_cncl_path:

-- 
2.56.0.307.g5fe7bd680c-goog


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH v2 2/2] dt-bindings: mfd: twl4030-audio: document preferred name for external mute
  2026-10-27 21:32 ` [PATCH v2 2/2] dt-bindings: mfd: twl4030-audio: document preferred name for external mute Dmitry Torokhov
@ 2026-10-27 21:39   ` sashiko-bot
  0 siblings, 0 replies; 5+ messages in thread
From: sashiko-bot @ 2026-10-27 21:39 UTC (permalink / raw)
  To: Dmitry Torokhov; +Cc: linux-sound, devicetree, robh, conor+dt

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] dt-bindings: mfd: twl4030-audio: legacy ti,hs_extmute_gpio not parsed by gpiolib
--

commit 532ee39ea30fdb221d903a6c57f70fe4aec67890
Author: Dmitry Torokhov <dmitry.torokhov@gmail.com>

dt-bindings: mfd: twl4030-audio: document preferred name for external mute

This commit documents ti,hs_extmute-gpios as the preferred property name for
the external headset mute GPIO in the twl4030-audio binding and marks
ti,hs_extmute_gpio as deprecated.

> diff --git a/Documentation/devicetree/bindings/sound/ti,twl4030-audio.yaml b/Documentation/devicetree/bindings/sound/ti,twl4030-audio.yaml
> index c9c3f7513ad42..399693bed077a 100644
> --- a/Documentation/devicetree/bindings/sound/ti,twl4030-audio.yaml
> +++ b/Documentation/devicetree/bindings/sound/ti,twl4030-audio.yaml
> @@ -39,10 +39,16 @@ properties:
>          description:
>            Enable the use of an external mute for headset pop reduction.
>  
> +      ti,hs_extmute-gpios:
> +        description:
> +          The GPIO specifier for the external mute control.
> +        maxItems: 1
> +
>        ti,hs_extmute_gpio:
>          $ref: /schemas/types.yaml#/definitions/phandle-array
>          description:
> -          The GPIO specifier for the external mute control.
> +          Deprecated legacy name for ti,hs_extmute-gpios.
> +        deprecated: true
>          maxItems: 1

[Severity: Medium]
Does gpiolib actually resolve the deprecated ti,hs_extmute_gpio property
(with an underscore before gpio) when the driver requests con_id
"ti,hs_extmute"?

In sound/soc/codecs/twl4030.c, twl4030_get_board_params() requests the GPIO
via:

	/*
	 * This will attempt to parse "ti,hs_extmute-gpios" or
	 * "ti,hs_extmute_gpio".
	 */
	params->hs_extmute_gpio = devm_fwnode_gpiod_get_optional(dev, codec_node,
								 "ti,hs_extmute",
								 GPIOD_OUT_LOW,
								 "hs_extmute");

However, of_find_gpio() builds property names using
for_each_gpio_property_name() in drivers/gpio/gpiolib.h, which formats
candidates with a hyphen separator over gpio_suffixes[] ("gpios" and "gpio"):

	if (con_id)
		snprintf(propname, sizeof(propname), "%s-%s", con_id, __gs);

For con_id "ti,hs_extmute", gpiolib only checks "ti,hs_extmute-gpios" and
"ti,hs_extmute-gpio", not "ti,hs_extmute_gpio", and of_find_gpio_rename() in
drivers/gpio/gpiolib-of.c has no rename entry for this property.

On device trees using the legacy ti,hs_extmute_gpio property, such as
twl_audio in arch/arm/boot/dts/ti/omap/logicpd-som-lv.dtsi:

	twl_audio: audio {
		compatible = "ti,twl4030-audio";
		codec {
			ti,hs_extmute_gpio = <&gpio2 25 GPIO_ACTIVE_HIGH>;
		};
	};

devm_fwnode_gpiod_get_optional() will return NULL, leaving external headset
mute disabled or configuring the internal TWL4030_PMBR1_REG EXTMUTE mux
instead of driving the external GPIO when ti,hs_extmute is also present.

Should the driver fall back to requesting the legacy property name (or add a
quirk in gpiolib-of.c) so that existing device trees using ti,hs_extmute_gpio
continue to work?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261027-twl4030-extmute-v2-0-c7e0c90509a1@gmail.com?part=2

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v2 1/2] ASoC: codecs: twl4030: fix external mute GPIO lookup
  2026-10-27 21:32 ` [PATCH v2 1/2] ASoC: codecs: twl4030: fix external mute GPIO lookup Dmitry Torokhov
@ 2026-10-27 21:40   ` sashiko-bot
  0 siblings, 0 replies; 5+ messages in thread
From: sashiko-bot @ 2026-10-27 21:40 UTC (permalink / raw)
  To: Dmitry Torokhov; +Cc: linux-sound, devicetree, robh, conor+dt

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] ASoC: twl4030: broken ti,hs_extmute_gpio lookup in twl4030_get_board_params()
--

commit 4ac8bbc6b258588c0a2286c88c8f200492ec2c36
Author: Dmitry Torokhov <dmitry.torokhov@gmail.com>

ASoC: codecs: twl4030: fix external mute GPIO lookup

This commit switches twl4030_get_board_params() to fwnode APIs and acquires
the external mute GPIO descriptor directly from the "codec" child firmware
node using devm_fwnode_gpiod_get_optional().

> diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
> index 7117af5a1a569..9541c8a5a24e8 100644
> --- a/sound/soc/codecs/twl4030.c
> +++ b/sound/soc/codecs/twl4030.c

[ ... ]

> @@ -198,41 +199,53 @@ static void twl4030_codec_enable(struct snd_soc_component *component, int enable
>  	udelay(10);
>  }
>  
> -static void
> -twl4030_get_board_param_values(struct twl4030_board_params *board_params,
> -			       struct device_node *node)
> +static struct twl4030_board_params *twl4030_get_board_params(struct device *dev)
>  {
> -	of_property_read_u32(node, "ti,digimic_delay", &board_params->digimic_delay);
> -	of_property_read_u32(node, "ti,ramp_delay_value", &board_params->ramp_delay_value);
> -	of_property_read_u32(node, "ti,offset_cncl_path", &board_params->offset_cncl_path);
> -	board_params->hs_extmute = of_property_read_bool(node, "ti,hs_extmute");
> +	struct twl4030_board_params *params;
> +	int error;
>  
> -	if (of_property_present(node, "ti,hs_extmute_gpio"))
> -		board_params->hs_extmute = 1;
> -}

[ ... ]

> +	/*
> +	 * This will attempt to parse "ti,hs_extmute-gpios" or
> +	 * "ti,hs_extmute_gpio".
> +	 */
> +	params->hs_extmute_gpio = devm_fwnode_gpiod_get_optional(dev, codec_node,
> +								 "ti,hs_extmute",
> +								 GPIOD_OUT_LOW,
> +								 "hs_extmute");

[Severity: High]
Will devm_fwnode_gpiod_get_optional() with con_id "ti,hs_extmute" actually
find the legacy "ti,hs_extmute_gpio" property (with an underscore)?

In drivers/gpio/gpiolib.h, for_each_gpio_property_name() constructs candidate
property names using a hyphen separator:

	if (con_id)
		snprintf(propname, sizeof(propname), "%s-%s", con_id, __gs);

With gpio_suffixes[] containing "gpios" and "gpio", passing "ti,hs_extmute"
makes of_find_gpio() in drivers/gpio/gpiolib-of.c look up
"ti,hs_extmute-gpios" and "ti,hs_extmute-gpio", and there is no entry in
of_find_gpio_rename() mapping "ti,hs_extmute" to "ti,hs_extmute_gpio".

However, both Documentation/devicetree/bindings/sound/ti,twl4030-audio.yaml
and arch/arm/boot/dts/ti/omap/logicpd-som-lv.dtsi spell the legacy property
with an underscore:

	twl_audio: audio {
		compatible = "ti,twl4030-audio";
		codec {
			ti,hs_extmute_gpio = <&gpio2 25 GPIO_ACTIVE_HIGH>;
		};
	};

On boards using "ti,hs_extmute_gpio", devm_fwnode_gpiod_get_optional() will
return NULL. When "ti,hs_extmute" is absent (as in logicpd-som-lv.dtsi), both
params->hs_extmute_gpio and params->hs_extmute remain unset, leaving external
mute disabled. When "ti,hs_extmute" is present alongside
"ti,hs_extmute_gpio", twl4030_get_hw_params() sees params->hs_extmute == 1 and
!params->hs_extmute_gpio, causing it to mux TWL4030's internal GPIO6 as
EXTMUTE instead of driving the external GPIO.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261027-twl4030-extmute-v2-0-c7e0c90509a1@gmail.com?part=1

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-10-27 21:40 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-27 21:32 [PATCH v2 0/2] ASoC: codecs: twl4030: external mute GPIO lookup fix and binding update Dmitry Torokhov
2026-10-27 21:32 ` [PATCH v2 1/2] ASoC: codecs: twl4030: fix external mute GPIO lookup Dmitry Torokhov
2026-10-27 21:40   ` sashiko-bot
2026-10-27 21:32 ` [PATCH v2 2/2] dt-bindings: mfd: twl4030-audio: document preferred name for external mute Dmitry Torokhov
2026-10-27 21:39   ` sashiko-bot

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.