记录看alsa源码的过程
1.alsa驱动的设备文件
在/dev/snd下可以看到当前系统中声卡的设备文件,全是字符设备。
controlC0:声卡0的控制接口
pcmC0D0c:声卡0的PCM录音接口
pcmC0D0p:声卡0的PCM播放接口
C0D0代表的是声卡0中的设备0,pcmC0D0c最后一个c代表capture,pcmC0D0p最后一个p代表playback。
2.注册alsa字符设备
sound/core/sound.c
static int __init alsa_sound_init(void)
{
snd_major = major;
snd_ecards_limit = cards_limit;
if (register_chrdev(major, "alsa", &snd_fops)) {
pr_err("ALSA core: unable to register native major device number %d\n", major);
return -EIO;
}
if (snd_info_init() < 0) {
unregister_chrdev(major, "alsa");
return -ENOMEM;
}
#ifndef MODULE
pr_info("Advanced Linux Sound Architecture Driver Initialized.\n");
#endif
return 0;
}
在/proc/devices下会出现alsa设备的主设备号“116 alsa”
3.注册声卡设备的控制接口
sound/core/control.c
int snd_ctl_create(struct snd_card *card)
{
static struct snd_device_ops ops = {
.dev_free = snd_ctl_dev_free,
.dev_register = snd_ctl_dev_register,
.dev_disconnect = snd_ctl_dev_disconnect,
};
int err;
if (snd_BUG_ON(!card))
return -ENXIO;
if (snd_BUG_ON(card->number < 0 || card->number >= SNDRV_CARDS))
return -ENXIO;
snd_device_initialize(&card->ctl_dev, card);
dev_set_name(&card->ctl_dev, "controlC%d", card->number);
err = snd_device_new(card, SNDRV_DEV_CONTROL, card, &ops);
if (err < 0)
put_device(&card->ctl_dev);
return err;
}
4.注册声卡的数据接口
sound/core/pcm.c