imx6solo wm8960始終沒有聲音輸出


我嘗試各種辦法,wm8960始終不能得到聲音輸出。調試過程如下:

首先,打開電源使能腳:

       ret=gpio_request(SABRESD_CODEC_PWR_EN,"audio_pwr_en");

       if (!ret){

              printk("Turn on audio(wm8962)power!(1:enable)\n");

              gpio_direction_output(SABRESD_CODEC_PWR_EN,1);         // 0:enable, 1:disable  

              gpio_free(SABRESD_CODEC_PWR_EN);

       }

串口打印如下出錯信息:

wm8962 0-001a: Failed to get supply 'SPKVDD1':-19

wm8962 0-001a: Failed to request supplies: -19

wm8962 0-001a: asoc: failed to probe CODECwm8962.0-001a: -19

asoc: failed toinstantiate card wm8962-audio: -19

InitializeHDMI-audio failed. Load HDMI-video first!

ALSA device list:

  No soundcards found.

把imx6q_init_audio();后移幾行,上面的錯誤就沒有了。但出現下面錯誤 :

wm8962 0-001a: Device is not a WM8962, ID 0 !=6243

wm8962 0-001a: asoc: failed to probe CODECwm8962.0-001a: -22

asoc: failed toinstantiate card wm8962-audio: -22

把sound/soc/codec/下面的wm8962.c改用wm8960.c(修改Kconfig和Makefile)。

