This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Linux/AM3358: Question about use internal clock for McASP with TISDK5.0.0.15

Part Number: AM3358
Other Parts Discussed in Thread: PCM5102A

Tool/software: Linux

Hi, I'm Roy.

I need to transfer PCM formatted data (8kHz samplerate / 16bit per sample / stereo) via McASP0 on BBB.

I found some articles and apply to my system like below:

- delete McASP0 pinmuxing  and related things in am335x-boneblack-common.dtsi.

- add McASP0 pinmuxing and PCM5102a codec binding to am335x-boneblack-pcm5102a-int_clk.dtsi:

&am33xx_pinmux {
        mcasp0_pins: mcasp0_pins {
                pinctrl-single,pins = <
                        AM33XX_IOPAD(0x990, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mcasp0_aclkx.mcasp0_aclkx */
                        AM33XX_IOPAD(0x994, PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* mcasp0_fsx.mcasp0_fsx */
                        AM33XX_IOPAD(0x998, PIN_INPUT_PULLDOWN | MUX_MODE0) /* mcasp0_axr0.mcasp0_axr0 */
                        AM33XX_IOPAD(0x99c, PIN_OUTPUT_PULLDOWN | MUX_MODE2) /* mcasp0_ahclkr.mcasp0_axr2*/
                >;
        };

        mcasp0_pins_sleep: mcasp0_pins_sleep {
                pinctrl-single,pins = <
                        AM33XX_IOPAD(0x990, PIN_INPUT_PULLDOWN | MUX_MODE7)
                        AM33XX_IOPAD(0x994, PIN_INPUT_PULLDOWN | MUX_MODE7)
                        AM33XX_IOPAD(0x998, PIN_INPUT_PULLDOWN | MUX_MODE7)
                        AM33XX_IOPAD(0x99c, PIN_INPUT_PULLDOWN | MUX_MODE7)
                >;
        };
};

&mcasp0 {
        #sound-dai-cells = <0>;
        pinctrl-names = "default";
        pinctrl-0 = <&mcasp0_pins>;
        pinctrl-1 = <&mcasp0_pins_sleep>;

        status = "okay";

        op-mode = <0>; /* MCASP_IIS_MODE */
        tdm-slots = <2>;
        /* 4 serializers */
        serial-dir = < /* 1 TX 2 RX 0 unused */
                2 0 1 0
        >;
        rx-num-evt = <32>;
        tx-num-evt = <32>;
};

/ {
        pcm5102a: pcm5102a {
                compatible = "ti,pcm5102a";
        };

        clk_mcasp0_fixed: clk_mcasp0_fixed {
                #clock-cells = <0>;
                compatible = "fixed-clock";
                clock-frequency = <4096000>;
        };

        clk_mcasp0: clk_mcasp0 {
                #clock-cells = <0>;
                clocks = <&clk_mcasp0_fixed>;
        };

        sound {
                compatible = "ti,pcm5102a-evm-audio";
                ti,model = "TI PCM5102A";
                ti,audio-codec = <&pcm5102a>;
                ti,mcasp-controller = <&mcasp0>;
                ti,codec-clock-rate = <4096000>;

                sound1_master: simple-audio-card,cpu {
                        sound-dai = <&mcasp0>;
                        clocks = <&clk_mcasp0>;
                };

                simple-audio-card,codec {
                        sound-dai = <&pcm5102a>;
                };
        };
};

- And include this dts to am335x-boneblack.dts

The PCM5102A codec is detected on my BBB with above and I execute below command:

# aplay ~/1kHz_sinewave_8000_16.wav

I expect FSX is 8kHz but the FSX is 24kHz (three times).  When I try with 16kHz sampled, FSX is 48kHz (three times).  Is it okay?

Can I get your opinion about this issue?

Thanks,

Roy.

  • Sorry, I have missed changes on davinci-evm.c

    #include <sound/pcm_params.h>
    
    static unsigned int evm_get_bclk(struct snd_pcm_hw_params *params)
    {
            int sample_size = snd_pcm_format_width(params_format(params));
            int rate = params_rate(params);
            int channels = params_channels(params);
    
            return sample_size * channels * rate;
    }
    
    static int pcm5102a_hw_params(struct snd_pcm_substream *substream,
                                     struct snd_pcm_hw_params *params)
    {
            struct snd_soc_pcm_runtime *rtd = substream->private_data;
            struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
            struct snd_soc_codec *codec = rtd->codec;
            struct snd_soc_card *soc_card = rtd->card;
            struct platform_device *pdev = to_platform_device(soc_card->dev);
            unsigned int bclk_freq = evm_get_bclk(params);
            unsigned sysclk = ((struct snd_soc_card_drvdata_davinci *)
                               snd_soc_card_get_drvdata(soc_card))->sysclk;
            int ret;
    
            ret = snd_soc_dai_set_clkdiv(cpu_dai, 1, sysclk/bclk_freq);
            if (ret < 0) {
                    dev_err(&pdev->dev, "can't set CPU DAI clock divider %d\n",
                            ret);
                    return ret;
            }
    
            printk(KERN_ERR "@@@ PCM5102a hw params\n");
            printk(KERN_ERR "@@@ sysclk=%d\n", sysclk);
            printk(KERN_ERR "@@@bclk_freq=%d\n", bclk_freq);
            ret = snd_soc_dai_set_sysclk(cpu_dai, 0, sysclk, SND_SOC_CLOCK_OUT);
            if (ret < 0)
                    return ret;
    
            return ret;
    }
    
    ...
    
    static struct snd_soc_ops pcm5102a_ops = {
            .startup = evm_startup,
            .shutdown = evm_shutdown,
            .hw_params = pcm5102a_hw_params,
    };
    
    static struct snd_soc_dai_link evm_dai_pcm5102a = {
            .name           = "PCM5102A",
            .stream_name    = "Playback",
            .codec_dai_name = "pcm5102a-hifi",
            .ops            = &pcm5102a_ops,
            .dai_fmt        = (SND_SOC_DAIFMT_CBS_CFS | SND_SOC_DAIFMT_I2S |
                               SND_SOC_DAIFMT_IB_NF),
    };
    
    ...
    
    static const struct of_device_id davinci_evm_dt_ids[] = {
            {
                    .compatible = "ti,pcm5102a-evm-audio",
                    .data = &evm_dai_pcm5102a,
            },
    ...
    
    

  • Roy,

    AM335x McASP module has multiple sample rates support (8KHz, 16KHz, 22.05KHz, 32KHz, 44.1KHz, 48KHz, 64KHz, 88.2KHz and 96KHz) for both capture and playback. You need to check if PCM5102a codec also support all these sample rates.

    Also I do not see below entries in your DTS file:

    simple-audio-card,bitclock-master
    simple-audio-card,frame-master

    Check below DTS files for reference:

    am335x-boneblack-common.dtsi
    am335x-evm.dts

    You can also explore below docs:

    processors.wiki.ti.com/.../Sitara_Linux_Audio_DAC_Example
    www.ti.com/.../sprac97.pdf
    www.ti.com/.../sprac09a.pdf
    www.ti.com/.../sprac10.pdf

    Regards,
    Pavel
  • Hi, Pavel.

    I have checked examples from your solution.

    Firstly, BCLK and FSYNC is not generated when I apply "sprac97.pdf".

    So, I try to "Sitara Linux Audio DAC Example", there is no entries "simple-audio-card,bitclock-master, simple-audio-card,frame-master", anyway BCLK and FSYNC is generated but I think frequency is wrong.

    Clock source of mcasp0 is "mcasp0_fck", it defined by dts like below:

            sound {
                    compatible = "ti,pcm5102a-evm-audio";
                    ti,model = "TI PCM5102A";
                    ti,audio-codec = <&pcm5102a>;
                    ti,mcasp-controller = <&mcasp0>;
                    ti,codec-clock-rate = <2560000>;
    
                    sound1_master: simple-audio-card,cpu {
                            sound-dai = <&mcasp0>;
                            clocks = <&mcasp0_fck>;
                            /* clocks = <&clk_mcasp0>; */
                    };
    
                    simple-audio-card,codec {
                            sound-dai = <&pcm5102a>;
                    };
            };

    And related register information is like below:

    AFSXCTL     is 0x00000113
    ACLKXCTL   is 0x00180033
    AHCLKXCTL is 0x00188000
    PFUNC         is 0x00000000
    PDIR             is 0xBC000004

    Finally, I played 8kHz rate/mono channel/16 bit per sample, I expect 128kHz BCLK and 8kHz FSYNC, but clock is something is wrong.  Please see below capture: (Signal #1 is BCLK, #2 is FSYNC)

    I have checked ALSA hwparams like below:

    access: RW_INTERLEAVED
    format: S16_LE
    subformat: STD
    channels: 1
    rate: 8000 (8000/1)
    period_size: 1000
    buffer_size: 4000

    I think configuration is no problem, could I get advice about this issue?

    Thanks,

    Roy.

  • Hi, I have confirmed clock configuration is invalid.

    I understand 24MHz AUXCLK can't generate 256kHz BCLK, so I will apply Ext. oscillator for AHCLKX.

    Thanks for your help.