ETDM (I2S/TDM)
ETDM (Enhanced Time Division Multiplexer) is an advanced version of the TDM technology, designed to improve data transmission efficiency and flexibility for audio applications. The ETDM interface is notable for its ability to support a larger number of audio channels and higher data rates compared to standard TDM interfaces. The ETDM interface can operate as an I2S interface for transmitting stereo or mono data, and also as a TDM interface capable of handling multiple independent audio channels simultaneously.
This section will provide some common use cases for the ETDM driver, and will introduce the ETDM configurations, such as DAI settings in the machine driver. It will also explain how to make customized modifications in the DTS. Finally, it will also cover the porting of I2S.
Driver Command Usage
The MT8370/MT8390/MT8395 features 6 ETDM interfaces, with two dedicated to capture and the remaining four allocated for playback.
etdm_in1: TDM capture
etdm_in2: I2S capture
etdm_out1: TDM playback
etdm_out2: I2S playback
etdm_out3: HDMI playback
DPTX: DP playback
Capture
Example for I2SIN, use
ETDM_XXX_Clock_Source
control to set the clock source.The default clock source is in low power mode, it saves power but may be jitter at high sample rates. You can set the control to
a1sys_a2sys
to activates the low jitter mode, which means either the 48K clock generated by APLL1 or the 44.1K clock generated by APLL2 will be chosen.amixer -c 0 cset name='ETDM_IN2_Clock_Source' 'a1sys_a2sys'
Here are two examples of ETDM capture, etdm_in1 interface is connected to UL8, and etdm_in2 interface is connected to UL3 in the direct path.
etdm_in1: arecord -Dhw:0,13 -c 2 -r 48000 -f S32_LE -d 10 etdm_rec1.wav etdm_in2: arecord -Dhw:0,9 -c 2 -r 48000 -f S32_LE -d 10 etdm_rec2.wav
Playback
Example for I2S OUT, set clock source from low power mode to low jitter mode.
ETDM out1: amixer -c 0 cset name='ETDM_OUT1_Clock_Source' 'a1sys_a2sys' ETDM out2: amixer -c 0 cset name='ETDM_OUT2_Clock_Source' 'a1sys_a2sys'
Here are two examples of ETDM playback.
ETDM out1: amixer -c 0 cset name='O072 I022 Switch' 1 amixer -c 0 cset name='O073 I023 Switch' 1 aplay test.wav -Dhw:0,6 ETDM out2: amixer -c 0 cset name='O048 I022 Switch' 1 amixer -c 0 cset name='O049 I023 Switch' 1 aplay test.wav -Dhw:0,6
HDMI/DP playback
Set clock source from low power mode to low jitter mode.
amixer -c 0 cset name='ETDM_OUT3_Clock_Source' 'a1sys_a2sys'
Switch to HDMI playback
amixer -c 0 cset name='DPTX_OUT_MUX' 0 amixer -c 0 cset name='HDMI_OUT_MUX' 1
Switch to DP playback
amixer -c 0 cset name='HDMI_OUT_MUX' 0 amixer -c 0 cset name='DPTX_OUT_MUX' 1
Using HDMI playback and DP playback simultaneously
amixer -c 0 cset name='HDMI_OUT_MUX' 1 amixer -c 0 cset name='DPTX_OUT_MUX' 1
Note
MT8370/MT8390/MT8395 only supports 2 channels of playback for this configuration!
Machine Driver Configuration
To specify ETDM DAI configurations in the MT8390/MT8395 machine driver.
Master/Slave mode
In master mode, the ETDM device generates the clock signals needed for the communication. The devices operating in master mode controls the timing of the data transmission, dictating when the slave device should send or receive data.
In slave mode, the ETDM device does not generate its own clock signals. Instead, it relies on an external source, the slave device receives the clock signals and synchronizes its data transmission or reception according to these external clocks.
Parameters
Mode
SND_SOC_DAIFMT_CBC_CFC
Master mode
SND_SOC_DAIFMT_CBS_CFS
Master mode (Deprecated since Linux v5.11)
SND_SOC_DAIFMT_CBP_CFP
Slave mode
SND_SOC_DAIFMT_CBM_CFM
Slave mode (Deprecated since Linux v5.11)
Currently, the new definition has been adopted for MT8365, MT8370 and MT8390, but the old definition is still being used for MT8395.
Format
There are various formats for DAI, and the user can specify the format in the machine driver.
Parameters
DAI format
SND_SOC_DAIFMT_I2S
FORMAT_I2S
SND_SOC_DAIFMT_LEFT_J
FORMAT_LJ
SND_SOC_DAIFMT_RIGHT_J
FORMAT_RJ
SND_SOC_DAIFMT_DSP_A
FORMAT_DSPA
SND_SOC_DAIFMT_DSP_B
FORMAT_DSPB
Clock Inverse
Clock inverse refers to the inversion of the clock signal polarity within a DAI, it means that the rising and falling edges of the clock signal are reversed. The clock signal is crucial for synchronizing the digital audio data stream during transmission. For instance, if one device’s DAI expects to receive data on the falling edge of the clock, while another device by default sends data on the rising edge, the clock inversion feature can ensure that the two devices can synchronize their data transfer correctly.
Parameters
BCK inverse
LRCK inverse
SND_SOC_DAIFMT_NB_NF
False
False
SND_SOC_DAIFMT_NB_IF
False
True
SND_SOC_DAIFMT_IB_NF
True
False
SND_SOC_DAIFMT_IB_IF
True
True
E.g.
Parameters
Value
MCLK rate
128 * sampling rate
Master/Slave mode
master
Format
I2S
Clock inverse
False
Step1: Set the MCLK rate in the
mclk_fs_ratio
property within the machine driver:static int mt8195_etdm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_card *card = rtd->card; struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); unsigned int rate = params_rate(params); unsigned int mclk_fs_ratio = 128; unsigned int mclk_fs = rate * mclk_fs_ratio; int ret; ret = snd_soc_dai_set_sysclk(cpu_dai, 0, mclk_fs, SND_SOC_CLOCK_OUT); if (ret) { dev_err(card->dev, "failed to set sysclk\n"); return ret; } return 0; }Step2: Add ops for ETDM MCLK rate:
static const struct snd_soc_ops mt8195_etdm_ops = { .hw_params = mt8195_etdm_hw_params, };Step3: Update the properties for
.dai_format
and.ops
in the respective dai-link:[DAI_LINK_ETDM1_IN_BE] = { .name = "ETDM1_IN_BE", .no_pcm = 1, .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS, .dpcm_capture = 1, .ops = &mt8195_etdm_ops, .be_hw_params_fixup = mt8195_etdm_hw_params_fixup, SND_SOC_DAILINK_REG(ETDM1_IN_BE), },
DTS Setting
There are four customizable DTS properties for ETDM.
mediatek,X-multi-pin-mode
mediatek,X-mclk-always-on-rate
mediatek,X-cowork-source
mediatek,X-chn-disabled
Here, we use X to represent the specific item names corresponding to different digital audio interfaces in the DTS file.
DTS item name |
Interface |
---|---|
etdm-in1 |
TDMIN |
etdm-in2 |
I2SIN |
etdm-out1 |
I2SO1 |
etdm-out2 |
I2SO2 |
mediatek,X-multi-pin-mode
By default, systems are configured to operate in one-pin mode, where one data pin handles the input from multiple devices. However, if your hardware setup requires multi-pin mode, where each device has a dedicated data pin, then this needs to be specified in the DTS file.
Here’s an example of how you would specify a property in the DTS file to set up in multi-pin mode of I2SIN:
&afe { mediatek,etdm-in2-multi-pin-mode; };
One-pin: Only one pin is responsible for transmitting/receiving data
Multi-pin: Each pin transmits/receives 2-channel data
mediatek,X-mclk-always-on-rate
Specify the MCLK output rate and MCLK will keep active all the time. MCLK rate is divided from APLL rate 196608000 or 180633600.
Note
mclk-always-on-rate
is only supported in MT8395.Here’s an example of how you would specify
mclk-always-on-rate
property in the DTS file of I2SO1:&afe { mediatek,etdm-out1-mclk-always-on-rate = <24576000>; };
In this way, I2SO1_MCLK always outputs 24.576MHz.
mediatek,X-cowork-source
When configuring an ETDM interface, specifying the co-clock source is crucial when you have multiple audio devices sharing the same clock signal. A co-clock source is a common clock shared by different devices to ensure they are synchronized.
Index
Interface
0
etdm-in1 (TDMIN)
1
etdm-in2 (I2SIN)
2
etdm-out1 (I2SO1)
3
etdm-out2 (I2SO2)
Here’s an example of how you would specify the co-clock source property in the DTS file.
For instance, etdm-in1 and etdm-out1 share the same clock. In this case, clock input or output only requires I2SO1 clock pins.
&afe { mediatek,etdm-in1-cowork-source = <2>; //out1 };
mediatek,X-chn-disabled
This property is used to disable ETDM in the channel for the direct path. The direct path refers to the data route connecting to memory interface UL without going through
afe_interconn
.Only
etdm_in1
andetdm_in2
in the direct path supports the feature. When using this DTS property, the user also needs to addbe_hw_params_fixup
in the machine driver.static int mt8390_etdm_in_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) { struct snd_interval *channels = hw_param_interval(params, SNDRV_PCM_HW_PARAM_CHANNELS); channels->min = channels->max = 4; return 0; } [DAI_LINK_ETDM2_IN_BE] = { .name = "ETDM2_IN_BE", ... .be_hw_params_fixup = mt8390_etdm_in_hw_params_fixup, },
Here’s an example of how you would specify the channel disabled property in the DTS file.
For example, if you are recording data from four channels (0~3) sourced from I2SIN, you may only be interested in retrieving the data from channel 1.
&afe { mediatek,etdm-in2-chn-disabled = /bits/ 8 <0x0 0x2 0x3>; };
By following this method, you can obtain stereo data where both channels are sourced from the channel 1 source.
I2S Porting
This section focuses on porting the I2S feature, starting from the hardware aspect, to the configuration in the DTS, and finally explaining how to connect the data path and set up the clock source. The following is an explanation using the Genio 1200-EVK as an example.
Please ensure that pins have been allocated for I2S use on your hardware
On the Genio 1200-EVK, for instance, there are no I2S pins allocated, so even if the software part is configured correctly, external devices cannot be connected for use. Therefore it can only be used for internal loopback testing.
Configure the I2S pins that will be used in the DTS file
In the DTS file, add all the I2S pins that will be used, and please make sure that these pins are not being used by other functions. Sometimes, to save on hardware, a single pin may have multiple functions, which can be switched depending on user requirements. For example, on Genio 1200-EVK, GPIO47 and GPIO48 are by default used for the DSI panel.
Here is an example of how to add I2S pins configuration in the DTS file:
aud_pins_default: audiodefault { pins-cmd-dat { pinmux = ... <PINMUX_GPIO46__FUNC_I2SIN_MCK>, <PINMUX_GPIO47__FUNC_I2SIN_BCK>, <PINMUX_GPIO48__FUNC_I2SIN_WS>, <PINMUX_GPIO49__FUNC_I2SIN_D0>, <PINMUX_GPIO57__FUNC_I2SO2_MCK>, <PINMUX_GPIO58__FUNC_I2SO2_BCK>, <PINMUX_GPIO59__FUNC_I2SO2_WS>, <PINMUX_GPIO60__FUNC_I2SO2_D0>, ... }; };
Confirm that the I2S audio data path is connected
By default, the platform has configured the audio data transmission paths within the AFE for each audio device. It is important to ensure that the switches on the path are turned on before use.
amixer -c mt8390evk cset name='O036 I012 Switch' on amixer -c mt8390evk cset name='O037 I013 Switch' on amixer -c mt8390evk cset name='O048 I022 Switch' on amixer -c mt8390evk cset name='O049 I023 Switch' on
Configure the clock source for the eTDM interface, where
a1sys
anda2sys
respectively represent the clock sources generated fromAPLL1
andAPLL2
for 48K and 44.1K.amixer -c mt8390evk cset name='ETDM_IN2_Clock_Source' a1sys_a2sys amixer -c mt8390evk cset name='ETDM_OUT2_Clock_Source' a1sys_a2sys
The above is just an example, and the actual situation still needs to refer to the hardware schematic, application processor functional specification, GPIO list, and other relevant documentation.
If you want to integrate an external audio codec into the platform, please refer to here.