NVIDIA Tegra
NVIDIA Tegra Linux Driver Package

Development Guide
28.3 Release


 
Tegra ASoC Driver for Jetson TX1 and TX2
 
ALSA
DAPM
Device Tree
Audio Driver
Tegra Audio Hub
Software Architecture
Tegra Platform Driver
ADMAIF
Tegra Codec Driver
XBAR
AMX
ADX
I2S
Mixer
SFC
ASRC
SPDIF
DMIC
MVC
OPE
DSPK
Tegra Machine Driver
Dynamic Audio Routing
Codec Driver Instantiation Using Device Tree
Clocking and Power Management
Audio Playback/Record Examples
Troubleshooting
Examples
ADMAIF
I2S
DMIC
The NVIDIA® Tegra® ASoC driver is implemented for the Android and Linux operating systems and is intended to work seamlessly with different Tegra devices, using an existing framework called Advanced Linux Sound Architecture (ALSA), which is maintained by the upstream Linux community.
The hardware functionality present on Jetson TX1 and Jetson TX2. Hardware functionality may not be supported by the software. Review your software documentation to determine availability of software for audio features.
On Jetson TX1 and TX2, audio output is supported using HDMI audio. Hardware for audio capture is NOT included in the development kit; however audio capture can be supported using the interfaces such as USB, I2S, or DMIC.
ALSA
The ALSA framework is a part of the Linux kernel that is supported and maintained by the larger Linux community. This makes it feasible to adapt to the framework, designing a driver that leverages NVIDIA audio routing support. ALSA includes a collection of sound card drivers, including actual codec drivers for platform ADC and DAC support, and can support adding new codec drivers.
ALSA also includes libraries and utilities that enable more refined audio control in Linux and Android user space. These libraries control audio applications without having to interact with kernel space drivers. These libraries include ALSA:
amixer
aplay
arecord
The ALSA software hierarchy is as follows.
User space ALSA applications interact with ALSA core (kernel space) through APIs provided by userspace libraries that initialize the actual hardware codecs at the backend of the audio pipeline.
More information on the ALSA framework is available at:
http://www.alsa-project.org/main/index.php/Main_Page
https://wiki.archlinux.org/index.php/Advanced_Linux_Sound_Architecture
DAPM
ALSA is designed to support various functionalities including, but not limited to, dynamic audio routing to the available PCM devices. The component of ALSA core that provides this support is Dynamic Audio Power Management (DAPM). DAPM controls the power flow into and out of various codec blocks in the audio subsystem, thereby minimizing power consumption. DAPM introduces switches or kernel controls in the form of widgets to turn ON/OFF the power of a module and help manipulate the required bit of the specific register dynamically using user space applications such as aplay, arecord, or alsamixer. The widgets are classified into various groups.
More information on the widgets and their applications is available at:
http://www.alsa-project.org/main/index.php/DAPM
https://www.kernel.org/doc/Documentation/sound/alsa/soc/DPCM.txt
In terms of software hierarchy, DAPM is part of the ALSA core that manages the codec module power efficiency. Consult theTegra ASoC Driver Overview diagram for details.
For more information consult:
Clocking and Power Management
Dynamic Audio Routing
Device Tree
The Device Tree is a data structure that describes devices on the platform. It is passed to the operating system at boot time to avoid hard coding component details in the operating system. In this way it makes it easier to change hardware configurations without rebuilding the kernel.
The data structure contains the name of nodes and properties. Each node can have properties or child nodes, and each property is comprised of a name and more than one value. Device Tree structures must be written in the correct format and according to format rules so that the data structure can be parsed by the operating system.
Usage details of DTS and its script format is available at:
http://www.devicetree.org/Device_Tree_Usage
A simple device tree example is available at Codec Driver Instantiation Using Device Tree.
Audio Driver
The Tegra Audio Driver leverages Tegra Audio Hub (AHUB) hardware acceleration in the form of platform and codec drivers. The ARM peripheral bus interface (ADMAIF) is implemented as a platform driver with PCM interfaces for playback/record and the rest of the AHUB modules such as the Audio Cross Bar (XBAR), Audio Multiplexer (AMX), Audio Demultiplexer (ADX) and Inter-IC sound (I2S) implemented as codec drivers. Each of the drivers is connected to XBAR through Digital Audio Interfaces (DAIs), inside a machine driver, forming an audio hub.
The machine driver probe instantiates the sound card device and registers all the PCM interfaces as exposed by ADMAIF. After booting, before using these interfaces to playback or record audio, the audio paths inside XBAR must be setup. By default, XBAR has no routing connections at boot, and no DAPM path is complete to power on the corresponding widgets. The XBAR driver introduces MUX widgets for all the audio components and enables creation of custom routing through kcontrol from user space using the ALSA amixer utility. If the audio path is not complete, the DAPM path is not closed. Hardware settings are not applied and audio output may not be heard.
For more details on how to setup the route and how to play or record on the PCM interfaces, see the Audio Playback/Record Examples.
Tegra Audio Hub
This topic provides an overview of:
The audio hub hardware architecture inside the the Tegra SoC.
The software architecture of the driver.
Tegra Audio Hub Architecture
 
