This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TLV320AIC3206EVM-U: About mixer control.

Part Number: TLV320AIC3206EVM-U
Other Parts Discussed in Thread: TLV320AIC3206, PCM1780,

Hi,

I have tried STM32MP157D-DK1 and PCM1780 before. However, I couldn't solve the problem, so I changed the device to TLV320AIC3206.

Using the sample device tree as a reference, I built the "simple audio card" device tree for the STM32MP157D and TLV320AIC3206.

I/F:i2c4 & sai1

----------------

STM32MP> i2c dev 0
  Setting bus to 0
STM32MP> i2c probe
  Valid chip addresses: 18 33
STM32MP> i2c bus 0
  Bus 0: i2c@5c002000 (active 0)
  33: stpmic@33, offset len 1, flags 0

  18: generic_18, offset len 1, flags 0 // TLVC320AIC3206
STM32MP> i2c md 18 32 10
  0032: 00 00 00 12 03 02 02 00 00 00 01 01 00 14 0c 00 ................
STM32MP> i2c mw 18 34 01
STM32MP> i2c md 18 32 10
  0032: 00 00 01 12 01 00 00 00 00 00 01 01 00 14 0c d8 ................

----------------

I can access TLV320AIC3206 via i2c from the u-boot console.

Attempting a mixer control from a Linux terminal fails.
Do you know where the cause of this problem is?

[ 3.609648] ALSA device list:
[ 3.611159] No soundcards found.
[ 70.881989] asoc-simple-card sound: tlv320aic32x4-hifi <-> 4400a004.audio-controller mapping ok

$ alsamixer
cannot load mixer controls: Operation not permitted
$ amixer -c0
amixer: Mixer hw:0 load error: Operation not permitted

$ sudo i2cdetect -y 0
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- UU -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- UU -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

Thanks,

