Configure Tegra ASoC Driver for custom hardware with TI audio CODEC

Hi actuated-man,

Could you have a try with the debug patch(i2s_debug_prints_patch.txt) in attachment to check the call flow/variables for i2s bus. I think your code does not run into tegra210_i2s_hw_params to cause i2s bus outputs nothing during “aplay”.the following log is mine and could be a reference.

ubuntu@tegra-ubuntu:~$ dmesg | grep tedc

[ 55.527346] (tedc) tegra_alt_asoc_utils_set_rate ++++
[ 55.527609] (tedc) tegra_alt_asoc_utils_set_rate clk_pll_a:282240000, clk_pll_a_out0:45158400, clk_cdev1:11289600 // configure pll_a here
[ 55.527625] (tedc) tegra_alt_asoc_utils_set_rate ----
[ 55.527640] (tedc) tegra210_xbar_set_clock ++++
[ 55.527690] (tedc) tegra210_xbar_set_clock clk_parent:45158400, clk:45158400
[ 55.527703] (tedc) tegra210_xbar_set_clock ----
[ 55.527739] (tedc) snd_soc_dai_set_sysclk ++++
[ 55.527753] (tedc) snd_soc_dai_set_sysclk dai->driver:rt5659-aif1
[ 55.527784] (tedc) snd_soc_dai_set_bclk_ratio ++++ ----
[ 55.527802] (tedc) tegra210_i2s_set_dai_bclk_ratio ++++ bclk_ratio:0
[ 55.527814] (tedc) tegra210_i2s_set_dai_bclk_ratio ----
[ 55.527838] (tedc) snd_soc_dai_set_bclk_ratio ++++ ----
[ 55.527853] (tedc) tegra210_i2s_set_dai_bclk_ratio ++++ bclk_ratio:4
[ 55.527866] (tedc) tegra210_i2s_set_dai_bclk_ratio ----
[ 55.570798] (tedc) tegra210_i2s_hw_params ++++ DAP:1
[ 55.570826] (tedc) tegra210_i2s_hw_params i2sclock:1411200, bitcnt:31, srate:44100
[ 55.570839] (tedc) tegra210_i2s_set_clock_rate ++++ Master Enabled // Here to start i2s and set it as Master.

[ 55.570882] (tedc) tegra210_i2s_set_clock_rate ----
[ 55.570899] (tedc) tegra210_i2s_hw_params ----

i2s_debug_prints_patch.txt (6.01 KB)

Sure enough, tegra210_i2s_hw_params is not called.

...boot messages...
(tedc) snd_soc_dai_set_sysclk ++++ 
(tedc) snd_soc_dai_set_sysclk dai->driver:CIF 
(tedc) tegra_alt_asoc_utils_set_rate ++++
(tedc) tegra_alt_asoc_utils_set_rate clk_pll_a:368640000, clk_pll_a_out0:24576000, clk_cdev1:24000000 
(tedc) tegra_alt_asoc_utils_set_rate ----
(tedc) snd_soc_dai_set_sysclk ++++ 
(tedc) snd_soc_dai_set_sysclk dai->driver:tlv320aic32x4-hifi 
(tedc) snd_soc_dai_set_bclk_ratio ++++ ----
(tedc) tegra210_i2s_set_dai_bclk_ratio ++++ bclk_ratio:1
(tedc) tegra210_i2s_set_dai_bclk_ratio ----
(tedc) tegra210_i2s_set_fmt ++++ DAP:1
(tedc) tegra210_i2s_set_fmt val:1400, data_offset:0, fsync_width:31
(tedc) tegra210_i2s_set_fmt ----
(tedc) snd_soc_dai_set_sysclk ++++ 
(tedc) snd_soc_dai_set_sysclk dai->driver:tlv320aic32x4-hifi 
(tedc) snd_soc_dai_set_sysclk ++++ 

...aplay messages...
(tedc) snd_soc_dai_set_sysclk ++++ 
(tedc) snd_soc_dai_set_sysclk dai->driver:tlv320aic32x4-hifi

It seems to be attached to the DAP Transmit/Receive widgets, which are involved in the audio path established.

469.991587: snd_soc_dapm_output_path: *I2S1 CIF RX -> (direct) -> I2S1 DAP TX
469.991589: snd_soc_dapm_output_path: *I2S1 DAP TX -> (direct) -> I2S1 DAP Transmit
469.991590: snd_soc_dapm_output_path: *I2S1 DAP Transmit -> (direct) -> I2S1 DAP Transmit-Playback
469.991592: snd_soc_dapm_output_path: *I2S1 DAP Transmit-Playback -> (direct) -> Playback

I assume that would be called by the underlying system, not by me, but what do I know. :-)

Where and how do I ensure this is called? Or where do I look to see what is going wrong? Maybe you could put a dump_stack() in there, but I suspect it’s deep in the ASoC mechanism.

Hi actuated-man,

