Devicetree
 help / color / mirror / Atom feed
* [PATCH 0/2] ASoC: codecs: wcd937x: add USB Type-C analog audio mux support
@ 2026-10-18 23:12 Val Packett
  2026-10-18 23:12 ` [PATCH 1/2] ASoC: dt-bindings: qcom,wcd937x: Add USB-C graph properties Val Packett
  2026-10-18 23:12 ` [PATCH 2/2] ASoC: codecs: wcd937x: add USB Type-C analog audio mux support Val Packett
  0 siblings, 2 replies; 5+ messages in thread
From: Val Packett @ 2026-10-18 23:12 UTC (permalink / raw)
  Cc: Val Packett, Srinivas Kandagatla, Liam Girdwood, Mark Brown,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Jaroslav Kysela,
	Takashi Iwai, ~postmarketos/upstreaming, phone-devel, linux-sound,
	linux-arm-msm, devicetree, linux-kernel

Currently only wcd939x has support for USB-C SBU audio in mainline, but the
older WCD codecs can do the same thing 939x does with USBSS, with an
external 3rd party mux instead. This series adds support for that based on
wcd939x code.

Tested with the FSA4480 (with the [1] series) on sm7325-motorola-dubai.

[1]: https://lore.kernel.org/all/20261018225906.1265299-1-val@packett.cool/

Thanks,
~val

---

Val Packett (2):
  ASoC: dt-bindings: qcom,wcd937x: Add USB-C graph properties
  ASoC: codecs: wcd937x: add USB Type-C analog audio mux support

 .../bindings/sound/qcom,wcd937x.yaml          |  15 ++
 sound/soc/codecs/wcd937x.c                    | 151 +++++++++++++++++-
 2 files changed, 163 insertions(+), 3 deletions(-)

-- 
2.55.0


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

* [PATCH 1/2] ASoC: dt-bindings: qcom,wcd937x: Add USB-C graph properties
  2026-10-18 23:12 [PATCH 0/2] ASoC: codecs: wcd937x: add USB Type-C analog audio mux support Val Packett
@ 2026-10-18 23:12 ` Val Packett
  2026-10-20  7:39   ` Krzysztof Kozlowski
  2026-10-18 23:12 ` [PATCH 2/2] ASoC: codecs: wcd937x: add USB Type-C analog audio mux support Val Packett
  1 sibling, 1 reply; 5+ messages in thread
From: Val Packett @ 2026-10-18 23:12 UTC (permalink / raw)
  To: Srinivas Kandagatla, Liam Girdwood, Mark Brown, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley
  Cc: Val Packett, Jaroslav Kysela, Takashi Iwai,
	~postmarketos/upstreaming, phone-devel, linux-sound,
	linux-arm-msm, devicetree, linux-kernel

This codec can be used with a USB-C SBU mux to support analog headphone
adapters. Describe the mode-switch, orientation-switch and port
properties similarly to wcd939x.

Signed-off-by: Val Packett <val@packett.cool>
---
 .../devicetree/bindings/sound/qcom,wcd937x.yaml   | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/Documentation/devicetree/bindings/sound/qcom,wcd937x.yaml b/Documentation/devicetree/bindings/sound/qcom,wcd937x.yaml
index f94203798f24..f15b9a9d90b1 100644
--- a/Documentation/devicetree/bindings/sound/qcom,wcd937x.yaml
+++ b/Documentation/devicetree/bindings/sound/qcom,wcd937x.yaml
@@ -25,6 +25,21 @@ properties:
           - const: qcom,wcd9375-codec
           - const: qcom,wcd9370-codec
 
+  mode-switch:
+    description: Flag the port as possible handler of altmode switching
+    type: boolean
+
+  orientation-switch:
+    description: Flag the port as possible handler of orientation switching
+    type: boolean
+
+  port:
+    $ref: /schemas/graph.yaml#/properties/port
+    description:
+      A port node to link the WCD937x Codec node to an external USB-C MUX IC for
+      handling altmode muxing and orientation switching to detect and enable
+      Audio Accessory Mode.
+
   vdd-px-supply:
     description: A reference to the 1.8V I/O supply
 
-- 
2.55.0


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

* [PATCH 2/2] ASoC: codecs: wcd937x: add USB Type-C analog audio mux support
  2026-10-18 23:12 [PATCH 0/2] ASoC: codecs: wcd937x: add USB Type-C analog audio mux support Val Packett
  2026-10-18 23:12 ` [PATCH 1/2] ASoC: dt-bindings: qcom,wcd937x: Add USB-C graph properties Val Packett
