snd_soc_codec_device 之 snd_soc_new_pcms(下)

(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可以看到这部分完成的结果,如

  • controlC0 --> 用于声卡的控制,例如通道选择,混音,麦克风的控制等
  • midiC0D0 --> 用于播放midi 音频
  • pcmC0D0c --〉用于录音的pcm 设备
  • pcmC0D0p --〉用于播放的pcm 设备
  • seq --〉音序器
  • timer --〉定时器

最后把codec->card, codec_dai, pcm关联起来,完成这部分函数功能。










你可能感兴趣的:(timer,struct,Stream,终端,Codec,playback)