All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/7] ASoC: Add Loongson-2K0300 I2S controller and sound card support
@ 2026-06-04  2:11 Binbin Zhou
  2026-06-04  2:11 ` [PATCH v2 1/7] ASoC: dt-bindings: loongson,ls2k1000-i2s: Document Loongson-2K0300 compatible Binbin Zhou
                   ` (6 more replies)
  0 siblings, 7 replies; 14+ messages in thread
From: Binbin Zhou @ 2026-06-04  2:11 UTC (permalink / raw)
  To: Binbin Zhou, Huacai Chen, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Liam Girdwood, Mark Brown, Jaroslav Kysela,
	Takashi Iwai
  Cc: Huacai Chen, Xuerui Wang, loongarch, devicetree, linux-sound,
	Binbin Zhou

Hi all:

This series adds ASoC support for the Loongson-2K0300 SoC and its
associated development boards, including the CTCISZ Forever Pi and the
ATK-DL2K0300B.

Key changes:
- Extend DT bindings to support ls2k0300-i2s and new audio card
  compatibles.
- Refactor the platform I2S driver to handle SoC differences via per-device
  configuration (rev_id, optional APB DMA config, reset sequence).
- Refactor the audio machine driver to support board-specific DAI formats,
  GPIO-based headphone detection/mute, speaker enable, and DAPM routing.
- Add jack detection and automatic switching between headphones and
  speakers for the DL2K0300B board.

The patchset also cleans up the existing audio card binding by
referencing the common sound-card properties, and adds new compatibles
for the Loongson-2K0300 variants with proper DAI format handling.

All changes have been tested on Loongson-2K2000 (PCI), Loongson-2K0300
Forever Pi and Loongson-2K0300 DL2K0300B boards.

Thanks.
Binbin

========
v2:
- The first four patches for V1 (related to code cleanup) have been
  accepted as a separate series. The link is as follows:
https://lore.kernel.org/all/178041371415.93058.4794135670349989571.b4-ty@b4/

Patch (1/7):
  - Add Reviewed-by tag from Krzysztof Kozlowski;
Patch (3/7):
  - New patch;
  - Reference sound-card-common.yaml, drop custom model property;
Patch (4/7)(5/7):
  - New patches;
  - Support Forever Pi board with different DAI format;
Patch (6/7)(7/7):
  - New patches;
  - Implement headphone jack detection and DAPM routing for ATK-DL2K0300B
    board.

Link to V1:
https://lore.kernel.org/all/cover.1773107475.git.zhoubinbin@loongson.cn/

Binbin Zhou (7):
  ASoC: dt-bindings: loongson,ls2k1000-i2s: Document Loongson-2K0300
    compatible
  ASoC: loongson: Add Loongson-2K0300 I2S controller support
  ASoC: dt-bindings: loongson,ls-audio-card: Use common sound card
  ASoC: dt-bindings: loongson,ls-audio-card: Add ctcisz forever pi
    compatible
  ASoC: loongson: Add Loongson-2K0300 CTCISZ Forever Pi sound card
    support
  ASoC: dt-bindings: loongson,ls-audio-card: Add ATK-DL2K0300B
    compatible
  ASoC: loongson: Add headphone jack detection and DAPM routing

 .../sound/loongson,ls-audio-card.yaml         |  52 +++++-
 .../bindings/sound/loongson,ls2k1000-i2s.yaml |  22 ++-
 sound/soc/loongson/loongson_card.c            | 163 +++++++++++++++++-
 sound/soc/loongson/loongson_i2s_plat.c        |  42 ++++-
 4 files changed, 256 insertions(+), 23 deletions(-)


base-commit: b2a71527074f5e4d273a25f6c89fb159172b2877
-- 
2.52.0


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

* [PATCH v2 1/7] ASoC: dt-bindings: loongson,ls2k1000-i2s: Document Loongson-2K0300 compatible
  2026-06-04  2:11 [PATCH v2 0/7] ASoC: Add Loongson-2K0300 I2S controller and sound card support Binbin Zhou
@ 2026-06-04  2:11 ` Binbin Zhou
  2026-06-04  2:11 ` [PATCH v2 2/7] ASoC: loongson: Add Loongson-2K0300 I2S controller support Binbin Zhou
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 14+ messages in thread
From: Binbin Zhou @ 2026-06-04  2:11 UTC (permalink / raw)
  To: Binbin Zhou, Huacai Chen, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Liam Girdwood, Mark Brown, Jaroslav Kysela,
	Takashi Iwai
  Cc: Huacai Chen, Xuerui Wang, loongarch, devicetree, linux-sound,
	Binbin Zhou, Krzysztof Kozlowski

Add a new compatible string `loongson,ls2k0300-i2s` for the I2S
controller found on Loongson-2K0300 SoC.

Unlike Loongson-2K1000, Loongson-2K0300 does not require the second
register region for APB DMA configuration, so update the binding to
allow a single reg entry.

Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn>
---
 .../bindings/sound/loongson,ls2k1000-i2s.yaml | 22 ++++++++++++++++++-
 1 file changed, 21 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/sound/loongson,ls2k1000-i2s.yaml b/Documentation/devicetree/bindings/sound/loongson,ls2k1000-i2s.yaml
index da79510bb2d9..51e23c189f7a 100644
--- a/Documentation/devicetree/bindings/sound/loongson,ls2k1000-i2s.yaml
+++ b/Documentation/devicetree/bindings/sound/loongson,ls2k1000-i2s.yaml
@@ -14,9 +14,12 @@ allOf:
 
 properties:
   compatible:
-    const: loongson,ls2k1000-i2s
+    enum:
+      - loongson,ls2k0300-i2s
+      - loongson,ls2k1000-i2s
 
   reg:
+    minItems: 1
     items:
       - description: Loongson I2S controller Registers.
       - description: APB DMA config register for Loongson I2S controller.
@@ -49,6 +52,23 @@ required:
 
 unevaluatedProperties: false
 
+if:
+  properties:
+    compatible:
+      contains:
+        enum:
+          - loongson,ls2k1000-i2s
+
+then:
+  properties:
+    reg:
+      minItems: 2
+
+else:
+  properties:
+    reg:
+      maxItems: 1
+
 examples:
   - |
     #include <dt-bindings/clock/loongson,ls2k-clk.h>
-- 
2.52.0


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

