Using a real (and different/simpler) audio codec on TX2

I’m having difficulties successfully getting audio to play out of TX2. We’re using a WM8731 codec connected to the first I2S interface (so that’s I2S1 or I2S0 depending on where you look), as well as to the tegra MCLK and an i2c bus. The codec is connected to a TRRS (headset) jack with a jack detect pin, which is going to a tegra GPIO.

I’ve duplicated and modified the default tegra_t186ref_mobile_rt565x.c kernel “ASoC machine” driver to essentially remove the RT565x-specific code and add support for parsing and using the jack detect GPIO from the device tree.

The driver code, as well as a portion of the device tree files (showing codec instantiation and the modified sound node) are here: https://gist.github.com/rpavlik/675dde5bd622bcb0d132f95906901c5c

I’ve sniffed the i2c bus and concluded that the WM8731 driver is successfully communicating at startup with the chip, as confirmed by the successful load of the driver without any warnings. I also no longer see any audio-related errors in the serial console/dmesg: the related lines are:

[    5.352407] nvadsp 2993000.adsp: in probe()...
[    5.368449] nvadsp 2993000.adsp: Registering AMC Error Interrupt
[    5.375012] nvadsp 2993000.adsp: AMC/ARAM initialized.
[    5.381458] nvadsp 2993000.adsp: nvadsp_app_module_probe
...
[    6.916096] tegra210_adsp_audio_platform_probe: platform probe started
[    6.923407] tegra210-adsp adsp_audio: Default param-type to BYTE for mp3-dec1
[    6.931041] tegra210-adsp adsp_audio: Default param-type to BYTE for spkprot
[    6.938641] tegra210-adsp adsp_audio: Default param-type to BYTE for src
[    6.945726] tegra210-adsp adsp_audio: Default param-type to BYTE for aac-dec1
[    6.953358] tegra210-adsp adsp_audio: Default param-type to BYTE for aec
[    6.960078] tegra210-adsp adsp_audio: adma channel page address dt entry not found
[    6.967648] tegra210-adsp adsp_audio: using adma channel page 0
[    6.973691] tegra210_adsp_audio_platform_probe probe successfull.
[    6.991351] OPE platform probe
[    6.994825] OPE platform probe successful
[    7.093596] tegra-snd-t186ref-generic sound: ADMAIF1 <-> ADMAIF1 mapping ok
[    7.100735] tegra-snd-t186ref-generic sound: ADMAIF2 <-> ADMAIF2 mapping ok
[    7.107816] tegra-snd-t186ref-generic sound: ADMAIF3 <-> ADMAIF3 mapping ok
[    7.115003] tegra-snd-t186ref-generic sound: ADMAIF4 <-> ADMAIF4 mapping ok
[    7.122093] tegra-snd-t186ref-generic sound: ADMAIF5 <-> ADMAIF5 mapping ok
[    7.129171] tegra-snd-t186ref-generic sound: ADMAIF6 <-> ADMAIF6 mapping ok
[    7.136293] tegra-snd-t186ref-generic sound: ADMAIF7 <-> ADMAIF7 mapping ok
[    7.143400] tegra-snd-t186ref-generic sound: ADMAIF8 <-> ADMAIF8 mapping ok
[    7.150489] tegra-snd-t186ref-generic sound: ADMAIF9 <-> ADMAIF9 mapping ok
[    7.157610] tegra-snd-t186ref-generic sound: ADMAIF10 <-> ADMAIF10 mapping ok
[    7.164895] tegra-snd-t186ref-generic sound: ADMAIF11 <-> ADMAIF11 mapping ok
[    7.172196] tegra-snd-t186ref-generic sound: ADMAIF12 <-> ADMAIF12 mapping ok
[    7.179474] tegra-snd-t186ref-generic sound: ADMAIF13 <-> ADMAIF13 mapping ok
[    7.186723] tegra-snd-t186ref-generic sound: ADMAIF14 <-> ADMAIF14 mapping ok
[    7.194045] tegra-snd-t186ref-generic sound: ADMAIF15 <-> ADMAIF15 mapping ok
[    7.201298] tegra-snd-t186ref-generic sound: ADMAIF16 <-> ADMAIF16 mapping ok
[    7.208548] tegra-snd-t186ref-generic sound: ADMAIF17 <-> ADMAIF17 mapping ok
[    7.215874] tegra-snd-t186ref-generic sound: ADMAIF18 <-> ADMAIF18 mapping ok
[    7.223173] tegra-snd-t186ref-generic sound: ADMAIF19 <-> ADMAIF19 mapping ok
[    7.230429] tegra-snd-t186ref-generic sound: ADMAIF20 <-> ADMAIF20 mapping ok
[    7.240997] tegra-snd-t186ref-generic sound: ADSP-FE1 <-> ADSP PCM1 mapping ok
[    7.248363] tegra-snd-t186ref-generic sound: ADSP-FE2 <-> ADSP PCM2 mapping ok
[    7.255654] compress asoc: ADSP-FE3 <-> ADSP COMPR1 mapping ok
[    7.261540] compress asoc: ADSP-FE4 <-> ADSP COMPR2 mapping ok
[    7.294324] input: tegra-snd-t186-amati-wm8731 Headphone Jack as /devices/sound/sound/card1/input2
[    7.303852] tegra-snd-t186ref-generic sound: codec-dai "wm8731-hifi" registered

