Hello,
We have a custom i.MX8QM board, and the MCLK input pin on the PCM3168A audio codec is routed to the MIPI_CSI0_MCLK_OUT pin on the iMX8QM.
I have tried adding &csi0_core_lpcg to the clocks section in the device tree instead of &mclkout0_lpcg, but I'm getting errors when try to play an audio file.
How do I enable the MIPI MCLK and set the frequency so that the audio codec can function?
// I2C
pcm3168a: audio-codec@44 {
compatible = "ti,pcm3168a";
reg = <0x44>;
reset-gpios = <&lsio_gpio4 24 GPIO_ACTIVE_LOW>;
clocks = <&csi0_core_lpcg 0>;
clock-names = "scki";
assigned-clocks = <&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_PLL>,
<&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_SLV_BUS>,
<&clk IMX_SC_R_AUDIO_PLL_0 IMX_SC_PM_CLK_MST_BUS>,
<&csi0_core_lpcg 0>;
assigned-clock-rates = <36864000>, <24576000>, <12288000>, <12288000>;
#sound-dai-cells = <0>;
VDD1-supply = <®_3v3>;
VDD2-supply = <®_3v3>;
VCCAD1-supply = <®_5v0>;
VCCAD2-supply = <®_5v0>;
VCCDA1-supply = <®_5v0>;
VCCDA2-supply = <®_5v0>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_audio_reset &pinctrl_codec_clk>;
};
// IOMUX
pinctrl_codec_clk: codec_clk {
fsl,pins = <
IMX8QM_MIPI_CSI0_MCLK_OUT_MIPI_CSI0_ACM_MCLK_OUT 0xc0000020
>;
};
# aplay some_audio.wav
[ 59.878902] pcm3168a 4-0044: unsupported sysclk ratio
[ 59.884023] pcm3168a 4-0044: ASoC: error at snd_soc_dai_hw_params on pcm3168a-dac: -22
[ 59.892294] 59040000.sai-pcm3168a-dac: ASoC: soc_pcm_hw_params() failed (-22)
ALSA lib ../../../alsa-lib-1.2.6.1/src/pcm/pcm_direct.c:1305:(snd1_pcm_direct_initialize_slave) unable to
install hw params
ALSA lib ../../../alsa-lib-1.2.6.1/src/pcm/pcm_dmix.c:1013:(snd_pcm_dmix_open) unable to initialize slave
aplay: main:831: audio open error: Invalid argument
解決済! 解決策の投稿を見る。
I ended up resolving this by adding an external clock for now. My device tree now looks like this:
codec_osc: fixed-22579200 {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <22579200>;
clock-accuracy = <20000>;
};
sound_card: sound-card {
compatible = "simple-audio-card";
simple-audio-card,name = "PCM3168A";
simple-audio-card,widgets =
"Speaker", "Channel1out",
"Speaker", "Channel2out",
"Speaker", "Channel3out",
"Speaker", "Channel4out",
"Speaker", "Channel5out",
"Speaker", "Channel6out",
"Speaker", "Channel7out",
"Speaker", "Channel8out",
"Microphone", "Channel1in",
"Microphone", "Channel2in",
"Line", "Channel3in",
"Line", "Channel4in";
simple-audio-card,routing =
"Channel1out", "AOUT1L",
"Channel2out", "AOUT1R",
"Channel3out", "AOUT2L",
"Channel4out", "AOUT2R",
"Channel5out", "AOUT3L",
"Channel6out", "AOUT3R",
"Channel7out", "AOUT4L",
"Channel8out", "AOUT4R",
"AIN1L", "Channel1in",
"AIN1R", "Channel2in",
"AIN2L", "Channel3in",
"AIN2R", "Channel4in";
simple-audio-card,dai-link@0 {
format = "left_j";
bitclock-master = <&pcm3168_dac>;
frame-master = <&pcm3168_dac>;
mclk-fs = <512>;
cpu {
sound-dai = <&sai0>;
dai-tdm-slot-num = <8>;
dai-tdm-slot-width = <32>;
};
pcm3168_dac: codec {
sound-dai = <&pcm3168a 0>;
clocks = <&codec_osc>;
dai-tdm-slot-num = <8>;
dai-tdm-slot-width = <32>;
};
};
simple-audio-card,dai-link@1 {
format = "left_j";
bitclock-master = <&pcm3168_adc>;
frame-master = <&pcm3168_adc>;
cpu {
sound-dai = <&sai0>;
dai-tdm-slot-num = <8>;
dai-tdm-slot-width = <32>;
};
pcm3168_adc: codec {
sound-dai = <&pcm3168a 1>;
clocks = <&codec_osc>;
dai-tdm-slot-num = <8>;
dai-tdm-slot-width = <32>;
};
};
};
pcm3168a: audio-codec@44 {
compatible = "ti,pcm3168a";
reg = <0x44>;
reset-gpios = <&lsio_gpio4 24 GPIO_ACTIVE_LOW>;
clocks = <&codec_osc>;
clock-names = "scki";
clock-frequency = <22579200>;
#sound-dai-cells = <1>;
VDD1-supply = <®_3v3>;
VDD2-supply = <®_3v3>;
VCCAD1-supply = <®_5v0>;
VCCAD2-supply = <®_5v0>;
VCCDA1-supply = <®_5v0>;
VCCDA2-supply = <®_5v0>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_audio_reset>;
};
I ended up resolving this by adding an external clock for now. My device tree now looks like this:
codec_osc: fixed-22579200 {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <22579200>;
clock-accuracy = <20000>;
};
sound_card: sound-card {
compatible = "simple-audio-card";
simple-audio-card,name = "PCM3168A";
simple-audio-card,widgets =
"Speaker", "Channel1out",
"Speaker", "Channel2out",
"Speaker", "Channel3out",
"Speaker", "Channel4out",
"Speaker", "Channel5out",
"Speaker", "Channel6out",
"Speaker", "Channel7out",
"Speaker", "Channel8out",
"Microphone", "Channel1in",
"Microphone", "Channel2in",
"Line", "Channel3in",
"Line", "Channel4in";
simple-audio-card,routing =
"Channel1out", "AOUT1L",
"Channel2out", "AOUT1R",
"Channel3out", "AOUT2L",
"Channel4out", "AOUT2R",
"Channel5out", "AOUT3L",
"Channel6out", "AOUT3R",
"Channel7out", "AOUT4L",
"Channel8out", "AOUT4R",
"AIN1L", "Channel1in",
"AIN1R", "Channel2in",
"AIN2L", "Channel3in",
"AIN2R", "Channel4in";
simple-audio-card,dai-link@0 {
format = "left_j";
bitclock-master = <&pcm3168_dac>;
frame-master = <&pcm3168_dac>;
mclk-fs = <512>;
cpu {
sound-dai = <&sai0>;
dai-tdm-slot-num = <8>;
dai-tdm-slot-width = <32>;
};
pcm3168_dac: codec {
sound-dai = <&pcm3168a 0>;
clocks = <&codec_osc>;
dai-tdm-slot-num = <8>;
dai-tdm-slot-width = <32>;
};
};
simple-audio-card,dai-link@1 {
format = "left_j";
bitclock-master = <&pcm3168_adc>;
frame-master = <&pcm3168_adc>;
cpu {
sound-dai = <&sai0>;
dai-tdm-slot-num = <8>;
dai-tdm-slot-width = <32>;
};
pcm3168_adc: codec {
sound-dai = <&pcm3168a 1>;
clocks = <&codec_osc>;
dai-tdm-slot-num = <8>;
dai-tdm-slot-width = <32>;
};
};
};
pcm3168a: audio-codec@44 {
compatible = "ti,pcm3168a";
reg = <0x44>;
reset-gpios = <&lsio_gpio4 24 GPIO_ACTIVE_LOW>;
clocks = <&codec_osc>;
clock-names = "scki";
clock-frequency = <22579200>;
#sound-dai-cells = <1>;
VDD1-supply = <®_3v3>;
VDD2-supply = <®_3v3>;
VCCAD1-supply = <®_5v0>;
VCCAD2-supply = <®_5v0>;
VCCDA1-supply = <®_5v0>;
VCCDA2-supply = <®_5v0>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_audio_reset>;
};
MIPI_CSI0_MCLK_OUT is for camera used, not for audio codec.
Hi @jimmychan ,
Thank you for the response. Yes, I am aware that this pin is meant for a camera, but it was an oversight by our hardware team. According to the PCM3168A datasheet, any clock will do and it can be an external clock. So basically, I would like to re-purpose the MIPI MCLK pin as a clock with a specific frequency. I searched for examples on how to do this, but so far I have not found any. Is there a way to do this?