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.

variable master clock

Other Parts Discussed in Thread: PCM5102A

I'm designing an Linux audio device driver with a variable external master clock for a Beaglebone Black. The clock is switchable between 22.5792 MHz and 24.576 MHz via a GPIO pin, and the driver knows which setting is in effect. In my dts file I have

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

I would like ALSA and the Davinci EVM driver to recognize when I select a sample rate, say 44.1 kHz or 48.0 kHz, and automatically choose the correct setting for the master clock. Ideally this would happen each time the device is opened, but it would be acceptable if this happened at boot time.

I guess that I can simply read the GPIO pin in davinci-evm.c evm_hw_params and override the default value of local variable sysclk before calling snd_soc_dai_set_sysclk. Will this work, or is there more to it? Maybe I need to update the soc_card drvdata structure instead?

Eventually I could figure this out, but the code is SO complicated, maybe someone already has done this and can save me a lot of time.

  • The following code at least executes and outputs valid I2S signals to my scope. pcm5102a_hw_params is based on http://processors.wiki.ti.com/index.php/Sitara_Linux_SDK_Audio_DAC_Example.


    in dts:

                    ti,codec-clock-rate = <24576000>;

    in davinci-evm.c (from linux 3.15.4) function pcm5102a_hw_params:

            unsigned int * sysclkptr = &((struct snd_soc_card_drvdata_davinci *)
                                       snd_soc_card_get_drvdata(soc_card))->sysclk;
            unsigned int sysclk = 22579200; // testing, actual value will be determined from sample rate
            //unsigned sysclk = ((struct snd_soc_card_drvdata_davinci *)
            //                 snd_soc_card_get_drvdata(soc_card))->sysclk;
            ...
            *sysclkptr = sysclk;