* [PATCH v2 2/7] ASoC: loongson: Add Loongson-2K0300 I2S controller support
  2026-06-04  2:11 [PATCH v2 0/7] ASoC: Add Loongson-2K0300 I2S controller and sound card support Binbin Zhou
  2026-06-04  2:11 ` [PATCH v2 1/7] ASoC: dt-bindings: loongson,ls2k1000-i2s: Document Loongson-2K0300 compatible Binbin Zhou
@ 2026-06-04  2:11 ` Binbin Zhou
  2026-06-04  2:24   ` sashiko-bot
  2026-06-04  2:11 ` [PATCH v2 3/7] ASoC: dt-bindings: loongson,ls-audio-card: Use common sound card Binbin Zhou
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 14+ messages in thread
From: Binbin Zhou @ 2026-06-04  2:11 UTC (permalink / raw)
  To: Binbin Zhou, Huacai Chen, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Liam Girdwood, Mark Brown, Jaroslav Kysela,
	Takashi Iwai
  Cc: Huacai Chen, Xuerui Wang, loongarch, devicetree, linux-sound,
	Binbin Zhou

The Loongson-2K0300 I2S interface differs significantly from the
Loongson-2K1000. Although both utilize external DMA controllers, the
Loongson-2K0300 does not require additional registers for routing
configuration.

Due to hardware design flaw, an extra controller reset sequence is
required during probe.

Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn>
---
 sound/soc/loongson/loongson_i2s_plat.c | 42 +++++++++++++++++++++-----
 1 file changed, 35 insertions(+), 7 deletions(-)

diff --git a/sound/soc/loongson/loongson_i2s_plat.c b/sound/soc/loongson/loongson_i2s_plat.c
index ac054b6ce632..b4d807ee7f8f 100644
--- a/sound/soc/loongson/loongson_i2s_plat.c
+++ b/sound/soc/loongson/loongson_i2s_plat.c
@@ -2,7 +2,7 @@
 //
 // Loongson I2S controller master mode dirver(platform device)
 //
-// Copyright (C) 2023-2024 Loongson Technology Corporation Limited
+// Copyright (C) 2023-2026 Loongson Technology Corporation Limited
 //
 // Author: Yingkun Meng <mengyingkun@loongson.cn>
 //         Binbin Zhou <zhoubinbin@loongson.cn>
@@ -21,6 +21,7 @@
 #include "loongson_i2s.h"
 #include "loongson_dma.h"
 
+/* Loongson-2K1000 APBDMA routing */
 #define LOONGSON_I2S_RX_DMA_OFFSET	21
 #define LOONGSON_I2S_TX_DMA_OFFSET	18
 
@@ -30,6 +31,11 @@
 #define LOONGSON_DMA3_CONF	0x3
 #define LOONGSON_DMA4_CONF	0x4
 
+struct loongson_i2s_plat_config {
+	int rev_id;
+	int (*i2s_dma_config)(struct platform_device *pdev);
+};
+
 static int loongson_i2s_apbdma_config(struct platform_device *pdev)
 {
 	int val;
@@ -47,8 +53,18 @@ static int loongson_i2s_apbdma_config(struct platform_device *pdev)
 	return 0;
 }
 
+static struct loongson_i2s_plat_config ls2k1000_i2s_plat_config = {
+	.rev_id = 0,
+	.i2s_dma_config = loongson_i2s_apbdma_config,
+};
+
+static struct loongson_i2s_plat_config ls2k0300_i2s_plat_config = {
+	.rev_id = 1,
+};
+
 static int loongson_i2s_plat_probe(struct platform_device *pdev)
 {
+	const struct loongson_i2s_plat_config *plat_config;
 	struct device *dev = &pdev->dev;
 	struct loongson_i2s *i2s;
 	struct resource *res;
@@ -59,12 +75,17 @@ static int loongson_i2s_plat_probe(struct platform_device *pdev)
 	if (!i2s)
 		return -ENOMEM;
 
-	ret = loongson_i2s_apbdma_config(pdev);
-	if (ret)
-		return ret;
+	plat_config = device_get_match_data(dev);
+	if (!plat_config)
+		return -EINVAL;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	i2s->reg_base = devm_ioremap_resource(&pdev->dev, res);
+	if (plat_config->i2s_dma_config) {
+		ret = plat_config->i2s_dma_config(pdev);
+		if (ret)
+			return ret;
+	}
+
+	i2s->reg_base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
 	if (IS_ERR(i2s->reg_base))
 		return dev_err_probe(dev, PTR_ERR(i2s->reg_base),
 				     "devm_ioremap_resource failed\n");
@@ -87,11 +108,17 @@ static int loongson_i2s_plat_probe(struct platform_device *pdev)
 	if (IS_ERR(i2s_clk))
 		return dev_err_probe(dev, PTR_ERR(i2s_clk), "clock property invalid\n");
 	i2s->clk_rate = clk_get_rate(i2s_clk);
+	i2s->rev_id = plat_config->rev_id;
 
 	dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
 	dev_set_name(dev, LS_I2S_DRVNAME);
 	dev_set_drvdata(dev, i2s);
 
+	if (i2s->rev_id == 1) {
+		regmap_update_bits(i2s->regmap, LS_I2S_CTRL, I2S_CTRL_RESET, I2S_CTRL_RESET);
+		fsleep(200);
+	}
+
 	ret = devm_snd_soc_register_component(dev, &loongson_i2s_edma_component,
 					      &loongson_i2s_dai, 1);
 	if (ret)
@@ -102,7 +129,8 @@ static int loongson_i2s_plat_probe(struct platform_device *pdev)
 }
 
 static const struct of_device_id loongson_i2s_ids[] = {
-	{ .compatible = "loongson,ls2k1000-i2s" },
+	{ .compatible = "loongson,ls2k0300-i2s", .data = &ls2k0300_i2s_plat_config },
+	{ .compatible = "loongson,ls2k1000-i2s", .data = &ls2k1000_i2s_plat_config },
 	{ /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, loongson_i2s_ids);
-- 
2.52.0


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

* [PATCH v2 3/7] ASoC: dt-bindings: loongson,ls-audio-card: Use common sound card
  2026-06-04  2:11 [PATCH v2 0/7] ASoC: Add Loongson-2K0300 I2S controller and sound card support Binbin Zhou
  2026-06-04  2:11 ` [PATCH v2 1/7] ASoC: dt-bindings: loongson,ls2k1000-i2s: Document Loongson-2K0300 compatible Binbin Zhou
  2026-06-04  2:11 ` [PATCH v2 2/7] ASoC: loongson: Add Loongson-2K0300 I2S controller support Binbin Zhou
@ 2026-06-04  2:11 ` Binbin Zhou
  2026-06-04  2:11 ` [PATCH v2 4/7] ASoC: dt-bindings: loongson,ls-audio-card: Add ctcisz forever pi compatible Binbin Zhou
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 14+ messages in thread
From: Binbin Zhou @ 2026-06-04  2:11 UTC (permalink / raw)
  To: Binbin Zhou, Huacai Chen, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Liam Girdwood, Mark Brown, Jaroslav Kysela,
	Takashi Iwai
  Cc: Huacai Chen, Xuerui Wang, loongarch, devicetree, linux-sound,
	Binbin Zhou

Reference the common sound card properties. This allows removing the
`model` property and directly using the common `audio-routing` property
later on.

Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn>
---
 .../bindings/sound/loongson,ls-audio-card.yaml        | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/Documentation/devicetree/bindings/sound/loongson,ls-audio-card.yaml b/Documentation/devicetree/bindings/sound/loongson,ls-audio-card.yaml
index 61e8babed402..e1b7445a8b22 100644
--- a/Documentation/devicetree/bindings/sound/loongson,ls-audio-card.yaml
+++ b/Documentation/devicetree/bindings/sound/loongson,ls-audio-card.yaml
@@ -8,20 +8,20 @@ title: Loongson 7axxx/2kxxx ASoC audio sound card driver
 
 maintainers:
   - Yingkun Meng <mengyingkun@loongson.cn>
+  - Binbin Zhou <zhoubinbin@loongson.cn>
 
 description:
   The binding describes the sound card present in loongson
   7axxx/2kxxx platform. The sound card is an ASoC component
   which uses Loongson I2S controller to transfer the audio data.
 
+allOf:
+  - $ref: sound-card-common.yaml#
+
 properties:
   compatible:
     const: loongson,ls-audio-card
 
-  model:
-    $ref: /schemas/types.yaml#/definitions/string
-    description: User specified audio sound card name
-
   mclk-fs:
     $ref: simple-card.yaml#/definitions/mclk-fs
 
@@ -47,12 +47,11 @@ properties:
 
 required:
   - compatible
-  - model
   - mclk-fs
   - cpu
   - codec
 
-additionalProperties: false
+unevaluatedProperties: false
 
 examples:
   - |
-- 
2.52.0


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

* [PATCH v2 4/7] ASoC: dt-bindings: loongson,ls-audio-card: Add ctcisz forever pi compatible
  2026-06-04  2:11 [PATCH v2 0/7] ASoC: Add Loongson-2K0300 I2S controller and sound card support Binbin Zhou
                   ` (2 preceding siblings ...)
  2026-06-04  2:11 ` [PATCH v2 3/7] ASoC: dt-bindings: loongson,ls-audio-card: Use common sound card Binbin Zhou
@ 2026-06-04  2:11 ` Binbin Zhou
  2026-06-04  2:21   ` sashiko-bot
  2026-06-04  2:11 ` [PATCH v2 5/7] ASoC: loongson: Add Loongson-2K0300 CTCISZ Forever Pi sound card support Binbin Zhou
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 14+ messages in thread
From: Binbin Zhou @ 2026-06-04  2:11 UTC (permalink / raw)
  To: Binbin Zhou, Huacai Chen, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Liam Girdwood, Mark Brown, Jaroslav Kysela,
	Takashi Iwai
  Cc: Huacai Chen, Xuerui Wang, loongarch, devicetree, linux-sound,
	Binbin Zhou

Add a new compatible string `loongson,ls2k0300-ctcisz-audio-card` for
the audio card on Loongson-2K0300 ctcisz forever pi SoC. It uses a
different DAI format compared to existing Loongson platforms.

The existing "loongson,ls-audio-card" remains valid for LS7A,
Loongson-2K1000 and Loongson-2K2000.

Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn>
---
 .../devicetree/bindings/sound/loongson,ls-audio-card.yaml     | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/sound/loongson,ls-audio-card.yaml b/Documentation/devicetree/bindings/sound/loongson,ls-audio-card.yaml
index e1b7445a8b22..8c214e5d04b1 100644
--- a/Documentation/devicetree/bindings/sound/loongson,ls-audio-card.yaml
+++ b/Documentation/devicetree/bindings/sound/loongson,ls-audio-card.yaml
@@ -20,7 +20,9 @@ allOf:
 
 properties:
   compatible:
-    const: loongson,ls-audio-card
+    enum:
+      - loongson,ls-audio-card  # Loongson-2K1000/Loongson-2K2000/LS7A
+      - loongson,ls2k0300-forever-pi-audio-card # CTCISZ Forever Pi
 
   mclk-fs:
     $ref: simple-card.yaml#/definitions/mclk-fs
-- 
2.52.0


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

* [PATCH v2 5/7] ASoC: loongson: Add Loongson-2K0300 CTCISZ Forever Pi sound card support
  2026-06-04  2:11 [PATCH v2 0/7] ASoC: Add Loongson-2K0300 I2S controller and sound card support Binbin Zhou
                   ` (3 preceding siblings ...)
  2026-06-04  2:11 ` [PATCH v2 4/7] ASoC: dt-bindings: loongson,ls-audio-card: Add ctcisz forever pi compatible Binbin Zhou
@ 2026-06-04  2:11 ` Binbin Zhou
  2026-06-04  2:26   ` sashiko-bot
  2026-06-04  2:11 ` [PATCH v2 6/7] ASoC: dt-bindings: loongson,ls-audio-card: Add ATK-DL2K0300B compatible Binbin Zhou
  2026-06-04  2:11 ` [PATCH v2 7/7] ASoC: loongson: Add headphone jack detection and DAPM routing Binbin Zhou
  6 siblings, 1 reply; 14+ messages in thread
From: Binbin Zhou @ 2026-06-04  2:11 UTC (permalink / raw)
  To: Binbin Zhou, Huacai Chen, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Liam Girdwood, Mark Brown, Jaroslav Kysela,
	Takashi Iwai
  Cc: Huacai Chen, Xuerui Wang, loongarch, devicetree, linux-sound,
	Binbin Zhou

The Loongson-2K0300 audio card uses a different DAI format compared to
existing Loongson platforms.

Move the dai_fmt setting from the static DAI link to runtime hw_params
via snd_soc_runtime_set_dai_fmt(), and pass the correct format through
driver match data.

Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn>
---
 sound/soc/loongson/loongson_card.c | 34 +++++++++++++++++++++++++-----
 1 file changed, 29 insertions(+), 5 deletions(-)

diff --git a/sound/soc/loongson/loongson_card.c b/sound/soc/loongson/loongson_card.c
index 7910d5d9ac4f..9200e8476c1f 100644
--- a/sound/soc/loongson/loongson_card.c
+++ b/sound/soc/loongson/loongson_card.c
@@ -2,8 +2,9 @@
 //
 // Loongson ASoC Audio Machine driver
 //
-// Copyright (C) 2023 Loongson Technology Corporation Limited
+// Copyright (C) 2023-2026 Loongson Technology Corporation Limited
 // Author: Yingkun Meng <mengyingkun@loongson.cn>
+//         Binbin Zhou <zhoubinbin@loongson.cn>
 //
 
 #include <linux/module.h>
@@ -18,6 +19,19 @@ static char codec_name[SND_ACPI_I2C_ID_LEN];
 struct loongson_card_data {
 	struct snd_soc_card snd_card;
 	unsigned int mclk_fs;
+	const struct loongson_card_config *cfg;
+};
+
+struct loongson_card_config {
+	unsigned int fmt;
+};
+
+static const struct loongson_card_config ls2k1000_card_config = {
+	.fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_IB_NF | SND_SOC_DAIFMT_CBC_CFC,
+};
+
+static const struct loongson_card_config ls2k0300_forever_pi_card_config = {
+	.fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC,
 };
 
 static int loongson_card_hw_params(struct snd_pcm_substream *substream,
@@ -45,7 +59,7 @@ static int loongson_card_hw_params(struct snd_pcm_substream *substream,
 		return ret;
 	}
 
-	return 0;
+	return snd_soc_runtime_set_dai_fmt(rtd, ls_card->cfg->fmt);
 }
 
 static const struct snd_soc_ops loongson_ops = {
@@ -61,8 +75,6 @@ static struct snd_soc_dai_link loongson_dai_links[] = {
 	{
 		.name = "Loongson Audio Port",
 		.stream_name = "Loongson Audio",
-		.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_IB_NF
-			| SND_SOC_DAIFMT_CBC_CFC,
 		SND_SOC_DAILINK_REG(analog),
 		.ops = &loongson_ops,
 	},
@@ -175,6 +187,10 @@ static int loongson_asoc_card_probe(struct platform_device *pdev)
 	if (!ls_priv)
 		return -ENOMEM;
 
+	ls_priv->cfg = (const struct loongson_card_config *)device_get_match_data(dev);
+	if (!ls_priv->cfg)
+		return -EINVAL;
+
 	card = &ls_priv->snd_card;
 
 	card->dev = dev;
@@ -200,7 +216,15 @@ static int loongson_asoc_card_probe(struct platform_device *pdev)
 }
 
 static const struct of_device_id loongson_asoc_dt_ids[] = {
-	{ .compatible = "loongson,ls-audio-card" },
+	/* Loongson-2K1000/Loongson-2K2000/LS7A */
+	{
+		.compatible = "loongson,ls-audio-card",
+		.data = &ls2k1000_card_config
+	},
+	{
+		.compatible = "loongson,ls2k0300-forever-pi-audio-card",
+		.data = &ls2k0300_forever_pi_card_config
+	},
 	{ /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, loongson_asoc_dt_ids);
-- 
2.52.0


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

* [PATCH v2 6/7] ASoC: dt-bindings: loongson,ls-audio-card: Add ATK-DL2K0300B compatible
  2026-06-04  2:11 [PATCH v2 0/7] ASoC: Add Loongson-2K0300 I2S controller and sound card support Binbin Zhou
                   ` (4 preceding siblings ...)
  2026-06-04  2:11 ` [PATCH v2 5/7] ASoC: loongson: Add Loongson-2K0300 CTCISZ Forever Pi sound card support Binbin Zhou
@ 2026-06-04  2:11 ` Binbin Zhou
  2026-06-04  2:11 ` [PATCH v2 7/7] ASoC: loongson: Add headphone jack detection and DAPM routing Binbin Zhou
  6 siblings, 0 replies; 14+ messages in thread
From: Binbin Zhou @ 2026-06-04  2:11 UTC (permalink / raw)
  To: Binbin Zhou, Huacai Chen, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Liam Girdwood, Mark Brown, Jaroslav Kysela,
	Takashi Iwai
  Cc: Huacai Chen, Xuerui Wang, loongarch, devicetree, linux-sound,
	Binbin Zhou

Add new compatible for the ATK-DL2K0300B development board based on
Loongson-2K0300.

Unlike others, this board features GPIO-controlled headphone detection,
headphone mute, and speaker enable.

Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn>
---
 .../sound/loongson,ls-audio-card.yaml         | 37 +++++++++++++++++++
 1 file changed, 37 insertions(+)

diff --git a/Documentation/devicetree/bindings/sound/loongson,ls-audio-card.yaml b/Documentation/devicetree/bindings/sound/loongson,ls-audio-card.yaml
index 8c214e5d04b1..e9b248e8246c 100644
--- a/Documentation/devicetree/bindings/sound/loongson,ls-audio-card.yaml
+++ b/Documentation/devicetree/bindings/sound/loongson,ls-audio-card.yaml
@@ -23,6 +23,7 @@ properties:
     enum:
       - loongson,ls-audio-card  # Loongson-2K1000/Loongson-2K2000/LS7A
       - loongson,ls2k0300-forever-pi-audio-card # CTCISZ Forever Pi
+      - loongson,ls2k0300-dl2k0300b-audio-card # ATK-DL2K0300B
 
   mclk-fs:
     $ref: simple-card.yaml#/definitions/mclk-fs
@@ -47,6 +48,18 @@ properties:
     required:
       - sound-dai
 
+  loongson,spkr-en-gpios:
+    maxItems: 1
+    description: The GPIO that enables the speakers
+
+  loongson,hp-mute-gpios:
+    maxItems: 1
+    description: The GPIO that mutes the headphones
+
+  loongson,hp-det-gpios:
+    maxItems: 1
+    description: The GPIO that detect headphones are plugged in
+
 required:
   - compatible
   - mclk-fs
@@ -69,3 +82,27 @@ examples:
              sound-dai = <&es8323>;
         };
     };
+
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+
+    sound {
+        compatible = "loongson,ls2k0300-dl2k0300b-audio-card";
+        model = "loongson-audio";
+        mclk-fs = <512>;
+        loongson,hp-det-gpios = <&gpio 81 GPIO_ACTIVE_HIGH>;
+        loongson,spkr-en-gpios = <&gpio 86 GPIO_ACTIVE_HIGH>;
+        loongson,hp-mute-gpios = <&gpio 87 GPIO_ACTIVE_HIGH>;
+        audio-routing =
+                      "Headphone", "LOUT1",
+                      "Headphone", "ROUT1",
+                      "Speaker", "LOUT2",
+                      "Speaker", "ROUT2";
+
+        cpu {
+            sound-dai = <&i2s>;
+        };
+        codec {
+             sound-dai = <&es8388>;
+        };
+    };
-- 
2.52.0


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

* [PATCH v2 7/7] ASoC: loongson: Add headphone jack detection and DAPM routing
  2026-06-04  2:11 [PATCH v2 0/7] ASoC: Add Loongson-2K0300 I2S controller and sound card support Binbin Zhou
                   ` (5 preceding siblings ...)
  2026-06-04  2:11 ` [PATCH v2 6/7] ASoC: dt-bindings: loongson,ls-audio-card: Add ATK-DL2K0300B compatible Binbin Zhou
@ 2026-06-04  2:11 ` Binbin Zhou
  2026-06-04  2:27   ` sashiko-bot
  2026-06-04 14:56   ` Mark Brown
  6 siblings, 2 replies; 14+ messages in thread
From: Binbin Zhou @ 2026-06-04  2:11 UTC (permalink / raw)
  To: Binbin Zhou, Huacai Chen, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Liam Girdwood, Mark Brown, Jaroslav Kysela,
	Takashi Iwai
  Cc: Huacai Chen, Xuerui Wang, loongarch, devicetree, linux-sound,
	Binbin Zhou

Extend the Loongson audio machine driver with jack detection, DAPM
widgets support, enabling proper switching between headphones and
speakers on the Loongson-2K0300 ATK-DL2K0300B board.

Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn>
---
 sound/soc/loongson/loongson_card.c | 129 ++++++++++++++++++++++++++++-
 1 file changed, 126 insertions(+), 3 deletions(-)

diff --git a/sound/soc/loongson/loongson_card.c b/sound/soc/loongson/loongson_card.c
index 9200e8476c1f..ee0cf305187a 100644
--- a/sound/soc/loongson/loongson_card.c
+++ b/sound/soc/loongson/loongson_card.c
@@ -7,33 +7,129 @@
 //         Binbin Zhou <zhoubinbin@loongson.cn>
 //
 
-#include <linux/module.h>
-#include <sound/soc.h>
-#include <sound/soc-acpi.h>
 #include <linux/acpi.h>
+#include <linux/gpio/consumer.h>
+#include <linux/module.h>
 #include <linux/pci.h>
+#include <sound/jack.h>
 #include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include <sound/soc-acpi.h>
 
 static char codec_name[SND_ACPI_I2C_ID_LEN];
 
 struct loongson_card_data {
 	struct snd_soc_card snd_card;
 	unsigned int mclk_fs;
+	struct gpio_desc *gpiod_hp_det;
+	struct gpio_desc *gpiod_hp_mute;
+	struct gpio_desc *gpiod_spkr_en;
 	const struct loongson_card_config *cfg;
 };
 
 struct loongson_card_config {
 	unsigned int fmt;
+	bool add_hp_jack;
+	bool add_dapm_widgets;
 };
 
 static const struct loongson_card_config ls2k1000_card_config = {
 	.fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_IB_NF | SND_SOC_DAIFMT_CBC_CFC,
+	.add_hp_jack = false,
+	.add_dapm_widgets = false,
 };
 
 static const struct loongson_card_config ls2k0300_forever_pi_card_config = {
 	.fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC,
+	.add_hp_jack = false,
+	.add_dapm_widgets = false,
+};
+
+static const struct loongson_card_config ls2k0300_dl2k0300b_card_config = {
+	.fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBC_CFC,
+	.add_hp_jack = true,
+	.add_dapm_widgets = true,
+};
+
+/* DAPM widget event: control headphone mute GPIO */
+static int headphone_widget_event(struct snd_soc_dapm_widget *w,
+				  struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_card *card = snd_soc_dapm_to_card(w->dapm);
+	struct loongson_card_data *priv = snd_soc_card_get_drvdata(card);
+
+	gpiod_set_value_cansleep(priv->gpiod_hp_mute, SND_SOC_DAPM_EVENT_ON(event));
+
+	return 0;
+}
+
+/* DAPM widget event: control speaker enable GPIO */
+static int speaker_widget_event(struct snd_soc_dapm_widget *w,
+				struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_card *card = snd_soc_dapm_to_card(w->dapm);
+	struct loongson_card_data *priv = snd_soc_card_get_drvdata(card);
+
+	gpiod_set_value_cansleep(priv->gpiod_spkr_en, SND_SOC_DAPM_EVENT_ON(event));
+
+	return 0;
+}
+
+static const struct snd_soc_dapm_widget loongson_aosc_dapm_widgets[] = {
+	SND_SOC_DAPM_HP("Headphone", headphone_widget_event),
+	SND_SOC_DAPM_SPK("Speaker", speaker_widget_event),
+};
+
+/* Headphones Jack */
+
+static struct snd_soc_jack loongson_asoc_hp_jack;
+
+static struct snd_soc_jack_pin loongson_asoc_hp_jack_pins[] = {
+	{
+		.pin = "Headphone",
+		.mask = SND_JACK_HEADPHONE
+	},
+	{
+		.pin = "Speaker",
+		.mask = SND_JACK_HEADPHONE,
+		.invert = 1
+	},
 };
 
+static struct snd_soc_jack_gpio loongson_asoc_hp_jack_gpio = {
+	.name = "Headphones detection",
+	.report = SND_JACK_HEADPHONE,
+	.debounce_time = 150,
+};
+
+static int loongson_asoc_machine_init(struct snd_soc_pcm_runtime *rtd)
+{
+	struct snd_soc_card *card = rtd->card;
+	struct loongson_card_data *ls_priv = snd_soc_card_get_drvdata(card);
+	int ret = 0;
+
+	if (!ls_priv->cfg->add_hp_jack)
+		return 0;
+
+	ret = snd_soc_card_jack_new_pins(card, "Headphones Jack",
+					 SND_JACK_HEADPHONE,
+					 &loongson_asoc_hp_jack,
+					 loongson_asoc_hp_jack_pins,
+					 ARRAY_SIZE(loongson_asoc_hp_jack_pins));
+	if (ret) {
+		dev_err(rtd->dev, "Headphones Jack creation failed: %d\n", ret);
+		return ret;
+	}
+
+	loongson_asoc_hp_jack_gpio.desc = ls_priv->gpiod_hp_det;
+
+	ret = snd_soc_jack_add_gpios(&loongson_asoc_hp_jack, 1, &loongson_asoc_hp_jack_gpio);
+	if (ret)
+		dev_err(rtd->dev, "Headphone GPIO not added: %d\n", ret);
+
+	return ret;
+}
+
 static int loongson_card_hw_params(struct snd_pcm_substream *substream,
 				   struct snd_pcm_hw_params *params)
 {
@@ -75,6 +171,7 @@ static struct snd_soc_dai_link loongson_dai_links[] = {
 	{
 		.name = "Loongson Audio Port",
 		.stream_name = "Loongson Audio",
+		.init = loongson_asoc_machine_init,
 		SND_SOC_DAILINK_REG(analog),
 		.ops = &loongson_ops,
 	},
@@ -197,6 +294,12 @@ static int loongson_asoc_card_probe(struct platform_device *pdev)
 	card->owner = THIS_MODULE;
 	card->dai_link = loongson_dai_links;
 	card->num_links = ARRAY_SIZE(loongson_dai_links);
+
+	if (ls_priv->cfg->add_dapm_widgets) {
+		card->dapm_widgets = loongson_aosc_dapm_widgets;
+		card->num_dapm_widgets = ARRAY_SIZE(loongson_aosc_dapm_widgets);
+	}
+
 	snd_soc_card_set_drvdata(card, ls_priv);
 
 	ret = device_property_read_string(dev, "model", &card->name);
@@ -207,6 +310,22 @@ static int loongson_asoc_card_probe(struct platform_device *pdev)
 	if (ret)
 		return dev_err_probe(dev, ret, "Error parsing mclk-fs\n");
 
+	ls_priv->gpiod_hp_det = devm_gpiod_get_optional(dev, "loongson,hp-det", GPIOD_IN);
+	if (IS_ERR(ls_priv->gpiod_hp_det))
+		return PTR_ERR(ls_priv->gpiod_hp_det);
+
+	ls_priv->gpiod_hp_mute = devm_gpiod_get_optional(dev, "loongson,hp-mute", GPIOD_OUT_LOW);
+	if (IS_ERR(ls_priv->gpiod_hp_mute))
+		return PTR_ERR(ls_priv->gpiod_hp_mute);
+
+	ls_priv->gpiod_spkr_en = devm_gpiod_get_optional(dev, "loongson,spkr-en", GPIOD_OUT_LOW);
+	if (IS_ERR(ls_priv->gpiod_spkr_en))
+		return PTR_ERR(ls_priv->gpiod_spkr_en);
+
+	ret = snd_soc_of_parse_audio_routing(card, "audio-routing");
+	if (ret)
+		dev_warn(dev, "Unable to parse routing\n");
+
 	ret = has_acpi_companion(dev) ? loongson_card_parse_acpi(ls_priv)
 				      : loongson_card_parse_of(ls_priv);
 	if (ret)
@@ -225,6 +344,10 @@ static const struct of_device_id loongson_asoc_dt_ids[] = {
 		.compatible = "loongson,ls2k0300-forever-pi-audio-card",
 		.data = &ls2k0300_forever_pi_card_config
 	},
+	{
+		.compatible = "loongson,ls2k0300-dl2k0300b-audio-card",
+		.data = &ls2k0300_dl2k0300b_card_config
+	},
 	{ /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, loongson_asoc_dt_ids);
-- 
2.52.0


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

* Re: [PATCH v2 4/7] ASoC: dt-bindings: loongson,ls-audio-card: Add ctcisz forever pi compatible
  2026-06-04  2:11 ` [PATCH v2 4/7] ASoC: dt-bindings: loongson,ls-audio-card: Add ctcisz forever pi compatible Binbin Zhou
@ 2026-06-04  2:21   ` sashiko-bot
  0 siblings, 0 replies; 14+ messages in thread
From: sashiko-bot @ 2026-06-04  2:21 UTC (permalink / raw)
  To: Binbin Zhou; +Cc: conor+dt, devicetree, robh

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] The commit message specifies a different compatible string than what is actually added in the code.
--

commit 9b240b4406c6099d7dd0c7904cdd748ee7b2bb68
Author: Binbin Zhou <zhoubinbin@loongson.cn>

ASoC: dt-bindings: loongson,ls-audio-card: Add ctcisz forever pi compatible

This commit adds a new compatible string for the audio card on the
Loongson-2K0300 ctcisz forever pi SoC.

> Add a new compatible string `loongson,ls2k0300-ctcisz-audio-card` for
> the audio card on Loongson-2K0300 ctcisz forever pi SoC.

[Severity: Medium]
Is the compatible string in this description accurate? The commit message
specifies loongson,ls2k0300-ctcisz-audio-card, but the code actually adds
loongson,ls2k0300-forever-pi-audio-card to the properties enum in the
device tree bindings.

Subsequent patches in the series correctly implement driver support for
loongson,ls2k0300-forever-pi-audio-card, which suggests the code is correct
but the commit message is inaccurate. Could the commit message be updated to
match the code?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/cover.1780538113.git.zhoubinbin@loongson.cn?part=4

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

* Re: [PATCH v2 2/7] ASoC: loongson: Add Loongson-2K0300 I2S controller support
  2026-06-04  2:11 ` [PATCH v2 2/7] ASoC: loongson: Add Loongson-2K0300 I2S controller support Binbin Zhou
@ 2026-06-04  2:24   ` sashiko-bot
  0 siblings, 0 replies; 14+ messages in thread
From: sashiko-bot @ 2026-06-04  2:24 UTC (permalink / raw)
  To: Binbin Zhou; +Cc: robh, devicetree, conor+dt

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] The hardware reset sequence is executed during probe but is missing from the resume path, which will cause the device to malfunction after waking up from sleep.
- [Low] Platform configuration structures are not marked as `const`.
--

commit 33b4276799f09ecdd4e5a93ded6b7cc2b6154e10
Author: Binbin Zhou <zhoubinbin@loongson.cn>

ASoC: loongson: Add Loongson-2K0300 I2S controller support
    
This commit adds support for the Loongson-2K0300 I2S controller. It introduces
new match data structures and applies an extra hardware reset sequence during
probe to work around a controller design flaw.

> diff --git a/sound/soc/loongson/loongson_i2s_plat.c b/sound/soc/loongson/loongson_i2s_plat.c
> index ac054b6ce6322..b4d807ee7f8f3 100644
> --- a/sound/soc/loongson/loongson_i2s_plat.c
> +++ b/sound/soc/loongson/loongson_i2s_plat.c

[ ... ]

> @@ -47,8 +53,18 @@ static int loongson_i2s_apbdma_config(struct platform_device *pdev)
>  	return 0;
>  }
>  
> +static struct loongson_i2s_plat_config ls2k1000_i2s_plat_config = {
> +	.rev_id = 0,
> +	.i2s_dma_config = loongson_i2s_apbdma_config,
> +};
> +
> +static struct loongson_i2s_plat_config ls2k0300_i2s_plat_config = {
> +	.rev_id = 1,
> +};
> +

