From 41d8aabf4156bebde5d0eeedac16c64d4c8f0013 Mon Sep 17 00:00:00 2001 From: Troy Mitchell Date: Fri, 22 May 2026 21:12:14 +0800 Subject: [PATCH 1/2] ASoC: dt-bindings: add SpacemiT K3 SoC compatible Add the spacemit,k3-i2s compatible string for the K3 SoC I2S controller. The K3 I2S IP is the same as K1 but requires additional clocks: a dedicated sysclk_div clock, along with common_sysclk and common_bclk which are shared across multiple I2S controllers on K3. Acked-by: Rob Herring (Arm) Signed-off-by: Troy Mitchell Signed-off-by: Linux RISC-V bot --- .../bindings/sound/spacemit,k1-i2s.yaml | 31 +++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/Documentation/devicetree/bindings/sound/spacemit,k1-i2s.yaml b/Documentation/devicetree/bindings/sound/spacemit,k1-i2s.yaml index 55bd0b307d22b3..240d90402e4f95 100644 --- a/Documentation/devicetree/bindings/sound/spacemit,k1-i2s.yaml +++ b/Documentation/devicetree/bindings/sound/spacemit,k1-i2s.yaml @@ -4,7 +4,7 @@ $id: http://devicetree.org/schemas/sound/spacemit,k1-i2s.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: K1 I2S controller +title: SpacemiT K1/K3 I2S controller description: The I2S bus (Inter-IC sound bus) is a serial link for digital @@ -15,27 +15,54 @@ maintainers: allOf: - $ref: dai-common.yaml# + - if: + properties: + compatible: + contains: + const: spacemit,k3-i2s + then: + properties: + clocks: + minItems: 7 + clock-names: + minItems: 7 + else: + properties: + clocks: + maxItems: 4 + clock-names: + maxItems: 4 properties: compatible: - const: spacemit,k1-i2s + enum: + - spacemit,k1-i2s + - spacemit,k3-i2s reg: maxItems: 1 clocks: + minItems: 4 items: - description: clock for I2S sysclk - description: clock for I2S bclk - description: clock for I2S bus - description: clock for I2S controller + - description: clock for I2S sysclk divider + - description: clock for I2S common sysclk + - description: clock for I2S common bclk clock-names: + minItems: 4 items: - const: sysclk - const: bclk - const: bus - const: func + - const: sysclk_div + - const: c_sysclk + - const: c_bclk dmas: minItems: 1 From e6bc9e0bb5b7d5f82573bbb52829f2939b9fd74c Mon Sep 17 00:00:00 2001 From: Troy Mitchell Date: Fri, 22 May 2026 21:12:15 +0800 Subject: [PATCH 2/2] ASoC: spacemit: add K3 SoC support with additional clocks Add support for the SpacemiT K3 SoC I2S controller, which shares the same IP as K1 but requires additional clocks: sysclk_div, c_sysclk, and c_bclk. These clocks only exist on K3 and are not present on K1. The sysclk_div clock is present on most K3 I2S controllers except I2S1. The c_sysclk and c_bclk clocks are shared across multiple I2S controllers on K3. Use devm_clk_get_optional_enabled() to acquire these clocks so that the driver works on both K1 (where they are absent) and K3 without needing SoC-specific match data. For K3, the sysclk_div rate is set before sysclk in set_sysclk, and the common clock rates are configured in hw_params based on the sample rate. Signed-off-by: Troy Mitchell Signed-off-by: Linux RISC-V bot --- sound/soc/spacemit/k1_i2s.c | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/sound/soc/spacemit/k1_i2s.c b/sound/soc/spacemit/k1_i2s.c index 5420ca2aefbd87..8871fc15b29cc0 100644 --- a/sound/soc/spacemit/k1_i2s.c +++ b/sound/soc/spacemit/k1_i2s.c @@ -53,6 +53,9 @@ struct spacemit_i2s_dev { struct clk *sysclk; struct clk *bclk; struct clk *sspa_clk; + struct clk *sysclk_div; + struct clk *c_sysclk; + struct clk *c_bclk; struct snd_dmaengine_dai_dma_data capture_dma_data; struct snd_dmaengine_dai_dma_data playback_dma_data; @@ -206,6 +209,14 @@ static int spacemit_i2s_hw_params(struct snd_pcm_substream *substream, params_rate(params) * data_bits; + ret = clk_set_rate(i2s->c_sysclk, bclk_rate * 2); + if (ret) + return ret; + + ret = clk_set_rate(i2s->c_bclk, bclk_rate); + if (ret) + return ret; + ret = clk_set_rate(i2s->bclk, bclk_rate); if (ret) return ret; @@ -217,10 +228,17 @@ static int spacemit_i2s_set_sysclk(struct snd_soc_dai *cpu_dai, int clk_id, unsigned int freq, int dir) { struct spacemit_i2s_dev *i2s = dev_get_drvdata(cpu_dai->dev); + int ret; if (freq == 0) return 0; + if (i2s->sysclk_div) { + ret = clk_set_rate(i2s->sysclk_div, freq); + if (ret) + return ret; + } + return clk_set_rate(i2s->sysclk, freq); } @@ -436,6 +454,21 @@ static int spacemit_i2s_probe(struct platform_device *pdev) return dev_err_probe(i2s->dev, PTR_ERR(i2s->sspa_clk), "failed to enable sspa clock\n"); + i2s->sysclk_div = devm_clk_get_optional_enabled(i2s->dev, "sysclk_div"); + if (IS_ERR(i2s->sysclk_div)) + return dev_err_probe(i2s->dev, PTR_ERR(i2s->sysclk_div), + "failed to enable sysclk_div clock\n"); + + i2s->c_sysclk = devm_clk_get_optional_enabled(i2s->dev, "c_sysclk"); + if (IS_ERR(i2s->c_sysclk)) + return dev_err_probe(i2s->dev, PTR_ERR(i2s->c_sysclk), + "failed to enable c_sysclk clock\n"); + + i2s->c_bclk = devm_clk_get_optional_enabled(i2s->dev, "c_bclk"); + if (IS_ERR(i2s->c_bclk)) + return dev_err_probe(i2s->dev, PTR_ERR(i2s->c_bclk), + "failed to enable c_bclk clock\n"); + i2s->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); if (IS_ERR(i2s->base)) return dev_err_probe(i2s->dev, PTR_ERR(i2s->base), "failed to map registers\n"); @@ -462,6 +495,7 @@ static int spacemit_i2s_probe(struct platform_device *pdev) static const struct of_device_id spacemit_i2s_of_match[] = { { .compatible = "spacemit,k1-i2s", }, + { .compatible = "spacemit,k3-i2s", }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, spacemit_i2s_of_match); @@ -476,4 +510,4 @@ static struct platform_driver spacemit_i2s_driver = { module_platform_driver(spacemit_i2s_driver); MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("I2S bus driver for SpacemiT K1 SoC"); +MODULE_DESCRIPTION("I2S bus driver for SpacemiT K1/K3 SoC");