最近一直在研究 ALSA 驅(qū)動,停了一段時間,突然發(fā)現(xiàn)Asla 驅(qū)動不是一天兩天能講清楚的。
1. ASoC 概述
ASoC (ALSA System on Chip) ,是建立在標準ALSA驅(qū)動層上,為了更好地支持嵌入式處理器和移動設(shè)備中的音頻Codec的一套軟件體系。在ASoc出現(xiàn)之前,內(nèi)核對于SoC中的音頻已經(jīng)有部分的支持,不過會有一些局限性:
Codec驅(qū)動與SoC CPU的底層耦合過于緊密,這種不理想會導(dǎo)致代碼的重復(fù)。
音頻事件沒有標準的方法來通知用戶,例如耳機、麥克風(fēng)的插拔和檢測,這些事件在移動設(shè)備中是非常普通的,而且通常都需要特定于機器的代碼重新對音頻路勁進行配置。
當進行播放或錄音時,驅(qū)動會讓整個codec處于上電狀態(tài),這對于PC沒問題,但對于移動設(shè)備來說,這意味著浪費大量的電量。同時也不支持通過改變過取樣頻率和偏置電流來達到省電的目的。
ASoC正是為了解決上述種種問題而提出的,目前已經(jīng)被整合至內(nèi)核的代碼樹中:sound/soc。ASoC不能單獨存在,他只是建立在標準ALSA驅(qū)動上的一個它必須和標準的ALSA驅(qū)動框架相結(jié)合才能工作。
2. 硬件架構(gòu)
嵌入式設(shè)備的音頻系統(tǒng)可以被劃分為板載硬件(Machine)、Soc(Platform)、Codec三大部分,如下圖所示:
Machine :是指某一款機器,可以是某款設(shè)備,某款開發(fā)板,由此可以看出Machine幾乎是不可重用的,每個Machine上的硬件實現(xiàn)可能都不一樣,CPU不一樣,Codec不一樣,音頻的輸入、輸出設(shè)備也不一樣,Machine為CPU、Codec、輸入輸出設(shè)備提供了一個載體。
Platform:一般是指某一個SoC平臺,比如s3cxxxx,與音頻相關(guān)的通常包含該SoC中的時鐘、DMA、I2S、PCM等等,只要指定了SoC,那么我們可以認為它會有一個對應(yīng)的Platform,它只與SoC相關(guān),與Machine無關(guān),這樣我們就可以把Platform抽象出來,使得同一款SoC不用做任何的改動,就可以用在不同的Machine中。實際上,把Platform認為是某個SoC更好理解。
Codec:字面上的意思就是編解碼器,Codec里面包含了I2S接口、D/A、A/D、Mixer、PA(功放),通常包含多種輸入(Mic、Line-in、I2S、PCM)和多個輸出(耳機、喇叭、聽筒,Line-out),Codec和Platform一樣,是可重用的部件,同一個Codec可以被不同的Machine使用。嵌入式Codec通常通過I2C對內(nèi)部的寄存器進行控制。
注釋:對于現(xiàn)在的很多嵌入式平臺,內(nèi)部集成了codec,我們在分析時也可以將其劃分到codec 上,不同的Soc 內(nèi)部Codec 有所不同,同時亦可兼容內(nèi)部codec 和 外部Codec。
3. 軟件架構(gòu)
在軟件層面,ASoC也把嵌入式設(shè)備的音頻系統(tǒng)同樣分為3大部分,Machine,Platform和Codec。
Machine: Machine 驅(qū)動負責(zé)處理機器特有的一些控件和音頻事件(例如,當播放音頻時,需要先行打開一個放大器);單獨的Platform 和 Codec驅(qū)動是不能工作的,它必須由Machine驅(qū)動把它們結(jié)合在一起才能完成整個設(shè)備的音頻處理工作。
Platform:它包含了該SoC平臺的音頻 DMA 和音頻接口的配置和控制(I2S,PCM,AC97等等);它也不能包含任何與板子或機器相關(guān)的代碼。
Codec : ASoC 中的一個重要設(shè)計原則就是要求Codec驅(qū)動是平臺無關(guān)的,它包含了一些音頻的控件(Controls),音頻接口,DAMP(動態(tài)音頻電源管理)的定義和某些Codec IO功能。為了保證硬件無關(guān)性,任何特定于平臺和機器的代碼都要移到 Platform 和Machine驅(qū)動中。所有的Codec驅(qū)動都要提供以下特性:
Codec DAI 和 PCM的配置信息;Codec的IO控制方式(I2C,SPI等);Mixer和其他的音頻控件;Codec的ALSA音頻操作接口;
必要時,也可以提供以下功能:
DAPM描述信息;
DAPM事件處理程序;
DAC數(shù)字靜音控制
4. ASOC 分析
4.1 硬件抽象
通常一個聲卡設(shè)備,大概包含以下幾個物理設(shè)備或者外設(shè):
Codec:音頻編解碼控制器,可以是內(nèi)部Codec(soc 集成),也可以是外部Codec. Codec 通過支持音頻編解碼,包括模擬麥或者spk, 有的甚至支持數(shù)字麥。
AMIC/SPK/DMIC:純硬件電路。麥克風(fēng)或者spk,軟件無需干預(yù)。
DMA:對于硬件設(shè)備的數(shù)據(jù)量,大多數(shù)情況都是通過dma 搬運來提高效率。
cpu:整個soc 平臺,主要提供音頻通信接口來實現(xiàn)和codec 傳輸。比如(I2S/PDM等)
DAI:音頻接口,抽象概念,比如I2S等。
Card:抽象概念,聲卡。
Capture:抽象概念,表示錄音設(shè)備
Playback:抽象概念,表示軟件設(shè)備
對于大多數(shù)平臺,dma 和 i2s/pdm 等集成在一個soc 上,有些甚至集成了Codec。
4.2 音頻數(shù)據(jù)流
音頻數(shù)據(jù)的數(shù)據(jù)流,大致如下。我們可以看到,不同的硬件平臺,其聲卡設(shè)備的硬件邏輯和數(shù)據(jù)流大致一致,故抽象ASoc 很有必要。
4.3 ASoc 軟件抽象
如下是筆者根據(jù)自己理解劃分 Alsa 聲卡驅(qū)動各個部分:
Machine:驅(qū)動頂層和入口,處理聲卡操作。包括聲卡創(chuàng)建,音頻流的傳輸與控制。
platform:主要負責(zé)Soc 平臺的DMA 和 CPU_DAI 操作。
Codec:主要負責(zé)Codec driver 和 Codec_dai 操作。
可以看到一個ALSA 聲卡驅(qū)動是十分復(fù)雜的,包含了各種復(fù)雜驅(qū)動。
codec driver:音頻配置和傳輸
dma:dma 處理
dai:i2s等接口配置
pcm:和上層應(yīng)用交互的中間層
control:和上層應(yīng)用交互的中間層
其他:比如i2c/spi ,codec 控制操作。
4.4 ASoc 驅(qū)動分析
我們以 linux-kernel-4.4.94 為例子來分析 ASoc 驅(qū)動。限于篇幅,我們只分析 Machine 驅(qū)動框架,對于Codec 驅(qū)動和其他設(shè)備驅(qū)動,有時間再分析。
ASoc Machine 驅(qū)動調(diào)用如下:
/*ASoCplatformdriver*/ staticstructplatform_driversoc_driver={ .driver={ .name="soc-audio", .pm=&snd_soc_pm_ops, }, .probe=soc_probe, .remove=soc_remove, };
最頂層入口是soc_probe,位于 sound/soc/soc-core.c,不同的Machine 位置可能不同。大部分在soc/xxx/下。
/*probesanewsocdev*/ staticintsoc_probe(structplatform_device*pdev) { structsnd_soc_card*card=platform_get_drvdata(pdev); /* |*nocard,somachinedrivershouldberegisteringcard |*weshouldnotbehereinthatcasesoreterror |*/ if(!card) return-EINVAL; dev_warn(&pdev->dev, |"ASoC:machine%sshouldusesnd_soc_register_card() ", |card->name); /*Bodgewhileweunpickinstantiation*/ card->dev=&pdev->dev; returnsnd_soc_register_card(card); }
最關(guān)鍵的就是 snd_soc_register_card 這個函數(shù)了。詳細分析看上圖uml 時許圖。
4.5 ASoc 數(shù)據(jù)結(jié)構(gòu)
ASoc 數(shù)據(jù)結(jié)構(gòu)如上圖。最頂層我們構(gòu)建了snd_soc_card。貫穿整個驅(qū)動生命周期中,snd_soc_pcm_runtime,至關(guān)重要。
dai_link 關(guān)聯(lián)著dai_driver 和 compoent_driver
snd_soc_codec:codec 相關(guān)
snd_soc_paltform:platform 相關(guān)
snd_soc_dai:cpu_dai 和 codec_dai 相關(guān)操作
snd_soc_component:關(guān)聯(lián)dai_driver 和 component_driver。關(guān)聯(lián)platform_driver 和 component_driver
snd_soc_ops/snd_soc_dai_ops/snd_pcm_ops:比較關(guān)鍵的幾個ops
對于剛開始學(xué)習(xí)ASLA 驅(qū)動時,我們先關(guān)注這幾個結(jié)構(gòu)體就行。后續(xù)將從音頻流和控制兩大塊,詳細分析整個數(shù)據(jù)流和控制的調(diào)用過程。
5. 總結(jié)
本文詳細的介紹了ALSA 驅(qū)動最關(guān)鍵的一環(huán)ASoC ,理解了ASoc 頂層設(shè)計框架對于我們后續(xù)深入學(xué)習(xí)ASLA 驅(qū)動至關(guān)重要。
當我們熟悉了一個平臺的驅(qū)動框架后,再去看另外一個平臺就知道哪些是我們需要關(guān)注的,哪些是linux 內(nèi)核已經(jīng)實現(xiàn)的,從而達到事半功倍的作用。
希望本文,對讀者朋友學(xué)習(xí)理解Alsa 驅(qū)動有所幫助!
審核編輯:湯梓紅
-
嵌入式
+關(guān)注
關(guān)注
5088文章
19159瀏覽量
306515 -
cpu
+關(guān)注
關(guān)注
68文章
10890瀏覽量
212430 -
soc
+關(guān)注
關(guān)注
38文章
4192瀏覽量
218633 -
alsa
+關(guān)注
關(guān)注
0文章
19瀏覽量
3626
原文標題:ALSA 驅(qū)動抽象:ASoc 理解與分析
文章出處:【微信號:漫談嵌入式,微信公眾號:漫談嵌入式】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論