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