1. 程式人生 > >fs4412開發板學習筆記(十七)

fs4412開發板學習筆記(十七)

 # madplay 123.mp3
 WM8960 Playback: ASoC: unmatched rate symmetry: 8000 - 44100
 output: ioctl(SNDCTL_DSP_SPEED): Invalid argument

#aplay  windowsxp.wav
 aplay: pcm_write:1939: write error: Input/output error
=====================================================
static int soc_pcm_params_symmetry(struct snd_pcm_substream *substream,
                struct
snd_pcm_hw_params *params) { struct snd_soc_dai *cpu_dai = substream->private_data->cpu_dai; rate = params_rate(params); if (symmetry && cpu_dai->rate && cpu_dai->rate != rate) { dev_err(rtd->dev, "ASoC: unmatched rate symmetry: %d - %d\n",//soc-pcm.c 157
} } || static int soc_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { ret = soc_pcm_params_symmetry(substream, params); } || int dpcm_be_dai_hw_params(struct snd_soc_pcm_runtime *fe, int stream) { struct snd_soc_dpcm *dpcm; int
ret; list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) { struct snd_soc_pcm_runtime *be = dpcm->be; struct snd_pcm_substream *be_substream =snd_soc_dpcm_get_substream(be, stream); /* copy params for each dpcm */ memcpy(&dpcm->hw_params, &fe->dpcm[stream].hw_params, sizeof(struct snd_pcm_hw_params)); ret = soc_pcm_hw_params(be_substream, &dpcm->hw_params); } || static int dpcm_fe_dai_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_soc_pcm_runtime *fe = substream->private_data; int ret, stream = substream->stream; memcpy(&fe->dpcm[substream->stream].hw_params, params, sizeof(struct snd_pcm_hw_params)); ret = dpcm_be_dai_hw_params(fe, substream->stream); } || int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num) { rtd->ops.hw_params = dpcm_fe_dai_hw_params; } || static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order) { //soc-core.c 1429 struct snd_soc_dai_link *dai_link = &card->dai_link[num]; struct snd_soc_pcm_runtime *rtd = &card->rtd[num]; ret = soc_new_pcm(rtd, num); } || static int snd_soc_instantiate_card(struct snd_soc_card *card) { /* probe all DAI links on this card */ /*probe所有音效卡上的DAI連結,主要執行兩個任務: *一是呼叫了s3c24xx_i2s_probe函式,完成i2s控制器時鐘啟動和 * s3c24xx的i2s對應的io口配置初始化; *二是執行了soc_new_pcm函式來建立PCM */ ret = soc_probe_link_dais(card, i, order); } || int snd_soc_register_card(struct snd_soc_card *card) { ret = snd_soc_instantiate_card(card); } || static int soc_probe(struct platform_device *pdev) { struct snd_soc_card *card = platform_get_drvdata(pdev); return snd_soc_register_card(card); } || static struct platform_driver soc_driver = { .driver = { .name = "soc-audio", }, .probe = soc_probe, }; || static int __init mixtile_audio_init(void) { //smdk_wm8960.c 321 mixtile_snd_device = platform_device_alloc("soc-audio", -1); } ========================= ioctl出錯: static long snd_pcm_oss_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { switch (cmd) { case SNDCTL_DSP_RESET: return snd_pcm_oss_reset(pcm_oss_file); case SNDCTL_DSP_SYNC: return snd_pcm_oss_sync(pcm_oss_file); case SNDCTL_DSP_SPEED: if (get_user(res, p)) return -EFAULT; if ((res = snd_pcm_oss_set_rate(pcm_oss_file, res))<0) return res;//定位到這裡 返回-22 sound/core/oss/pcm_oss.c 2533 return put_user(res, p); } || \/ static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream) { if ((err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_HW_PARAMS, sparams)) < 0) { //sound/core/oss/pcm_oss.c 1000 snd_printd("HW_PARAMS failed: %i\n", err); printk("snd_pcm_kernel_ioctl < 0"); goto failure; } } || static int snd_pcm_common_ioctl1(struct file *file, struct snd_pcm_substream *substream, unsigned int cmd, void __user *arg) { case SNDRV_PCM_IOCTL_HW_PARAMS: return snd_pcm_hw_params_user(substream, arg);//sound/core/pcm_native.c 2566 } || static int snd_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { if (substream->ops->hw_params != NULL) { err = substream->ops->hw_params(substream, params);//sound/core/pcm_native.c 430 if (err < 0) { goto _error; } } } || static int soc_pcm_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { ret = soc_pcm_params_symmetry(substream, params); if (ret) { printk("--%s-----%d-----\n",__FUNCTION__,__LINE__);//error <<====//sound/soc/soc-pcm.c 619 goto out; } } ========================== WM8960 Playback: ASoC: unmatched rate symmetry: 8000 - 44100 output: ioctl(SNDCTL_DSP_SPEED): Invalid argument 解決:下面的ioctl是由上面的rate不匹配造成的 cpu->rate的設定是在: wm8960.c static struct snd_soc_dai_driver wm8960_dai = { .name = "wm8960-hifi", .playback = { .stream_name = "Playback", .channels_min = 1, .channels_max = 2, .rates = WM8960_RATES,//改為SNDRV_PCM_RATE_44100 .formats = WM8960_FORMATS,}, .capture = { .stream_name = "Capture", .channels_min = 1, .channels_max = 2, .rates = WM8960_RATES, .formats = WM8960_FORMATS,}, .ops = &wm8960_dai_ops, .symmetric_rates = 1, };