S5PV210 WM8960 ASOC 移植
內(nèi)核版本Linux 3.9.11 ? ? ?編譯器版本 4.5.1
Asoc框架是linux內(nèi)核采用的一種音頻子系統(tǒng)框架。他在alsa框架的基礎(chǔ)上又封裝了一層。實(shí)際上就把a(bǔ)soc移植看成alsa移植即可。(雖然2個(gè)我都不太懂,初學(xué)asoc驅(qū)動(dòng))
在對(duì)實(shí)際文件分析后我把a(bǔ)lsa框架需要修改的主要為如下幾類:
其中I2S控制器驅(qū)動(dòng)和I2C子系統(tǒng)驅(qū)動(dòng)由內(nèi)核已經(jīng)給出。I2S驅(qū)動(dòng)主要是設(shè)置I2S相關(guān)的寄存器,便于ASOC其他部分(框架理解不是很透徹,這里可以看成PCM數(shù)據(jù)發(fā)送)發(fā)送數(shù)據(jù)。
而I2C子系統(tǒng)驅(qū)動(dòng)則負(fù)責(zé)配置WM8960的寄存器。SMDK.c文件主要是負(fù)責(zé)將asoc各個(gè)部分通過(guò)一個(gè)結(jié)構(gòu)體描述連接起來(lái)。他們都是由asoc更上層的結(jié)構(gòu)進(jìn)行調(diào)用的。
對(duì)于我們移植來(lái)說(shuō),主要是關(guān)心SMDK_xxxx.c這樣的Machine部分的文件。如果內(nèi)核沒(méi)有的話,就需要自己動(dòng)手寫(xiě)了,我這里是沒(méi)有的,所以我去找了個(gè)S3c2451的WM8960的Machine文件,接下來(lái)說(shuō)下修改步驟。
想要正確播放出聲音,第一步就需要修改machine中的dai結(jié)構(gòu)體:
下面只說(shuō)下主要的成員:
Cpu_dai_name? ?? ? ? 對(duì)應(yīng)i2s控制器驅(qū)動(dòng)
Codec_dai_name ? ? 對(duì)應(yīng)于內(nèi)核提供的codec文件中的同名dai 圖3 給出
Platform_name ? ? ? 用于數(shù)據(jù)傳輸?shù)钠脚_(tái)名稱 (我猜的 I2SDMA?)
Codec_name ? ? ? ? ? 對(duì)應(yīng)于控制codec的 i2c驅(qū)動(dòng)
ops ? ? ? ? ? ? ? ? ? ? ? ? 主要成員是.hw_params變量,當(dāng)通過(guò)alsa-util測(cè)試播放的時(shí)候,應(yīng)用會(huì)通過(guò) 這個(gè)函數(shù)傳入一些控制參數(shù)來(lái)設(shè)置i2s和wm8960。 通過(guò) 圖2 劃線的2個(gè)參數(shù)就能對(duì)應(yīng)到codec和i2s各自的控制函數(shù)當(dāng)中。分別進(jìn)行設(shè)置。參數(shù)則通過(guò)查看他們對(duì)應(yīng)的函數(shù)就能得出。
修改后若使用默認(rèn)的設(shè)置無(wú)法播放,則需要檢查設(shè)置讓關(guān)鍵的寄存器值變正確。
IIS設(shè)置主要要設(shè)置時(shí)鐘源選I2SCLK,通過(guò)EPLL產(chǎn)生時(shí)鐘,設(shè)置可以查看芯片手冊(cè)中的i2s時(shí)鐘路線圖,然后就是bfs,rfs,psr參數(shù),通常使用bfs=32 rfs=256,因?yàn)閣m8960中默認(rèn)設(shè)置還會(huì)將傳入的頻率/256和/32,所以為了保證頻率正確就這樣設(shè)置,這兩個(gè)可以通過(guò)應(yīng)用傳參得到。而psr就需要我們通過(guò)計(jì)算得到了,比如44100hz采樣率就是5 采樣率是22050時(shí)就是10。這是通過(guò)公式算出來(lái)的。(psr是i2s預(yù)分頻寄存器)
我們只需要讓這些值真確寫(xiě)入寄存器就好了。設(shè)置通過(guò)i2s控制器驅(qū)動(dòng)中的i2s_set_clkdiv函數(shù),當(dāng)然這些只是設(shè)置,并沒(méi)有實(shí)際寫(xiě)入到寄存器,真正寫(xiě)入到寄存器的是config_setup函數(shù),里面調(diào)用
set_bfs(i2s, bfs); set_rfs(i2s, rfs);寫(xiě)入寄存器,psr在最后進(jìn)行設(shè)置。
if (!(i2s->quirks & QUIRK_NO_MUXPSR)) {psr =m_psr;// i2s->rclk_srcrate / i2s->frmclk / rfs;printk("i2s %s setup psr:%d \r\n",__func__,psr);writel(((psr ) << 8) | PSR_PSREN, i2s->addr + I2SPSR);dev_dbg(&i2s->pdev->dev,"RCLK_SRC=%luHz PSR=%u, RCLK=%dfs, BCLK=%dfs\n",i2s->rclk_srcrate, psr, rfs, bfs);}可以看到我用m_psr替換掉了原始的psr計(jì)算,這是因?yàn)?#xff0c;我在machine中已經(jīng)計(jì)算好了psr的值,傳入設(shè)置好的時(shí)候,不用計(jì)算直接寫(xiě)入即可。
并且,i2s驅(qū)動(dòng)中的set_clkdiv可能會(huì)少 rfs和psr的設(shè)置,加入即可。
(這些修改的部分是通過(guò)machine中的.hw_params函數(shù)設(shè)置的)
以下代碼是I2S.c中的代碼,添加了2和3兩個(gè)選項(xiàng)(這是通過(guò)調(diào)試得到的缺少的部分)。
這里還需要注意一個(gè)函數(shù)就是i2s_txctrl ,這個(gè)函數(shù)控制著i2s的輸出,在函數(shù)的末尾可以看到設(shè)置IISCON和IISMOD寄存器,如果不出聲音可以在此跟蹤一下這兩個(gè)寄存器的狀態(tài)。
正確的狀態(tài)不知道的話可以先寫(xiě)下裸機(jī)wm8960驅(qū)動(dòng)以后再來(lái)驗(yàn)證,裸機(jī)驅(qū)動(dòng)wm8960的代碼網(wǎng)上還是比較多的。
我這里改成了con |1, 原因可以通過(guò)看手冊(cè)和跟蹤寄存器得出。
到此I2S部分和machine部分就修改完了。還要注意一點(diǎn),如果iis設(shè)置全對(duì),還是沒(méi)有聲音,這時(shí)就要考慮codec驅(qū)動(dòng)的初始化問(wèn)題了,以wm8960.c為例,我是在代碼中的wm8960_probe函數(shù)中看到了wm8960的一些寄存器初始化函數(shù)調(diào)用,一些關(guān)鍵的設(shè)置并不正確,于是修改為如下:
注釋掉的是原來(lái)的,wm8960寄存器地址在wm8960.h中都有定義的,我為了省事直接把裸機(jī)代碼拿過(guò)來(lái)用了,效果是一樣的。主要設(shè)置了電源,時(shí)鐘,音量和聲音輸出,這些缺1不可(測(cè)試過(guò))。
這樣修改完后聲音應(yīng)該能放出來(lái)了。
如果出聲音了,速率不對(duì),偏快或偏慢,那是因?yàn)镋PLL時(shí)鐘設(shè)置不對(duì),IIS需要67.7M的時(shí)鐘頻率才能正確播放。,當(dāng)然80M的頻率播放也蠻有意思的,音調(diào)被改變,一樣的音樂(lè),不一樣的感受。^_^
另外提一下asoc驅(qū)動(dòng)移植注意。
smdk_8960.c是我手動(dòng)添加的,還需要修改Makefile和Kconfig文件,才能被配置和編譯。
首先需要在smdk_s5pv210.c中的device __init數(shù)值,確定iis0和i2c0設(shè)備在數(shù)組中。(我的wm8960 用的是iis0和i2c0),將wm8960作為i2c子設(shè)備添加到 i2c0中,配置內(nèi)核支持i2c,asoc然后啟動(dòng)后確定i2c0,wm8960,asoc正確被加載(看輸出),i2s0會(huì)在wm8960匹配成功后會(huì)出現(xiàn)如下類似輸出:
最終成功時(shí)會(huì)有如下輸出:
ALSA device list:#0: SMDK-I2S也就是成功注冊(cè)了一個(gè)聲卡設(shè)備。
在/dev目錄下會(huì)出現(xiàn)這些設(shè)備節(jié)點(diǎn):
最后通過(guò)alsa-util調(diào)用alsa-lib庫(kù) 播放wav文件 如果需要播放MP3還需要libmad(MP3解碼庫(kù))的支持,直接讓alsa-lib使用libmad庫(kù)我還沒(méi)找到方法,但可以通過(guò)自己寫(xiě)一個(gè)程序,調(diào)用libmad和alsa-lib來(lái)播放MP3,代碼網(wǎng)上可以搜到。
附上測(cè)試播放調(diào)試圖:
WAV文件:
MP3文件:
可以看到,播放MP3和WAV的驅(qū)動(dòng)輸出基本是一樣的,最原始的音頻數(shù)據(jù)是WAV,播放MP3只是通過(guò)軟解碼轉(zhuǎn)換成WAV文件流而已。
心得體會(huì)
對(duì)于這些帶框架的驅(qū)動(dòng)學(xué)習(xí),如果遇到問(wèn)題不知道出在哪里可以先去調(diào)試一下裸機(jī)代碼,確定寄存器的正確配置后再來(lái)調(diào)驅(qū)動(dòng)框架會(huì)有事半功倍的效果。^_^
總結(jié)
以上是生活随笔為你收集整理的S5PV210 WM8960 ASOC 移植的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 浙江大学【面板数据分析与STATA应用】
- 下一篇: 生产部经理绩效考核