WM8994調試要點記錄

來源:互聯網
上載者:User

這兩個禮拜調試WM8994,還算順利,除了開始LDO不大穩定造成CODEC經常性異常外。不得不感歎,有時候一個電阻阻值的大小都影響了整個系統,做硬體的同學要注意哇。

Wolfson的工程師也很nice,對於我反饋的問題,都能及時得以解答,感謝他們。

下面記錄幾個大的問題點,至於一些瑣碎的,如缺少一些mixer controls (MIC Bias)、回放錄音通路設定等就略過了。

1、線上查看/更改CODEC寄存器

mount -t debugfs none /d  //掛載debugfs檔案系統cd /d/asoc/WMT_WM8994/wm8994-codec //進入wm8994調試目錄cat codec_reg //查看wm8994寄存器echo 6 0010 > codec_reg //寫0x0010到reg[0006h]

這樣調試非常方便,有時候mixer controls還沒寫好,直接寫寄存器也能達到目的。

2、AIF模式(Master/Slave)選擇

WM8994支援Master/Slave模式,而每種模式都可使用MCLK或FLL作為AIFnCLK,所以這一塊根據自己實際情況配置好。比如我們使用如下模式:

則AIF1的hw_params這樣寫:

/* Set codec DAI configuration */ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_CBS_CFS | SND_SOC_DAIFMT_I2S);if (ret< 0)return ret;/* Set cpu DAI configuration for I2S */ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S);if (ret < 0)return ret;/* Set the codec system clock for DAC and ADC */if (!(params_rate(params) % 11025))ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_MCLK1, 11289600,    SND_SOC_CLOCK_IN);elseret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_MCLK1, 12288000,    SND_SOC_CLOCK_IN);

3、Voice DAI

在調試Voice DAI中遇到一些問題,頗為耗時的問題。

我們通話模組的設計基本就是WM8994的典型設計:

使用AIF2與MODEM的PCM介面相連。這個在Linux-3.0.8裡有個不錯的例子可以參考,見sound/soc/samsung/goni_wm8994.c。不過我們配置modem為Master,CODEC為Slave,資料格式是PCM,所以AIF2的hw_params有點變動:

static int wmt_voice_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;int ret = 0;if (params_rate(params) != 8000)return -EINVAL;/* Set codec DAI configuration */ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_A |SND_SOC_DAIFMT_IB_NF | SND_SOC_DAIFMT_CBS_CFS);if (ret < 0)return ret;/* Set the codec system clock for DAC and ADC */if (!(params_rate(params) % 11025))ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_MCLK1, 11289600,SND_SOC_CLOCK_IN);elseret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_MCLK1, 12288000,SND_SOC_CLOCK_IN);return ret;}

改好了這個後,接下去馬上發現一個很大的問題,Android啟動後打電話,無法開啟AIF2,表現在open /dev/snd/pcmC0D1(or pcmC0D1p) failed (Invalid argument)。這個問題跟了一天,通過audio_hw->tinyalsa->alsa-core一步步加列印最終定位問題所在,出錯的地方:

snd_pcm_open_substream   --> snd_pcm_attach_substream   --> substream->ops->open(substream)   --> err = snd_pcm_hw_constraints_complete(substream);           --> err = snd_pcm_hw_constraint_mask(runtime, SNDRV_PCM_HW_PARAM_ACCESS, mask);

我們看看snd_pcm_hw_constraints_complete函數:

