Using MIPI MCLK for audio codec clock

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Using MIPI MCLK for audio codec clock

Jump to solution
418 Views
jsmith8831
Contributor III

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 = <&reg_3v3>;
	VDD2-supply = <&reg_3v3>;
	VCCAD1-supply = <&reg_5v0>;
	VCCAD2-supply = <&reg_5v0>;
	VCCDA1-supply = <&reg_5v0>;
	VCCDA2-supply = <&reg_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

 

0 Kudos
1 Solution
247 Views
jsmith8831
Contributor III

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 = <&reg_3v3>;
		VDD2-supply = <&reg_3v3>;
		VCCAD1-supply = <&reg_5v0>;
		VCCAD2-supply = <&reg_5v0>;
		VCCDA1-supply = <&reg_5v0>;
		VCCDA2-supply = <&reg_5v0>;
		pinctrl-names = "default";
		pinctrl-0 = <&pinctrl_audio_reset>;
	};

View solution in original post

3 Replies
248 Views
jsmith8831
Contributor III

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 = <&reg_3v3>;
		VDD2-supply = <&reg_3v3>;
		VCCAD1-supply = <&reg_5v0>;
		VCCAD2-supply = <&reg_5v0>;
		VCCDA1-supply = <&reg_5v0>;
		VCCDA2-supply = <&reg_5v0>;
		pinctrl-names = "default";
		pinctrl-0 = <&pinctrl_audio_reset>;
	};
392 Views
jimmychan
NXP TechSupport
NXP TechSupport

MIPI_CSI0_MCLK_OUT is for camera used, not for audio codec.

0 Kudos
385 Views
jsmith8831
Contributor III

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?

0 Kudos