The audio hub contains the modules I2S, SPDIF, and the Digital MIC Controller (DMIC) that interface with the external world. The audio hub also contains:
Mixer
Sampling Frequency Converter (SFC)
Master Volume Control (MVC)
Output Processing Engine (OPE)
Audio Multiplexers (AMX)
Audio Demultiplexers (ADX)
Audio Flow Controllers (AFC)
An Audio Direct Memory Access (ADMA) component is included (ADMAIF-DMA) to communicate with memory.
The Crossbar (XBAR) facilitates the routing of audio samples through these modules using a proprietary protocol called Audio Client Interface (ACIF).
Module
Jetson TX1 Instances
(T210)
Jetson TX2 Instances
(T186)
I2S
5x
6x
DMIC Controller
3x
4x
SPDIF
1x
1x
IQC
2x
2x
Mixer
10 inputs, 5 outputs
10 inputs, 5 outputs
AMX
2x
4x
ADX
2x
4x
SFC
4x
4x
AFC
6x
6x
OPE
2x
1x
SPKPROT
1x
1x
MVC
2x
2x
ADMA
22 channels
32 channels
ADMA I/F
10 Tx channels, 10 Rx channels
20 Tx channels, 20 Rx channels
ASRC
None
1x
ARAD
None
1x
DSPK
None
2x
The modules in the audio hub support various kinds of audio devices that are expected to interface with the application processor, such as:
Cellular baseband devices
Different types of audio CODECs
Bluetooth modules
A/V receivers
The audio hub is capable of supporting the different interface and signal quality requirements of these devices.
Each of the AHUB modules has at least one RX port and one TX port, and some have more than one, depending on whether they are for duplex flow such as I2S.
The RX ports feed off from XBAR and the TX ports are fed back into XBAR, except in the case of I2S where one end feeds of the actual codec. This configuration makes XBAR a switch where an audio input can be fed to multiple outputs depending on use case.
Each ADMAIF has TX and RX FIFOs that support simultaneous recording and playback. ADMA transfers the data to the ADMAIF FIFO for all audio routing scenarios.
For dynamic audio routing examples consult Audio Playback/Record Examples.
For details on hardware configuration details of each module, consult the Tegra Reference Manual.
Software Architecture
The software architecture of the Tegra ASoC driver is similar to the hardware architecture of the AHUB. It leverages the features supported by the hardware and conforms to the ALSA framework. This ALSA System on a Chip (ASoC) driver is comprised of platform, codec and machine drivers.
Platform driver: responsible for PCM registration and interfaces with the PCM driver. The ADMAIF is the platform driver.
Codec driver: any driver that registers snd_soc_codec_driver structure with the ASoC core can be viewed as the codec driver.
The module must have at least one input and one output.
The structure provides a way to define your own DAPM widgets for power management and kcontrols for register setting from user space.
All other modules except ADMAIF are implemented as codec drivers.
Machine driver: connects one or more codec drivers and a PCM driver together for a given platform.
For details on writing a machine driver and identifying a sound card, consult:Tegra Machine Driver.
For details on the kernel documentation for AsoC framework consult:
https://www.kernel.org/doc/Documentation/sound/alsa/soc/
Tegra Platform Driver
The Tegra platform driver realizes the number of ports of playback and capture possible inside the AHUB. Connect some or all of these ports to form a full audio routing path.
For more information on these paths consult Audio Playback/Record Examples.
ADMAIF
In the Tegra ASoC driver, ADMAIF is implemented as a platform driver and interfaces with the PCM driver. The PCM driver helps perform DMA operations by overriding the function pointers exposed by the snd_pcm_ops structure. The PCM driver is platform agnostic and interacts with the SOC DMA engine upstream APIs. The DMA engine then interacts with the platform specific DMA driver to get the correct DMA settings. The ADMAIF platform driver defines DAIs and registers the same with ASoC core.
In Jetson TX2, there are 20 ADMAIFs. Each ADMAIF is bi-directional, facilitating 20 streams of playback and 20 streams of capture.
card 1: tegrasndt186ref [tegra-snd-t186ref-mobile-rt565x]
Playback Hardware Devices in the Tegra alt ASoC Driver
/dev/snd/pcmC1D[0…..19]p
ADMA I/F1 is mapped to pcmC1D0p
ADMA I/F20 is mapped to pcmC1D19p
Capture Hardware Devices in the Tegra AsoC Driver
/dev/snd/pcmC1D[0…..19]c
ADMA I/F1 is mapped to pcmC1D0c
ADMA I/F20 is mapped to pcmC1D19c
Tegra Codec Driver
An overview of codec drivers is presented in the Tegra Audio Hub. In the Tegra ASoC driver implementation, the rest of the AHUB modules, except ADMAIF, are implemented as codec drivers. Their responsibilities include:
Interface to other modules by defining DAIs.
Define DAPM widgets and establish DAPM routes for dynamic power switching.
Expose additional kcontrols (kernel controls) as needed for user space utilities to dynamically control module behavior.
XBAR
The XBAR codec driver defines RX, TX and MUX widgets for all the interfacing modules such as ADMAIF, AMX, ADX, I2S, SPDIF, DMIC, Mixer, SFC, MVC, OPE and AFC. MUX widgets are permanently routed to the corresponding TX widgets inside the snd_soc_dapm_route structure.
However, the XBAR interconnections are made by connecting any RX widget block to any MUX widget block as needed using the ALSA amixer utility. The get/put handlers for these widgets are implemented so that audio connections are stored by setting the appropriate bit in the hardware MUX register.
For more information consult:
Audio Playback/Record Examples
Dynamic Audio Routing
AMX
An Audio Multiplexer (AMX) module can multiplex up to 4 streams of 16 channels, 32 bits each, into one time-division multiplexed (TDM) stream of 16 channels and 32 bits. The 4 RX ports of AMX originate from XBAR and 1 TX port feeds into XBAR. The DAPM widgets exposed are as follows. The DAPM routes established using these widgets are shown as dotted lines.
AMX Codec Driver Internals
ADX
An Audio Demultiplexer (ADX) module can de-multiplex a single TDM stream of 16 channels and 32 bits into 4 streams of up to 16 channels, 32 bits each. The 1 RX port of ADX originates from XBAR and 4 TX ports feeds into XBAR. The DAPM widgets exposed are as follows. The DAPM routes established using these widgets are shown as dotted lines.
ADX Codec Driver Internals
I2S
An I2S module supports 6 different modes, the most useful of which are I2S and TDM. When I2S is configured in TDM mode, use AMX and ADX for multiplexing and demultiplexing audio streams. I2S module can be in I2S mode if the physical codec interfaced does not support TDM mode of operation. An I2S codec driver supports bidirectional data flow and thereby defines CIF and DAP RX/TX widgets as follows. The CIF side of I2S, interfaces with XBAR and DAP side interfaces with the physical codec on the given platform. The DAPM routes established using these widgets are shown as dotted lines. I2S modules also expose kernel control to enable internal I2S loopback.
I2S Codec Driver Internals
Mixer
The Mixer mixes audio streams from any of the 10 XBAR-originating input ports to any of the 5 output ports. The DAPM widgets and routes for Mixer are as follows. The Mixer driver also exposes Rx Gain and Mixer Enable as additional kcontrols to set the volume of each input stream and to globally enable or disable the Mixer itself.
Mixer Codec Driver Internals
SFC
The Sampling Frequency Converter(SFC) converts the input sampling frequency to the required sampling rate. SFC has one input port and one output port which are connected to XBAR.
DAPM widgets and routes for SFC
ASRC
The Arbitrary Sample Rate Converter (ASRC) is a High Quality (HQ) sampling frequency converter. It can handle a wide range of sampling-rate ratios from 1:24 to 24:1, with input and output sample rates in the range of 8 KHz to 192 KHz. Additionally, it supports up to 6 streams of up to 12 total channels.
The ASRC has 6 input ports and 6 output ports that are connected to XBAR. The DAPM widgets and routes for ASRC are as follows.
ASRC Codec Driver Internals
SPDIF
The SPDIF driver is similar to I2S in terms of the DAPM widgets that are exposed and the routing setup. SPDIF is bidirectional and adapts to the sampling rate of the incoming data. The SPDIF is implemented as follows.
SPDIF Driver Internals
DMIC
To avoid the need for a PDM-capable external codec, use pulse-density modulation (PDM) to interface directly to digital microphones and speakers. The DMIC controller implements a converter to convert PDM signals to PCM (Pulse code modulation) signals. The DAPM widgets and routes are as follows.
DMIC Driver Internals
MVC
MVC provides gain or attenuation to a digital signal path. The digital volume control block is a generic block. It can be used for:
Input or output digital signal path
Per-stream volume control and master volume control
The DAPM widgets and routes are as follows.
MVC Driver Internals
OPE
The Output Processing Engine (OPE) is a client of AHUB. OPE contains PEQ and MBDRC which have a scalable number of BiQuad stages, support stereo, 5p1 and 7p1 channels, and meet ultra-low power(ULP) audio requirements.
The DAPM widgets and routes for OPE
DSPK
The Digital Speaker (DSPK) is a PDM transmit block that converts multi-bit PCM audio input to over-sampled 1-bit PDM output.
DSPK Codec Driver Internals
Tegra Machine Driver
The Tegra machine driver connects the codec drivers by linking the DAIs exposed by each module. It defines the snd_soc_dai_link structure and instantiates the sound card.
Machine driver responsibilities include:
Populate the snd_soc_dai_link structure with appropriate CPU and CODEC DAIs
Physical codec clock setting (if any) and codec initializations
Master/slave configurations (if any)
Define DAPM widgets to route through the physical codec internals and complete DAPM path as needed
Propagate the runtime sampling frequency to the individual codec drivers as needed
To adapt the generic machine driver template to a given platform, you must:
Initialize the platform data structure in the device tree structure file.
Gather information about the hardware platform.
Identify the physical codecs present on board and the I2S instance they interface with in the hardware.
Consult the hardware schematics for the platform.
sound_ref {
compatible = " ";
nvidia,model = " ";
nvidia,num-codec-link = < >;
 
nvidia,audio-routing = ;
nvidia,xbar = <&tegra_axbar>;
 
nvidia,dai-link-1 {
link-name = " ";
cpu-dai = < >;
codec-dai = < >;
cpu-dai-name = " ";
codec-dai-name = " ";
format = " ";
bitclock-slave;
frame-slave;
bitclock-noninversion;
frame-noninversion;
bit-format = " ";
bclk_ratio = < >;
srate = < >;
num-channel = < >;
name-prefix = " ";
};
};
The sound node is added to the DT file for sound card registration and passing platform related data. To bind a device driver to a specific device in a DT file, each node must define a compatible property, which is a list of strings. The optional nvidia,model property is used for the sound card name. The nvidia,num-codec-link property shows the number of DAI links exposed outside of the Tegra devices such as I2S, SPDIF or DMIC. This is the same as the number of nvidia,dai-link-<number> child nodes.
The nvidia,dai-link-<number> node is initialized based on I2S and physical codec links. You can replace the codec with a dummy spdif-dit.0 codec. In that case, you must program the physical codecs at the required sampling rate and operational modes either through a separate utility or by adding necessary hw_params API calls inside the machine driver. The link-name property represents each DAI link, and differentiates the codecs connected to the different I2S instances.
Slave, frame-slave, format, bitclock-noninverstion and frame-noninversion properties set I2S in I2S/TDM formats and/or master/slave modes. The bclk-ratio property is available to configure the I2S bit clock sample rate. The srate and num-channel properties indicate I2S LRCK and the number of channels in one frame. DAPM routes are initialized as established in nvidia,audio-routing property.
To populate the snd_soc_dai_link structure in the machine driver
1. Initialize all XBAR related DAI links common to any machine driver. Use the APIs in the utility file tegra_asoc_machine_alt.h in the machine driver probe function as shown in the following example:
/* get the xbar dai link structure */
tegra_machine_dai_links=
tegra_machine_get_dai_link();
 