int snd_pcm_hw_constraints_complete(struct snd_pcm_substream *substream){struct snd_pcm_runtime *runtime = substream->runtime;struct snd_pcm_hardware *hw = &runtime->hw;int err;unsigned int mask = 0;if (hw->info & SNDRV_PCM_INFO_INTERLEAVED)mask |= 1 << SNDRV_PCM_ACCESS_RW_INTERLEAVED;if (hw->info & SNDRV_PCM_INFO_NONINTERLEAVED)mask |= 1 << SNDRV_PCM_ACCESS_RW_NONINTERLEAVED;if (hw->info & SNDRV_PCM_INFO_MMAP) {if (hw->info & SNDRV_PCM_INFO_INTERLEAVED)mask |= 1 << SNDRV_PCM_ACCESS_MMAP_INTERLEAVED;if (hw->info & SNDRV_PCM_INFO_NONINTERLEAVED)mask |= 1 << SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED;if (hw->info & SNDRV_PCM_INFO_COMPLEX)mask |= 1 << SNDRV_PCM_ACCESS_MMAP_COMPLEX;}err = snd_pcm_hw_constraint_mask(runtime, SNDRV_PCM_HW_PARAM_ACCESS, mask);if (err < 0)return err;

這樣基本可以確定hw->info是空的,順藤摸瓜我們會留意struct snd_pcm_hardware這個結構體,這個東東一般是在DMA(一般是sound/soc/XXX/XXX_pcm.c)裡面設定的,如:

static const struct snd_pcm_hardware wmt_pcm_hardware = {.info= SNDRV_PCM_INFO_MMAP |  SNDRV_PCM_INFO_MMAP_VALID |  SNDRV_PCM_INFO_INTERLEAVED |  SNDRV_PCM_INFO_PAUSE |  SNDRV_PCM_INFO_RESUME,.formats= SNDRV_PCM_FMTBIT_S16_LE,.rate_min= 8000,.rate_max= 96000,.period_bytes_min= 32,.period_bytes_max= 4 * 1024,.periods_min= 2,.periods_max= 128,.buffer_bytes_max= 64 * 1024,//.fifo_size= 32,};static int wmt_pcm_open(struct snd_pcm_substream *substream){// ...snd_soc_set_runtime_hwparams(substream, &wmt_pcm_hardware);// ...}

這樣就很容易理解了,因為在goni_wm8994.c中,它根本沒有設定runtime hwparams,而我們照瓜畫瓢,自然就出錯了。因為AIF2是與MODEM PCM直連的,並不需要為它寫一個DMA驅動,因此我們在startup時設定runtime hwparams:

static const struct snd_pcm_hardware wmt_voice_hardware = {.info= SNDRV_PCM_INFO_MMAP |  SNDRV_PCM_INFO_MMAP_VALID |  SNDRV_PCM_INFO_INTERLEAVED |  SNDRV_PCM_INFO_PAUSE |  SNDRV_PCM_INFO_RESUME,.formats= SNDRV_PCM_FMTBIT_S16_LE,.rate_min= 8000,.rate_max= 16000,.period_bytes_min= 16,.period_bytes_max= 1024,.periods_min= 2,.periods_max= 16,.buffer_bytes_max= 4*1024,//.fifo_size= 32,};static int wmt_voice_startup(struct snd_pcm_substream *substream){struct snd_pcm_runtime *runtime = substream->runtime;int ret;snd_soc_set_runtime_hwparams(substream, &wmt_voice_hardware);/* Ensure that buffer size is a multiple of period size */ret = snd_pcm_hw_constraint_integer(runtime,SNDRV_PCM_HW_PARAM_PERIODS);return ret;}static struct snd_soc_ops wmt_voice_ops = {.startup   = wmt_voice_startup,.hw_params = wmt_voice_hw_params,};

這樣上層就能成功開啟AIF2,通話通路也正常了。但我還是有點困惑:三星這個方案它如何run起來的呢?我本來很信任它的,經曆了這一遭,還是要對任何權威抱有懷疑態度才行。

4、BT DAI

-------------------------------------------------------------------------------------------

2013/3/26

不想多寫了,我只想說一句:如果你以後不想被這個項目搞得心力憔悴,各種奇怪問題層出不窮,騷擾得你上天無路入地無門求生不得求死不能的話,那麼最好讓codec作主,modem作從。

在做硬體設計前,請認真閱讀WM8994規格書DIGITAL AUDIO INTERFACE CLOCKING CONFIGURATIONS:

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.