* [PATCH 0/4] ASoC: loongson: Optimized code and variable naming
@ 2026-03-18 9:16 Binbin Zhou
2026-03-18 9:16 ` [PATCH 1/4] MAINTAINERS: Add entry for Loongson ASoC driver Binbin Zhou
` (3 more replies)
0 siblings, 4 replies; 6+ messages in thread
From: Binbin Zhou @ 2026-03-18 9:16 UTC (permalink / raw)
To: Binbin Zhou, Huacai Chen, Liam Girdwood, Mark Brown,
Jaroslav Kysela, Takashi Iwai
Cc: Huacai Chen, Xuerui Wang, loongarch, linux-sound, Binbin Zhou
Hi all:
This patchset is separated from [1], because it is unrelated to
Loongson-2K0300 support, and there are other features that need to be
added for Loongson-2K0300.
Patchset Overview:
1. Updated MAINTAINERS to add the Loongson ASoC entry;
2. Merged regmap definitions to eliminate warnings;
3. Renamed internal DMA/external DMA variables and decoupled external
DMA from the platform interface.
Thanks.
Binbin
======
Change from [1]:
Patch (2/4):
- Reordered the `write` function to follow the `read` function;
Patch (3/4)/(4/4):
- Use `idma` (internal dma) and `edma` (external dma) for short.
[1]: https://lore.kernel.org/all/cover.1773107475.git.zhoubinbin@loongson.cn/
Binbin Zhou (4):
MAINTAINERS: Add entry for Loongson ASoC driver
ASoC: loongson: Combined regmap definitions
ASoC: loongson: Use the `idma` identifier for internal DMA variables
ASoC: loongson: Separate external shared DMA from the platform
interface
MAINTAINERS | 7 ++
sound/soc/loongson/Makefile | 4 +-
sound/soc/loongson/loongson_dma.c | 148 +++++++++++++++++--------
sound/soc/loongson/loongson_dma.h | 6 +-
sound/soc/loongson/loongson_i2s.c | 55 +++++++++
sound/soc/loongson/loongson_i2s.h | 7 +-
sound/soc/loongson/loongson_i2s_pci.c | 59 +---------
sound/soc/loongson/loongson_i2s_plat.c | 67 +----------
8 files changed, 180 insertions(+), 173 deletions(-)
base-commit: de12d535e2730ab630ffc65aee915c8155c9752a
--
2.52.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/4] MAINTAINERS: Add entry for Loongson ASoC driver
2026-03-18 9:16 [PATCH 0/4] ASoC: loongson: Optimized code and variable naming Binbin Zhou
@ 2026-03-18 9:16 ` Binbin Zhou
2026-03-18 9:16 ` [PATCH 2/4] ASoC: loongson: Combined regmap definitions Binbin Zhou
` (2 subsequent siblings)
3 siblings, 0 replies; 6+ messages in thread
From: Binbin Zhou @ 2026-03-18 9:16 UTC (permalink / raw)
To: Binbin Zhou, Huacai Chen, Liam Girdwood, Mark Brown,
Jaroslav Kysela, Takashi Iwai
Cc: Huacai Chen, Xuerui Wang, loongarch, 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 96ea84948d76..6a652d8878bf 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -14935,6 +14935,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] 6+ messages in thread
* [PATCH 2/4] ASoC: loongson: Combined regmap definitions
2026-03-18 9:16 [PATCH 0/4] ASoC: loongson: Optimized code and variable naming Binbin Zhou
2026-03-18 9:16 ` [PATCH 1/4] MAINTAINERS: Add entry for Loongson ASoC driver Binbin Zhou
@ 2026-03-18 9:16 ` Binbin Zhou
2026-03-18 14:16 ` Mark Brown
2026-03-18 9:16 ` [PATCH 3/4] ASoC: loongson: Use the `idma` identifier for internal DMA variables Binbin Zhou
2026-03-18 9:17 ` [PATCH 4/4] ASoC: loongson: Separate external shared DMA from the platform interface Binbin Zhou
3 siblings, 1 reply; 6+ messages in thread
From: Binbin Zhou @ 2026-03-18 9:16 UTC (permalink / raw)
To: Binbin Zhou, Huacai Chen, Liam Girdwood, Mark Brown,
Jaroslav Kysela, Takashi Iwai
Cc: Huacai Chen, Xuerui Wang, loongarch, 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..bd504cf41a29 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_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_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_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,
+ .readable_reg = loongson_i2s_rd_reg,
+ .writeable_reg = loongson_i2s_wr_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] 6+ messages in thread
* [PATCH 3/4] ASoC: loongson: Use the `idma` identifier for internal DMA variables
2026-03-18 9:16 [PATCH 0/4] ASoC: loongson: Optimized code and variable naming Binbin Zhou
2026-03-18 9:16 ` [PATCH 1/4] MAINTAINERS: Add entry for Loongson ASoC driver Binbin Zhou
2026-03-18 9:16 ` [PATCH 2/4] ASoC: loongson: Combined regmap definitions Binbin Zhou
@ 2026-03-18 9:16 ` Binbin Zhou
2026-03-18 9:17 ` [PATCH 4/4] ASoC: loongson: Separate external shared DMA from the platform interface Binbin Zhou
3 siblings, 0 replies; 6+ messages in thread
From: Binbin Zhou @ 2026-03-18 9:16 UTC (permalink / raw)
To: Binbin Zhou, Huacai Chen, Liam Girdwood, Mark Brown,
Jaroslav Kysela, Takashi Iwai
Cc: Huacai Chen, Xuerui Wang, loongarch, linux-sound, Binbin Zhou
The DMA controller used in Loongson I2S is divided into internal
exclusive DMA and external shared DMA (APBDMA). Add the `idma` 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 | 89 ++++++++++++++-------------
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, 52 insertions(+), 52 deletions(-)
diff --git a/sound/soc/loongson/loongson_dma.c b/sound/soc/loongson/loongson_dma.c
index a149b643175c..3ebf59d60a71 100644
--- a/sound/soc/loongson/loongson_dma.c
+++ b/sound/soc/loongson/loongson_dma.c
@@ -14,9 +14,10 @@
#include <sound/soc.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
+
#include "loongson_i2s.h"
-/* DMA dma_order Register */
+/* Internal DMA dma_order Register */
#define DMA_ORDER_STOP BIT(4) /* DMA stop */
#define DMA_ORDER_START BIT(3) /* DMA start */
#define DMA_ORDER_ASK_VALID BIT(2) /* DMA ask valid flag */
@@ -27,9 +28,9 @@
#define DMA_ORDER_CTRL_MASK (0x0fUL) /* Control mask */
/*
- * DMA registers descriptor.
+ * Internal DMA registers descriptor.
*/
-struct loongson_dma_desc {
+struct loongson_idma_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_idma_data *dma_data;
- struct loongson_dma_desc *dma_desc_arr;
+ struct loongson_idma_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_idma_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_idma_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_idma_desc),
.buffer_bytes_max = 1024 * 1024,
};
-static struct
-loongson_dma_desc *dma_desc_save(struct loongson_runtime_data *prtd)
+static struct loongson_idma_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_idma_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_idma_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_idma_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_idma_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_idma_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_idma_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_idma_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_idma_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_idma_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_idma_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_idma_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_idma_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_idma_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_idma_pcm_dma_irq,
IRQF_TRIGGER_HIGH, LS_I2S_DRVNAME,
substream);
if (ret < 0) {
@@ -330,16 +330,17 @@ 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_idma_hardware.buffer_bytes_max);
}
-const struct snd_soc_component_driver loongson_i2s_component = {
+/* Internal DMA component */
+const struct snd_soc_component_driver loongson_i2s_idma_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_new = loongson_pcm_new,
+ .open = loongson_idma_pcm_open,
+ .close = loongson_idma_pcm_close,
+ .hw_params = loongson_idma_pcm_hw_params,
+ .trigger = loongson_idma_pcm_trigger,
+ .pointer = loongson_idma_pcm_pointer,
+ .mmap = loongson_idma_pcm_mmap,
+ .pcm_new = loongson_idma_pcm_new,
};
diff --git a/sound/soc/loongson/loongson_dma.h b/sound/soc/loongson/loongson_dma.h
index 073ee8c0c046..8a8fa8abd85a 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_idma_component;
#endif
diff --git a/sound/soc/loongson/loongson_i2s.h b/sound/soc/loongson/loongson_i2s.h
index e73ffa954ec9..8b4603c876c5 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_idma_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_idma_data tx_dma_data;
};
union {
struct snd_dmaengine_dai_dma_data capture_dma_data;
- struct loongson_dma_data rx_dma_data;
+ struct loongson_idma_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..f5b560465706 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_idma_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_idma_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] 6+ messages in thread
* [PATCH 4/4] ASoC: loongson: Separate external shared DMA from the platform interface
2026-03-18 9:16 [PATCH 0/4] ASoC: loongson: Optimized code and variable naming Binbin Zhou
` (2 preceding siblings ...)
2026-03-18 9:16 ` [PATCH 3/4] ASoC: loongson: Use the `idma` identifier for internal DMA variables Binbin Zhou
@ 2026-03-18 9:17 ` Binbin Zhou
3 siblings, 0 replies; 6+ messages in thread
From: Binbin Zhou @ 2026-03-18 9:17 UTC (permalink / raw)
To: Binbin Zhou, Huacai Chen, Liam Girdwood, Mark Brown,
Jaroslav Kysela, Takashi Iwai
Cc: Huacai Chen, Xuerui Wang, loongarch, 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 | 59 ++++++++++++++++++++++++++
sound/soc/loongson/loongson_dma.h | 2 +
sound/soc/loongson/loongson_i2s_plat.c | 59 +-------------------------
4 files changed, 65 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 3ebf59d60a71..06cb78f97609 100644
--- a/sound/soc/loongson/loongson_dma.c
+++ b/sound/soc/loongson/loongson_dma.c
@@ -344,3 +344,62 @@ const struct snd_soc_component_driver loongson_i2s_idma_component = {
.mmap = loongson_idma_pcm_mmap,
.pcm_new = loongson_idma_pcm_new,
};
+EXPORT_SYMBOL_GPL(loongson_i2s_idma_component);
+
+static const struct snd_pcm_hardware loongson_edma_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_edma_hardware,
+ .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
+ .prealloc_buffer_size = 128 * 1024,
+};
+EXPORT_SYMBOL_GPL(loongson_dmaengine_pcm_config);
+
+/* External DMA component */
+static int loongson_edma_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_edma_component = {
+ .name = LS_I2S_DRVNAME,
+ .open = loongson_edma_pcm_open,
+};
+EXPORT_SYMBOL_GPL(loongson_i2s_edma_component);
diff --git a/sound/soc/loongson/loongson_dma.h b/sound/soc/loongson/loongson_dma.h
index 8a8fa8abd85a..a040681d2693 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_idma_component;
+extern const struct snd_soc_component_driver loongson_i2s_edma_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..ac054b6ce632 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_edma_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] 6+ messages in thread
* Re: [PATCH 2/4] ASoC: loongson: Combined regmap definitions
2026-03-18 9:16 ` [PATCH 2/4] ASoC: loongson: Combined regmap definitions Binbin Zhou
@ 2026-03-18 14:16 ` Mark Brown
0 siblings, 0 replies; 6+ messages in thread
From: Mark Brown @ 2026-03-18 14:16 UTC (permalink / raw)
To: Binbin Zhou
Cc: Binbin Zhou, Huacai Chen, Liam Girdwood, Jaroslav Kysela,
Takashi Iwai, Huacai Chen, Xuerui Wang, loongarch, linux-sound
[-- Attachment #1: Type: text/plain, Size: 1318 bytes --]
On Wed, Mar 18, 2026 at 05:16:36PM +0800, Binbin Zhou wrote:
> +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;
> + };
> +}
This is the same as what was in the PCI driver but...
> --- a/sound/soc/loongson/loongson_i2s_plat.c
> +++ b/sound/soc/loongson/loongson_i2s_plat.c
> -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,
> -};
...the platform driver marked all the registers as cacheable. With
registers like LS_I2S_CTRL marked as volatile this means we'll stop
caching the configuration done by set_fmt(), and currently the driver
uses a regcache sync to restore from suspend so things might get
confused.
If you're just marking things volatile to stop the warnings and the zero
defaults are actually fine you can also supply explicit zero defaults
for all the registers, or switch to a sparse cache type if the
performance and allocation requirements you have are OK with that.
I think this means there was an issue that got missed in the PCI
driver..
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-03-18 14:16 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-18 9:16 [PATCH 0/4] ASoC: loongson: Optimized code and variable naming Binbin Zhou
2026-03-18 9:16 ` [PATCH 1/4] MAINTAINERS: Add entry for Loongson ASoC driver Binbin Zhou
2026-03-18 9:16 ` [PATCH 2/4] ASoC: loongson: Combined regmap definitions Binbin Zhou
2026-03-18 14:16 ` Mark Brown
2026-03-18 9:16 ` [PATCH 3/4] ASoC: loongson: Use the `idma` identifier for internal DMA variables Binbin Zhou
2026-03-18 9:17 ` [PATCH 4/4] ASoC: loongson: Separate external shared DMA from the platform interface Binbin Zhou
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox