AM335x—WM8960音效卡驅動移植
經過一段時間的除錯,終於調好了TQ335x的音效卡驅動。TQ335x採用的Codec是WM8960,本文來總結下WM8960驅動在AM335x平臺上的移植方法。Linux音效卡驅動架構有OSS和ALSA兩種架構,目前最常用的架構是ALSA,本文也使用ALSA架構對WM8960驅動進行移植。
ASoC是對ALSA驅動架構的進一步封裝。ASoC將ALSA驅動中的各模組抽象為三部分:Platform、Codec和Machine。Platform主要是平臺硬體驅動,包括SoC的IIS模組、DMA等,在本文中就是指AM335x的McASP模組及AM335x用於音訊讀寫操作的EDMA。Codec是編解碼晶片驅動,在本文中就是WM8960。Machine是用來描述單板音訊系統連線關係的驅動,在本文中其作用是將WM8960與McASP繫結起來,註冊音效卡裝置節點。由於3.17版本的核心已經帶有TI維護的McASP驅動和Wolf公司維護的WM8960驅動,因此,原理上講,我們只需要編寫Machine部分,建立WM8960與McASP的連線關係即可。不幸的是Wolf對WM8960的維護不是太完善,還需要我們進一步修改。下面我們來看下WM8960在TQ335x上的移植方法。
1. 在DTS中新增音效卡資訊
Step1. 完善sound資訊
在DTS有一個節點名為sound,該節點用來描述單板上音效卡裝置資訊,修改後的內容如下:
- sound {
- compatible = "ti,tq-evm-audio";
- ti,model = "AM335x-EVM";
- ti,audio-codec = <&wm8960>;
- ti,mcasp-controller = <&mcasp1>;
- ti,codec-clock-rate = <24576000>;
- ti,audio-routing =
- "Headphone Jack", "HP_L",
- "Headphone Jack", "HP_R",
- "LINPUT1", "Line In";
- };
(1) compatible = "ti,tq-evm-audio" --> 指定音效卡相容的裝置,與Machine驅動中的compatible匹配。
(2) ti,model = "AM335x-EVM" --> 音效卡的名稱,原則上講可以隨意指定,但最好具有一定的可讀性,這裡沒有修改。
(3) ti,audio-codec = <&wm8960> --> 指定單板使用的Codec,具體的Codec資訊由其指向的節點wm8960描述。
(4) ti,mcasp-controller = <&mcasp1> --> 指定單板使用的Codec連線到AM335x的McASP1上,McASP1的具體資訊由其指向的節點mcasp1描述。
(5) ti,codec-clock-rate = <24576000> --> 指定Codec的MCLK時鐘頻率,單位是HZ。TQ335x的Codec使用24.576MHZ的有源晶振提供MCLK,故設定為24576000。
(6) ti,audio-routing --> DAPM資訊描述,用來指定Codec與McASP的連線關係。此處若不設定,則需要在Machine驅動中進行設定。本文在這裡做了修改。
Step2. 完善Codec資訊
通過閱讀TQ335x的原理圖可知,WM8960的控制埠連線到了AM335x的I2C0埠上,因此,可以i2c0節點內新增如下資訊(類似上篇文章中觸控裝置驅動節點):
- wm8960: [email protected] {
- compatible = "wlf,wm8960";
- reg = <0x1a>;
- };
(1) compatible = "wlf,wm8960" --> 指定Codec相容裝置,與Codec驅動中的compatible匹配。
(2) reg = <0x1a> --> WM8960的I2C地址是1A,故設定為0x1a。
Step3. 完善Platform資訊
AM335x的Platform資訊主要指McASP和EMDA設定資訊。由於預設的DTS已經配置好了McASP及EDMA的大部分資訊,需要我們配置的是McASP的pinmux和i2s資訊。
(1) 修改pinmux資訊需要具體參考TQ335x的原理圖,下面是根據原理圖中的引腳連線方式修改的pinmux資訊,如果有啥不懂的可以留言討論:
- am335x_evm_audio_pins: am335x_evm_audio_pins {
- pinctrl-single,pins = <
- 0x1A0 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcasp0_aclkr.mcasp1_aclkx */
- 0x1A4 (PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcasp0_fsr.mcasp1_fsx */
- 0x1A8 (PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* mcasp0_axr1.mcasp1_axr0 */
- 0x1AC (PIN_INPUT_PULLDOWN | MUX_MODE3) /* mcasp0_ahclkx.mcasp1_axr1 */
- >;
- };
- &mcasp1 {
- pinctrl-names = "default";
- pinctrl-0 = <&am335x_evm_audio_pins>;
- status = "okay";
- op-mode = <0>; /* MCASP_IIS_MODE */
- tdm-slots = <2>;
- /* 4 serializers */
- serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */
- 1 2 0 0
- >;
- tx-num-evt = <1>;
- rx-num-evt = <1>;
- };
(1) pinctrl-0 = <&am335x_evm_audio_pins> --> 指定mcasp1的pinmux資訊。
(2) op-mode = <0> --> 指定McASP為I2S工作模式。
(3) tdm-slots = <2> --> 指定通道數。AM335x的手冊以更廣泛意義的單詞slot命名,具體到I2S介面,其含義就是Channel。
(4) serial-dir --> 指定serializer的方向。AM335x的手冊中提到每個McASP有16個serializer,但AM335x這款晶片的McAPS只有4個serializer,分別用於AXR0、AXR1、AXR2和ARX3。由於TQ335x中將AXR0作為傳送(輸出)、ARX1作為接收(輸入)且沒有ARX2和ARX3,故設定4個serial-dir為1、2、0、0(0表示沒有使用,1表示傳送,2表示接收)。
(5) tx-num-evt = <1> --> 指定傳送FIFO大小,本文設定為1。
(6) rx-num-evt = <1> --> 指定接收FIFO大小,本文設定為1。
至此,就完成了DTS的全部配置,後面我會將完整的DTS檔案上傳到我的資源。
2. Codec驅動完善
Step1. 修改Codec驅動,使其支援DTS
由於我們在DTS中指定了Codec的compatible為"wlf,wm8960",而Linux核心自帶的WM8960驅動並沒有支援新式的DTS模式關聯。修改方法很簡單,新增i2c_driver的.driver中指定of_match_table即可,修改後的程式碼片段如下:
- staticconststruct of_device_id wm8960_of_match[] = {
- { .compatible = "wlf,wm8960", },
- { }
- };
- MODULE_DEVICE_TABLE(of, wm8960_of_match);
- staticstruct i2c_driver wm8960_i2c_driver = {
- .driver = {
- .name = "wm8960",
- .owner = THIS_MODULE,
- .of_match_table = wm8960_of_match,
- },
- .probe = wm8960_i2c_probe,
- .remove = wm8960_i2c_remove,
- .id_table = wm8960_i2c_id,
- };
預設的WM8960驅動初始化資訊不夠完整,還需要對WM8960進行額外的初始化,修改後的程式碼片段如下:
- staticint wm8960_probe(struct snd_soc_codec *codec)
- {
- struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec);
- struct wm8960_data *pdata = dev_get_platdata(codec->dev);
- int ret;
- wm8960->set_bias_level = wm8960_set_bias_level_out3;
- if (!pdata) {
- dev_warn(codec->dev, "No platform data supplied\n");
- } else {
- if (pdata->capless)
- wm8960->set_bias_level = wm8960_set_bias_level_capless;
- }
- ret = wm8960_reset(codec);
- if (ret < 0) {
- dev_err(codec->dev, "Failed to issue reset\n");
- return ret;
- }
- wm8960->set_bias_level(codec, SND_SOC_BIAS_STANDBY);
- /* Latch the update bits */
- snd_soc_update_bits(codec, WM8960_LINVOL, 0x100, 0x100);
- snd_soc_update_bits(codec, WM8960_RINVOL, 0x100, 0x100);
- snd_soc_update_bits(codec, WM8960_LADC, 0x100, 0x100);
- snd_soc_update_bits(codec, WM8960_RADC, 0x100, 0x100);
- snd_soc_update_bits(codec, WM8960_LDAC, 0x100, 0x100);
- snd_soc_update_bits(codec, WM8960_RDAC, 0x100, 0x100);
- snd_soc_update_bits(codec, WM8960_LOUT1, 0x100, 0x100);
- snd_soc_update_bits(codec, WM8960_ROUT1, 0x100, 0x100);
- snd_soc_update_bits(codec, WM8960_LOUT2, 0x100, 0x100);
- snd_soc_update_bits(codec, WM8960_ROUT2, 0x100, 0x100);
- /* other configuration */
- snd_soc_update_bits(codec, WM8960_POWER1, 0x1ea, 0x1ea);
- snd_soc_update_bits(codec, WM8960_POWER2, 0x1f8, 0x1f8);
- snd_soc_update_bits(codec, WM8960_POWER3, 0xcc, 0xcc);
- snd_soc_update_bits(codec, WM8960_LOUTMIX, 0x100, 0x100);
- snd_soc_update_bits(codec, WM8960_ROUTMIX, 0x100, 0x100);
- snd_soc_update_bits(codec, WM8960_POWER3, 0xc, 0xc);
- snd_soc_update_bits(codec, WM8960_LOUT1, 0x7f, 0x7f);
- snd_soc_update_bits(codec, WM8960_ROUT1, 0x7f, 0x7f);
- snd_soc_update_bits(codec, WM8960_IFACE2, 0x40, 0x40);
- snd_soc_update_bits(codec, WM8960_MONOMIX2, 0x120, 0x120);
- snd_soc_update_bits(codec, WM8960_LINPATH, 0x1f8, 0x138);
- snd_soc_update_bits(codec, WM8960_LINVOL, 0x19f, 0x11f);
- snd_soc_update_bits(codec, WM8960_RINVOL, 0x19f, 0x11f);
- snd_soc_update_bits(codec, WM8960_LOUT2, 0x1ff, 0x1ff);
- snd_soc_update_bits(codec, WM8960_ROUT2, 0x1ff, 0x1ff);
- snd_soc_update_bits(codec, WM8960_CLASSD3, 0x1a, 0x12);
- snd_soc_update_bits(codec, WM8960_CLASSD1, 0xc0, 0xc0);
- snd_soc_add_codec_controls(codec, wm8960_snd_controls,
- ARRAY_SIZE(wm8960_snd_controls));
- wm8960_add_widgets(codec);
- return 0;
- }
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新增如下兩行資訊:
- { "Left DAC", NULL, "Left Input Mixer" },
- { "Right DAC", NULL, "Right Input Mixer" },
由於除錯時間比較長,可能有些修改我沒有描述到,完整的wm8960.c檔案我會一併上傳到我的資源,可以下載參考。
3. 編寫Machine驅動
核心程式碼有個很好的例子就是davinci-evm.c,這是am335x-evm評估板的Machine驅動,該評估採用的Codec並不是WM8960,因此,我們在該檔案中新增WM8960資訊即可。具體的修改如下:
Step1. 新增compatible資訊。修改後的內容如下:
- staticconststruct of_device_id davinci_evm_dt_ids[] = {
- {
- .compatible = "ti,tq-evm-audio",
- .data = (void *) &evm_dai_wm8960,
- },
- {
- .compatible = "ti,da830-evm-audio",
- .data = (void *) &evm_dai_tlv320aic3x,
- },
- { /* sentinel */ }
- };
- staticstruct snd_soc_dai_link evm_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裝置名稱,與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相關的設定,本人理解也不是非常深刻,直接貼上程式碼,具體如下:
- staticconststruct snd_soc_dapm_widget evm_wm8960_dapm_widgets[] = {
- SND_SOC_DAPM_SPK("Audio Out1", NULL),
- SND_SOC_DAPM_MIC("my Mic", NULL),
- SND_SOC_DAPM_MIC("my Line IN", NULL),
- };
- staticconststruct snd_kcontrol_new evm_wm8960_controls[] = {
- SOC_DAPM_PIN_SWITCH("Audio Out1"),
- SOC_DAPM_PIN_SWITCH("my Mic"),
- SOC_DAPM_PIN_SWITCH("my Line IN"),
- };
- staticconststruct snd_soc_dapm_route evm_wm8960_audio_map[] = {
- /* Connections to the ... */
- {"Audio Out1", NULL, "HP_L"},
- {"Audio Out1", NULL, "HP_R"},
- /* Mic */
- {"LINPUT1", NULL, "MICB"},
- {"MICB", NULL, "my Mic"},
- /* Line in */
- {"LINPUT3", NULL, "my Line IN"},
- {"RINPUT3", NULL, "my Line IN"},
- };
- staticint evm_wm8960_init(struct snd_soc_pcm_runtime *rtd)
- {
- int err;
- struct snd_soc_codec *codec = rtd->codec;
- struct snd_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)
- return err;
- snd_soc_dapm_add_routes(dapm, evm_wm8960_audio_map,
- ARRAY_SIZE(evm_wm8960_audio_map));
- snd_soc_dapm_enable_pin(dapm, "Audio Out1");
- snd_soc_dapm_enable_pin(dapm, "my Mic");
- snd_soc_dapm_sync( dapm );
- return 0;
- }
- staticint evm_wm8960_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *params)
- {
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = rtd->codec_dai;
- struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- struct snd_soc_card *soc_card = rtd->card;
- int ret = 0;
- unsigned sysclk = ((struct snd_soc_card_drvdata_davinci *)
- snd_soc_card_get_drvdata(soc_card))->sysclk;
- /* set the codec system clock */
- ret = snd_soc_dai_set_sysclk(codec_dai, 0, sysclk, SND_SOC_CLOCK_IN);
- if (ret < 0)
- return ret;
- /* set the CPU system clock */
- ret = snd_soc_dai_set_sysclk(cpu_dai, 0, sysclk, SND_SOC_CLOCK_IN);
- if (ret < 0)
- return ret;
- return 0;
- }
- staticstruct snd_soc_ops evm_wm8960_ops = {
- .startup = evm_startup,
- .shutdown = evm_shutdown,
- .hw_params = evm_wm8960_hw_params,
- };
4. 配置核心
完成了程式碼的移植工作之後還需要對核心進一步配置。預設的核心將ALSA作為module載入,本文將編譯進核心。具體步驟如下:
Step1. 修改sound/soc/codecs/Kconfig,新增wm8960編譯選項,修改後的內容如下:
- config SND_SOC_WM8960
- tristate "Wolfson Microelectronics WM8960 CODEC"
- depends on I2C && INPUT
執行指令:
- make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- menuconfig
- Device Drivers --->
- <*> Sound card support --->
- <*> Advanced Linux Sound Architecture --->
- <*> ALSA for SoC audio support --->
- <*> SoC Audio for Texas Instruments chips using eDMA (AM33XX/43XX)
- -*- Multichannel Audio Serial Port (McASP) support
- <*> SoC Audio for the AM33XX chip based boards
- CODEC drivers --->
- <*> Wolfson Microelectronics WM8960 CODEC
- make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- -j8
5. 效果
將編譯後的核心檔案zImage和tq335x.dtb檔案拷貝SD卡並啟動開發板,按任意鍵進入uboot命令模式,輸入如下指令:- load mmc 0:1 0x88000000 /boot/tq335x.dtb
- load mmc 0:1 0x82000000 /boot/zImage
- bootz 0x82000000 - 0x88000000
- Starting kernel ...
- [ 0.000000] Booting Linux on physical CPU 0x0
- [ 0.000000] Linux version 3.17.2 ([email protected]) (gcc version 4.7.3 (Ubuntu/Linaro 4.7.3-12ubuntu1) ) #68 SMP Sat Dec 20 00:03:09 CST 2014
- [ 0.000000] CPU: ARMv7 Processor [413fc082] revision 2 (ARMv7), cr=10c5387d
- [ 0.000000] CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache
- [ 0.000000] Machine model: TI AM335x EVM
- [ 0.000000] cma: Reserved 16 MiB at 9e800000
- [ 0.000000] Memory policy: Data cache writeback
- [ 0.000000] HighMem zone: 1048574 pages exceeds freesize 0
- [ 0.000000] CPU: All CPU(s) started in SVC mode.
- [ 0.000000] AM335X ES2.1 (sgx neon )
- [ 0.000000] PERCPU: Embedded 9 pages/cpu @dfa99000 s14336 r8192 d14336 u36864
- [ 0.000000] Built 1 zonelists in Zone order, mobility grouping on. Total pages: 129792
- [ 0.000000] Kernel command line: console=ttyO0,115200n8 root=/dev/mmcblk0p2 rw rootfstype=ext3 rootwait
- [ 0.000000] PID hash table entries: 2048 (order: 1, 8192 bytes)
- [ 0.000000] Dentry cache hash table entries: 65536 (order: 6, 262144 bytes)
- [ 0.000000] Inode-cache hash table entries: 32768 (order: 5, 131072 bytes)
- [ 0.000000] Memory: 484124K/523264K available (6070K kernel code, 666K rwdata, 2444K rodata, 410K init, 8214K bss, 39140K reserved, 0K highmem)
- [ 0.000000] Virtual kernel memory layout:
- [ 0.000000] vector : 0xffff0000 - 0xffff1000 ( 4 kB)
- [ 0.000000] fixmap : 0xffc00000 - 0xffe00000 (2048 kB)
- [ 0.000000] vmalloc : 0xe0800000 - 0xff000000 ( 488 MB)
- [ 0.000000] lowmem : 0xc0000000 - 0xe0000000 ( 512 MB)
- [ 0.000000] pkmap : 0xbfe00000 - 0xc0000000 ( 2 MB)
- [ 0.000000] modules : 0xbf000000 - 0xbfe00000 ( 14 MB)
- [ 0.000000] .text : 0xc0008000 - 0xc0858bc0 (8515 kB)
- [ 0.000000] .init : 0xc0859000 - 0xc08bf800 ( 410 kB)
- [ 0.000000] .data : 0xc08c0000 - 0xc0966b50 ( 667 kB)
- [ 0.000000] .bss : 0xc0966b50 - 0xc116c6e0 (8215 kB)
- [ 0.000000] Hierarchical RCU implementation.
- [ 0.000000] RCU restricting CPUs from NR_CPUS=2 to nr_cpu_ids=1.
- [ 0.000000] RCU: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=1
- [ 0.000000] NR_IRQS:16 nr_irqs:16 16
- [ 0.000000] IRQ: Found an INTC at 0xfa200000 (revision 5.0) with 128 interrupts
- [ 0.000000] Total of 128 interrupts on 1 active controller
- [ 0.000000] OMAP clockevent source: timer2 at 24000000 Hz
- [ 0.000015] sched_clock: 32 bits at 24MHz, resolution 41ns, wraps every 178956969942ns
- [ 0.000061] OMAP clocksource: timer1 at 24000000 Hz
- [ 0.000798] Console: colour dummy device 80x30
- [ 0.000849] Lock dependency validator: Copyright (c) 2006 Red Hat, Inc., Ingo Molnar
- [ 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] memory used by lock dependency info: 5167 kB
- [ 0.000916] per task-struct memory footprint: 1152 bytes
- [ 0.000956] Calibrating delay loop... 996.14 BogoMIPS (lpj=4980736)
- [ 0.079039] pid_max: default: 32768 minimum: 301
- [ 0.079431] Security Framework initialized
- [ 0.079555] Mount-cache hash table entries: 1024 (order: 0, 4096 bytes)
- [ 0.079568] Mountpoint-cache hash table entries: 1024 (order: 0, 4096 bytes)
- [ 0.081736] CPU: Testing write buffer coherency: ok
- [ 0.082916] CPU0: thread -1, cpu 0, socket -1, mpidr 0
- [ 0.083033] Setting up static identity map for 0x805bf4f0 - 0x805bf560
- [ 0.086259] Brought up 1 CPUs
- [ 0.086278] SMP: Total of 1 processors activated.
- [ 0.086288] CPU: All CPU(s) started in SVC mode.
- [ 0.088875] devtmpfs: initialized
- [ 0.097689] VFP support v0.3: implementor 41 architecture 3 part 30 variant c rev 3
- [ 0.133508] omap_hwmod: tptc0 using broken dt data from edma
- [ 0.133865] omap_hwmod: tptc1 using broken dt data from edma
- [ 0.134203] omap_hwmod: tptc2 using broken dt data from edma
- [ 0.142102] omap_hwmod: debugss: _wait_target_disable failed
- [ 0.200093] pinctrl core: initialized pinctrl subsystem
- [ 0.202608] regulator-dummy: no parameters
- [ 0.232298] NET: Registered protocol family 16
- [ 0.240800] DMA: preallocated 256 KiB pool for atomic coherent allocations
- [ 0.243054] cpuidle: using governor ladder
- [ 0.243083] cpuidle: using governor menu
- [ 0.255025] OMAP GPIO hardware version 0.1
- [ 0.270226] omap-gpmc 50000000.gpmc: could not find pctldev for node /[email protected]/nandflash_pins_s0, deferring probe
- [ 0.270268] platform 50000000.gpmc: Driver omap-gpmc requests probe deferral
- [ 0.274762] hw-breakpoint: debug architecture 0x4 unsupported.
- [ 0.319722] edma-dma-engine edma-dma-engine.0: TI EDMA DMA engine driver
- [ 0.321054] vbat: 5000 mV
- [ 0.321851] lis3_reg: no parameters
- [ 0.325260] SCSI subsystem initialized
- [ 0.326060] usbcore: registered new interface driver usbfs
- [ 0.326235] usbcore: registered new interface driver hub
- [ 0.330180] usbcore: registered new device driver usb
- [ 0.331021] omap_i2c 44e0b000.i2c: could not find pctldev for node /[email protected]/pinmux_i2c0_pins, deferring probe
- [ 0.331059] platform 44e0b000.i2c: Driver omap_i2c requests probe deferral
- [ 0.331115] omap_i2c 4802a000.i2c: could not find pctldev for node /[email protected]/pinmux_i2c1_pins, deferring probe
- [ 0.331139] platform 4802a000.i2c: Driver omap_i2c requests probe deferral
- [ 0.332318] Advanced Linux Sound Architecture Driver Initialized.
- [ 0.335684] Switched to clocksource timer1
- [ 0.486994] NET: Registered protocol family 2
- [ 0.488860] TCP established hash table entries: 4096 (order: 2, 16384 bytes)
- [ 0.489040] TCP bind hash table entries: 4096 (order: 5, 147456 bytes)
- [ 0.490403] TCP: Hash tables configured (established 4096 bind 4096)
- [ 0.490593] TCP: reno registered
- [ 0.490617] UDP hash table entries: 256 (order: 2, 20480 bytes)
- [ 0.490807] UDP-Lite hash table entries: 256 (order: 2, 20480 bytes)
- [ 0.491827] NET: Registered protocol family 1
- [ 0.493704] RPC: Registered named UNIX socket transport module.
- [ 0.493729] RPC: Registered udp transport module.
- [ 0.493738] RPC: Registered tcp transport module.
- [ 0.493747] RPC: Registered tcp NFSv4.1 backchannel transport module.
- [ 0.495022] hw perfevents: enabled with armv7_cortex_a8 PMU driver, 5 counters available
- [ 0.499438] futex hash table entries: 256 (order: 2, 16384 bytes)
- [ 0.504727] VFS: Disk quotas dquot_6.5.2
- [ 0.504882] Dquot-cache hash table entries: 1024 (order 0, 4096 bytes)
- [ 0.507359] NFS: Registering the id_resolver key type
- [ 0.507727] Key type id_resolver registered
- [ 0.507743] Key type id_legacy registered
- [ 0.507886] jffs2: version 2.2. (NAND) (SUMMARY) 漏 2001-2006 Red Hat, Inc.
- [ 0.508320] msgmni has been set to 977
- [ 0.513238] io scheduler noop registered
- [ 0.513269] io scheduler deadline registered
- [ 0.513341] io scheduler cfq registered (default)
- [ 0.515815] pinctrl-single 44e10800.pinmux: 142 pins at pa f9e10800 size 568
- [ 0.520975] backlight supply power not found, using dummy regulator
- [ 0.524309] Serial: 8250/16550 driver, 4 ports, IRQ sharing enabled
- [ 0.530939] omap_uart 44e09000.serial: no wakeirq for uart0
- [ 0.531575] 44e09000.serial: ttyO0 at MMIO 0x44e09000 (irq = 88, base_baud = 3000000) is a OMAP UART0
- [ 1.231857] console [ttyO0] enabled
- [ 1.241315] omap_rng 48310000.rng: OMAP Random Number Generator ver. 20
- [ 1.248987] [drm] Initialized drm 1.1.0 20060810
- [ 1.261218] [drm] Supports vblank timestamp caching Rev 2 (21.10.2013).
- [ 1.268316] [drm] No driver support for vblank timestamp query.
- [ 1.320991] Console: switching to colour frame buffer device 100x30
- [ 1.332042] tilcdc 4830e000.lcdc: fb0: frame buffer device
- [ 1.337919] tilcdc 4830e000.lcdc: registered panic notifier
- [ 1.343814] [drm] Initialized tilcdc 1.0.0 20121205 on minor 0
- [ 1.380804] brd: module loaded
- [ 1.398539] loop: module loaded
- [ 1.404724] mtdoops: mtd device (mtddev=name/number) must be supplied
- [ 1.414737] usbcore: registered new interface driver asix
- [ 1.420619] usbcore: registered new interface driver ax88179_178a
- [ 1.427154] usbcore: registered new interface driver cdc_ether
- [ 1.433416] usbcore: registered new interface driver smsc95xx
- [ 1.439572] usbcore: registered new interface driver net1080
- [ 1.445625] usbcore: registered new interface driver cdc_subset
- [ 1.451932] usbcore: registered new interface driver zaurus
- [ 1.457997] usbcore: registered new interface driver cdc_ncm
- [ 1.465136] usbcore: registered new interface driver cdc_wdm
- [ 1.471412] usbcore: registered new interface driver usb-storage
- [ 1.477942] usbcore: registered new interface driver usbtest
- [ 1.486105] mousedev: PS/2 mouse device common for all mice
- [ 1.496690] omap_rtc 44e3e000.rtc: rtc core: registered 44e3e000.rtc as rtc0
- [ 1.504827] i2c /dev entries driver
- [ 1.508655] Driver for 1-wire Dallas network protocol.
- [ 1.517293] omap_wdt: OMAP Watchdog Timer Rev 0x01: initial timeout 60 sec
- [ 1.527282] omap_hsmmc 48060000.mmc: unable to get vmmc regulator -517
- [ 1.534612] platform 48060000.mmc: Driver omap_hsmmc requests probe deferral
- [ 1.544215] ledtrig-cpu: registered to indicate activity on CPUs
- [ 1.551195] usbcore: registered new interface driver usbhid
- [ 1.557065] usbhid: USB HID core driver
- [ 1.575960] davinci_evm sound: ASoC: CODEC (null) not registered
- [ 1.582524] davinci_evm sound: snd_soc_register_card failed (-517)
- [ 1.589121] platform sound: Driver davinci_evm requests probe deferral
- [ 1.596830] oprofile: using arm/armv7
- [ 1.601311] TCP: cubic registered
- [ 1.604789] Initializing XFRM netlink socket
- [ 1.609445] NET: Registered protocol family 17
- [ 1.614179] NET: Registered protocol family 15
- [ 1.619196] Key type dns_resolver registered
- [ 1.623867] omap_voltage_late_init: Voltage driver support not added
- [ 1.630565] sr_dev_init: No voltage domain specified for smartreflex0. Cannot initialize
- [ 1.639038] sr_dev_init: No voltage domain specified for smartreflex1. Cannot initialize
- [ 1.648614] ThumbEE CPU extension supported.
- [ 1.653130] Registering SWP/SWPB emulation handler
- [ 1.658211] SmartReflex Class3 initialized
- [ 1.667886] omap-gpmc 50000000.gpmc: GPMC revision 6.0
- [ 1.674877] nand: device found, Manufacturer ID: 0xec, Chip ID: 0xd3
- [ 1.681647] nand: Samsung NAND 1GiB 3,3V 8-bit
- [ 1.686312] nand: 1024MiB, SLC, page size: 2048, OOB size: 64
- [ 1.692312] nand: error: CONFIG_MTD_NAND_OMAP_BCH not enabled
- [ 1.698428] omap2-nand: probe of omap2-nand.0 failed with error -22
- [ 1.790962] tps65910 0-002d: No interrupt support, no core IRQ
- [ 1.807488] vrtc: 1800 mV
- [ 1.810865] vrtc: supplied by vbat
- [ 1.818190] vio: at 1500 mV
- [ 1.821460] vio: supplied by vbat
- [ 1.828397] vdd_mpu: 912 <--> 1312 mV at 1325 mV
- [ 1.833532] vdd_mpu: supplied by vbat
- [ 1.840598] vdd_core: 912 <--> 1150 mV at 1137 mV
- [ 1.845924] vdd_core: supplied by vbat
- [ 1.852537] vdd3: 5000 mV
- [ 1.858001] vdig1: at 1800 mV
- [ 1.861420] vdig1: supplied by vbat
- [ 1.867904] vdig2: at 1800 mV
- [ 1.871302] vdig2: supplied by vbat
- [ 1.878529] vpll: at 1800 mV
- [ 1.881866] vpll: supplied by vbat
- [ 1.888426] vdac: at 1800 mV
- [ 1.891747] vdac: supplied by vbat
- [ 1.898169] vaux1: at 1800 mV
- [ 1.901568] vaux1: supplied by vbat
- [ 1.908027] vaux2: at 3300 mV
- [ 1.911421] vaux2: supplied by vbat
- [ 1.917833] vaux33: at 3300 mV
- [ 1.921323] vaux33: supplied by vbat
- [ 1.927806] vmmc: 1800 <--> 3300 mV at 3300 mV
- [ 1.932761] vmmc: supplied by vbat
- [ 1.938842] vbb: at 3000 mV
- [ 1.942302] vbb: supplied by vbat
- [ 1.949841] omap_i2c 44e0b000.i2c: bus 0 rev0.11 at 400 kHz
- [ 1.963667] omap_i2c 4802a000.i2c: bus 1 rev0.11 at 100 kHz
- [ 2.007363] wm8960 0-001a: No platform data supplied
- [ 2.084399] mmc0: host does not support reading read-only switch. assuming write-enable.
- [ 2.095817] mmc0: new high speed SDHC card at address aaaa
- [ 2.104312] mmcblk0: mmc0:aaaa SL16G 14.8 GiB
- [ 2.116665] mmcblk0: p1 p2
- [ 2.131506] davinci_evm sound: wm8960-hifi <-> 4803c000.mcasp mapping ok
- [ 2.215823] davinci_mdio 4a101000.mdio: davinci mdio revision 1.6
- [ 2.222212] davinci_mdio 4a101000.mdio: detected phy mask ffffffde
- [ 2.232273] libphy: 4a101000.mdio: probed
- [ 2.236597] davinci_mdio 4a101000.mdio: phy[0]: device 4a101000.mdio:00, driver unknown
- [ 2.244957] davinci_mdio 4a101000.mdio: phy[5]: device 4a101000.mdio:05, driver unknown
- [ 2.254567] cpsw 4a100000.ethernet: Detected MACID = c4:ed:ba:88:b5:e4
- [ 2.266507] input: [email protected] as /devices/[email protected]/input/input0
- [ 2.276227] omap_rtc 44e3e000.rtc: setting system clock to 2000-01-01 00:00:00 UTC (946684800)
- [ 2.285247] sr_init: No PMIC hook to init smartreflex
- [ 2.290884] sr_init: platform driver register failed for SR
- [ 2.313832] lis3_reg: disabling
- [ 2.317496] ALSA device list:
- [ 2.320598] #0: AM335x-EVM
- [ 2.434398] kjournald starting. Commit interval 5 seconds
- [ 2.444085] EXT3-fs (mmcblk0p2): using internal journal
- [ 2.452049] EXT3-fs (mmcblk0p2): recovery complete
- [ 2.457123] EXT3-fs (mmcblk0p2): mounted filesystem with ordered data mode
- [ 2.464445] VFS: Mounted root (ext3 filesystem) on device 179:2.
- [ 2.474111] devtmpfs: mounted
- [ 2.478057] Freeing unused kernel memory: 408K (c0859000 - c08bf000)
- ----------mount all..........
- ----------Starting mdev......
- Please press Enter to activate this console.
- @tq335x #
6. 測試
測試ALSA音效卡驅動的常用方法是移植alsa-lib和alsa-utils,使用alsa-utils提供的arecord來測試音效卡的錄音,aplay來測試播放。alsa-lib和alsa-utils的移植教程有很多,這裡我就不多講了(如果有不明白這塊的可以留言)。
錄音測試:
- arecord -f cd test.wav
- aplay test.wav
7. 總結
除錯音效卡驅動大約進行了三週,也算是略有心得。
(1) 必要的工具:我除錯的時候手頭上工具不夠齊全。我是在家裡除錯的,沒有示波器,也就無法測量BCLK和LRCLK時鐘,除錯了很久都不知道WM8960到底有沒有工作,因此,必要的工具可以有效的提高除錯效率。
(2) 先除錯放音,wm8960放音再除錯錄音。放音可以很容易檢測效果,錄音則沒有方便的檢測手段。同時,放音的配置比錄音要簡單些,可以有效檢測驅動部分是否存在問題。
以上是完整的WM8960驅動移植過程,如果疑問歡迎留言討論。
相關推薦
AM335x—WM8960音效卡驅動移植
經過一段時間的除錯,終於調好了TQ335x的音效卡驅動。TQ335x採用的Codec是WM8960,本文來總結下WM8960驅動在AM335x平臺上的移植方法。Linux音效卡驅動架構有OSS和ALSA兩種架構,目前最常用的架構是ALSA,本文也使用ALSA架構對WM896
AM335x(TQ335x)學習筆記——WM8960音效卡驅動移植
經過一段時間的除錯,終於調好了TQ335x的音效卡驅動。TQ335x採用的Codec是WM8960,本文來總結下WM8960驅動在AM335x平臺上的移植方法。Linux音效卡驅動架構有OSS和ALSA兩種架構,目前最常用的架構是ALSA,本文也使用ALSA架構對WM
alsa音效卡驅動移植
1 配置核心支援UDA1341: /* 下面是需要配置的巨集,後面函式的編譯取決這些巨集 */CONFIG_SND_S3C24XX_I2S // s3c24xx-i2s.c CONFIG_SND_
Linux音效卡驅動移植和測試
一、分析驅動程式,根據開發板修改程式碼 程式碼太長,就不貼了,幾個注意點: 1、 檢視開發板原理圖和S3C2410的datasheet,UDA1341的L3MODE、L3DATA、L3CLOCK分別與S3C2410的GPB2、GPB3、GPB4相連,IISLRCK=GPE0
android下除錯音效卡驅動之wm8960介紹二
三、LINPUT輸入通道介紹 有關LINPUT的主要配置如下: R32的bit8(LMN1)置1:LINPUT1連線PGA; R0
基於S3C2440的Linux-3.6.6移植——音效卡驅動
Linux的ALSA音效卡驅動較為複雜,它需要註冊多個平臺裝置。在mach-zhaocj2440.c檔案中的平臺裝置陣列內一共有四個與ALSA相關的平臺裝置: &s3c_device_iis, &uda1340_codec, &mini2440_au
android下除錯音效卡驅動之wm8960介紹一
經過了一段時間的Android下wm8960驅動的除錯,終於實現錄音和播放功能了,在除錯過程中有了一些心得,與大家分享一 下,由於能力有限,錯誤之處還望海涵和指教。 一、總述
linux驅動編寫(音效卡驅動之asoc移植)
【 宣告:版權所有,歡迎轉載,請勿用於商業用途。 聯絡信箱:feixiaoxing @163.com】 Linux下面的音效卡驅動很複雜,根本不是一篇部落格能夠說清楚的。所以,本片文章的目的就是讓
解決win10音效卡驅動不相容問題和成功安裝戰神k650-i5-d2上的Sound Blaster Cinema2在win10系統上
安裝win10後,偶爾會出現藍屏,經過我的發現,每次聽歌用揚聲器並且長時間。都會發生藍屏 1 . 所以懷疑音效卡驅動VIA HD Audio(Win 8.1)與系統不相容。 2 .乾脆重新安裝音效卡驅動。在網上找到與win10相容的VIAHDAud_v11_1100e_01
Linux ALSA音效卡驅動之六:ASoC架構中的Machine
前面一節的內容我們提到,ASoC被分為Machine、Platform和Codec三大部分,其中的Machine驅動負責Platform和Codec之間的耦合以及部分和裝置或板子特定的程式碼,再次引用上一節的內容:Machine驅動負責處理機器特有的一些控制元件和音訊
ALSA音效卡驅動中的DAPM詳解之二:widget-具備路徑和電源管理資訊的kcontrol
上一篇文章中,我們介紹了音訊驅動中對基本控制單元的封裝:kcontrol。利用kcontrol,我們可以完成對音訊系統中的mixer,mux,音量控制,音效控制,以及各種開關量的控制,通過對各種kcontrol的控制,使得音訊硬體能夠按照我們預想的結果進行工作。同時我
ALSA音效卡驅動中的DAPM詳解之七:dapm事件機制(dapm event)
前面的六篇文章,我們已經討論了dapm關於動態電源管理的有關知識,包括widget的建立和初始化,widget之間的連線以及widget的上下電順序等等。本章我們準備討論dapm框架中的另一個機制:事件機制。通過dapm事件機制,widget可以對它所關心的dapm事
初識Linux 驅動移植 之 dm9621網絡卡驅動移植
概述 將kernel移植到開發板並能正常載入和啟動核心後,發現網絡卡並沒有工作,因此將網絡卡作為第一個移植的實踐。這篇文章用於記錄移植dm9621網絡卡過程中遇到的問題以及如何定位問題並嘗試解決。 配置核心 在找到dm9621網絡卡驅動的原始碼後,需要將其新增
關於音效卡驅動後的madplay安裝問題以及解決
安裝madplay所需要的庫檔案的時候 遇到了zlib.h找不到的原因 按照上面的內容執行會出現libz找不到的問題 後經過網上的查詢發現是Makefile中編譯器名字出現的問題 //////////////////////////////////////////////////////
音效卡驅動除錯過程
ALSA音效卡驅動 https://blog.csdn.net/droidphone/article/category/1118446 PCM(Pulse-code modulation)脈衝編碼調製,把聲音從模擬轉換成數字訊號的一種技術 https://blog.csdn.
android下除錯音效卡驅動之概述
在Android中音訊系統使用的是ALSA系統架構。ASoC--ALSA System on Chip ,是建立在標準ALSA驅動層上,為了更好地支援 嵌入式處理器和移動裝置中的音訊Cod
基於Exynos4412 cortex A9開發板的無線網絡卡驅動移植過程
移植無線網絡卡的驅動: 準備工作: 1.無線網絡卡 2.首先在這個官網上[www.realtek.com.tw](無線網絡卡),下載相應網絡卡的驅動,本次下載的名稱為: 0001RTL8188
Linux ALSA音效卡驅動之八:ASoC架構中的Platform
1. Platform驅動在ASoC中的作用 前面幾章內容已經說過,ASoC被分為Machine,Platform和Codec三大部件,Platform驅動的主要作用是完成音訊資料的管理,最終通過CPU的數字音訊介面(DAI)把音訊資料傳送給Codec進行處理,最終由Co
ALSA音效卡驅動中的DAPM詳解之五:建立widget之間的連線關係
前面我們主要著重於codec、platform、machine驅動程式中如何使用和建立dapm所需要的widget,route,這些是音訊驅動開發人員必須要了解的內容,經過前幾章的介紹,我們應該知道如何在alsa音訊驅動的3大部分(codec、platform、machin
android 音訊系統/音效卡驅動 codec
0. 專用術語 1. 物理結構 2. 系統架構 本文基於Freescale IMX平臺Codec ALC5625為例。 0. 專用術語 ASLA - Advanced Sound Linux Architecture OSS - 以前的Linux音訊體系結構,被ASL