(2)soc_new_pcm
根据card->num_links,创建所有的pcm,主要是播放流playback 和录音流record ,每次创建新PCM都是调用
static int soc_new_pcm(struct snd_soc_device *socdev,
struct snd_soc_dai_link *dai_link, int num)
第一个参数讲过了,第二个是设备和cpu连接的结构体,在include/sound的soc.h中定义,第三个num是PCM的id
在调用snd_pcm_new之前,先生成设备字符串
sprintf(new_name, "%s %s-%d", dai_link->stream_name, codec_dai->name,
num);
生成的结果new_name作为 char *id 参数传给snd_pcm_new
int snd_pcm_new(struct snd_card *card, const char *id, int device,
int playback_count, int capture_count,
struct snd_pcm ** rpcm)
函数返回新建生成的snd_pcm指针rpcm
其实这些都是在填充结构体struct snd_pcm,上面已经做了一部分,包括id、pcm名称、card、device等的填充,代码的接下部分是
填充pcm的ops部分,
soc_pcm_ops.mmap = platform->pcm_ops->mmap;
soc_pcm_ops.pointer = platform->pcm_ops->pointer;
soc_pcm_ops.ioctl = platform->pcm_ops->ioctl;
soc_pcm_ops.copy = platform->pcm_ops->copy;
soc_pcm_ops.silence = platform->pcm_ops->silence;
soc_pcm_ops.ack = platform->pcm_ops->ack;
soc_pcm_ops.page = platform->pcm_ops->page;
填充完ops,就调用snd_pcm_set_ops把ops和音频流关联起来
if (playback)
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &soc_pcm_ops);
if (capture)
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &soc_pcm_ops);
在终端用ls /dev/snd可以看到这部分完成的结果,如
最后把codec->card, codec_dai, pcm关联起来,完成这部分函数功能。