* [PATCH v2 0/2] ASoC: spacemit: add i2s support to K1 SoC
@ 2025-08-28 3:37 ` Troy Mitchell
0 siblings, 0 replies; 14+ messages in thread
From: Troy Mitchell @ 2025-08-28 3:37 UTC (permalink / raw)
To: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Yixun Lan, Jaroslav Kysela, Takashi Iwai,
Philipp Zabel
Cc: linux-sound, devicetree, linux-riscv, spacemit, linux-kernel,
Troy Mitchell, Jinmei Wei
On the K1 SoC, there is a full-duplex I2S controller.
The I2S is programmable, with the sample width configurable
to 8, 16, 18, or 32 bits.
A dedicated FIFO is provided for transmit (TXFIFO) and another
for receive (RXFIFO). In non-packed mode, both FIFOs are 32
entries deep and 32 bits wide, giving a total of 32 samples each.
The register definitions can be found here[1]
Link:
https://developer.spacemit.com/documentation?token=Rn9Kw3iFHirAMgkIpTAcV2Arnkf#18.2-spi%2Fi2s [1]
Signed-off-by: Troy Mitchell <troy.mitchell@linux.spacemit.com>
---
Changes in v2:
- Patch 1/2:
- modify commit message
- remove unused third cell from pdma dmas property
- update SPDX license in spacemit,k1-i2s.yaml to (GPL-2.0-only OR BSD-2-Clause)
- Patch 2/2:
- modify commit message
- reset_assert in dai_ops::remove
- select CMA and DMA_CMA in Kconfig
- use devm_reset_control_get_exclusive
- Link to v1: https://lore.kernel.org/r/20250814-k1-i2s-v1-0-c31149b29041@linux.spacemit.com
---
Troy Mitchell (2):
ASoC: dt-bindings: Add bindings for SpacemiT K1
ASoC: spacemit: add i2s support for K1 SoC
.../devicetree/bindings/sound/spacemit,k1-i2s.yaml | 88 ++++
sound/soc/Kconfig | 1 +
sound/soc/Makefile | 1 +
sound/soc/spacemit/Kconfig | 16 +
sound/soc/spacemit/Makefile | 5 +
sound/soc/spacemit/k1_i2s.c | 452 +++++++++++++++++++++
6 files changed, 563 insertions(+)
---
base-commit: 8f5ae30d69d7543eee0d70083daf4de8fe15d585
change-id: 20250813-k1-i2s-115bf65eaac8
prerequisite-change-id: 20250804-k1-clk-i2s-generation-eee7049ee17a:v4
prerequisite-patch-id: b46d4007c5b20f11845db739fc78ffccc54f4dab
prerequisite-patch-id: 1e193c412de1206c024a674e2dd7da88092976b9
prerequisite-patch-id: af07a4bca4109b13a74c0b20a12f96af863090ef
prerequisite-change-id: 20250701-working_dma_0701_v2-7d2cf506aad7:v5
prerequisite-patch-id: 3fe97698036c32c20d03b1b835a5735e8ee8126c
prerequisite-patch-id: bf64cb2fbb9699d2ace64ae517532f13c6f8d277
prerequisite-patch-id: 49263c65c84a0b045f9b5ae6831dc011c4dea52f
prerequisite-patch-id: 2b43599bf7568e6432faa2f6aca5b2db792cd1c1
prerequisite-patch-id: 1b840918a99543f4497b6475ee52977bdb59f1c3
prerequisite-patch-id: 2f77be523fd5423bd011e3081a3635d130410096
prerequisite-patch-id: 78bcc660796fc4f73b884d17a1b63e62f99dfdd0
prerequisite-patch-id: 62d0b3678cf825bca51424ad85cf35ebdd6dc171
prerequisite-message-id: <20250824-k1-clk-i2s-v5-0-217b6b7cea06@linux.spacemit.com>
prerequisite-patch-id: 6f2626811da4833395f52f712d9f2a5fb553cb48
prerequisite-patch-id: d2594982f7a8f39c2aa4f21490a19e93ab67254d
Best regards,
--
Troy Mitchell <troy.mitchell@linux.spacemit.com>
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
^ permalink raw reply [flat|nested] 14+ messages in thread* [PATCH v2 0/2] ASoC: spacemit: add i2s support to K1 SoC @ 2025-08-28 3:37 ` Troy Mitchell 0 siblings, 0 replies; 14+ messages in thread From: Troy Mitchell @ 2025-08-28 3:37 UTC (permalink / raw) To: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Yixun Lan, Jaroslav Kysela, Takashi Iwai, Philipp Zabel Cc: linux-sound, devicetree, linux-riscv, spacemit, linux-kernel, Troy Mitchell, Jinmei Wei On the K1 SoC, there is a full-duplex I2S controller. The I2S is programmable, with the sample width configurable to 8, 16, 18, or 32 bits. A dedicated FIFO is provided for transmit (TXFIFO) and another for receive (RXFIFO). In non-packed mode, both FIFOs are 32 entries deep and 32 bits wide, giving a total of 32 samples each. The register definitions can be found here[1] Link: https://developer.spacemit.com/documentation?token=Rn9Kw3iFHirAMgkIpTAcV2Arnkf#18.2-spi%2Fi2s [1] Signed-off-by: Troy Mitchell <troy.mitchell@linux.spacemit.com> --- Changes in v2: - Patch 1/2: - modify commit message - remove unused third cell from pdma dmas property - update SPDX license in spacemit,k1-i2s.yaml to (GPL-2.0-only OR BSD-2-Clause) - Patch 2/2: - modify commit message - reset_assert in dai_ops::remove - select CMA and DMA_CMA in Kconfig - use devm_reset_control_get_exclusive - Link to v1: https://lore.kernel.org/r/20250814-k1-i2s-v1-0-c31149b29041@linux.spacemit.com --- Troy Mitchell (2): ASoC: dt-bindings: Add bindings for SpacemiT K1 ASoC: spacemit: add i2s support for K1 SoC .../devicetree/bindings/sound/spacemit,k1-i2s.yaml | 88 ++++ sound/soc/Kconfig | 1 + sound/soc/Makefile | 1 + sound/soc/spacemit/Kconfig | 16 + sound/soc/spacemit/Makefile | 5 + sound/soc/spacemit/k1_i2s.c | 452 +++++++++++++++++++++ 6 files changed, 563 insertions(+) --- base-commit: 8f5ae30d69d7543eee0d70083daf4de8fe15d585 change-id: 20250813-k1-i2s-115bf65eaac8 prerequisite-change-id: 20250804-k1-clk-i2s-generation-eee7049ee17a:v4 prerequisite-patch-id: b46d4007c5b20f11845db739fc78ffccc54f4dab prerequisite-patch-id: 1e193c412de1206c024a674e2dd7da88092976b9 prerequisite-patch-id: af07a4bca4109b13a74c0b20a12f96af863090ef prerequisite-change-id: 20250701-working_dma_0701_v2-7d2cf506aad7:v5 prerequisite-patch-id: 3fe97698036c32c20d03b1b835a5735e8ee8126c prerequisite-patch-id: bf64cb2fbb9699d2ace64ae517532f13c6f8d277 prerequisite-patch-id: 49263c65c84a0b045f9b5ae6831dc011c4dea52f prerequisite-patch-id: 2b43599bf7568e6432faa2f6aca5b2db792cd1c1 prerequisite-patch-id: 1b840918a99543f4497b6475ee52977bdb59f1c3 prerequisite-patch-id: 2f77be523fd5423bd011e3081a3635d130410096 prerequisite-patch-id: 78bcc660796fc4f73b884d17a1b63e62f99dfdd0 prerequisite-patch-id: 62d0b3678cf825bca51424ad85cf35ebdd6dc171 prerequisite-message-id: <20250824-k1-clk-i2s-v5-0-217b6b7cea06@linux.spacemit.com> prerequisite-patch-id: 6f2626811da4833395f52f712d9f2a5fb553cb48 prerequisite-patch-id: d2594982f7a8f39c2aa4f21490a19e93ab67254d Best regards, -- Troy Mitchell <troy.mitchell@linux.spacemit.com> ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v2 1/2] ASoC: dt-bindings: Add bindings for SpacemiT K1 2025-08-28 3:37 ` Troy Mitchell @ 2025-08-28 3:37 ` Troy Mitchell -1 siblings, 0 replies; 14+ messages in thread From: Troy Mitchell @ 2025-08-28 3:37 UTC (permalink / raw) To: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Yixun Lan, Jaroslav Kysela, Takashi Iwai, Philipp Zabel Cc: linux-sound, devicetree, linux-riscv, spacemit, linux-kernel, Troy Mitchell Add dt-binding for the i2s driver of SpacemiT's K1 SoC. Signed-off-by: Troy Mitchell <troy.mitchell@linux.spacemit.com> --- .../devicetree/bindings/sound/spacemit,k1-i2s.yaml | 88 ++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/Documentation/devicetree/bindings/sound/spacemit,k1-i2s.yaml b/Documentation/devicetree/bindings/sound/spacemit,k1-i2s.yaml new file mode 100644 index 0000000000000000000000000000000000000000..042001c38ed8d434889183831e44289ea9c5aef2 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/spacemit,k1-i2s.yaml @@ -0,0 +1,88 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/spacemit,k1-i2s.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: K1 I2S controller + +description: + The I2S bus (Inter-IC sound bus) is a serial link for digital + audio data transfer between devices in the system. + +maintainers: + - Troy Mitchell <troy.mitchell@linux.spacemit.com> + +allOf: + - $ref: dai-common.yaml# + +properties: + compatible: + const: spacemit,k1-i2s + + reg: + maxItems: 1 + + clocks: + items: + - description: clock for I2S sysclk + - description: clock for I2S bclk + - description: clock for I2S bus + - description: clock for I2S controller + + clock-names: + items: + - const: sysclk + - const: bclk + - const: bus + - const: func + + dmas: + minItems: 1 + maxItems: 2 + + dma-names: + oneOf: + - const: rx + - items: + - const: tx + - const: rx + + resets: + maxItems: 1 + + port: + $ref: audio-graph-port.yaml# + unevaluatedProperties: false + + "#sound-dai-cells": + const: 0 + +required: + - compatible + - reg + - clocks + - clock-names + - dmas + - dma-names + - resets + - "#sound-dai-cells" + +unevaluatedProperties: false + +examples: + - | + #include <dt-bindings/clock/spacemit,k1-syscon.h> + i2s@d4026000 { + compatible = "spacemit,k1-i2s"; + reg = <0xd4026000 0x30>; + clocks = <&syscon_mpmu CLK_I2S_SYSCLK>, + <&syscon_mpmu CLK_I2S_BCLK>, + <&syscon_apbc CLK_SSPA0_BUS>, + <&syscon_apbc CLK_SSPA0>; + clock-names = "sysclk", "bclk", "bus", "func"; + dmas = <&pdma0 21>, <&pdma0 22>; + dma-names = "tx", "rx"; + resets = <&syscon_apbc RESET_SSPA0>; + #sound-dai-cells = <0>; + }; -- 2.50.1 _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v2 1/2] ASoC: dt-bindings: Add bindings for SpacemiT K1 @ 2025-08-28 3:37 ` Troy Mitchell 0 siblings, 0 replies; 14+ messages in thread From: Troy Mitchell @ 2025-08-28 3:37 UTC (permalink / raw) To: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Yixun Lan, Jaroslav Kysela, Takashi Iwai, Philipp Zabel Cc: linux-sound, devicetree, linux-riscv, spacemit, linux-kernel, Troy Mitchell Add dt-binding for the i2s driver of SpacemiT's K1 SoC. Signed-off-by: Troy Mitchell <troy.mitchell@linux.spacemit.com> --- .../devicetree/bindings/sound/spacemit,k1-i2s.yaml | 88 ++++++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/Documentation/devicetree/bindings/sound/spacemit,k1-i2s.yaml b/Documentation/devicetree/bindings/sound/spacemit,k1-i2s.yaml new file mode 100644 index 0000000000000000000000000000000000000000..042001c38ed8d434889183831e44289ea9c5aef2 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/spacemit,k1-i2s.yaml @@ -0,0 +1,88 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/spacemit,k1-i2s.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: K1 I2S controller + +description: + The I2S bus (Inter-IC sound bus) is a serial link for digital + audio data transfer between devices in the system. + +maintainers: + - Troy Mitchell <troy.mitchell@linux.spacemit.com> + +allOf: + - $ref: dai-common.yaml# + +properties: + compatible: + const: spacemit,k1-i2s + + reg: + maxItems: 1 + + clocks: + items: + - description: clock for I2S sysclk + - description: clock for I2S bclk + - description: clock for I2S bus + - description: clock for I2S controller + + clock-names: + items: + - const: sysclk + - const: bclk + - const: bus + - const: func + + dmas: + minItems: 1 + maxItems: 2 + + dma-names: + oneOf: + - const: rx + - items: + - const: tx + - const: rx + + resets: + maxItems: 1 + + port: + $ref: audio-graph-port.yaml# + unevaluatedProperties: false + + "#sound-dai-cells": + const: 0 + +required: + - compatible + - reg + - clocks + - clock-names + - dmas + - dma-names + - resets + - "#sound-dai-cells" + +unevaluatedProperties: false + +examples: + - | + #include <dt-bindings/clock/spacemit,k1-syscon.h> + i2s@d4026000 { + compatible = "spacemit,k1-i2s"; + reg = <0xd4026000 0x30>; + clocks = <&syscon_mpmu CLK_I2S_SYSCLK>, + <&syscon_mpmu CLK_I2S_BCLK>, + <&syscon_apbc CLK_SSPA0_BUS>, + <&syscon_apbc CLK_SSPA0>; + clock-names = "sysclk", "bclk", "bus", "func"; + dmas = <&pdma0 21>, <&pdma0 22>; + dma-names = "tx", "rx"; + resets = <&syscon_apbc RESET_SSPA0>; + #sound-dai-cells = <0>; + }; -- 2.50.1 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH v2 1/2] ASoC: dt-bindings: Add bindings for SpacemiT K1 2025-08-28 3:37 ` Troy Mitchell @ 2025-08-29 17:16 ` Rob Herring -1 siblings, 0 replies; 14+ messages in thread From: Rob Herring @ 2025-08-29 17:16 UTC (permalink / raw) To: Troy Mitchell Cc: Liam Girdwood, Mark Brown, Krzysztof Kozlowski, Conor Dooley, Yixun Lan, Jaroslav Kysela, Takashi Iwai, Philipp Zabel, linux-sound, devicetree, linux-riscv, spacemit, linux-kernel On Thu, Aug 28, 2025 at 11:37:32AM +0800, Troy Mitchell wrote: > Add dt-binding for the i2s driver of SpacemiT's K1 SoC. > > Signed-off-by: Troy Mitchell <troy.mitchell@linux.spacemit.com> > --- > .../devicetree/bindings/sound/spacemit,k1-i2s.yaml | 88 ++++++++++++++++++++++ > 1 file changed, 88 insertions(+) > > diff --git a/Documentation/devicetree/bindings/sound/spacemit,k1-i2s.yaml b/Documentation/devicetree/bindings/sound/spacemit,k1-i2s.yaml > new file mode 100644 > index 0000000000000000000000000000000000000000..042001c38ed8d434889183831e44289ea9c5aef2 > --- /dev/null > +++ b/Documentation/devicetree/bindings/sound/spacemit,k1-i2s.yaml > @@ -0,0 +1,88 @@ > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) > +%YAML 1.2 > +--- > +$id: http://devicetree.org/schemas/sound/spacemit,k1-i2s.yaml# > +$schema: http://devicetree.org/meta-schemas/core.yaml# > + > +title: K1 I2S controller > + > +description: > + The I2S bus (Inter-IC sound bus) is a serial link for digital > + audio data transfer between devices in the system. > + > +maintainers: > + - Troy Mitchell <troy.mitchell@linux.spacemit.com> > + > +allOf: > + - $ref: dai-common.yaml# > + > +properties: > + compatible: > + const: spacemit,k1-i2s > + > + reg: > + maxItems: 1 > + > + clocks: > + items: > + - description: clock for I2S sysclk > + - description: clock for I2S bclk > + - description: clock for I2S bus > + - description: clock for I2S controller > + > + clock-names: > + items: > + - const: sysclk > + - const: bclk > + - const: bus > + - const: func > + > + dmas: > + minItems: 1 > + maxItems: 2 > + > + dma-names: > + oneOf: > + - const: rx > + - items: > + - const: tx > + - const: rx If tx is optional, wouldn't this be simpler: minItems: 1 items: - const: rx - const: tx > + > + resets: > + maxItems: 1 > + > + port: > + $ref: audio-graph-port.yaml# > + unevaluatedProperties: false > + > + "#sound-dai-cells": > + const: 0 > + > +required: > + - compatible > + - reg > + - clocks > + - clock-names > + - dmas > + - dma-names > + - resets > + - "#sound-dai-cells" > + > +unevaluatedProperties: false > + > +examples: > + - | > + #include <dt-bindings/clock/spacemit,k1-syscon.h> > + i2s@d4026000 { > + compatible = "spacemit,k1-i2s"; > + reg = <0xd4026000 0x30>; > + clocks = <&syscon_mpmu CLK_I2S_SYSCLK>, > + <&syscon_mpmu CLK_I2S_BCLK>, > + <&syscon_apbc CLK_SSPA0_BUS>, > + <&syscon_apbc CLK_SSPA0>; > + clock-names = "sysclk", "bclk", "bus", "func"; > + dmas = <&pdma0 21>, <&pdma0 22>; > + dma-names = "tx", "rx"; > + resets = <&syscon_apbc RESET_SSPA0>; > + #sound-dai-cells = <0>; > + }; > > -- > 2.50.1 > _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v2 1/2] ASoC: dt-bindings: Add bindings for SpacemiT K1 @ 2025-08-29 17:16 ` Rob Herring 0 siblings, 0 replies; 14+ messages in thread From: Rob Herring @ 2025-08-29 17:16 UTC (permalink / raw) To: Troy Mitchell Cc: Liam Girdwood, Mark Brown, Krzysztof Kozlowski, Conor Dooley, Yixun Lan, Jaroslav Kysela, Takashi Iwai, Philipp Zabel, linux-sound, devicetree, linux-riscv, spacemit, linux-kernel On Thu, Aug 28, 2025 at 11:37:32AM +0800, Troy Mitchell wrote: > Add dt-binding for the i2s driver of SpacemiT's K1 SoC. > > Signed-off-by: Troy Mitchell <troy.mitchell@linux.spacemit.com> > --- > .../devicetree/bindings/sound/spacemit,k1-i2s.yaml | 88 ++++++++++++++++++++++ > 1 file changed, 88 insertions(+) > > diff --git a/Documentation/devicetree/bindings/sound/spacemit,k1-i2s.yaml b/Documentation/devicetree/bindings/sound/spacemit,k1-i2s.yaml > new file mode 100644 > index 0000000000000000000000000000000000000000..042001c38ed8d434889183831e44289ea9c5aef2 > --- /dev/null > +++ b/Documentation/devicetree/bindings/sound/spacemit,k1-i2s.yaml > @@ -0,0 +1,88 @@ > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) > +%YAML 1.2 > +--- > +$id: http://devicetree.org/schemas/sound/spacemit,k1-i2s.yaml# > +$schema: http://devicetree.org/meta-schemas/core.yaml# > + > +title: K1 I2S controller > + > +description: > + The I2S bus (Inter-IC sound bus) is a serial link for digital > + audio data transfer between devices in the system. > + > +maintainers: > + - Troy Mitchell <troy.mitchell@linux.spacemit.com> > + > +allOf: > + - $ref: dai-common.yaml# > + > +properties: > + compatible: > + const: spacemit,k1-i2s > + > + reg: > + maxItems: 1 > + > + clocks: > + items: > + - description: clock for I2S sysclk > + - description: clock for I2S bclk > + - description: clock for I2S bus > + - description: clock for I2S controller > + > + clock-names: > + items: > + - const: sysclk > + - const: bclk > + - const: bus > + - const: func > + > + dmas: > + minItems: 1 > + maxItems: 2 > + > + dma-names: > + oneOf: > + - const: rx > + - items: > + - const: tx > + - const: rx If tx is optional, wouldn't this be simpler: minItems: 1 items: - const: rx - const: tx > + > + resets: > + maxItems: 1 > + > + port: > + $ref: audio-graph-port.yaml# > + unevaluatedProperties: false > + > + "#sound-dai-cells": > + const: 0 > + > +required: > + - compatible > + - reg > + - clocks > + - clock-names > + - dmas > + - dma-names > + - resets > + - "#sound-dai-cells" > + > +unevaluatedProperties: false > + > +examples: > + - | > + #include <dt-bindings/clock/spacemit,k1-syscon.h> > + i2s@d4026000 { > + compatible = "spacemit,k1-i2s"; > + reg = <0xd4026000 0x30>; > + clocks = <&syscon_mpmu CLK_I2S_SYSCLK>, > + <&syscon_mpmu CLK_I2S_BCLK>, > + <&syscon_apbc CLK_SSPA0_BUS>, > + <&syscon_apbc CLK_SSPA0>; > + clock-names = "sysclk", "bclk", "bus", "func"; > + dmas = <&pdma0 21>, <&pdma0 22>; > + dma-names = "tx", "rx"; > + resets = <&syscon_apbc RESET_SSPA0>; > + #sound-dai-cells = <0>; > + }; > > -- > 2.50.1 > ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v2 1/2] ASoC: dt-bindings: Add bindings for SpacemiT K1 2025-08-29 17:16 ` Rob Herring @ 2025-09-02 1:36 ` Troy Mitchell -1 siblings, 0 replies; 14+ messages in thread From: Troy Mitchell @ 2025-09-02 1:36 UTC (permalink / raw) To: Rob Herring, Troy Mitchell Cc: Liam Girdwood, Mark Brown, Krzysztof Kozlowski, Conor Dooley, Yixun Lan, Jaroslav Kysela, Takashi Iwai, Philipp Zabel, linux-sound, devicetree, linux-riscv, spacemit, linux-kernel On Fri, Aug 29, 2025 at 12:16:24PM -0500, Rob Herring wrote: > On Thu, Aug 28, 2025 at 11:37:32AM +0800, Troy Mitchell wrote: > > Add dt-binding for the i2s driver of SpacemiT's K1 SoC. > > > > Signed-off-by: Troy Mitchell <troy.mitchell@linux.spacemit.com> > > --- > > .../devicetree/bindings/sound/spacemit,k1-i2s.yaml | 88 ++++++++++++++++++++++ > > 1 file changed, 88 insertions(+) > > > > diff --git a/Documentation/devicetree/bindings/sound/spacemit,k1-i2s.yaml b/Documentation/devicetree/bindings/sound/spacemit,k1-i2s.yaml > > new file mode 100644 > > index 0000000000000000000000000000000000000000..042001c38ed8d434889183831e44289ea9c5aef2 > > --- /dev/null > > +++ b/Documentation/devicetree/bindings/sound/spacemit,k1-i2s.yaml [...] > > + dmas: > > + minItems: 1 > > + maxItems: 2 > > + > > + dma-names: > > + oneOf: > > + - const: rx > > + - items: > > + - const: tx > > + - const: rx > > If tx is optional, wouldn't this be simpler: > > minItems: 1 > items: > - const: rx > - const: tx > Thanks! I will simplify this in the next version - Troy > > > + > > + resets: > > + maxItems: 1 > > + > > + port: > > + $ref: audio-graph-port.yaml# > > + unevaluatedProperties: false > > + > > + "#sound-dai-cells": > > + const: 0 > > + > > +required: > > + - compatible > > + - reg > > + - clocks > > + - clock-names > > + - dmas > > + - dma-names > > + - resets > > + - "#sound-dai-cells" > > + > > +unevaluatedProperties: false > > + > > +examples: > > + - | > > + #include <dt-bindings/clock/spacemit,k1-syscon.h> > > + i2s@d4026000 { > > + compatible = "spacemit,k1-i2s"; > > + reg = <0xd4026000 0x30>; > > + clocks = <&syscon_mpmu CLK_I2S_SYSCLK>, > > + <&syscon_mpmu CLK_I2S_BCLK>, > > + <&syscon_apbc CLK_SSPA0_BUS>, > > + <&syscon_apbc CLK_SSPA0>; > > + clock-names = "sysclk", "bclk", "bus", "func"; > > + dmas = <&pdma0 21>, <&pdma0 22>; > > + dma-names = "tx", "rx"; > > + resets = <&syscon_apbc RESET_SSPA0>; > > + #sound-dai-cells = <0>; > > + }; > > > > -- > > 2.50.1 > > > _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v2 1/2] ASoC: dt-bindings: Add bindings for SpacemiT K1 @ 2025-09-02 1:36 ` Troy Mitchell 0 siblings, 0 replies; 14+ messages in thread From: Troy Mitchell @ 2025-09-02 1:36 UTC (permalink / raw) To: Rob Herring, Troy Mitchell Cc: Liam Girdwood, Mark Brown, Krzysztof Kozlowski, Conor Dooley, Yixun Lan, Jaroslav Kysela, Takashi Iwai, Philipp Zabel, linux-sound, devicetree, linux-riscv, spacemit, linux-kernel On Fri, Aug 29, 2025 at 12:16:24PM -0500, Rob Herring wrote: > On Thu, Aug 28, 2025 at 11:37:32AM +0800, Troy Mitchell wrote: > > Add dt-binding for the i2s driver of SpacemiT's K1 SoC. > > > > Signed-off-by: Troy Mitchell <troy.mitchell@linux.spacemit.com> > > --- > > .../devicetree/bindings/sound/spacemit,k1-i2s.yaml | 88 ++++++++++++++++++++++ > > 1 file changed, 88 insertions(+) > > > > diff --git a/Documentation/devicetree/bindings/sound/spacemit,k1-i2s.yaml b/Documentation/devicetree/bindings/sound/spacemit,k1-i2s.yaml > > new file mode 100644 > > index 0000000000000000000000000000000000000000..042001c38ed8d434889183831e44289ea9c5aef2 > > --- /dev/null > > +++ b/Documentation/devicetree/bindings/sound/spacemit,k1-i2s.yaml [...] > > + dmas: > > + minItems: 1 > > + maxItems: 2 > > + > > + dma-names: > > + oneOf: > > + - const: rx > > + - items: > > + - const: tx > > + - const: rx > > If tx is optional, wouldn't this be simpler: > > minItems: 1 > items: > - const: rx > - const: tx > Thanks! I will simplify this in the next version - Troy > > > + > > + resets: > > + maxItems: 1 > > + > > + port: > > + $ref: audio-graph-port.yaml# > > + unevaluatedProperties: false > > + > > + "#sound-dai-cells": > > + const: 0 > > + > > +required: > > + - compatible > > + - reg > > + - clocks > > + - clock-names > > + - dmas > > + - dma-names > > + - resets > > + - "#sound-dai-cells" > > + > > +unevaluatedProperties: false > > + > > +examples: > > + - | > > + #include <dt-bindings/clock/spacemit,k1-syscon.h> > > + i2s@d4026000 { > > + compatible = "spacemit,k1-i2s"; > > + reg = <0xd4026000 0x30>; > > + clocks = <&syscon_mpmu CLK_I2S_SYSCLK>, > > + <&syscon_mpmu CLK_I2S_BCLK>, > > + <&syscon_apbc CLK_SSPA0_BUS>, > > + <&syscon_apbc CLK_SSPA0>; > > + clock-names = "sysclk", "bclk", "bus", "func"; > > + dmas = <&pdma0 21>, <&pdma0 22>; > > + dma-names = "tx", "rx"; > > + resets = <&syscon_apbc RESET_SSPA0>; > > + #sound-dai-cells = <0>; > > + }; > > > > -- > > 2.50.1 > > > ^ permalink raw reply [flat|nested] 14+ messages in thread
* [PATCH v2 2/2] ASoC: spacemit: add i2s support for K1 SoC 2025-08-28 3:37 ` Troy Mitchell @ 2025-08-28 3:37 ` Troy Mitchell -1 siblings, 0 replies; 14+ messages in thread From: Troy Mitchell @ 2025-08-28 3:37 UTC (permalink / raw) To: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Yixun Lan, Jaroslav Kysela, Takashi Iwai, Philipp Zabel Cc: linux-sound, devicetree, linux-riscv, spacemit, linux-kernel, Troy Mitchell, Jinmei Wei Add ASoC platform driver for the SpacemiT K1 SoC full-duplex I2S controller. Co-developer: Jinmei Wei <weijinmei@linux.spacemit.com> Signed-off-by: Jinmei Wei <weijinmei@linux.spacemit.com> Signed-off-by: Troy Mitchell <troy.mitchell@linux.spacemit.com> --- sound/soc/Kconfig | 1 + sound/soc/Makefile | 1 + sound/soc/spacemit/Kconfig | 16 ++ sound/soc/spacemit/Makefile | 5 + sound/soc/spacemit/k1_i2s.c | 452 ++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 475 insertions(+) diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig index ce74818bd7152dbe110b9fff7d908b0ddf34a9f5..36e0d443ba0ebe584ffe797c378c838f448ffcb9 100644 --- a/sound/soc/Kconfig +++ b/sound/soc/Kconfig @@ -127,6 +127,7 @@ source "sound/soc/renesas/Kconfig" source "sound/soc/rockchip/Kconfig" source "sound/soc/samsung/Kconfig" source "sound/soc/sdca/Kconfig" +source "sound/soc/spacemit/Kconfig" source "sound/soc/spear/Kconfig" source "sound/soc/sprd/Kconfig" source "sound/soc/starfive/Kconfig" diff --git a/sound/soc/Makefile b/sound/soc/Makefile index 462322c38aa42d4c394736239de0317d5918d5a7..8c0480e6484e75eb0b6db306630ba77d259ba8e3 100644 --- a/sound/soc/Makefile +++ b/sound/soc/Makefile @@ -70,6 +70,7 @@ obj-$(CONFIG_SND_SOC) += rockchip/ obj-$(CONFIG_SND_SOC) += samsung/ obj-$(CONFIG_SND_SOC) += sdca/ obj-$(CONFIG_SND_SOC) += sof/ +obj-$(CONFIG_SND_SOC) += spacemit/ obj-$(CONFIG_SND_SOC) += spear/ obj-$(CONFIG_SND_SOC) += sprd/ obj-$(CONFIG_SND_SOC) += starfive/ diff --git a/sound/soc/spacemit/Kconfig b/sound/soc/spacemit/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..2179f94f3f179c54cd06e6ced5523ed3f5225cf4 --- /dev/null +++ b/sound/soc/spacemit/Kconfig @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: GPL-2.0-only +menu "SpacemiT" + depends on COMPILE_TEST || ARCH_SPACEMIT + depends on HAVE_CLK + +config SND_SOC_K1_I2S + tristate "K1 I2S Device Driver" + select SND_SOC_GENERIC_DMAENGINE_PCM + select CMA + select DMA_CMA + help + Say Y or M if you want to add support for I2S driver for + K1 I2S controller. The device supports up to maximum of + 2 channels each for play and record. + +endmenu diff --git a/sound/soc/spacemit/Makefile b/sound/soc/spacemit/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..9069de8ef89c84db8cc7d3a4d3b154fff9bd7aff --- /dev/null +++ b/sound/soc/spacemit/Makefile @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0 +# K1 Platform Support +snd-soc-k1-i2s-y := k1_i2s.o + +obj-$(CONFIG_SND_SOC_K1_I2S) += snd-soc-k1-i2s.o diff --git a/sound/soc/spacemit/k1_i2s.c b/sound/soc/spacemit/k1_i2s.c new file mode 100644 index 0000000000000000000000000000000000000000..1657e2db6f36edeeeb1a6dc1fc4cca6be08a5bed --- /dev/null +++ b/sound/soc/spacemit/k1_i2s.c @@ -0,0 +1,452 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2025 Troy Mitchell <troy.mitchell@linux.spacemit.com> */ + +#include <linux/bitfield.h> +#include <linux/clk.h> +#include <linux/reset.h> +#include <sound/dmaengine_pcm.h> +#include <sound/pcm.h> +#include <sound/pcm_params.h> + +#define SSCR 0x00 /* SPI/I2S top control register */ +#define SSFCR 0x04 /* SPI/I2S FIFO control register */ +#define SSINTEN 0x08 /* SPI/I2S interrupt enable register */ +#define SSDATR 0x10 /* SPI/I2S data register */ +#define SSPSP 0x18 /* SPI/I2S programmable serial protocol control register */ +#define SSRWT 0x24 /* SPI/I2S root control register */ + +/* SPI/I2S Work data size, register bits value 0~31 indicated data size 1~32 bits */ +#define SSCR_FIELD_DSS GENMASK(9, 5) +#define SSCR_DW_8BYTE FIELD_PREP(SSCR_FIELD_DSS, 0x7) +#define SSCR_DW_16BYTE FIELD_PREP(SSCR_FIELD_DSS, 0xf) +#define SSCR_DW_18BYTE FIELD_PREP(SSCR_FIELD_DSS, 0x11) +#define SSCR_DW_32BYTE FIELD_PREP(SSCR_FIELD_DSS, 0x1f) + +#define SSCR_SSE BIT(0) /* SPI/I2S Enable */ +#define SSCR_FRF_PSP GENMASK(2, 1) /* Frame Format*/ +#define SSCR_TRAIL BIT(13) /* Trailing Byte */ + +#define SSFCR_FIELD_TFT GENMASK(3, 0) /* TXFIFO Trigger Threshold */ +#define SSFCR_FIELD_RFT GENMASK(8, 5) /* RXFIFO Trigger Threshold */ +#define SSFCR_TSRE BIT(10) /* Transmit Service Request Enable */ +#define SSFCR_RSRE BIT(11) /* Receive Service Request Enable */ + +#define SSPSP_FSRT BIT(3) /* Frame Sync Relative Timing Bit */ +#define SSPSP_SFRMP BIT(4) /* Serial Frame Polarity */ +#define SSPSP_FIELD_SFRMWDTH GENMASK(17, 12) /* Serial Frame Width field */ + +#define SSRWT_RWOT BIT(0) /* Receive Without Transmit */ + +#define SPACEMIT_PCM_RATES SNDRV_PCM_RATE_8000_192000 +#define SPACEMIT_PCM_FORMATS (SNDRV_PCM_FMTBIT_S8 | \ + SNDRV_PCM_FMTBIT_S16_LE | \ + SNDRV_PCM_FMTBIT_S24_LE | \ + SNDRV_PCM_FMTBIT_S32_LE) + +#define SPACEMIT_I2S_PERIOD_SIZE 1024 + +struct spacemit_i2s_dev { + struct device *dev; + + void __iomem *base; + + struct reset_control *reset; + + struct clk *sysclk; + struct clk *bclk; + struct clk *sspa_clk; + + struct snd_dmaengine_dai_dma_data capture_dma_data; + struct snd_dmaengine_dai_dma_data playback_dma_data; + + bool has_capture; + bool has_playback; + + int dai_fmt; + + int started_count; +}; + +static const struct snd_pcm_hardware spacemit_pcm_hardware = { + .info = SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_BATCH, + .formats = SPACEMIT_PCM_FORMATS, + .rates = SPACEMIT_PCM_RATES, + .rate_min = SNDRV_PCM_RATE_8000, + .rate_max = SNDRV_PCM_RATE_192000, + .channels_min = 1, + .channels_max = 2, + .buffer_bytes_max = SPACEMIT_I2S_PERIOD_SIZE * 4 * 4, + .period_bytes_min = SPACEMIT_I2S_PERIOD_SIZE * 2, + .period_bytes_max = SPACEMIT_I2S_PERIOD_SIZE * 4, + .periods_min = 2, + .periods_max = 4, +}; + +static const struct snd_dmaengine_pcm_config spacemit_dmaengine_pcm_config = { + .pcm_hardware = &spacemit_pcm_hardware, + .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config, + .chan_names = {"tx", "rx"}, + .prealloc_buffer_size = 32 * 1024, +}; + +static void spacemit_i2s_init(struct spacemit_i2s_dev *i2s) +{ + u32 sscr_val, sspsp_val, ssfcr_val, ssrwt_val; + + sscr_val = SSCR_TRAIL | SSCR_FRF_PSP; + ssfcr_val = FIELD_PREP(SSFCR_FIELD_TFT, 5) | + FIELD_PREP(SSFCR_FIELD_RFT, 5) | + SSFCR_RSRE | SSFCR_TSRE; + ssrwt_val = SSRWT_RWOT; + + /* SSPSP register was set by set_fmt */ + sspsp_val = readl(i2s->base + SSPSP); + sspsp_val |= SSPSP_SFRMP; + + writel(sscr_val, i2s->base + SSCR); + writel(ssfcr_val, i2s->base + SSFCR); + writel(sspsp_val, i2s->base + SSPSP); + writel(ssrwt_val, i2s->base + SSRWT); + writel(0, i2s->base + SSINTEN); +} + +static int spacemit_i2s_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct spacemit_i2s_dev *i2s = snd_soc_dai_get_drvdata(dai); + struct snd_dmaengine_dai_dma_data *dma_data; + u32 data_width, data_bits; + unsigned long bclk_rate; + u32 val; + int ret; + + val = readl(i2s->base + SSCR); + if (val & SSCR_SSE) + return 0; + + dma_data = &i2s->playback_dma_data; + + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + dma_data = &i2s->capture_dma_data; + + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S8: + data_bits = 8; + data_width = SSCR_DW_8BYTE; + dma_data->maxburst = 8; + dma_data->addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; + break; + case SNDRV_PCM_FORMAT_S16_LE: + data_bits = 16; + data_width = SSCR_DW_16BYTE; + dma_data->maxburst = 16; + dma_data->addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; + if ((i2s->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_I2S) { + data_width = SSCR_DW_32BYTE; + dma_data->maxburst = 32; + dma_data->addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; + } + break; + case SNDRV_PCM_FORMAT_S32_LE: + data_bits = 32; + data_width = SSCR_DW_32BYTE; + dma_data->maxburst = 32; + dma_data->addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; + break; + default: + dev_dbg(i2s->dev, "unexpected data width type"); + return -EINVAL; + } + + val = readl(i2s->base + SSCR); + val &= ~SSCR_DW_32BYTE; + val |= data_width; + writel(val, i2s->base + SSCR); + + bclk_rate = params_channels(params) * + params_rate(params) * + data_bits; + + ret = clk_set_rate(i2s->bclk, bclk_rate); + if (ret) + return ret; + + return clk_set_rate(i2s->sspa_clk, bclk_rate); +} + +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); + + if (freq == 0) + return 0; + + return clk_set_rate(i2s->sysclk, freq); +} + +static int spacemit_i2s_set_fmt(struct snd_soc_dai *cpu_dai, + unsigned int fmt) +{ + struct spacemit_i2s_dev *i2s = dev_get_drvdata(cpu_dai->dev); + u32 sspsp_val; + + sspsp_val = readl(i2s->base + SSPSP); + sspsp_val &= ~SSPSP_FIELD_SFRMWDTH; + + i2s->dai_fmt = fmt; + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + cpu_dai->driver->playback.formats = SNDRV_PCM_FMTBIT_S16_LE; + cpu_dai->driver->capture.formats = SNDRV_PCM_FMTBIT_S16_LE; + sspsp_val |= FIELD_PREP(SSPSP_FIELD_SFRMWDTH, 0x10) | + SSPSP_FSRT; + break; + case SND_SOC_DAIFMT_DSP_A: + case SND_SOC_DAIFMT_DSP_B: + cpu_dai->driver->playback.channels_min = 1; + cpu_dai->driver->playback.channels_max = 1; + cpu_dai->driver->capture.channels_min = 1; + cpu_dai->driver->capture.channels_max = 1; + cpu_dai->driver->playback.formats = SNDRV_PCM_FMTBIT_S32_LE; + cpu_dai->driver->capture.formats = SNDRV_PCM_FMTBIT_S32_LE; + sspsp_val |= FIELD_PREP(SSPSP_FIELD_SFRMWDTH, 0x1); + break; + default: + dev_dbg(i2s->dev, "unexpected format type"); + return -EINVAL; + } + + if ((fmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_DSP_A) + sspsp_val |= SSPSP_FSRT; + + writel(sspsp_val, i2s->base + SSPSP); + + return 0; +} + +static int spacemit_i2s_trigger(struct snd_pcm_substream *substream, + int cmd, struct snd_soc_dai *dai) +{ + struct spacemit_i2s_dev *i2s = snd_soc_dai_get_drvdata(dai); + u32 val; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + if (!i2s->started_count) { + val = readl(i2s->base + SSCR); + val |= SSCR_SSE; + writel(val, i2s->base + SSCR); + } + i2s->started_count++; + break; + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + if (i2s->started_count) + i2s->started_count--; + + if (!i2s->started_count) { + val = readl(i2s->base + SSCR); + val &= ~SSCR_SSE; + writel(val, i2s->base + SSCR); + } + break; + default: + return -EINVAL; + } + + return 0; +} + +static int spacemit_i2s_dai_probe(struct snd_soc_dai *dai) +{ + struct spacemit_i2s_dev *i2s = snd_soc_dai_get_drvdata(dai); + + snd_soc_dai_init_dma_data(dai, + i2s->has_playback ? &i2s->playback_dma_data : NULL, + i2s->has_capture ? &i2s->capture_dma_data : NULL); + + reset_control_deassert(i2s->reset); + + spacemit_i2s_init(i2s); + + return 0; +} + +static int spacemit_i2s_dai_remove(struct snd_soc_dai *dai) +{ + struct spacemit_i2s_dev *i2s = snd_soc_dai_get_drvdata(dai); + + reset_control_assert(i2s->reset); + + return 0; +} + +static const struct snd_soc_dai_ops spacemit_i2s_dai_ops = { + .probe = spacemit_i2s_dai_probe, + .remove = spacemit_i2s_dai_remove, + .hw_params = spacemit_i2s_hw_params, + .set_sysclk = spacemit_i2s_set_sysclk, + .set_fmt = spacemit_i2s_set_fmt, + .trigger = spacemit_i2s_trigger, +}; + +static struct snd_soc_dai_driver spacemit_i2s_dai = { + .ops = &spacemit_i2s_dai_ops, + .playback = { + .channels_min = 1, + .channels_max = 2, + .rates = SPACEMIT_PCM_RATES, + .rate_min = SNDRV_PCM_RATE_8000, + .rate_max = SNDRV_PCM_RATE_192000, + .formats = SPACEMIT_PCM_FORMATS, + }, + .capture = { + .channels_min = 1, + .channels_max = 2, + .rates = SPACEMIT_PCM_RATES, + .rate_min = SNDRV_PCM_RATE_8000, + .rate_max = SNDRV_PCM_RATE_192000, + .formats = SPACEMIT_PCM_FORMATS, + }, + .symmetric_rate = 1, +}; + +static int spacemit_i2s_init_dai(struct spacemit_i2s_dev *i2s, + struct snd_soc_dai_driver **dp, + dma_addr_t addr) +{ + struct device_node *node = i2s->dev->of_node; + struct snd_soc_dai_driver *dai; + struct property *dma_names; + const char *dma_name; + + of_property_for_each_string(node, "dma-names", dma_names, dma_name) { + if (!strcmp(dma_name, "tx")) + i2s->has_playback = true; + if (!strcmp(dma_name, "rx")) + i2s->has_capture = true; + } + + dai = devm_kmemdup(i2s->dev, &spacemit_i2s_dai, + sizeof(*dai), GFP_KERNEL); + if (!dai) + return -ENOMEM; + + if (i2s->has_playback) { + dai->playback.stream_name = "Playback"; + dai->playback.channels_min = 1; + dai->playback.channels_max = 2; + dai->playback.rates = SPACEMIT_PCM_RATES; + dai->playback.formats = SPACEMIT_PCM_FORMATS; + + i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; + i2s->playback_dma_data.maxburst = 32; + i2s->playback_dma_data.addr = addr; + } + + if (i2s->has_capture) { + dai->capture.stream_name = "Capture"; + dai->capture.channels_min = 1; + dai->capture.channels_max = 2; + dai->capture.rates = SPACEMIT_PCM_RATES; + dai->capture.formats = SPACEMIT_PCM_FORMATS; + + i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; + i2s->capture_dma_data.maxburst = 32; + i2s->capture_dma_data.addr = addr; + } + + if (dp) + *dp = dai; + + return 0; +} + +static const struct snd_soc_component_driver spacemit_i2s_component = { + .name = "i2s-k1", + .legacy_dai_naming = 1, +}; + +static int spacemit_i2s_probe(struct platform_device *pdev) +{ + struct snd_soc_dai_driver *dai; + struct spacemit_i2s_dev *i2s; + struct resource *res; + struct clk *clk; + int ret; + + i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL); + if (!i2s) + return -ENOMEM; + + i2s->dev = &pdev->dev; + + i2s->sysclk = devm_clk_get_enabled(i2s->dev, "sysclk"); + if (IS_ERR(i2s->sysclk)) + return dev_err_probe(i2s->dev, PTR_ERR(i2s->sysclk), + "failed to enable sysbase clock\n"); + + i2s->bclk = devm_clk_get_enabled(i2s->dev, "bclk"); + if (IS_ERR(i2s->bclk)) + return dev_err_probe(i2s->dev, PTR_ERR(i2s->bclk), "failed to enable bit clock\n"); + + clk = devm_clk_get_enabled(i2s->dev, "sspa_bus"); + if (IS_ERR(clk)) + return dev_err_probe(i2s->dev, PTR_ERR(clk), "failed to enable sspa_bus clock\n"); + + i2s->sspa_clk = devm_clk_get_enabled(i2s->dev, "sspa"); + if (IS_ERR(clk)) + return dev_err_probe(i2s->dev, PTR_ERR(clk), "failed to enable sspa 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"); + + i2s->reset = devm_reset_control_get_exclusive(&pdev->dev, NULL); + if (IS_ERR(i2s->reset)) + return dev_err_probe(i2s->dev, PTR_ERR(i2s->reset), + "failed to get reset control"); + + dev_set_drvdata(i2s->dev, i2s); + + spacemit_i2s_init_dai(i2s, &dai, res->start + SSDATR); + + ret = devm_snd_soc_register_component(i2s->dev, + &spacemit_i2s_component, + dai, 1); + if (ret) + return dev_err_probe(i2s->dev, ret, "failed to register component"); + + return devm_snd_dmaengine_pcm_register(&pdev->dev, &spacemit_dmaengine_pcm_config, 0); +} + +static void spacemit_i2s_remove(struct platform_device *pdev) +{ + /* resources auto-freed by devm_ */ +} + +static const struct of_device_id spacemit_i2s_of_match[] = { + { .compatible = "spacemit,k1-i2s", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, spacemit_i2s_of_match); + +static struct platform_driver spacemit_i2s_driver = { + .probe = spacemit_i2s_probe, + .remove = spacemit_i2s_remove, + .driver = { + .name = "i2s-k1", + .of_match_table = spacemit_i2s_of_match, + }, +}; +module_platform_driver(spacemit_i2s_driver); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("I2S bus driver for SpacemiT K1 SoC"); -- 2.50.1 _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply related [flat|nested] 14+ messages in thread
* [PATCH v2 2/2] ASoC: spacemit: add i2s support for K1 SoC @ 2025-08-28 3:37 ` Troy Mitchell 0 siblings, 0 replies; 14+ messages in thread From: Troy Mitchell @ 2025-08-28 3:37 UTC (permalink / raw) To: Liam Girdwood, Mark Brown, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Yixun Lan, Jaroslav Kysela, Takashi Iwai, Philipp Zabel Cc: linux-sound, devicetree, linux-riscv, spacemit, linux-kernel, Troy Mitchell, Jinmei Wei Add ASoC platform driver for the SpacemiT K1 SoC full-duplex I2S controller. Co-developer: Jinmei Wei <weijinmei@linux.spacemit.com> Signed-off-by: Jinmei Wei <weijinmei@linux.spacemit.com> Signed-off-by: Troy Mitchell <troy.mitchell@linux.spacemit.com> --- sound/soc/Kconfig | 1 + sound/soc/Makefile | 1 + sound/soc/spacemit/Kconfig | 16 ++ sound/soc/spacemit/Makefile | 5 + sound/soc/spacemit/k1_i2s.c | 452 ++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 475 insertions(+) diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig index ce74818bd7152dbe110b9fff7d908b0ddf34a9f5..36e0d443ba0ebe584ffe797c378c838f448ffcb9 100644 --- a/sound/soc/Kconfig +++ b/sound/soc/Kconfig @@ -127,6 +127,7 @@ source "sound/soc/renesas/Kconfig" source "sound/soc/rockchip/Kconfig" source "sound/soc/samsung/Kconfig" source "sound/soc/sdca/Kconfig" +source "sound/soc/spacemit/Kconfig" source "sound/soc/spear/Kconfig" source "sound/soc/sprd/Kconfig" source "sound/soc/starfive/Kconfig" diff --git a/sound/soc/Makefile b/sound/soc/Makefile index 462322c38aa42d4c394736239de0317d5918d5a7..8c0480e6484e75eb0b6db306630ba77d259ba8e3 100644 --- a/sound/soc/Makefile +++ b/sound/soc/Makefile @@ -70,6 +70,7 @@ obj-$(CONFIG_SND_SOC) += rockchip/ obj-$(CONFIG_SND_SOC) += samsung/ obj-$(CONFIG_SND_SOC) += sdca/ obj-$(CONFIG_SND_SOC) += sof/ +obj-$(CONFIG_SND_SOC) += spacemit/ obj-$(CONFIG_SND_SOC) += spear/ obj-$(CONFIG_SND_SOC) += sprd/ obj-$(CONFIG_SND_SOC) += starfive/ diff --git a/sound/soc/spacemit/Kconfig b/sound/soc/spacemit/Kconfig new file mode 100644 index 0000000000000000000000000000000000000000..2179f94f3f179c54cd06e6ced5523ed3f5225cf4 --- /dev/null +++ b/sound/soc/spacemit/Kconfig @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: GPL-2.0-only +menu "SpacemiT" + depends on COMPILE_TEST || ARCH_SPACEMIT + depends on HAVE_CLK + +config SND_SOC_K1_I2S + tristate "K1 I2S Device Driver" + select SND_SOC_GENERIC_DMAENGINE_PCM + select CMA + select DMA_CMA + help + Say Y or M if you want to add support for I2S driver for + K1 I2S controller. The device supports up to maximum of + 2 channels each for play and record. + +endmenu diff --git a/sound/soc/spacemit/Makefile b/sound/soc/spacemit/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..9069de8ef89c84db8cc7d3a4d3b154fff9bd7aff --- /dev/null +++ b/sound/soc/spacemit/Makefile @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0 +# K1 Platform Support +snd-soc-k1-i2s-y := k1_i2s.o + +obj-$(CONFIG_SND_SOC_K1_I2S) += snd-soc-k1-i2s.o diff --git a/sound/soc/spacemit/k1_i2s.c b/sound/soc/spacemit/k1_i2s.c new file mode 100644 index 0000000000000000000000000000000000000000..1657e2db6f36edeeeb1a6dc1fc4cca6be08a5bed --- /dev/null +++ b/sound/soc/spacemit/k1_i2s.c @@ -0,0 +1,452 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2025 Troy Mitchell <troy.mitchell@linux.spacemit.com> */ + +#include <linux/bitfield.h> +#include <linux/clk.h> +#include <linux/reset.h> +#include <sound/dmaengine_pcm.h> +#include <sound/pcm.h> +#include <sound/pcm_params.h> + +#define SSCR 0x00 /* SPI/I2S top control register */ +#define SSFCR 0x04 /* SPI/I2S FIFO control register */ +#define SSINTEN 0x08 /* SPI/I2S interrupt enable register */ +#define SSDATR 0x10 /* SPI/I2S data register */ +#define SSPSP 0x18 /* SPI/I2S programmable serial protocol control register */ +#define SSRWT 0x24 /* SPI/I2S root control register */ + +/* SPI/I2S Work data size, register bits value 0~31 indicated data size 1~32 bits */ +#define SSCR_FIELD_DSS GENMASK(9, 5) +#define SSCR_DW_8BYTE FIELD_PREP(SSCR_FIELD_DSS, 0x7) +#define SSCR_DW_16BYTE FIELD_PREP(SSCR_FIELD_DSS, 0xf) +#define SSCR_DW_18BYTE FIELD_PREP(SSCR_FIELD_DSS, 0x11) +#define SSCR_DW_32BYTE FIELD_PREP(SSCR_FIELD_DSS, 0x1f) + +#define SSCR_SSE BIT(0) /* SPI/I2S Enable */ +#define SSCR_FRF_PSP GENMASK(2, 1) /* Frame Format*/ +#define SSCR_TRAIL BIT(13) /* Trailing Byte */ + +#define SSFCR_FIELD_TFT GENMASK(3, 0) /* TXFIFO Trigger Threshold */ +#define SSFCR_FIELD_RFT GENMASK(8, 5) /* RXFIFO Trigger Threshold */ +#define SSFCR_TSRE BIT(10) /* Transmit Service Request Enable */ +#define SSFCR_RSRE BIT(11) /* Receive Service Request Enable */ + +#define SSPSP_FSRT BIT(3) /* Frame Sync Relative Timing Bit */ +#define SSPSP_SFRMP BIT(4) /* Serial Frame Polarity */ +#define SSPSP_FIELD_SFRMWDTH GENMASK(17, 12) /* Serial Frame Width field */ + +#define SSRWT_RWOT BIT(0) /* Receive Without Transmit */ + +#define SPACEMIT_PCM_RATES SNDRV_PCM_RATE_8000_192000 +#define SPACEMIT_PCM_FORMATS (SNDRV_PCM_FMTBIT_S8 | \ + SNDRV_PCM_FMTBIT_S16_LE | \ + SNDRV_PCM_FMTBIT_S24_LE | \ + SNDRV_PCM_FMTBIT_S32_LE) + +#define SPACEMIT_I2S_PERIOD_SIZE 1024 + +struct spacemit_i2s_dev { + struct device *dev; + + void __iomem *base; + + struct reset_control *reset; + + struct clk *sysclk; + struct clk *bclk; + struct clk *sspa_clk; + + struct snd_dmaengine_dai_dma_data capture_dma_data; + struct snd_dmaengine_dai_dma_data playback_dma_data; + + bool has_capture; + bool has_playback; + + int dai_fmt; + + int started_count; +}; + +static const struct snd_pcm_hardware spacemit_pcm_hardware = { + .info = SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_BATCH, + .formats = SPACEMIT_PCM_FORMATS, + .rates = SPACEMIT_PCM_RATES, + .rate_min = SNDRV_PCM_RATE_8000, + .rate_max = SNDRV_PCM_RATE_192000, + .channels_min = 1, + .channels_max = 2, + .buffer_bytes_max = SPACEMIT_I2S_PERIOD_SIZE * 4 * 4, + .period_bytes_min = SPACEMIT_I2S_PERIOD_SIZE * 2, + .period_bytes_max = SPACEMIT_I2S_PERIOD_SIZE * 4, + .periods_min = 2, + .periods_max = 4, +}; + +static const struct snd_dmaengine_pcm_config spacemit_dmaengine_pcm_config = { + .pcm_hardware = &spacemit_pcm_hardware, + .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config, + .chan_names = {"tx", "rx"}, + .prealloc_buffer_size = 32 * 1024, +}; + +static void spacemit_i2s_init(struct spacemit_i2s_dev *i2s) +{ + u32 sscr_val, sspsp_val, ssfcr_val, ssrwt_val; + + sscr_val = SSCR_TRAIL | SSCR_FRF_PSP; + ssfcr_val = FIELD_PREP(SSFCR_FIELD_TFT, 5) | + FIELD_PREP(SSFCR_FIELD_RFT, 5) | + SSFCR_RSRE | SSFCR_TSRE; + ssrwt_val = SSRWT_RWOT; + + /* SSPSP register was set by set_fmt */ + sspsp_val = readl(i2s->base + SSPSP); + sspsp_val |= SSPSP_SFRMP; + + writel(sscr_val, i2s->base + SSCR); + writel(ssfcr_val, i2s->base + SSFCR); + writel(sspsp_val, i2s->base + SSPSP); + writel(ssrwt_val, i2s->base + SSRWT); + writel(0, i2s->base + SSINTEN); +} + +static int spacemit_i2s_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct spacemit_i2s_dev *i2s = snd_soc_dai_get_drvdata(dai); + struct snd_dmaengine_dai_dma_data *dma_data; + u32 data_width, data_bits; + unsigned long bclk_rate; + u32 val; + int ret; + + val = readl(i2s->base + SSCR); + if (val & SSCR_SSE) + return 0; + + dma_data = &i2s->playback_dma_data; + + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + dma_data = &i2s->capture_dma_data; + + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S8: + data_bits = 8; + data_width = SSCR_DW_8BYTE; + dma_data->maxburst = 8; + dma_data->addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; + break; + case SNDRV_PCM_FORMAT_S16_LE: + data_bits = 16; + data_width = SSCR_DW_16BYTE; + dma_data->maxburst = 16; + dma_data->addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; + if ((i2s->dai_fmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_I2S) { + data_width = SSCR_DW_32BYTE; + dma_data->maxburst = 32; + dma_data->addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; + } + break; + case SNDRV_PCM_FORMAT_S32_LE: + data_bits = 32; + data_width = SSCR_DW_32BYTE; + dma_data->maxburst = 32; + dma_data->addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; + break; + default: + dev_dbg(i2s->dev, "unexpected data width type"); + return -EINVAL; + } + + val = readl(i2s->base + SSCR); + val &= ~SSCR_DW_32BYTE; + val |= data_width; + writel(val, i2s->base + SSCR); + + bclk_rate = params_channels(params) * + params_rate(params) * + data_bits; + + ret = clk_set_rate(i2s->bclk, bclk_rate); + if (ret) + return ret; + + return clk_set_rate(i2s->sspa_clk, bclk_rate); +} + +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); + + if (freq == 0) + return 0; + + return clk_set_rate(i2s->sysclk, freq); +} + +static int spacemit_i2s_set_fmt(struct snd_soc_dai *cpu_dai, + unsigned int fmt) +{ + struct spacemit_i2s_dev *i2s = dev_get_drvdata(cpu_dai->dev); + u32 sspsp_val; + + sspsp_val = readl(i2s->base + SSPSP); + sspsp_val &= ~SSPSP_FIELD_SFRMWDTH; + + i2s->dai_fmt = fmt; + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + cpu_dai->driver->playback.formats = SNDRV_PCM_FMTBIT_S16_LE; + cpu_dai->driver->capture.formats = SNDRV_PCM_FMTBIT_S16_LE; + sspsp_val |= FIELD_PREP(SSPSP_FIELD_SFRMWDTH, 0x10) | + SSPSP_FSRT; + break; + case SND_SOC_DAIFMT_DSP_A: + case SND_SOC_DAIFMT_DSP_B: + cpu_dai->driver->playback.channels_min = 1; + cpu_dai->driver->playback.channels_max = 1; + cpu_dai->driver->capture.channels_min = 1; + cpu_dai->driver->capture.channels_max = 1; + cpu_dai->driver->playback.formats = SNDRV_PCM_FMTBIT_S32_LE; + cpu_dai->driver->capture.formats = SNDRV_PCM_FMTBIT_S32_LE; + sspsp_val |= FIELD_PREP(SSPSP_FIELD_SFRMWDTH, 0x1); + break; + default: + dev_dbg(i2s->dev, "unexpected format type"); + return -EINVAL; + } + + if ((fmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_DSP_A) + sspsp_val |= SSPSP_FSRT; + + writel(sspsp_val, i2s->base + SSPSP); + + return 0; +} + +static int spacemit_i2s_trigger(struct snd_pcm_substream *substream, + int cmd, struct snd_soc_dai *dai) +{ + struct spacemit_i2s_dev *i2s = snd_soc_dai_get_drvdata(dai); + u32 val; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + if (!i2s->started_count) { + val = readl(i2s->base + SSCR); + val |= SSCR_SSE; + writel(val, i2s->base + SSCR); + } + i2s->started_count++; + break; + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + if (i2s->started_count) + i2s->started_count--; + + if (!i2s->started_count) { + val = readl(i2s->base + SSCR); + val &= ~SSCR_SSE; + writel(val, i2s->base + SSCR); + } + break; + default: + return -EINVAL; + } + + return 0; +} + +static int spacemit_i2s_dai_probe(struct snd_soc_dai *dai) +{ + struct spacemit_i2s_dev *i2s = snd_soc_dai_get_drvdata(dai); + + snd_soc_dai_init_dma_data(dai, + i2s->has_playback ? &i2s->playback_dma_data : NULL, + i2s->has_capture ? &i2s->capture_dma_data : NULL); + + reset_control_deassert(i2s->reset); + + spacemit_i2s_init(i2s); + + return 0; +} + +static int spacemit_i2s_dai_remove(struct snd_soc_dai *dai) +{ + struct spacemit_i2s_dev *i2s = snd_soc_dai_get_drvdata(dai); + + reset_control_assert(i2s->reset); + + return 0; +} + +static const struct snd_soc_dai_ops spacemit_i2s_dai_ops = { + .probe = spacemit_i2s_dai_probe, + .remove = spacemit_i2s_dai_remove, + .hw_params = spacemit_i2s_hw_params, + .set_sysclk = spacemit_i2s_set_sysclk, + .set_fmt = spacemit_i2s_set_fmt, + .trigger = spacemit_i2s_trigger, +}; + +static struct snd_soc_dai_driver spacemit_i2s_dai = { + .ops = &spacemit_i2s_dai_ops, + .playback = { + .channels_min = 1, + .channels_max = 2, + .rates = SPACEMIT_PCM_RATES, + .rate_min = SNDRV_PCM_RATE_8000, + .rate_max = SNDRV_PCM_RATE_192000, + .formats = SPACEMIT_PCM_FORMATS, + }, + .capture = { + .channels_min = 1, + .channels_max = 2, + .rates = SPACEMIT_PCM_RATES, + .rate_min = SNDRV_PCM_RATE_8000, + .rate_max = SNDRV_PCM_RATE_192000, + .formats = SPACEMIT_PCM_FORMATS, + }, + .symmetric_rate = 1, +}; + +static int spacemit_i2s_init_dai(struct spacemit_i2s_dev *i2s, + struct snd_soc_dai_driver **dp, + dma_addr_t addr) +{ + struct device_node *node = i2s->dev->of_node; + struct snd_soc_dai_driver *dai; + struct property *dma_names; + const char *dma_name; + + of_property_for_each_string(node, "dma-names", dma_names, dma_name) { + if (!strcmp(dma_name, "tx")) + i2s->has_playback = true; + if (!strcmp(dma_name, "rx")) + i2s->has_capture = true; + } + + dai = devm_kmemdup(i2s->dev, &spacemit_i2s_dai, + sizeof(*dai), GFP_KERNEL); + if (!dai) + return -ENOMEM; + + if (i2s->has_playback) { + dai->playback.stream_name = "Playback"; + dai->playback.channels_min = 1; + dai->playback.channels_max = 2; + dai->playback.rates = SPACEMIT_PCM_RATES; + dai->playback.formats = SPACEMIT_PCM_FORMATS; + + i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; + i2s->playback_dma_data.maxburst = 32; + i2s->playback_dma_data.addr = addr; + } + + if (i2s->has_capture) { + dai->capture.stream_name = "Capture"; + dai->capture.channels_min = 1; + dai->capture.channels_max = 2; + dai->capture.rates = SPACEMIT_PCM_RATES; + dai->capture.formats = SPACEMIT_PCM_FORMATS; + + i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES; + i2s->capture_dma_data.maxburst = 32; + i2s->capture_dma_data.addr = addr; + } + + if (dp) + *dp = dai; + + return 0; +} + +static const struct snd_soc_component_driver spacemit_i2s_component = { + .name = "i2s-k1", + .legacy_dai_naming = 1, +}; + +static int spacemit_i2s_probe(struct platform_device *pdev) +{ + struct snd_soc_dai_driver *dai; + struct spacemit_i2s_dev *i2s; + struct resource *res; + struct clk *clk; + int ret; + + i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL); + if (!i2s) + return -ENOMEM; + + i2s->dev = &pdev->dev; + + i2s->sysclk = devm_clk_get_enabled(i2s->dev, "sysclk"); + if (IS_ERR(i2s->sysclk)) + return dev_err_probe(i2s->dev, PTR_ERR(i2s->sysclk), + "failed to enable sysbase clock\n"); + + i2s->bclk = devm_clk_get_enabled(i2s->dev, "bclk"); + if (IS_ERR(i2s->bclk)) + return dev_err_probe(i2s->dev, PTR_ERR(i2s->bclk), "failed to enable bit clock\n"); + + clk = devm_clk_get_enabled(i2s->dev, "sspa_bus"); + if (IS_ERR(clk)) + return dev_err_probe(i2s->dev, PTR_ERR(clk), "failed to enable sspa_bus clock\n"); + + i2s->sspa_clk = devm_clk_get_enabled(i2s->dev, "sspa"); + if (IS_ERR(clk)) + return dev_err_probe(i2s->dev, PTR_ERR(clk), "failed to enable sspa 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"); + + i2s->reset = devm_reset_control_get_exclusive(&pdev->dev, NULL); + if (IS_ERR(i2s->reset)) + return dev_err_probe(i2s->dev, PTR_ERR(i2s->reset), + "failed to get reset control"); + + dev_set_drvdata(i2s->dev, i2s); + + spacemit_i2s_init_dai(i2s, &dai, res->start + SSDATR); + + ret = devm_snd_soc_register_component(i2s->dev, + &spacemit_i2s_component, + dai, 1); + if (ret) + return dev_err_probe(i2s->dev, ret, "failed to register component"); + + return devm_snd_dmaengine_pcm_register(&pdev->dev, &spacemit_dmaengine_pcm_config, 0); +} + +static void spacemit_i2s_remove(struct platform_device *pdev) +{ + /* resources auto-freed by devm_ */ +} + +static const struct of_device_id spacemit_i2s_of_match[] = { + { .compatible = "spacemit,k1-i2s", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, spacemit_i2s_of_match); + +static struct platform_driver spacemit_i2s_driver = { + .probe = spacemit_i2s_probe, + .remove = spacemit_i2s_remove, + .driver = { + .name = "i2s-k1", + .of_match_table = spacemit_i2s_of_match, + }, +}; +module_platform_driver(spacemit_i2s_driver); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("I2S bus driver for SpacemiT K1 SoC"); -- 2.50.1 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* Re: [PATCH v2 2/2] ASoC: spacemit: add i2s support for K1 SoC 2025-08-28 3:37 ` Troy Mitchell @ 2025-08-28 9:04 ` Mark Brown -1 siblings, 0 replies; 14+ messages in thread From: Mark Brown @ 2025-08-28 9:04 UTC (permalink / raw) To: Troy Mitchell Cc: Liam Girdwood, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Yixun Lan, Jaroslav Kysela, Takashi Iwai, Philipp Zabel, linux-sound, devicetree, linux-riscv, spacemit, linux-kernel, Jinmei Wei [-- Attachment #1.1: Type: text/plain, Size: 593 bytes --] On Thu, Aug 28, 2025 at 11:37:33AM +0800, Troy Mitchell wrote: > + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { > + case SND_SOC_DAIFMT_DSP_A: > + case SND_SOC_DAIFMT_DSP_B: > + cpu_dai->driver->playback.channels_min = 1; > + cpu_dai->driver->playback.channels_max = 1; > + if ((fmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_DSP_A) > + sspsp_val |= SSPSP_FSRT; It's weird and confusing that this isn't part of the above switch case. > +static void spacemit_i2s_remove(struct platform_device *pdev) > +{ > + /* resources auto-freed by devm_ */ > +} If this can be empty remove it. [-- Attachment #1.2: signature.asc --] [-- Type: application/pgp-signature, Size: 488 bytes --] [-- Attachment #2: Type: text/plain, Size: 161 bytes --] _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v2 2/2] ASoC: spacemit: add i2s support for K1 SoC @ 2025-08-28 9:04 ` Mark Brown 0 siblings, 0 replies; 14+ messages in thread From: Mark Brown @ 2025-08-28 9:04 UTC (permalink / raw) To: Troy Mitchell Cc: Liam Girdwood, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Yixun Lan, Jaroslav Kysela, Takashi Iwai, Philipp Zabel, linux-sound, devicetree, linux-riscv, spacemit, linux-kernel, Jinmei Wei [-- Attachment #1: Type: text/plain, Size: 593 bytes --] On Thu, Aug 28, 2025 at 11:37:33AM +0800, Troy Mitchell wrote: > + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { > + case SND_SOC_DAIFMT_DSP_A: > + case SND_SOC_DAIFMT_DSP_B: > + cpu_dai->driver->playback.channels_min = 1; > + cpu_dai->driver->playback.channels_max = 1; > + if ((fmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_DSP_A) > + sspsp_val |= SSPSP_FSRT; It's weird and confusing that this isn't part of the above switch case. > +static void spacemit_i2s_remove(struct platform_device *pdev) > +{ > + /* resources auto-freed by devm_ */ > +} If this can be empty remove it. [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 488 bytes --] ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v2 2/2] ASoC: spacemit: add i2s support for K1 SoC 2025-08-28 9:04 ` Mark Brown @ 2025-09-02 1:39 ` Troy Mitchell -1 siblings, 0 replies; 14+ messages in thread From: Troy Mitchell @ 2025-09-02 1:39 UTC (permalink / raw) To: Mark Brown, Troy Mitchell Cc: Liam Girdwood, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Yixun Lan, Jaroslav Kysela, Takashi Iwai, Philipp Zabel, linux-sound, devicetree, linux-riscv, spacemit, linux-kernel, Jinmei Wei On Thu, Aug 28, 2025 at 11:04:19AM +0200, Mark Brown wrote: > On Thu, Aug 28, 2025 at 11:37:33AM +0800, Troy Mitchell wrote: > > > + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { > > + case SND_SOC_DAIFMT_DSP_A: > > + case SND_SOC_DAIFMT_DSP_B: > > + cpu_dai->driver->playback.channels_min = 1; > > + cpu_dai->driver->playback.channels_max = 1; > > > + if ((fmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_DSP_A) > > + sspsp_val |= SSPSP_FSRT; > > It's weird and confusing that this isn't part of the above switch case. Thanks! I'll change it. > > > +static void spacemit_i2s_remove(struct platform_device *pdev) > > +{ > > + /* resources auto-freed by devm_ */ > > +} > > If this can be empty remove it. Yes, I will remove it in the next version. Best regards, Troy _______________________________________________ linux-riscv mailing list linux-riscv@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-riscv ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [PATCH v2 2/2] ASoC: spacemit: add i2s support for K1 SoC @ 2025-09-02 1:39 ` Troy Mitchell 0 siblings, 0 replies; 14+ messages in thread From: Troy Mitchell @ 2025-09-02 1:39 UTC (permalink / raw) To: Mark Brown, Troy Mitchell Cc: Liam Girdwood, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Yixun Lan, Jaroslav Kysela, Takashi Iwai, Philipp Zabel, linux-sound, devicetree, linux-riscv, spacemit, linux-kernel, Jinmei Wei On Thu, Aug 28, 2025 at 11:04:19AM +0200, Mark Brown wrote: > On Thu, Aug 28, 2025 at 11:37:33AM +0800, Troy Mitchell wrote: > > > + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { > > + case SND_SOC_DAIFMT_DSP_A: > > + case SND_SOC_DAIFMT_DSP_B: > > + cpu_dai->driver->playback.channels_min = 1; > > + cpu_dai->driver->playback.channels_max = 1; > > > + if ((fmt & SND_SOC_DAIFMT_FORMAT_MASK) == SND_SOC_DAIFMT_DSP_A) > > + sspsp_val |= SSPSP_FSRT; > > It's weird and confusing that this isn't part of the above switch case. Thanks! I'll change it. > > > +static void spacemit_i2s_remove(struct platform_device *pdev) > > +{ > > + /* resources auto-freed by devm_ */ > > +} > > If this can be empty remove it. Yes, I will remove it in the next version. Best regards, Troy ^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2025-09-02 1:40 UTC | newest] Thread overview: 14+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-08-28 3:37 [PATCH v2 0/2] ASoC: spacemit: add i2s support to K1 SoC Troy Mitchell 2025-08-28 3:37 ` Troy Mitchell 2025-08-28 3:37 ` [PATCH v2 1/2] ASoC: dt-bindings: Add bindings for SpacemiT K1 Troy Mitchell 2025-08-28 3:37 ` Troy Mitchell 2025-08-29 17:16 ` Rob Herring 2025-08-29 17:16 ` Rob Herring 2025-09-02 1:36 ` Troy Mitchell 2025-09-02 1:36 ` Troy Mitchell 2025-08-28 3:37 ` [PATCH v2 2/2] ASoC: spacemit: add i2s support for K1 SoC Troy Mitchell 2025-08-28 3:37 ` Troy Mitchell 2025-08-28 9:04 ` Mark Brown 2025-08-28 9:04 ` Mark Brown 2025-09-02 1:39 ` Troy Mitchell 2025-09-02 1:39 ` Troy Mitchell
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.