cancel
Showing results for 
Search instead for 
Did you mean: 

Need help with SAI DeviceTree - STM32MP135F - TI TLV320AIC3254

skarayigit
Associate III

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 ?

 

10 REPLIES 10

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.

In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.