Add PWM-DAC audio support for StarFive JH7110 RISC-V SoC
Subsystems (6)
Hal Feng
maintainerv2 cover Add PWM-DAC audio support for StarFive JH7110 RISC-V SoC
This patchset adds PWM-DAC audio support for the StarFive JH7110 SoC. The PWM-DAC module does not require a hardware codec, but a dummy codec is needed for the driver. The dummy spdif codec driver, which is already upstream, is compatible with the one which JH7110 PWM-DAC needed. So we use it as the dummy codec driver for the JH7110 PWM-DAC module.
The third patch depends on tag next-20230728 in linux-next branch.
Changes since v1:
- Rebase on tag v6.5-rc3.
- Drop patch 1 and 2.
- Drop the unneeded space and line in patch 3.
- Use the dummy spdif codec driver instead of adding a new one.
- Change "dai_link->stop_dma_first = 1" to "dai_link->trigger_stop = SND_SOC_TRIGGER_ORDER_LDC" in patch 4.
- Drop the unneeded "status = "okay;" in patch 5.
- Change some node names in patch 5.
---
v1: https://lore.kernel.org/all/[email protected]/
Hal Feng (3):
ASoC: dt-bindings: Add StarFive JH7110 PWM-DAC controller
ASoC: starfive: Add JH7110 PWM-DAC driver
riscv: dts: starfive: Add JH7110 PWM-DAC support
.../sound/starfive,jh7110-pwmdac.yaml | 76 ++ MAINTAINERS | 7 + .../jh7110-starfive-visionfive-2.dtsi | 99 +++ arch/riscv/boot/dts/starfive/jh7110.dtsi | 156 ++++ sound/soc/starfive/Kconfig | 9 + sound/soc/starfive/Makefile | 1 + sound/soc/starfive/jh7110_pwmdac.c | 787 ++++++++++++++++++ 7 files changed, 1135 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/starfive,jh7110-pwmdac.yaml create mode 100644 sound/soc/starfive/jh7110_pwmdac.c
base-commit: 6eaae198076080886b9e7d57f4ae06fa782f90ef
Signature · 1 line
2.38.1
Hal Feng
maintainerPATCH v2 1/3 ASoC: dt-bindings: Add StarFive JH7110 PWM-DAC controller
Add bindings for the PWM-DAC controller on the JH7110 RISC-V SoC by StarFive Ltd.
--- .../sound/starfive,jh7110-pwmdac.yaml | 76 +++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/starfive,jh7110-pwmdac.yaml
Documentation/devicetree/bindings/sound/starfive,jh7110-pwmdac.yaml new file +76 -0
@@ -0,0 +1,76 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/starfive,jh7110-pwmdac.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: StarFive JH7110 PWM-DAC Controller + +description: + The PWM-DAC Controller uses PWM square wave generators plus RC filters to + form a DAC for audio play in StarFive JH7110 SoC. This audio play controller + supports 16 bit audio format, up to 48K sampling frequency, up to left and + right dual channels. + +maintainers: + - Hal Feng <[email protected]> + +allOf: + - $ref: dai-common.yaml# + +properties: + compatible: + const: starfive,jh7110-pwmdac + + reg: + maxItems: 1 + + clocks: + items: + - description: PWMDAC APB + - description: PWMDAC CORE + + clock-names: + items: + - const: apb + - const: core + + resets: + maxItems: 1 + description: PWMDAC APB + + dmas: + maxItems: 1 + description: TX DMA Channel + + dma-names: + const: tx + + "#sound-dai-cells": + const: 0 + +required: + - compatible + - reg + - clocks + - clock-names + - resets + - dmas + - dma-names + - "#sound-dai-cells" + +additionalProperties: false + +examples: + - | + pwmdac@100b0000 { + compatible = "starfive,jh7110-pwmdac"; + reg = <0x100b0000 0x1000>; + clocks = <&syscrg 157>, + <&syscrg 158>; + clock-names = "apb", "core"; + resets = <&syscrg 96>; + dmas = <&dma 22>; + dma-names = "tx"; + #sound-dai-cells = <0>; + };
Signature · 1 line
2.38.1
Hal Feng
maintainerPATCH v2 2/3 ASoC: starfive: Add JH7110 PWM-DAC driver
In reply to Hal FengAdd PWM-DAC driver support for the StarFive JH7110 SoC.
--- MAINTAINERS | 7 + sound/soc/starfive/Kconfig | 9 + sound/soc/starfive/Makefile | 1 + sound/soc/starfive/jh7110_pwmdac.c | 787 +++++++++++++++++++++++++++++ 4 files changed, 804 insertions(+) create mode 100644 sound/soc/starfive/jh7110_pwmdac.c
MAINTAINERS +7 -0
@@ -20284,6 +20284,13 @@ S: Supported F: Documentation/devicetree/bindings/mmc/starfive* F: drivers/mmc/host/dw_mmc-starfive.c +STARFIVE JH7110 PWMDAC DRIVER +M: Hal Feng <[email protected]> +M: Xingyu Wu <[email protected]> +S: Supported +F: Documentation/devicetree/bindings/sound/starfive,jh7110-pwmdac.yaml +F: sound/soc/starfive/jh7110_pwmdac.c + STARFIVE JH7110 TDM DRIVER M: Walker Chen <[email protected]> S: Maintained
sound/soc/starfive/Kconfig +9 -0
@@ -7,6 +7,15 @@ config SND_SOC_STARFIVE the Starfive SoCs' Audio interfaces. You will also need to select the audio interfaces to support below. +config SND_SOC_JH7110_PWMDAC + tristate "JH7110 PWM-DAC device driver" + depends on HAVE_CLK && SND_SOC_STARFIVE + select SND_SOC_GENERIC_DMAENGINE_PCM + select SND_SOC_SPDIF + help + Say Y or M if you want to add support for StarFive JH7110 + PWM-DAC driver. + config SND_SOC_JH7110_TDM tristate "JH7110 TDM device driver" depends on HAVE_CLK && SND_SOC_STARFIVE
sound/soc/starfive/Makefile +1 -0
@@ -1,2 +1,3 @@ # StarFive Platform Support +obj-$(CONFIG_SND_SOC_JH7110_PWMDAC) += jh7110_pwmdac.o obj-$(CONFIG_SND_SOC_JH7110_TDM) += jh7110_tdm.o
sound/soc/starfive/jh7110_pwmdac.c new file +787 -0
787 lines not on this page · raw message
Signature · 1 line
2.38.1
Re: [PATCH v2 2/3] ASoC: starfive: Add JH7110 PWM-DAC driver
Quoted 2 lines · Hal Feng
Add PWM-DAC driver support for the StarFive JH7110 SoC.
...
Quoted 12 lines
sound/soc/starfive/jh7110_pwmdac.c new file +12
-0+static int jh7110_pwmdac_probe (struct platform_device *pdev) +{ +struct jh7110_pwmdac_dev *dev; +struct resource *res; +int ret; + + dev =devm_kzalloc (&pdev->dev,sizeof (*dev),GFP_KERNEL ); +if (!dev) +return -ENOMEM ; + + dev->base =devm_platform_get_and_ioremap_resource (pdev,0 , &res); +if (IS_ERR (dev->base))
sound/soc/starfive/jh7110_pwmdac.c line 711
Quoted 10 lines
sound/soc/starfive/jh7110_pwmdac.c new file +10
-0+return PTR_ERR (dev->base); + + dev->mapbase = res->start; + + dev->clks[0 ].id ="apb" ; + dev->clks[1 ].id ="core" ; + + ret =devm_clk_bulk_get (&pdev->dev,ARRAY_SIZE (dev->clks), dev->clks); +if (ret) { +dev_err (&pdev->dev,"failed to get pwmdac clocks\n" );
return dev_err_probe
sound/soc/starfive/jh7110_pwmdac.c line 718
Quoted 7 lines
sound/soc/starfive/jh7110_pwmdac.c new file +7
-0+return ret; + } + + dev->rst_apb =devm_reset_control_get_exclusive (&pdev->dev,NULL ); +if (IS_ERR (dev->rst_apb)) { +dev_err (&pdev->dev,"failed to get pwmdac apb reset\n" ); +return PTR_ERR (dev->rst_apb);
return dev_err_probe
Quoted 7 lines
sound/soc/starfive/jh7110_pwmdac.c new file +7
-0+ } + + dev->dev = &pdev->dev; + dev->shift =PWMDAC_SHIFT_8 ; + dev->duty_cycle =PWMDAC_CYCLE_CENTER ; + dev->cnt_n =PWMDAC_SAMPLE_CNT_1 ; + dev->data_change =NO_CHANGE ;
sound/soc/starfive/jh7110_pwmdac.c line 735
Quoted 10 lines
sound/soc/starfive/jh7110_pwmdac.c new file +10
-0+ dev->data_mode =INVERTER_DATA_MSB ; + dev->data_shift =PWMDAC_DATA_LEFT_SHIFT_BIT_0 ; + +dev_set_drvdata (&pdev->dev, dev); + ret =devm_snd_soc_register_component (&pdev->dev, + &jh7110_pwmdac_component, + &jh7110_pwmdac_dai,1 ); +if (ret) { +dev_err (&pdev->dev,"failed to register dai\n" ); +return ret;
I guess here as well for consistency and shorter code even though EPROBE_DEFER does not happen really.
return dev_err_probe
sound/soc/starfive/jh7110_pwmdac.c line 741
Quoted 6 lines
sound/soc/starfive/jh7110_pwmdac.c new file +6
-0+ } + + ret =devm_snd_dmaengine_pcm_register (&pdev->dev,NULL ,0 ); +if (ret) { +dev_err (&pdev->dev,"failed to register pcm\n" ); +return ret;
return dev_err_probe
Review
Quoted 2 lines
(quoted diff) +2
-0+ } +
Best regards,
Krzysztof
_______________________________________________
linux-riscv mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-riscv
Hal Feng
maintainerRe: [PATCH v2 2/3] ASoC: starfive: Add JH7110 PWM-DAC driver
Quoted 23 lines · Krzysztof Kozlowski
Quoted 2 lines · Hal Feng
Add PWM-DAC driver support for the StarFive JH7110 SoC.
...
Quoted 16 lines
sound/soc/starfive/jh7110_pwmdac.c new file +16
-0+static int jh7110_pwmdac_probe (struct platform_device *pdev) +{ +struct jh7110_pwmdac_dev *dev; +struct resource *res; +int ret; + + dev =devm_kzalloc (&pdev->dev,sizeof (*dev),GFP_KERNEL ); +if (!dev) +return -ENOMEM ; + + dev->base =devm_platform_get_and_ioremap_resource (pdev,0 , &res); +if (IS_ERR (dev->base)) +return PTR_ERR (dev->base); + + dev->mapbase = res->start; +
Quoted 8 lines
sound/soc/starfive/jh7110_pwmdac.c line 711
Quoted 6 lines
sound/soc/starfive/jh7110_pwmdac.c new file +6
-0+ dev->clks[0 ].id ="apb" ; + dev->clks[1 ].id ="core" ; + + ret =devm_clk_bulk_get (&pdev->dev,ARRAY_SIZE (dev->clks), dev->clks); +if (ret) { +dev_err (&pdev->dev,"failed to get pwmdac clocks\n" );return
dev_err_probe
OK, will fix.
Quoted 10 lines
sound/soc/starfive/jh7110_pwmdac.c line 718
Quoted 8 lines
sound/soc/starfive/jh7110_pwmdac.c new file +7
-0+return ret; + } + + dev->rst_apb =devm_reset_control_get_exclusive (&pdev->dev,NULL ); +if (IS_ERR (dev->rst_apb)) { +dev_err (&pdev->dev,"failed to get pwmdac apb reset\n" ); +return PTR_ERR (dev->rst_apb);return
dev_err_probe
Will fix.
Quoted 22 lines
Quoted 8 lines
sound/soc/starfive/jh7110_pwmdac.c new file +7
-0+ } + + dev->dev = &pdev->dev; + dev->shift =PWMDAC_SHIFT_8 ; + dev->duty_cycle =PWMDAC_CYCLE_CENTER ; + dev->cnt_n =PWMDAC_SAMPLE_CNT_1 ; + dev->data_change =NO_CHANGE ;sound/soc/starfive/jh7110_pwmdac.c line 735
Quoted 10 lines
sound/soc/starfive/jh7110_pwmdac.c new file +10
-0+ dev->data_mode =INVERTER_DATA_MSB ; + dev->data_shift =PWMDAC_DATA_LEFT_SHIFT_BIT_0 ; + +dev_set_drvdata (&pdev->dev, dev); + ret =devm_snd_soc_register_component (&pdev->dev, + &jh7110_pwmdac_component, + &jh7110_pwmdac_dai,1 ); +if (ret) { +dev_err (&pdev->dev,"failed to register dai\n" ); +return ret;I guess here as well for consistency and shorter code even though
EPROBE_DEFERdoes not happen really.
Quoted 1 line
return
dev_err_probe
Will fix.
Quoted 9 lines
sound/soc/starfive/jh7110_pwmdac.c line 741
Quoted 7 lines
sound/soc/starfive/jh7110_pwmdac.c new file +6
-0+ } + + ret =devm_snd_dmaengine_pcm_register (&pdev->dev,NULL ,0 ); +if (ret) { +dev_err (&pdev->dev,"failed to register pcm\n" ); +return ret;return
dev_err_probe
Will fix. Thanks for your review.
Best regards,
Hal
Quoted 3 lines
Quoted 3 lines
(quoted diff) +2
-0+ } +
Mark Brown
maintainerRe: [PATCH v2 2/3] ASoC: starfive: Add JH7110 PWM-DAC driver
In reply to Hal Fengsound/soc/starfive/jh7110_pwmdac.c line 140
Quoted 10 lines · Hal Feng
sound/soc/starfive/jh7110_pwmdac.c new file +10
-0+static const struct jh7110_ct_pwmdac pwmdac_ct_data_shift[] = { + { .name ="left 0 bit" , .vals =PWMDAC_DATA_LEFT_SHIFT_BIT_0 }, + { .name ="left 1 bit" , .vals =PWMDAC_DATA_LEFT_SHIFT_BIT_1 }, + { .name ="left 2 bit" , .vals =PWMDAC_DATA_LEFT_SHIFT_BIT_2 }, + { .name ="left 3 bit" , .vals =PWMDAC_DATA_LEFT_SHIFT_BIT_3 }, + { .name ="left 4 bit" , .vals =PWMDAC_DATA_LEFT_SHIFT_BIT_4 }, + { .name ="left 5 bit" , .vals =PWMDAC_DATA_LEFT_SHIFT_BIT_5 }, + { .name ="left 6 bit" , .vals =PWMDAC_DATA_LEFT_SHIFT_BIT_6 }, + { .name ="left 7 bit" , .vals =PWMDAC_DATA_LEFT_SHIFT_BIT_7 } +};
It's not clear to me why this is user selectable - what does the control do?
Quoted 12 lines
sound/soc/starfive/jh7110_pwmdac.c new file +11
-0+static int jh7110_pwmdac_put (struct snd_kcontrol *kcontrol, +struct snd_ctl_elem_value *ucontrol, +int pwmdac_ct) +{ +struct snd_soc_component *component =snd_kcontrol_chip (kcontrol); +struct jh7110_pwmdac_dev *dev =snd_soc_component_get_drvdata (component); +int sel = ucontrol->value.enumerated.item[0 ]; +unsigned int items; +if (pwmdac_ct ==PWMDAC_CT_SHIFT ) + dev->shift = pwmdac_ct_shift[sel].vals; +else if (pwmdac_ct ==PWMDAC_CT_DUTY_CYCLE )
sound/soc/starfive/jh7110_pwmdac.c line 233
Quoted 10 lines
sound/soc/starfive/jh7110_pwmdac.c new file +10
-0+ dev->duty_cycle = pwmdac_ct_duty_cycle[sel].vals; + else if (pwmdac_ct == PWMDAC_CT_DATA_CHANGE) + dev->data_change = pwmdac_ct_data_change[sel].vals; + else if (pwmdac_ct == PWMDAC_CT_DATA_MODE) + dev->data_mode = pwmdac_ct_data_mode[sel].vals; + else if (pwmdac_ct == PWMDAC_CT_DATA_SHIFT) + dev->data_shift = pwmdac_ct_data_shift[sel].vals; + +return 0 ; +}
_put() operations should return 1 if the control value changes so event generation works - please test a card using this driver with the mixer-test selftest, it'll identify this and a bunch of other potential issues.
sound/soc/starfive/jh7110_pwmdac.c line 618
Quoted 6 lines
sound/soc/starfive/jh7110_pwmdac.c new file +6
-0+static int jh7110_pwmdac_component_probe (struct snd_soc_component *component) +{ +snd_soc_add_component_controls (component, jh7110_pwmdac_snd_controls, +ARRAY_SIZE (jh7110_pwmdac_snd_controls)); +return 0 ; +}
The driver can just point to the controls from the _driver struct and skip having a probe() function.
Hal Feng
maintainerRe: [PATCH v2 2/3] ASoC: starfive: Add JH7110 PWM-DAC driver
Quoted 15 lines · Mark Brown
sound/soc/starfive/jh7110_pwmdac.c line 140
Quoted 10 lines · Hal Feng
sound/soc/starfive/jh7110_pwmdac.c new file +10
-0+static const struct jh7110_ct_pwmdac pwmdac_ct_data_shift[] = { + { .name ="left 0 bit" , .vals =PWMDAC_DATA_LEFT_SHIFT_BIT_0 }, + { .name ="left 1 bit" , .vals =PWMDAC_DATA_LEFT_SHIFT_BIT_1 }, + { .name ="left 2 bit" , .vals =PWMDAC_DATA_LEFT_SHIFT_BIT_2 }, + { .name ="left 3 bit" , .vals =PWMDAC_DATA_LEFT_SHIFT_BIT_3 }, + { .name ="left 4 bit" , .vals =PWMDAC_DATA_LEFT_SHIFT_BIT_4 }, + { .name ="left 5 bit" , .vals =PWMDAC_DATA_LEFT_SHIFT_BIT_5 }, + { .name ="left 6 bit" , .vals =PWMDAC_DATA_LEFT_SHIFT_BIT_6 }, + { .name ="left 7 bit" , .vals =PWMDAC_DATA_LEFT_SHIFT_BIT_7 } +};It's not clear to me why this is user selectable - what does the control do?
It's convenient to change the register values in user space with the control. But actually using fixed register configuration is enough. I will drop all these control in the next version.
Quoted 20 lines
Quoted 20 lines
sound/soc/starfive/jh7110_pwmdac.c new file +18
-0+static int jh7110_pwmdac_put (struct snd_kcontrol *kcontrol, +struct snd_ctl_elem_value *ucontrol, +int pwmdac_ct) +{ +struct snd_soc_component *component =snd_kcontrol_chip (kcontrol); +struct jh7110_pwmdac_dev *dev =snd_soc_component_get_drvdata (component); +int sel = ucontrol->value.enumerated.item[0 ]; +unsigned int items; +if (pwmdac_ct ==PWMDAC_CT_SHIFT ) + dev->shift = pwmdac_ct_shift[sel].vals; +else if (pwmdac_ct ==PWMDAC_CT_DUTY_CYCLE ) + dev->duty_cycle = pwmdac_ct_duty_cycle[sel].vals; +else if (pwmdac_ct ==PWMDAC_CT_DATA_CHANGE ) + dev->data_change = pwmdac_ct_data_change[sel].vals; +else if (pwmdac_ct ==PWMDAC_CT_DATA_MODE ) + dev->data_mode = pwmdac_ct_data_mode[sel].vals; +else if (pwmdac_ct ==PWMDAC_CT_DATA_SHIFT ) + dev->data_shift = pwmdac_ct_data_shift[sel].vals;
Quoted 8 lines
sound/soc/starfive/jh7110_pwmdac.c line 175
Quoted 3 lines
sound/soc/starfive/jh7110_pwmdac.c new file +3
-0+ +return 0 ; +}
_put()operations should return 1 if the control value changes so event generation works - please test a card using this driver with the mixer-test selftest, it'll identify this and a bunch of other potential issues.
Thanks for the correct, but it doesn't matter as I will drop these control later.
Quoted 10 lines
sound/soc/starfive/jh7110_pwmdac.c line 618
Quoted 7 lines
sound/soc/starfive/jh7110_pwmdac.c new file +6
-0+static int jh7110_pwmdac_component_probe (struct snd_soc_component *component) +{ +snd_soc_add_component_controls (component, jh7110_pwmdac_snd_controls, +ARRAY_SIZE (jh7110_pwmdac_snd_controls)); +return 0 ; +}The driver can just point to the controls from the
_driverstruct and skip having aprobe()function.
Thanks for your advice, but I would like to drop these control later.
Thanks again for your review.
Best regards,
Hal
_______________________________________________
linux-riscv mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-riscv
Hal Feng
maintainerPATCH v2 3/3 riscv: dts: starfive: Add JH7110 PWM-DAC support
In reply to Hal FengAdd PWM-DAC support for StarFive JH7110 SoC.
--- .../jh7110-starfive-visionfive-2.dtsi | 49 +++++++++++++++++++ arch/riscv/boot/dts/starfive/jh7110.dtsi | 13 +++++ 2 files changed, 62 insertions(+)
arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi +49 -0
@@ -38,6 +38,33 @@ gpio-restart { gpios = <&sysgpio 35 GPIO_ACTIVE_HIGH>; priority = <224>; }; + + pwmdac_codec: pwmdac-codec { + compatible = "linux,spdif-dit"; + #sound-dai-cells = <0>; + }; + + sound-pwmdac { + compatible = "simple-audio-card"; + simple-audio-card,name = "StarFive-PWMDAC-Sound-Card"; + #address-cells = <1>; + #size-cells = <0>; + + simple-audio-card,dai-link@0 { + reg = <0>; + format = "left_j"; + bitclock-master = <&sndcpu0>; + frame-master = <&sndcpu0>; + + sndcpu0: cpu { + sound-dai = <&pwmdac>; + }; + + codec { + sound-dai = <&pwmdac_codec>; + }; + }; + }; }; &dvp_clk {
@@ -185,6 +212,12 @@ &i2c6 { status = "okay"; }; +&pwmdac { + pinctrl-names = "default"; + pinctrl-0 = <&pwmdac_pins>; + status = "okay"; +}; + &spi0 { pinctrl-names = "default"; pinctrl-0 = <&spi0_pins>;
@@ -254,6 +287,22 @@ GPOEN_SYS_I2C6_DATA, }; }; + pwmdac_pins: pwmdac-0 { + pwmdac-pins { + pinmux = <GPIOMUX(33, GPOUT_SYS_PWMDAC_LEFT, + GPOEN_ENABLE, + GPI_NONE)>, + <GPIOMUX(34, GPOUT_SYS_PWMDAC_RIGHT, + GPOEN_ENABLE, + GPI_NONE)>; + bias-disable; + drive-strength = <2>; + input-disable; + input-schmitt-disable; + slew-rate = <0>; + }; + }; + spi0_pins: spi0-0 { mosi-pins { pinmux = <GPIOMUX(52, GPOUT_SYS_SPI0_TXD,
arch/riscv/boot/dts/starfive/jh7110.dtsi +13 -0
@@ -512,6 +512,19 @@ tdm: tdm@10090000 { status = "disabled"; }; + pwmdac: pwmdac@100b0000 { + compatible = "starfive,jh7110-pwmdac"; + reg = <0x0 0x100b0000 0x0 0x1000>; + clocks = <&syscrg JH7110_SYSCLK_PWMDAC_APB>, + <&syscrg JH7110_SYSCLK_PWMDAC_CORE>; + clock-names = "apb", "core"; + resets = <&syscrg JH7110_SYSRST_PWMDAC_APB>; + dmas = <&dma 22>; + dma-names = "tx"; + #sound-dai-cells = <0>; + status = "disabled"; + }; + usb0: usb@10100000 { compatible = "starfive,jh7110-usb"; ranges = <0x0 0x0 0x10100000 0x100000>;
Signature · 1 line
2.38.1