在嵌入式音頻開發中,順芯(Everest)ES8389/ES8390是一款高集成度的音頻Codec芯片,廣泛應用于智能音箱、車載終端、便攜設備等場景。本文基于Linux6.1內核,從驅動架構、寄存器配置、核心函數、數據流走向四個維度,完整拆解ES8389的Linux驅動實現,幫你吃透這款芯片的驅動邏輯。
注意:在講解rk3576系列課程的視頻中有提到es8388已經停產了,目前這個8390是pin對pin替代的,估計也是升級版。
一、驅動整體架構:基于ASoC+I2C框架
ES8389驅動完全遵循Linux音頻子系統的ASoC(ALSA System on Chip)框架設計,同時依托I2C完成芯片寄存器的讀寫交互,整體架構分為三層:
?I2C驅動層:實現芯片與內核的I2C通信,是驅動的基礎載體;
?ASoC Component層:封裝Codec的硬件操作(probe/remove/suspend/resume)、音頻控制(音量/靜音/混音);
?ASoC DAI層:定義音頻接口(I2S/TDM)、采樣率/格式等參數,是CPU與Codec的音頻數據交互入口。
核心代碼中,es8389_i2c_driver是I2C驅動主體,soc_codec_dev_es8389是ASoC Component驅動,es8389_dai是DAI(Digital Audio Interface)驅動,三者共同構成完整的驅動體系。
二、核心數據結構:驅動的“骨架”
1.私有數據結構體(es8389_private)
驅動通過該結構體管理芯片的運行時狀態,是貫穿整個驅動的核心:
structes8389_private{structsnd_soc_component*component; // 關聯ASoC組件structregmap*regmap; // 寄存器映射(簡化I2C讀寫)structclk*mclk; // 主時鐘句柄unsignedintsysclk; // 系統時鐘頻率intmastermode; // 主/從模式標識u8 adc_slot; // ADC TDM時隙u8 dac_slot; // DAC TDM時隙intdmic; // DMIC使能標識u8 mclk_src; // 主時鐘源enumsnd_soc_bias_levelbias_level; // 功耗偏置等級};
2.時鐘系數結構體(_coeff_div)
ES8389的時鐘配置高度依賴采樣率和主時鐘(MCLK)的匹配,驅動預定義了不同MCLK/采樣率組合下的寄存器配置表:
struct_coeff_div {u16 fs; // 采樣率(如8000/16000/48000)u32 mclk; // 主時鐘頻率u32 rate; // 音頻速率u8 Reg0x04; // 時鐘分頻寄存器0x04配置值// ... 省略其他寄存器配置項u8 Reg0x19; // 系統寄存器0x19配置值};
代碼中coeff_div數組包含了8kHz/16kHz/44.1kHz/48kHz等主流采樣率的時鐘參數,get_coeff()函數負責根據實際MCLK和采樣率匹配對應的寄存器配置。
三、關鍵寄存器解析:硬件的“指令集”
ES8389驅動的核心是寄存器操作,按功能可分為5大類,以下結合代碼中的關鍵操作解析:
1.時鐘配置寄存器(0x04-0x0A、0x0F、0x11)
?作用:配置時鐘分頻、倍頻、源選擇,是音頻采樣率匹配的核心;
?關鍵操作:es8389_pcm_hw_params()函數中,根據采樣率匹配coeff_div表后,批量寫入時鐘寄存器:
regmap, ES8389_CLK_DIV1_REG04, coeff_div[coeff].Reg0x04);regmap, ES8389_CLK_MUL_REG05, coeff_div[coeff].Reg0x05);// ... 其他時鐘寄存器寫入
2. ADC/DAC核心寄存器(0x20、0x40)
?作用:配置音頻格式(S16_LE/S24_LE/S32_LE)、I2S/TDM模式、靜音等;
?關鍵操作:
?格式配置:hw_params()中根據PCM參數設置數據長度:
switch(params_format(params)){caseSNDRV_PCM_FORMAT_S16_LE:state |= ES8389_S16_LE; // 16位小端格式break;// ... 其他格式配置}regmap_update_bits(es8389->regmap, ES8389_ADC_REG20, ES8389_DATA_LEN_MASK, state);
?靜音控制:es8389_mute()中通過0x20/0x40寄存器的低2位控制ADC/DAC靜音:
regmap_update_bits(es8389->regmap, ES8389_DAC_REG40,0x03,0x03); // 靜音DAC
3.模擬偏置寄存器(0x60-0x63)
?作用:配置模擬電路的偏置電壓、電源模式,是芯片正常工作的基礎;
?關鍵操作:es8389_init()中初始化模擬電路:
regmap_write(es8389->regmap, ES8389_VMID_REG60,0x2A); // 偏置電壓配置regmap_write(es8389->regmap, ES8389_ANA_CTL1_REG61,0xC9); // 模擬控制1
4.混音/路由寄存器(0x2B、0x44、0x31)
?作用:配置ADC/DAC的混音源、通道路由(如左右聲道交換、ADC MUX選擇);
?關鍵操作:通過DAPM(Dynamic Audio Power Management)控件配置路由,例如:
// 配置ADC MUX選擇AMIC/DMICstaticconststructsoc_enum es8389_dmic_mux_enum =SOC_VALUE_ENUM_SINGLE(ES8389_DMIC_EN_REG6D,6,3, es8389_dmic_mux_txt, es8389_dmic_mux_values);
5.功耗控制寄存器(0x00、0x10、0x69)
?作用:控制芯片的復位、功耗等級(ON/STANDBY/OFF);
?關鍵操作:es8389_set_bias_level()中切換功耗狀態:
caseSND_SOC_BIAS_ON:regmap_write(es8389->regmap,ES8389_RESET_REG00,0x01);// 退出復位regmap_update_bits(es8389->regmap,ES8389_HPSW_REG69,0x20,0x20);// 開啟耳機電源break;caseSND_SOC_BIAS_STANDBY:regmap_write(es8389->regmap,ES8389_RESET_REG00,0x3E);// 進入待機break;
四、核心函數分析:驅動的“靈魂”
1. probe函數:驅動初始化入口
es8389_probe()是驅動加載時的核心函數,完成以下關鍵操作:
1.從設備樹讀取配置(mclk-src、adc-slot、dmic-enabled等);
2.獲取并使能主時鐘(MCLK);
3.調用es8389_init()完成芯片默認寄存器配置;
4.關聯ASoC組件和私有數據。
2. hw_params函數:音頻參數適配
es8389_pcm_hw_params()在音頻流啟動前被調用,核心邏輯:
1.解析PCM參數(采樣率、格式、通道數);
2.配置ADC/DAC的數據格式(如S16_LE);
3.匹配時鐘系數表,寫入時鐘寄存器;
4.完成硬件參數與芯片寄存器的映射。
3. set_bias_level函數:功耗管理
ES8389支持4種功耗等級(OFF/STANDBY/PREPARE/ON),該函數負責切換不同等級:
?ON:芯片全功能運行,開啟模擬電路、時鐘;
?STANDBY:低功耗待機,關閉部分時鐘和模擬電路;
?OFF:深度休眠,僅保留必要的電源。
4. mute函數:靜音控制
es8389_mute()實現ADC/DAC的靜音/取消靜音:
?靜音:設置ADC/DAC寄存器的靜音位;
?取消靜音:清除靜音位,同時恢復ADC使能和時鐘配置。
五、音頻數據流走向:從CPU到耳機/麥克風
ES8389的數據流分為播放(Playback)和采集(Capture)兩條路徑,驅動通過DAPM路由定義了完整的數據流鏈路,以下結合流程圖詳解:
1.播放(Playback)數據流

關鍵節點:
?I2S IN:CPU通過I2S接口發送音頻數據到Codec;
?DACL/DACR:數字音頻解碼為模擬信號;
?OUT MUX:支持左右聲道交換(如DAC2→DAC1);
?HPOL/HPOR:最終輸出到耳機左/右聲道。
2.采集(Capture)數據流

關鍵節點:
?PGAL/PGAR:模擬信號前置放大(增益可通過寄存器0x72/0x73配置);
?ADC Mixer:支持DAC信號回灌到ADC(如音頻回環測試);
?ADC MUX:切換模擬麥克風(AMIC)/數字麥克風(DMIC);
?I2S OUT:數字音頻數據通過I2S發送到CPU。
六、總結與拓展
核心要點
1.框架依賴:驅動基于ASoC+I2C框架,遵循Linux音頻子系統的標準設計,適配性強;
2.時鐘核心:采樣率匹配的關鍵是coeff_div時鐘表,需確保MCLK與采樣率的匹配;
3.功耗管理:通過bias_level實現不同功耗等級的切換,平衡性能與功耗;
4.路由靈活:DAPM路由支持混音、聲道交換、麥克風類型切換,滿足復雜音頻場景。
適配注意事項
1.設備樹需配置everest,mclk-src(時鐘源)、everest,dmic-enabled(DMIC使能)等屬性;
2.不同硬件平臺的MCLK頻率不同,需確認coeff_div表中是否有匹配的時鐘參數;
3.Linux6.1內核下,ASoC框架的接口無重大變化,適配其他版本(如5.15/6.6)僅需微調寄存器配置。
如需獲取相關驅動,請評論區留言,需要適配其他Linux內核版本(如4.19/5.10),或定制音頻路由、功耗策略,可私信交流具體的修改方案。

本文從驅動架構到數據流,完整拆解了ES8389音頻Codec的Linux驅動實現,希望能幫助嵌入式開發者快速掌握這款芯片的驅動邏輯,解決實際開發中的音頻適配問題。
-
Linux
+關注
關注
88文章
11758瀏覽量
219006 -
音頻芯片
+關注
關注
3文章
162瀏覽量
18835
發布評論請先 登錄
Linux音頻開發必藏!這個官網藏著從驅動到應用的全套解決方案
拆解RK3568啟動日志:Debian12+Linux6.1下的調試密碼,初學者也能看懂
初次編譯rk3568(rk3576)Linux 6.1內核踩坑記錄:從報錯終止到成功解決的完整流程
ES7243E+ES8311音頻錄制與播放電路資料
RK3576+Android15+Linux6.1調試EM05 4G模塊全記錄:從底層到上層的踩坑與破局
保姆級教程!RK3588 Linux6.1?固件簽名完整實現方案(不含rootfs)
探索TLE8082ES+TLE8080EM評估板:從硬件到軟件的深度解析
Linux內核printk日志級別全解析:從參數解讀到實操配置
【免費送書】成為硬核Linux開發者:《Linux 設備驅動開發(第 2 版)》
【書籍評測活動NO.67】成為硬核Linux開發者:《Linux 設備驅動開發(第 2 版)》
ES8311+音頻PA雙引擎,AirAUDIO_1010釋放聲音潛能!
揭秘,瑞芯微全系擁抱Linux 6.1內核的底層邏輯
新品 | Module Audio,ES8388音頻交互模塊
杰理科技推出AC706N多功能音頻芯片
樹莓派4 性能大比拼:標準Linux與實時Linux 4.19內核的延遲測試
深度解析ES8389/ES8390/音頻芯片Linux驅動(Linux6.1內核)
評論