However, a few things don’t work right:

  • Jack detect appears to not be working: when I check the status using sysfs/debugfs, it says that it's not plugged in (and I never see the debug prints in the console) even though I've checked the jack detect voltage levels and have plugged/unplugged the plug.
  • There are very many /dev/snd/pcmC1D* devices (I've determined that C0 is HDA audio via HDMI, and C1 is the main audio hardware "card" on the Tegra), and I can't figure out which one I should be directing audio to in order to just play it out the headphones: I know (at least the codec-side) DAPM names and DAI links involved, but can't figure out a mapping from device index to any of these.
  • Not sure if this matters, but when looking using the command line mixer at the available controls on card 1, I get "tegra210-adsp adsp_audio: Plugin not yet initialized" in the serial console.

Any help on any of the 3 points would be appreciated.

Ryan

I’ve pasted the “interesting” looking controls from the command line mixer below:

567	BOOL	1	I2S1 Loopback                            Off
568	ENUM	1	I2S1 input bit format                    16
569	ENUM	1	I2S1 codec bit format                    None
570	INT	1	I2S1 Sample Rate                         0
571	INT	1	I2S1 Channels                            0
572	ENUM	1	I2S1 RX stereo to mono conv              None
573	ENUM	1	I2S1 RX mono to stereo conv              None
574	ENUM	1	I2S1 TX stereo to mono conv              None
575	ENUM	1	I2S1 TX mono to stereo conv              None
576	INT	2	x Master Playback Volume                 121 121
577	BOOL	2	x Master Playback ZC Switch              Off Off
578	INT	2	x Capture Volume                         23 23
579	BOOL	2	x Line Capture Switch                    Off Off
580	INT	1	x Mic Boost Volume                       0
581	BOOL	1	x Mic Capture Switch                     Off
582	INT	1	x Sidetone Playback Volume               3
583	BOOL	1	x ADC High Pass Filter Switch            On
584	BOOL	1	x Store DC Offset Switch                 Off
585	BOOL	1	x Playback Deemphasis Switch             Off
586	BOOL	1	x Int Spk Switch                         Off
587	BOOL	1	x Headphone Jack Switch                  Off
588	BOOL	1	x Mic Jack Switch                        Off
589	BOOL	1	x Int Mic Switch                         Off
590	ENUM	1	codec-x rate                             None
591	ENUM	1	codec-x format                           None
592	ENUM	1	Jack-state                               None
593	ENUM	1	ADMAIF1 Mux                              I2S1
594	ENUM	1	ADMAIF2 Mux                              I2S6

599	ENUM	1	ADMAIF7 Mux                              MIXER1-1

603	ENUM	1	I2S1 Mux                                 MIXER1-1

611	ENUM	1	SFC4 Mux                                 MIXER1-1
612	ENUM	1	MIXER1-1 Mux                             ADMAIF1
613	ENUM	1	MIXER1-2 Mux                             ASRC1-2

617	ENUM	1	MIXER1-6 Mux                             ADMAIF6

654	ENUM	1	I2S6 Mux                                 ADMAIF2

666	ENUM	1	ASRC1-2 Mux                              ADMAIF5

674	BOOL	1	Adder1 RX1                               On
675	BOOL	1	Adder1 RX2                               On
676	BOOL	1	Adder1 RX3                               Off
677	BOOL	1	Adder1 RX4                               Off
678	BOOL	1	Adder1 RX5                               Off
679	BOOL	1	Adder1 RX6                               On

724	ENUM	1	ADSP-FE1 MUX                             APM-OUT3

733	ENUM	1	ADSP-ADMAIF4 MUX                         APM-OUT1

750	ENUM	1	APM-IN1 MUX                              ADSP-ADMAIF3
751	ENUM	1	APM-IN2 MUX                              None
752	ENUM	1	APM-IN3 MUX                              ADSP-ADMAIF8
753	ENUM	1	APM-IN4 MUX                              None
754	ENUM	1	APM-IN5 MUX                              None
755	ENUM	1	APM-IN6 MUX                              None
756	ENUM	1	APM-IN7 MUX                              None
757	ENUM	1	APM-IN8 MUX                              None
758	ENUM	1	APM-OUT1 MUX                             ADMA2-TX
759	ENUM	1	APM-OUT2 MUX                             None
760	ENUM	1	APM-OUT3 MUX                             AEC

766	ENUM	1	ADMA1 MUX                                APM-IN1
767	ENUM	1	ADMA2 MUX                                None
768	ENUM	1	ADMA3 MUX                                None
769	ENUM	1	ADMA4 MUX                                APM-IN3
770	ENUM	1	ADMA5 MUX                                None
771	ENUM	1	ADMA6 MUX                                None
772	ENUM	1	ADMA7 MUX                                None
773	ENUM	1	ADMA8 MUX                                None
774	ENUM	1	ADMA9 MUX                                None
775	ENUM	1	ADMA10 MUX                               None
776	ENUM	1	ADMA1-TX MUX                             None
777	ENUM	1	ADMA2-TX MUX                             SPKPROT-SW

787	ENUM	1	SPKPROT-SW MUX                           ADMA1
788	ENUM	1	SRC MUX                                  None
789	ENUM	1	AAC-DEC1 MUX                             None
790	ENUM	1	AEC MUX                                  ADMA4

796	BOOL	1	x Output Mixer Line Bypass Switch        Off
797	BOOL	1	x Output Mixer Mic Sidetone Switch       Off
798	BOOL	1	x Output Mixer HiFi Playback Switch      Off
799	ENUM	1	x Input Mux                              Line In

Hi Ryan,

With regard to the jack detect gpio can you check bit 6 (input enable) is set in the following padctl register …

sudo cat /sys/kernel/debug/tegra_pinctrl_reg | grep gpio_aud0_pj5
Bank: 0 Reg: 0x02431018 Val: 0x00000058 -> gpio_aud0_pj5

If that looks good, then check bit 0 is set and bit 1 are not set in the GPIO_ENABLE_CONFIG (ENB = 0x4d) register …

ubuntu@tegra-ubuntu:~$ sudo cat /sys/kernel/debug/tegra_gpio | grep “Port|J:5”
Port:Pin:ENB DBC IN OUT_CTRL OUT_VAL INT_CLR
J:5 0x4d 0x0 0x1 0x1 0x0 0x0

If all looks good, have you checked the return status from snd_soc_jack_add_gpios()?

With regard to the PCM devices, yes card 0 if for HDA and card 1 is for the I2S/DMIC/DSPK etc. There should be 20 playback and capture devices for card 1 and this is because there are 20 DMA channels for the APE (audio processing engine). The APE has a crossbar that routes the DMA traffic to the various devices such as I2S/DMIC/DSPK, etc. We can configure the route via the mixer controls using amixer and map any I2S to any DMA channel. For more information take a look at the “Tegra ASoC Driver” (under “System Configuration”) in the L4T documentation [0]. However, essentially to route I2S0 to ADMAIF1 you would …

$ amixer -c tegrasndt186ref sset “I2S1 Mux” “ADMAIF1”

Then you should be able to use the following device for playback …

$ aplay -D hw:tegrasndt186ref,0

Or for capture …

amixer -c tegrasndt186ref sset "ADMAIF1 Mux" "I2S1" arecord -D hw:tegrasndt186ref,0

We don’t currently support the ADSP for audio processing on L4T and so you can ignore the ADSP message you are seeing.

Regards,
Jon

[0] https://developer.nvidia.com/embedded/dlc/l4t-documentation-28-2-ga

The pinctrl line matches yours: 0x00000058 (so bit 6 set) is also on mine.

On the GPIO ENB, I get 0x01 - different than you, but bit 0 set and bit 1 not set.

Thanks for the mixer/control info. Will do some testing there.

Looks like I have a GPIO issue: adding a check and return-on-error on snd_soc_jack_add_gpios return value gives me:

[    3.648385] tegra-snd-t186ref-generic sound: snd_soc_jack_add_gpios failed -517
[    3.648388] tegra-snd-t186ref-generic sound: ASoC: failed to init wm8731-playback: -517
[    3.648391] tegra-snd-t186ref-generic sound: ASoC: failed to instantiate card -517
[    3.657057] gpiod_unexport: invalid GPIO
[    3.658847] tegra-snd-t186ref-generic sound: snd_soc_register_card failed (-517)

So now I have some DT debugging to do. Will be back if still stuck.

OK, so I’ve updated to 28.2-equivalent kernel, ported over updates in the reference driver to my driver, and also fixed the jack detection, so that part now works reliably at least.

I’ve updated the DTS (mostly just added a few DAPM routes in an attempt to fix error messages, as well as adding the GPIO hogs to “function” in modified form that the troubleshooting section mentions) and source that I had uploaded: https://gist.github.com/rpavlik/675dde5bd622bcb0d132f95906901c5c You can see the changes (which include the 28.1 to 28.2 changes as well as my fixes to jack detect) here https://gist.github.com/rpavlik/675dde5bd622bcb0d132f95906901c5c/revisions

Note that my GPIO hogs differ from the L4T docs, presumably because I’m using TX2 not TX1? I2S0/1 and AUDIO_MCLK is on the same pins as GPIO PJ.0-PJ.4 according to the pinmux spreadsheet. However, adding this gpio hog section to the config didn’t appear to affect anything. I’m wondering if maybe this is one of the cases where order matters in device tree and it needs to go separately from the WM8731 definition up with other GPIO hogs. (I am using the default “Quill” BCT files because when I used my custom ones for this board with L4T, the flashing tool stops responding/doesn’t boot up.)

RE: the mixer commands, if specifying the name I need to use a different name (since I don’t call the card t186ref), but otherwise they appear to work as expected. (I’m only really concerned about playback right now.) I had read the Tegra ASoC driver docs but to be honest they were rather overwhelming and hard to follow when I only wanted to implement a simple single stereo audio output.

However, when trying to play a sample bit of audio, I get no speaker output, and it appears to finish much quicker than it should. Here is my terminal log:

nvidia@tegra-ubuntu:~$ amixer -c 1 sset "I2S1 Mux" "ADMAIF1"
Simple mixer control 'I2S1 Mux',0
  Capabilities: enum
  Items: 'None' 'ADMAIF1' 'ADMAIF2' 'ADMAIF3' 'ADMAIF4' 'ADMAIF5' 'ADMAIF6' 'ADMAIF7' 'ADMAIF8' 'ADMAIF9' 'ADMAIF10' 'ADMAIF11' 'ADMAIF12' 'ADMAIF13' 'ADMAIF14' 'ADMAIF15' 'ADMAIF16' 'I2S1' 'I2S2' 'I2S3' 'I2S4' 'I2S5' 'I2S6' 'SFC1' 'SFC2' 'SFC3' 'SFC4' 'MIXER1-1' 'MIXER1-2' 'MIXER1-3' 'MIXER1-4' 'MIXER1-5' 'AMX1' 'AMX2' 'AMX3' 'AMX4' 'ARAD1' 'SPDIF1-1' 'SPDIF1-2' 'AFC1' 'AFC2' 'AFC3' 'AFC4' 'AFC5' 'AFC6' 'OPE1' 'SPKPROT1' 'MVC1' 'MVC2' 'IQC1-1' 'IQC1-2' 'IQC2-1' 'IQC2-2' 'DMIC1' 'DMIC2' 'DMIC3' 'DMIC4' 'ADX1-1' 'ADX1-2' 'ADX1-3' 'ADX1-4' 'ADX2-1' 'ADX2-2' 'ADX2-3' 'ADX2-4' 'ADX3-1' 'ADX3-2' 'ADX3-3' 'ADX3-4' 'ADX4-1' 'ADX4-2' 'ADX4-3' 'ADX4-4' 'ADMAIF17' 'ADMAIF18' 'ADMAIF19' 'ADMAIF20' 'ASRC1-1' 'ASRC1-2' 'ASRC1-3' 'ASRC1-4' 'ASRC1-5' 'ASRC1-6'
  Item0: 'ADMAIF1'

nvidia@tegra-ubuntu:~$ time aplay -D hw:tegrasndt186ama,0 LRMonoPhase4.wav 
Playing WAVE 'LRMonoPhase4.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Stereo

real	0m1.262s
user	0m0.052s
sys	0m0.108s

The “LRMonoPhase4.wav” file is “Uncompressed 16-bit PCM audio”, stereo, with a sample rate of 48000Hz and a duration of 38 seconds - much longer than the 1.26 seconds it takes to play it on the Tegra.

I’ve run amixer -c 1 contents (to get all the mixer values) and redirected it to a file, which I’ll attach. Not sure if it matters, but I see on std err the following message 10 times:

amixer: Control hw:1 element TLV read error: No such device or address

Is there some way to hard-code a default value for those mixers?

I’ve run vizdapm https://github.com/mihais/asoc-tools (as suggested by an ASoC tutorial) to look at the DAPM routes: ./vizdapm /sys/kernel/debug/asoc/tegra-snd-t186-amati-wm8731/dapm/ vizdapm.png I’ll attach the image. The only path that I see that’s more than 2 nodes is the one explicitly, entirely set up with mic bias in the device tree file. Is this a problem? (Should I be manually adding more routes to complete a path?) Or is the vizdapm app no longer useful/not useful on Tegra?

dmesg: I get the following audio-related messages and error messages on boot (not sure the source or reason for the SError - I don’t remember seeing this before updating to 28.2.)

[10:26:24:331] [    0.310643] Advanced Linux Sound Architecture Driver Initialized.␍␊
[10:26:24:373] [    0.316666] vdd-1v8: 1800 mV ␍␊
[10:26:24:377] [    0.316681] vdd-1v8: Failed to create debugfs directory␍␊
[10:26:25:003] [    2.444992] gk20a 17000000.gp10b: failed to allocate secure buffer -12␍␊
[10:26:27:966] [    5.355901] tegra186-padctl 3520000.pinctrl: Missing OC pin 0 pinctrl state vbus_en0_sfio_tristate: -19␍␊
[10:26:28:032] [    5.368635] snd_hda_codec_hdmi hdaudioC0D4: HDMI: Unknown ELD version 0␍␊
[10:26:28:040] [    5.369263] input: tegra-hda HDMI/DP,pcm=3 as /devices/3510000.hda/sound/card0/input0␍␊
[10:26:28:050] [    5.369459] input: tegra-hda HDMI/DP,pcm=7 as /devices/3510000.hda/sound/card0/input1␍␊
[10:26:28:060] [    5.370025] tegra210_adsp_audio_platform_probe: platform probe started␍␊
[10:26:28:068] [    5.371055] tegra210-adsp adsp_audio: Default param-type to BYTE for mp3-dec1␍␊
[10:26:28:077] [    5.371671] tegra210-adsp adsp_audio: Default param-type to BYTE for spkprot␍␊
[10:26:28:084] [    5.372638] tegra210-adsp adsp_audio: Default param-type to BYTE for src␍␊
[10:26:28:094] [    5.373293] tegra210-adsp adsp_audio: Default param-type to BYTE for aac-dec1␍␊
[10:26:28:102] [    5.374117] tegra210-adsp adsp_audio: Default param-type to BYTE for aec␍␊
[10:26:28:111] [    5.374123] tegra210-adsp adsp_audio: adma channel page address dt entry not found␍␊
[10:26:28:120] [    5.374126] tegra210-adsp adsp_audio: using adma channel page 0␍␊
[10:26:28:128] [    5.387587] tegra210_adsp_audio_platform_probe probe successfull.␍␊
[10:26:28:152] [    5.499857] tegra-snd-t186ref-generic sound: ADMAIF1 <-> ADMAIF1 mapping ok␍␊
[10:26:28:161] [    5.499967] tegra-snd-t186ref-generic sound: ADMAIF2 <-> ADMAIF2 mapping ok␍␊
[10:26:28:169] [    5.500082] tegra-snd-t186ref-generic sound: ADMAIF3 <-> ADMAIF3 mapping ok␍␊
[10:26:28:178] [    5.500207] tegra-snd-t186ref-generic sound: ADMAIF4 <-> ADMAIF4 mapping ok␍␊
[10:26:28:186] [    5.500334] tegra-snd-t186ref-generic sound: ADMAIF5 <-> ADMAIF5 mapping ok␍␊
[10:26:28:195] [    5.500437] tegra-snd-t186ref-generic sound: ADMAIF6 <-> ADMAIF6 mapping ok␍␊
[10:26:28:204] [    5.500545] tegra-snd-t186ref-generic sound: ADMAIF7 <-> ADMAIF7 mapping ok␍␊
[10:26:28:212] [    5.500666] tegra-snd-t186ref-generic sound: ADMAIF8 <-> ADMAIF8 mapping ok␍␊
[10:26:28:220] [    5.501164] tegra-snd-t186ref-generic sound: ADMAIF9 <-> ADMAIF9 mapping ok␍␊
[10:26:28:229] [    5.501275] tegra-snd-t186ref-generic sound: ADMAIF10 <-> ADMAIF10 mapping ok␍␊
[10:26:28:236] [    5.501380] tegra-snd-t186ref-generic sound: ADMAIF11 <-> ADMAIF11 mapping ok␍␊
[10:26:28:246] [    5.501483] tegra-snd-t186ref-generic sound: ADMAIF12 <-> ADMAIF12 mapping ok␍␊
[10:26:28:256] [    5.501608] tegra-snd-t186ref-generic sound: ADMAIF13 <-> ADMAIF13 mapping ok␍␊
[10:26:28:263] [    5.501725] tegra-snd-t186ref-generic sound: ADMAIF14 <-> ADMAIF14 mapping ok␍␊
[10:26:28:272] [    5.501829] tegra-snd-t186ref-generic sound: ADMAIF15 <-> ADMAIF15 mapping ok␍␊
[10:26:28:281] [    5.501950] tegra-snd-t186ref-generic sound: ADMAIF16 <-> ADMAIF16 mapping ok␍␊
[10:26:28:290] [    5.502059] tegra-snd-t186ref-generic sound: ADMAIF17 <-> ADMAIF17 mapping ok␍␊
[10:26:28:298] [    5.502178] tegra-snd-t186ref-generic sound: ADMAIF18 <-> ADMAIF18 mapping ok␍␊
[10:26:28:307] [    5.502286] tegra-snd-t186ref-generic sound: ADMAIF19 <-> ADMAIF19 mapping ok␍␊
[10:26:28:314] [    5.502391] tegra-snd-t186ref-generic sound: ADMAIF20 <-> ADMAIF20 mapping ok␍␊
[10:26:28:324] [    5.508050] tegra-snd-t186ref-generic sound: ADSP-FE1 <-> ADSP PCM1 mapping ok␍␊
[10:26:28:332] [    5.508189] tegra-snd-t186ref-generic sound: ADSP-FE2 <-> ADSP PCM2 mapping ok␍␊
[10:26:28:340] [    5.508228] compress asoc: ADSP-FE3 <-> ADSP COMPR1 mapping ok␍␊
[10:26:28:348] [    5.508263] compress asoc: ADSP-FE4 <-> ADSP COMPR2 mapping ok␍␊
[10:26:28:355] [    5.537230] input: tegra-snd-t186-amati-wm8731 Headphone Jack as /devices/sound/sound/card1/input2␍␊
[10:26:28:365] [    5.537717] tegra-snd-t186ref-generic sound: codec-dai "wm8731-hifi" registered␍␊
[10:26:28:605] [    5.660223] tegra-snd-t186ref-generic sound: jack status = 1␍␊
[10:26:28:611] [    5.660227] tegra-snd-t186ref-generic sound: switch state to 2␍␊
[10:26:28:785] [    5.792826] CPU0: SError detected, daif=1c0, spsr=0x800000c5, mpidr=80000100, esr=bf40c000␍␊
[10:26:28:794] [    5.792828] CPU3: SError detected, daif=1c0, spsr=0x800000c5, mpidr=80000101, esr=bf40c000␍␊
[10:26:28:805] [    5.792831] CPU5: SError detected, daif=1c0, spsr=0x800000c5, mpidr=80000103, esr=bf40c000␍␊
[10:26:28:812] [    5.792834] CPU4: SError detected, daif=1c0, spsr=0x800000c5, mpidr=80000102, esr=bf40c000␍␊
[10:26:28:823] [    5.792838] CPU2: SError detected, daif=1c0, spsr=0x800000c5, mpidr=80000001, esr=be000000␍␊
[10:26:28:831] [    5.792845] CPU1: SError detected, daif=1c0, spsr=0x600000c5, mpidr=80000000, esr=be000000␍␊
[10:26:28:842] [    5.792954] ROC:CCE Machine Check Error:␍␊
[10:26:28:846] [    5.792957] ⇥	Address Type = Secure DRAM␍␊
[10:26:28:851] [    5.792971] ⇥	Address = 0x0 (Unknown Device)␍␊
[10:26:28:858] [    5.793075] ROC:IOB Machine Check Error:␍␊
[10:26:28:863] [    5.793077] ⇥	Address Type = Secure DRAM␍␊
[10:26:28:868] [    5.793080] ⇥	Address = 0x0 (Unknown Device)␍␊
[10:26:28:928] [    5.860029] ALSA device list:␍␊
[10:26:28:933] [    5.860031]   #0: tegra-hda at 0x3518000 irq 391␍␊
[10:26:28:939] [    5.860032]   #1: tegra-snd-t186-amati-wm8731␍␊

plus a lot of messages like this - can I disable the ADSP somehow in device tree if it’s not usable?

tegra210-adsp adsp_audio: ADSP is not booted yet␍␊

and this at the end of boot, presumably it’s trying to play a startup sound?

[10:26:43:584] [   21.101318] tegra_t186ref_dai_init: audio_clock.set_mclk = 45158400 Hz, aud_mclk = 11289600 Hz, codec rate = 44100 Hz␍␊
[10:26:43:648] [   21.165100] tegra_t186ref_dai_init: audio_clock.set_mclk = 45158400 Hz, aud_mclk = 11289600 Hz, codec rate = 44100 Hz␍␊
[10:26:43:710] [   21.227467] tegra_t186ref_dai_init: audio_clock.set_mclk = 45158400 Hz, aud_mclk = 11289600 Hz, codec rate = 44100 Hz␍␊
[10:26:43:769] [   21.287008] tegra_t186ref_dai_init: audio_clock.set_mclk = 45158400 Hz, aud_mclk = 11289600 Hz, codec rate = 44100 Hz␍␊
[10:26:43:784] [   21.301263] tegra_t186ref_dai_init: audio_clock.set_mclk = 45158400 Hz, aud_mclk = 11289600 Hz, codec rate = 44100 Hz␍␊
[10:26:43:799] [   21.316259] tegra_t186ref_dai_init: audio_clock.set_mclk = 45158400 Hz, aud_mclk = 11289600 Hz, codec rate = 44100 Hz␍␊
[10:26:43:843] [   21.360501] tegra_t186ref_dai_init: audio_clock.set_mclk = 45158400 Hz, aud_mclk = 11289600 Hz, codec rate = 44100 Hz␍␊
[10:26:43:858] [   21.373981] tegra_t186ref_dai_init: audio_clock.set_mclk = 45158400 Hz, aud_mclk = 11289600 Hz, codec rate = 44100 Hz␍␊
[10:26:43:879] [   21.396745] tegra_t186ref_dai_init: audio_clock.set_mclk = 45158400 Hz, aud_mclk = 11289600 Hz, codec rate = 44100 Hz␍␊
[10:26:43:924] [   21.441318] tegra_t186ref_dai_init: audio_clock.set_mclk = 45158400 Hz, aud_mclk = 11289600 Hz, codec rate = 44100 Hz␍␊

Playing the WAV file mentioned above (48KHz) prompts the dmesg output:

[11:15:18:381] [  374.403734] tegra_t186ref_dai_init: audio_clock.set_mclk = 49152000 Hz, aud_mclk = 12288000 Hz, codec rate = 48000 Hz␍␊

I tried probing the I2S data line (IN for the codec, OUT from TX2) while I was running the above aplay command in a loop, but I didn’t see any data. Now, the WM8731 we’re using is a QFN package and unfortunately there are no test points on the I2S lines of our board, so it’s possible I was missing the pad with my scope probe, but I feel fairly confident, especially since the playback speed doesn’t match reality.

Thanks for any help you can provide!
vizdapm.png
amixer-contents.txt (449 KB)

Hi Ryan,

Thanks for all the info.

  1. GPIO/Pin configuration
    TX1 is different from TX2 (which is not clear from the docs). For TX1 the selection of whether a pin was a GPIO or SFIO (special function IO, eg I2S, etc) is configured via the GPIO registers. For TX2 and newer devices this is now configured by the pinmux registers. So you do not need the gpio hogs part in your DT. If you dump the contents of ‘/sys/kernel/debug/tegra_pinctrl_reg’ you should have something like the following for dap1 and the aud_mclk …
$ sudo cat /sys/kernel/debug/tegra_pinctrl_reg | grep 'dap1\|mclk'
Bank: 0 Reg: 0x02431020 Val: 0x00000400 -> aud_mclk_pj4
Bank: 0 Reg: 0x02431028 Val: 0x00000400 -> dap1_fs_pj3
Bank: 0 Reg: 0x02431030 Val: 0x00000458 -> dap1_din_pj2
Bank: 0 Reg: 0x02431038 Val: 0x00000400 -> dap1_dout_pj1
Bank: 0 Reg: 0x02431040 Val: 0x00000400 -> dap1_sclk_pj0

Bit 10 in the above registers indicates if it is GPIO (0) or SFIO (1). You can see all of mine are SFIO and bits [1:0] are 0 which is for I2S. See the ‘PADCTL_AUDIO_DAP1_xxx’ registers in the TRM for more details.

  1. Audio playback
    If playback completes in a very short amount of time, then this does indicate that the audio path is not complete. Mostly likely you will find that the I2S port is not even turning on. Typically there are some codec related settings that need to be turned on in order to complete the path. To see what dapm widgets are turning on I typically …
echo 0 > /sys/kernel/debug/tracing/events/enable
echo 0 > /sys/kernel/debug/tracing/trace
echo 1 > /sys/kernel/debug/tracing/events/asoc/snd_soc_dapm_widget_power/enable

< initiate playback >

cat /sys/kernel/debug/tracing/trace

I recommend that you check the codec documentation and ensure the registers are setup correctly. You
should be able to dump the registers for the codec via /sys/kernel/debug/regmap/.

  1. Mixer Errors
    Ideally you should not see any mixer errors while dumping all the mixer control settings. You may wish to check the latest wm8731 driver from the mainline kernel to see if there are any differences in this regard. Other than hacking the driver I am not sure of a way to set the defaults. However, it is probably worth debugging this issue and fixing it.

  2. ADSP
    The ADSP messages are harmless so ignore these. It is possible to disable via the kernel configuration but I did run into some compilation errors. I can help with this is necessary, but we will be disabling in future releases by default.

Regards,
Jon

Thanks for the tip on the gpio hog vs pinmux - that makes more sense since nowhere else did I have a gpio hog with “function” in it. My initial values (using the Quill BCT) were

Bank: 0 Reg: 0x02431020 Val: 0x00000400 -> aud_mclk_pj4
Bank: 0 Reg: 0x02431028 Val: 0x00000440 -> dap1_fs_pj3
Bank: 0 Reg: 0x02431030 Val: 0x00000450 -> dap1_din_pj2
Bank: 0 Reg: 0x02431038 Val: 0x00000440 -> dap1_dout_pj1
Bank: 0 Reg: 0x02431040 Val: 0x00000440 -> dap1_sclk_pj0

which looked wrong - fs,etc. shouldn’t be input according to my pinmux spreadsheet (only din). I updated the pinctrl in the dts file and successfully got it to match yours (as well as what I expected based on the spreadsheet).

Initially I didn’t get anything in the trace, but after digging thru the widgets and adjusting the routes I got a better looking trace. I’ll attach the trace log from playing that audio file (I’ve enabled all ASoC traces, not just the one you mentioned), as well as the script I’m using to set up the mixers/controls and play the audio.

So now, when I play the file, it acts more realistic - seems like it’s trying to play for a while, and the clock rates that are getting set per dmesg (I added messages to the codec driver) are the expected ones:

[15:39:40:434] [  137.835166] tegra_t186ref_dai_init: audio_clock.set_mclk = 49152000 Hz, aud_mclk = 12288000 Hz, codec rate = 48000 Hz␍␊
[15:39:40:445] [  137.846260] *** wm8731_set_dai_sysclk freq=12288000Hz␍␊
[15:39:40:464] [  137.863033] *** wm8731_startup␍␊
[15:39:40:468] [  137.866451] *** wm8731_hw_params␍␊

but then I get the following error, after almost exactly 20 seconds based on the kernel trace messages.

nvidia@tegra-ubuntu:~$ ./audiotest.sh 
Simple mixer control 'I2S1 Mux',0
  Capabilities: enum
  Items: 'None' 'ADMAIF1' 'ADMAIF2' 'ADMAIF3' 'ADMAIF4' 'ADMAIF5' 'ADMAIF6' 'ADMAIF7' 'ADMAIF8' 'ADMAIF9' 'ADMAIF10' 'ADMAIF11' 'ADMAIF12' 'ADMAIF13' 'ADMAIF14' 'ADMAIF15' 'ADMAIF16' 'I2S1' 'I2S2' 'I2S3' 'I2S4' 'I2S5' 'I2S6' 'SFC1' 'SFC2' 'SFC3' 'SFC4' 'MIXER1-1' 'MIXER1-2' 'MIXER1-3' 'MIXER1-4' 'MIXER1-5' 'AMX1' 'AMX2' 'AMX3' 'AMX4' 'ARAD1' 'SPDIF1-1' 'SPDIF1-2' 'AFC1' 'AFC2' 'AFC3' 'AFC4' 'AFC5' 'AFC6' 'OPE1' 'SPKPROT1' 'MVC1' 'MVC2' 'IQC1-1' 'IQC1-2' 'IQC2-1' 'IQC2-2' 'DMIC1' 'DMIC2' 'DMIC3' 'DMIC4' 'ADX1-1' 'ADX1-2' 'ADX1-3' 'ADX1-4' 'ADX2-1' 'ADX2-2' 'ADX2-3' 'ADX2-4' 'ADX3-1' 'ADX3-2' 'ADX3-3' 'ADX3-4' 'ADX4-1' 'ADX4-2' 'ADX4-3' 'ADX4-4' 'ADMAIF17' 'ADMAIF18' 'ADMAIF19' 'ADMAIF20' 'ASRC1-1' 'ASRC1-2' 'ASRC1-3' 'ASRC1-4' 'ASRC1-5' 'ASRC1-6'
  Item0: 'ADMAIF1'
Simple mixer control 'x Output Mixer HiFi',0
  Capabilities: pswitch pswitch-joined
  Playback channels: Mono
  Mono: Playback [on]
numid=572,iface=MIXER,name='I2S1 Channels'
  ; type=INTEGER,access=rw------,values=1,min=0,max=16,step=0
  : values=2
Playing WAVE 'LRMonoPhase4.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Stereo
aplay: pcm_write:1940: write error: Input/output error

real	0m20.455s
user	0m0.032s
sys	0m0.096s

Unfortunately “write error: Input/output error” is very vague. Any tips on tracking this down?

(Re: The mixer errors - I noticed that when I saw those, I also got dmesg warnings about adsp, so I think it’s just when the dump tries to interrogate an adsp-related mixer setting.)

I’ve updated the dts file at https://gist.github.com/rpavlik/675dde5bd622bcb0d132f95906901c5c (see the revisions tab to see my most recent changes)

I’ve also attached the output from the “tegra-audio-debug.sh” script you’ve attached to some other forum threads (contains the alsactl dump as well as all DAPM data)

(Strangely, when I tried to get the regmap debug data for the codec, I got nothing, and got an error in dmesg. I suspect the registers are right, since I’ve stuck prints in the main calls of the codec driver and it’s a very, very simple codec compared to even the simplest one I’ve read about on these forums.

[16:06:14:919] [ 1732.330785] ------------[ cut here ]------------␍␊
[16:06:14:923] [ 1732.335434] WARNING: at ffffffc0005b3864 [verbose debug info unavailable]␍␊
[16:06:14:939] [ 1732.342223] Modules linked in:␍␊
[16:06:14:939] [ 1732.345294] ␍␊
[16:06:14:939] [ 1732.346804] CPU: 3 PID: 2232 Comm: cat Not tainted 4.4.38+ #2␍␊
[16:06:14:943] [ 1732.352557] Hardware name: quill (DT)␍␊
[16:06:14:947] [ 1732.356226] task: ffffffc1e5aae400 ti: ffffffc1af59c000 task.ti: ffffffc1af59c000␍␊
[16:06:14:954] [ 1732.363728] PC is at regmap_debugfs_get_dump_start.part.0+0x1ac/0x220␍␊
[16:06:14:958] [ 1732.370174] LR is at regmap_debugfs_get_dump_start.part.0+0x130/0x220␍␊
[16:06:14:969] [ 1732.376617] pc : [<ffffffc0005b3864>] lr : [<ffffffc0005b37e8>] pstate: 60000145␍␊
[16:06:14:972] [ 1732.384011] sp : ffffffc1af59fcc0␍␊
[16:06:14:977] [ 1732.387329] x29: ffffffc1af59fcc0 x28: ffffffc1ebbf7c00 ␍␊
[16:06:14:982] [ 1732.392673] x27: ffffffc1af59fda8 x26: 0000000000000010 ␍␊
[16:06:14:986] [ 1732.398016] x25: 0000000000000000 x24: 0000000000000000 ␍␊
[16:06:14:991] [ 1732.403361] x23: ffffffc1ebbf7d20 x22: ffffffc1ebbf7d20 ␍␊
[16:06:14:999] [ 1732.408702] x21: ffffffc1ebbf7d30 x20: 0000000000000000 ␍␊
[16:06:15:003] [ 1732.414044] x19: ffffffc1ebbf7d20 x18: 0000000000000020 ␍␊
[16:06:15:007] [ 1732.419384] x17: 000000000041a1c0 x16: ffffffc0001dae98 ␍␊
[16:06:15:014] [ 1732.424725] x15: 0000000000000020 x14: 0000000000000000 ␍␊
[16:06:15:018] [ 1732.430064] x13: 0000000000000000 x12: 0000000000000001 ␍␊
[16:06:15:023] [ 1732.435405] x11: 0000000000000038 x10: 0000000000000068 ␍␊
[16:06:15:031] [ 1732.440744] x9 : ffffffc1af59fd30 x8 : ffffffc1af59fd30 ␍␊
[16:06:15:034] [ 1732.446085] x7 : ffffffc000f9fef0 x6 : 0000000000000001 ␍␊
[16:06:15:039] [ 1732.451426] x5 : 0000000000000000 x4 : 0000000000000000 ␍␊
[16:06:15:045] [ 1732.456767] x3 : ffffffc0005ab738 x2 : 0000000000000000 ␍␊
[16:06:15:050] [ 1732.462105] x1 : 0000000000000001 x0 : 000000000000000f ␍␊
[16:06:15:055] [ 1732.467445] ␍␊
[16:06:15:058] [ 1732.469522] ---[ end trace 28a214836fb21701 ]---␍␊
[16:06:15:062] [ 1732.474144] Call trace:␍␊
[16:06:15:068] [ 1732.476609] [<ffffffc0005b3864>] regmap_debugfs_get_dump_start.part.0+0x1ac/0x220␍␊
[16:06:15:072] [ 1732.484096] [<ffffffc0005b3b3c>] regmap_read_debugfs+0x264/0x2b8␍␊
[16:06:15:078] [ 1732.490108] [<ffffffc0005b3be8>] regmap_map_read_file+0x28/0x30␍␊
[16:06:15:084] [ 1732.496038] [<ffffffc0001d9a4c>] __vfs_read+0x1c/0xc8␍␊
[16:06:15:089] [ 1732.501096] [<ffffffc0001da2d4>] vfs_read+0x7c/0x148␍␊
[16:06:15:094] [ 1732.506067] [<ffffffc0001daedc>] SyS_read+0x44/0xa0␍␊
[16:06:15:099] [ 1732.510957] [<ffffffc000084ff0>] el0_svc_naked+0x24/0x28␍␊

)

trace.txt (30.5 KB)
audiotest.sh.txt (189 Bytes)
tegra-audio-debug.txt (649 KB)

Hi Ryan,

Looking at the trace I am still wondering if the path through the codec is complete. Seems a bit too breif. Looking at the wm8731 driver I would have expected to see it turn on the DAC, etc. So I still think something is missing with regard to the routing. I will need to find some time next week to look at this.

Typically, when I see ‘IO errors’ reported, it is usually a sign the I2S interface is not active. Looking at your DTS it appears that you have commented out the bit clock and frame sync slave. So is the codec the master? If so, then most likely the codec is not generating the bit and frame clocks.

I do not recall seeing an problems with dumping all the mixer controls with the ADSP being enabled. The only problem I would see if I did …

alsactl -f store myalsa-settings.txt alsactl -f restore myalsa-settings.txt

Then it would complain that it could not restore the ADSP settings, but would not prevent you from dumping or setting other controls. If you seen the issue with the stock rel28.2 release with no changes, then that definitely sounds like a bug.

With regard, to the regmap registers are you dumping …

$ sudo cat /sys/kernel/debug/regmap//registers

If so and you see the above, then that sounds bad.

Regards,
Jon

I’ve updated the gist with the code again - basically just adjusted the dapm routing (and included the pinctrl updates). The in-kernel machine drivers that use WM8371, such as kernel-4.4/sound/soc/atmel/sam9x5_wm8731.c (as used by the book “GNU/Linux Rapid Embedded Programming”) don’t appear to mention (in their DTS nor code) the DAC DAPM widget but I’ve added it anyway.

In an attempt to look into the register setting of the codec, I turned on regmap tracing, which also conveniently shows the tegra audio system items as well. I’ve attached the trace log.

Still getting the below messages, though I do now hear a “click” when the audio playback is supposed to be starting.

nvidia@tegra-ubuntu:~$ ./audiotest.sh 
numid=592,iface=MIXER,name='ADMAIF1 Mux'
  ; type=ENUMERATED,access=rw------,values=1,items=83
  ; Item #0 'None'
  ; Item #1 'ADMAIF1'
  ; Item #2 'ADMAIF2'
  ; Item #3 'ADMAIF3'
  ; Item #4 'ADMAIF4'
  ; Item #5 'ADMAIF5'
  ; Item #6 'ADMAIF6'
  ; Item #7 'ADMAIF7'
  ; Item #8 'ADMAIF8'
  ; Item #9 'ADMAIF9'
  ; Item #10 'ADMAIF10'
  ; Item #11 'ADMAIF11'
  ; Item #12 'ADMAIF12'
  ; Item #13 'ADMAIF13'
  ; Item #14 'ADMAIF14'
  ; Item #15 'ADMAIF15'
  ; Item #16 'ADMAIF16'
  ; Item #17 'I2S1'
  ; Item #18 'I2S2'
  ; Item #19 'I2S3'
  ; Item #20 'I2S4'
  ; Item #21 'I2S5'
  ; Item #22 'I2S6'
  ; Item #23 'SFC1'
  ; Item #24 'SFC2'
  ; Item #25 'SFC3'
  ; Item #26 'SFC4'
  ; Item #27 'MIXER1-1'
  ; Item #28 'MIXER1-2'
  ; Item #29 'MIXER1-3'
  ; Item #30 'MIXER1-4'
  ; Item #31 'MIXER1-5'
  ; Item #32 'AMX1'
  ; Item #33 'AMX2'
  ; Item #34 'AMX3'
  ; Item #35 'AMX4'
  ; Item #36 'ARAD1'
  ; Item #37 'SPDIF1-1'
  ; Item #38 'SPDIF1-2'
  ; Item #39 'AFC1'
  ; Item #40 'AFC2'
  ; Item #41 'AFC3'
  ; Item #42 'AFC4'
  ; Item #43 'AFC5'
  ; Item #44 'AFC6'
  ; Item #45 'OPE1'
  ; Item #46 'SPKPROT1'
  ; Item #47 'MVC1'
  ; Item #48 'MVC2'
  ; Item #49 'IQC1-1'
  ; Item #50 'IQC1-2'
  ; Item #51 'IQC2-1'
  ; Item #52 'IQC2-2'
  ; Item #53 'DMIC1'
  ; Item #54 'DMIC2'
  ; Item #55 'DMIC3'
  ; Item #56 'DMIC4'
  ; Item #57 'ADX1-1'
  ; Item #58 'ADX1-2'
  ; Item #59 'ADX1-3'
  ; Item #60 'ADX1-4'
  ; Item #61 'ADX2-1'
  ; Item #62 'ADX2-2'
  ; Item #63 'ADX2-3'
  ; Item #64 'ADX2-4'
  ; Item #65 'ADX3-1'
  ; Item #66 'ADX3-2'
  ; Item #67 'ADX3-3'
  ; Item #68 'ADX3-4'
  ; Item #69 'ADX4-1'
  ; Item #70 'ADX4-2'
  ; Item #71 'ADX4-3'
  ; Item #72 'ADX4-4'
  ; Item #73 'ADMAIF17'
  ; Item #74 'ADMAIF18'
  ; Item #75 'ADMAIF19'
  ; Item #76 'ADMAIF20'
  ; Item #77 'ASRC1-1'
  ; Item #78 'ASRC1-2'
  ; Item #79 'ASRC1-3'
  ; Item #80 'ASRC1-4'
  ; Item #81 'ASRC1-5'
  ; Item #82 'ASRC1-6'
  : values=17
numid=577,iface=MIXER,name='x Master Playback Volume'
  ; type=INTEGER,access=rw---R--,values=2,min=0,max=127,step=0
  : values=64,64
  | dBscale-min=-121.00dB,step=1.00dB,mute=1
Simple mixer control 'I2S1 Mux',0
  Capabilities: enum
  Items: 'None' 'ADMAIF1' 'ADMAIF2' 'ADMAIF3' 'ADMAIF4' 'ADMAIF5' 'ADMAIF6' 'ADMAIF7' 'ADMAIF8' 'ADMAIF9' 'ADMAIF10' 'ADMAIF11' 'ADMAIF12' 'ADMAIF13' 'ADMAIF14' 'ADMAIF15' 'ADMAIF16' 'I2S1' 'I2S2' 'I2S3' 'I2S4' 'I2S5' 'I2S6' 'SFC1' 'SFC2' 'SFC3' 'SFC4' 'MIXER1-1' 'MIXER1-2' 'MIXER1-3' 'MIXER1-4' 'MIXER1-5' 'AMX1' 'AMX2' 'AMX3' 'AMX4' 'ARAD1' 'SPDIF1-1' 'SPDIF1-2' 'AFC1' 'AFC2' 'AFC3' 'AFC4' 'AFC5' 'AFC6' 'OPE1' 'SPKPROT1' 'MVC1' 'MVC2' 'IQC1-1' 'IQC1-2' 'IQC2-1' 'IQC2-2' 'DMIC1' 'DMIC2' 'DMIC3' 'DMIC4' 'ADX1-1' 'ADX1-2' 'ADX1-3' 'ADX1-4' 'ADX2-1' 'ADX2-2' 'ADX2-3' 'ADX2-4' 'ADX3-1' 'ADX3-2' 'ADX3-3' 'ADX3-4' 'ADX4-1' 'ADX4-2' 'ADX4-3' 'ADX4-4' 'ADMAIF17' 'ADMAIF18' 'ADMAIF19' 'ADMAIF20' 'ASRC1-1' 'ASRC1-2' 'ASRC1-3' 'ASRC1-4' 'ASRC1-5' 'ASRC1-6'
  Item0: 'ADMAIF1'
Simple mixer control 'x Output Mixer HiFi',0
  Capabilities: pswitch pswitch-joined
  Playback channels: Mono
  Mono: Playback [on]
numid=572,iface=MIXER,name='I2S1 Channels'
  ; type=INTEGER,access=rw------,values=1,min=0,max=16,step=0
  : values=2
Playing WAVE 'LRMonoPhase4.wav' : Signed 16 bit Little Endian, Rate 48000 Hz, Stereo
aplay: pcm_write:1940: write error: Input/output error

real	0m20.477s
user	0m0.040s
sys	0m0.112s

Note that the error happens after about 20 seconds of attempted playback. dmesg:

[  245.641754] tegra_t186ref_dai_init: audio_clock.set_mclk = 49152000 Hz, aud_mclk = 12288000 Hz, codec rate = 48000 Hz␍␊
[21:10:51:879] [  245.652749] *** wm8731_set_dai_sysclk freq=12288000Hz␍␊
[21:10:51:896] [  245.666796] *** wm8731_startup␍␊
[21:10:51:896] [  245.670020] *** wm8731_hw_params␍␊
[21:10:51:896] [  245.674249] wm8731 6-001a: Set deemphasis 0 (0Hz)␍␊

Does that first line imply that the output of the mclk pin is 12288000Hz? or the 49MHz number? I stepped through the code manually but it’s not very clear the distinction between the similarly-named fields.

my-trace.txt (3.65 MB)

Hi Ryan,

The ‘aud_mclk’ is the output mclk and so yes it should be 12.288MHz (which would make sense for 16-bit stereo @ 48kHz).

Regards,
Jon

OK, great, thanks. Any thoughts on why it might still not be working/giving the write error?

I’ve decoded the regmap traces (from the attach above) for the codec, which appear to show that the DAC and output powerdown are being disabled as expected, so I don’t think it’s codec related.

245.673424:     Register 8h (Sampling Control) {'SR': 0, 'BOSR': False, 'CLKIDIV2': False, 'USB': False, 'CLKODIV2': False}
245.679240:     Register 7h (Digital Audio Interface Format) {'FORMAT': 3, 'IWL': 0, 'MS': False, 'LRP': True, 'BCLKINV': False, 'LRSWAP': False}
245.679513:     Register 5h (Digital Audio Path Control) {'DACMU': False, 'DEEMP': 0, 'HPOR': False, 'ADCHPD': False}
245.679742:     Register 9h (Active Control) {'ACTIVE': True}
245.680031:     Register 6h (Power Down Control) {'OUTPD': True, 'DACPD': False, 'MICPD': False, 'POWEROFF': False, 'CLKOUTPD': True, 'OSCPD': True, 'ADCPD': True, 'LINEINPD': True}
245.680207:     Register 6h (Power Down Control) {'OUTPD': False, 'DACPD': False, 'MICPD': False, 'POWEROFF': False, 'CLKOUTPD': True, 'OSCPD': True, 'ADCPD': True, 'LINEINPD': True}
265.801134:     Register 6h (Power Down Control) {'OUTPD': True, 'DACPD': False, 'MICPD': False, 'POWEROFF': False, 'CLKOUTPD': True, 'OSCPD': True, 'ADCPD': True, 'LINEINPD': True}
265.801468:     Register 6h (Power Down Control) {'OUTPD': True, 'DACPD': True, 'MICPD': False, 'POWEROFF': False, 'CLKOUTPD': True, 'OSCPD': True, 'ADCPD': True, 'LINEINPD': True}
265.801758:     Register 5h (Digital Audio Path Control) {'DACMU': True, 'DEEMP': 0, 'HPOR': False, 'ADCHPD': False}
265.801976:     Register 9h (Active Control) {'ACTIVE': False}

Do you have the ability to probe the I2S bit-clock and frame-sync? If so I would check that the bit clock and frame sync are active as I believe that the codec is the bit clock and frame sync master.

Regards,
Jon

In my most recent changes to the DTS file I put back the two lines that have the effect of making the tegra clock master. I was able to probe a test point on CLKOUT from the codec (after tweaking the codec driver to enable the clock output power) and it looks OK, as does the BCLK pin/pad (it’s a QFN package on the codec…). However, the DACDAT (I2S data input to codec) and the DACLRC (frame sync clock into codec) both just go “high” for the duration of the attempted audio playback then return to low after. (This is with my scope on the same time/div as I used for probing BCLK which should be sufficient to show transitions cleanly.)

Here’s a new register decoding - I enhanced my regmap decoder script to parse out even the little details of the sample rate lookup table. It looks OK to me on the codec end. Not sure what’s happening on the Tegra end to cause the write error.

12222.735704:	Register 6h (Power Down Control) {'POWEROFF': False, 'LINEINPD': True, 'OUTPD': True, 'DACPD': True, 'CLKOUTPD': False, 'OSCPD': True, 'ADCPD': True, 'MICPD': False}
12222.748065:	Register 8h (Sampling Control) {'BOSR': 'BOSR=0: 256fs with MCLK=12.288MHz', 'USB': 'Normal mode (256/384fs)', 'CLKIDIV2': 'Core clock is MCLK', 'CLKODIV2': 'CLOCKOUT is Core Clock', 'SR': 'SR=0000, MCLK 12.288MHz, ADC 48kHz, DAC 48kHz, 256fs, Digital filter type 1'}
12222.753359:	Register 7h (Digital Audio Interface Format) {'MS': 'Enable slave mode', 'LRSWAP': False, 'IWL': '16 bits', 'BCLKINV': False, 'LRP': 'DSP A (MSB is available on 2nd BCLK rising edge after DACLRC rising edge)', 'FORMAT': 'Audio Data Format: DSP Mode, frame sync + 2 data packed words'}
12222.753655:	Register 5h (Digital Audio Path Control) {'ADCHPD': False, 'HPOR': 'Clear DC offset', 'DEEMPH': 'De-emphasis control: Disable', 'DACMU': False}
12222.753879:	Register 9h (Active Control) {'ACTIVE': True}
12222.754215:	Register 6h (Power Down Control) {'POWEROFF': False, 'LINEINPD': True, 'OUTPD': True, 'DACPD': False, 'CLKOUTPD': False, 'OSCPD': True, 'ADCPD': True, 'MICPD': False}
12222.754373:	Register 6h (Power Down Control) {'POWEROFF': False, 'LINEINPD': True, 'OUTPD': False, 'DACPD': False, 'CLKOUTPD': False, 'OSCPD': True, 'ADCPD': True, 'MICPD': False}
12242.859069:	Register 6h (Power Down Control) {'POWEROFF': False, 'LINEINPD': True, 'OUTPD': True, 'DACPD': False, 'CLKOUTPD': False, 'OSCPD': True, 'ADCPD': True, 'MICPD': False}
12242.859370:	Register 6h (Power Down Control) {'POWEROFF': False, 'LINEINPD': True, 'OUTPD': True, 'DACPD': True, 'CLKOUTPD': False, 'OSCPD': True, 'ADCPD': True, 'MICPD': False}
12242.859641:	Register 5h (Digital Audio Path Control) {'ADCHPD': False, 'HPOR': 'Clear DC offset', 'DEEMPH': 'De-emphasis control: Disable', 'DACMU': True}
12242.859853:	Register 9h (Active Control) {'ACTIVE': False}

I’ve attached a trace (which includes DAPM as well as regmap) from my latest run, where I ran my audio test script several times one after another while I was probing around on the board.

mytrace3.txt (12.8 MB)

If the fsync is not toggling then that may still explain why the ‘write error’ is occurring. However, I can see from the following register write that the I2S is being configured as master and so it should be driving the fsync. If you look at the register description for I2S_CTRL_0 in the TRM, the you will see that the fsync width is being configured to 32-bit clocks (which is the default the driver programs if nothing is specified). I see that previously you had commented out the setting for ‘fsync-width’ for the I2S interface. Can you try setting this to ‘1’ seeing as you are using dsp-a mode?

kworker/u12:3-3235 [004] d…2 11860.714297: regmap_reg_write: tegra210-i2s.0 reg=a0 val=1f001603

You can also just take the rel28.2 release as-is (before you make changes to add the codec support) and you should be able to adjust the ‘format’ and ‘fsync-width’ settings in device-tree, and verify that you see the correct bit-clock, fsync, data-out (from Tegra) by playing the file without having the codec connected. It is always a good test to ensure the I2S timings look good for the codec you are using.

Regards,
Jon

A ha! Thank you for the pointer regarding fsync-width - that was the cause of the write failure (that is, it went away when I reconfigured fsync-width to 1, and I now see data). I hadn’t noticed/paid attention to that line before (I assume I just commented it out when I copied it from some other Tegra codec file) and hadn’t realized its importance because I was thinking of that line as “LR clock” rather than fsync.

I now see reasonable-ish looking data on those lines, though I realize now it’s less reasonable than I thought when I first took these measurements.

Attachments:

  • bclk-fsync-1.jpg
  • bclk-fsync-2.jpg
  • bclk-fsync-3.jpg

These have BCLK on top, fsync/lrclk on the bottom, at various time-bases and trigger settings (triggering on bclk for the first two, on fsync for the third I think).

Note picture 2 - it shows that with fsync-width = <1>, the output fsync signal stays high for two full periods of the bclk signal. This contradicts what I expected based on the WM8731 datasheet figure 29: that in “DSP-A” mode I should see LRCLK/FSYNC high for 1 period of BCLK, followed by n bits of left data and n bits of right data, one bit per period of BCLK.

This would explain, however, why I still heard nothing aside from a few pops/clicks from probing, despite seeing what looked at first like reasonable signals on the scope.

  • bclk-data.jpg
  • data.jpg

These pictures show the data line: first triggered by the BCLK signal, and subsequently on the data line on its own. A little hard to see on the first one, but there is a trace for “data” on both high and low, and on the second it’s quite clear that data is toggling high-low at a reliable clocked timing though not in a simple fixed on-off - that is, it looks like data, I think.

I have no particular attachment to DSP-A mode: it seemed like the most flexible and usable mode between the Tegra and the codec. (The codec supports I2S mode, right and left justified mode, as well as DSP-A and DSP-B). We’re only using “simple” 16-bit 44.1k or 48k audio. The codec driver configures itself from whatever I put in the device-tree as the mode (which is why I assumed the same behavior from the Tegra side of the link, presumably), so I can change that at will, if there’s a reason to prefer another mode.

Why is it showing 2 bit clocks of fsync when fsync-width is explicitly 1? Is it adding 1 to the value somewhere?

Would I use 16 for fsync-width if using, e.g., I2S mode? or 17 since the wm8731 figure shows at least n + 1 bit clocks (actually shows 1 + n + 2 - perhaps it only pays attention to the 16 MSB? This behavior was explicitly specified for the DSP mode, which is why I picked it over I2S mode.) for the left channel? Unfortunately “fsync-width” does not seem to be a very common term on the Internet even without quotes: about half of it is about file systems, then there are a few audio codecs and other Tegra forum posts…





Great news! With regard to fsync-width for dsp-a mode you actually want ‘0’ in device-tree and not 1. I forgot that the value programmed into the register is one less than what we want. Hence, the default value you see is ‘31’ but that actually generates ‘32’ bit clocks. So try ‘0’ and you should see 1 bit clock for the fsync. And for normal i2s mode, you would want to program ‘15’.

To be honest, I am not sure why we don’t just let the I2S driver handle the fsync-width as depending ont the mode, data size, bit clock ratio, we know what to program.

Cheers
Jon