@ 2026-10-18 23:12 ` Val Packett
  2026-10-18 23:27   ` sashiko-bot
  1 sibling, 1 reply; 5+ messages in thread
From: Val Packett @ 2026-10-18 23:12 UTC (permalink / raw)
  To: Srinivas Kandagatla, Liam Girdwood, Mark Brown, Jaroslav Kysela,
	Takashi Iwai
  Cc: Val Packett, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	~postmarketos/upstreaming, phone-devel, linux-sound,
	linux-arm-msm, devicetree, linux-kernel

On mobile devices, this codec is frequently paired with a USB-C SBU mux
like the FSA4480 to support analog headphone adapters. To support this,
register the codec in the Type-C graph whenever one is present in the
device tree, handle the hotplug notifications and report detected GND-MIC
pin swap back to the external mux as Type-C orientation.

Based on code from the wcd939x driver.

Signed-off-by: Val Packett <val@packett.cool>
---
 sound/soc/codecs/wcd937x.c | 151 ++++++++++++++++++++++++++++++++++++-
 1 file changed, 148 insertions(+), 3 deletions(-)

diff --git a/sound/soc/codecs/wcd937x.c b/sound/soc/codecs/wcd937x.c
index 7ffbb445f8ac..770f5925e89f 100644
--- a/sound/soc/codecs/wcd937x.c
+++ b/sound/soc/codecs/wcd937x.c
@@ -8,12 +8,15 @@
 #include <linux/gpio/consumer.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/of_graph.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/regmap.h>
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>
+#include <linux/usb/typec_mux.h>
+#include <linux/usb/typec_altmode.h>
 #include <sound/jack.h>
 #include <sound/pcm_params.h>
 #include <sound/pcm.h>