[Severity: Low]
Should these platform configuration structures be marked as const?

Since they are statically allocated and used exclusively as read-only match
data, omitting const places them in the mutable .data section instead of
.rodata. Marking them as const would save RAM and reduce the mutable attack
surface.

>  static int loongson_i2s_plat_probe(struct platform_device *pdev)
>  {

[ ... ]

> @@ -87,11 +108,17 @@ static int loongson_i2s_plat_probe(struct platform_device *pdev)
>  	if (IS_ERR(i2s_clk))
>  		return dev_err_probe(dev, PTR_ERR(i2s_clk), "clock property invalid\n");
>  	i2s->clk_rate = clk_get_rate(i2s_clk);
> +	i2s->rev_id = plat_config->rev_id;
>  
>  	dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64));
>  	dev_set_name(dev, LS_I2S_DRVNAME);
>  	dev_set_drvdata(dev, i2s);
>  
> +	if (i2s->rev_id == 1) {
> +		regmap_update_bits(i2s->regmap, LS_I2S_CTRL, I2S_CTRL_RESET, I2S_CTRL_RESET);
> +		fsleep(200);
> +	}
> +

[Severity: High]
Will the device malfunction after waking up from sleep because this reset
sequence is missing from the resume path?

If the device loses power during system suspend, it will wake up in its
default flawed state. The shared PM operations only perform a
regcache_sync() during resume:

