fs4412開發板學習筆記(十七)
阿新 • • 發佈:2019-01-02
# 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,
};