@@ -82,6 +85,13 @@ struct wcd937x_priv {
 	struct regmap *regmap;
 	/* micb setup lock */
 	struct mutex micb_lock;
+	/* typec handling */
+	bool typec_analog_mux;
+#if IS_ENABLED(CONFIG_TYPEC)
+	enum typec_orientation typec_orientation;
+	unsigned long typec_mode;
+	struct typec_switch *typec_switch;
+#endif /* CONFIG_TYPEC */
 	/* mbhc module */
 	struct wcd_mbhc *wcd_mbhc;
 	struct wcd_mbhc_config mbhc_cfg;
@@ -1869,7 +1879,7 @@ static void wcd937x_mbhc_moisture_config(struct snd_soc_component *component)
 {
 	struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component);
 
-	if (wcd937x->mbhc_cfg.moist_rref == R_OFF) {
+	if (wcd937x->mbhc_cfg.moist_rref == R_OFF || wcd937x->typec_analog_mux) {
 		snd_soc_component_write_field(component, WCD937X_MBHC_NEW_CTL_2,
 					      WCD937X_M_RTH_CTL_MASK, R_OFF);
 		return;
@@ -1905,7 +1915,7 @@ static bool wcd937x_mbhc_get_moisture_status(struct snd_soc_component *component
 	struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component);
 	bool ret = false;
 
-	if (wcd937x->mbhc_cfg.moist_rref == R_OFF) {
+	if (wcd937x->mbhc_cfg.moist_rref == R_OFF || wcd937x->typec_analog_mux) {
 		snd_soc_component_write_field(component, WCD937X_MBHC_NEW_CTL_2,
 					      WCD937X_M_RTH_CTL_MASK, R_OFF);
 		goto done;
@@ -2634,6 +2644,40 @@ static const struct snd_soc_component_driver soc_codec_dev_wcd937x = {
 	.endianness = 1,
 };
 
+#if IS_ENABLED(CONFIG_TYPEC)
+/* Get USB-C plug orientation to provide swap event for MBHC */
+static int wcd937x_typec_switch_set(struct typec_switch_dev *sw,
+				    enum typec_orientation orientation)
+{
+	struct wcd937x_priv *wcd937x = typec_switch_get_drvdata(sw);
+
+	wcd937x->typec_orientation = orientation;
+
+	return 0;
+}
+
+static int wcd937x_typec_mux_set(struct typec_mux_dev *mux,
+				 struct typec_mux_state *state)
+{
+	struct wcd937x_priv *wcd937x = typec_mux_get_drvdata(mux);
+	unsigned int previous_mode = wcd937x->typec_mode;
+
+	if (!wcd937x->wcd_mbhc)
+		return -EINVAL;
+
+	if (wcd937x->typec_mode != state->mode) {
+		wcd937x->typec_mode = state->mode;
+
+		if (wcd937x->typec_mode == TYPEC_MODE_AUDIO)
+			return wcd_mbhc_typec_report_plug(wcd937x->wcd_mbhc);
+		else if (previous_mode == TYPEC_MODE_AUDIO)
+			return wcd_mbhc_typec_report_unplug(wcd937x->wcd_mbhc);
+	}
+
+	return 0;
+}
+#endif /* CONFIG_TYPEC */
+
 static bool wcd937x_swap_gnd_mic(struct snd_soc_component *component)
 {
 	int value;
@@ -2644,6 +2688,13 @@ static bool wcd937x_swap_gnd_mic(struct snd_soc_component *component)
 	value = gpiod_get_value(wcd937x->us_euro_gpio);
 	gpiod_set_value(wcd937x->us_euro_gpio, !value);
 
+#if IS_ENABLED(CONFIG_TYPEC)
+	if (wcd937x->typec_analog_mux && wcd937x->typec_switch)
+		typec_switch_set(wcd937x->typec_switch,
+				 wcd937x->typec_orientation == TYPEC_ORIENTATION_REVERSE ?
+					TYPEC_ORIENTATION_NORMAL : TYPEC_ORIENTATION_REVERSE);
+#endif /* CONFIG_TYPEC */
+
 	return true;
 }
 
@@ -2761,10 +2812,24 @@ static int wcd937x_bind(struct device *dev)
 	/* Give the SDW subdevices some more time to settle */
 	usleep_range(5000, 5010);
 
+#if IS_ENABLED(CONFIG_TYPEC)
+	/*
+	 * Get the USB Type-C switch to send GND/MIC swap events.
+	 * typec_switch is fetched now to avoid a probe deadlock since
+	 * the switch depends on the typec_mux register in wcd937x_probe()
+	 */
+	if (wcd937x->typec_analog_mux) {
+		wcd937x->typec_switch = fwnode_typec_switch_get(dev->fwnode);
+		if (IS_ERR(wcd937x->typec_switch))
+			return dev_err_probe(dev, PTR_ERR(wcd937x->typec_switch),
+					     "failed to acquire orientation-switch\n");
+	}
+#endif /* CONFIG_TYPEC */
+
 	ret = component_bind_all(dev, wcd937x);
 	if (ret) {
 		dev_err(dev, "Slave bind failed, ret = %d\n", ret);
-		return ret;
+		goto err_put_typec_switch;
 	}
 
 	wcd937x->rxdev = of_sdw_find_device_by_node(wcd937x->rxnode);
@@ -2852,6 +2917,12 @@ static int wcd937x_bind(struct device *dev)
 	put_device(wcd937x->rxdev);
 err_component_unbind:
 	component_unbind_all(dev, wcd937x);
+err_put_typec_switch:
+#if IS_ENABLED(CONFIG_TYPEC)
+	if (wcd937x->typec_analog_mux)
+		typec_switch_put(wcd937x->typec_switch);
+#endif /* CONFIG_TYPEC */
+
 	return ret;
 }
 
@@ -2874,6 +2945,61 @@ static const struct component_master_ops wcd937x_comp_ops = {
 	.unbind = wcd937x_unbind,
 };
 
+#if IS_ENABLED(CONFIG_TYPEC)
+static void wcd937x_typec_mux_unregister(void *data)
+{
+	struct typec_mux_dev *typec_mux = data;
+
+	typec_mux_unregister(typec_mux);
+}
+
+static void wcd937x_typec_switch_unregister(void *data)
+{
+	struct typec_switch_dev *typec_sw = data;
+
+	typec_switch_unregister(typec_sw);
+}
+
+static int wcd937x_add_typec(struct wcd937x_priv *wcd937x, struct device *dev)
+{
+	int ret;
+	struct typec_mux_dev *typec_mux;
+	struct typec_switch_dev *typec_sw;
+	struct typec_mux_desc mux_desc = {
+		.drvdata = wcd937x,
+		.fwnode = dev_fwnode(dev),
+		.set = wcd937x_typec_mux_set,
+	};
+	struct typec_switch_desc sw_desc = {
+		.drvdata = wcd937x,
+		.fwnode = dev_fwnode(dev),
+		.set = wcd937x_typec_switch_set,
+	};
+
+	typec_mux = typec_mux_register(dev, &mux_desc);
+	if (IS_ERR(typec_mux))
+		return dev_err_probe(dev, PTR_ERR(typec_mux),
+				     "failed to register typec mux\n");
+
+	ret = devm_add_action_or_reset(dev, wcd937x_typec_mux_unregister,
+				       typec_mux);
+	if (ret)
+		return ret;
+
+	typec_sw = typec_switch_register(dev, &sw_desc);
+	if (IS_ERR(typec_sw))
+		return dev_err_probe(dev, PTR_ERR(typec_sw),
+				     "failed to register typec switch\n");
+
+	ret = devm_add_action_or_reset(dev, wcd937x_typec_switch_unregister,
+				       typec_sw);
+	if (ret)
+		return ret;
+
+	return 0;
+}
+#endif
+
 static int wcd937x_add_slave_components(struct wcd937x_priv *wcd937x,
 					struct device *dev,
 					struct component_match **matchptr)
@@ -2907,6 +3033,9 @@ static int wcd937x_probe(struct platform_device *pdev)
 	struct device *dev = &pdev->dev;
 	struct wcd937x_priv *wcd937x;
 	struct wcd_mbhc_config *cfg;
+#if IS_ENABLED(CONFIG_TYPEC)
+	struct device_node *np;
+#endif /* CONFIG_TYPEC */
 	int ret;
 
 	wcd937x = devm_kzalloc(dev, sizeof(*wcd937x), GFP_KERNEL);
@@ -2951,6 +3080,22 @@ static int wcd937x_probe(struct platform_device *pdev)
 
 	wcd_dt_parse_mbhc_data(dev, &wcd937x->mbhc_cfg);
 
+#if IS_ENABLED(CONFIG_TYPEC)
+	/*
+	 * If the node has a port and a valid remote endpoint,
+	 * consider HP lines as connected to a USB-C SBU mux
+	 */
+	np = of_graph_get_remote_node(dev->of_node, 0, 0);
+	if (np) {
+		wcd937x->typec_analog_mux = true;
+		cfg->typec_analog_mux = true;
+
+		ret = wcd937x_add_typec(wcd937x, dev);
+		if (ret)
+			return ret;
+	}
+#endif /* CONFIG_TYPEC */
+
 	ret = wcd937x_add_slave_components(wcd937x, dev, &match);
 	if (ret)
 		return ret;
-- 
2.55.0


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

* Re: [PATCH 2/2] ASoC: codecs: wcd937x: add USB Type-C analog audio mux support
  2026-10-18 23:12 ` [PATCH 2/2] ASoC: codecs: wcd937x: add USB Type-C analog audio mux support Val Packett
@ 2026-10-18 23:27   ` sashiko-bot
  0 siblings, 0 replies; 5+ messages in thread
From: sashiko-bot @ 2026-10-18 23:27 UTC (permalink / raw)
  To: Val Packett; +Cc: devicetree, robh, conor+dt

Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [High] ASoC: wcd937x: UAF and invalid dereference in wcd937x_typec_mux_set()
- [Medium] ASoC: wcd937x: device_node reference leak in wcd937x_probe()
- [Medium] ASoC: wcd937x: typec_switch leak in wcd937x_unbind()
- [Low] ASoC: wcd937x: link failure when SND_SOC_WCD937X=y and TYPEC=m
--

commit 67788c3177c93896a3809eff47952d70eb25c1a1
Author: Val Packett <val@packett.cool>

ASoC: codecs: wcd937x: add USB Type-C analog audio mux support

This commit adds USB Type-C analog audio mux and orientation switch support
to the wcd937x codec driver, handling hotplug notifications and reporting
detected GND-MIC pin swaps back to the external mux.

> diff --git a/sound/soc/codecs/wcd937x.c b/sound/soc/codecs/wcd937x.c
> index 7ffbb445f8ac4..770f5925e89f3 100644
> --- a/sound/soc/codecs/wcd937x.c
> +++ b/sound/soc/codecs/wcd937x.c

[ ... ]

> @@ -2634,6 +2644,40 @@ static const struct snd_soc_component_driver soc_codec_dev_wcd937x = {
>  	.endianness = 1,
>  };
>  
> +#if IS_ENABLED(CONFIG_TYPEC)
> +/* Get USB-C plug orientation to provide swap event for MBHC */
> +static int wcd937x_typec_switch_set(struct typec_switch_dev *sw,
> +				    enum typec_orientation orientation)
> +{
> +	struct wcd937x_priv *wcd937x = typec_switch_get_drvdata(sw);
> +
> +	wcd937x->typec_orientation = orientation;
> +
> +	return 0;
> +}
> +
> +static int wcd937x_typec_mux_set(struct typec_mux_dev *mux,
> +				 struct typec_mux_state *state)
> +{
> +	struct wcd937x_priv *wcd937x = typec_mux_get_drvdata(mux);
> +	unsigned int previous_mode = wcd937x->typec_mode;
> +
> +	if (!wcd937x->wcd_mbhc)
> +		return -EINVAL;
> +
> +	if (wcd937x->typec_mode != state->mode) {
> +		wcd937x->typec_mode = state->mode;
> +
> +		if (wcd937x->typec_mode == TYPEC_MODE_AUDIO)
> +			return wcd_mbhc_typec_report_plug(wcd937x->wcd_mbhc);
> +		else if (previous_mode == TYPEC_MODE_AUDIO)
> +			return wcd_mbhc_typec_report_unplug(wcd937x->wcd_mbhc);
> +	}
> +
> +	return 0;
> +}
> +#endif /* CONFIG_TYPEC */

[Severity: High]
Can wcd937x_typec_mux_set() dereference a freed, error-valued, or partially
initialized wcd937x->wcd_mbhc pointer?

wcd937x_probe() registers wcd937x_typec_mux_set() via typec_mux_register()
and manages its lifetime with devm_add_action_or_reset() on the platform
device, so the callback remains active for the entire platform device
lifetime. However, wcd937x_typec_mux_set() only checks !wcd937x->wcd_mbhc
before calling wcd_mbhc_typec_report_plug() or
wcd_mbhc_typec_report_unplug(), both of which immediately dereference
mbhc->cfg->typec_analog_mux:

sound/soc/codecs/wcd-mbhc-v2.c:wcd_mbhc_typec_report_plug() {
	if (!mbhc || !mbhc->cfg->typec_analog_mux)
		return -EINVAL;

There appear to be three ways this check can be bypassed while wcd_mbhc is
not ready for use:

1. During sound card binding in snd_soc_bind_card(),
soc_probe_link_components() calls wcd937x_soc_codec_probe() ->
wcd937x_mbhc_init() -> wcd_mbhc_init(), which allocates wcd937x->wcd_mbhc
with mbhc->cfg left as NULL until wcd937x_codec_set_jack() later calls
wcd_mbhc_start(). If a Type-C audio mode event arrives before
wcd_mbhc_start() runs (or if set_jack is never called), mbhc->cfg is NULL.

2. When wcd937x_soc_codec_remove() runs (for example, if a subsequent DAI
link in snd_soc_bind_card() returns -EPROBE_DEFER and triggers
soc_cleanup_card_resources(), or when the sound card or component master is
unbound), wcd937x_mbhc_deinit() calls wcd_mbhc_deinit(wcd937x->wcd_mbhc),
which kfrees wcd937x->wcd_mbhc without clearing wcd937x->wcd_mbhc to NULL:

sound/soc/codecs/wcd937x.c:wcd937x_mbhc_deinit() {
	struct wcd937x_priv *wcd937x = snd_soc_component_get_drvdata(component);

	wcd_mbhc_deinit(wcd937x->wcd_mbhc);
}

3. If wcd_mbhc_init() fails in wcd937x_mbhc_init(), wcd937x->wcd_mbhc holds
an ERR_PTR value:

sound/soc/codecs/wcd937x.c:wcd937x_mbhc_init() {
	wcd937x->wcd_mbhc = wcd_mbhc_init(component, &mbhc_cb, intr_ids, wcd_mbhc_fields, true);
	if (IS_ERR(wcd937x->wcd_mbhc))
		return PTR_ERR(wcd937x->wcd_mbhc);

[ ... ]

> @@ -2852,6 +2917,12 @@ static int wcd937x_bind(struct device *dev)
>  	put_device(wcd937x->rxdev);
>  err_component_unbind:
>  	component_unbind_all(dev, wcd937x);
> +err_put_typec_switch:
> +#if IS_ENABLED(CONFIG_TYPEC)
> +	if (wcd937x->typec_analog_mux)
> +		typec_switch_put(wcd937x->typec_switch);
> +#endif /* CONFIG_TYPEC */
> +
>  	return ret;
>  }
>  
> @@ -2874,6 +2945,61 @@ static const struct component_master_ops wcd937x_comp_ops = {
>  	.unbind = wcd937x_unbind,
>  };

[Severity: Medium]
Does wcd937x_unbind() leak wcd937x->typec_switch?

In wcd937x_bind(), wcd937x->typec_switch is acquired via
fwnode_typec_switch_get(dev->fwnode) when wcd937x->typec_analog_mux is true.
fwnode_typec_switch_get() is not devm-managed; it allocates a struct
typec_switch and takes device and module references that must be released
with typec_switch_put().

While the error path in wcd937x_bind() calls
typec_switch_put(wcd937x->typec_switch), wcd937x_unbind() does not:

sound/soc/codecs/wcd937x.c:wcd937x_unbind() {
	struct wcd937x_priv *wcd937x = dev_get_drvdata(dev);

	snd_soc_unregister_component(dev);
	device_link_remove(dev, wcd937x->txdev);
	device_link_remove(dev, wcd937x->rxdev);
	device_link_remove(wcd937x->rxdev, wcd937x->txdev);
	component_unbind_all(dev, wcd937x);
	mutex_destroy(&wcd937x->micb_lock);
	put_device(wcd937x->txdev);
	put_device(wcd937x->rxdev);
}

> +#if IS_ENABLED(CONFIG_TYPEC)
> +static void wcd937x_typec_mux_unregister(void *data)
> +{
> +	struct typec_mux_dev *typec_mux = data;
> +
> +	typec_mux_unregister(typec_mux);
> +}

[Severity: Low]
Can this cause a link failure when CONFIG_SND_SOC_WCD937X_SDW=y (which
selects CONFIG_SND_SOC_WCD937X=y) and CONFIG_TYPEC=m?

With IS_ENABLED(CONFIG_TYPEC), built-in wcd937x.o will reference symbols
exported by typec.ko (such as typec_mux_register(), typec_switch_register(),
and fwnode_typec_switch_get()), but neither SND_SOC_WCD937X nor
SND_SOC_WCD937X_SDW in sound/soc/codecs/Kconfig has a "depends on TYPEC ||
!TYPEC" dependency like SND_SOC_WCD939X and SND_SOC_WCD939X_SDW do.

[ ... ]

> @@ -2951,6 +3080,22 @@ static int wcd937x_probe(struct platform_device *pdev)
>  
>  	wcd_dt_parse_mbhc_data(dev, &wcd937x->mbhc_cfg);
>  
> +#if IS_ENABLED(CONFIG_TYPEC)
> +	/*
> +	 * If the node has a port and a valid remote endpoint,
> +	 * consider HP lines as connected to a USB-C SBU mux
> +	 */
> +	np = of_graph_get_remote_node(dev->of_node, 0, 0);
> +	if (np) {
> +		wcd937x->typec_analog_mux = true;
> +		cfg->typec_analog_mux = true;
> +
> +		ret = wcd937x_add_typec(wcd937x, dev);
> +		if (ret)
> +			return ret;
> +	}
> +#endif /* CONFIG_TYPEC */
> +
>  	ret = wcd937x_add_slave_components(wcd937x, dev, &match);
>  	if (ret)
>  		return ret;

[Severity: Medium]
Does wcd937x_probe() leak the device_node reference returned by
of_graph_get_remote_node()?

of_graph_get_remote_node() returns a struct device_node pointer with its
reference count incremented, but of_node_put(np) is not called on either the
normal path or the early return when wcd937x_add_typec() fails.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261018231244.1266926-1-val@packett.cool?part=2

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

* Re: [PATCH 1/2] ASoC: dt-bindings: qcom,wcd937x: Add USB-C graph properties
  2026-10-18 23:12 ` [PATCH 1/2] ASoC: dt-bindings: qcom,wcd937x: Add USB-C graph properties Val Packett
@ 2026-10-20  7:39   ` Krzysztof Kozlowski
  0 siblings, 0 replies; 5+ messages in thread
From: Krzysztof Kozlowski @ 2026-10-20  7:39 UTC (permalink / raw)
  To: Val Packett
  Cc: Srinivas Kandagatla, Liam Girdwood, Mark Brown, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Jaroslav Kysela, Takashi Iwai,
	~postmarketos/upstreaming, phone-devel, linux-sound,
	linux-arm-msm, devicetree, linux-kernel

On Sun, Oct 18, 2026 at 08:12:29PM -0300, Val Packett wrote:
> This codec can be used with a USB-C SBU mux to support analog headphone
> adapters. Describe the mode-switch, orientation-switch and port
> properties similarly to wcd939x.
> 
> Signed-off-by: Val Packett <val@packett.cool>
> ---
>  .../devicetree/bindings/sound/qcom,wcd937x.yaml   | 15 +++++++++++++++
>  1 file changed, 15 insertions(+)

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>

Best regards,
Krzysztof


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

end of thread, other threads:[~2026-10-20  7:39 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-18 23:12 [PATCH 0/2] ASoC: codecs: wcd937x: add USB Type-C analog audio mux support Val Packett
2026-10-18 23:12 ` [PATCH 1/2] ASoC: dt-bindings: qcom,wcd937x: Add USB-C graph properties Val Packett
2026-10-20  7:39   ` Krzysztof Kozlowski
2026-10-18 23:12 ` [PATCH 2/2] ASoC: codecs: wcd937x: add USB Type-C analog audio mux support Val Packett
2026-10-18 23:27   ` sashiko-bot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox