新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > AM335x(TQ335x)學習筆記——WM8960聲卡驅動移植

        AM335x(TQ335x)學習筆記——WM8960聲卡驅動移植

        作者: 時間:2016-11-28 來源:網絡 收藏

        Step3. 調整WM8960驅動結構

        內核中自帶的WM8960驅動結構很舊,編寫Machine是需要過多的了解Codec芯片內部細節,本文對WM8960的驅動結構進行了調整,可以使Machine忽略Codec的內部細節。

        修改的大體內容如下:

        (1) 添加set_sysclk函數,接收Machine設置的sysclk時鐘頻率。具體本文就是DTS中設置的24576000。

        (2) 在hw_params中添加BCLK、DACCLK、ADCCLK的配置操作。hw_params可以根據參數和sysclk對以上參數進行設置,放在這里很合適。

        (3) 去除函數wm8960_set_dai_clkdiv,并將wm8960_set_dai_pll設置為驅動內部函數,不作為set_pll接口提供給內核驅動(實際上內核驅動也不調用這個函數)。

        Step4. 修改WM8960的route信息

        根據TQ335x的原理圖可知,使用WM8960進行錄音或放音時使用的LRCLK是同一個,都是DACCLK,故在snd_soc_dapm_route添加如下兩行信息:

        1. {"LeftDAC",NULL,"LeftInputMixer"},
        2. {"RightDAC",NULL,"RightInputMixer"},
        這樣在錄音時也會使能DAC產生LRCLK。

        由于調試時間比較長,可能有些修改我沒有描述到,完整的wm8960.c文件我會一并上傳到我的資源,可以下載參考。

        3. 編寫Machine驅動
        內核代碼有個很好的例子就是davinci-evm.c,這是am335x-evm評估板的Machine驅動,該評估采用的Codec并不是WM8960,因此,我們在該文件中添加WM8960信息即可。具體的修改如下:

        Step1. 添加compatible信息。修改后的內容如下:

        1. staticconststructof_device_iddavinci_evm_dt_ids[]={
        2. {
        3. .compatible="ti,tq-evm-audio",
        4. .data=(void*)&evm_dai_wm8960,
        5. },
        6. {
        7. .compatible="ti,da830-evm-audio",
        8. .data=(void*)&evm_dai_tlv320aic3x,
        9. },
        10. {/*sentinel*/}
        11. };
        Step2. 實現em_dai_wm8960。需要添加如下代碼:
        1. staticstructsnd_soc_dai_linkevm_dai_wm8960={
        2. .name="wm8960",
        3. .stream_name="wm8960-hifi",
        4. .codec_dai_name="wm8960-hifi",
        5. .ops=&evm_wm8960_ops,
        6. .init=evm_wm8960_init,
        7. .dai_fmt=SND_SOC_DAIFMT_I2S|SND_SOC_DAIFMT_CBM_CFM|
        8. SND_SOC_DAIFMT_NB_NF,
        9. };
        含義:

        (1) codec_dai_name = "wm8960-hifi" --> 指定codec設備名稱,與wm8960.c中指定的相同即可。

        (2) ops --> 指定wm8960的各種操作函數,本文僅實現了hw_params函數。

        (3) init --> 指定wm8960的初始化函數,主要是完成dapm相關的初始化。

        (4) dai_fmt --> 指定音頻的接口方式、主從關系和時鐘翻轉信息。SND_SOC_DAIFMT_I2S表示音頻接口采用I2S協議;SND_SOC_DAIFMT_CBM_CFM表示Codec的BCLK為Master,LRCLK為Master,即wm8960為主,AM335x為從;SND_SOC_DAIFMT_NB_NF表示BCLK和LRCLK都不需要翻轉。

        Step3.實現evm_wm8960_init

        這一部分主要是dapm相關的設置,本人理解也不是非常深刻,直接貼上代碼,具體如下:

        1. staticconststructsnd_soc_dapm_widgetevm_wm8960_dapm_widgets[]={
        2. SND_SOC_DAPM_SPK("AudioOut1",NULL),
        3. SND_SOC_DAPM_MIC("myMic",NULL),
        4. SND_SOC_DAPM_MIC("myLineIN",NULL),
        5. };
        6. staticconststructsnd_kcontrol_newevm_wm8960_controls[]={
        7. SOC_DAPM_PIN_SWITCH("AudioOut1"),
        8. SOC_DAPM_PIN_SWITCH("myMic"),
        9. SOC_DAPM_PIN_SWITCH("myLineIN"),
        10. };
        11. staticconststructsnd_soc_dapm_routeevm_wm8960_audio_map[]={
        12. /*Connectionstothe...*/
        13. {"AudioOut1",NULL,"HP_L"},
        14. {"AudioOut1",NULL,"HP_R"},
        15. /*Mic*/
        16. {"LINPUT1",NULL,"MICB"},
        17. {"MICB",NULL,"myMic"},
        18. /*Linein*/
        19. {"LINPUT3",NULL,"myLineIN"},
        20. {"RINPUT3",NULL,"myLineIN"},
        21. };
        22. staticintevm_wm8960_init(structsnd_soc_pcm_runtime*rtd)
        23. {
        24. interr;
        25. structsnd_soc_codec*codec=rtd->codec;
        26. structsnd_soc_dapm_context*dapm=&codec->dapm;
        27. snd_soc_dapm_new_controls(dapm,evm_wm8960_dapm_widgets,
        28. ARRAY_SIZE(evm_wm8960_dapm_widgets));
        29. err=snd_soc_add_codec_controls(codec,evm_wm8960_controls,
        30. ARRAY_SIZE(evm_wm8960_controls));
        31. if(err<0)
        32. returnerr;
        33. snd_soc_dapm_add_routes(dapm,evm_wm8960_audio_map,
        34. ARRAY_SIZE(evm_wm8960_audio_map));
        35. snd_soc_dapm_enable_pin(dapm,"AudioOut1");
        36. snd_soc_dapm_enable_pin(dapm,"myMic");
        37. snd_soc_dapm_sync(dapm);
        38. return0;
        39. }
        Step4. 實現evm_wm8960_ops及相關函數,需要添加如下代碼:
        1. staticintevm_wm8960_hw_params(structsnd_pcm_substream*substream,
        2. structsnd_pcm_hw_params*params)
        3. {
        4. structsnd_soc_pcm_runtime*rtd=substream->private_data;
        5. structsnd_soc_dai*codec_dai=rtd->codec_dai;
        6. structsnd_soc_dai*cpu_dai=rtd->cpu_dai;
        7. structsnd_soc_card*soc_card=rtd->card;
        8. intret=0;
        9. unsignedsysclk=((structsnd_soc_card_drvdata_davinci*)
        10. snd_soc_card_get_drvdata(soc_card))->sysclk;
        11. /*setthecodecsystemclock*/
        12. ret=snd_soc_dai_set_sysclk(codec_dai,0,sysclk,SND_SOC_CLOCK_IN);
        13. if(ret<0)
        14. returnret;
        15. /*settheCPUsystemclock*/
        16. ret=snd_soc_dai_set_sysclk(cpu_dai,0,sysclk,SND_SOC_CLOCK_IN);
        17. if(ret<0)
        18. returnret;
        19. return0;
        20. }
        21. staticstructsnd_soc_opsevm_wm8960_ops={
        22. .startup=evm_startup,
        23. .shutdown=evm_shutdown,
        24. .hw_params=evm_wm8960_hw_params,
        25. };
        至此,就完成了代碼移植的全部工作,修改涉及到的三個文件是:tq335x.dts、davinci-evm.c和wm8960.c,修改后的這三個文件我會上傳到我的資源,如有需要,請去我的資源中下載。

        4. 配置內核

        完成了代碼的移植工作之后還需要對內核進一步配置。默認的內核將ALSA作為module加載,本文將編譯進內核。具體步驟如下:

        Step1. 修改sound/soc/codecs/Kconfig,添加wm8960編譯選項,修改后的內容如下:

        1. configSND_SOC_WM8960
        2. tristate"WolfsonMicroelectronicsWM8960CODEC"
        3. dependsonI2C&&INPUT
        Step2. 通過menuconfig配置內核

        執行指令:

        1. makeARCH=armCROSS_COMPILE=arm-linux-gnueabi-menuconfig
        進行如下修改:
        1. DeviceDrivers--->
        2. <*>Soundcardsupport--->
        3. <*>AdvancedLinuxSoundArchitecture--->
        4. <*>ALSAforSoCaudiosupport--->
        5. <*>SoCAudioforTexasInstrumentschipsusingeDMA(AM33XX/43XX)
        6. -*-MultichannelAudioSerialPort(McASP)support
        7. <*>SoCAudiofortheAM33XXchipbasedboards
        8. CODECdrivers--->
        9. <*>WolfsonMicroelectronicsWM8960CODEC
        重新編譯內核:
        1. makeARCH=armCROSS_COMPILE=arm-linux-gnueabi--j8

        5. 效果將編譯后的內核文件zImage和tq335x.dtb文件拷貝SD卡并啟動開發板,按任意鍵進入uboot命令模式,輸入如下指令:

        1. loadmmc0:10x88000000/boot/tq335x.dtb
        2. loadmmc0:10x82000000/boot/zImage
        3. bootz0x82000000-0x88000000
        通過上面的三條指令可以啟動內核,完整的Log信息如下:
        1. Startingkernel...
        2. [0.000000]BootingLinuxonphysicalCPU0x0
        3. [0.000000]Linuxversion3.17.2(lilianrong@smarter)(gccversion4.7.3(Ubuntu/Linaro4.7.3-12ubuntu1))#68SMPSatDec2000:03:09CST2014
        4. [0.000000]CPU:ARMv7Processor[413fc082]revision2(ARMv7),cr=10c5387d
        5. [0.000000]CPU:PIPT/VIPTnonaliasingdatacache,VIPTaliasinginstructioncache
        6. [0.000000]Machinemodel:TIAM335xEVM
        7. [0.000000]cma:Reserved16MiBat9e800000
        8. [0.000000]Memorypolicy:Datacachewriteback
        9. [0.000000]HighMemzone:1048574pagesexceedsfreesize0
        10. [0.000000]CPU:AllCPU(s)startedinSVCmode.
        11. [0.000000]AM335XES2.1(sgxneon)
        12. [0.000000]PERCPU:Embedded9pages/cpu@dfa99000s14336r8192d14336u36864
        13. [0.000000]Built1zonelistsinZoneorder,mobilitygroupingon.Totalpages:129792
        14. [0.000000]Kernelcommandline:console=ttyO0,115200n8root=/dev/mmcblk0p2rwrootfstype=ext3rootwait
        15. [0.000000]PIDhashtableentries:2048(order:1,8192bytes)
        16. [0.000000]Dentrycachehashtableentries:65536(order:6,262144bytes)
        17. [0.000000]Inode-cachehashtableentries:32768(order:5,131072bytes)
        18. [0.000000]Memory:484124K/523264Kavailable(6070Kkernelcode,666Krwdata,2444Krodata,410Kinit,8214Kbss,39140Kreserved,0Khighmem)
        19. [0.000000]Virtualkernelmemorylayout:
        20. [0.000000]vector:0xffff0000-0xffff1000(4kB)
        21. [0.000000]fixmap:0xffc00000-0xffe00000(2048kB)
        22. [0.000000]vmalloc:0xe0800000-0xff000000(488MB)
        23. [0.000000]lowmem:0xc0000000-0xe0000000(512MB)
        24. [0.000000]pkmap:0xbfe00000-0xc0000000(2MB)
        25. [0.000000]modules:0xbf000000-0xbfe00000(14MB)
        26. [0.000000].text:0xc0008000-0xc0858bc0(8515kB)
        27. [0.000000].init:0xc0859000-0xc08bf800(410kB)
        28. [0.000000].data:0xc08c0000-0xc0966b50(667kB)
        29. [0.000000].bss:0xc0966b50-0xc116c6e0(8215kB)
        30. [0.000000]HierarchicalRCUimplementation.
        31. [0.000000]RCUrestrictingCPUsfromNR_CPUS=2tonr_cpu_ids=1.
        32. [0.000000]RCU:Adjustinggeometryforrcu_fanout_leaf=16,nr_cpu_ids=1
        33. [0.000000]NR_IRQS:16nr_irqs:1616
        34. [0.000000]IRQ:FoundanINTCat0xfa200000(revision5.0)with128interrupts
        35. [0.000000]Totalof128interruptson1activecontroller
        36. [0.000000]OMAPclockeventsource:timer2at24000000Hz
        37. [0.000015]sched_clock:32bitsat24MHz,resolution41ns,wrapsevery178956969942ns
        38. [0.000061]OMAPclocksource:timer1at24000000Hz
        39. [0.000798]Console:colourdummydevice80x30
        40. [0.000849]Lockdependencyvalidator:Copyright(c)2006RedHat,Inc.,IngoMolnar
        41. [0.000858]...MAX_LOCKDEP_SUBCLASSES:8
        42. [0.000865]...MAX_LOCK_DEPTH:48
        43. [0.000873]...MAX_LOCKDEP_KEYS:8191
        44. [0.000880]...CLASSHASH_SIZE:4096
        45. [0.000887]...MAX_LOCKDEP_ENTRIES:32768
        46. [0.000894]...MAX_LOCKDEP_CHAINS:65536
        47. [0.000901]...CHAINHASH_SIZE:32768
        48. [0.000909]memoryusedbylockdependencyinfo:5167kB
        49. [0.000916]pertask-structmemoryfootprint:1152bytes
        50. [0.000956]Calibratingdelayloop...996.14BogoMIPS(lpj=4980736)
        51. [0.079039]pid_max:default:32768minimum:301
        52. [0.079431]SecurityFrameworkinitialized
        53. [0.079555]Mount-cachehashtableentries:1024(order:0,4096bytes)
        54. [0.079568]Mountpoint-cachehashtableentries:1024(order:0,4096bytes)
        55. [0.081736]CPU:Testingwritebuffercoherency:ok
        56. [0.082916]CPU0:thread-1,cpu0,socket-1,mpidr0
        57. [0.083033]Settingupstaticidentitymapfor0x805bf4f0-0x805bf560
        58. [0.086259]Broughtup1CPUs
        59. [0.086278]SMP:Totalof1processorsactivated.
        60. [0.086288]CPU:AllCPU(s)startedinSVCmode.
        61. [0.088875]devtmpfs:initialized
        62. [0.097689]VFPsupportv0.3:implementor41architecture3part30variantcrev3
        63. [0.133508]omap_hwmod:tptc0usingbrokendtdatafromedma
        64. [0.133865]omap_hwmod:tptc1usingbrokendtdatafromedma
        65. [0.134203]omap_hwmod:tptc2usingbrokendtdatafromedma
        66. [0.142102]omap_hwmod:debugss:_wait_target_disablefailed
        67. [0.200093]pinctrlcore:initializedpinctrlsubsystem
        68. [0.202608]regulator-dummy:noparameters
        69. [0.232298]NET:Registeredprotocolfamily16
        70. [0.240800]DMA:preallocated256KiBpoolforatomiccoherentallocations
        71. [0.243054]cpuidle:usinggovernorladder
        72. [0.243083]cpuidle:usinggovernormenu
        73. [0.255025]OMAPGPIOhardwareversion0.1
        74. [0.270226]omap-gpmc50000000.gpmc:couldnotfindpctldevfornode/pinmux@44e10800/nandflash_pins_s0,deferringprobe
        75. [0.270268]platform50000000.gpmc:Driveromap-gpmcrequestsprobedeferral
        76. [0.274762]hw-breakpoint:debugarchitecture0x4unsupported.
        77. [0.319722]edma-dma-engineedma-dma-engine.0:TIEDMADMAenginedriver
        78. [0.321054]vbat:5000mV
        79. [0.321851]lis3_reg:noparameters
        80. [0.325260]SCSIsubsysteminitialized
        81. [0.326060]usbcore:registerednewinterfacedriverusbfs
        82. [0.326235]usbcore:registerednewinterfacedriverhub
        83. [0.330180]usbcore:registerednewdevicedriverusb

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 定陶县| 太保市| 双鸭山市| 永吉县| 邯郸市| 顺平县| 湖南省| 宁河县| 河南省| 汉中市| 新巴尔虎左旗| 密山市| 日照市| 老河口市| 麻江县| 澄江县| 康乐县| 桂平市| 惠来县| 老河口市| 诸城市| 磴口县| 新疆| 昌图县| 南靖县| 隆昌县| 庆元县| 贡山| 荆州市| 南昌县| 云浮市| 高雄市| 百色市| 武清区| 大庆市| 钟祥市| 雷州市| 巴青县| 石泉县| 沁水县| 苏尼特右旗|