sound/soc/loongson/loongson_i2s.c:i2s_resume() {
	struct loongson_i2s *i2s = dev_get_drvdata(dev);
	regcache_cache_only(i2s->regmap, false);
	return regcache_sync(i2s->regmap);
}

Because LS_I2S_CTRL is a volatile register, regcache_sync() skips it.
Without reapplying this reset sequence in i2s_resume(), does the controller
remain in an unstable state after resuming?

>  	ret = devm_snd_soc_register_component(dev, &loongson_i2s_edma_component,
>  					      &loongson_i2s_dai, 1);
>  	if (ret)

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/cover.1780538113.git.zhoubinbin@loongson.cn?part=2

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

* Re: [PATCH v2 5/7] ASoC: loongson: Add Loongson-2K0300 CTCISZ Forever Pi sound card support
  2026-06-04  2:11 ` [PATCH v2 5/7] ASoC: loongson: Add Loongson-2K0300 CTCISZ Forever Pi sound card support Binbin Zhou
@ 2026-06-04  2:26   ` sashiko-bot
  0 siblings, 0 replies; 14+ messages in thread
From: sashiko-bot @ 2026-06-04  2:26 UTC (permalink / raw)
  To: Binbin Zhou; +Cc: conor+dt, devicetree, robh

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:

