i2S 傳輸模式分為 I2S 標(biāo)準(zhǔn)模式, I2S 左對(duì)齊模式, I2S 右對(duì)齊模式,還有 TDM 模式, PCM 模式 。
I2S 標(biāo)準(zhǔn)模式 :

LRCK:幀同步時(shí)鐘,其頻率就是音頻采樣率,圖中是一個(gè)周期的 LRCK,也就是采樣率的倒數(shù)。在時(shí)鐘的低電平傳輸左聲道,在時(shí)鐘的高電平傳輸右聲道。
BCLK:位同步時(shí)鐘。 BCLK_rate = sample_rate * slot * slot_width
- sample_rate 是音頻采樣率,
- slot 通道數(shù)(I2S 標(biāo)準(zhǔn)格式下,只能是 1 或 2),
- slot_width 是傳輸單通道數(shù)據(jù)內(nèi)最大的比特位。通常是 8/16/24/32bit 可選。
MCLK: CPU 輸出頻率給外部 codec 工作時(shí)鐘,跟 I2S 模式無關(guān)
I2S 左對(duì)齊協(xié)議 :

I2S 左對(duì)齊模式:與 I2S 標(biāo)準(zhǔn)的差異,在 LRCK 發(fā)生翻轉(zhuǎn)時(shí)就開始傳輸數(shù)據(jù)。
LRCK 為高電平時(shí),表示第一個(gè)聲道,低電平為第二個(gè)聲道。 BCLK 電平在 LRCK 發(fā)生電平變化后從低電平開始。
I2S 右對(duì)齊協(xié)議 :

I2S 右對(duì)齊模式:與 I2S 標(biāo)準(zhǔn)的差異,聲音數(shù)據(jù) LSB 傳輸完成的同時(shí), LRCLK 完成第二次翻轉(zhuǎn)。LRCK 為高電平時(shí),表示第一個(gè)聲道,低電平為第二個(gè)聲道。 BCLK 電平在 LRCK 發(fā)生電平變化后從低電平開始。
I2S 的 TDM 模式 :
I2S 標(biāo)準(zhǔn) _TDM :
如果要傳輸超過兩聲道的數(shù)據(jù),就需要使用 I2S 的 TDM 模式,因?yàn)楦鱾€(gè)廠家實(shí)現(xiàn)不一樣 ,僅供參考。

與 I2S 標(biāo)準(zhǔn)協(xié)議差異就是可以傳輸多個(gè)通道,最高支持到 16 聲道。
在 LRCK 的低電平傳輸左聲道,高電平傳輸右聲道。
可以看到在 Slot 傳輸兩個(gè)通道時(shí),就是標(biāo)準(zhǔn) I2S 的傳輸。
BCLK_rate = sample_rate * slot * slot_width。
I2S 左對(duì)齊 _TDM :

I2S 左對(duì)齊模式:與 I2S 標(biāo)準(zhǔn)的差異,在 LRCK 發(fā)生翻轉(zhuǎn)時(shí)就開始傳輸數(shù)據(jù)。這種協(xié)議使用較少。
I2S 右對(duì)齊 _TDM :

I2S 右對(duì)齊模式:與 I2S 標(biāo)準(zhǔn)的差異,聲音數(shù)據(jù) LSB 傳輸完成的同時(shí), LRCLK 完成第二次翻轉(zhuǎn)。這種協(xié)議又被稱為 sony 模式。
I2S 的 PCM 模式 :
PCM 接口包括四根信號(hào):
PCM_CLK:數(shù)據(jù)時(shí)鐘(位時(shí)鐘)信號(hào),類似 I2S 的 BCLK,頻率等于采樣率。
PCM_SYNC:幀同步信號(hào),類似 I2S 的LRCK
PCM_IN:接收數(shù)據(jù)信號(hào),類似 I2S 的 DIN
PCM_OUT:發(fā)送數(shù)據(jù)信號(hào),類似 I2S 的 DOUT
一般應(yīng)用場(chǎng)景:
PCM 模式通常用于 AP 處理器和通信 MODEM 之間傳輸語音數(shù)據(jù)。
AP 處理器和藍(lán)牙之間也是通過 PCM 模式來傳輸語音數(shù)據(jù)。撥打電話的藍(lán)牙數(shù)據(jù)走的是 PCM 模式,播放音樂藍(lán)牙數(shù)據(jù)走的是串口,不是 PCM 模式傳輸。
PCM 接口和 I2S 接口引腳一致,幀同步時(shí)鐘、位時(shí)鐘。
根據(jù)數(shù)據(jù)相對(duì)幀同步時(shí)鐘 LRCK 的位置, PCM 模式分為兩種基本模式。
DSP_MODE_A:數(shù)據(jù)在 LRCK 有效后, BCLK 的第 2 個(gè)上升沿有效。
DSP_MODE_B:數(shù)據(jù)在 LRCK 有效后, BCLK 的第 1 個(gè)上升沿有效。根據(jù)幀同步時(shí)鐘寬度的大小, PCM 又分為兩種模式。
短幀: LRCK width 等于 1 個(gè) BCLK。
長幀: LRCK width 大于 1 個(gè) BCLK,小于 LRCK 周期
短針示圖:

LRCK width = 1 個(gè) BCLK,就是上圖中 LRCK 的高電平,對(duì)應(yīng)一個(gè) BCLK 的寬度。這種就是短幀模式。
幀同步時(shí)鐘寬度為一個(gè)位時(shí)鐘周期,數(shù)據(jù)在 LRCK 有效后, BCLK 的第二個(gè)上升有效,又是**DSP_MODE_A **模式。
長針示圖:

LRCK width = 2 個(gè) BCLK,就是上圖中 LRCK 的高電平,對(duì)應(yīng)兩個(gè) BCLK 的寬度。這種就是長幀模式。
幀同步時(shí)鐘寬度為兩個(gè)位時(shí)鐘周期,數(shù)據(jù)在 LRCK 有效后, BCLK 的第一個(gè)上升有效,又是**DSP_MODE_B **模式。
短幀,長幀:
BCLK = LRCK * (slot * slot_width)
PCM短針配置實(shí)例(R818_Linux&RTL8821c):
藍(lán)牙固件自行和模組廠商確認(rèn)。
daudio1:daudio@0x05091000 {
mclk_div = <0x01>;
frametype = <0x00>;
tdm_config = <0x00>;
sign_extend = <0x00>;
tx_data_mode = <0x00>;
rx_data_mode = <0x00>;
msb_lsb_first = <0x00>;
pcm_lrck_period = <0x20>;
slot_width_select = <0x10>;
pinctrl-0 = <&daudio1_pins_a>;
pinctrl-1 = <&daudio1_pins_b>;
status = "okay";
};
各配置說明:
-
mclk_div:1/2/4…176/192:輸出 mclk。設(shè)置外部codec的時(shí)鐘,這里的頻率就是pll_audio/mclk_div。該值根據(jù)外接codec需要的mclk的頻率來配置。
示例:
pll_audio 一般為 24.576M 或者 22.5792M,外接的codec需要 MCLK,頻率為3.072M 或者 2.8224M,那么mclk_div就要設(shè)置為8。 - frametype:配置一個(gè)時(shí)鐘幀的長度,0表示短幀,1個(gè)時(shí)鐘的長度。1表示長幀,2個(gè)時(shí)鐘的長度,默認(rèn)配置0就行。
- tdm_config:tdm模式的配置,0表示pcm模式,1表示i2s模式。這里要使用i2s的pcm模式,所以要配置為0。
- sign_extend:0:(Zero Padding,高位補(bǔ)零)、1:(Sign Extend,符號(hào)擴(kuò)展)。
- tx_data_mode:TX端數(shù)據(jù)的格式。表示發(fā)送,也就是輸出信號(hào)。0: 16bit linear PCM;1: reserved;2: 8bit u-law;3: 8bit a-law
- rx_data_mode:RX端數(shù)據(jù)格式配置。表示發(fā)送,也就是輸入信號(hào)。同上
- msb_lsb_first:數(shù)據(jù)傳輸有效位選擇,數(shù)據(jù)傳輸有效位選擇,0: MSB 高 bit 發(fā)生至低 bit。 1: LSB 低 bit 發(fā)生至高 bit。,通常配置為0
-
pcm_lrck_period: BCLK:16/32/64/128/256,lrck 數(shù)據(jù)位寬,表示一個(gè)LRCK時(shí)鐘后BCLK的個(gè)數(shù)。
BCLK = LRCK * (slot * slot_width)
- slot_width_select:可選值:8bit/16bit/32bit 采樣位深(寬度):必須大于或等于采樣精度,一般等于最高支持采樣精度。
最大通道數(shù)(pcm 模式) = pcm_lrck_period / slot_width_select;
最大采樣位深= slot_width_select;
snddaudio1:sound@4 {
/*sunxi,snddaudio-codec = "ac107.1-0036";*/
/*sunxi,snddaudio-codec-dai = "ac107-pcm1";*/
audio_format = <0x04>;
daudio_master = <0x01>;
signal_inversion = <0x01>;
status = "okay";
};
-
audio_format:配置i2s/pcm協(xié)議格式。
i2s協(xié)議格式有i2s,right_j,left_j,分別表示i2s標(biāo)準(zhǔn)格式,i2s右對(duì)齊,i2s左對(duì)齊,對(duì)應(yīng)1-3
pcm協(xié)議的格式有dsp_a,dsp_b,分別表示MSB在LRCK上升沿后的第二個(gè)BCLK上升沿出現(xiàn)(DSP_MODE_A)短針,MSB在LRCK上升沿后的第一個(gè)BCLK上升沿出現(xiàn)(DSP_MODE_B)長針。對(duì)應(yīng)4-5- I2S vs 左對(duì)齊:I2S延遲一個(gè)時(shí)鐘開始傳輸,左對(duì)齊直接開始。
- 右對(duì)齊:數(shù)據(jù)低位對(duì)齊,填充高位方向。
- DSP_A vs DSP_B:區(qū)別在于MSB出現(xiàn)的時(shí)鐘周期(A延遲1個(gè)周期,B無延遲)。
daudio_master:1:表示SOC做從slave、codec做主master,4:表示SOC做主master、codec做從slave。
-
signal_inversion:信號(hào)采樣模式。 normal & invert
1: SND_SOC_DAIFMT_NB_NF (BCLK 正常模式, LRCK 正常模式)
2: SND_SOC_DAIFMT_NB_IF (BCLK 正常模式, LRCK 翻轉(zhuǎn)模式)
3: SND_SOC_DAIFMT_IB_NF (BCLK 翻轉(zhuǎn)模式, LRCK 正常模式)
4: SND_SOC_DAIFMT_IB_IF (BCLK 翻轉(zhuǎn)模式, LRCK 翻轉(zhuǎn)模式)
分頻系數(shù)求取方法
LRCLK同步時(shí)鐘分頻系數(shù)、位時(shí)鐘分頻系數(shù)BCLK_DIV計(jì)算方法如下所示:
公式1:LRCLK同步時(shí)鐘分頻系數(shù) = PLL/采樣率
公式2:對(duì)于PCM模式:位時(shí)鐘分頻系數(shù)BCLK_DIV= PLL/采樣率/pcm_lrck_period
公式3:對(duì)于I2S模式:位時(shí)鐘分頻系數(shù)BCLK_DIV= PLL/采樣率/pcm_lrck_period * 2
由公式1可知,分頻系數(shù)除了與采樣率、pcm_lrck_period有關(guān)外,還與PLL時(shí)鐘有關(guān)。通過時(shí)鐘樹獲取I2S/PCM的父時(shí)鐘PLL的大小,獲取方法與關(guān)鍵信息如下:
#mount -t debugfs none /sys/kernel/debug/
#cat /sys/kernel/debug/clk/clk_summary
pll_audiox4 7 7 90316800 0 0
codec_dac_1x 1 1 22579200 0 0
i2s2 2 2 22579200 0 0
i2s1 1 1 22579200 0 0
codec_4x 0 0 90316800 0 0
dmic 0 0 90316800 0 0
spdif 0 0 90316800 0 0
i2s3 0 0 90316800 0 0
i2s0 0 0 90316800 0 0
pll_audiox2 0 0 45158400 0 0
pll_audio 2 2 22579200 0 0
pll_audiox8 0 0 180633600 0 0
pll_audiox4的PLL 時(shí)鐘大小為90316800。根據(jù)公式1,PLL除以采樣率16000,得到同步時(shí)鐘的分頻系數(shù)clk_div;聲卡是PCM模式,借助公式2計(jì)算BCLK_DIV= PLL÷(16000*pcm_lrck_period)= 176.
查找源碼或者規(guī)格書來確認(rèn)分頻是否在其范圍內(nèi):
#BCLK_DIV分頻系數(shù)取值范圍為1、2、4、6、8、12、16、24、32、48、64、96、128、176、192....

對(duì)于PCM模式,pcm_lrck_period (0x20)表示一個(gè) LRCK 中BCLK的個(gè)數(shù),配置中為32 。對(duì)于I2S模式,pcm_lrck_period表示半個(gè)LRCK 中BCLK的個(gè)數(shù)。該字段調(diào)整可配置為 16/32/64/128/256 個(gè) bclk。
配置設(shè)備樹時(shí),可以適當(dāng)增大pcm_lrck_period,增大該字段后slot個(gè)數(shù)會(huì)增多,該模塊的有效數(shù)據(jù)在第一個(gè)slot,其他slot并不影響數(shù)據(jù)通信。