putting the following log for you debug and can you share the dapm status during “aplay” by cat /sys/kernel/debug/asoc/tegra-snd-t210ref-mobile-rt565x/dapm/* (in your case, should be tegra-snd-t210ref)

[ 100.059882] CPU: 0 PID: 890 Comm: aplay Not tainted 3.10.96-tegra #26
[ 100.059897] Call trace:
[ 100.059923] [] dump_backtrace+0x0/0xf4
[ 100.059940] [] show_stack+0x14/0x1c
[ 100.059960] [] dump_stack+0x20/0x28
[ 100.059982] [] tegra210_i2s_hw_params+0x384/0x3bc
[ 100.060019] [] snd_soc_dai_link_event+0x260/0x3b8
[ 100.060038] [] dapm_seq_check_event+0x178/0x224
[ 100.060071] [] dapm_seq_run_coalesced+0x10c/0x1e8
[ 100.060359] [] dapm_seq_run+0xd4/0x3ac
[ 100.060380] [] dapm_power_widgets+0x318/0x444
[ 100.060414] [] soc_dapm_stream_event+0xd0/0xe0
[ 100.060432] [] snd_soc_dapm_stream_event+0x3c/0x54
[ 100.060451] [] soc_pcm_prepare+0x16c/0x1a0
[ 100.060474] [] snd_pcm_do_prepare+0x1c/0x38
[ 100.060492] [] snd_pcm_action_single+0x40/0x8c
[ 100.060509] [] snd_pcm_action_nonatomic+0x68/0x90
[ 100.060525] [] snd_pcm_prepare+0x64/0x84
[ 100.060543] [] snd_pcm_common_ioctl1+0x2c0/0x3bc
[ 100.060571] [] snd_pcm_playback_ioctl1+0x3a0/0x3c0
[ 100.060588] [] snd_pcm_playback_ioctl+0x2c/0x40
[ 100.060607] [] vfs_ioctl+0x1c/0x44
[ 100.060625] [] do_vfs_ioctl+0x220/0x22c
[ 100.060641] [] SyS_ioctl+0xdc/0x18c

In the device tree, please add the property name-prefix and modify audio-routing also.
We used name-prefix = “x”; in order to distinguish between different dai link names. The control names can be duplicated between various drivers like codec, machine, platform so in order to create unique names these prefix is use.

I had omitted the name-prefix because it kept giving me errors; I figured the names were unique enough. But your suggestion got me thinking that was kinda lame, so I went about fixing that. Turns out the name I had given the CODEC didn’t exactly match the name the CODEC gave itself, so when adding widgets it couldn’t find the prefix I indicated. Once I fixed that, the audio path became very clear, and a few mixer settings completed the route (the CODEC disabled all output by default). With that (and replacing a couple capacitors on our amp), output works!

Thanks for all your help, tedc.

Now to get the microphone working… ;-)

Hi actuated-man, It is great to hear that the microphone works for you. well done :)

Hi Actuated-man,

We have added required DT properties and configuration. Still We are in same page like you were…

  1. Not getting I2S Bit clock
  2. In Power tree, vdd-1v8-audio-hv-bias is OFF by default
  3. In tegra gpio config, Values are not configured as sfio
  4. aplay/arecord throwing same error like You faced…

We could not understand Your fix clearly. Could You please explain the fix in detail which you have posted last. It would be helpful to proceed further development.

I don’t have a lot of time to fully describe things, but I can point you at something that was oddly important: the name of the CODEC in the device tree is not arbitrary, and must exactly match the name the driver chooses. Otherwise the driver cannot find the chip.

i2c@7000c000 {
              aic32x4: tlv320aic32x4.0-0018@18 {
                      compatible = "ti,tlv320aic32x4";
                      reg = <0x18>;

See the name in there? “tlv320aic32x4.0-0018@18” had to be formatted exactly like that. The ALSA code looks for the driver stanza by the name of the driver, so make sure yours matches. Your driver probably prints its name whenever it writes to the kernel log.

Also incredibly handy is to see the audio path created, as you’ll likely need to enable the outputs on your CODEC: mine were all off by default. To see them, I wrote the following wrapper script.


set -eu -o pipefail

if ! which "${1:-}" > /dev/null; then
	echo >&2 "usage: $0 command args..."
	exit 2


# clear the trace
sudo bash -c "echo 0 > $t/tracing_on"
sudo bash -c "echo > $t/trace"

# enable ASoC tracing
sudo bash -c "echo 1 > $t/events/asoc/enable"
sudo bash -c "echo 0 > $t/events/asoc/snd_soc_reg_read/enable"

# trace a single invocation
sudo bash -c "echo 1 > $t/tracing_on"
sudo bash -c "echo 0 > $t/tracing_on"

# filter out blank lines
sudo grep '\S' $t/trace > trace.log


I called it “” and used it whenever I ran something like aplay. E.g., “./ aplay sample.wav”.

Hi Actuated Man,
Looks like problem Solved. Only thing is we set the label for codec name. Thanks for your reply…

Can anyone here help me, a complete newbie to the TX2 and Linux Ubuntu 16.04, get started on how to enable and test I2S on the Jetson TX2? Thank you.