From 8607306d50e56a6a18b757f5373d5ecd9dd1e565 Mon Sep 17 00:00:00 2001 From: Stephen Gordon <gordoste@iinet.net.au> Date: Thu, 27 Feb 2025 22:01:41 +1100 Subject: [PATCH] Backport support for ezsound 6x8 soundcard to 6.6.y Signed-off-by: Stephen Gordon <gordoste@iinet.net.au> --- .../bindings/sound/ti,pcm3168a.yaml | 8 ++ arch/arm/boot/dts/overlays/Makefile | 1 + arch/arm/boot/dts/overlays/README | 6 + .../dts/overlays/ezsound-6x8iso-overlay.dts | 117 ++++++++++++++++++ arch/arm64/configs/bcm2712_defconfig | 1 + sound/soc/codecs/pcm3168a.c | 12 ++ 6 files changed, 145 insertions(+) create mode 100644 arch/arm/boot/dts/overlays/ezsound-6x8iso-overlay.dts diff --git a/Documentation/devicetree/bindings/sound/ti,pcm3168a.yaml b/Documentation/devicetree/bindings/sound/ti,pcm3168a.yaml index b6a4360ab845dd..6acc22364fa0ac 100644 --- a/Documentation/devicetree/bindings/sound/ti,pcm3168a.yaml +++ b/Documentation/devicetree/bindings/sound/ti,pcm3168a.yaml @@ -58,6 +58,14 @@ properties: VCCDA2-supply: description: DAC power supply regulator 2 (+5V) + adc-force-cons: + description: Force ADC to operate in consumer mode. Useful if ADC and DAC + clock pins are tied together with DAC as producer. + + dac-force-cons: + description: Force DAC to operate in consumer mode. Useful if ADC and DAC + clock pins are tied together with ADC as producer. + ports: $ref: audio-graph-port.yaml#/definitions/port-base properties: diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile index 272717f6d01db5..595a8991b46e7c 100644 --- a/arch/arm/boot/dts/overlays/Makefile +++ b/arch/arm/boot/dts/overlays/Makefile @@ -64,6 +64,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \ enc28j60.dtbo \ enc28j60-spi2.dtbo \ exc3000.dtbo \ + ezsound-6x8iso.dtbo \ fbtft.dtbo \ fe-pi-audio.dtbo \ fsm-demo.dtbo \ diff --git a/arch/arm/boot/dts/overlays/README b/arch/arm/boot/dts/overlays/README index 820af14f58cfd4..0b69aeb997fca7 100644 --- a/arch/arm/boot/dts/overlays/README +++ b/arch/arm/boot/dts/overlays/README @@ -1284,6 +1284,12 @@ Params: interrupt GPIO used for interrupt (default 4) swapxy Touchscreen swapped x y axis +Name: ezsound-6x8iso +Info: Overlay for the ezsound 6x8 isolated soundcard. +Load: dtoverlay=ezsound-6x8iso +Params: <None> + + Name: fbtft Info: Overlay for SPI-connected displays using the fbtft drivers. diff --git a/arch/arm/boot/dts/overlays/ezsound-6x8iso-overlay.dts b/arch/arm/boot/dts/overlays/ezsound-6x8iso-overlay.dts new file mode 100644 index 00000000000000..ac58be7039523f --- /dev/null +++ b/arch/arm/boot/dts/overlays/ezsound-6x8iso-overlay.dts @@ -0,0 +1,117 @@ +//Device tree overlay for ezsound 6x8 isolated card +/dts-v1/; +/plugin/; + +/ { + compatible = "brcm,bcm2712"; + + fragment@0 { + target = <&rp1_i2s0_18_21>; + __overlay__ { + pins = "gpio18", "gpio19", "gpio20", "gpio22", "gpio24", + "gpio26", "gpio21", "gpio23", "gpio25", "gpio27"; + }; + }; + + fragment@1 { + target = <&rp1_i2s1_18_21>; + __overlay__ { + pins = "gpio18", "gpio19", "gpio20", "gpio22", "gpio24", + "gpio26", "gpio21", "gpio23", "gpio25", "gpio27"; + }; + }; + + fragment@2 { + target = <&sound>; + __overlay__ { + compatible = "simple-audio-card"; + #address-cells = <1>; + #size-cells = <0>; + i2s-controller = <&i2s_clk_consumer>; + status="okay"; + + simple-audio-card,name = "ezsound-6x8"; + + simple-audio-card,dai-link@0 { + reg = <0>; + format = "i2s"; + bitclock-master = <&pcm3168_playback>; + frame-master = <&pcm3168_playback>; + cpu { + sound-dai = <&i2s_clk_consumer>; + dai-tdm-slot-num = <2>; + dai-tdm-slot-width = <32>; + }; + pcm3168_playback: codec { + system-clock-fixed; + mclk-fs = <256>; + sound-dai = <&pcm3168a 0>; + dai-tdm-slot-num = <2>; + dai-tdm-slot-width = <32>; + }; + }; + simple-audio-card,dai-link@1 { + reg = <1>; + format = "i2s"; + bitclock-master = <&pcm3168_capture>; + frame-master = <&pcm3168_capture>; + cpu { + sound-dai = <&i2s_clk_consumer>; + dai-tdm-slot-num = <2>; + dai-tdm-slot-width = <32>; + }; + pcm3168_capture: codec { + system-clock-fixed; + mclk-fs = <256>; + sound-dai = <&pcm3168a 1>; + dai-tdm-slot-num = <2>; + dai-tdm-slot-width = <32>; + }; + }; + }; + }; + + fragment@3 { + target-path = "/"; + __overlay__ { + scki_clk: scki-clock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <24576000>; + }; + }; + }; + + // Bring the I2S clock consumer block up + fragment@4 { + target = <&i2s_clk_consumer>; + __overlay__ { + #sound-dai-cells = <0>; + status = "okay"; + }; + }; + + fragment@5 { + target = <&i2c1>; + __overlay__ { + #address-cells = <1>; + #size-cells = <0>; + + pcm3168a: audio-codec@45 { + #sound-dai-cells = <1>; + compatible = "ti,pcm3168a"; + status = "okay"; + reg = <0x45>; + clocks = <&scki_clk>; + clock-names = "scki"; + dac-force-cons; + VDD1-supply = <&vdd_3v3_reg>; + VDD2-supply = <&vdd_3v3_reg>; + VCCAD1-supply = <&vdd_5v0_reg>; + VCCAD2-supply = <&vdd_5v0_reg>; + VCCDA1-supply = <&vdd_5v0_reg>; + VCCDA2-supply = <&vdd_5v0_reg>; + }; + }; + }; +}; diff --git a/arch/arm64/configs/bcm2712_defconfig b/arch/arm64/configs/bcm2712_defconfig index 3bdf65c72b403b..b3d2024b8ddc1c 100644 --- a/arch/arm64/configs/bcm2712_defconfig +++ b/arch/arm64/configs/bcm2712_defconfig @@ -1150,6 +1150,7 @@ CONFIG_SND_SOC_CS4265=m CONFIG_SND_SOC_ICS43432=m CONFIG_SND_SOC_MA120X0P=m CONFIG_SND_SOC_MAX98357A=m +CONFIG_SND_SOC_PCM3168A_I2C=m CONFIG_SND_SOC_SPDIF=m CONFIG_SND_SOC_TLV320AIC23_I2C=m CONFIG_SND_SOC_WM8804_I2C=m diff --git a/sound/soc/codecs/pcm3168a.c b/sound/soc/codecs/pcm3168a.c index 9d6431338fb715..f5125a7ba41776 100644 --- a/sound/soc/codecs/pcm3168a.c +++ b/sound/soc/codecs/pcm3168a.c @@ -61,6 +61,7 @@ struct pcm3168a_priv { struct clk *scki; struct gpio_desc *gpio_rst; unsigned long sysclk; + bool adc_fc, dac_fc; // Force clock consumer mode struct pcm3168a_io_params io_params[2]; struct snd_soc_dai_driver dai_drv[2]; @@ -479,6 +480,12 @@ static int pcm3168a_hw_params(struct snd_pcm_substream *substream, ms = 0; } + // Force clock consumer mode if needed + if (pcm3168a->adc_fc && dai->id == PCM3168A_DAI_ADC) + ms = 0; + if (pcm3168a->dac_fc && dai->id == PCM3168A_DAI_DAC) + ms = 0; + format = io_params->format; if (io_params->slot_width) @@ -757,6 +764,11 @@ int pcm3168a_probe(struct device *dev, struct regmap *regmap) pcm3168a->sysclk = clk_get_rate(pcm3168a->scki); + pcm3168a->adc_fc = of_property_read_bool(dev->of_node, + "adc-force-cons"); + pcm3168a->dac_fc = of_property_read_bool(dev->of_node, + "dac-force-cons"); + for (i = 0; i < ARRAY_SIZE(pcm3168a->supplies); i++) pcm3168a->supplies[i].supply = pcm3168a_supply_names[i];