alsa音频架构1 (五)

2014-11-24 02:34:44 · 作者: · 浏览: 17
ard || !device_data || !ops))
return -ENXIO;
dev = kzalloc(sizeof(*dev), GFP_KERNEL); //分配声卡设备内存
if (dev == NULL) {
snd_printk(KERN_ERR "Cannot allocate device\n");
return -ENOMEM;
}
dev->card = card; //设备捆绑对象
dev->type = type; //指定设备类型
dev->state = SNDRV_DEV_BUILD; //设备状态 已创建
dev->device_data = device_data; //设备数据
dev->ops = ops; //设备操作函数集
list_add(&dev->list, &card->devices); //添加到声卡对象的设备devices链表中
return 0;
}
EXPORT_SYMBOL(snd_device_new);

int snd_device_new(struct snd_card *card, snd_device_type_t type,void *device_data, struct snd_device_ops *ops)
{
struct snd_device *dev;

if (snd_BUG_ON(!card || !device_data || !ops))
return -ENXIO;
dev = kzalloc(sizeof(*dev), GFP_KERNEL); //分配声卡设备内存
if (dev == NULL) {
snd_printk(KERN_ERR "Cannot allocate device\n");
return -ENOMEM;
}
dev->card = card; //设备捆绑对象
dev->type = type; //指定设备类型
dev->state = SNDRV_DEV_BUILD; //设备状态 已创建
dev->device_data = device_data; //设备数据
dev->ops = ops; //设备操作函数集
list_add(&dev->list, &card->devices); //添加到声卡对象的设备devices链表中
return 0;
}
EXPORT_SYMBOL(snd_device_new);这里声卡设备的snd_device_ops是传递进来的结构体指针,实际操作中一般调用以下API来创建不同类型的声卡

1.1 创建声卡设备常见API

[cpp]
snd_ctl_create -->snd_device_new(card, SNDRV_DEV_CONTROL, card, &ops);
snd_card_proc_new -->snd_device_new(card, SNDRV_DEV_INFO, entry, &ops)
snd_timer_new -->snd_device_new(card, SNDRV_DEV_TIMER, timer, &ops)
snd_jack_new -->snd_device_new(card, SNDRV_DEV_JACK, jack, &ops)
snd_pcm_new -->snd_device_new(card, SNDRV_DEV_PCM, pcm, &ops)
snd_rawmidi_new -->snd_device_new(card, SNDRV_DEV_RAWMIDI, rmidi, &ops)
snd_seq_device_new -->snd_device_new(card, SNDRV_DEV_SEQUENCER, dev, &dops)
snd_hwdep_new -->snd_device_new(card, SNDRV_DEV_HWDEP, hwdep, &ops)
snd_i2c_bus_create -->snd_device_new(card, SNDRV_DEV_BUS, bus, &ops)
snd_hda_bus_new -->snd_device_new(card, SNDRV_DEV_BUS, bus, &dev_ops)
snd_ac97_bus -->snd_device_new(card, SNDRV_DEV_BUS, bus, &dev_ops)
...//不完整

snd_ctl_create -->snd_device_new(card, SNDRV_DEV_CONTROL, card, &ops);
snd_card_proc_new -->snd_device_new(card, SNDRV_DEV_INFO, entry, &ops)
snd_timer_new -->snd_device_new(card, SNDRV_DEV_TIMER, timer, &ops)
snd_jack_new -->snd_device_new(card, SNDRV_DEV_JACK, jack, &ops)
snd_pcm_new -->snd_device_new(card, SNDRV_DEV_PCM, pcm, &ops)
snd_rawmidi_new -->snd_device_new(card, SNDRV_DEV_RAWMIDI, rmidi, &ops)
snd_seq_device_new -->snd_device_new(card, SNDRV_DEV_SEQUENCER, dev, &dops)
snd_hwdep_new -->snd_device_new(card, SNDRV_DEV_HWDEP, hwdep, &ops)
snd_i2c_bus_create -->snd_device_new(card, SNDRV_DEV_BUS, bus, &ops)
snd_hda_bus_new -->snd_device_new(card, SNDRV_DEV_BUS, bus, &dev_ops)
snd_ac97_bus -->snd_device_new(card, SNDRV_DEV_BUS, bus, &dev_ops)
...//不完整这些API都静态设置了对应类型的snd_device_ops结构体ops,然后调用snd_device_new并将ops传递进来
后面我们再针对不同的声卡设备类型展开分析

创建声卡设备后系统大致入下图描述

创建后的声卡设备的state值为SNDRV_DEV_BUILD

第四部分 注册声卡

1.注册声卡

[cpp]
int snd_card_register(struct snd_card *card)
{
int err;
if (snd_BUG_ON(!card))
return -EINVAL;
if (!card->card_dev) {
//创建设备文件"/sys/class/sound/cardX"
card->card_dev = device_create(sound_c