Pre-existing issues:
- [High] Uninitialized pointer `codec_dai_name` is used if the required device property is missing.
--

commit ca8a45881e3592679d02b8f941222c143f73d4c0
Author: Binbin Zhou <zhoubinbin@loongson.cn>

ASoC: loongson: Add Loongson-2K0300 CTCISZ Forever Pi sound card support

The Loongson-2K0300 audio card uses a different DAI format compared to
existing Loongson platforms. Move the dai_fmt setting from the static DAI
link to runtime hw_params via snd_soc_runtime_set_dai_fmt(), and pass the
correct format through driver match data.

> diff --git a/sound/soc/loongson/loongson_card.c b/sound/soc/loongson/loongson_card.c
> index 7910d5d9ac4ff..9200e8476c1fa 100644
> --- a/sound/soc/loongson/loongson_card.c
> +++ b/sound/soc/loongson/loongson_card.c

[ ... ]

[Severity: High]
This isn't a bug introduced by this patch, but while reviewing this file I
noticed a pre-existing issue in loongson_card_parse_acpi().

Is it possible for the "codec-dai-name" device property to be missing?

In loongson_card_parse_acpi(), codec_dai_name is declared without being
initialized:

	const char *codec_dai_name;
	...
	device_property_read_string(card->dev, "codec-dai-name", &codec_dai_name);

	for (i = 0; i < card->num_links; i++) {
		loongson_dai_links[i].platforms->name = dev_name(phy_dev);
		loongson_dai_links[i].codecs->name = codec_name;
		loongson_dai_links[i].codecs->dai_name = codec_dai_name;
	}