Nishimura

  • Hi

    Check the difference of clock-names between ti and cs.

    for TI:

    clock-names = "mclk";

    for CS

    clock-names = "MCLK"; 

    Is it capital?

  • Hi,

    I only need audio playback.
    Since CS is an evaluation board, it has some functions that do not require capture.
    I have already tried changing the clock name to "MCLK".
    This setting will result in an error. It seems that "MCLK" routing fails.

  • Kindly add some log in alsa-side code to check why .set_sysclk does not call. This can help us know the reason why set_sysclk  is not called each time.

  • Hi,

    I think mclk-fs solved the problem.
    I found a big difference in the structure of the device tree between "simple-audio-card" and "audio-graph-card".
    I checked the simple-card.c, simple-card-utils.c, audio-graph-card.c files and defined "mclk-fs".

    The clock is set after the aplay command, but aic32x4_setup_clocks () fails to adjust.

    [ 127.289000] WVC:su:asoc_simple_startup()
    [ 127.292905] WVC:su:asoc_simple_clk_enable() dai=1
    [ 127.297696] WVC:su:asoc_simple_clk_enable() dai=1
    Playing WAVE 'loop3.wav' : Signed 16 bit L
    [ 127.308711] WVC:su:asoc_simple_hw_params() start mclk_fs=0, dai_props->mclk_fs=256
    [ 127.316182] WVC:su:asoc_simple_hw_params() mclk_fs=256
    [ 127.321483] WVC:su:asoc_simple_hw_params() asoc_simple_set_clk_rate(dai_props->codec_dai)
    [ 127.329757] WVC:su:asoc_simple_set_clk_rate()
    [ 127.334139] WVC:su:asoc_simple_hw_params() asoc_simple_set_clk_rate(dai_props->cpu_dai)
    [ 127.342284] WVC:su:asoc_simple_set_clk_rate()
    [ 127.346678] WVC:su:asoc_simple_hw_params() snd_soc_dai_set_sysclk(codec_dai, SND_SOC_CLOCK_IN)
    [ 127.355525] ASoC tlv320aic32x4 codec driver : aic32x4_set_dai_sysclk() clk_id=0, freq=11289600, dir=0
    [ 127.364818] ASoC tlv320aic32x4 codec driver : aic32x4_set_dai_sysclk() clk_set_rate ret=0
    [ 127.373054] WVC:su:asoc_simple_hw_params() snd_soc_dai_set_sysclk(cpu_dai, SND_SOC_CLOCK_OUT)
    [ 127.381698] WVC:stm32_sai_set_sysclk() clk_id=0, freq=11289600, dir=1, 1
    [ 127.388529] WVC:stm32_sai_set_sysclk() (dir == SND_SOC_CLOCK_OUT && sai->sai_mclk)
    [ 127.396085] WVC:stm32_sai_set_sysclk() stm32_sai_sub_reg_up
    [ 127.401864] WVC:stm32_sai_sub_reg_up() reg=0x0, mask=0x80000, val=0x0
    [ 127.408351] WVC:stm32_sai_sub_reg_up() clk_enable success
    [ 127.413774] WVC:stm32_sai_sub_reg_up() regmap_update_bits
    [ 127.419331] WVC:stm32_sai_sub_readable_reg() reg=0x0, true
    [ 127.424846] WVC:stm32_sai_sub_volatile_reg() reg=0x0, false
    [ 127.430508] WVC:stm32_sai_sub_readable_reg() reg=0x0, true
    [ 127.436084] WVC:stm32_sai_sub_volatile_reg() reg=0x0, false
    [ 127.441751] WVC:stm32_sai_sub_writeable_reg() reg=0x0, true
    [ 127.447414] WVC:stm32_sai_sub_readable_reg() reg=0x0, true
    [ 127.452991] WVC:stm32_sai_sub_volatile_reg() reg=0x0, false
    [ 127.458823] WVC:stm32_sai_sub_reg_up() clk_disable
    [ 127.463547] WVC:stm32_sai_set_sysclk() stm32_sai_set_parent_clock
    [ 127.469820] WVC:stm32_sai_set_parent_clock()
    [ 127.474095] WVC:stm32_sai_mclk_recalc_rate() mclk->freq=0, mclk->sai_data->mclk_rate=0
    [ 127.482280] WVC:stm32_sai_mclk_recalc_rate() mclk->freq=0, mclk->sai_data->mclk_rate=0
    [ 127.490222] WVC:stm32_sai_set_sysclk() clk_set_rate_exclusive
    [ 127.495957] WVC:stm32_sai_mclk_round_rate()
    [ 127.500288] WVC:stm32_sai_get_clk_div()
    [ 127.504151] WVC:stm32_sai_mclk_round_rate()
    [ 127.508476] WVC:stm32_sai_get_clk_div()
    [ 127.512347] WVC:stm32_sai_mclk_set_rate() rate=11290699, parent_rate=11290699
    [ 127.519637] WVC:stm32_sai_get_clk_div()
    [ 127.523494] WVC:stm32_sai_mclk_set_rate() div=1
    [ 127.528109] WVC:stm32_sai_set_clk_div() div=1
    [ 127.532718] WVC:stm32_sai_sub_reg_up() reg=0x0, mask=0x3f00000, val=0x100000
    [ 127.539810] WVC:stm32_sai_sub_reg_up() clk_enable success
    [ 127.545188] WVC:stm32_sai_sub_reg_up() regmap_update_bits
    [ 127.550736] WVC:stm32_sai_sub_readable_reg() reg=0x0, true
    [ 127.556258] WVC:stm32_sai_sub_volatile_reg() reg=0x0, false
    [ 127.561921] WVC:stm32_sai_sub_readable_reg() reg=0x0, true
    [ 127.567497] WVC:stm32_sai_sub_volatile_reg() reg=0x0, false
    [ 127.573163] WVC:stm32_sai_sub_writeable_reg() reg=0x0, true
    [ 127.578827] WVC:stm32_sai_sub_readable_reg() reg=0x0, true
    [ 127.584403] WVC:stm32_sai_sub_volatile_reg() reg=0x0, false
    [ 127.590244] WVC:stm32_sai_sub_reg_up() clk_disable
    [ 127.594963] WVC:stm32_sai_mclk_recalc_rate() mclk->freq=11290699, mclk->sai_data->mclk_rate=0
    [ 127.603678] WVC:stm32_sai_set_sysclk() sai->mclk_rate=0, freq=11289600
    [ 127.610463] WVC:stm32_sai_set_sysclk() end
    [ 127.614436] WVC:su:asoc_simple_hw_params() pass
    [ 127.619131] ASoC tlv320aic32x4 codec driver : aic32x4_hw_params() start
    [ 127.625788] params_channels(params)=2, params_rate(params)=44100, params_width(params)=16

    [ 127.637123] ASoC tlv320aic32x4 codec driver : aic32x4_setup_clocks() sample_rate=44100
    [ 127.645144] ASoC tlv320aic32x4 codec driver : aic32x4_setup_clocks() devm_clk_bulk_get 0
    [ 127.653218] ASoC tlv320aic32x4 codec driver : aic32x4_setup_clocks() sample_rate <= 48000

    [ 127.661518] ASoC tlv320aic32x4 codec driver : aic32x4_set_processing_blocks()

    ittle En

    [ 127.670030] ASoC tlv320aic32x4 codec driver : aic32x4_setup_clocks() madc=2, max_dosr=136, min_dosr=56, max_nadc=9

    [ 127.680106] Division by zero in kernel.
    [ 127.683670] CPU: 0 PID: 8105 Comm: aplay Not tainted 5.4.56 #96
    [ 127.689588] Hardware name: STM32 (Device Tree Support)
    [ 127.694763] [<c011253c>] (unwind_backtrace) from [<c010d780>] (show_stack+0x10/0x14)
    [ 127.702497] [<c010d780>] (show_stack) from [<c0b07134>] (dump_stack+0xb0/0xc4)
    [ 127.709731] [<c0b07134>] (dump_stack) from [<c0b04880>] (Ldiv0_64+0x8/0x18)
    [ 127.716703] [<c0b04880>] (Ldiv0_64) from [<c098d744>] (clk_aic32x4_pll_calc_muldiv+0xe8/0x134)
    [ 127.725329] [<c098d744>] (clk_aic32x4_pll_calc_muldiv) from [<c098d7bc>] (clk_aic32x4_pll_round_rate+0x2c/0x68)
    [ 127.735439] [<c098d7bc>] (clk_aic32x4_pll_round_rate) from [<c05aca58>] (clk_core_determine_round_nolock.part.0+0x44/0x60)
    [ 127.746503] [<c05aca58>] (clk_core_determine_round_nolock.part.0) from [<c05ad9c0>] (clk_round_rate+0x5c/0xe0)
    [ 127.756524] [<c05ad9c0>] (clk_round_rate) from [<c098cd34>] (aic32x4_setup_clocks+0x394/0x59c)
    [ 127.765154] [<c098cd34>] (aic32x4_setup_clocks) from [<c098cf90>] (aic32x4_hw_params+0x54/0xcc)
    [ 127.773872] [<c098cf90>] (aic32x4_hw_params) from [<c097e790>] (snd_soc_dai_hw_params+0x5c/0xa4)
    [ 127.782672] [<c097e790>] (snd_soc_dai_hw_params) from [<c0980454>] (soc_pcm_hw_params+0x248/0x5b4)
    [ 127.791646] [<c0980454>] (soc_pcm_hw_params) from [<c09646ec>] (snd_pcm_hw_params+0x118/0x388)
    [ 127.800274] [<c09646ec>] (snd_pcm_hw_params) from [<c0965f40>] (snd_pcm_common_ioctl+0x250/0x1118)
    [ 127.809252] [<c0965f40>] (snd_pcm_common_ioctl) from [<c02d9af8>] (do_vfs_ioctl+0x404/0x7c8)
    [ 127.817706] [<c02d9af8>] (do_vfs_ioctl) from [<c02d9ef0>] (ksys_ioctl+0x34/0x60)
    [ 127.825111] [<c02d9ef0>] (ksys_ioctl) from [<c0101000>] (ret_fast_syscall+0x0/0x54)
    [ 127.832772] Exception stack(0xdf759fa8 to 0xdf759ff0)
    [ 127.837832] 9fa0: bed22620 0048cd98 00000004 c25c4111 bed22620 0002000e
    [ 127.846024] 9fc0: bed22620 0048cd98 0048cd48 00000036 bed22250 004823f8 bed22260 0000ac44
    [ 127.854211] 9fe0: b6f53844 bed22184 b6eed02b b6e1d418

    [ 127.859731] ASoC tlv320aic32x4 codec driver : aic32x4_setup_clocks() clk_round_rate faild
    ・・・
    [ 143.637617] ASoC tlv320aic32x4 codec driver : aic32x4_setup_clocks() Could not set clocks to support sample rate.
    [ 143.648127] tlv320aic32x4 0-0018: Could not set clocks to support sample rate.
    [ 143.655899] ASoC tlv320aic32x4 codec driver : aic32x4_hw_params() success

  • Congratulations on your big step. Kindly share what you have changed in your device tree.

    Kindly try the 48kHz wav file first. Let check whether to have the same issue.

    Also add more log in the aic32x4_setup_clocks to check why it cause issue. It seem that platform can't support the clk to be set.

  • Hi,

    It seems that the cause of the failure is that the following code does not pass.
      if (clk_round_rate (clocks [0] .clk, dac_clock_rate) == 0) {
      }

    Do you know an easy way to make sure this setting is normal?
      ret = devm_clk_bulk_get (component-> dev, ARRAY_SIZE (clocks), clocks);

    I changed the device tree settings.
    / {
    sound: sound { // top
    compatible = "simple-audio-card";
    simple-audio-card,name = "IoTGateway-S";
    simple-audio-card,format = "i2s";
    simple-audio-card,mclk-fs = <256>;
    simple-audio-card,bitclock-master = <&dailink0_master>;
    simple-audio-card,frame-master = <&dailink0_master>;
    simple-audio-card,widgets =
    "Line", "Line In",
    "Line", "Line Out",
    "Headphone", "Headphone";
    simple-audio-card,routing =
    "IN1_L", "Line In",
    "IN1_R", "Line In",
    "Line Out", "LOL",
    "Line Out", "LOR",
    "Headphone", "HPL",
    "Headphone", "HPR";

    status = "okay";

    simple-audio-card,cpu { // cpu
    sound-dai = <&sai1a 0>;
    };

    dailink0_master: simple-audio-card,codec { // codec
    sound-dai = <&tlv3206_codec>;
    clocks = <&rcc SAI1_K>;
    system-clock-direction-out = "out";
    dai-tdm-slot-num = <2>;
    dai-tdm-slot-width = <32>;
    };
    };
    };

    &i2c4 {
    pinctrl-names = "default", "sleep";
    pinctrl-0 = <&i2c4_pins_a>;
    pinctrl-1 = <&i2c4_pins_sleep_a>;
    i2c-scl-rising-time-ns = <185>;
    i2c-scl-falling-time-ns = <20>;
    clock-frequency = <400000>;
    status = "okay";
    /delete-property/dmas;
    /delete-property/dma-names;

    tlv3206_codec: tlv320aic32x6@18 {
    compatible = "ti,tlv320aic32x6";
    #sound-dai-cells = <0>;
    reg = <0x18>;
    clocks = <&sai1a>;
    clock-names = "mclk";
    iov-supply = <&v3v3>;
    ldoin-supply = <&v1v8_audio>;
    dv-supply = <&v1v8_audio>;
    av-supply = <&v1v8_audio>;
    status = "okay";
    };
    };

    &sai1 {
    clocks = <&rcc SAI1>, <&rcc PLL3_Q>, <&rcc PLL3_R>;
    clock-names = "pclk", "x8k", "x11k";
    pinctrl-names = "default", "sleep";
    pinctrl-0 = <&sai1a_pins_a>;
    pinctrl-1 = <&sai1a_sleep_pins_a>;
    status = "okay";

    sai1a: audio-controller@4400a004 {
    #clock-cells = <0>;
    dma-names = "tx";
    clocks = <&rcc SAI1_K>; //
    clock-names = "sai_ck";
    status = "okay";
    };
    };

    Thanks,

  • Hi,

    I tried a 48kHz wav file.
    The problem is similar to 44.1kHz.
    There is a problem because parent_rate is 0 in the following places.

    tlv320aic32x4-clk.c
     clk_aic32x4_pll_calc_muldiv() {
       do_div(multiplier, parent_rate);

    }

    log;
    root@arm:/home/debian/wav# aplay st005.wav
    [ 349.967537] WVC:stm32_sai_startup()
    [ 349.969682] WVC:stm32_sai_sub_reg_wr() reg=0x18, mask=0x7f, val=0x7f
    [ 349.976222] WVC:stm32_sai_sub_readable_reg() reg=0x18, true
    [ 349.981779] WVC:stm32_sai_sub_volatile_reg() reg=0x18, false
    [ 349.987528] WVC:stm32_sai_sub_readable_reg() reg=0x18, true
    [ 349.993191] WVC:stm32_sai_sub_volatile_reg() reg=0x18, false
    [ 349.998946] WVC:stm32_sai_sub_writeable_reg() reg=0x18, true
    [ 350.004696] WVC:stm32_sai_sub_readable_reg() reg=0x18, true
    [ 350.010360] WVC:stm32_sai_sub_volatile_reg() reg=0x18, false
    [ 350.016215] WVC:stm32_sai_sub_reg_up() reg=0x10, mask=0x7f, val=0x61
    [ 350.022572] WVC:stm32_sai_sub_reg_up() clk_enable success
    [ 350.028158] WVC:stm32_sai_sub_reg_up() regmap_update_bits
    [ 350.033547] WVC:stm32_sai_sub_readable_reg() reg=0x10, true
    [ 350.039209] WVC:stm32_sai_sub_volatile_reg() reg=0x10, false
    [ 350.044961] WVC:stm32_sai_sub_readable_reg() reg=0x10, true
    [ 350.050624] WVC:stm32_sai_sub_volatile_reg() reg=0x10, false
    [ 350.056378] WVC:stm32_sai_sub_writeable_reg() reg=0x10, true
    [ 350.062129] WVC:stm32_sai_sub_readable_reg() reg=0x10, true
    [ 350.067792] WVC:stm32_sai_sub_volatile_reg() reg=0x10, false
    [ 350.073644] WVC:stm32_sai_sub_reg_up() clk_disable
    [ 350.078512] WVC:su:asoc_simple_startup()
    [ 350.082437] WVC:su:asoc_simple_clk_enable() dai=1
    [ 350.087336] WVC:su:asoc_simple_clk_enable() dai=1

    Playing WAVE 'st005.wav' : Signed 24 bit Little Endian in 3bytes, Rate 48000 Hz, Stereo

    [ 350.099433] WVC:su:asoc_simple_hw_params() start mclk_fs=0, dai_props->mclk_fs=256
    [ 350.107208] WVC:su:asoc_simple_hw_params() mclk_fs=256
    [ 350.112147] WVC:su:asoc_simple_hw_params() asoc_simple_set_clk_rate(dai_props->codec_dai)
    [ 350.121391] WVC:su:asoc_simple_set_clk_rate()
    [ 350.125696] WVC:su:asoc_simple_hw_params() asoc_simple_set_clk_rate(dai_props->cpu_dai)
    [ 350.133684] WVC:su:asoc_simple_set_clk_rate()
    [ 350.138191] WVC:su:asoc_simple_hw_params() snd_soc_dai_set_sysclk(codec_dai, SND_SOC_CLOCK_IN)
    [ 350.146937] WVC:tlv320aic32x4; aic32x4_set_dai_sysclk() clk_id=0, freq=12288000, dir=0
    [ 350.155145] WVC:tlv320aic32x4; aic32x4_set_dai_sysclk() clk_set_rate ret=0
    [ 350.161829] WVC:su:asoc_simple_hw_params() snd_soc_dai_set_sysclk(cpu_dai, SND_SOC_CLOCK_OUT)
    [ 350.170575] WVC:stm32_sai_set_sysclk() clk_id=0, freq=12288000, dir=1, 1
    [ 350.177329] WVC:stm32_sai_set_sysclk() (dir == SND_SOC_CLOCK_OUT && sai->sai_mclk)
    [ 350.185041] WVC:stm32_sai_set_sysclk() stm32_sai_sub_reg_up
    [ 350.190590] WVC:stm32_sai_sub_reg_up() reg=0x0, mask=0x80000, val=0x0
    [ 350.197269] WVC:stm32_sai_sub_reg_up() clk_enable success
    [ 350.202614] WVC:stm32_sai_sub_reg_up() regmap_update_bits
    [ 350.208240] WVC:stm32_sai_sub_readable_reg() reg=0x0, true
    [ 350.213682] WVC:stm32_sai_sub_volatile_reg() reg=0x0, false
    [ 350.219344] WVC:stm32_sai_sub_readable_reg() reg=0x0, true
    [ 350.224919] WVC:stm32_sai_sub_volatile_reg() reg=0x0, false
    [ 350.230587] WVC:stm32_sai_sub_writeable_reg() reg=0x0, true
    [ 350.236251] WVC:stm32_sai_sub_readable_reg() reg=0x0, true
    [ 350.241828] WVC:stm32_sai_sub_volatile_reg() reg=0x0, false
    [ 350.247641] WVC:stm32_sai_sub_reg_up() clk_disable
    [ 350.252385] WVC:stm32_sai_set_sysclk() stm32_sai_set_parent_clock
    [ 350.258656] WVC:stm32_sai_set_parent_clock()
    [ 350.262928] WVC:stm32_sai_set_sysclk() clk_set_rate_exclusive
    [ 350.268891] WVC:stm32_sai_mclk_round_rate()
    [ 350.273069] WVC:stm32_sai_get_clk_div()
    [ 350.277047] WVC:stm32_sai_mclk_round_rate()
    [ 350.281228] WVC:stm32_sai_get_clk_div()
    [ 350.285250] WVC:stm32_sai_mclk_set_rate() rate=12286937, parent_rate=24573875
    [ 350.292384] WVC:stm32_sai_get_clk_div()
    [ 350.296381] WVC:stm32_sai_mclk_set_rate() div=2
    [ 350.300929] WVC:stm32_sai_set_clk_div() div=2
    [ 350.305446] WVC:stm32_sai_sub_reg_up() reg=0x0, mask=0x3f00000, val=0x200000
    [ 350.312523] WVC:stm32_sai_sub_reg_up() clk_enable success
    [ 350.318071] WVC:stm32_sai_sub_reg_up() regmap_update_bits
    [ 350.323503] WVC:stm32_sai_sub_readable_reg() reg=0x0, true
    [ 350.329076] WVC:stm32_sai_sub_volatile_reg() reg=0x0, false
    [ 350.334741] WVC:stm32_sai_sub_readable_reg() reg=0x0, true
    [ 350.340318] WVC:stm32_sai_sub_volatile_reg() reg=0x0, false
    [ 350.345985] WVC:stm32_sai_sub_writeable_reg() reg=0x0, true
    [ 350.351649] WVC:stm32_sai_sub_readable_reg() reg=0x0, true
    [ 350.357225] WVC:stm32_sai_sub_volatile_reg() reg=0x0, false
    [ 350.363034] WVC:stm32_sai_sub_reg_up() clk_disable
    [ 350.367857] WVC:stm32_sai_mclk_recalc_rate() mclk->freq=12286937, mclk->sai_data->mclk_rate=0
    [ 350.376488] WVC:stm32_sai_set_sysclk() sai->mclk_rate=0, freq=12288000
    [ 350.383027] WVC:stm32_sai_set_sysclk() end
    [ 350.387299] WVC:su:asoc_simple_hw_params() pass
    [ 350.391836] WVC:tlv320aic32x4; aic32x4_hw_params() start
    [ 350.397311] params_channels(params)=2, params_rate(params)=48000, params_width(params)=32
    [ 350.408613] WVC:tlv320aic32x4; aic32x4_setup_clocks() sample_rate=48000
    [ 350.415325] WVC:tlv320aic32x4; aic32x4_setup_clocks() clocks.id=pll, clocks.clk=afde89f3
    [ 350.423388] WVC:tlv320aic32x4; aic32x4_setup_clocks() clocks.id=nadc, clocks.clk=8722a559
    [ 350.431814] WVC:tlv320aic32x4; aic32x4_setup_clocks() clocks.id=madc, clocks.clk=db063d60
    [ 350.440041] WVC:tlv320aic32x4; aic32x4_setup_clocks() clocks.id=ndac, clocks.clk=a5f68547
    [ 350.448277] WVC:tlv320aic32x4; aic32x4_setup_clocks() clocks.id=mdac, clocks.clk=054d83ff
    [ 350.456578] WVC:tlv320aic32x4; aic32x4_setup_clocks() clocks.id=bdiv, clocks.clk=df38ab58
    [ 350.464783] WVC:tlv320aic32x4; aic32x4_setup_clocks() devm_clk_bulk_get pass ret=0
    [ 350.472505] WVC:tlv320aic32x4; aic32x4_setup_clocks() sample_rate<=48000
    [ 350.479330] WVC:tlv320aic32x4; aic32x4_set_processing_blocks()
    [ 350.486613] WVC:tlv320aic32x4; aic32x4_set_processing_blocks() snd_soc_component_write(reg=3d, val=1)
    [ 350.496673] WVC:tlv320aic32x4; aic32x4_set_processing_blocks() snd_soc_component_write(reg=3c, val=1)
    [ 350.506030] WVC:tlv320aic32x4; aic32x4_setup_clocks() aic32x4_set_processing_blocks(1, 1)
    [ 350.514217] WVC:tlv320aic32x4; aic32x4_setup_clocks() Start adjustment madc=2, max_dosr=128, min_dosr=56, max_nadc=8
    [ 350.524904] WVC:tlv320aic32x4; aic32x4_setup_clocks() clk_round_rate pll dac_clock_rate=98304000
    [ 350.533732] WVC:clk; clk_round_rate() clk->dev_id=0-0018, clk->con_id=pll, clk->min_rate=0, clk->max_rate=4294967295, rate=98304000
    [ 350.545788] WVC:clk; clk_round_rate() clk_prepare_lock
    [ 350.550897] WVC:clk; clk_round_rate() clk->exclusive_count1=0
    [ 350.556826] WVC:clk; clk_round_rate() clk_core_get_boundaries
    [ 350.562576] WVC:clk; clk_round_rate() req.rate=98304000
    [ 350.568016] WVC:clk; clk_round_rate() clk_core_round_rate_nolock
    [ 350.573992] WVC:clk; clk_core_round_rate_nolock() lockdep_assert_held
    [ 350.580604] WVC:clk; clk_core_round_rate_nolock() clk_core_init_rate_req
    [ 350.587399] WVC:clk; clk_core_round_rate_nolock() clk_core_determine_round_nolock
    [ 350.594955] ASoC TLV320AIC32x4 clk : clk_aic32x4_pll_round_rate() rate=98304000, parent_rate=0
    [ 350.603629] ASoC TLV320AIC32x4 clk : clk_aic32x4_pll_calc_muldiv() rate=98304000, parent_rate=0
    [ 350.612489] ASoC TLV320AIC32x4 clk : clk_aic32x4_pll_calc_muldiv() settings->p=1
    [ 350.619981] ASoC TLV320AIC32x4 clk : clk_aic32x4_pll_calc_muldiv() multiplier=983040000000
    [ 350.628337] Division by zero in kernel.
    [ 350.632141] CPU: 1 PID: 8086 Comm: aplay Not tainted 5.4.56 #125
    [ 350.638143] Hardware name: STM32 (Device Tree Support)
    [ 350.643319] [<c011253c>] (unwind_backtrace) from [<c010d780>] (show_stack+0x10/0x14)
    [ 350.651054] [<c010d780>] (show_stack) from [<c0b077f4>] (dump_stack+0xb0/0xc4)
    [ 350.658288] [<c0b077f4>] (dump_stack) from [<c0b04f40>] (Ldiv0_64+0x8/0x18)
    [ 350.665260] [<c0b04f40>] (Ldiv0_64) from [<c098d4c4>] (__div64_32+0x14/0x20)
    [ 350.672319] [<c098d4c4>] (__div64_32) from [<c098d9f8>] (clk_aic32x4_pll_calc_muldiv+0xc4/0x198)
    [ 350.681121] [<c098d9f8>] (clk_aic32x4_pll_calc_muldiv) from [<c098dbd8>] (clk_aic32x4_pll_round_rate+0x44/0xa0)
    [ 350.691235] [<c098dbd8>] (clk_aic32x4_pll_round_rate) from [<c05aca58>] (clk_core_determine_round_nolock.part.0+0x44/0x60)
    [ 350.702301] [<c05aca58>] (clk_core_determine_round_nolock.part.0) from [<c05ad5d8>] (clk_round_rate+0x88/0x288)
    [ 350.712409] [<c05ad5d8>] (clk_round_rate) from [<c098c728>] (aic32x4_setup_clocks+0x3c8/0x5e4)
    [ 350.721037] [<c098c728>] (aic32x4_setup_clocks) from [<c098c9d0>] (aic32x4_hw_params+0x54/0xcc)
    [ 350.729756] [<c098c9d0>] (aic32x4_hw_params) from [<c097ea88>] (snd_soc_dai_hw_params+0x5c/0xa4)
    [ 350.738559] [<c097ea88>] (snd_soc_dai_hw_params) from [<c098074c>] (soc_pcm_hw_params+0x248/0x5b4)
    [ 350.747535] [<c098074c>] (soc_pcm_hw_params) from [<c09649e4>] (snd_pcm_hw_params+0x118/0x388)
    [ 350.756164] [<c09649e4>] (snd_pcm_hw_params) from [<c0966238>] (snd_pcm_common_ioctl+0x250/0x1118)
    [ 350.765144] [<c0966238>] (snd_pcm_common_ioctl) from [<c02d9af8>] (do_vfs_ioctl+0x404/0x7c8)
    [ 350.773599] [<c02d9af8>] (do_vfs_ioctl) from [<c02d9ef0>] (ksys_ioctl+0x34/0x60)
    [ 350.781006] [<c02d9ef0>] (ksys_ioctl) from [<c0101000>] (ret_fast_syscall+0x0/0x54)
    [ 350.788670] Exception stack(0xd0d17fa8 to 0xd0d17ff0)
    [ 350.793730] 7fa0: bec91f08 00515d98 00000004 c25c4111 bec91f08 0002000e
    [ 350.801925] 7fc0: bec91f08 00515d98 00515d48 00000036 b6f268f5 b6f2540d b6f268d9 bec9224c
    [ 350.810117] 7fe0: b6f88844 bec91e4c b6f2202b b6e52418
    [ 350.815316] ASoC TLV320AIC32x4 clk : clk_aic32x4_pll_calc_muldiv() settings->r=1
    [ 350.822673] ASoC TLV320AIC32x4 clk : clk_aic32x4_pll_calc_muldiv() multiplier=0
    [ 350.830183] ASoC TLV320AIC32x4 clk : clk_aic32x4_pll_round_rate() clk_aic32x4_pll_calc_muldiv error=-1
    [ 350.839550] WVC:clk; clk_round_rate() clk->exclusive_count2=0
    [ 350.845417] WVC:clk; clk_round_rate() clk_prepare_unlock
    [ 350.850741] WVC:clk; clk_round_rate() req.rate=0
    [ 350.855524] WVC:tlv320aic32x4; aic32x4_setup_clocks() clk_round_rate faild dac_clock_rate=98304000
    [ 350.864511] WVC:tlv320aic32x4; aic32x4_setup_clocks() clk_round_rate pll dac_clock_rate=98304000
    [ 350.873521] WVC:clk; clk_round_rate() clk->dev_id=0-0018, clk->con_id=pll, clk->min_rate=0, clk->max_rate=4294967295, rate=98304000
    [ 350.885413] WVC:clk; clk_round_rate() clk_prepare_lock
    [ 350.890573] WVC:clk; clk_round_rate() clk->exclusive_count1=0
    [ 350.896462] WVC:clk; clk_round_rate() clk_core_get_boundaries
    [ 350.902256] WVC:clk; clk_round_rate() req.rate=98304000
    [ 350.907624] WVC:clk; clk_round_rate() clk_core_round_rate_nolock
    [ 350.913670] WVC:clk; clk_core_round_rate_nolock() lockdep_assert_held
    [ 350.920271] WVC:clk; clk_core_round_rate_nolock() clk_core_init_rate_req
    [ 350.927061] WVC:clk; clk_core_round_rate_nolock() clk_core_determine_round_nolock
    [ 350.934590] ASoC TLV320AIC32x4 clk : clk_aic32x4_pll_round_rate() rate=98304000, parent_rate=0
    [ 350.943395] ASoC TLV320AIC32x4 clk : clk_aic32x4_pll_calc_muldiv() rate=98304000, parent_rate=0
    [ 350.952191] ASoC TLV320AIC32x4 clk : clk_aic32x4_pll_calc_muldiv() settings->p=1
    [ 350.959654] ASoC TLV320AIC32x4 clk : clk_aic32x4_pll_calc_muldiv() multiplier=983040000000

    Thanks,

  • The parent_rate is always 0, which means there exists an issue on the clock-bindings setting. I found two document from Linux kernel

    You can find the tlv320aic32x4.txt in Documentation\devicetree\bindings\sound, which reference the clock-bindings.txt.

    Texas Instruments - tlv320aic32x4 Codec module
    
    The tlv320aic32x4 serial control bus communicates through I2C protocols
    
    Required properties:
     - compatible - "string" - One of:
    	"ti,tlv320aic32x4" TLV320AIC3204
    	"ti,tlv320aic32x6" TLV320AIC3206, TLV320AIC3256
     - reg: I2C slave address
     - supply-*: Required supply regulators are:
        "iov" - digital IO power supply
        "ldoin" - LDO power supply
        "dv" - Digital core power supply
        "av" - Analog core power supply
        If you supply ldoin, dv and av are optional. Otherwise they are required
       See regulator/regulator.txt for more information about the detailed binding
       format.
    
    Optional properties:
     - reset-gpios: Reset-GPIO phandle with args as described in gpio/gpio.txt
     - clocks/clock-names: Clock named 'mclk' for the master clock of the codec.
       See clock/clock-bindings.txt for information about the detailed format.
     - aic32x4-gpio-func - <array of 5 int>
    	- Types are defined in include/sound/tlv320aic32x4.h
    
    
    Example:
    
    codec: tlv320aic32x4@18 {
    	compatible = "ti,tlv320aic32x4";
    	reg = <0x18>;
    	clocks = <&clks 201>;
    	clock-names = "mclk";
    	aic32x4-gpio-func= <
    			0xff /* AIC32X4_MFPX_DEFAULT_VALUE */
    			0xff /* AIC32X4_MFPX_DEFAULT_VALUE */
    			0x04 /* MFP3 AIC32X4_MFP3_GPIO_ENABLED */
    			0xff /* AIC32X4_MFPX_DEFAULT_VALUE */
    			0x08 /* MFP5 AIC32X4_MFP5_GPIO_INPUT */
    		>;
    };
    

    You can find clock-bindings.txt from Documentation\devicetree\bindings\clock

    This binding is a work-in-progress, and are based on some experimental
    work by benh[1].
    
    Sources of clock signal can be represented by any node in the device
    tree.  Those nodes are designated as clock providers.  Clock consumer
    nodes use a phandle and clock specifier pair to connect clock provider
    outputs to clock inputs.  Similar to the gpio specifiers, a clock
    specifier is an array of zero, one or more cells identifying the clock
    output on a device.  The length of a clock specifier is defined by the
    value of a #clock-cells property in the clock provider node.
    
    [1] https://patchwork.ozlabs.org/patch/31551/
    
    ==Clock providers==
    
    Required properties:
    #clock-cells:	   Number of cells in a clock specifier; Typically 0 for nodes
    		   with a single clock output and 1 for nodes with multiple
    		   clock outputs.
    
    Optional properties:
    clock-output-names: Recommended to be a list of strings of clock output signal
    		    names indexed by the first cell in the clock specifier.
    		    However, the meaning of clock-output-names is domain
    		    specific to the clock provider, and is only provided to
    		    encourage using the same meaning for the majority of clock
    		    providers.  This format may not work for clock providers
    		    using a complex clock specifier format.  In those cases it
    		    is recommended to omit this property and create a binding
    		    specific names property.
    
    		    Clock consumer nodes must never directly reference
    		    the provider's clock-output-names property.
    
    For example:
    
        oscillator {
            #clock-cells = <1>;
            clock-output-names = "ckil", "ckih";
        };
    
    - this node defines a device with two clock outputs, the first named
      "ckil" and the second named "ckih".  Consumer nodes always reference
      clocks by index. The names should reflect the clock output signal
      names for the device.
    
    clock-indices:	   If the identifying number for the clocks in the node
    		   is not linear from zero, then this allows the mapping of
    		   identifiers into the clock-output-names array.
    
    For example, if we have two clocks <&oscillator 1> and <&oscillator 3>:
    
    	oscillator {
    		compatible = "myclocktype";
    		#clock-cells = <1>;
    		clock-indices = <1>, <3>;
    		clock-output-names = "clka", "clkb";
    	}
    
    	This ensures we do not have any empty strings in clock-output-names
    
    
    ==Clock consumers==
    
    Required properties:
    clocks:		List of phandle and clock specifier pairs, one pair
    		for each clock input to the device.  Note: if the
    		clock provider specifies '0' for #clock-cells, then
    		only the phandle portion of the pair will appear.
    
    Optional properties:
    clock-names:	List of clock input name strings sorted in the same
    		order as the clocks property.  Consumers drivers
    		will use clock-names to match clock input names
    		with clocks specifiers.
    clock-ranges:	Empty property indicating that child nodes can inherit named
    		clocks from this node. Useful for bus nodes to provide a
    		clock to their children.
    
    For example:
    
        device {
            clocks = <&osc 1>, <&ref 0>;
            clock-names = "baud", "register";
        };
    
    
    This represents a device with two clock inputs, named "baud" and "register".
    The baud clock is connected to output 1 of the &osc device, and the register
    clock is connected to output 0 of the &ref.
    
    ==Example==
    
        /* external oscillator */
        osc: oscillator {
            compatible = "fixed-clock";
            #clock-cells = <0>;
            clock-frequency  = <32678>;
            clock-output-names = "osc";
        };
    
        /* phase-locked-loop device, generates a higher frequency clock
         * from the external oscillator reference */
        pll: pll@4c000 {
            compatible = "vendor,some-pll-interface"
            #clock-cells = <1>;
            clocks = <&osc 0>;
            clock-names = "ref";
            reg = <0x4c000 0x1000>;
            clock-output-names = "pll", "pll-switched";
        };
    
        /* UART, using the low frequency oscillator for the baud clock,
         * and the high frequency switched PLL output for register
         * clocking */
        uart@a000 {
            compatible = "fsl,imx-uart";
            reg = <0xa000 0x1000>;
            interrupts = <33>;
            clocks = <&osc 0>, <&pll 1>;
            clock-names = "baud", "register";
        };
    
    This DT fragment defines three devices: an external oscillator to provide a
    low-frequency reference clock, a PLL device to generate a higher frequency
    clock signal, and a UART.
    
    * The oscillator is fixed-frequency, and provides one clock output, named "osc".
    * The PLL is both a clock provider and a clock consumer. It uses the clock
      signal generated by the external oscillator, and provides two output signals
      ("pll" and "pll-switched").
    * The UART has its baud clock connected the external oscillator and its
      register clock connected to the PLL clock (the "pll-switched" signal)
    
    ==Assigned clock parents and rates==
    
    Some platforms may require initial configuration of default parent clocks
    and clock frequencies. Such a configuration can be specified in a device tree
    node through assigned-clocks, assigned-clock-parents and assigned-clock-rates
    properties. The assigned-clock-parents property should contain a list of parent
    clocks in the form of a phandle and clock specifier pair and the
    assigned-clock-rates property should contain a list of frequencies in Hz. Both
    these properties should correspond to the clocks listed in the assigned-clocks
    property.
    
    To skip setting parent or rate of a clock its corresponding entry should be
    set to 0, or can be omitted if it is not followed by any non-zero entry.
    
        uart@a000 {
            compatible = "fsl,imx-uart";
            reg = <0xa000 0x1000>;
            ...
            clocks = <&osc 0>, <&pll 1>;
            clock-names = "baud", "register";
    
            assigned-clocks = <&clkcon 0>, <&pll 2>;
            assigned-clock-parents = <&pll 2>;
            assigned-clock-rates = <0>, <460800>;
        };
    
    In this example the <&pll 2> clock is set as parent of clock <&clkcon 0> and
    the <&pll 2> clock is assigned a frequency value of 460800 Hz.
    
    Configuring a clock's parent and rate through the device node that consumes
    the clock can be done only for clocks that have a single user. Specifying
    conflicting parent or rate configuration in multiple consumer nodes for
    a shared clock is forbidden.
    
    Configuration of common clocks, which affect multiple consumer devices can
    be similarly specified in the clock provider node.
    
    ==Protected clocks==
    
    Some platforms or firmwares may not fully expose all the clocks to the OS, such
    as in situations where those clks are used by drivers running in ARM secure
    execution levels. Such a configuration can be specified in device tree with the
    protected-clocks property in the form of a clock specifier list. This property should
    only be specified in the node that is providing the clocks being protected:
    
       clock-controller@a000f000 {
            compatible = "vendor,clk95;
            reg = <0xa000f000 0x1000>
            #clocks-cells = <1>;
            ...
            protected-clocks = <UART3_CLK>, <SPI5_CLK>;
       };
    

    One more thing, can you share your wav file with me?

  • Hi,

    Yes, I can provide a wav file.
    Can I attach files to this forum?
    If it is not possible, I will reply by attaching it to an email.

    Thanks,

  • Hi,

    The test sound source can be downloaded from the following site.

    44.1kHz
    www.ne.jp/.../wave.htm
    loop3.wav

    48kHz
    music.yukizakura.net/.../all_bgm.html
    No. b074
    st005.wav

    Thanks,

  • Hi,

    I checked the text.
    It seems that the cause is that the parent is not set to the "pll" that the TVL320AIC32x4 driver has internally.
    It seems that the best parent clock is selected, "pll" seems to be set only on the TLV320AIC32x4 probe.

    [ 7.918511] WVC:tlv320aic32x4; aic32x4_probe() start
    [ 7.923434] WVC:tlv320aic32x4; aic32x4_probe() np ---> aic32x4_parse_dt()
    [ 7.930337] WVC:tlv320aic32x4; aic32x4_parse_dt()
    [ 7.935142] WVC:tlv320aic32x4; aic32x4_parse_dt() ret=0
    [ 7.940443] WVC:tlv320aic32x4; aic32x4_parse_dt() aic32x4->rstn_gpio=-2, aic32x4_setup->gpio_func=0,0,0,0,0
    [ 7.950298] WVC:tlv320aic32x4; aic32x4_probe() aic32x4->mclk_name=audio-controller
    [ 7.957953] ASoC TLV320AIC32x4 clk : aic32x4_register_clocks() mclk_name=audio-controller

    [ 7.966229] ASoC TLV320AIC32x4 clk : aic32x4_register_clk() devname=0-0018, desc->name=pll
    [ 7.975009] ASoC TLV320AIC32x4 clk : clk_aic32x4_pll_get_parent() val=11, ret=0
    [ 7.982015] ASoC TLV320AIC32x4 clk : clk_aic32x4_pll_recalc_rate()
    [ 7.988289] ASoC TLV320AIC32x4 clk : clk_aic32x4_pll_get_muldiv()
    [ 7.995555] ASoC TLV320AIC32x4 clk : clk_aic32x4_pll_calc_rate()
    [ 8.000815] ASoC TLV320AIC32x4 clk : clk_aic32x4_pll_get_parent() val=11, ret=0

    However, at this stage, the best_parent_rate is not set, and I think that the parent clock cannot be found.
    The best_parent_rate is set when the aplay command is executed. The parent of "pll" remains empty.
    Is there a way to re set the parent clock for "pll"?

    Playing WAVE 'loop3.wav' : Signed 16 bit L

    [ 208.863971] WVC:su:asoc_simple_hw_params() start mclk_fs=0, dai_props->mclk_fs=256
    [ 208.871733] WVC:su:asoc_simple_hw_params() mclk_fs=256
    [ 208.876906] WVC:su:asoc_simple_hw_params() asoc_simple_set_clk_rate(dai_props->codec_dai)
    [ 208.885145] WVC:su:asoc_simple_set_clk_rate()

    [ 208.889545] WVC:clk; clk_mux_determine_rate_flags() check best_parent_rate req->rate=11289600
    [ 208.898227] WVC:clk; clk_mux_determine_rate_flags() parent->name=pll3_q
    [ 208.904993] WVC:clk; clk_mux_determine_rate_flags() best2=24573875
    [ 208.911145] WVC:clk; clk_mux_determine_rate_flags() best=24573875, req->best_parent_rate=24573875, req->rate=24573875

    [ 208.921951] WVC:su:asoc_simple_hw_params() asoc_simple_set_clk_rate(dai_props->cpu_dai)
    [ 208.930045] WVC:su:asoc_simple_set_clk_rate()
    [ 208.934408] WVC:su:asoc_simple_hw_params() snd_soc_dai_set_sysclk(codec_dai, SND_SOC_CLOCK_IN)
    [ 208.943208] WVC:tlv320aic32x4; aic32x4_set_dai_sysclk() clk_id=0, freq=11289600, dir=0
    [ 208.951214] WVC:tlv320aic32x4; aic32x4_set_dai_sysclk() clk_set_rate ret=0
    [ 208.958152] WVC:su:asoc_simple_hw_params() snd_soc_dai_set_sysclk(cpu_dai, SND_SOC_CLOCK_OUT)
    [ 208.966860] WVC:stm32_sai_set_sysclk() clk_id=0, freq=11289600, dir=1, 1
    [ 208.973528] WVC:stm32_sai_set_sysclk() (dir == SND_SOC_CLOCK_OUT && sai->sai_mclk)
    [ 208.981283] WVC:stm32_sai_set_sysclk() stm32_sai_sub_reg_up
    ・・・
    [ 209.398444] WVC:clk; clk_core_init_rate_req() check best_parent_rate core->name=pll
    [ 209.406192] WVC:clk; clk_core_init_rate_req() parent=(null)

    [ 209.411799] WVC:clk; clk_core_round_rate_nolock() clk_core_determine_round_nolock
    [ 209.419486] WVC:clk; clk_core_determine_round_nolock() core->name=pll, req->rate=101606400
    [ 209.427835] WVC:clk; clk_core_determine_round_nolock() core->protect_count=0
    [ 209.434999] WVC:clk; clk_core_determine_round_nolock() core->ops->round_rate req->rate=101606400, req->best_parent_rate=0
    [ 209.446058] ASoC TLV320AIC32x4 clk : clk_aic32x4_pll_round_rate() rate=101606400, parent_rate=0
    [ 209.454803] ASoC TLV320AIC32x4 clk : clk_aic32x4_pll_calc_muldiv() rate=101606400, parent_rate=0
    [ 209.463639] ASoC TLV320AIC32x4 clk : clk_aic32x4_pll_calc_muldiv() settings->p=1
    [ 209.471260] ASoC TLV320AIC32x4 clk : clk_aic32x4_pll_calc_muldiv() multiplier=1016064000000

    Thanks,

  • Hi

    Sorry, I have no idea on this. Kindly consult the pll setting from platform vendor.

    Thanks.

  • Hi,

    Isn't the following set by the TVL320AIC32x4 driver?

    pll
    codec_clkin
    ndac
    mdac
    nadc
    madc
    bdiv

    Thanks,

  • Hi,

    I would like you to give me your advice
    I'm having trouble setting the parent clock for "pll".

    The TLV320AIC32x4 driver registers the following clocks in the probe request.
    "pll", "codec_clkin", "ndac", "mdac", "bdiv"
    It's in tlv320aic32x4-clk.c file(static struct aic32x4_clkdesc aic32x4_clkdesc_array[]).

    Operation steps for the TLV320AIC32x4 driver;
    1. Read the parent clock name from the device node. "aic32x4->mclk_name=audio-controller" is read out on my system.
      ret = of_property_match_string(np, "clock-names", "mclk");
      aic32x4->mclk_name = of_clk_get_parent_name(np, ret);

    2. Each clock is registered by the "aic32x4_register_clocks(dev, aic32x4->mclk_name)" function.

      aic32x4_clkdesc_array[0].parent_names = (const char* []) { mclk_name, "bclk", "gpio", "din" };
      aic32x4_clkdesc_array[1].parent_names = (const char *[]) { mclk_name, "bclk", "gpio", "pll" };

    Note:The parent_names of "aic32x4_clkdesc_array[]" will be registered after being updated by aic32x4->mclk_name.
    That is, it replaces the audio-controller.

    3. Registration is now complete.
    I checked the clock status with "cat /sys/kernel/debug/clk/clk_summary" command.

     pll                                  0        0        0           0          0     0  50000
        codec_clkin                       0        0        0           0          0     0  50000
           nadc                           0        0        0           0          0     0  50000
              madc                        0        0        0           0          0     0  50000
           ndac                           0        0        0           0          0     0  50000
              mdac                        0        0        0           0          0     0  50000
                 bdiv                     0        0        0           0          0     0  50000

    I tried changing the device tree in several ways but it didn't work.
    Is it a problem with the Simple-Card driver? Or is it possible to avoid it by modifying the TLV320AIC32x4 driver?

    Thanks,

    Does the TLV320AIC32x4 driver expect an audio-controller for the "pll" parent clock?
    There is no "audio-controller" on my system.
    I suspect sai1a_mclk is an alternative, but I can't read it.

        pll3                              1        1        0   417755859          0     0  50000
           pll3_r                         0        0        0    11290699          0     0  50000
           pll3_q                         0        0        0    24573875          0     0  47058
              adfsdm_k                    0        0        0    24573875          0     0  50000
              sai1_k                      0        0        0    24573875          0     0  50000
                 sai1a_mclk               0        0        0           0          0     0  50000

  • Since hard to set the clk setting on your platform.

    You can set a fixed mclk

    use following setting.

    static const struct aic32x4_rate_divs aic32x4_divs[] = {
    //mclk rate nadc madc aosr ndac mdac dosr
    {12288000, 48000, 1, 2, 128, 1, 2, 128},
    {12288000, 24000, 1, 4, 128, 1, 2, 256},
    {12288000, 12000, 1, 8, 128, 1, 2, 512},
    { 8192000, 32000, 1, 2, 128, 1, 2, 128},
    { 8192000, 16000, 1, 4, 128, 1, 2, 256},
    { 8192000, 8000, 1, 8, 128, 1, 2, 512},

    {11289600, 44100, 1, 2, 128, 1, 2, 128},
    {11289600, 22050, 1, 4, 128, 1, 2, 256},
    {11289600, 11025, 1, 8, 128, 1, 2, 512},
    //mclk rate 0x12 0x13 0x14 0x0b 0x0c 0x0 d-0x0e
    {15360000, 48000, 1, 2, 128, 1, 2, 128},
    {15360000, 24000, 1, 4, 128, 1, 2, 256 },
    {15360000, 12000, 1, 8, 128, 1, 2, 512 },

    {10240000, 32000, 1, 2, 128, 1, 2, 128},
    {10240000, 16000, 1, 4, 128, 1, 2, 256 },
    {10240000, 8000, 1, 8, 128, 1, 2, 512 },

    {14112000, 44100, 1, 2, 128, 1, 2, 128},
    {14112000, 22050, 1, 4, 128, 1, 2, 256 },
    {14112000, 11025, 1, 8, 128, 1, 2, 512 },
    };

  • Hi,

    Thank you for the advice.
    How do you use this table(aic32x4_rate_divs aic32x4_divs[])?
    Do you want to match the sample rate in the aic32x4_setup_clocks() function and set it with clk_set_rate()?
    Do you have sample source code?

    Thanks,

  • struct aic32x4_rate_divs {
    u32 mclk;
    u32 rate;
    u8 nadc;
    u8 madc;
    u8 aosr;
    u8 ndac;
    u8 mdac;
    u16 dosr;
    };

    The sample code can refer to tlv320aic31xx.c which is open source in the Linux Kernel code . The key word is as following

    One of our customers used this way to rewrite the clk setting code.

    Here is the link to introduce this method, but it is Chinese.

    (93条消息) 海思hi3531d音频外接codec (tlv320aic32x4)_赏善罚饿的博客-CSDN博客_i2s音频

    Hope this can help you.

  • Kindly share the dts file for aic3206. I'll compare the setting

  • Hi,

    Need all the files?
    First of all, you need the following developer packages. Have you already downloaded it?

    STM32MP1 OpenSTLinux Developer Package Ver:2.1.0
    en.SOURCES-stm32mp1-openstlinux-5-4-dunfell-mp1-20-11-12.tar.xz

    www.st.com/.../stm32mp1dev.html

    Thanks,

  • Hi,

    Did you download the file?
    The basic dts file is in the following path:
    stm32mp1-openstlinux-5-4-dunfell-mp1-20-11-12/sources/arm-ostl-linux-gnueabi/linux-stm32mp-5.4.56-r0/linux-5.4.56/arch/arm/boot/dts

    The dts files for my device are created with reference to them.
    stm32mp157d-dk1.dts

    IoTGateway.dts
    
    /dts-v1/;
    
    #include "stm32mp157.dtsi"
    #include "stm32mp15xd.dtsi"
    #include "IoTGateway-pinctrl.dtsi"
    #include "stm32mp15xxac-pinctrl.dtsi"
    #include "IoTGateway_xxx.dtsi"
    / {
    	model = "IoT Gateway Board : Linux";
    	compatible = "plk,IoTGateway", "st,stm32mp157";
    	aliases {
    		serial0 = &uart4;
    		i2c0 = &i2c4;
    		spi0 = &spi1;
    	};
    	chosen {
    		stdout-path = "serial0:115200n8";
    	};
    	reserved-memory {
    		gpu_reserved: gpu@da000000 {
    			reg = <0xda000000 0x4000000>;
    			no-map;
    		};
    	};
    };
    

    IoTGateway-pinctrl.dtsi
    
    #include <dt-bindings/pinctrl/stm32-pinfunc.h>
    &pinctrl {
    	sai1a_pins_a: sai1a-0 {
    		pins {
    			pinmux = <STM32_PINMUX('G', 13, AF6)>,	/* SAI1_SCK_A */
    					<STM32_PINMUX('E', 6, AF6)>,	/* SAI1_SD_A */
    					<STM32_PINMUX('G', 15, AF6)>,	/* SAI1_FS_A */
    					<STM32_PINMUX('G', 7, AF6)>;	/* SAI1_MCLK_A */
    			slew-rate = <0>;
    			drive-push-pull;
    			bias-disable;
    		};
    	};
    	sai1a_sleep_pins_a: sai1a_sleep-0 {
    		pins {
    			pinmux = <STM32_PINMUX('G', 13, ANALOG)>,	/* SAI1_SCK_A */
    					<STM32_PINMUX('E', 6, ANALOG)>,		/* SAI1_SD_A */
    					<STM32_PINMUX('G', 15, ANALOG)>,	/* SAI1_FS_A */
    					<STM32_PINMUX('G', 7, ANALOG)>;		/* SAI1_MCLK_A */
    		};
    	};
    	・・・
    };
    
    

    IoTGateway_xxx.dtsi
    
    #include <dt-bindings/mfd/st,stpmic1.h>
    
    / {
    	・・・
    	sound: sound {									// top
    		compatible = "simple-audio-card";
    		simple-audio-card,name = "IoTGateway-S";
    		simple-audio-card,format = "i2s";
    		simple-audio-card,mclk-fs = <256>;
    //@ master : Both bitclock-master and frame-master are valid
    //@ slave  : Both bitclock-master and frame-master are comment out
    		simple-audio-card,bitclock-master = <&dailink0_master>;
    		simple-audio-card,frame-master = <&dailink0_master>;
    //@		simple-audio-card,bitclock-inversion;
    		simple-audio-card,widgets =
    			"Headphone", "Headphone";
    /***
    			"Line", "Line In",
    			"Line", "Line Out",
    			"Headphone", "Headphone";
    ***/
    		simple-audio-card,routing =
    			"Headphone", "HPL",
    			"Headphone", "HPR";
    /***
    			"IN1_L", "Line In",
    			"IN1_R", "Line In",
    			"Line Out", "LOL",
    			"Line Out", "LOR",
    			"Headphone", "HPL",
    			"Headphone", "HPR";
    ***/
    		status = "okay";
    
    		simple-audio-card,cpu {						// cpu
    			sound-dai = <&sai1a>;					// Required items
    		};
    
    		dailink0_master: simple-audio-card,codec {	// codec
    			sound-dai = <&tlv3206_codec>;
    //@			clocks = <&rcc SAI1_K>;
    			system-clock-direction-out = "out";		// SND_SOC_CLOCK_OUT
    			dai-tdm-slot-num = <2>;
    			dai-tdm-slot-width = <32>;
    		};
    	};
    }; /*root*/
    
    &i2c4 {
    	pinctrl-names = "default", "sleep";
    	pinctrl-0 = <&i2c4_pins_a>;
    	pinctrl-1 = <&i2c4_pins_sleep_a>;
    	i2c-scl-rising-time-ns = <185>;
    	i2c-scl-falling-time-ns = <20>;
    	clock-frequency = <400000>;
    	status = "okay";
    	/* spare dmas for other usage */
    	/delete-property/dmas;
    	/delete-property/dma-names;
    	・・・
    
    	tlv3206_codec: tlv320aic32x6@18 {
    		compatible = "ti,tlv320aic32x6";
    		#sound-dai-cells = <0>;
    		reg = <0x18>;
    		clocks = <&sai1a>;
    		clock-names = "mclk";
    		iov-supply = <&v3v3>;			// digital IO power supply
    		ldoin-supply = <&v1v8_audio>;	// LDO power supply
    		dv-supply = <&v1v8_audio>;		// Digital core power supply
    		av-supply = <&v1v8_audio>;		// Analog core power supply
    		status = "okay";
    	};
    };
    
    &sai1 {
    	clocks = <&rcc SAI1>, <&rcc PLL3_Q>, <&rcc PLL3_R>;
    	clock-names = "pclk", "x8k", "x11k";
    	pinctrl-names = "default", "sleep";
    	pinctrl-0 = <&sai1a_pins_a>;
    	pinctrl-1 = <&sai1a_sleep_pins_a>;
    	status = "okay";
    
    	sai1a: audio-controller@4400a004 {
    		#clock-cells = <0>;
    		clocks = <&rcc SAI1_K>;
    		clock-names = "sai_ck";
    		dma-names = "tx";
    		status = "okay";
    	};
    };
    

    I have extracted the part related to the sound card (i2c4, sai1).

    Thanks,

  • What's the simple-audio-card,mclk-fs = <256>; mean?

  • Hi,

    - simple-audio-card,mclk-fs             : Multiplication factor between stream rate and codec
    					  mclk. When defined, mclk-fs property defined in
    					  dai-link sub nodes are ignored.
    
  • Hi,

    By disabling the following, the waveform output of MCLK, WCLK, BCLK, and DIN could be confirmed.
    However, there was no audio output.
    I gave it a fixed clock, but it seems that something is wrong because the parent clock setting for "pll" is unresolved.

    //@ simple-audio-card,bitclock-master = <&dailink0_master>;
    //@ simple-audio-card,frame-master = <&dailink0_master>;

    Do you know where the TLV320AIC32x4 driver sets the parent clock for "pll"?

    [ 210.757101] WVC:clk; clk_core_init_rate_req() check best_parent_rate core->name=pll
    [ 210.764758] WVC:clk; clk_core_init_rate_req() parent=(null)
    [ 210.770521] ASoC TLV320AIC32x4 clk : clk_aic32x4_pll_round_rate() rate=11289600, parent_rate=0
    [ 210.779229] ASoC TLV320AIC32x4 clk : clk_aic32x4_pll_calc_muldiv() rate=11289600, parent_rate=0
    [ 210.788015] ASoC TLV320AIC32x4 clk : clk_aic32x4_pll_calc_muldiv() settings->p=1
    [ 210.795438] ASoC TLV320AIC32x4 clk : clk_aic32x4_pll_calc_muldiv() multiplier=112896000000
    [ 210.803952] Division by zero in kernel.
    [ 210.807783] CPU: 1 PID: 7887 Comm: aplay Not tainted 5.4.56 #188
    [ 210.813652] Hardware name: STM32 (Device Tree Support)
    [ 210.818829] [<c011253c>] (unwind_backtrace) from [<c010d780>] (show_stack+0x10/0x14)
    [ 210.826563] [<c010d780>] (show_stack) from [<c0b076f4>] (dump_stack+0xb0/0xc4)
    [ 210.833798] [<c0b076f4>] (dump_stack) from [<c0b04e40>] (Ldiv0_64+0x8/0x18)
    [ 210.840770] [<c0b04e40>] (Ldiv0_64) from [<c098d578>] (__div64_32+0x14/0x20)
    [ 210.847829] [<c098d578>] (__div64_32) from [<c098dae8>] (clk_aic32x4_pll_calc_muldiv+0xc4/0x198)
    [ 210.856629] [<c098dae8>] (clk_aic32x4_pll_calc_muldiv) from [<c098dcc8>] (clk_aic32x4_pll_round_rate+0x44/0xa0)
    [ 210.866742] [<c098dcc8>] (clk_aic32x4_pll_round_rate) from [<c05ab7c0>] (clk_core_determine_round_nolock+0x84/0x1d4)
    [ 210.877288] [<c05ab7c0>] (clk_core_determine_round_nolock) from [<c05b0ba0>] (clk_core_set_rate_nolock+0x50/0x1d4)
    [ 210.887658] [<c05b0ba0>] (clk_core_set_rate_nolock) from [<c05b0d54>] (clk_set_rate+0x30/0x88)
    [ 210.896286] [<c05b0d54>] (clk_set_rate) from [<c098c95c>] (aic32x4_hw_params+0x26c/0x3c8)

    ・・・
    [ 211.004784] ASoC TLV320AIC32x4 clk : clk_aic32x4_pll_round_rate() clk_aic32x4_pll_calc_muldiv error=-1

    Thanks,

  • Hi,

    I have a new question.

    /1/ The Windows application for checking the operation of TLV320AIC3206EVM-U can be downloaded, but is there any software that can be used on a Linux PC (Ubuntu, etc.)?

    /2/ Has the TLV320AIC32x4 i2c driver been proven to work on Linux?
    It doesn't matter if it's a PC or boards.
    Please tell me the environment.
    Kernel version, board parts number, distribution, etc.

    Thanks,

  • Q1: We only have windows application. As to Linux, we usually use alsa tools or i2c tool to debug the codec.

    Q2: We develop the driver on Kernel 4.4 or 4.14 on BBB. As far as I know, the driver code has been already upstream to Kernel main branch, you can download it from latest kernel

  • Hi,

    I understand the existence of the driver source code.
    What I would like to know is the existence of BSPs and MCU boards that have a proven track record of running this driver.

    Thanks,

  • I have an MSP430 F5529 LaunchPad.
    I think doesn't Linux work on this board.
    Does the tlv320aic32x4 i2c driver and Linux work?

  • Yes, it can work on Linux.

    The document describe how to use the tools to generate he register map for MCU platform and it contain a sample code.

  • Can I install Llinux on MSP430 F5529 LaunchPad?
    This CPU has only 128kB of flash and 8kB of RAM.

  • Kindly consult TI MCU team, I'm not the expert on this. As far as I know, it can't, it is only 16-bit MCU and its CPU freq is only 24M, not strong enough to run the Linux system.

  • ??
    Let's return to today's question.
    / 2 / Do you know the MPU board where the TLV320AIC32x4 i2c driver and Linux work? For example, i.MX etc.

  • Is BeagleBone black MPU board? Some of my customers integrate AIC32x4 on i.MX.