public inbox for devicetree@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] ASoC: Add Loongson-2k0300 I2S controller support
@ 2026-03-11  6:37 Binbin Zhou
  2026-03-11  6:37 ` [PATCH 1/6] MAINTAINERS: Add entry for Loongson ASoC driver Binbin Zhou
                   ` (5 more replies)
  0 siblings, 6 replies; 16+ messages in thread
From: Binbin Zhou @ 2026-03-11  6:37 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 patchset adds support for the Loongson-2K0300 I2S controller.
Similar to the Loongson-2K2000, it utilizes internal DMA for data
transfer but interfaces as a platform device.

Also, I cleaned up the redundant code from before.

Thanks.
Binbin

Binbin Zhou (6):
  MAINTAINERS: Add entry for Loongson ASoC driver
  ASoC: loongson: Combined regmap definitions
  ASoC: loongson: Add `internal` to the names of internal DMA variables
  ASoC: loongson: Separate external shared DMA from the platform
    interface
  ASoC: dt-bindings: loongson,ls2k1000-i2s: Document Loongson-2K0300
    compatible
  ASoC: loongson: Add Loongson-2k0300 I2S controller support

 .../bindings/sound/loongson,ls2k1000-i2s.yaml |  22 ++-
 MAINTAINERS                                   |   7 +
 sound/soc/loongson/Makefile                   |   4 +-
 sound/soc/loongson/loongson_card.c            |   2 +-
 sound/soc/loongson/loongson_dma.c             | 142 ++++++++++++------
 sound/soc/loongson/loongson_dma.h             |   6 +-
 sound/soc/loongson/loongson_i2s.c             |  61 +++++++-
 sound/soc/loongson/loongson_i2s.h             |   7 +-
 sound/soc/loongson/loongson_i2s_pci.c         |  59 +-------
 sound/soc/loongson/loongson_i2s_plat.c        |  98 ++++--------
 10 files changed, 229 insertions(+), 179 deletions(-)


base-commit: e69bc9b4c9827f4af5dfecba10df35dcc67d180a
-- 
2.52.0


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

* [PATCH 1/6] MAINTAINERS: Add entry for Loongson ASoC driver
  2026-03-11  6:37 [PATCH 0/3] ASoC: Add Loongson-2k0300 I2S controller support Binbin Zhou
@ 2026-03-11  6:37 ` Binbin Zhou
  2026-03-11  6:37 ` [PATCH 2/6] ASoC: loongson: Combined regmap definitions Binbin Zhou
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 16+ messages in thread
From: Binbin Zhou @ 2026-03-11  6:37 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 myself as maintainer of Loongson ASoC driver as I will be
responsible for this driver.

Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn>
---
 MAINTAINERS | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 77fdfcb55f06..d58619de1c97 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14936,6 +14936,13 @@ F:	arch/loongarch/
 F:	drivers/*/*loongarch*
 F:	drivers/cpufreq/loongson3_cpufreq.c
 
+LOONGSON AUDIO (ASoC) DRIVERS
+M:	Binbin Zhou <zhoubinbin@loongson.cn>
+L:	linux-sound@vger.kernel.org
+S:	Maintained
+F:	sound/soc/loongson/loongson_*.c
+F:	sound/soc/loongson/loongson_*.h
+
 LOONGSON GPIO DRIVER
 M:	Yinbo Zhu <zhuyinbo@loongson.cn>
 L:	linux-gpio@vger.kernel.org
-- 
2.52.0


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

* [PATCH 2/6] ASoC: loongson: Combined regmap definitions
  2026-03-11  6:37 [PATCH 0/3] ASoC: Add Loongson-2k0300 I2S controller support Binbin Zhou
  2026-03-11  6:37 ` [PATCH 1/6] MAINTAINERS: Add entry for Loongson ASoC driver Binbin Zhou
@ 2026-03-11  6:37 ` Binbin Zhou
  2026-03-11  7:55   ` Huacai Chen
  2026-03-11  6:37 ` [PATCH 3/6] ASoC: loongson: Add `internal` to the names of internal DMA variables Binbin Zhou
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 16+ messages in thread
From: Binbin Zhou @ 2026-03-11  6:37 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

For Loongson I2S, the difference between i2s_plat and i2s_pci is more in
the external interface, the internal registers are accessed in the same
way, so the regmap definitions can be united to simplify the code.

Also, the following warning for the i2s_plat driver will be eliminated:

loongson-i2s-plat loongson-i2s: using zero-initialized flat cache, this may cause unexpected behavior.

Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn>
---
 sound/soc/loongson/loongson_i2s.c      | 55 ++++++++++++++++++++++++++
 sound/soc/loongson/loongson_i2s.h      |  1 +
 sound/soc/loongson/loongson_i2s_pci.c  | 54 -------------------------
 sound/soc/loongson/loongson_i2s_plat.c |  8 ----
 4 files changed, 56 insertions(+), 62 deletions(-)

diff --git a/sound/soc/loongson/loongson_i2s.c b/sound/soc/loongson/loongson_i2s.c
index e336656e13eb..09ccab0c535e 100644
--- a/sound/soc/loongson/loongson_i2s.c
+++ b/sound/soc/loongson/loongson_i2s.c
@@ -272,5 +272,60 @@ const struct dev_pm_ops loongson_i2s_pm = {
 };
 EXPORT_SYMBOL_GPL(loongson_i2s_pm);
 
+static bool loongson_i2s_wr_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case LS_I2S_CFG:
+	case LS_I2S_CTRL:
+	case LS_I2S_RX_DATA:
+	case LS_I2S_TX_DATA:
+	case LS_I2S_CFG1:
+		return true;
+	default:
+		return false;
+	};
+}
+
+static bool loongson_i2s_rd_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case LS_I2S_VER:
+	case LS_I2S_CFG:
+	case LS_I2S_CTRL:
+	case LS_I2S_RX_DATA:
+	case LS_I2S_TX_DATA:
+	case LS_I2S_CFG1:
+		return true;
+	default:
+		return false;
+	};
+}
+
+static bool loongson_i2s_volatile_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case LS_I2S_CFG:
+	case LS_I2S_CTRL:
+	case LS_I2S_RX_DATA:
+	case LS_I2S_TX_DATA:
+	case LS_I2S_CFG1:
+		return true;
+	default:
+		return false;
+	};
+}
+
+const struct regmap_config loongson_i2s_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 4,
+	.val_bits = 32,
+	.max_register = LS_I2S_CFG1,
+	.writeable_reg = loongson_i2s_wr_reg,
+	.readable_reg = loongson_i2s_rd_reg,
+	.volatile_reg = loongson_i2s_volatile_reg,
+	.cache_type = REGCACHE_FLAT,
+};
+EXPORT_SYMBOL_GPL(loongson_i2s_regmap_config);
+
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Common functions for loongson I2S controller driver");
diff --git a/sound/soc/loongson/loongson_i2s.h b/sound/soc/loongson/loongson_i2s.h
index c8052a762c1b..e73ffa954ec9 100644
--- a/sound/soc/loongson/loongson_i2s.h
+++ b/sound/soc/loongson/loongson_i2s.h
@@ -65,6 +65,7 @@ struct loongson_i2s {
 	u32 sysclk;
 };
 
+extern const struct regmap_config loongson_i2s_regmap_config;
 extern const struct dev_pm_ops loongson_i2s_pm;
 extern struct snd_soc_dai_driver loongson_i2s_dai;
 
diff --git a/sound/soc/loongson/loongson_i2s_pci.c b/sound/soc/loongson/loongson_i2s_pci.c
index 1ea5501a97f8..dea1e4ebee29 100644
--- a/sound/soc/loongson/loongson_i2s_pci.c
+++ b/sound/soc/loongson/loongson_i2s_pci.c
@@ -18,60 +18,6 @@
 
 #define DRIVER_NAME "loongson-i2s-pci"
 
-static bool loongson_i2s_wr_reg(struct device *dev, unsigned int reg)
-{
-	switch (reg) {
-	case LS_I2S_CFG:
-	case LS_I2S_CTRL:
-	case LS_I2S_RX_DATA:
-	case LS_I2S_TX_DATA:
-	case LS_I2S_CFG1:
-		return true;
-	default:
-		return false;
-	};
-}
-
-static bool loongson_i2s_rd_reg(struct device *dev, unsigned int reg)
-{
-	switch (reg) {
-	case LS_I2S_VER:
-	case LS_I2S_CFG:
-	case LS_I2S_CTRL:
-	case LS_I2S_RX_DATA:
-	case LS_I2S_TX_DATA:
-	case LS_I2S_CFG1:
-		return true;
-	default:
-		return false;
-	};
-}
-
-static bool loongson_i2s_volatile_reg(struct device *dev, unsigned int reg)
-{
-	switch (reg) {
-	case LS_I2S_CFG:
-	case LS_I2S_CTRL:
-	case LS_I2S_RX_DATA:
-	case LS_I2S_TX_DATA:
-	case LS_I2S_CFG1:
-		return true;
-	default:
-		return false;
-	};
-}
-
-static const struct regmap_config loongson_i2s_regmap_config = {
-	.reg_bits = 32,
-	.reg_stride = 4,
-	.val_bits = 32,
-	.max_register = LS_I2S_CFG1,
-	.writeable_reg = loongson_i2s_wr_reg,
-	.readable_reg = loongson_i2s_rd_reg,
-	.volatile_reg = loongson_i2s_volatile_reg,
-	.cache_type = REGCACHE_FLAT,
-};
-
 static int loongson_i2s_pci_probe(struct pci_dev *pdev,
 				  const struct pci_device_id *pid)
 {
diff --git a/sound/soc/loongson/loongson_i2s_plat.c b/sound/soc/loongson/loongson_i2s_plat.c
index fa2e450ff618..f8d7aca8b903 100644
--- a/sound/soc/loongson/loongson_i2s_plat.c
+++ b/sound/soc/loongson/loongson_i2s_plat.c
@@ -85,14 +85,6 @@ static const struct snd_soc_component_driver loongson_i2s_component_driver = {
 	.open	= loongson_pcm_open,
 };
 
-static const struct regmap_config loongson_i2s_regmap_config = {
-	.reg_bits = 32,
-	.reg_stride = 4,
-	.val_bits = 32,
-	.max_register = 0x14,
-	.cache_type = REGCACHE_FLAT,
-};
-
 static int loongson_i2s_apbdma_config(struct platform_device *pdev)
 {
 	int val;
-- 
2.52.0


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

* [PATCH 3/6] ASoC: loongson: Add `internal` to the names of internal DMA variables
  2026-03-11  6:37 [PATCH 0/3] ASoC: Add Loongson-2k0300 I2S controller support Binbin Zhou
  2026-03-11  6:37 ` [PATCH 1/6] MAINTAINERS: Add entry for Loongson ASoC driver Binbin Zhou
  2026-03-11  6:37 ` [PATCH 2/6] ASoC: loongson: Combined regmap definitions Binbin Zhou
@ 2026-03-11  6:37 ` Binbin Zhou
  2026-03-11  7:56   ` Huacai Chen
  2026-03-11  6:37 ` [PATCH 4/6] ASoC: loongson: Separate external shared DMA from the platform interface Binbin Zhou
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 16+ messages in thread
From: Binbin Zhou @ 2026-03-11  6:37 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 DMA controller used in Loongson I2S is divided into internal
exclusive DMA and external shared DMA (APBDMA). Add the `internal`
dentifier to internal DMA variable names to better distinguish them from
external shared DMA.

No functional change intended.

Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn>
---
 sound/soc/loongson/loongson_dma.c     | 84 +++++++++++++--------------
 sound/soc/loongson/loongson_dma.h     |  4 +-
 sound/soc/loongson/loongson_i2s.h     |  6 +-
 sound/soc/loongson/loongson_i2s_pci.c |  5 +-
 4 files changed, 49 insertions(+), 50 deletions(-)

diff --git a/sound/soc/loongson/loongson_dma.c b/sound/soc/loongson/loongson_dma.c
index f26b2951bc9c..07a084cebdc0 100644
--- a/sound/soc/loongson/loongson_dma.c
+++ b/sound/soc/loongson/loongson_dma.c
@@ -14,6 +14,7 @@
 #include <sound/soc.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
+
 #include "loongson_i2s.h"
 
 /* DMA dma_order Register */
@@ -29,7 +30,7 @@
 /*
  * DMA registers descriptor.
  */
-struct loongson_dma_desc {
+struct loongson_internal_dma_desc {
 	u32 order;		/* Next descriptor address register */
 	u32 saddr;		/* Source address register */
 	u32 daddr;		/* Device address register */
@@ -44,17 +45,17 @@ struct loongson_dma_desc {
 } __packed;
 
 struct loongson_runtime_data {
-	struct loongson_dma_data *dma_data;
+	struct loongson_internal_dma_data *dma_data;
 
-	struct loongson_dma_desc *dma_desc_arr;
+	struct loongson_internal_dma_desc *dma_desc_arr;
 	dma_addr_t dma_desc_arr_phy;
 	int dma_desc_arr_size;
 
-	struct loongson_dma_desc *dma_pos_desc;
+	struct loongson_internal_dma_desc *dma_pos_desc;
 	dma_addr_t dma_pos_desc_phy;
 };
 
-static const struct snd_pcm_hardware ls_pcm_hardware = {
+static const struct snd_pcm_hardware loongson_internal_dma_hardware = {
 	.info = SNDRV_PCM_INFO_MMAP |
 		SNDRV_PCM_INFO_INTERLEAVED |
 		SNDRV_PCM_INFO_MMAP_VALID |
@@ -67,12 +68,11 @@ static const struct snd_pcm_hardware ls_pcm_hardware = {
 	.period_bytes_min = 128,
 	.period_bytes_max = 128 * 1024,
 	.periods_min = 1,
-	.periods_max = PAGE_SIZE / sizeof(struct loongson_dma_desc),
+	.periods_max = PAGE_SIZE / sizeof(struct loongson_internal_dma_desc),
 	.buffer_bytes_max = 1024 * 1024,
 };
 
-static struct
-loongson_dma_desc *dma_desc_save(struct loongson_runtime_data *prtd)
+static struct loongson_internal_dma_desc *dma_desc_save(struct loongson_runtime_data *prtd)
 {
 	void __iomem *order_reg = prtd->dma_data->order_addr;
 	u64 val;
@@ -88,8 +88,8 @@ loongson_dma_desc *dma_desc_save(struct loongson_runtime_data *prtd)
 	return prtd->dma_pos_desc;
 }
 
-static int loongson_pcm_trigger(struct snd_soc_component *component,
-				struct snd_pcm_substream *substream, int cmd)
+static int loongson_internal_dma_pcm_trigger(struct snd_soc_component *component,
+					     struct snd_pcm_substream *substream, int cmd)
 {
 	struct loongson_runtime_data *prtd = substream->runtime->private_data;
 	struct device *dev = substream->pcm->card->dev;
@@ -131,9 +131,9 @@ static int loongson_pcm_trigger(struct snd_soc_component *component,
 	return 0;
 }
 
-static int loongson_pcm_hw_params(struct snd_soc_component *component,
-				  struct snd_pcm_substream *substream,
-				  struct snd_pcm_hw_params *params)
+static int loongson_internal_dma_pcm_hw_params(struct snd_soc_component *component,
+					       struct snd_pcm_substream *substream,
+					       struct snd_pcm_hw_params *params)
 {
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct device *dev = substream->pcm->card->dev;
@@ -141,7 +141,7 @@ static int loongson_pcm_hw_params(struct snd_soc_component *component,
 	size_t buf_len = params_buffer_bytes(params);
 	size_t period_len = params_period_bytes(params);
 	dma_addr_t order_addr, mem_addr;
-	struct loongson_dma_desc *desc;
+	struct loongson_internal_dma_desc *desc;
 	u32 num_periods;
 	int i;
 
@@ -195,12 +195,12 @@ static int loongson_pcm_hw_params(struct snd_soc_component *component,
 }
 
 static snd_pcm_uframes_t
-loongson_pcm_pointer(struct snd_soc_component *component,
-		     struct snd_pcm_substream *substream)
+loongson_internal_dma_pcm_pointer(struct snd_soc_component *component,
+				  struct snd_pcm_substream *substream)
 {
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct loongson_runtime_data *prtd = runtime->private_data;
-	struct loongson_dma_desc *desc;
+	struct loongson_internal_dma_desc *desc;
 	snd_pcm_uframes_t x;
 	u64 addr;
 
@@ -213,7 +213,7 @@ loongson_pcm_pointer(struct snd_soc_component *component,
 	return x;
 }
 
-static irqreturn_t loongson_pcm_dma_irq(int irq, void *devid)
+static irqreturn_t loongson_internal_dma_pcm_dma_irq(int irq, void *devid)
 {
 	struct snd_pcm_substream *substream = devid;
 
@@ -221,14 +221,14 @@ static irqreturn_t loongson_pcm_dma_irq(int irq, void *devid)
 	return IRQ_HANDLED;
 }
 
-static int loongson_pcm_open(struct snd_soc_component *component,
-			     struct snd_pcm_substream *substream)
+static int loongson_internal_dma_pcm_open(struct snd_soc_component *component,
+					  struct snd_pcm_substream *substream)
 {
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
 	struct snd_card *card = substream->pcm->card;
 	struct loongson_runtime_data *prtd;
-	struct loongson_dma_data *dma_data;
+	struct loongson_internal_dma_data *dma_data;
 
 	/*
 	 * For mysterious reasons (and despite what the manual says)
@@ -241,7 +241,7 @@ static int loongson_pcm_open(struct snd_soc_component *component,
 				   SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 128);
 	snd_pcm_hw_constraint_integer(substream->runtime,
 				      SNDRV_PCM_HW_PARAM_PERIODS);
-	snd_soc_set_runtime_hwparams(substream, &ls_pcm_hardware);
+	snd_soc_set_runtime_hwparams(substream, &loongson_internal_dma_hardware);
 
 	prtd = kzalloc_obj(*prtd);
 	if (!prtd)
@@ -277,8 +277,8 @@ static int loongson_pcm_open(struct snd_soc_component *component,
 	return -ENOMEM;
 }
 
-static int loongson_pcm_close(struct snd_soc_component *component,
-			      struct snd_pcm_substream *substream)
+static int loongson_internal_dma_pcm_close(struct snd_soc_component *component,
+					   struct snd_pcm_substream *substream)
 {
 	struct snd_card *card = substream->pcm->card;
 	struct loongson_runtime_data *prtd = substream->runtime->private_data;
@@ -293,21 +293,21 @@ static int loongson_pcm_close(struct snd_soc_component *component,
 	return 0;
 }
 
-static int loongson_pcm_mmap(struct snd_soc_component *component,
-			     struct snd_pcm_substream *substream,
-			     struct vm_area_struct *vma)
+static int loongson_internal_dma_pcm_mmap(struct snd_soc_component *component,
+					  struct snd_pcm_substream *substream,
+					  struct vm_area_struct *vma)
 {
 	return remap_pfn_range(vma, vma->vm_start,
-			substream->dma_buffer.addr >> PAGE_SHIFT,
-			vma->vm_end - vma->vm_start, vma->vm_page_prot);
+			       substream->dma_buffer.addr >> PAGE_SHIFT,
+			       vma->vm_end - vma->vm_start, vma->vm_page_prot);
 }
 
-static int loongson_pcm_new(struct snd_soc_component *component,
-			    struct snd_soc_pcm_runtime *rtd)
+static int loongson_internal_dma_pcm_new(struct snd_soc_component *component,
+					 struct snd_soc_pcm_runtime *rtd)
 {
 	struct snd_card *card = rtd->card->snd_card;
 	struct snd_pcm_substream *substream;
-	struct loongson_dma_data *dma_data;
+	struct loongson_internal_dma_data *dma_data;
 	unsigned int i;
 	int ret;
 
@@ -319,7 +319,7 @@ static int loongson_pcm_new(struct snd_soc_component *component,
 		dma_data = snd_soc_dai_get_dma_data(snd_soc_rtd_to_cpu(rtd, 0),
 						    substream);
 		ret = devm_request_irq(card->dev, dma_data->irq,
-				       loongson_pcm_dma_irq,
+				       loongson_internal_dma_pcm_dma_irq,
 				       IRQF_TRIGGER_HIGH, LS_I2S_DRVNAME,
 				       substream);
 		if (ret < 0) {
@@ -330,16 +330,16 @@ static int loongson_pcm_new(struct snd_soc_component *component,
 
 	return snd_pcm_set_fixed_buffer_all(rtd->pcm, SNDRV_DMA_TYPE_DEV,
 					    card->dev,
-					    ls_pcm_hardware.buffer_bytes_max);
+					    loongson_internal_dma_hardware.buffer_bytes_max);
 }
 
-const struct snd_soc_component_driver loongson_i2s_component = {
+const struct snd_soc_component_driver loongson_i2s_internal_dma_component = {
 	.name		= LS_I2S_DRVNAME,
-	.open		= loongson_pcm_open,
-	.close		= loongson_pcm_close,
-	.hw_params	= loongson_pcm_hw_params,
-	.trigger	= loongson_pcm_trigger,
-	.pointer	= loongson_pcm_pointer,
-	.mmap		= loongson_pcm_mmap,
-	.pcm_construct	= loongson_pcm_new,
+	.open		= loongson_internal_dma_pcm_open,
+	.close		= loongson_internal_dma_pcm_close,
+	.hw_params	= loongson_internal_dma_pcm_hw_params,
+	.trigger	= loongson_internal_dma_pcm_trigger,
+	.pointer	= loongson_internal_dma_pcm_pointer,
+	.mmap		= loongson_internal_dma_pcm_mmap,
+	.pcm_construct	= loongson_internal_dma_pcm_new,
 };
diff --git a/sound/soc/loongson/loongson_dma.h b/sound/soc/loongson/loongson_dma.h
index 073ee8c0c046..8795fd7874bb 100644
--- a/sound/soc/loongson/loongson_dma.h
+++ b/sound/soc/loongson/loongson_dma.h
@@ -9,8 +9,6 @@
 #ifndef _LOONGSON_DMA_H
 #define _LOONGSON_DMA_H
 
-#include <sound/soc.h>
-
-extern const struct snd_soc_component_driver loongson_i2s_component;
+extern const struct snd_soc_component_driver loongson_i2s_internal_dma_component;
 
 #endif
diff --git a/sound/soc/loongson/loongson_i2s.h b/sound/soc/loongson/loongson_i2s.h
index e73ffa954ec9..5f773bbd24c5 100644
--- a/sound/soc/loongson/loongson_i2s.h
+++ b/sound/soc/loongson/loongson_i2s.h
@@ -42,7 +42,7 @@
 
 #define LS_I2S_DRVNAME		"loongson-i2s"
 
-struct loongson_dma_data {
+struct loongson_internal_dma_data {
 	dma_addr_t dev_addr;		/* device physical address for DMA */
 	void __iomem *order_addr;	/* DMA order register */
 	int irq;			/* DMA irq */
@@ -52,11 +52,11 @@ struct loongson_i2s {
 	struct device *dev;
 	union {
 		struct snd_dmaengine_dai_dma_data playback_dma_data;
-		struct loongson_dma_data tx_dma_data;
+		struct loongson_internal_dma_data tx_dma_data;
 	};
 	union {
 		struct snd_dmaengine_dai_dma_data capture_dma_data;
-		struct loongson_dma_data rx_dma_data;
+		struct loongson_internal_dma_data rx_dma_data;
 	};
 	struct regmap *regmap;
 	void __iomem *reg_base;
diff --git a/sound/soc/loongson/loongson_i2s_pci.c b/sound/soc/loongson/loongson_i2s_pci.c
index dea1e4ebee29..9120432bbe64 100644
--- a/sound/soc/loongson/loongson_i2s_pci.c
+++ b/sound/soc/loongson/loongson_i2s_pci.c
@@ -13,6 +13,7 @@
 #include <linux/acpi.h>
 #include <linux/pci.h>
 #include <sound/soc.h>
+
 #include "loongson_i2s.h"
 #include "loongson_dma.h"
 
@@ -22,7 +23,7 @@ static int loongson_i2s_pci_probe(struct pci_dev *pdev,
 				  const struct pci_device_id *pid)
 {
 	const struct fwnode_handle *fwnode = pdev->dev.fwnode;
-	struct loongson_dma_data *tx_data, *rx_data;
+	struct loongson_internal_dma_data *tx_data, *rx_data;
 	struct device *dev = &pdev->dev;
 	struct loongson_i2s *i2s;
 	int ret;
@@ -79,7 +80,7 @@ static int loongson_i2s_pci_probe(struct pci_dev *pdev,
 		udelay(200);
 	}
 
-	ret = devm_snd_soc_register_component(dev, &loongson_i2s_component,
+	ret = devm_snd_soc_register_component(dev, &loongson_i2s_internal_dma_component,
 					      &loongson_i2s_dai, 1);
 	if (ret)
 		return dev_err_probe(dev, ret, "register DAI failed\n");
-- 
2.52.0


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

* [PATCH 4/6] ASoC: loongson: Separate external shared DMA from the platform interface
  2026-03-11  6:37 [PATCH 0/3] ASoC: Add Loongson-2k0300 I2S controller support Binbin Zhou
                   ` (2 preceding siblings ...)
  2026-03-11  6:37 ` [PATCH 3/6] ASoC: loongson: Add `internal` to the names of internal DMA variables Binbin Zhou
@ 2026-03-11  6:37 ` Binbin Zhou
  2026-03-11  6:37 ` [PATCH 5/6] ASoC: dt-bindings: loongson,ls2k1000-i2s: Document Loongson-2K0300 compatible Binbin Zhou
  2026-03-11  6:37 ` [PATCH 6/6] ASoC: loongson: Add Loongson-2k0300 I2S controller support Binbin Zhou
  5 siblings, 0 replies; 16+ messages in thread
From: Binbin Zhou @ 2026-03-11  6:37 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

External shared DMA has no binding relationship with the platform
interface. Separating external shared DMA-related definitions enhances
the clarity of the overall structural hierarchy.

Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn>
---
 sound/soc/loongson/Makefile            |  4 +-
 sound/soc/loongson/loongson_dma.c      | 58 +++++++++++++++++++++++++
 sound/soc/loongson/loongson_dma.h      |  2 +
 sound/soc/loongson/loongson_i2s_plat.c | 59 +-------------------------
 4 files changed, 64 insertions(+), 59 deletions(-)

diff --git a/sound/soc/loongson/Makefile b/sound/soc/loongson/Makefile
index 4c6d3130bcee..6e43672071fc 100644
--- a/sound/soc/loongson/Makefile
+++ b/sound/soc/loongson/Makefile
@@ -1,12 +1,12 @@
 # SPDX-License-Identifier: GPL-2.0
 #Platform Support
-snd-soc-loongson-i2s-pci-y := loongson_i2s_pci.o loongson_dma.o
+snd-soc-loongson-i2s-pci-y := loongson_i2s_pci.o
 obj-$(CONFIG_SND_SOC_LOONGSON_I2S_PCI) += snd-soc-loongson-i2s-pci.o snd-soc-loongson-i2s.o
 
 snd-soc-loongson-i2s-plat-y := loongson_i2s_plat.o
 obj-$(CONFIG_SND_SOC_LOONGSON_I2S_PLATFORM) += snd-soc-loongson-i2s-plat.o snd-soc-loongson-i2s.o
 
-snd-soc-loongson-i2s-y := loongson_i2s.o
+snd-soc-loongson-i2s-y := loongson_i2s.o loongson_dma.o
 
 obj-$(CONFIG_SND_LOONGSON1_AC97) += loongson1_ac97.o
 
diff --git a/sound/soc/loongson/loongson_dma.c b/sound/soc/loongson/loongson_dma.c
index 07a084cebdc0..07ee9afc4981 100644
--- a/sound/soc/loongson/loongson_dma.c
+++ b/sound/soc/loongson/loongson_dma.c
@@ -343,3 +343,61 @@ const struct snd_soc_component_driver loongson_i2s_internal_dma_component = {
 	.mmap		= loongson_internal_dma_pcm_mmap,
 	.pcm_construct	= loongson_internal_dma_pcm_new,
 };
+EXPORT_SYMBOL_GPL(loongson_i2s_internal_dma_component);
+
+static const struct snd_pcm_hardware loongson_external_dma_hardware = {
+	.info = SNDRV_PCM_INFO_MMAP |
+		SNDRV_PCM_INFO_INTERLEAVED |
+		SNDRV_PCM_INFO_MMAP_VALID |
+		SNDRV_PCM_INFO_RESUME |
+		SNDRV_PCM_INFO_PAUSE,
+	.formats = SNDRV_PCM_FMTBIT_S16_LE |
+		   SNDRV_PCM_FMTBIT_S20_3LE |
+		   SNDRV_PCM_FMTBIT_S24_LE,
+	.period_bytes_min = 128,
+	.period_bytes_max = 128 * 1024,
+	.periods_min = 1,
+	.periods_max = 64,
+	.buffer_bytes_max = 1024 * 1024,
+};
+
+const struct snd_dmaengine_pcm_config loongson_dmaengine_pcm_config = {
+	.pcm_hardware = &loongson_external_dma_hardware,
+	.prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
+	.prealloc_buffer_size = 128 * 1024,
+};
+EXPORT_SYMBOL_GPL(loongson_dmaengine_pcm_config);
+
+static int loongson_external_dma_pcm_open(struct snd_soc_component *component,
+					  struct snd_pcm_substream *substream)
+{
+	struct snd_pcm_runtime *runtime = substream->runtime;
+
+	if (substream->pcm->device & 1) {
+		runtime->hw.info &= ~SNDRV_PCM_INFO_INTERLEAVED;
+		runtime->hw.info |= SNDRV_PCM_INFO_NONINTERLEAVED;
+	}
+
+	if (substream->pcm->device & 2)
+		runtime->hw.info &= ~(SNDRV_PCM_INFO_MMAP |
+				      SNDRV_PCM_INFO_MMAP_VALID);
+	/*
+	 * For mysterious reasons (and despite what the manual says)
+	 * playback samples are lost if the DMA count is not a multiple
+	 * of the DMA burst size.  Let's add a rule to enforce that.
+	 */
+	snd_pcm_hw_constraint_step(runtime, 0,
+				   SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 128);
+	snd_pcm_hw_constraint_step(runtime, 0,
+				   SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 128);
+	snd_pcm_hw_constraint_integer(substream->runtime,
+				      SNDRV_PCM_HW_PARAM_PERIODS);
+
+	return 0;
+}
+
+const struct snd_soc_component_driver loongson_i2s_external_dma_component = {
+	.name   = LS_I2S_DRVNAME,
+	.open	= loongson_external_dma_pcm_open,
+};
+EXPORT_SYMBOL_GPL(loongson_i2s_external_dma_component);
diff --git a/sound/soc/loongson/loongson_dma.h b/sound/soc/loongson/loongson_dma.h
index 8795fd7874bb..989832385220 100644
--- a/sound/soc/loongson/loongson_dma.h
+++ b/sound/soc/loongson/loongson_dma.h
@@ -10,5 +10,7 @@
 #define _LOONGSON_DMA_H
 
 extern const struct snd_soc_component_driver loongson_i2s_internal_dma_component;
+extern const struct snd_soc_component_driver loongson_i2s_external_dma_component;
+extern const struct snd_dmaengine_pcm_config loongson_dmaengine_pcm_config;
 
 #endif
diff --git a/sound/soc/loongson/loongson_i2s_plat.c b/sound/soc/loongson/loongson_i2s_plat.c
index f8d7aca8b903..eaaab2b05633 100644
--- a/sound/soc/loongson/loongson_i2s_plat.c
+++ b/sound/soc/loongson/loongson_i2s_plat.c
@@ -19,6 +19,7 @@
 #include <sound/soc.h>
 
 #include "loongson_i2s.h"
+#include "loongson_dma.h"
 
 #define LOONGSON_I2S_RX_DMA_OFFSET	21
 #define LOONGSON_I2S_TX_DMA_OFFSET	18
@@ -29,62 +30,6 @@
 #define LOONGSON_DMA3_CONF	0x3
 #define LOONGSON_DMA4_CONF	0x4
 
-/* periods_max = PAGE_SIZE / sizeof(struct ls_dma_chan_reg) */
-static const struct snd_pcm_hardware loongson_pcm_hardware = {
-	.info = SNDRV_PCM_INFO_MMAP |
-		SNDRV_PCM_INFO_INTERLEAVED |
-		SNDRV_PCM_INFO_MMAP_VALID |
-		SNDRV_PCM_INFO_RESUME |
-		SNDRV_PCM_INFO_PAUSE,
-	.formats = SNDRV_PCM_FMTBIT_S16_LE |
-		   SNDRV_PCM_FMTBIT_S20_3LE |
-		   SNDRV_PCM_FMTBIT_S24_LE,
-	.period_bytes_min = 128,
-	.period_bytes_max = 128 * 1024,
-	.periods_min = 1,
-	.periods_max = 64,
-	.buffer_bytes_max = 1024 * 1024,
-};
-
-static const struct snd_dmaengine_pcm_config loongson_dmaengine_pcm_config = {
-	.pcm_hardware = &loongson_pcm_hardware,
-	.prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
-	.prealloc_buffer_size = 128 * 1024,
-};
-
-static int loongson_pcm_open(struct snd_soc_component *component,
-			     struct snd_pcm_substream *substream)
-{
-	struct snd_pcm_runtime *runtime = substream->runtime;
-
-	if (substream->pcm->device & 1) {
-		runtime->hw.info &= ~SNDRV_PCM_INFO_INTERLEAVED;
-		runtime->hw.info |= SNDRV_PCM_INFO_NONINTERLEAVED;
-	}
-
-	if (substream->pcm->device & 2)
-		runtime->hw.info &= ~(SNDRV_PCM_INFO_MMAP |
-				      SNDRV_PCM_INFO_MMAP_VALID);
-	/*
-	 * For mysterious reasons (and despite what the manual says)
-	 * playback samples are lost if the DMA count is not a multiple
-	 * of the DMA burst size.  Let's add a rule to enforce that.
-	 */
-	snd_pcm_hw_constraint_step(runtime, 0,
-				   SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 128);
-	snd_pcm_hw_constraint_step(runtime, 0,
-				   SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 128);
-	snd_pcm_hw_constraint_integer(substream->runtime,
-				      SNDRV_PCM_HW_PARAM_PERIODS);
-
-	return 0;
-}
-
-static const struct snd_soc_component_driver loongson_i2s_component_driver = {
-	.name   = LS_I2S_DRVNAME,
-	.open	= loongson_pcm_open,
-};
-
 static int loongson_i2s_apbdma_config(struct platform_device *pdev)
 {
 	int val;
@@ -147,7 +92,7 @@ static int loongson_i2s_plat_probe(struct platform_device *pdev)
 	dev_set_name(dev, LS_I2S_DRVNAME);
 	dev_set_drvdata(dev, i2s);
 
-	ret = devm_snd_soc_register_component(dev, &loongson_i2s_component_driver,
+	ret = devm_snd_soc_register_component(dev, &loongson_i2s_external_dma_component,
 					      &loongson_i2s_dai, 1);
 	if (ret)
 		return dev_err_probe(dev, ret, "failed to register DAI\n");
-- 
2.52.0


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

* [PATCH 5/6] ASoC: dt-bindings: loongson,ls2k1000-i2s: Document Loongson-2K0300 compatible
  2026-03-11  6:37 [PATCH 0/3] ASoC: Add Loongson-2k0300 I2S controller support Binbin Zhou
                   ` (3 preceding siblings ...)
  2026-03-11  6:37 ` [PATCH 4/6] ASoC: loongson: Separate external shared DMA from the platform interface Binbin Zhou
@ 2026-03-11  6:37 ` Binbin Zhou
  2026-03-11  7:57   ` Huacai Chen
  2026-03-13 13:18   ` Krzysztof Kozlowski
  2026-03-11  6:37 ` [PATCH 6/6] ASoC: loongson: Add Loongson-2k0300 I2S controller support Binbin Zhou
  5 siblings, 2 replies; 16+ messages in thread
From: Binbin Zhou @ 2026-03-11  6:37 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 "loongson,ls2k0300-i2s" dedicated compatible to represent the I2S
interface of the Loongson-2K0300 chip.

The hardware integration of the Loongson-2K0300 I2S interface differs
significantly from that of the Loongson-2K1000. Specifically, while both
utilize external DMA controllers, the Loongson-2K0300 configures DMA
channel routing via the `dmas` property, whereas the Loongson-2K1000
requires additional register.

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] 16+ messages in thread

* [PATCH 6/6] ASoC: loongson: Add Loongson-2k0300 I2S controller support
  2026-03-11  6:37 [PATCH 0/3] ASoC: Add Loongson-2k0300 I2S controller support Binbin Zhou
                   ` (4 preceding siblings ...)
  2026-03-11  6:37 ` [PATCH 5/6] ASoC: dt-bindings: loongson,ls2k1000-i2s: Document Loongson-2K0300 compatible Binbin Zhou
@ 2026-03-11  6:37 ` Binbin Zhou
  2026-03-11 16:15   ` Mark Brown
  5 siblings, 1 reply; 16+ messages in thread
From: Binbin Zhou @ 2026-03-11  6:37 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 a hardware design flaw, PCM_START requires an explicit reset.
It has been tested and does not affect other machines.

Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn>
---
 sound/soc/loongson/loongson_card.c     |  2 +-
 sound/soc/loongson/loongson_i2s.c      |  6 +++--
 sound/soc/loongson/loongson_i2s_plat.c | 35 +++++++++++++++++++++-----
 3 files changed, 34 insertions(+), 9 deletions(-)

diff --git a/sound/soc/loongson/loongson_card.c b/sound/soc/loongson/loongson_card.c
index 7910d5d9ac4f..0d891b716e19 100644
--- a/sound/soc/loongson/loongson_card.c
+++ b/sound/soc/loongson/loongson_card.c
@@ -61,7 +61,7 @@ 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
+		.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
 			| SND_SOC_DAIFMT_CBC_CFC,
 		SND_SOC_DAILINK_REG(analog),
 		.ops = &loongson_ops,
diff --git a/sound/soc/loongson/loongson_i2s.c b/sound/soc/loongson/loongson_i2s.c
index 09ccab0c535e..4393410a1c98 100644
--- a/sound/soc/loongson/loongson_i2s.c
+++ b/sound/soc/loongson/loongson_i2s.c
@@ -32,14 +32,16 @@ static int loongson_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
 				struct snd_soc_dai *dai)
 {
 	struct loongson_i2s *i2s = snd_soc_dai_get_drvdata(dai);
-	unsigned int mask;
+	unsigned int mask = 0;
 	int ret = 0;
 
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
+		mask = I2S_CTRL_RESET;
+		fallthrough;
 	case SNDRV_PCM_TRIGGER_RESUME:
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
-		mask = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
+		mask |= (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
 		       LOONGSON_I2S_TX_ENABLE : LOONGSON_I2S_RX_ENABLE;
 		regmap_update_bits(i2s->regmap, LS_I2S_CTRL, mask, mask);
 		break;
diff --git a/sound/soc/loongson/loongson_i2s_plat.c b/sound/soc/loongson/loongson_i2s_plat.c
index eaaab2b05633..15ccaca4b969 100644
--- a/sound/soc/loongson/loongson_i2s_plat.c
+++ b/sound/soc/loongson/loongson_i2s_plat.c
@@ -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;
+
+	if (plat_config->i2s_dma_config) {
+		ret = plat_config->i2s_dma_config(pdev);
+		if (ret)
+			return ret;
+	}
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	i2s->reg_base = devm_ioremap_resource(&pdev->dev, res);
+	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,6 +108,7 @@ 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);
@@ -102,7 +124,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] 16+ messages in thread

* Re: [PATCH 2/6] ASoC: loongson: Combined regmap definitions
  2026-03-11  6:37 ` [PATCH 2/6] ASoC: loongson: Combined regmap definitions Binbin Zhou
@ 2026-03-11  7:55   ` Huacai Chen
  2026-03-11  8:17     ` Binbin Zhou
  0 siblings, 1 reply; 16+ messages in thread
From: Huacai Chen @ 2026-03-11  7:55 UTC (permalink / raw)
  To: Binbin Zhou
  Cc: Binbin Zhou, Huacai Chen, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Liam Girdwood, Mark Brown, Jaroslav Kysela,
	Takashi Iwai, Xuerui Wang, loongarch, devicetree, linux-sound

Hi, Binbin,

On Wed, Mar 11, 2026 at 2:37 PM Binbin Zhou <zhoubinbin@loongson.cn> wrote:
>
> For Loongson I2S, the difference between i2s_plat and i2s_pci is more in
> the external interface, the internal registers are accessed in the same
> way, so the regmap definitions can be united to simplify the code.
>
> Also, the following warning for the i2s_plat driver will be eliminated:
>
> loongson-i2s-plat loongson-i2s: using zero-initialized flat cache, this may cause unexpected behavior.
>
> Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn>
> ---
>  sound/soc/loongson/loongson_i2s.c      | 55 ++++++++++++++++++++++++++
>  sound/soc/loongson/loongson_i2s.h      |  1 +
>  sound/soc/loongson/loongson_i2s_pci.c  | 54 -------------------------
>  sound/soc/loongson/loongson_i2s_plat.c |  8 ----
>  4 files changed, 56 insertions(+), 62 deletions(-)
>
> diff --git a/sound/soc/loongson/loongson_i2s.c b/sound/soc/loongson/loongson_i2s.c
> index e336656e13eb..09ccab0c535e 100644
> --- a/sound/soc/loongson/loongson_i2s.c
> +++ b/sound/soc/loongson/loongson_i2s.c
> @@ -272,5 +272,60 @@ const struct dev_pm_ops loongson_i2s_pm = {
>  };
>  EXPORT_SYMBOL_GPL(loongson_i2s_pm);
>
> +static bool loongson_i2s_wr_reg(struct device *dev, unsigned int reg)
> +{
> +       switch (reg) {
> +       case LS_I2S_CFG:
> +       case LS_I2S_CTRL:
> +       case LS_I2S_RX_DATA:
> +       case LS_I2S_TX_DATA:
> +       case LS_I2S_CFG1:
> +               return true;
> +       default:
> +               return false;
> +       };
> +}
The 'write' function is usually after the 'read' function.

> +
> +static bool loongson_i2s_rd_reg(struct device *dev, unsigned int reg)
> +{
> +       switch (reg) {
> +       case LS_I2S_VER:
> +       case LS_I2S_CFG:
> +       case LS_I2S_CTRL:
> +       case LS_I2S_RX_DATA:
> +       case LS_I2S_TX_DATA:
> +       case LS_I2S_CFG1:
> +               return true;
> +       default:
> +               return false;
> +       };
> +}
> +
> +static bool loongson_i2s_volatile_reg(struct device *dev, unsigned int reg)
> +{
> +       switch (reg) {
> +       case LS_I2S_CFG:
> +       case LS_I2S_CTRL:
> +       case LS_I2S_RX_DATA:
> +       case LS_I2S_TX_DATA:
> +       case LS_I2S_CFG1:
> +               return true;
> +       default:
> +               return false;
> +       };
> +}
> +
> +const struct regmap_config loongson_i2s_regmap_config = {
> +       .reg_bits = 32,
> +       .reg_stride = 4,
> +       .val_bits = 32,
> +       .max_register = LS_I2S_CFG1,
> +       .writeable_reg = loongson_i2s_wr_reg,
> +       .readable_reg = loongson_i2s_rd_reg,
> +       .volatile_reg = loongson_i2s_volatile_reg,
> +       .cache_type = REGCACHE_FLAT,
> +};
> +EXPORT_SYMBOL_GPL(loongson_i2s_regmap_config);
> +
>  MODULE_LICENSE("GPL");
>  MODULE_DESCRIPTION("Common functions for loongson I2S controller driver");
> diff --git a/sound/soc/loongson/loongson_i2s.h b/sound/soc/loongson/loongson_i2s.h
> index c8052a762c1b..e73ffa954ec9 100644
> --- a/sound/soc/loongson/loongson_i2s.h
> +++ b/sound/soc/loongson/loongson_i2s.h
> @@ -65,6 +65,7 @@ struct loongson_i2s {
>         u32 sysclk;
>  };
>
> +extern const struct regmap_config loongson_i2s_regmap_config;
>  extern const struct dev_pm_ops loongson_i2s_pm;
>  extern struct snd_soc_dai_driver loongson_i2s_dai;
>
> diff --git a/sound/soc/loongson/loongson_i2s_pci.c b/sound/soc/loongson/loongson_i2s_pci.c
> index 1ea5501a97f8..dea1e4ebee29 100644
> --- a/sound/soc/loongson/loongson_i2s_pci.c
> +++ b/sound/soc/loongson/loongson_i2s_pci.c
> @@ -18,60 +18,6 @@
>
>  #define DRIVER_NAME "loongson-i2s-pci"
>
> -static bool loongson_i2s_wr_reg(struct device *dev, unsigned int reg)
> -{
> -       switch (reg) {
> -       case LS_I2S_CFG:
> -       case LS_I2S_CTRL:
> -       case LS_I2S_RX_DATA:
> -       case LS_I2S_TX_DATA:
> -       case LS_I2S_CFG1:
> -               return true;
> -       default:
> -               return false;
> -       };
> -}
> -
> -static bool loongson_i2s_rd_reg(struct device *dev, unsigned int reg)
> -{
> -       switch (reg) {
> -       case LS_I2S_VER:
> -       case LS_I2S_CFG:
> -       case LS_I2S_CTRL:
> -       case LS_I2S_RX_DATA:
> -       case LS_I2S_TX_DATA:
> -       case LS_I2S_CFG1:
> -               return true;
> -       default:
> -               return false;
> -       };
> -}
> -
> -static bool loongson_i2s_volatile_reg(struct device *dev, unsigned int reg)
> -{
> -       switch (reg) {
> -       case LS_I2S_CFG:
> -       case LS_I2S_CTRL:
> -       case LS_I2S_RX_DATA:
> -       case LS_I2S_TX_DATA:
> -       case LS_I2S_CFG1:
> -               return true;
> -       default:
> -               return false;
> -       };
> -}
> -
> -static const struct regmap_config loongson_i2s_regmap_config = {
> -       .reg_bits = 32,
> -       .reg_stride = 4,
> -       .val_bits = 32,
> -       .max_register = LS_I2S_CFG1,
> -       .writeable_reg = loongson_i2s_wr_reg,
The same.

Huacai

> -       .readable_reg = loongson_i2s_rd_reg,
> -       .volatile_reg = loongson_i2s_volatile_reg,
> -       .cache_type = REGCACHE_FLAT,
> -};
> -
>  static int loongson_i2s_pci_probe(struct pci_dev *pdev,
>                                   const struct pci_device_id *pid)
>  {
> diff --git a/sound/soc/loongson/loongson_i2s_plat.c b/sound/soc/loongson/loongson_i2s_plat.c
> index fa2e450ff618..f8d7aca8b903 100644
> --- a/sound/soc/loongson/loongson_i2s_plat.c
> +++ b/sound/soc/loongson/loongson_i2s_plat.c
> @@ -85,14 +85,6 @@ static const struct snd_soc_component_driver loongson_i2s_component_driver = {
>         .open   = loongson_pcm_open,
>  };
>
> -static const struct regmap_config loongson_i2s_regmap_config = {
> -       .reg_bits = 32,
> -       .reg_stride = 4,
> -       .val_bits = 32,
> -       .max_register = 0x14,
> -       .cache_type = REGCACHE_FLAT,
> -};
> -
>  static int loongson_i2s_apbdma_config(struct platform_device *pdev)
>  {
>         int val;
> --
> 2.52.0
>
>

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

* Re: [PATCH 3/6] ASoC: loongson: Add `internal` to the names of internal DMA variables
  2026-03-11  6:37 ` [PATCH 3/6] ASoC: loongson: Add `internal` to the names of internal DMA variables Binbin Zhou
@ 2026-03-11  7:56   ` Huacai Chen
  2026-03-11  8:24     ` Binbin Zhou
  0 siblings, 1 reply; 16+ messages in thread
From: Huacai Chen @ 2026-03-11  7:56 UTC (permalink / raw)
  To: Binbin Zhou
  Cc: Binbin Zhou, Huacai Chen, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Liam Girdwood, Mark Brown, Jaroslav Kysela,
	Takashi Iwai, Xuerui Wang, loongarch, devicetree, linux-sound

Hi, Binbin,

On Wed, Mar 11, 2026 at 2:37 PM Binbin Zhou <zhoubinbin@loongson.cn> wrote:
>
> The DMA controller used in Loongson I2S is divided into internal
> exclusive DMA and external shared DMA (APBDMA). Add the `internal`
> dentifier to internal DMA variable names to better distinguish them from
> external shared DMA.
>
> No functional change intended.
>
> Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn>
> ---
>  sound/soc/loongson/loongson_dma.c     | 84 +++++++++++++--------------
>  sound/soc/loongson/loongson_dma.h     |  4 +-
>  sound/soc/loongson/loongson_i2s.h     |  6 +-
>  sound/soc/loongson/loongson_i2s_pci.c |  5 +-
>  4 files changed, 49 insertions(+), 50 deletions(-)
>
> diff --git a/sound/soc/loongson/loongson_dma.c b/sound/soc/loongson/loongson_dma.c
> index f26b2951bc9c..07a084cebdc0 100644
> --- a/sound/soc/loongson/loongson_dma.c
> +++ b/sound/soc/loongson/loongson_dma.c
> @@ -14,6 +14,7 @@
>  #include <sound/soc.h>
>  #include <sound/pcm.h>
>  #include <sound/pcm_params.h>
> +
>  #include "loongson_i2s.h"
>
>  /* DMA dma_order Register */
> @@ -29,7 +30,7 @@
>  /*
>   * DMA registers descriptor.
>   */
> -struct loongson_dma_desc {
> +struct loongson_internal_dma_desc {
Can we use idma (internal dma) and edma (external) for short?

Huacai

>         u32 order;              /* Next descriptor address register */
>         u32 saddr;              /* Source address register */
>         u32 daddr;              /* Device address register */
> @@ -44,17 +45,17 @@ struct loongson_dma_desc {
>  } __packed;
>
>  struct loongson_runtime_data {
> -       struct loongson_dma_data *dma_data;
> +       struct loongson_internal_dma_data *dma_data;
>
> -       struct loongson_dma_desc *dma_desc_arr;
> +       struct loongson_internal_dma_desc *dma_desc_arr;
>         dma_addr_t dma_desc_arr_phy;
>         int dma_desc_arr_size;
>
> -       struct loongson_dma_desc *dma_pos_desc;
> +       struct loongson_internal_dma_desc *dma_pos_desc;
>         dma_addr_t dma_pos_desc_phy;
>  };
>
> -static const struct snd_pcm_hardware ls_pcm_hardware = {
> +static const struct snd_pcm_hardware loongson_internal_dma_hardware = {
>         .info = SNDRV_PCM_INFO_MMAP |
>                 SNDRV_PCM_INFO_INTERLEAVED |
>                 SNDRV_PCM_INFO_MMAP_VALID |
> @@ -67,12 +68,11 @@ static const struct snd_pcm_hardware ls_pcm_hardware = {
>         .period_bytes_min = 128,
>         .period_bytes_max = 128 * 1024,
>         .periods_min = 1,
> -       .periods_max = PAGE_SIZE / sizeof(struct loongson_dma_desc),
> +       .periods_max = PAGE_SIZE / sizeof(struct loongson_internal_dma_desc),
>         .buffer_bytes_max = 1024 * 1024,
>  };
>
> -static struct
> -loongson_dma_desc *dma_desc_save(struct loongson_runtime_data *prtd)
> +static struct loongson_internal_dma_desc *dma_desc_save(struct loongson_runtime_data *prtd)
>  {
>         void __iomem *order_reg = prtd->dma_data->order_addr;
>         u64 val;
> @@ -88,8 +88,8 @@ loongson_dma_desc *dma_desc_save(struct loongson_runtime_data *prtd)
>         return prtd->dma_pos_desc;
>  }
>
> -static int loongson_pcm_trigger(struct snd_soc_component *component,
> -                               struct snd_pcm_substream *substream, int cmd)
> +static int loongson_internal_dma_pcm_trigger(struct snd_soc_component *component,
> +                                            struct snd_pcm_substream *substream, int cmd)
>  {
>         struct loongson_runtime_data *prtd = substream->runtime->private_data;
>         struct device *dev = substream->pcm->card->dev;
> @@ -131,9 +131,9 @@ static int loongson_pcm_trigger(struct snd_soc_component *component,
>         return 0;
>  }
>
> -static int loongson_pcm_hw_params(struct snd_soc_component *component,
> -                                 struct snd_pcm_substream *substream,
> -                                 struct snd_pcm_hw_params *params)
> +static int loongson_internal_dma_pcm_hw_params(struct snd_soc_component *component,
> +                                              struct snd_pcm_substream *substream,
> +                                              struct snd_pcm_hw_params *params)
>  {
>         struct snd_pcm_runtime *runtime = substream->runtime;
>         struct device *dev = substream->pcm->card->dev;
> @@ -141,7 +141,7 @@ static int loongson_pcm_hw_params(struct snd_soc_component *component,
>         size_t buf_len = params_buffer_bytes(params);
>         size_t period_len = params_period_bytes(params);
>         dma_addr_t order_addr, mem_addr;
> -       struct loongson_dma_desc *desc;
> +       struct loongson_internal_dma_desc *desc;
>         u32 num_periods;
>         int i;
>
> @@ -195,12 +195,12 @@ static int loongson_pcm_hw_params(struct snd_soc_component *component,
>  }
>
>  static snd_pcm_uframes_t
> -loongson_pcm_pointer(struct snd_soc_component *component,
> -                    struct snd_pcm_substream *substream)
> +loongson_internal_dma_pcm_pointer(struct snd_soc_component *component,
> +                                 struct snd_pcm_substream *substream)
>  {
>         struct snd_pcm_runtime *runtime = substream->runtime;
>         struct loongson_runtime_data *prtd = runtime->private_data;
> -       struct loongson_dma_desc *desc;
> +       struct loongson_internal_dma_desc *desc;
>         snd_pcm_uframes_t x;
>         u64 addr;
>
> @@ -213,7 +213,7 @@ loongson_pcm_pointer(struct snd_soc_component *component,
>         return x;
>  }
>
> -static irqreturn_t loongson_pcm_dma_irq(int irq, void *devid)
> +static irqreturn_t loongson_internal_dma_pcm_dma_irq(int irq, void *devid)
>  {
>         struct snd_pcm_substream *substream = devid;
>
> @@ -221,14 +221,14 @@ static irqreturn_t loongson_pcm_dma_irq(int irq, void *devid)
>         return IRQ_HANDLED;
>  }
>
> -static int loongson_pcm_open(struct snd_soc_component *component,
> -                            struct snd_pcm_substream *substream)
> +static int loongson_internal_dma_pcm_open(struct snd_soc_component *component,
> +                                         struct snd_pcm_substream *substream)
>  {
>         struct snd_pcm_runtime *runtime = substream->runtime;
>         struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
>         struct snd_card *card = substream->pcm->card;
>         struct loongson_runtime_data *prtd;
> -       struct loongson_dma_data *dma_data;
> +       struct loongson_internal_dma_data *dma_data;
>
>         /*
>          * For mysterious reasons (and despite what the manual says)
> @@ -241,7 +241,7 @@ static int loongson_pcm_open(struct snd_soc_component *component,
>                                    SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 128);
>         snd_pcm_hw_constraint_integer(substream->runtime,
>                                       SNDRV_PCM_HW_PARAM_PERIODS);
> -       snd_soc_set_runtime_hwparams(substream, &ls_pcm_hardware);
> +       snd_soc_set_runtime_hwparams(substream, &loongson_internal_dma_hardware);
>
>         prtd = kzalloc_obj(*prtd);
>         if (!prtd)
> @@ -277,8 +277,8 @@ static int loongson_pcm_open(struct snd_soc_component *component,
>         return -ENOMEM;
>  }
>
> -static int loongson_pcm_close(struct snd_soc_component *component,
> -                             struct snd_pcm_substream *substream)
> +static int loongson_internal_dma_pcm_close(struct snd_soc_component *component,
> +                                          struct snd_pcm_substream *substream)
>  {
>         struct snd_card *card = substream->pcm->card;
>         struct loongson_runtime_data *prtd = substream->runtime->private_data;
> @@ -293,21 +293,21 @@ static int loongson_pcm_close(struct snd_soc_component *component,
>         return 0;
>  }
>
> -static int loongson_pcm_mmap(struct snd_soc_component *component,
> -                            struct snd_pcm_substream *substream,
> -                            struct vm_area_struct *vma)
> +static int loongson_internal_dma_pcm_mmap(struct snd_soc_component *component,
> +                                         struct snd_pcm_substream *substream,
> +                                         struct vm_area_struct *vma)
>  {
>         return remap_pfn_range(vma, vma->vm_start,
> -                       substream->dma_buffer.addr >> PAGE_SHIFT,
> -                       vma->vm_end - vma->vm_start, vma->vm_page_prot);
> +                              substream->dma_buffer.addr >> PAGE_SHIFT,
> +                              vma->vm_end - vma->vm_start, vma->vm_page_prot);
>  }
>
> -static int loongson_pcm_new(struct snd_soc_component *component,
> -                           struct snd_soc_pcm_runtime *rtd)
> +static int loongson_internal_dma_pcm_new(struct snd_soc_component *component,
> +                                        struct snd_soc_pcm_runtime *rtd)
>  {
>         struct snd_card *card = rtd->card->snd_card;
>         struct snd_pcm_substream *substream;
> -       struct loongson_dma_data *dma_data;
> +       struct loongson_internal_dma_data *dma_data;
>         unsigned int i;
>         int ret;
>
> @@ -319,7 +319,7 @@ static int loongson_pcm_new(struct snd_soc_component *component,
>                 dma_data = snd_soc_dai_get_dma_data(snd_soc_rtd_to_cpu(rtd, 0),
>                                                     substream);
>                 ret = devm_request_irq(card->dev, dma_data->irq,
> -                                      loongson_pcm_dma_irq,
> +                                      loongson_internal_dma_pcm_dma_irq,
>                                        IRQF_TRIGGER_HIGH, LS_I2S_DRVNAME,
>                                        substream);
>                 if (ret < 0) {
> @@ -330,16 +330,16 @@ static int loongson_pcm_new(struct snd_soc_component *component,
>
>         return snd_pcm_set_fixed_buffer_all(rtd->pcm, SNDRV_DMA_TYPE_DEV,
>                                             card->dev,
> -                                           ls_pcm_hardware.buffer_bytes_max);
> +                                           loongson_internal_dma_hardware.buffer_bytes_max);
>  }
>
> -const struct snd_soc_component_driver loongson_i2s_component = {
> +const struct snd_soc_component_driver loongson_i2s_internal_dma_component = {
>         .name           = LS_I2S_DRVNAME,
> -       .open           = loongson_pcm_open,
> -       .close          = loongson_pcm_close,
> -       .hw_params      = loongson_pcm_hw_params,
> -       .trigger        = loongson_pcm_trigger,
> -       .pointer        = loongson_pcm_pointer,
> -       .mmap           = loongson_pcm_mmap,
> -       .pcm_construct  = loongson_pcm_new,
> +       .open           = loongson_internal_dma_pcm_open,
> +       .close          = loongson_internal_dma_pcm_close,
> +       .hw_params      = loongson_internal_dma_pcm_hw_params,
> +       .trigger        = loongson_internal_dma_pcm_trigger,
> +       .pointer        = loongson_internal_dma_pcm_pointer,
> +       .mmap           = loongson_internal_dma_pcm_mmap,
> +       .pcm_construct  = loongson_internal_dma_pcm_new,
>  };
> diff --git a/sound/soc/loongson/loongson_dma.h b/sound/soc/loongson/loongson_dma.h
> index 073ee8c0c046..8795fd7874bb 100644
> --- a/sound/soc/loongson/loongson_dma.h
> +++ b/sound/soc/loongson/loongson_dma.h
> @@ -9,8 +9,6 @@
>  #ifndef _LOONGSON_DMA_H
>  #define _LOONGSON_DMA_H
>
> -#include <sound/soc.h>
> -
> -extern const struct snd_soc_component_driver loongson_i2s_component;
> +extern const struct snd_soc_component_driver loongson_i2s_internal_dma_component;
>
>  #endif
> diff --git a/sound/soc/loongson/loongson_i2s.h b/sound/soc/loongson/loongson_i2s.h
> index e73ffa954ec9..5f773bbd24c5 100644
> --- a/sound/soc/loongson/loongson_i2s.h
> +++ b/sound/soc/loongson/loongson_i2s.h
> @@ -42,7 +42,7 @@
>
>  #define LS_I2S_DRVNAME         "loongson-i2s"
>
> -struct loongson_dma_data {
> +struct loongson_internal_dma_data {
>         dma_addr_t dev_addr;            /* device physical address for DMA */
>         void __iomem *order_addr;       /* DMA order register */
>         int irq;                        /* DMA irq */
> @@ -52,11 +52,11 @@ struct loongson_i2s {
>         struct device *dev;
>         union {
>                 struct snd_dmaengine_dai_dma_data playback_dma_data;
> -               struct loongson_dma_data tx_dma_data;
> +               struct loongson_internal_dma_data tx_dma_data;
>         };
>         union {
>                 struct snd_dmaengine_dai_dma_data capture_dma_data;
> -               struct loongson_dma_data rx_dma_data;
> +               struct loongson_internal_dma_data rx_dma_data;
>         };
>         struct regmap *regmap;
>         void __iomem *reg_base;
> diff --git a/sound/soc/loongson/loongson_i2s_pci.c b/sound/soc/loongson/loongson_i2s_pci.c
> index dea1e4ebee29..9120432bbe64 100644
> --- a/sound/soc/loongson/loongson_i2s_pci.c
> +++ b/sound/soc/loongson/loongson_i2s_pci.c
> @@ -13,6 +13,7 @@
>  #include <linux/acpi.h>
>  #include <linux/pci.h>
>  #include <sound/soc.h>
> +
>  #include "loongson_i2s.h"
>  #include "loongson_dma.h"
>
> @@ -22,7 +23,7 @@ static int loongson_i2s_pci_probe(struct pci_dev *pdev,
>                                   const struct pci_device_id *pid)
>  {
>         const struct fwnode_handle *fwnode = pdev->dev.fwnode;
> -       struct loongson_dma_data *tx_data, *rx_data;
> +       struct loongson_internal_dma_data *tx_data, *rx_data;
>         struct device *dev = &pdev->dev;
>         struct loongson_i2s *i2s;
>         int ret;
> @@ -79,7 +80,7 @@ static int loongson_i2s_pci_probe(struct pci_dev *pdev,
>                 udelay(200);
>         }
>
> -       ret = devm_snd_soc_register_component(dev, &loongson_i2s_component,
> +       ret = devm_snd_soc_register_component(dev, &loongson_i2s_internal_dma_component,
>                                               &loongson_i2s_dai, 1);
>         if (ret)
>                 return dev_err_probe(dev, ret, "register DAI failed\n");
> --
> 2.52.0
>
>

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

* Re: [PATCH 5/6] ASoC: dt-bindings: loongson,ls2k1000-i2s: Document Loongson-2K0300 compatible
  2026-03-11  6:37 ` [PATCH 5/6] ASoC: dt-bindings: loongson,ls2k1000-i2s: Document Loongson-2K0300 compatible Binbin Zhou
@ 2026-03-11  7:57   ` Huacai Chen
  2026-03-11  8:29     ` Binbin Zhou
  2026-03-13 13:18   ` Krzysztof Kozlowski
  1 sibling, 1 reply; 16+ messages in thread
From: Huacai Chen @ 2026-03-11  7:57 UTC (permalink / raw)
  To: Binbin Zhou
  Cc: Binbin Zhou, Huacai Chen, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Liam Girdwood, Mark Brown, Jaroslav Kysela,
	Takashi Iwai, Xuerui Wang, loongarch, devicetree, linux-sound

Hi, Binbin,

On Wed, Mar 11, 2026 at 2:38 PM Binbin Zhou <zhoubinbin@loongson.cn> wrote:
>
> Add "loongson,ls2k0300-i2s" dedicated compatible to represent the I2S
> interface of the Loongson-2K0300 chip.
>
> The hardware integration of the Loongson-2K0300 I2S interface differs
> significantly from that of the Loongson-2K1000. Specifically, while both
> utilize external DMA controllers, the Loongson-2K0300 configures DMA
> channel routing via the `dmas` property, whereas the Loongson-2K1000
> requires additional register.
Can this patch be the second one?

Huacai

>
> 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	[flat|nested] 16+ messages in thread

* Re: [PATCH 2/6] ASoC: loongson: Combined regmap definitions
  2026-03-11  7:55   ` Huacai Chen
@ 2026-03-11  8:17     ` Binbin Zhou
  0 siblings, 0 replies; 16+ messages in thread
From: Binbin Zhou @ 2026-03-11  8:17 UTC (permalink / raw)
  To: Huacai Chen
  Cc: Binbin Zhou, Huacai Chen, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Liam Girdwood, Mark Brown, Jaroslav Kysela,
	Takashi Iwai, Xuerui Wang, loongarch, devicetree, linux-sound

On Wed, Mar 11, 2026 at 3:55 PM Huacai Chen <chenhuacai@kernel.org> wrote:
>
> Hi, Binbin,
>
> On Wed, Mar 11, 2026 at 2:37 PM Binbin Zhou <zhoubinbin@loongson.cn> wrote:
> >
> > For Loongson I2S, the difference between i2s_plat and i2s_pci is more in
> > the external interface, the internal registers are accessed in the same
> > way, so the regmap definitions can be united to simplify the code.
> >
> > Also, the following warning for the i2s_plat driver will be eliminated:
> >
> > loongson-i2s-plat loongson-i2s: using zero-initialized flat cache, this may cause unexpected behavior.
> >
> > Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn>
> > ---
> >  sound/soc/loongson/loongson_i2s.c      | 55 ++++++++++++++++++++++++++
> >  sound/soc/loongson/loongson_i2s.h      |  1 +
> >  sound/soc/loongson/loongson_i2s_pci.c  | 54 -------------------------
> >  sound/soc/loongson/loongson_i2s_plat.c |  8 ----
> >  4 files changed, 56 insertions(+), 62 deletions(-)
> >
> > diff --git a/sound/soc/loongson/loongson_i2s.c b/sound/soc/loongson/loongson_i2s.c
> > index e336656e13eb..09ccab0c535e 100644
> > --- a/sound/soc/loongson/loongson_i2s.c
> > +++ b/sound/soc/loongson/loongson_i2s.c
> > @@ -272,5 +272,60 @@ const struct dev_pm_ops loongson_i2s_pm = {
> >  };
> >  EXPORT_SYMBOL_GPL(loongson_i2s_pm);
> >
> > +static bool loongson_i2s_wr_reg(struct device *dev, unsigned int reg)
> > +{
> > +       switch (reg) {
> > +       case LS_I2S_CFG:
> > +       case LS_I2S_CTRL:
> > +       case LS_I2S_RX_DATA:
> > +       case LS_I2S_TX_DATA:
> > +       case LS_I2S_CFG1:
> > +               return true;
> > +       default:
> > +               return false;
> > +       };
> > +}
> The 'write' function is usually after the 'read' function.

Okay, it will be reordered in the next version.
>
> > +
> > +static bool loongson_i2s_rd_reg(struct device *dev, unsigned int reg)
> > +{
> > +       switch (reg) {
> > +       case LS_I2S_VER:
> > +       case LS_I2S_CFG:
> > +       case LS_I2S_CTRL:
> > +       case LS_I2S_RX_DATA:
> > +       case LS_I2S_TX_DATA:
> > +       case LS_I2S_CFG1:
> > +               return true;
> > +       default:
> > +               return false;
> > +       };
> > +}
> > +
> > +static bool loongson_i2s_volatile_reg(struct device *dev, unsigned int reg)
> > +{
> > +       switch (reg) {
> > +       case LS_I2S_CFG:
> > +       case LS_I2S_CTRL:
> > +       case LS_I2S_RX_DATA:
> > +       case LS_I2S_TX_DATA:
> > +       case LS_I2S_CFG1:
> > +               return true;
> > +       default:
> > +               return false;
> > +       };
> > +}
> > +
> > +const struct regmap_config loongson_i2s_regmap_config = {
> > +       .reg_bits = 32,
> > +       .reg_stride = 4,
> > +       .val_bits = 32,
> > +       .max_register = LS_I2S_CFG1,
> > +       .writeable_reg = loongson_i2s_wr_reg,
> > +       .readable_reg = loongson_i2s_rd_reg,
> > +       .volatile_reg = loongson_i2s_volatile_reg,
> > +       .cache_type = REGCACHE_FLAT,
> > +};
> > +EXPORT_SYMBOL_GPL(loongson_i2s_regmap_config);
> > +
> >  MODULE_LICENSE("GPL");
> >  MODULE_DESCRIPTION("Common functions for loongson I2S controller driver");
> > diff --git a/sound/soc/loongson/loongson_i2s.h b/sound/soc/loongson/loongson_i2s.h
> > index c8052a762c1b..e73ffa954ec9 100644
> > --- a/sound/soc/loongson/loongson_i2s.h
> > +++ b/sound/soc/loongson/loongson_i2s.h
> > @@ -65,6 +65,7 @@ struct loongson_i2s {
> >         u32 sysclk;
> >  };
> >
> > +extern const struct regmap_config loongson_i2s_regmap_config;
> >  extern const struct dev_pm_ops loongson_i2s_pm;
> >  extern struct snd_soc_dai_driver loongson_i2s_dai;
> >
> > diff --git a/sound/soc/loongson/loongson_i2s_pci.c b/sound/soc/loongson/loongson_i2s_pci.c
> > index 1ea5501a97f8..dea1e4ebee29 100644
> > --- a/sound/soc/loongson/loongson_i2s_pci.c
> > +++ b/sound/soc/loongson/loongson_i2s_pci.c
> > @@ -18,60 +18,6 @@
> >
> >  #define DRIVER_NAME "loongson-i2s-pci"
> >
> > -static bool loongson_i2s_wr_reg(struct device *dev, unsigned int reg)
> > -{
> > -       switch (reg) {
> > -       case LS_I2S_CFG:
> > -       case LS_I2S_CTRL:
> > -       case LS_I2S_RX_DATA:
> > -       case LS_I2S_TX_DATA:
> > -       case LS_I2S_CFG1:
> > -               return true;
> > -       default:
> > -               return false;
> > -       };
> > -}
> > -
> > -static bool loongson_i2s_rd_reg(struct device *dev, unsigned int reg)
> > -{
> > -       switch (reg) {
> > -       case LS_I2S_VER:
> > -       case LS_I2S_CFG:
> > -       case LS_I2S_CTRL:
> > -       case LS_I2S_RX_DATA:
> > -       case LS_I2S_TX_DATA:
> > -       case LS_I2S_CFG1:
> > -               return true;
> > -       default:
> > -               return false;
> > -       };
> > -}
> > -
> > -static bool loongson_i2s_volatile_reg(struct device *dev, unsigned int reg)
> > -{
> > -       switch (reg) {
> > -       case LS_I2S_CFG:
> > -       case LS_I2S_CTRL:
> > -       case LS_I2S_RX_DATA:
> > -       case LS_I2S_TX_DATA:
> > -       case LS_I2S_CFG1:
> > -               return true;
> > -       default:
> > -               return false;
> > -       };
> > -}
> > -
> > -static const struct regmap_config loongson_i2s_regmap_config = {
> > -       .reg_bits = 32,
> > -       .reg_stride = 4,
> > -       .val_bits = 32,
> > -       .max_register = LS_I2S_CFG1,
> > -       .writeable_reg = loongson_i2s_wr_reg,
> The same.
>
> Huacai
>
> > -       .readable_reg = loongson_i2s_rd_reg,
> > -       .volatile_reg = loongson_i2s_volatile_reg,
> > -       .cache_type = REGCACHE_FLAT,
> > -};
> > -
> >  static int loongson_i2s_pci_probe(struct pci_dev *pdev,
> >                                   const struct pci_device_id *pid)
> >  {
> > diff --git a/sound/soc/loongson/loongson_i2s_plat.c b/sound/soc/loongson/loongson_i2s_plat.c
> > index fa2e450ff618..f8d7aca8b903 100644
> > --- a/sound/soc/loongson/loongson_i2s_plat.c
> > +++ b/sound/soc/loongson/loongson_i2s_plat.c
> > @@ -85,14 +85,6 @@ static const struct snd_soc_component_driver loongson_i2s_component_driver = {
> >         .open   = loongson_pcm_open,
> >  };
> >
> > -static const struct regmap_config loongson_i2s_regmap_config = {
> > -       .reg_bits = 32,
> > -       .reg_stride = 4,
> > -       .val_bits = 32,
> > -       .max_register = 0x14,
> > -       .cache_type = REGCACHE_FLAT,
> > -};
> > -
> >  static int loongson_i2s_apbdma_config(struct platform_device *pdev)
> >  {
> >         int val;
> > --
> > 2.52.0
> >
> >

-- 
Thanks.
Binbin

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

* Re: [PATCH 3/6] ASoC: loongson: Add `internal` to the names of internal DMA variables
  2026-03-11  7:56   ` Huacai Chen
@ 2026-03-11  8:24     ` Binbin Zhou
  0 siblings, 0 replies; 16+ messages in thread
From: Binbin Zhou @ 2026-03-11  8:24 UTC (permalink / raw)
  To: Huacai Chen
  Cc: Binbin Zhou, Huacai Chen, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Liam Girdwood, Mark Brown, Jaroslav Kysela,
	Takashi Iwai, Xuerui Wang, loongarch, devicetree, linux-sound

On Wed, Mar 11, 2026 at 3:56 PM Huacai Chen <chenhuacai@kernel.org> wrote:
>
> Hi, Binbin,
>
> On Wed, Mar 11, 2026 at 2:37 PM Binbin Zhou <zhoubinbin@loongson.cn> wrote:
> >
> > The DMA controller used in Loongson I2S is divided into internal
> > exclusive DMA and external shared DMA (APBDMA). Add the `internal`
> > dentifier to internal DMA variable names to better distinguish them from
> > external shared DMA.
> >
> > No functional change intended.
> >
> > Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn>
> > ---
> >  sound/soc/loongson/loongson_dma.c     | 84 +++++++++++++--------------
> >  sound/soc/loongson/loongson_dma.h     |  4 +-
> >  sound/soc/loongson/loongson_i2s.h     |  6 +-
> >  sound/soc/loongson/loongson_i2s_pci.c |  5 +-
> >  4 files changed, 49 insertions(+), 50 deletions(-)
> >
> > diff --git a/sound/soc/loongson/loongson_dma.c b/sound/soc/loongson/loongson_dma.c
> > index f26b2951bc9c..07a084cebdc0 100644
> > --- a/sound/soc/loongson/loongson_dma.c
> > +++ b/sound/soc/loongson/loongson_dma.c
> > @@ -14,6 +14,7 @@
> >  #include <sound/soc.h>
> >  #include <sound/pcm.h>
> >  #include <sound/pcm_params.h>
> > +
> >  #include "loongson_i2s.h"
> >
> >  /* DMA dma_order Register */
> > @@ -29,7 +30,7 @@
> >  /*
> >   * DMA registers descriptor.
> >   */
> > -struct loongson_dma_desc {
> > +struct loongson_internal_dma_desc {
> Can we use idma (internal dma) and edma (external) for short?

Emm...
Using `idma`/`edma` seems more concise. I'll also add some comments.
>
> Huacai
>
> >         u32 order;              /* Next descriptor address register */
> >         u32 saddr;              /* Source address register */
> >         u32 daddr;              /* Device address register */
> > @@ -44,17 +45,17 @@ struct loongson_dma_desc {
> >  } __packed;
> >
> >  struct loongson_runtime_data {
> > -       struct loongson_dma_data *dma_data;
> > +       struct loongson_internal_dma_data *dma_data;
> >
> > -       struct loongson_dma_desc *dma_desc_arr;
> > +       struct loongson_internal_dma_desc *dma_desc_arr;
> >         dma_addr_t dma_desc_arr_phy;
> >         int dma_desc_arr_size;
> >
> > -       struct loongson_dma_desc *dma_pos_desc;
> > +       struct loongson_internal_dma_desc *dma_pos_desc;
> >         dma_addr_t dma_pos_desc_phy;
> >  };
> >
> > -static const struct snd_pcm_hardware ls_pcm_hardware = {
> > +static const struct snd_pcm_hardware loongson_internal_dma_hardware = {
> >         .info = SNDRV_PCM_INFO_MMAP |
> >                 SNDRV_PCM_INFO_INTERLEAVED |
> >                 SNDRV_PCM_INFO_MMAP_VALID |
> > @@ -67,12 +68,11 @@ static const struct snd_pcm_hardware ls_pcm_hardware = {
> >         .period_bytes_min = 128,
> >         .period_bytes_max = 128 * 1024,
> >         .periods_min = 1,
> > -       .periods_max = PAGE_SIZE / sizeof(struct loongson_dma_desc),
> > +       .periods_max = PAGE_SIZE / sizeof(struct loongson_internal_dma_desc),
> >         .buffer_bytes_max = 1024 * 1024,
> >  };
> >
> > -static struct
> > -loongson_dma_desc *dma_desc_save(struct loongson_runtime_data *prtd)
> > +static struct loongson_internal_dma_desc *dma_desc_save(struct loongson_runtime_data *prtd)
> >  {
> >         void __iomem *order_reg = prtd->dma_data->order_addr;
> >         u64 val;
> > @@ -88,8 +88,8 @@ loongson_dma_desc *dma_desc_save(struct loongson_runtime_data *prtd)
> >         return prtd->dma_pos_desc;
> >  }
> >
> > -static int loongson_pcm_trigger(struct snd_soc_component *component,
> > -                               struct snd_pcm_substream *substream, int cmd)
> > +static int loongson_internal_dma_pcm_trigger(struct snd_soc_component *component,
> > +                                            struct snd_pcm_substream *substream, int cmd)
> >  {
> >         struct loongson_runtime_data *prtd = substream->runtime->private_data;
> >         struct device *dev = substream->pcm->card->dev;
> > @@ -131,9 +131,9 @@ static int loongson_pcm_trigger(struct snd_soc_component *component,
> >         return 0;
> >  }
> >
> > -static int loongson_pcm_hw_params(struct snd_soc_component *component,
> > -                                 struct snd_pcm_substream *substream,
> > -                                 struct snd_pcm_hw_params *params)
> > +static int loongson_internal_dma_pcm_hw_params(struct snd_soc_component *component,
> > +                                              struct snd_pcm_substream *substream,
> > +                                              struct snd_pcm_hw_params *params)
> >  {
> >         struct snd_pcm_runtime *runtime = substream->runtime;
> >         struct device *dev = substream->pcm->card->dev;
> > @@ -141,7 +141,7 @@ static int loongson_pcm_hw_params(struct snd_soc_component *component,
> >         size_t buf_len = params_buffer_bytes(params);
> >         size_t period_len = params_period_bytes(params);
> >         dma_addr_t order_addr, mem_addr;
> > -       struct loongson_dma_desc *desc;
> > +       struct loongson_internal_dma_desc *desc;
> >         u32 num_periods;
> >         int i;
> >
> > @@ -195,12 +195,12 @@ static int loongson_pcm_hw_params(struct snd_soc_component *component,
> >  }
> >
> >  static snd_pcm_uframes_t
> > -loongson_pcm_pointer(struct snd_soc_component *component,
> > -                    struct snd_pcm_substream *substream)
> > +loongson_internal_dma_pcm_pointer(struct snd_soc_component *component,
> > +                                 struct snd_pcm_substream *substream)
> >  {
> >         struct snd_pcm_runtime *runtime = substream->runtime;
> >         struct loongson_runtime_data *prtd = runtime->private_data;
> > -       struct loongson_dma_desc *desc;
> > +       struct loongson_internal_dma_desc *desc;
> >         snd_pcm_uframes_t x;
> >         u64 addr;
> >
> > @@ -213,7 +213,7 @@ loongson_pcm_pointer(struct snd_soc_component *component,
> >         return x;
> >  }
> >
> > -static irqreturn_t loongson_pcm_dma_irq(int irq, void *devid)
> > +static irqreturn_t loongson_internal_dma_pcm_dma_irq(int irq, void *devid)
> >  {
> >         struct snd_pcm_substream *substream = devid;
> >
> > @@ -221,14 +221,14 @@ static irqreturn_t loongson_pcm_dma_irq(int irq, void *devid)
> >         return IRQ_HANDLED;
> >  }
> >
> > -static int loongson_pcm_open(struct snd_soc_component *component,
> > -                            struct snd_pcm_substream *substream)
> > +static int loongson_internal_dma_pcm_open(struct snd_soc_component *component,
> > +                                         struct snd_pcm_substream *substream)
> >  {
> >         struct snd_pcm_runtime *runtime = substream->runtime;
> >         struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
> >         struct snd_card *card = substream->pcm->card;
> >         struct loongson_runtime_data *prtd;
> > -       struct loongson_dma_data *dma_data;
> > +       struct loongson_internal_dma_data *dma_data;
> >
> >         /*
> >          * For mysterious reasons (and despite what the manual says)
> > @@ -241,7 +241,7 @@ static int loongson_pcm_open(struct snd_soc_component *component,
> >                                    SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 128);
> >         snd_pcm_hw_constraint_integer(substream->runtime,
> >                                       SNDRV_PCM_HW_PARAM_PERIODS);
> > -       snd_soc_set_runtime_hwparams(substream, &ls_pcm_hardware);
> > +       snd_soc_set_runtime_hwparams(substream, &loongson_internal_dma_hardware);
> >
> >         prtd = kzalloc_obj(*prtd);
> >         if (!prtd)
> > @@ -277,8 +277,8 @@ static int loongson_pcm_open(struct snd_soc_component *component,
> >         return -ENOMEM;
> >  }
> >
> > -static int loongson_pcm_close(struct snd_soc_component *component,
> > -                             struct snd_pcm_substream *substream)
> > +static int loongson_internal_dma_pcm_close(struct snd_soc_component *component,
> > +                                          struct snd_pcm_substream *substream)
> >  {
> >         struct snd_card *card = substream->pcm->card;
> >         struct loongson_runtime_data *prtd = substream->runtime->private_data;
> > @@ -293,21 +293,21 @@ static int loongson_pcm_close(struct snd_soc_component *component,
> >         return 0;
> >  }
> >
> > -static int loongson_pcm_mmap(struct snd_soc_component *component,
> > -                            struct snd_pcm_substream *substream,
> > -                            struct vm_area_struct *vma)
> > +static int loongson_internal_dma_pcm_mmap(struct snd_soc_component *component,
> > +                                         struct snd_pcm_substream *substream,
> > +                                         struct vm_area_struct *vma)
> >  {
> >         return remap_pfn_range(vma, vma->vm_start,
> > -                       substream->dma_buffer.addr >> PAGE_SHIFT,
> > -                       vma->vm_end - vma->vm_start, vma->vm_page_prot);
> > +                              substream->dma_buffer.addr >> PAGE_SHIFT,
> > +                              vma->vm_end - vma->vm_start, vma->vm_page_prot);
> >  }
> >
> > -static int loongson_pcm_new(struct snd_soc_component *component,
> > -                           struct snd_soc_pcm_runtime *rtd)
> > +static int loongson_internal_dma_pcm_new(struct snd_soc_component *component,
> > +                                        struct snd_soc_pcm_runtime *rtd)
> >  {
> >         struct snd_card *card = rtd->card->snd_card;
> >         struct snd_pcm_substream *substream;
> > -       struct loongson_dma_data *dma_data;
> > +       struct loongson_internal_dma_data *dma_data;
> >         unsigned int i;
> >         int ret;
> >
> > @@ -319,7 +319,7 @@ static int loongson_pcm_new(struct snd_soc_component *component,
> >                 dma_data = snd_soc_dai_get_dma_data(snd_soc_rtd_to_cpu(rtd, 0),
> >                                                     substream);
> >                 ret = devm_request_irq(card->dev, dma_data->irq,
> > -                                      loongson_pcm_dma_irq,
> > +                                      loongson_internal_dma_pcm_dma_irq,
> >                                        IRQF_TRIGGER_HIGH, LS_I2S_DRVNAME,
> >                                        substream);
> >                 if (ret < 0) {
> > @@ -330,16 +330,16 @@ static int loongson_pcm_new(struct snd_soc_component *component,
> >
> >         return snd_pcm_set_fixed_buffer_all(rtd->pcm, SNDRV_DMA_TYPE_DEV,
> >                                             card->dev,
> > -                                           ls_pcm_hardware.buffer_bytes_max);
> > +                                           loongson_internal_dma_hardware.buffer_bytes_max);
> >  }
> >
> > -const struct snd_soc_component_driver loongson_i2s_component = {
> > +const struct snd_soc_component_driver loongson_i2s_internal_dma_component = {
> >         .name           = LS_I2S_DRVNAME,
> > -       .open           = loongson_pcm_open,
> > -       .close          = loongson_pcm_close,
> > -       .hw_params      = loongson_pcm_hw_params,
> > -       .trigger        = loongson_pcm_trigger,
> > -       .pointer        = loongson_pcm_pointer,
> > -       .mmap           = loongson_pcm_mmap,
> > -       .pcm_construct  = loongson_pcm_new,
> > +       .open           = loongson_internal_dma_pcm_open,
> > +       .close          = loongson_internal_dma_pcm_close,
> > +       .hw_params      = loongson_internal_dma_pcm_hw_params,
> > +       .trigger        = loongson_internal_dma_pcm_trigger,
> > +       .pointer        = loongson_internal_dma_pcm_pointer,
> > +       .mmap           = loongson_internal_dma_pcm_mmap,
> > +       .pcm_construct  = loongson_internal_dma_pcm_new,
> >  };
> > diff --git a/sound/soc/loongson/loongson_dma.h b/sound/soc/loongson/loongson_dma.h
> > index 073ee8c0c046..8795fd7874bb 100644
> > --- a/sound/soc/loongson/loongson_dma.h
> > +++ b/sound/soc/loongson/loongson_dma.h
> > @@ -9,8 +9,6 @@
> >  #ifndef _LOONGSON_DMA_H
> >  #define _LOONGSON_DMA_H
> >
> > -#include <sound/soc.h>
> > -
> > -extern const struct snd_soc_component_driver loongson_i2s_component;
> > +extern const struct snd_soc_component_driver loongson_i2s_internal_dma_component;
> >
> >  #endif
> > diff --git a/sound/soc/loongson/loongson_i2s.h b/sound/soc/loongson/loongson_i2s.h
> > index e73ffa954ec9..5f773bbd24c5 100644
> > --- a/sound/soc/loongson/loongson_i2s.h
> > +++ b/sound/soc/loongson/loongson_i2s.h
> > @@ -42,7 +42,7 @@
> >
> >  #define LS_I2S_DRVNAME         "loongson-i2s"
> >
> > -struct loongson_dma_data {
> > +struct loongson_internal_dma_data {
> >         dma_addr_t dev_addr;            /* device physical address for DMA */
> >         void __iomem *order_addr;       /* DMA order register */
> >         int irq;                        /* DMA irq */
> > @@ -52,11 +52,11 @@ struct loongson_i2s {
> >         struct device *dev;
> >         union {
> >                 struct snd_dmaengine_dai_dma_data playback_dma_data;
> > -               struct loongson_dma_data tx_dma_data;
> > +               struct loongson_internal_dma_data tx_dma_data;
> >         };
> >         union {
> >                 struct snd_dmaengine_dai_dma_data capture_dma_data;
> > -               struct loongson_dma_data rx_dma_data;
> > +               struct loongson_internal_dma_data rx_dma_data;
> >         };
> >         struct regmap *regmap;
> >         void __iomem *reg_base;
> > diff --git a/sound/soc/loongson/loongson_i2s_pci.c b/sound/soc/loongson/loongson_i2s_pci.c
> > index dea1e4ebee29..9120432bbe64 100644
> > --- a/sound/soc/loongson/loongson_i2s_pci.c
> > +++ b/sound/soc/loongson/loongson_i2s_pci.c
> > @@ -13,6 +13,7 @@
> >  #include <linux/acpi.h>
> >  #include <linux/pci.h>
> >  #include <sound/soc.h>
> > +
> >  #include "loongson_i2s.h"
> >  #include "loongson_dma.h"
> >
> > @@ -22,7 +23,7 @@ static int loongson_i2s_pci_probe(struct pci_dev *pdev,
> >                                   const struct pci_device_id *pid)
> >  {
> >         const struct fwnode_handle *fwnode = pdev->dev.fwnode;
> > -       struct loongson_dma_data *tx_data, *rx_data;
> > +       struct loongson_internal_dma_data *tx_data, *rx_data;
> >         struct device *dev = &pdev->dev;
> >         struct loongson_i2s *i2s;
> >         int ret;
> > @@ -79,7 +80,7 @@ static int loongson_i2s_pci_probe(struct pci_dev *pdev,
> >                 udelay(200);
> >         }
> >
> > -       ret = devm_snd_soc_register_component(dev, &loongson_i2s_component,
> > +       ret = devm_snd_soc_register_component(dev, &loongson_i2s_internal_dma_component,
> >                                               &loongson_i2s_dai, 1);
> >         if (ret)
> >                 return dev_err_probe(dev, ret, "register DAI failed\n");
> > --
> > 2.52.0
> >
> >

-- 
Thanks.
Binbin

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

* Re: [PATCH 5/6] ASoC: dt-bindings: loongson,ls2k1000-i2s: Document Loongson-2K0300 compatible
  2026-03-11  7:57   ` Huacai Chen
@ 2026-03-11  8:29     ` Binbin Zhou
  0 siblings, 0 replies; 16+ messages in thread
From: Binbin Zhou @ 2026-03-11  8:29 UTC (permalink / raw)
  To: Huacai Chen
  Cc: Binbin Zhou, Huacai Chen, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Liam Girdwood, Mark Brown, Jaroslav Kysela,
	Takashi Iwai, Xuerui Wang, loongarch, devicetree, linux-sound

On Wed, Mar 11, 2026 at 3:57 PM Huacai Chen <chenhuacai@kernel.org> wrote:
>
> Hi, Binbin,
>
> On Wed, Mar 11, 2026 at 2:38 PM Binbin Zhou <zhoubinbin@loongson.cn> wrote:
> >
> > Add "loongson,ls2k0300-i2s" dedicated compatible to represent the I2S
> > interface of the Loongson-2K0300 chip.
> >
> > The hardware integration of the Loongson-2K0300 I2S interface differs
> > significantly from that of the Loongson-2K1000. Specifically, while both
> > utilize external DMA controllers, the Loongson-2K0300 configures DMA
> > channel routing via the `dmas` property, whereas the Loongson-2K1000
> > requires additional register.
> Can this patch be the second one?

Typically, I place the dt-binding patch before the new platform driver
patches, while patch 2-4 involve code cleanup for existing drivers.
Therefore, I prefer to position this patch after them.
>
> Huacai
>
> >
> > 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
> >

--
Thanks.
Binbin

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

* Re: [PATCH 6/6] ASoC: loongson: Add Loongson-2k0300 I2S controller support
  2026-03-11  6:37 ` [PATCH 6/6] ASoC: loongson: Add Loongson-2k0300 I2S controller support Binbin Zhou
@ 2026-03-11 16:15   ` Mark Brown
  2026-03-17 12:46     ` Binbin Zhou
  0 siblings, 1 reply; 16+ messages in thread
From: Mark Brown @ 2026-03-11 16:15 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: 1057 bytes --]

On Wed, Mar 11, 2026 at 02:37:48PM +0800, Binbin Zhou wrote:

> Due to a hardware design flaw, PCM_START requires an explicit reset.
> It has been tested and does not affect other machines.

Are you sure?  It just does a reset whenever we start a stream which
means if one direction is already running the controller will get reset
underneath it and disrupt things if the other is started.  If this IP
requires it I guess that's just unfortunate but presumably existing
devices don't require the reset and will be regressed.

> +++ b/sound/soc/loongson/loongson_card.c
> @@ -61,7 +61,7 @@ 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
> +		.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
>  			| SND_SOC_DAIFMT_CBC_CFC,
>  		SND_SOC_DAILINK_REG(analog),
>  		.ops = &loongson_ops,

This changes the clock inversion for everything - should this be
parameterised as that seems to be a fairly generic card?

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

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

* Re: [PATCH 5/6] ASoC: dt-bindings: loongson,ls2k1000-i2s: Document Loongson-2K0300 compatible
  2026-03-11  6:37 ` [PATCH 5/6] ASoC: dt-bindings: loongson,ls2k1000-i2s: Document Loongson-2K0300 compatible Binbin Zhou
  2026-03-11  7:57   ` Huacai Chen
@ 2026-03-13 13:18   ` Krzysztof Kozlowski
  1 sibling, 0 replies; 16+ messages in thread
From: Krzysztof Kozlowski @ 2026-03-13 13:18 UTC (permalink / raw)
  To: Binbin Zhou
  Cc: Binbin Zhou, Huacai Chen, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Liam Girdwood, Mark Brown, Jaroslav Kysela,
	Takashi Iwai, Huacai Chen, Xuerui Wang, loongarch, devicetree,
	linux-sound

On Wed, Mar 11, 2026 at 02:37:47PM +0800, Binbin Zhou wrote:
> Add "loongson,ls2k0300-i2s" dedicated compatible to represent the I2S
> interface of the Loongson-2K0300 chip.
> 
> The hardware integration of the Loongson-2K0300 I2S interface differs
> significantly from that of the Loongson-2K1000. Specifically, while both
> utilize external DMA controllers, the Loongson-2K0300 configures DMA
> channel routing via the `dmas` property, whereas the Loongson-2K1000
> requires additional register.
> 
> Signed-off-by: Binbin Zhou <zhoubinbin@loongson.cn>
> ---
>  .../bindings/sound/loongson,ls2k1000-i2s.yaml | 22 ++++++++++++++++++-
>  1 file changed, 21 insertions(+), 1 deletion(-)

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

Best regards,
Krzysztof


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

* Re: [PATCH 6/6] ASoC: loongson: Add Loongson-2k0300 I2S controller support
  2026-03-11 16:15   ` Mark Brown
@ 2026-03-17 12:46     ` Binbin Zhou
  0 siblings, 0 replies; 16+ messages in thread
From: Binbin Zhou @ 2026-03-17 12:46 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:

Sorry for my late reply.

On Thu, Mar 12, 2026 at 12:15 AM Mark Brown <broonie@kernel.org> wrote:
>
> On Wed, Mar 11, 2026 at 02:37:48PM +0800, Binbin Zhou wrote:
>
> > Due to a hardware design flaw, PCM_START requires an explicit reset.
> > It has been tested and does not affect other machines.
>
> Are you sure?  It just does a reset whenever we start a stream which
> means if one direction is already running the controller will get reset
> underneath it and disrupt things if the other is started.  If this IP
> requires it I guess that's just unfortunate but presumably existing
> devices don't require the reset and will be regressed.

Sorry, I may have misunderstood that.
We just need to soft-reset the controller in
`loongson_i2s_plat_probe()`, similar to `loongson_i2s_pci_probe()`.
>
> > +++ b/sound/soc/loongson/loongson_card.c
> > @@ -61,7 +61,7 @@ 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
> > +             .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
> >                       | SND_SOC_DAIFMT_CBC_CFC,
> >               SND_SOC_DAILINK_REG(analog),
> >               .ops = &loongson_ops,
>
> This changes the clock inversion for everything - should this be
> parameterised as that seems to be a fairly generic card?

Okay, I'll add the new compatible.

In addition, this series of patches seems a bit disorganized, so I
plan to separate the first four patches into a standalone patchset
focused on code reorganization.
I plan to add GPIO-based headphone detection (Headphones Jack), which
will be used by the Loongson-2K0300 SoC.

-- 
Thanks.
Binbin

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

end of thread, other threads:[~2026-03-17 12:46 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-11  6:37 [PATCH 0/3] ASoC: Add Loongson-2k0300 I2S controller support Binbin Zhou
2026-03-11  6:37 ` [PATCH 1/6] MAINTAINERS: Add entry for Loongson ASoC driver Binbin Zhou
2026-03-11  6:37 ` [PATCH 2/6] ASoC: loongson: Combined regmap definitions Binbin Zhou
2026-03-11  7:55   ` Huacai Chen
2026-03-11  8:17     ` Binbin Zhou
2026-03-11  6:37 ` [PATCH 3/6] ASoC: loongson: Add `internal` to the names of internal DMA variables Binbin Zhou
2026-03-11  7:56   ` Huacai Chen
2026-03-11  8:24     ` Binbin Zhou
2026-03-11  6:37 ` [PATCH 4/6] ASoC: loongson: Separate external shared DMA from the platform interface Binbin Zhou
2026-03-11  6:37 ` [PATCH 5/6] ASoC: dt-bindings: loongson,ls2k1000-i2s: Document Loongson-2K0300 compatible Binbin Zhou
2026-03-11  7:57   ` Huacai Chen
2026-03-11  8:29     ` Binbin Zhou
2026-03-13 13:18   ` Krzysztof Kozlowski
2026-03-11  6:37 ` [PATCH 6/6] ASoC: loongson: Add Loongson-2k0300 I2S controller support Binbin Zhou
2026-03-11 16:15   ` Mark Brown
2026-03-17 12:46     ` Binbin Zhou

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