2024-02-12 07:39 PM
Hi,
I need help to setup the DeviceTree for our custom board using STM32MP135FAE7 and TI TLV320AIC3254.
I have read the Wiki about SAI and read and tried to implement SAI using these posts as reference:
No Luck.
And also got confused about where to put the Codec. On the Wiki Page here shows codec under i2c node but on this post there is a comment from @Erwan SZYMANSKI saying that codec should be under root not I2C or I2S. How should I decide where to put it, is it depending on the IC ? What am I missing?
and following those comments, I have enabled the configs related to codec in the config file and updated the kernel and they show up.
CONFIG_SND_SOC_TLV320AIC32X4_I2C=m
CONFIG_SND_SOC_TLV320AIC32X4_SPI=m
root@stm32mp1:~# lsmod
Module Size Used by
cfg80211 663552 0
usb_f_ncm 24576 2
u_ether 20480 1 usb_f_ncm
libcomposite 49152 10 usb_f_ncm
stm32_adc 36864 0
stm32_timer_trigger 20480 1 stm32_adc
stm32_lptimer_trigger 16384 1 stm32_adc
snd_soc_stm32_sai_sub 28672 0
snd_soc_audio_graph_card 16384 0
snd_soc_simple_card_utils 20480 1 snd_soc_audio_graph_card
stm32_adc_core 20480 0
snd_soc_tlv320aic32x4_spi 16384 0
snd_soc_tlv320aic32x4_i2c 16384 0
snd_soc_tlv320aic32x4 36864 2 snd_soc_tlv320aic32x4_spi,snd_soc_tlv320aic32x4_i2c
snd_soc_core 184320 4 snd_soc_audio_graph_card,snd_soc_simple_card_utils,snd_soc_tlv320aic32x4,snd_soc_stm32_sai_sub
snd_soc_stm32_sai 16384 0
snd_pcm_dmaengine 16384 1 snd_soc_core
ac97_bus 16384 1 snd_soc_core
snd_pcm 98304 5 snd_pcm_dmaengine,snd_soc_simple_card_utils,snd_soc_tlv320aic32x4,snd_soc_core,snd_soc_stm32_sai_sub
snd_timer 28672 1 snd_pcm
snd 57344 5 snd_timer,snd_soc_tlv320aic32x4,snd_soc_core,snd_pcm,snd_soc_stm32_sai_sub
soundcore 16384 1 snd
sch_fq_codel 20480 4
ip_tables 24576 0
x_tables 24576 1 ip_tables
ipv6 503808 40
But I don't get any error messages or anything related with the soundcard except the messages below:
root@stm32mp1:~# dmesg |grep sound
root@stm32mp1:~# dmesg |grep audio
[ 0.056931] platform ti-codec: Fixed dependency cycle(s) with /soc/sai@4400a000/audio-controller@4400a024
[ 0.056977] platform ti-codec: Fixed dependency cycle(s) with /soc/sai@4400a000/audio-controller@4400a004
root@stm32mp1:~# dmesg |grep sai
[ 0.056931] platform ti-codec: Fixed dependency cycle(s) with /soc/sai@4400a000/audio-controller@4400a024
[ 0.056977] platform ti-codec: Fixed dependency cycle(s) with /soc/sai@4400a000/audio-controller@4400a004
Here is my devicetree related to SAI part:
/ { /* ROOT */
sound {
compatible = "audio-graph-card";
label = "Prove-Audio-Card";
// routing =
// "Playback" , "MCLK",
// "Capture", "MCLK";
dais = <&sai1a_port>;
status = "okay";
};
codec: ti-codec {
compatible = "ti,tlv320aic32x4";
#sound-dai-cells = <0>;
reset-gpios = <&gpioc 0 GPIO_ACTIVE_LOW>;
ldoin-supply = <&scmi_vdd>;
iov-supply = <&scmi_vdd>;
dv-supply = <&scmi_vdd>;
av-supply = <&scmi_v1v8_periph>;
clocks = <&sai1a>;
clock-names = "mclk";
tlv320aic32x4_port: port {
#address-cells = <1>;
#size-cells = <0>;
tlv320aic32x4_tx_endpoint: endpoint@0 {
reg = <0>;
remote-endpoint = <&sai1a_endpoint>;
frame-master; /* codec is master */
bitclock-master;
};
tlv320aic32x4_rx_endpoint: endpoint@1 {
reg = <1>;
remote-endpoint = <&sai1b_endpoint>;
frame-master; /* codec is master */
bitclock-master;
};
};
};
};
&i2c5{
pinctrl-names = "default", "sleep";
pinctrl-0 = <&i2c5_pins_mx>;
pinctrl-1 = <&i2c5_sleep_pins_mx>;
status = "okay";
/* USER CODE BEGIN i2c5 */
i2c-scl-rising-time-ns = <185>;
i2c-scl-falling-time-ns = <20>;
clock-frequency = <400000>;
/* spare dmas for other usage */
/delete-property/dmas;
/delete-property/dma-names;
/* USER CODE END i2c5 */
};
&sai1{
pinctrl-names = "default", "sleep";
pinctrl-0 = <&sai1a_pins_mx>, <&sai1b_pins_mx>;
pinctrl-1 = <&sai1a_sleep_pins_mx>, <&sai1b_sleep_pins_mx>;
status = "okay";
/* USER CODE BEGIN sai1 */
clocks = <&rcc SAI1>, <&scmi_clk CK_SCMI_PLL3_Q>, <&scmi_clk CK_SCMI_PLL3_R>;
clock-names = "pclk", "x8k", "x11k";
// #sound-dai-cells = <1>;
/* USER CODE END sai1 */
sai1a:audio-controller@4400a004{
status = "okay";
/* USER CODE BEGIN sai1a */
#sound-dai-cells = <0>;
compatible = "st,stm32-sai-sub-a";
dma-names = "tx";
#clock-cells = <0>;
clocks = <&rcc SAI1_K>;
clock-names = "sai_ck";
sai1a_port: port {
sai1a_endpoint: endpoint {
remote-endpoint = <&tlv320aic32x4_tx_endpoint>;
format = "i2s";
mclk-fs = <256>;
dai-tdm-slot-num = <2>;
dai-tdm-slot-width = <32>;
};
};
/* USER CODE END sai1a */
};
sai1b:audio-controller@4400a024{
status = "okay";
/* USER CODE BEGIN sai1b */
#sound-dai-cells = <0>;
dma-names = "rx"; /* SAI set as receiver */
st,sync = <&sai1a 1>; /* SAI1B is slave of SAI1A */
clocks = <&rcc SAI1_K>, <&sai1a>;
clock-names = "sai_ck", "mclk";
sai1b_port: port {
sai1b_endpoint: endpoint {
remote-endpoint = <&tlv320aic32x4_rx_endpoint>;
format = "i2s";
mclk-fs = <256>;
dai-tdm-slot-num = <2>;
dai-tdm-slot-width = <32>;
};
};
};
};
&pinctrl {
i2c5_pins_mx: i2c5_mx-0 {
pins {
pinmux = <STM32_PINMUX('F', 3, AF4)>, /* I2C5_SDA */
<STM32_PINMUX('H', 13, AF4)>; /* I2C5_SCL */
bias-disable;
drive-open-drain;
slew-rate = <0>;
};
};
i2c5_sleep_pins_mx: i2c5_sleep_mx-0 {
pins {
pinmux = <STM32_PINMUX('F', 3, ANALOG)>, /* I2C5_SDA */
<STM32_PINMUX('H', 13, ANALOG)>; /* I2C5_SCL */
};
};
sai1a_pins_mx: sai1a_mx-0 {
pins {
pinmux = <STM32_PINMUX('A', 4, AF12)>, /* SAI1_SCK_A */
<STM32_PINMUX('A', 5, AF6)>, /* SAI1_SD_A */
<STM32_PINMUX('C', 3, AF10)>, /* SAI1_MCLK_A */
<STM32_PINMUX('E', 4, AF6)>; /* SAI1_FS_A */
bias-disable;
drive-push-pull;
slew-rate = <0>;
};
};
sai1a_sleep_pins_mx: sai1a_sleep_mx-0 {
pins {
pinmux = <STM32_PINMUX('A', 4, ANALOG)>, /* SAI1_SCK_A */
<STM32_PINMUX('A', 5, ANALOG)>, /* SAI1_SD_A */
<STM32_PINMUX('C', 3, ANALOG)>, /* SAI1_MCLK_A */
<STM32_PINMUX('E', 4, ANALOG)>; /* SAI1_FS_A */
};
};
sai1b_pins_mx: sai1b_mx-0 {
pins {
pinmux = <STM32_PINMUX('A', 0, AF6)>; /* SAI1_SD_B */
bias-disable;
drive-push-pull;
slew-rate = <0>;
};
};
sai1b_sleep_pins_mx: sai1b_sleep_mx-0 {
pins {
pinmux = <STM32_PINMUX('A', 0, ANALOG)>; /* SAI1_SD_B */
};
};
};
And my clock settings:
root@stm32mp1:~# cat /sys/kernel/debug/clk/clk_summary |grep sai
sai2 0 0 0 104450000 0 0 50000 N
sai1 0 2 0 104450000 0 0 50000 N
sai2_k 0 0 0 24000000 0 0 50000 N
sai1_k 0 0 0 24000000 0 0 50000 N
sai1a_mclk 0 0 0 0 0 0 50000 ?
2024-05-13 12:44 AM
Hello @Bstyles ,
I have a doubt about this. I am surprised regarding your device tree that the lane 10 does not return the error, because, as far as I think, for me it is supposed to take a clock called "pll" in your device tree, that you have not for me. But it seems to pass... so very disturbing.
Anyway, on STM32MP157F-DK2, we have an audio codec integrated on the platform, driven by the driver: cs42l51.c. In this driver, you can see the logic between MCLK manipulation, and the device tree defined at this location : <linux>/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi.
I think it will help you to go forward.
Kind regards,
Erwan.