wm8960_i2c_probe不調用。原因是:

       .driver = {

              .name = "wm8960",

而   {

              I2C_BOARD_INFO("wm8962", 0x1a),

              .platform_data =&wm8962_config_data,

       },

linux driver是根據name來匹配的,如果匹配就調用。

登記了snd_soc_register_codec后,codec的probe也不調用。

原因是下面這個snd_dai_driver的name要一致才能調用。

static struct snd_soc_dai_driver wm8960_dai = {

       .name = "wm8960",

static structsnd_soc_dai_link imx_dai[] = {

       {

              .name = "HiFi",

              .stream_name = "HiFi",

              .codec_dai_name       = "wm8960",

調用后顯示:

wm8960 0-001a: wm8960 probed success!

wm8960 0-001a: Failed to add routeHPOUTL->Headphone Jack

asoc: wm8960<-> imx-ssi.1 mapping ok

input:wm8960-audio DMIC as /devices/platform/soc-audio.5/sound/card0/input1

input:wm8960-audio Ext Spk as /devices/platform/soc-audio.5/sound/card0/input2

ALSA device list:

  #0: wm8960-audio

root@imx6solo ~$find / -name *wm8960*

/sys/devices/platform/imx-wm8960.0

/sys/bus/platform/devices/imx-wm8960.0

/sys/bus/platform/drivers/imx-wm8960

/sys/bus/platform/drivers/imx-wm8960/imx-wm8960.0

/sys/bus/i2c/drivers/wm8960

/proc/asound/wm8960audio

root@imx6solo ~$

問題是/dev/下面並沒有增加設備,無法使用/dev/pcm。

root@imx6solo/usr/bin$ aplay -L                 

null

    Discard all samples (playback) or generatezero samples (capture)

root@imx6solo/usr/bin$ aplay -l

**** List ofPLAYBACK Hardware Devices ****

card 0:wm8960audio [wm8960-audio], device 0: HiFi wm8960-0 []

  Subdevices: 1/1

  Subdevice #0: subdevice #0

root@imx6solo/usr/bin$

 

現在應該是試試ALSA驅動程序是不是真能用的時候了. 接者就是使用它.

查看聲卡是否存在:

root@imx6solo ~$cat /proc/asound/cards

 0 [wm8960audio    ]: wm8960-audio - wm8960-audio

                      wm8960-audio

ALSA 驅動程序在 /dev/snd/ 目錄下有自己的驅動程序。

root@imx6solo ~$ ls /dev/snd/

controlC0 pcmC0D0c   pcmC0D0p  timer

http://www.alsa-project.org/main/index.php/Download上面下載alsa tester包括alsa-lib,alsa-utils。

編譯:./gitcompile CC=arm-linux-gcc --host=arm-linux

現在進化到configure都從網絡上臨時下載的地步了,我有點out了。

編譯alsa-utils總是過不去。重新下載alsaplayer。

./configure--host=arm-linux CC=arm-linux-gcc --disable-oggvorbis

然后make.

對比了wm8960.c/wm8962.c,imx-wm8960.c/imx-wm8962.c,差別其實非常大。

http://bbs.21ic.com/forum.php?mod=viewthread&tid=869393,從這個鏈接地址可以下載imx-wm8960.c。

重新配置linux kernel,設備/dev/dsp和/dev/mixer出來,這是OSS接口的要求。

root@imx6solo/test/audio$ ./wavplay test.wav

 

-------------------------------------------------------------------->

 

File Magic:         [RIFF]

File Length:        [424636]

File Type:          [WAVE]

 

Fmt Magic:          [fmt ]

Fmt Size:           [16]

Fmt Format:         [PCM]

Fmt Channels:       [2]

FmtSample_rate:    [22050](HZ),22khz

FmtBytes_p_second: [88200]

FmtBlocks_align:   [4]

FmtSample_length:  [16]

 

Chunk Type:         [data]

Chunk Length:       [424600]

 

<--------------------------------------------------------------------

 

Plug PCM: Rateconversion PCM (44100, sformat=S16_LE)

Converter:linear-interpolation

Protocol version:10002

Its setup is:

  stream      : PLAYBACK

  access      : RW_INTERLEAVED

  format      : S16_LE

  subformat   : STD

  channels    : 2

  rate        : 22050

  exact rate  : 22050 (22050/1)

  msbits      : 16

  buffer_size : 8192

  period_size : 256

  period_time : 11609

  tstamp_mode : NONE

  period_step : 1

  avail_min   : 256

  period_event : 0

  start_threshold  : 1

  stop_threshold   : 8192

  silence_threshold: 0

  silence_size : 0

  boundary    : 536870912

Slave: DirectStream Mixing PCM

Its setup is:

  stream      : PLAYBACK

  access      : MMAP_INTERLEAVED

  format      : S16_LE

  subformat   : STD

  channels    : 2

  rate        : 44100         //44khz

  exact rate  : 44100 (44100/1)

  msbits      : 16

  buffer_size : 16384

  period_size : 512

  period_time : 11609

  tstamp_mode : NONE

  period_step : 1

  avail_min   : 512

  period_event : 0

  start_threshold  : 2

  stop_threshold   : 16384

  silence_threshold: 0

  silence_size : 0

  boundary    : 1073741824

Hardware PCM card0 'wm8960-audio' device 0 subdevice 0

Its setup is:

  stream      : PLAYBACK

  access      : MMAP_INTERLEAVED

  format      : S16_LE

  subformat   : STD

  channels    : 2

  rate        : 44100         //44khz

  exact rate  : 44100 (44100/1)

  msbits      : 16

  buffer_size : 16384

  period_size : 512

  period_time : 11609

  tstamp_mode : ENABLE

  period_step : 1

  avail_min   : 512

  period_event : 0

  start_threshold  : 1

  stop_threshold   : 1073741824

  silence_threshold: 0

  silence_size : 1073741824

  boundary    : 1073741824

  appl_ptr    : 0

  hw_ptr      : 0

 

 

root@imx6solo/test/audio$ aplay test.wav

Playing WAVE'test.wav' : Signed 16 bit Little Endian, Rate 22050 Hz, Stereo

Aborted by signalInterrupt...

root@imx6solo/test/audio$

仍然是沒有聲音輸出!!

換了一個44khz采集率的wav文件,仍然沒有聲音輸出!

root@imx6solo/test/audio$ aplay xihuanni.wav

Playing WAVE'xihuanni.wav' : Signed 16 bit Little Endian, Rate 44100 Hz, Stereo

Aborted by signalInterrupt...

再次檢查了pin mux config,是正確的。但就是沒有任何audio輸出!

如果直接用imx-wm8962.c,則有許多出錯信息,如下:

root@imx6solo/test/audio$ aplay xihuanni.wav

WM8960 PLL:Unsupported N=3

Failed to startFLL: -22

Failed to setSYSCLK: -22

asoc: machinehw_params failed

Failed to setSYSCLK: -22

ALSA libpcm_direct.c:980:(snd1_pFailed to set SYSCLK: -22

cm_direct_initialize_slave)unable to install hw params

ALSA libpcm_dmix.c:1030:(snd_pcm_dmix_open) unable to initialize slave

aplay: main:660:audio open error: Invalid argument

所以,要用imx-wm8962.c來修改的話,還有點麻煩,不會很容易。

網上找了一個人交流,他用的是imx-wm8960.module,就是編譯出來的.o

ifneq ($(wildcardsound/soc/imx/imx-wm8960.c),)

snd-soc-imx-wm8960-objs:= imx-wm8960.c

else

snd-soc-imx-wm8960-objs:= imx-wm8960.module

endif

我這樣修改后,運行導致crash。

register wm8960 I2C driver success!

Unable to handlekernel paging request at virtual address f8f2fe18

pgd = 80004000

[f8f2fe18] *pgd=1bce9811, *pte=00000000,*ppte=00000000

Internal error:Oops: 807 [#1] PREEMPT

Modules linked in:

CPU: 0    Not tainted (3.0.101-2790-gc248ed7 #274)

 

 

先驗證了i2c,示波器顯示有輸出,並且測了看device addr也是0x1A。

alsamixer配置也是全部拉高,退出后重新進入,也是對的,可以保存和讀出。

i2s data仍然沒有,數據線對地電阻也測了,並沒有短路。

仔細查了linux代碼,沒有i2s部分,應該是改成SSI了。

ssi有兩個,一個是在driver/mxc/ssi.c,這個是以前的。

現在是sound/soc/imx/imx-ssi.c。

imx6q_add_imx_ssi(1,&mx6_sabresd_ssi_pdata); 注冊為platform device。

加了一句打印:

imx_ssi_probesuccessfully。證明probe是被調用了的。

root@imx6solo/test/audio$ aplay xihuanni.wav

snd_pcm_dmix_open()

snd1_pcm_hw_open_fd()

snd_pcm_plug_open()

Playing WAVE'xihuanni.wav' : Signed 16 bit Little Endian, Rate 44100 Hz, Stereo

snd_pcm_mmap_writei

snd_pcm_mmap_writei

snd_pcm_mmap_writei

snd_pcm_mmap_writei

snd_pcm_mmap_writei

snd_pcm_mmap_writei

snd_pcm_mmap_writei

snd_pcm_mmap_writei

snd_pcm_mmap_writei

snd_pcm_mmap_writei

snd_pcm_mmap_writei

snd_pcm_mmap_writei

snd_pcm_mmap_writei

snd_pcm_mmap_writei

snd_pcm_mmap_writei

snd_pcm_mmap_writei

snd_pcm_mmap_writei

snd_pcm_mmap_writei

snd_pcm_mmap_writei

snd_pcm_mmap_writei

snd_pcm_mmap_writei

snd_pcm_mmap_writei

snd_pcm_mmap_writei

snd_pcm_mmap_writei

snd_pcm_mmap_writei

snd_pcm_mmap_writei

snd_pcm_mmap_writei

snd_pcm_mmap_writei

snd_pcm_mmap_writei

snd_pcm_mmap_writei

snd_pcm_mmap_writei

snd_pcm_mmap_writei

snd_pcm_mmap_writei

然后掛起,ssi接口無輸出,應該是mixer配置不正確。

 

最終查明原因,是沒有正確初始化wm8960導致的。
在imx-wm8960.c的
static int imx_hifi_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)函數中增加:
...
wm8960_vendor_set(codec_dai);
...

/* based on the result of dump */
void wm8960_vendor_set(struct snd_soc_dai *codec_dai)
{
struct snd_soc_codec *codec = codec_dai->codec;

snd_soc_write(codec, 0x19, 0xc0); /* power1, ok*/
snd_soc_write(codec, 0x1a, 0x199); /* power2, ok*/

snd_soc_write(codec, 0x31, 0xf7); /* classd1 : enable L&R, ok */
snd_soc_write(codec, 0x33, 0x11b); /* classd3 : volume max, ok */

snd_soc_write(codec, 0x28, 0x179); /* ok */
snd_soc_write(codec, 0x29, 0x179); /* ok */

snd_soc_write(codec, 0x22, 0x100); /* dac to mixer, ok */
snd_soc_write(codec, 0x25, 0x100); /* dac to mixer, ok */

snd_soc_write(codec, 0x2f, 0x0c); /* left & right output mixer enable, ok */
snd_soc_write(codec, 0x05, 0x00); /* ok */
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM