summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2026-06-01 18:00:46 +0300
committerMark Brown <broonie@kernel.org>2026-06-01 18:00:46 +0300
commit054f183fb307174055caef0e5373b9f2ea32b65d (patch)
tree7f3f51059c049ef6bf16f3c162ae5c79fab0ee9e
parent36cf16513f9dfc6dc5eee7ed5ca5fd4f649e1f1a (diff)
parent1c6ca2ca5c1bdc97912cf3f9b4a1e186919a6a98 (diff)
downloadlinux-054f183fb307174055caef0e5373b9f2ea32b65d.tar.xz
ASoC: spacemit: add K3 SoC support
Troy Mitchell <troy.mitchell@linux.spacemit.com> says: This series adds K3 SoC support for the SpacemiT I2S controller driver. Patch 1 adds the dt-bindings for the spacemit,k3-i2s compatible. The K3 SoC uses the same I2S IP as K1 but requires additional clocks (sysclk_div, c_sysclk, c_bclk) that are shared across multiple I2S controllers. Patch 2 adds driver support for K3 SoC with additional clocks. Link: https://patch.msgid.link/20260522-k3-i2s-v3-0-08e3eb811d93@linux.spacemit.com
-rw-r--r--Documentation/devicetree/bindings/sound/spacemit,k1-i2s.yaml31
-rw-r--r--sound/soc/spacemit/k1_i2s.c36
2 files changed, 64 insertions, 3 deletions
diff --git a/Documentation/devicetree/bindings/sound/spacemit,k1-i2s.yaml b/Documentation/devicetree/bindings/sound/spacemit,k1-i2s.yaml
index 55bd0b307d22..240d90402e4f 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
diff --git a/sound/soc/spacemit/k1_i2s.c b/sound/soc/spacemit/k1_i2s.c
index 5420ca2aefbd..8871fc15b29c 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");