If device_property_read_string() returns an error because the property is
missing, codec_dai_name remains uninitialized garbage. This garbage pointer
is then assigned to the global loongson_dai_links[i].codecs->dai_name,
which ASoC core will dereference during component matching.

Could this lead to a kernel panic if the firmware lacks this property? Should
the return value of device_property_read_string() be checked or a default
value be provided?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/cover.1780538113.git.zhoubinbin@loongson.cn?part=5

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

* Re: [PATCH v2 7/7] ASoC: loongson: Add headphone jack detection and DAPM routing
  2026-06-04  2:11 ` [PATCH v2 7/7] ASoC: loongson: Add headphone jack detection and DAPM routing Binbin Zhou
@ 2026-06-04  2:27   ` sashiko-bot
  2026-06-04 14:56   ` Mark Brown
  1 sibling, 0 replies; 14+ messages in thread
From: sashiko-bot @ 2026-06-04  2:27 UTC (permalink / raw)
  To: Binbin Zhou; +Cc: devicetree, conor+dt, robh

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [High] The headphone mute GPIO is incorrectly asserted when the headphone widget powers on, muting the audio.
- [High] Double-free / reference count underflow of the headphone detection GPIO descriptor on device unbind or probe failure.
- [Medium] The sound card probe fails completely if the optional headphone detection GPIO is omitted from the device tree.
--

commit 5cf0c58f5dc0c2adba751fce8cc39fa382767c93
Author: Binbin Zhou <zhoubinbin@loongson.cn>
Subject: ASoC: loongson: Add headphone jack detection and DAPM routing

This commit adds headphone jack detection and DAPM routing to the Loongson
audio machine driver. It enables proper switching between headphones and
speakers on the Loongson-2K0300 ATK-DL2K0300B board.

> diff --git a/sound/soc/loongson/loongson_card.c b/sound/soc/loongson/loongson_card.c
> index 9200e8476c1fa..ee0cf305187a7 100644
> --- a/sound/soc/loongson/loongson_card.c
> +++ b/sound/soc/loongson/loongson_card.c

[ ... ]

> +/* DAPM widget event: control headphone mute GPIO */
> +static int headphone_widget_event(struct snd_soc_dapm_widget *w,
> +				  struct snd_kcontrol *kcontrol, int event)
> +{
> +	struct snd_soc_card *card = snd_soc_dapm_to_card(w->dapm);
> +	struct loongson_card_data *priv = snd_soc_card_get_drvdata(card);
> +
> +	gpiod_set_value_cansleep(priv->gpiod_hp_mute, SND_SOC_DAPM_EVENT_ON(event));

[Severity: High]
Does this logic assert the mute signal exactly when the headphones should be
active? 

The hp-mute GPIO is initialized with GPIOD_OUT_LOW (unmuted) during probe.
When the widget powers on, SND_SOC_DAPM_EVENT_ON evaluates to 1, asserting
the mute and resulting in no sound. When it powers off, it evaluates to 0,
unmuting.

Should this logic be inverted so the headphones remain muted while powered
off and unmuted when active?

> +
> +	return 0;
> +}

[ ... ]

> +static int loongson_asoc_machine_init(struct snd_soc_pcm_runtime *rtd)
> +{
> +	struct snd_soc_card *card = rtd->card;
> +	struct loongson_card_data *ls_priv = snd_soc_card_get_drvdata(card);
> +	int ret = 0;
> +
> +	if (!ls_priv->cfg->add_hp_jack)
> +		return 0;
> +
> +	ret = snd_soc_card_jack_new_pins(card, "Headphones Jack",
> +					 SND_JACK_HEADPHONE,
> +					 &loongson_asoc_hp_jack,
> +					 loongson_asoc_hp_jack_pins,
> +					 ARRAY_SIZE(loongson_asoc_hp_jack_pins));
> +	if (ret) {
> +		dev_err(rtd->dev, "Headphones Jack creation failed: %d\n", ret);
> +		return ret;
> +	}
> +
> +	loongson_asoc_hp_jack_gpio.desc = ls_priv->gpiod_hp_det;
> +
> +	ret = snd_soc_jack_add_gpios(&loongson_asoc_hp_jack, 1, &loongson_asoc_hp_jack_gpio);

[Severity: Medium]
Will this cause the sound card probe to fail completely if the optional
headphone detection GPIO is omitted from the device tree?

The loongson,hp-det GPIO is acquired using devm_gpiod_get_optional() during
loongson_asoc_card_probe(), which returns NULL if the property is absent.

If the descriptor is NULL, passing it to snd_soc_jack_add_gpios() without
setting gpiod_dev causes it to return -EINVAL. This propagates back through
the DAI link initialization, breaking the device initialization.

[Severity: High]
Will this result in a double-free of the headphone detection GPIO descriptor
on device unbind or probe failure?

The gpiod_hp_det descriptor is acquired with devm_gpiod_get_optional(), which
registers a devres action to call gpiod_put() when the device is unbound.

Passing this explicitly acquired descriptor directly to
snd_soc_jack_add_gpios() transfers ownership, as it registers its own devres
action that also unconditionally calls gpiod_put(). 

On probe failure or unbind, devres will execute both cleanup actions, causing
a reference count underflow and leading to a use-after-free of the gpio_device.

> +	if (ret)
> +		dev_err(rtd->dev, "Headphone GPIO not added: %d\n", ret);
> +
> +	return ret;
> +}

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/cover.1780538113.git.zhoubinbin@loongson.cn?part=7

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

* Re: [PATCH v2 7/7] ASoC: loongson: Add headphone jack detection and DAPM routing
  2026-06-04  2:11 ` [PATCH v2 7/7] ASoC: loongson: Add headphone jack detection and DAPM routing Binbin Zhou
  2026-06-04  2:27   ` sashiko-bot
@ 2026-06-04 14:56   ` Mark Brown
  2026-06-05  1:25     ` Binbin Zhou
  1 sibling, 1 reply; 14+ messages in thread
From: Mark Brown @ 2026-06-04 14:56 UTC (permalink / raw)
  To: Binbin Zhou
  Cc: Binbin Zhou, Huacai Chen, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Liam Girdwood, Jaroslav Kysela, Takashi Iwai,
	Huacai Chen, Xuerui Wang, loongarch, devicetree, linux-sound

[-- Attachment #1: Type: text/plain, Size: 450 bytes --]

On Thu, Jun 04, 2026 at 10:11:47AM +0800, Binbin Zhou wrote:

> +	ret = snd_soc_of_parse_audio_routing(card, "audio-routing");
> +	if (ret)
> +		dev_warn(dev, "Unable to parse routing\n");

The routing is optional in the schema but the helper will return an
error if it's missing AFAICT (the of_property_count_strings() won't find
the property).  I'm wondering if it makes more sense to have the check
for a missing property here or in the helper...

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

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

* Re: [PATCH v2 7/7] ASoC: loongson: Add headphone jack detection and DAPM routing
  2026-06-04 14:56   ` Mark Brown
@ 2026-06-05  1:25     ` Binbin Zhou
  0 siblings, 0 replies; 14+ messages in thread
From: Binbin Zhou @ 2026-06-05  1:25 UTC (permalink / raw)
  To: Mark Brown
  Cc: Binbin Zhou, Huacai Chen, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Liam Girdwood, Jaroslav Kysela, Takashi Iwai,
	Huacai Chen, Xuerui Wang, loongarch, devicetree, linux-sound

Hi Mark:

Thanks for your reply.

On Thu, Jun 4, 2026 at 10:56 PM Mark Brown <broonie@kernel.org> wrote:
>
> On Thu, Jun 04, 2026 at 10:11:47AM +0800, Binbin Zhou wrote:
>
> > +     ret = snd_soc_of_parse_audio_routing(card, "audio-routing");
> > +     if (ret)
> > +             dev_warn(dev, "Unable to parse routing\n");
>
> The routing is optional in the schema but the helper will return an
> error if it's missing AFAICT (the of_property_count_strings() won't find
> the property).  I'm wondering if it makes more sense to have the check
> for a missing property here or in the helper...

Yes, I noticed that too.

In the next version, I'll add an `add_dapm_routes` field to `struct
loongson_card_config` to indicate whether `dapm_routes` needs to be
parsed, in order to avoid unnecessary warning output.

Also, since the newly added parsing items only apply to FDT, I’ll move
them to `loongson_card_parse_of()` as well, which should make the code
clearer.

-- 
Thanks.
Binbin

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

end of thread, other threads:[~2026-06-05  1:25 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-04  2:11 [PATCH v2 0/7] ASoC: Add Loongson-2K0300 I2S controller and sound card support Binbin Zhou
2026-06-04  2:11 ` [PATCH v2 1/7] ASoC: dt-bindings: loongson,ls2k1000-i2s: Document Loongson-2K0300 compatible Binbin Zhou
2026-06-04  2:11 ` [PATCH v2 2/7] ASoC: loongson: Add Loongson-2K0300 I2S controller support Binbin Zhou
2026-06-04  2:24   ` sashiko-bot
2026-06-04  2:11 ` [PATCH v2 3/7] ASoC: dt-bindings: loongson,ls-audio-card: Use common sound card Binbin Zhou
2026-06-04  2:11 ` [PATCH v2 4/7] ASoC: dt-bindings: loongson,ls-audio-card: Add ctcisz forever pi compatible Binbin Zhou
2026-06-04  2:21   ` sashiko-bot
2026-06-04  2:11 ` [PATCH v2 5/7] ASoC: loongson: Add Loongson-2K0300 CTCISZ Forever Pi sound card support Binbin Zhou
2026-06-04  2:26   ` sashiko-bot
2026-06-04  2:11 ` [PATCH v2 6/7] ASoC: dt-bindings: loongson,ls-audio-card: Add ATK-DL2K0300B compatible Binbin Zhou
2026-06-04  2:11 ` [PATCH v2 7/7] ASoC: loongson: Add headphone jack detection and DAPM routing Binbin Zhou
2026-06-04  2:27   ` sashiko-bot
2026-06-04 14:56   ` Mark Brown
2026-06-05  1:25     ` Binbin Zhou

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.