AM335x(TQ335x)學(xué)習(xí)筆記——WM8960聲卡驅(qū)動(dòng)移植
Step3. 調(diào)整WM8960驅(qū)動(dòng)結(jié)構(gòu)
內(nèi)核中自帶的WM8960驅(qū)動(dòng)結(jié)構(gòu)很舊,編寫Machine是需要過多的了解Codec芯片內(nèi)部細(xì)節(jié),本文對(duì)WM8960的驅(qū)動(dòng)結(jié)構(gòu)進(jìn)行了調(diào)整,可以使Machine忽略Codec的內(nèi)部細(xì)節(jié)。
修改的大體內(nèi)容如下:
(1) 添加set_sysclk函數(shù),接收Machine設(shè)置的sysclk時(shí)鐘頻率。具體本文就是DTS中設(shè)置的24576000。
(2) 在hw_params中添加BCLK、DACCLK、ADCCLK的配置操作。hw_params可以根據(jù)參數(shù)和sysclk對(duì)以上參數(shù)進(jìn)行設(shè)置,放在這里很合適。
(3) 去除函數(shù)wm8960_set_dai_clkdiv,并將wm8960_set_dai_pll設(shè)置為驅(qū)動(dòng)內(nèi)部函數(shù),不作為set_pll接口提供給內(nèi)核驅(qū)動(dòng)(實(shí)際上內(nèi)核驅(qū)動(dòng)也不調(diào)用這個(gè)函數(shù))。
Step4. 修改WM8960的route信息
根據(jù)TQ335x的原理圖可知,使用WM8960進(jìn)行錄音或放音時(shí)使用的LRCLK是同一個(gè),都是DACCLK,故在snd_soc_dapm_route添加如下兩行信息:
- {"LeftDAC",NULL,"LeftInputMixer"},
- {"RightDAC",NULL,"RightInputMixer"},
由于調(diào)試時(shí)間比較長,可能有些修改我沒有描述到,完整的wm8960.c文件我會(huì)一并上傳到我的資源,可以下載參考。
3. 編寫Machine驅(qū)動(dòng)
內(nèi)核代碼有個(gè)很好的例子就是davinci-evm.c,這是am335x-evm評(píng)估板的Machine驅(qū)動(dòng),該評(píng)估采用的Codec并不是WM8960,因此,我們?cè)谠撐募刑砑覹M8960信息即可。具體的修改如下:
Step1. 添加compatible信息。修改后的內(nèi)容如下:
- staticconststructof_device_iddavinci_evm_dt_ids[]={
- {
- .compatible="ti,tq-evm-audio",
- .data=(void*)&evm_dai_wm8960,
- },
- {
- .compatible="ti,da830-evm-audio",
- .data=(void*)&evm_dai_tlv320aic3x,
- },
- {/*sentinel*/}
- };
- staticstructsnd_soc_dai_linkevm_dai_wm8960={
- .name="wm8960",
- .stream_name="wm8960-hifi",
- .codec_dai_name="wm8960-hifi",
- .ops=&evm_wm8960_ops,
- .init=evm_wm8960_init,
- .dai_fmt=SND_SOC_DAIFMT_I2S|SND_SOC_DAIFMT_CBM_CFM|
- SND_SOC_DAIFMT_NB_NF,
- };
(1) codec_dai_name = "wm8960-hifi" --> 指定codec設(shè)備名稱,與wm8960.c中指定的相同即可。
(2) ops --> 指定wm8960的各種操作函數(shù),本文僅實(shí)現(xiàn)了hw_params函數(shù)。
(3) init --> 指定wm8960的初始化函數(shù),主要是完成dapm相關(guān)的初始化。
(4) dai_fmt --> 指定音頻的接口方式、主從關(guān)系和時(shí)鐘翻轉(zhuǎn)信息。SND_SOC_DAIFMT_I2S表示音頻接口采用I2S協(xié)議;SND_SOC_DAIFMT_CBM_CFM表示Codec的BCLK為Master,LRCLK為Master,即wm8960為主,AM335x為從;SND_SOC_DAIFMT_NB_NF表示BCLK和LRCLK都不需要翻轉(zhuǎn)。
Step3.實(shí)現(xiàn)evm_wm8960_init
這一部分主要是dapm相關(guān)的設(shè)置,本人理解也不是非常深刻,直接貼上代碼,具體如下:
- staticconststructsnd_soc_dapm_widgetevm_wm8960_dapm_widgets[]={
- SND_SOC_DAPM_SPK("AudioOut1",NULL),
- SND_SOC_DAPM_MIC("myMic",NULL),
- SND_SOC_DAPM_MIC("myLineIN",NULL),
- };
- staticconststructsnd_kcontrol_newevm_wm8960_controls[]={
- SOC_DAPM_PIN_SWITCH("AudioOut1"),
- SOC_DAPM_PIN_SWITCH("myMic"),
- SOC_DAPM_PIN_SWITCH("myLineIN"),
- };
- staticconststructsnd_soc_dapm_routeevm_wm8960_audio_map[]={
- /*Connectionstothe...*/
- {"AudioOut1",NULL,"HP_L"},
- {"AudioOut1",NULL,"HP_R"},
- /*Mic*/
- {"LINPUT1",NULL,"MICB"},
- {"MICB",NULL,"myMic"},
- /*Linein*/
- {"LINPUT3",NULL,"myLineIN"},
- {"RINPUT3",NULL,"myLineIN"},
- };
- staticintevm_wm8960_init(structsnd_soc_pcm_runtime*rtd)
- {
- interr;
- structsnd_soc_codec*codec=rtd->codec;
- structsnd_soc_dapm_context*dapm=&codec->dapm;
- snd_soc_dapm_new_controls(dapm,evm_wm8960_dapm_widgets,
- ARRAY_SIZE(evm_wm8960_dapm_widgets));
- err=snd_soc_add_codec_controls(codec,evm_wm8960_controls,
- ARRAY_SIZE(evm_wm8960_controls));
- if(err<0)
- returnerr;
- snd_soc_dapm_add_routes(dapm,evm_wm8960_audio_map,
- ARRAY_SIZE(evm_wm8960_audio_map));
- snd_soc_dapm_enable_pin(dapm,"AudioOut1");
- snd_soc_dapm_enable_pin(dapm,"myMic");
- snd_soc_dapm_sync(dapm);
- return0;
- }
- staticintevm_wm8960_hw_params(structsnd_pcm_substream*substream,
- structsnd_pcm_hw_params*params)
- {
- structsnd_soc_pcm_runtime*rtd=substream->private_data;
- structsnd_soc_dai*codec_dai=rtd->codec_dai;
- structsnd_soc_dai*cpu_dai=rtd->cpu_dai;
- structsnd_soc_card*soc_card=rtd->card;
- intret=0;
- unsignedsysclk=((structsnd_soc_card_drvdata_davinci*)
- snd_soc_card_get_drvdata(soc_card))->sysclk;
- /*setthecodecsystemclock*/
- ret=snd_soc_dai_set_sysclk(codec_dai,0,sysclk,SND_SOC_CLOCK_IN);
- if(ret<0)
- returnret;
- /*settheCPUsystemclock*/
- ret=snd_soc_dai_set_sysclk(cpu_dai,0,sysclk,SND_SOC_CLOCK_IN);
- if(ret<0)
- returnret;
- return0;
- }
- staticstructsnd_soc_opsevm_wm8960_ops={
- .startup=evm_startup,
- .shutdown=evm_shutdown,
- .hw_params=evm_wm8960_hw_params,
- };
4. 配置內(nèi)核
完成了代碼的移植工作之后還需要對(duì)內(nèi)核進(jìn)一步配置。默認(rèn)的內(nèi)核將ALSA作為module加載,本文將編譯進(jìn)內(nèi)核。具體步驟如下:
Step1. 修改sound/soc/codecs/Kconfig,添加wm8960編譯選項(xiàng),修改后的內(nèi)容如下:
- configSND_SOC_WM8960
- tristate"WolfsonMicroelectronicsWM8960CODEC"
- dependsonI2C&&INPUT
執(zhí)行指令:
- makeARCH=armCROSS_COMPILE=arm-linux-gnueabi-menuconfig
- DeviceDrivers--->
- <*>Soundcardsupport--->
- <*>AdvancedLinuxSoundArchitecture--->
- <*>ALSAforSoCaudiosupport--->
- <*>SoCAudioforTexasInstrumentschipsusingeDMA(AM33XX/43XX)
- -*-MultichannelAudioSerialPort(McASP)support
- <*>SoCAudiofortheAM33XXchipbasedboards
- CODECdrivers--->
- <*>WolfsonMicroelectronicsWM8960CODEC
- makeARCH=armCROSS_COMPILE=arm-linux-gnueabi--j8
5. 效果將編譯后的內(nèi)核文件zImage和tq335x.dtb文件拷貝SD卡并啟動(dòng)開發(fā)板,按任意鍵進(jìn)入uboot命令模式,輸入如下指令:
- loadmmc0:10x88000000/boot/tq335x.dtb
- loadmmc0:10x82000000/boot/zImage
- bootz0x82000000-0x88000000
- Startingkernel...
- [0.000000]BootingLinuxonphysicalCPU0x0
- [0.000000]Linuxversion3.17.2(lilianrong@smarter)(gccversion4.7.3(Ubuntu/Linaro4.7.3-12ubuntu1))#68SMPSatDec2000:03:09CST2014
- [0.000000]CPU:ARMv7Processor[413fc082]revision2(ARMv7),cr=10c5387d
- [0.000000]CPU:PIPT/VIPTnonaliasingdatacache,VIPTaliasinginstructioncache
- [0.000000]Machinemodel:TIAM335xEVM
- [0.000000]cma:Reserved16MiBat9e800000
- [0.000000]Memorypolicy:Datacachewriteback
- [0.000000]HighMemzone:1048574pagesexceedsfreesize0
- [0.000000]CPU:AllCPU(s)startedinSVCmode.
- [0.000000]AM335XES2.1(sgxneon)
- [0.000000]PERCPU:Embedded9pages/cpu@dfa99000s14336r8192d14336u36864
- [0.000000]Built1zonelistsinZoneorder,mobilitygroupingon.Totalpages:129792
- [0.000000]Kernelcommandline:console=ttyO0,115200n8root=/dev/mmcblk0p2rwrootfstype=ext3rootwait
- [0.000000]PIDhashtableentries:2048(order:1,8192bytes)
- [0.000000]Dentrycachehashtableentries:65536(order:6,262144bytes)
- [0.000000]Inode-cachehashtableentries:32768(order:5,131072bytes)
- [0.000000]Memory:484124K/523264Kavailable(6070Kkernelcode,666Krwdata,2444Krodata,410Kinit,8214Kbss,39140Kreserved,0Khighmem)
- [0.000000]Virtualkernelmemorylayout:
- [0.000000]vector:0xffff0000-0xffff1000(4kB)
- [0.000000]fixmap:0xffc00000-0xffe00000(2048kB)
- [0.000000]vmalloc:0xe0800000-0xff000000(488MB)
- [0.000000]lowmem:0xc0000000-0xe0000000(512MB)
- [0.000000]pkmap:0xbfe00000-0xc0000000(2MB)
- [0.000000]modules:0xbf000000-0xbfe00000(14MB)
- [0.000000].text:0xc0008000-0xc0858bc0(8515kB)
- [0.000000].init:0xc0859000-0xc08bf800(410kB)
- [0.000000].data:0xc08c0000-0xc0966b50(667kB)
- [0.000000].bss:0xc0966b50-0xc116c6e0(8215kB)
- [0.000000]HierarchicalRCUimplementation.
- [0.000000]RCUrestrictingCPUsfromNR_CPUS=2tonr_cpu_ids=1.
- [0.000000]RCU:Adjustinggeometryforrcu_fanout_leaf=16,nr_cpu_ids=1
- [0.000000]NR_IRQS:16nr_irqs:1616
- [0.000000]IRQ:FoundanINTCat0xfa200000(revision5.0)with128interrupts
- [0.000000]Totalof128interruptson1activecontroller
- [0.000000]OMAPclockeventsource:timer2at24000000Hz
- [0.000015]sched_clock:32bitsat24MHz,resolution41ns,wrapsevery178956969942ns
- [0.000061]OMAPclocksource:timer1at24000000Hz
- [0.000798]Console:colourdummydevice80x30
- [0.000849]Lockdependencyvalidator:Copyright(c)2006RedHat,Inc.,IngoMolnar
- [0.000858]...MAX_LOCKDEP_SUBCLASSES:8
- [0.000865]...MAX_LOCK_DEPTH:48
- [0.000873]...MAX_LOCKDEP_KEYS:8191
- [0.000880]...CLASSHASH_SIZE:4096
- [0.000887]...MAX_LOCKDEP_ENTRIES:32768
- [0.000894]...MAX_LOCKDEP_CHAINS:65536
- [0.000901]...CHAINHASH_SIZE:32768
- [0.000909]memoryusedbylockdependencyinfo:5167kB
- [0.000916]pertask-structmemoryfootprint:1152bytes
- [0.000956]Calibratingdelayloop...996.14BogoMIPS(lpj=4980736)
- [0.079039]pid_max:default:32768minimum:301
- [0.079431]SecurityFrameworkinitialized
- [0.079555]Mount-cachehashtableentries:1024(order:0,4096bytes)
- [0.079568]Mountpoint-cachehashtableentries:1024(order:0,4096bytes)
- [0.081736]CPU:Testingwritebuffercoherency:ok
- [0.082916]CPU0:thread-1,cpu0,socket-1,mpidr0
- [0.083033]Settingupstaticidentitymapfor0x805bf4f0-0x805bf560
- [0.086259]Broughtup1CPUs
- [0.086278]SMP:Totalof1processorsactivated.
- [0.086288]CPU:AllCPU(s)startedinSVCmode.
- [0.088875]devtmpfs:initialized
- [0.097689]VFPsupportv0.3:implementor41architecture3part30variantcrev3
- [0.133508]omap_hwmod:tptc0usingbrokendtdatafromedma
- [0.133865]omap_hwmod:tptc1usingbrokendtdatafromedma
- [0.134203]omap_hwmod:tptc2usingbrokendtdatafromedma
- [0.142102]omap_hwmod:debugss:_wait_target_disablefailed
- [0.200093]pinctrlcore:initializedpinctrlsubsystem
- [0.202608]regulator-dummy:noparameters
- [0.232298]NET:Registeredprotocolfamily16
- [0.240800]DMA:preallocated256KiBpoolforatomiccoherentallocations
- [0.243054]cpuidle:usinggovernorladder
- [0.243083]cpuidle:usinggovernormenu
- [0.255025]OMAPGPIOhardwareversion0.1
- [0.270226]omap-gpmc50000000.gpmc:couldnotfindpctldevfornode/pinmux@44e10800/nandflash_pins_s0,deferringprobe
- [0.270268]platform50000000.gpmc:Driveromap-gpmcrequestsprobedeferral
- [0.274762]hw-breakpoint:debugarchitecture0x4unsupported.
- [0.319722]edma-dma-engineedma-dma-engine.0:TIEDMADMAenginedriver
- [0.321054]vbat:5000mV
- [0.321851]lis3_reg:noparameters
- [0.325260]SCSIsubsysteminitialized
- [0.326060]usbcore:registerednewinterfacedriverusbfs
- [0.326235]usbcore:registerednewinterfacedriverhub
- [0.330180]usbcore:registerednewdevicedriverusb
相關(guān)推薦
技術(shù)專區(qū)
- FPGA
- DSP
- MCU
- 示波器
- 步進(jìn)電機(jī)
- Zigbee
- LabVIEW
- Arduino
- RFID
- NFC
- STM32
- Protel
- GPS
- MSP430
- Multisim
- 濾波器
- CAN總線
- 開關(guān)電源
- 單片機(jī)
- PCB
- USB
- ARM
- CPLD
- 連接器
- MEMS
- CMOS
- MIPS
- EMC
- EDA
- ROM
- 陀螺儀
- VHDL
- 比較器
- Verilog
- 穩(wěn)壓電源
- RAM
- AVR
- 傳感器
- 可控硅
- IGBT
- 嵌入式開發(fā)
- 逆變器
- Quartus
- RS-232
- Cyclone
- 電位器
- 電機(jī)控制
- 藍(lán)牙
- PLC
- PWM
- 汽車電子
- 轉(zhuǎn)換器
- 電源管理
- 信號(hào)放大器
評(píng)論