/* set sfc dai_init */
tegra_machine_set_dai_init(TEGRA210_DAI_LINK_SFC1_RX,
&tegra_t210ref_sfc1_init);
tegra_machine_set_dai_init(TEGRA210_DAI_LINK_SFC2_RX,
&tegra_t210ref_sfc2_init);
tegra_machine_set_dai_init(TEGRA210_DAI_LINK_SFC3_RX,
&tegra_t210ref_sfc3_init);
tegra_machine_set_dai_init(TEGRA210_DAI_LINK_SFC4_RX,
&tegra_t210ref_sfc4_init);
2. The generic machine driver handles DAI link management based on the initialized platform specific data in the DT file. This step is platform/machine dependent.
The Jetson TX1 and TX2 machine drivers are available in the kernel sources archive at:
kernel/kernel-4.4/sound/soc/tegra-alt/tegra_t210ref_mobile_rt565x_alt.c
kernel/t18x/sound/soc/tegra-alt/tegra_t186ref_mobile_rt565x_alt.c
The Jetson TX1 and TX2 reference device tree “sound” nodes are available in the kernel source archive at:
hardware/nvidia/platform/t210/jetson/kernel-dts/tegra210-jetson-cv-base-p2957-2180-a00.dts
hardware/nvidia/platform/t18x/common/kernel-dts/t18x-common-platforms/tegra186-quill-common.dtsi
Dynamic Audio Routing
Instantiation of the sound card after boot indicates that all codec drivers and the platform driver are interconnected using the machine driver. The remaining step before obtaining the audio output on the physical codecs involves routing through the XBAR internals using MUX widgets to complete the DAPM path using the alsamixer utility. To support audio routing dynamically between AHUB modules, this route setting step is performed from user space. This provides flexibility for complicated use cases.
For example, [amixer -c 0 cset name=‘I2S1 Mux’ ‘I2S1’] realizes the internal AHUB path I2S1 RX -> XBAR -> I2S1 TX.
Codec Driver Instantiation Using Device Tree
Based on architecture, the Makefile in the following directory conditionally compiles the required DTS files into DTB files:
$KERNEL_TOP/arch/arm64/boot/dts/
When the kernel is flashed, the flash script chooses the required DTS file for parsing during boot, and the ASoC codecs listed in DTS are instantiated. To add any new module instantiation as a requirement, identify and edit the Device Tree script as reported in the dmesg log on the target as shown in the following example:
[ 0.030809] Tegra Speedo/IDDQ fuse revision 4
[ 0.030832] Tegra: CPU Speedo ID 7, SoC Speedo ID 0, GPU Speedo ID 2
[ 0.030855] Tegra: CPU Process ID 0, SoC Process ID 1, GPU Process ID 0
[ 0.030879] Tegra: CPU Speedo Value 2044, SoC Speedo Value 1965, GPU Speedo Value 2079
[ 0.030911] Tegra: CPU IDDQ Value 2636, SoC IDDQ Value 2912, GPU IDDQ Value 3610
[ 0.030956] Tegra Revision: A02 SKU: 0x17 CPU Process: 0 SoC Process: 1
[ 0.032780] DTS File Name: /home/jonathanh/workdir/tegra/l4t-rel28/kernel/kernel-4.4/arch/arm64/boot/dts/../../../../../../hardware/nvidia/platform/t210/jetson/kernel-dts/tegra210-jetson-tx1-p2597-2180-a01-devkit.dts
[ 0.032834] DTB Build time: Dec 11 2017 15:26:52
To add new devices for instantiation
Add the device name with the base address and status as okay.
ahub {
status = "okay";
i2s@702d1000 {
pinctrl-names = "dap_active", "dap_inactive";
pinctrl-0 = <>;
pinctrl-1 = <>;
status = "okay";
};
};
Clocking and Power Management
The clock tree of the Tegra ASoC driver in the idle state, when no audio record or playback is in progress, is as follows.
clock state ref div rate
--------------------------------------------------------------
i2s4_sync on 1 24000000
i2s3_sync on 1 24000000
*audio3 off 0 24000000
i2s2_sync on 1 24000000
i2s1_sync on 1 24000000
*audio1 off 0 24000000
i2s0_sync on 1 24000000
spdif_in_sync on 1 24000000
*audio2_dmic off 0 24000000
*audio1_dmic off 0 24000000
*audio0_dmic off 0 24000000
*audio off 0 24000000
*audio_2x off 0 x2 48000000
*audio4 off 0 24000000
*audio2 off 0 24000000
*audio0 off 0 24000000
osc on 3 38400000
pll_ref on 7 1.0 38400000
pll_a on 1 x9.5 368639844
pll_a_out0 on 1 15.0 24575990
extern1 on 3 1.0 24575990
clk_out_1 on 2 1.0 24575990
d_audio off 0 2.0 12287995
*dmic3 off 0 11.0 2234181
*dmic2 off 0 11.0 2234181
*dmic1 off 0 11.0 2234181
spdif_out off 0 21.0 1170286
i2s4 off 0 5.5 4468362
i2s3 off 0 5.50 4468362
i2s1 off 0 5.50 4468362
i2s0 off 0 10.50 2340571
pll_p on 15 x10.6 408000000
*spdif_in off 0 8.50 48000000
ape off 0 2.0 204000000
xbar.ape off 0 204000000
adsp.ape off 0 204000000
adma.ape off 0 204000000
The clocks of the individual modules, AMX, ADX, AFC, SFC, MIXER, and others, are internally handled by the APE clock. The clock for the codec drivers I2S and XBAR are switched OFF in idle. They are turned ON when audio playback or recording is in progress. The idle_bias_off option provided by ASoC core (snd_soc_codec_driver) is set to 1 in the individual codec drivers for dynamic audio power management. With this option, the ASoC core calls the appropriate resume() and suspend() functions in the codec driver that was registered using SET_RUNTIME_PM_OPS during platform probe.
The suspend and resume APIs are called when playback or record stops or starts. The suspend API caches the register map and disables the clock. The resume API enables the clock and then syncs the register map from the cache.
Note:
Volatile registers are not synced in this process. Those registers must be reprogrammed after the clock is re-enabled. The internal mapping RAM FIFOs, if any, are cleared during every suspend/resume cycle. The RAM configuration must be restored as well during this process.
Audio Playback/Record Examples
To test audio playback and record scenarios, make sure the XBAR route is set up using alsamixer commands, based on the platform. The sample testing command for audio playback and record scenario is as follows.
Command
Result
aplay -D hw:tegrahda,3 sample.wav
Audio playback using HDMI/DP
Troubleshooting
Issue 1: No Sound Cards Found
Identify the ASoC error that lead to no sound card detection with the dmesg [dmesg | grep ASoC] command. Output is as follows:
[4.874720] tegra-audio-t210ref tegra-audio-t210ref.0: ASoC: no source widget found for x OUT
[4.874724] tegra-audio-t210ref tegra-audio-t210ref.0: ASoC: Failed to add route x OUT-> direct-> Headphone-x
[4.874736] tegra-audio-t210ref tegra-audio-t210ref.0: ASoC: no sink widget found for x IN
[4.874739] tegra-audio-t210ref tegra-audio-t210ref.0: ASoC: Failed to add route LineIn-x-> direct-> x IN
In this case, x OUT and x IN are the widgets of the spdif-dit dummy codec. It may not have been instantiated in ASoC. Confirm that with this command, if spdif-dit is instantiated:
cat /sys/kernel/debug/asoc/codecs
The spdif device must be instantiated using platform_register in the board-specific file.
If output from the dmesg [dmesg | grep ASoC] command is as follows:
[4.874720] tegra-audio-t210ref tegra-audio-t210ref.0: ASoC: CPU DAI DAP not registered
In this case, “DAP” is the CPU DAI for the I2S to codec dai link. The I2S codec may not be instantiated in ASoC. Confirm with this command, if tegra210-i2s is instantiated:
cat /sys/kernel/debug/asoc/codecs
Identification of the DAI link at the point of failure would give a clue on the I2S instance number that failed to instantiate. Accordingly, the I2S codec driver can be instantiated by providing a suitable entry point in DTS file as described in Codec Driver Instantiation Using Device Tree.
Issue 2: Sound Not Audible
1. Confirm if the DAPM path is completed. Check the path using ALSA amixer utility as described in Examples.
2. Confirm the settings for the audio interface pins. The pins for the audio interface must be configured as special function IOs (SFIOs) and not GPIOs. Then the pinmux settings for the SFIO must select the desired audio function.
For example, to configure the I2S, DMIC and AUD_MCLK that are mapped to header J21 on the Jetson TX1 as SFIO, the following change must be made:
diff --git a/kernel-dts/tegra210-jetson-cv-base-p2597-2180-a00.dts b/kernel-dts/tegra210-jetson-cv-base-p2597-2180-a00.dts
index d1046a3e3d22..10729ec8a48f 100644
--- a/kernel-dts/tegra210-jetson-cv-base-p2597-2180-a00.dts
+++ b/kernel-dts/tegra210-jetson-cv-base-p2597-2180-a00.dts
@@ -77,6 +77,27 @@
};
};
+ gpio@6000d000 {
+ p2597-j21-audio {
+ gpio-hog;
+ function;
+ gpios = <
+ TEGRA_GPIO(B, 0) 0
+ TEGRA_GPIO(B, 1) 0
+ TEGRA_GPIO(B, 2) 0
+ TEGRA_GPIO(B, 3) 0
+ TEGRA_GPIO(BB, 0) 0
+ TEGRA_GPIO(E, 4) 0
+ TEGRA_GPIO(E, 5) 0
+ >;
+ label = "I2S0_LRCLK", "I2S0_SDIN",
+ "I2S0_SDOUT", "I2S0_CLK",
+ "AUDIO_MCLK", "DMIC3_CLK",
+ "DMIC3_DAT";
+ status = "okay";
+ };
+ };
+
pinmux@700008d4 {
/* Dynamic pinmux config for DMIC3 */
dmic3_dap_active_state: dmic3_dap_active {
To verify the default SFIO pinmux configuration, check the pinmux node in the appropriate device-tree source file for the board. For example, for Jetson TX1, check the pinmux node in the device-tree file to verify how the audio interface pins are configured:
hardware/nvidia/platform/t210/jetson/kernel-dts/tegra210-jetson-cv-pinmux-p2957-2180-a00.dts
3. Confirm the status property of the audio interface is set to okay in the the appropriate device-tree source file.
For example, for Jetson TX2, the device tree file is at:
hardware/nvidia/soc/t210/kernel-dts/tegra210-soc/tegra210-audio.dtsi
4. Probe the audio signals with an oscilloscope.
For example, if using I2S, probe the frame sync (FS) and bit clock (BCLK) to verify that the timings are correct.
Examples
In these examples:
Jetson TX1 <soundcard-name> is tegrasndt210ref
Jetson-TX2 <soundcard-name> is tegrasndt186ref
ADMAIF
To use ADMAIF1 internal loopback
# amixer -c <soundcard-name> cset name=“ADMAIF1 Mux” ADMAIF1
# aplay -D hw:<soundcard-name>,0 <inputfile.wav>
# arecord -D hw:<soundcard-name>,0 -r <rate> -c <no.of channels> -b <bits per sample> <outputfile.wav>
To use ADMAIF2 for playback and ADMAIF1 for playback
# amixer -c <soundcard-name> cset name=“ADMAIF1 Mux” ADMAIF2
# aplay -D hw:<soundcard-name>,1 <inputfile.wav>
# arecord -D hw:<soundcard-name>,0 -r <rate> -c <no.of channels> -b <bits per sample> <outputfile.wav>
I2S
To playback I2S with ADMA I/F 3
# amixer -c <soundcard-name> cset name=“I2S2 Mux” ADMAIF3
# aplay -D hw:<soundcard-name>,2 <inputfile.wav>
To use I2S2 with ADMA I/F 3 for capture
# amixer -c <soundcard-name> cset name=“ADMAIF3 Mux” I2S2
# arecord -D hw:<soundcard-name>,2 -r <rate> -c <no.of channels> -b <bits per sample> <outputfile.wav>
To perform a loopback test with I2S2 using ADMA I/F3
# amixer -c <soundcard-name> cset name="I2S2 Mux" "ADMAIF3"
# amixer -c <soundcard-name> cset name="ADMAIF3 Mux" "I2S2"
# amixer -c <soundcard-name> cset name="I2S2 Loopback" "on"
# aplay -D hw:<soundcard-name>,2 <inputfile.wav>
# arecord -D hw:<soundcard-name>,2 -r <rate> -c <no.of channels> -b <bits per sample> <outputfile.wav>
To playback mono stream playback over I2S,both speakers, with an RT5658 codec
# amixer -c <soundcard-name> cset name="I2S1 Mux" "ADMAIF8"
# amixer -c <soundcard-name> cset name="ADMAIF8 TX mono to stereo conv" COPY
# amixer -c <soundcard-name> cset name="I2S1 Channels" "2"
 
# amixer -c <soundcard-name> cset name="x Headphone Playback Volume" "0x1e"
# amixer -c <soundcard-name> cset name="x Stereo DAC MIXR DAC R1 Switch" "1"
# amixer -c <soundcard-name> cset name="x Stereo DAC MIXL DAC L1 Switch" "1"
# amixer -c <soundcard-name> cset name="x Int Spk Switch" "0"
# amixer -c <soundcard-name> cset name="x HPO R Playback Switch" "1"
# amixer -c <soundcard-name> cset name="x HPO L Playback Switch" "1"
# amixer -c <soundcard-name> cset name="x Headphone Jack Switch" "1"
 
# aplay -D hw:<soundcard-name>,7 <inputfile.wav>
DMIC
To perform a 48 kHz stereo capture from DMIC3 using ADMIF9
# amixer -c <soundcard-name> cset name="ADMAIF9 Mux" DMIC3
# amixer -c <soundcard-name> cset name="DMIC3 Boost Gain" 400
# arecord -D hw:<soundcard-name>,8 -r 48000 -c 2 -b 16 <outputfile.wav>
To perform 48 kHz mono capture from DMIC3 using ADMIF9, left MIC
# amixer -c <soundcard-name> cset name="ADMAIF9 Mux" DMIC3
# amixer -c <soundcard-name> cset name="DMIC3 Boost Gain" 400
# amixer -c <soundcard-name> cset name="DMIC3 Mono Channel Select" L
# arecord -D hw:<soundcard-name>,8 -r 48000 -c 1 -b 16 <outputfile.wav>
To perform a mono capture from DMIC3 using ADMIF9, right MIC
# amixer -c <soundcard-name> cset name="ADMAIF9 Mux" DMIC3
# amixer -c <soundcard-name> cset name="DMIC3 Boost Gain" 400
# amixer -c <soundcard-name> cset name="DMIC3 Mono Channel Select" R
# arecord -D hw:<soundcard-name>,8 -r 48000 -c 1 -b 16 <outputfile.wav>