AnsweredAssumed Answered

clock set up for a simple-audio-card

Question asked by Kapil Bhutani on Sep 19, 2019
Latest reply on Sep 22, 2019 by Kapil Bhutani

I want to know a working example of DTS for sai, codec and simple-audio-card in kernel 5.0.5

using imx8mq and ti, pcm3060, specially from the clocks perspective.

 

I have got a sound card through the simple-audio-card, but when I try to play back a WAV file using aplay, it fails in hw_params check inside fsl_sai driver.

Here are the details.

 

Hi

I am working on getting simple_audio_card work for imx8mq and pcm3060 codec, I am on kernel version 5.05 and it appears both the the platform driver (fsl_sai) and the codec driver (pcm3060) support the ASOC design and the simple audio card. Here is the snapshot of my dts for simple audio card

  • Add pcm3060 on espi2

&ecspi2 {

  fsl,spi-num-chipselects = <1>;

  cs-gpios = <&gpio5 13 0>;

  pinctrl-names = "default";

  pinctrl-0 = <&pinctrl_ecspi2>;

  status = "okay";

 

  // As per the IMX8MDQLQRM applications processors reference manual PDF

  // 7.1.4 SDMA event mapping

  // NOTES:

  //  - our transfer sizes aren't big enough to justify DMA

  //  - we need a patched imx-smda.c unless we're using Linux 5.1 or newer

  // dmas = <&sdma1 2 7 0>, <&sdma1 3 7 0>;

  // dma-names = "rx", "tx";

 

  pcm3060: pcm3060@0 {

      #sound-dai-cells = <0>;

      compatible = "pcm3060";

      spi-max-frequency = <20000000>;

      reg = <0>;

  };

};

 

  • Add a new sai device

        sai1: sai@30010000 {

                #sound-dai-cells = <0>;

                compatible = "fsl,imx8mq-sai",

                            "fsl,imx6sx-sai";

                reg = <0x0 0x30010000 0x0 0x10000>;

                interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;

                clocks = <&clk IMX8MQ_CLK_SAI1_IPG>,

                        <&clk IMX8MQ_CLK_SAI1_ROOT>,

                        <&clk IMX8MQ_AUDIO_PLL1>,

                        <&clk IMX8MQ_CLK_DUMMY>;

                clock-names = "bus", "mclk1", "mclk2", "mclk3";

                dmas = <&sdma1 10 24 0>, <&sdma1 11 24 0>;

                dma-names = "rx", "tx";

                fsl,dataline = <0xff 0xff>;

                status = "disabled";

        };

 

  • Enable sai and assign clocks

