Hi there,
I am trying to switch my codec configuration to set the SAI of my IMX7D as master as I want to multiplex several codecs with the same SAI, my codec is TI tlv320aic3104.
My Linux kernel version is iMX 4.14.
I've changed my configuration but can't hear sound when I run some tests with speaker-test.
Here is my config, any idea of what is wrong?
&sai2 {
#sound-dai-cells = <1>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_sai2 &pinctrl_codec_reset &pinctrl_audio_ctrl>;
assigned-clocks = <&clks IMX7D_SAI2_ROOT_SRC>,
<&clks IMX7D_SAI2_ROOT_CLK>;
assigned-clock-parents = <&clks IMX7D_PLL_AUDIO_POST_DIV>;
assigned-clock-rates = <0>, <12288000>;
fsl,sai-synchronous-rx;
fsl,sai-mclk-direction-output;
status = "okay";
};
sound-codec {
compatible = "simple-audio-card";
status = "okay";
simple-audio-card,name = "EG4-Sound-Card";
simple-audio-card,format = "i2s";
simple-audio-card,bitclock-master = <&dailink0_master>;
simple-audio-card,frame-master = <&dailink0_master>;
simple-audio-card,widgets =
"Speaker", "Speaker",
"Line", "LineOut",
"Headphone", "Ambient",
"Microphone", "SpeakerMic",
"Microphone", "AmbientMic";
simple-audio-card,routing =
"Speaker", "LLOUT",
"LineOut", "RLOUT",
"Ambient", "HPLOUT",
"LINE1L", "SpeakerMic",
"LINE1R", "AmbientMic";
dailink0_master: simple-audio-card,cpu {
sound-dai = <&sai2 0>;
system-clock-frequency = <12288000>;
};
simple-audio-card,codec {
sound-dai = <&tlv320aic3104>;
clocks = <&clks IMX7D_SAI2_ROOT_CLK>;
system-clock-frequency = <12288000>;
};
};
tlv320aic3104: tlv320aic3104@18 {
#sound-dai-cells = <0>;
compatible = "ti,tlv320aic3104";
reg = <0x18>;
gpio-reset = <&gpio2 10 0>;
clocks = <&clks IMX7D_SAI2_ROOT_CLK>;
clock-names = "mclk";
assigned-clocks = <&clks IMX7D_PLL_AUDIO_POST_DIV>,
<&clks IMX7D_AUDIO_MCLK_ROOT_DIV>;
assigned-clock-rates = <884736000>,
<12288000>;
AVDD-supply = <&avdd>;
DRVDD-supply = <&avdd>;
IOVDD-supply = <&iovdd>;
DVDD-supply = <&dvdd>;
};
pinctrl_sai2: sai2grp {
fsl,pins = <
MX7D_PAD_SAI1_MCLK__SAI2_MCLK 0x04
MX7D_PAD_SAI2_TX_BCLK__SAI2_TX_BCLK 0x1c
MX7D_PAD_SAI2_TX_SYNC__SAI2_TX_SYNC 0x1c
MX7D_PAD_SAI2_TX_DATA__SAI2_TX_DATA0 0x04
MX7D_PAD_SAI2_RX_DATA__SAI2_RX_DATA0 0x1c
>;
};
Many thanks,
已解决! 转到解答。
I finally found the answer to my question, it seems that there is an issue on iMX7D SoC as mentioned on this document https://www.nxp.com/docs/en/errata/IMX7DS_3N09P.pdf page 14.
ERR011096: SAI: Internal bit clock is not generated when RCR2[BCI]=1 or TCR2[BCI]=1
Description
When the SAI transmitter or receiver is configured for internal bit clock with BCI = 1, the bit clock is not generated for either of the
following two configurations:
a) SYNC = 00 and BCS = 0
b) SYNC = 01 and BCS = 1
Workaround
When the SAI transmitter or receiver is configured for internal bit clock with BCI=1, use only one of the following two configurations:
a) SYNC = 01 and BCS = 0
b) SYNC = 00 and BCS = 1
The solution to set the SAI as master is to create a kind of mix between a master/slave configuration, this probably requires a workaround from an HW point of view.
It seems also that the classic GPIOs have to be redirected because of that issue, here is an example between my configuration and another one from Variscite of what it could look like :
I voluntarily switched to SAI1
&sai1 {
#sound-dai-cells = <1>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_sai1 &pinctrl_sai1_mclk>;
assigned-clocks = <&clks IMX7D_SAI1_ROOT_SRC>,
<&clks IMX7D_SAI1_ROOT_CLK>;
assigned-clock-parents = <&clks IMX7D_PLL_AUDIO_POST_DIV>;
assigned-clock-rates = <0>, <36864000>;
status = "okay";
};
&clks {
assigned-clocks = <&clks IMX7D_PLL_AUDIO_POST_DIV>;
assigned-clock-rates = <884736000>;
};
sound-codec {
compatible = "simple-audio-card";
status = "okay";
simple-audio-card,name = "EG4-Sound-Card";
simple-audio-card,widgets =
"Speaker", "Speaker",
"Line", "LineOut",
"Headphone", "Ambient",
"Microphone", "SpeakerMic",
"Microphone", "AmbientMic";
simple-audio-card,routing =
"Speaker", "LLOUT",
"LineOut", "RLOUT",
"Ambient", "HPLOUT",
"LINE1L", "SpeakerMic",
"LINE1R", "AmbientMic";
simple-audio-card,format = "i2s";
simple-audio-card,bitclock-master = <&dailink0_master>;
simple-audio-card,frame-master = <&dailink0_master>;
/*simple-audio-card,bitclock-inversion;*/
assigned-clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_SRC>,
<&clks IMX7D_AUDIO_MCLK_ROOT_CLK>;
assigned-clock-parents = <&clks IMX7D_PLL_AUDIO_POST_DIV>;
assigned-clock-rates = <0>, <12288000>;
dailink0_master: simple-audio-card,cpu {
sound-dai = <&sai1 0>;
};
simple-audio-card,codec {
sound-dai = <&tlv320aic3104>;
system-clock-frequency = <12288000>;
};
};
tlv320aic3104: tlv320aic3104@18 {
#sound-dai-cells = <0>;
compatible = "ti,tlv320aic3104";
reg = <0x18>;
gpio-reset = <&gpio2 10 0>;
clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_CLK>;
clock-names = "mclk";
AVDD-supply = <&avdd>;
DRVDD-supply = <&avdd>;
IOVDD-supply = <&dvdd>;
DVDD-supply = <&dvdd>;
};
GPIOs configuration to be tested and confirmed but the classic SAI outputs can't be used in that case and must be redirected to LPSR GPIOs:
pinctrl_sai1: sai1grp {
fsl,pins = <
MX7D_PAD_ENET1_RX_CLK__SAI1_TX_BCLK 0x1f
MX7D_PAD_ENET1_CRS__SAI1_TX_SYNC 0x1f
MX7D_PAD_ENET1_COL__SAI1_TX_DATA0 0x30
MX7D_PAD_ENET1_TX_CLK__SAI1_RX_DATA0 0x1f
>;
};
pinctrl_sai1_mclk: sai1grp_mclk {
fsl,pins = <
MX7D_PAD_LPSR_GPIO1_IO01__SAI1_MCLK 0x1f
>;
};
I finally found the answer to my question, it seems that there is an issue on iMX7D SoC as mentioned on this document https://www.nxp.com/docs/en/errata/IMX7DS_3N09P.pdf page 14.
ERR011096: SAI: Internal bit clock is not generated when RCR2[BCI]=1 or TCR2[BCI]=1
Description
When the SAI transmitter or receiver is configured for internal bit clock with BCI = 1, the bit clock is not generated for either of the
following two configurations:
a) SYNC = 00 and BCS = 0
b) SYNC = 01 and BCS = 1
Workaround
When the SAI transmitter or receiver is configured for internal bit clock with BCI=1, use only one of the following two configurations:
a) SYNC = 01 and BCS = 0
b) SYNC = 00 and BCS = 1
The solution to set the SAI as master is to create a kind of mix between a master/slave configuration, this probably requires a workaround from an HW point of view.
It seems also that the classic GPIOs have to be redirected because of that issue, here is an example between my configuration and another one from Variscite of what it could look like :
I voluntarily switched to SAI1
&sai1 {
#sound-dai-cells = <1>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_sai1 &pinctrl_sai1_mclk>;
assigned-clocks = <&clks IMX7D_SAI1_ROOT_SRC>,
<&clks IMX7D_SAI1_ROOT_CLK>;
assigned-clock-parents = <&clks IMX7D_PLL_AUDIO_POST_DIV>;
assigned-clock-rates = <0>, <36864000>;
status = "okay";
};
&clks {
assigned-clocks = <&clks IMX7D_PLL_AUDIO_POST_DIV>;
assigned-clock-rates = <884736000>;
};
sound-codec {
compatible = "simple-audio-card";
status = "okay";
simple-audio-card,name = "EG4-Sound-Card";
simple-audio-card,widgets =
"Speaker", "Speaker",
"Line", "LineOut",
"Headphone", "Ambient",
"Microphone", "SpeakerMic",
"Microphone", "AmbientMic";
simple-audio-card,routing =
"Speaker", "LLOUT",
"LineOut", "RLOUT",
"Ambient", "HPLOUT",
"LINE1L", "SpeakerMic",
"LINE1R", "AmbientMic";
simple-audio-card,format = "i2s";
simple-audio-card,bitclock-master = <&dailink0_master>;
simple-audio-card,frame-master = <&dailink0_master>;
/*simple-audio-card,bitclock-inversion;*/
assigned-clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_SRC>,
<&clks IMX7D_AUDIO_MCLK_ROOT_CLK>;
assigned-clock-parents = <&clks IMX7D_PLL_AUDIO_POST_DIV>;
assigned-clock-rates = <0>, <12288000>;
dailink0_master: simple-audio-card,cpu {
sound-dai = <&sai1 0>;
};
simple-audio-card,codec {
sound-dai = <&tlv320aic3104>;
system-clock-frequency = <12288000>;
};
};
tlv320aic3104: tlv320aic3104@18 {
#sound-dai-cells = <0>;
compatible = "ti,tlv320aic3104";
reg = <0x18>;
gpio-reset = <&gpio2 10 0>;
clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_CLK>;
clock-names = "mclk";
AVDD-supply = <&avdd>;
DRVDD-supply = <&avdd>;
IOVDD-supply = <&dvdd>;
DVDD-supply = <&dvdd>;
};
GPIOs configuration to be tested and confirmed but the classic SAI outputs can't be used in that case and must be redirected to LPSR GPIOs:
pinctrl_sai1: sai1grp {
fsl,pins = <
MX7D_PAD_ENET1_RX_CLK__SAI1_TX_BCLK 0x1f
MX7D_PAD_ENET1_CRS__SAI1_TX_SYNC 0x1f
MX7D_PAD_ENET1_COL__SAI1_TX_DATA0 0x30
MX7D_PAD_ENET1_TX_CLK__SAI1_RX_DATA0 0x1f
>;
};
pinctrl_sai1_mclk: sai1grp_mclk {
fsl,pins = <
MX7D_PAD_LPSR_GPIO1_IO01__SAI1_MCLK 0x1f
>;
};
Hello,
Yes, you should have something like this:
I suggest you check the reference device tree for i.MX7D or the reference device tree for i.MX8MM that also uses "simple-audio-card".
Best regards.
Hello, I hope you are doing well.
You said, "I've changed my configuration but can't hear sound when I run some tests with speaker-test", did you was able to hear sound from the codec with a previous configuration?
I suggest you take a look at Chapter 16 Porting Audio Codecs i.MX Porting Guide.
Best regards.
Hi Jorge,
Yes, I did, with the same i2s and i2c configuration and the codec as master, I can hear sound, here are more logs :
[ 3.782982] asoc-simple-card sound-codec: tlv320aic3x-hifi <-> 308b0000.sai mapping ok
[ 3.796342] rtc-pcf85063 3-0051: setting system clock to 2023-08-01 07:41:03 UTC (1690875663)
[ 3.820909] usb_otg1_vbus: disabling
[ 3.824515] A3V3: disabling
[ 3.827327] D3V3: disabling
[ 3.830174] D1V8: disabling
[ 3.832987] VDD_SD1: disabling
[ 3.836070] ALSA device list:
[ 3.839076] #0: EG4-Sound-Card
root@hdl-eg4:~# aplay -L
null
Discard all samples (playback) or generate zero samples (capture)
sysdefault:CARD=EG4SoundCard
EG4-Sound-Card,
Default Audio Device
root@hdl-eg4:~# speaker-test -Dsysdefault:CARD=EG4SoundCard -f 4000 -tsine -S 100
speaker-test 1.2.1
Playback device is sysdefault:CARD=EG4SoundCard
Stream parameters are 48000Hz, S16_LE, 1 channels
Sine wave rate is 4000.0000Hz
Rate set to 48000Hz (requested 48000Hz)
Buffer size range from 64 to 16384
Period size range from 32 to 8192
Using max buffer size 16384
Periods = 4
was set period_size = 4096
was set buffer_size = 16384
0 - Front Left
Time per period = 2.653695
0 - Front Left
Time per period = 2.986700
0 - Front Left
As you can see speaker-test works well but I can't hear no sound.
Same test but codec is master :
[ 70.836270] fsl-sai 308b0000.sai: ASoC: Store rate : 48000
[ 96.522594] fsl-sai 308b0000.sai: ASoC: Store rate : 48000
[ 340.312911] fsl-sai 308b0000.sai: ASoC: Store rate : 48000
root@hdl-eg4:~# alsamixer -c1
root@hdl-eg4:~# speaker-test -Dsysdefault:CARD=EG4SoundCard -f 4000 -tsine -S 100
speaker-test 1.2.1
Playback device is sysdefault:CARD=EG4SoundCard
Stream parameters are 48000Hz, S16_LE, 1 channels
Sine wave rate is 4000.0000Hz
Rate set to 48000Hz (requested 48000Hz)
Buffer size range from 64 to 16384
Period size range from 32 to 8192
Using max buffer size 16384
Periods = 4
was set period_size = 4096
was set buffer_size = 16384
0 - Front Left
Time per period = 2.653926
0 - Front Left
Time per period = 2.986455
0 - Front Left
Time per period = 2.98