&sai1 {

        #sound-dai-cells = <0>;

        pinctrl-names = "default";

        pinctrl-0 = <&pinctrl_sai1>;

        assigned-clocks = <&clk IMX8MQ_SAI1>;       

        assigned-clock-parents = <&clk IMX8MQ_AUDIO_PLL1_OUT>;

        assigned-clock-rates = <49152000>;

        status = "okay";

};

 

  • Define sai pin controls

                pinctrl_sai1: sai1grp {

                        fsl,pins = <

                                MX8MQ_IOMUXC_SAI1_MCLK_SAI1_MCLK                0xd6

                                MX8MQ_IOMUXC_SAI1_TXFS_SAI1_TX_SYNC            0xd6

                                MX8MQ_IOMUXC_SAI1_TXC_SAI1_TX_BCLK              0xd6

                                MX8MQ_IOMUXC_SAI1_TXD0_SAI1_TX_DATA0            0xd6

                                MX8MQ_IOMUXC_SAI1_RXD0_SAI1_RX_DATA0            0xd6

                        >;

                };

 

 

 

  • Define simple sound card

 

        sound {

        compatible = "simple-audio-card";

        simple-audio-card,name = "pcm3060-audio";

        simple-audio-card,format = "i2s";

        simple-audio-card,bitclock-master = <&dai_cpu>;

        simple-audio-card,frame-master = <&dai_cpu>;

        simple-audio-card,widgets =

                "Line", "Balanced In",

                "Line", "Balanced Out",

                "Line", "Unbalanced Out",

                "Line", "Unbalanced In";

        simple-audio-card,routing =

                "INL", "Balanced In",

                "INR", "Unbalanced In",

                "Balanced Out", "OUTL",

                "Unbalanced Out", "OUTR";

 

        dai_cpu:  simple-audio-card,cpu {

                sound-dai = <&sai1>;

        };

 

        dai0-codec: simple-audio-card,codec {

                sound-dai = <&pcm3060>;

                clocks = <&clk IMX8MQ_CLK_SAI1_ROOT>;

        };

 

  • Assign AUDIO_PLL1 to the desired frequency


&clk {

        assigned-clocks = <&clk IMX8MQ_AUDIO_PLL1>;

        assigned-clock-rates = <49152000>;

};

Issue

 The device tree specifically the clocks for sai. This is based on what is used on upstream (5.2.x) and NXP maintained 4.19.y for i.MX8mq branch. On upstream, they provide the bus clock and only one master clock (mclk1). This configuration is not fails when I am trying to playback an audio wav file. When the sai driver tries to set the bitclock for i2s. (sound/soc/fsl/fsl_sai.c :: fsl_sai_set_bclk), the m_clck provided to the driver [as specified in the dts] does not match the requirement of the sample rate of the audio being played. Following the code snippet of that function with my addition logging. 

 

        sai1: sai@30010000 {

                #sound-dai-cells = <0>;

                compatible = "fsl,imx8mq-sai",

                            "fsl,imx6sx-sai";

                reg = <0x0 0x30010000 0x0 0x10000>;

                interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;

                clocks = <&clk IMX8MQ_CLK_SAI1_IPG>,

                        <&clk IMX8MQ_CLK_SAI1_ROOT>,

                        <&clk IMX8MQ_AUDIO_PLL1>,<-------------------------- On upstream it is IMX8MQ_CLK_DUMMY, I supplied AUDIO_PLL1 as one of the mclk and it does fit for the stream playback, but fails when it tries to prepare and enable that clock.

                        <&clk IMX8MQ_CLK_DUMMY>;

                clock-names = "bus", "mclk1", "mclk2", "mclk3";

                dmas = <&sdma1 10 24 0>, <&sdma1 11 24 0>;

                dma-names = "rx", "tx";

                fsl,dataline = <0xff 0xff>;

                status = "disabled";

        };

 

&sai1 {

        #sound-dai-cells = <0>;

        pinctrl-names = "default";

        pinctrl-0 = <&pinctrl_sai1>;

        assigned-clocks = <&clk IMX8MQ_SAI1>;     

        assigned-clock-parents = <&clk IMX8MQ_AUDIO_PLL1_OUT>;

        assigned-clock-rates = <49152000>;

        status = "okay";

};

 

&clk {

        assigned-clocks = <&clk IMX8MQ_AUDIO_PLL1>;

        assigned-clock-rates = <49152003>;

};

 

 

I get following logs

 

2018-03-09T12:39:49.515972+00:00 localhost kernel: [  336.690525] 001: fsl-sai 30010000.sai: inside fsl_sai_hw_params  channels=2 word_width=24 slots=2 slot_width=24

2018-03-09T12:39:49.516023+00:00 localhost kernel: [  336.690545] 001: fsl-sai 30010000.sai: inside fsl_sai_set_bclk for freq: 768000Hz

2018-03-09T12:39:49.516028+00:00 localhost kernel: [  336.690554] 001: fsl-sai 30010000.sai: failed to get the required clock rate 12500000Hz for frequency: 768000Hz ----> bus

2018-03-09T12:39:49.516032+00:00 localhost kernel: [  336.690563] 001: fsl-sai 30010000.sai: failed to get the required clock rate 25000000Hz for frequency: 768000Hz -----> mclk1 --- > SAI1_ROOT

2018-03-09T12:39:49.516036+00:00 localhost kernel: [  336.690571] 001: fsl-sai 30010000.sai: ratio 64 for freq 768000Hz based on clock 49152001Hz      -----------------------------------------> mclk2 ---> AUDIO_PLL1  ---->    it is configured to run at a desirable rate, but fails when the driver tries to prepare and enable the clock.

2018-03-09T12:39:49.516039+00:00 localhost kernel: [  336.690579] 001: fsl-sai 30010000.sai: failed to get the clock 0Hz for frequency: 768000Hz

2018-03-09T12:39:49.516046+00:00 localhost kernel: [  336.690602] 001: fsl-sai 30010000.sai: best fit: clock id=2, div=32, deviation =1

2018-03-09T12:39:49.516050+00:00 localhost kernel: [  336.700617] 001: fsl-sai 30010000.sai: inside fsl_sai_hw_params could not prepare clk with clock id: 2

2018-03-09T12:39:49.526003+00:00 localhost kernel: [  336.701229] 001: fsl-sai 30010000.sai: ASoC: can't set 30010000.sai hw params: -110

 

Can you please tell me that how were the clock arrangements in you device tree when you made it work with simple audio card

Cheers

Outcomes