alsa音频架构1 (七)

2014-11-24 02:34:44 · 作者: · 浏览: 18
((err = dev->ops->dev_register(dev)) < 0) //调用声卡设备的dev_register方法
return err;
dev->state = SNDRV_DEV_REGISTERED; //修改状态为已注册
}
}
return 0;
}这里会遍历声卡对象的devices设备链表,然后调用声卡设备所捆绑的声卡设备操作函数集合的dev_register方法,注册初始化对应的声卡设备

注册完声卡后,声卡设备的state值修改为SNDRV_DEV_REGISTERED


第五部分 注册声卡设备

不同类型的声卡设备的操作函数集的dev_register不同,但是也有其共性,下面主要是针对共性来分析

1.snd_minor声卡字符设备结构体


[cpp]
struct snd_minor {
int type; //声卡设备类型 SNDRV_DEVICE_TYPE_XXX
int card; //声卡索引号
int device; /* device number */
const struct file_operations *f_ops; //文件操作函数集
void *private_data; //私有数据
struct device *dev; //设备文件
};

struct snd_minor {
int type; //声卡设备类型 SNDRV_DEVICE_TYPE_XXX
int card; //声卡索引号
int device; /* device number */
const struct file_operations *f_ops; //文件操作函数集
void *private_data; //私有数据
struct device *dev; //设备文件
};1.1 snd_minor的type类型[cpp] view plaincopyprint enum {
SNDRV_DEVICE_TYPE_CONTROL, //控制
SNDRV_DEVICE_TYPE_SEQUENCER, //音序器
SNDRV_DEVICE_TYPE_TIMER, //定时器
SNDRV_DEVICE_TYPE_HWDEP, //硬件依赖层
SNDRV_DEVICE_TYPE_RAWMIDI, //raw midi
SNDRV_DEVICE_TYPE_PCM_PLAYBACK, //PCM回放
SNDRV_DEVICE_TYPE_PCM_CAPTURE, //PCM捕捉
};

enum {
SNDRV_DEVICE_TYPE_CONTROL, //控制
SNDRV_DEVICE_TYPE_SEQUENCER, //音序器
SNDRV_DEVICE_TYPE_TIMER, //定时器
SNDRV_DEVICE_TYPE_HWDEP, //硬件依赖层
SNDRV_DEVICE_TYPE_RAWMIDI, //raw midi
SNDRV_DEVICE_TYPE_PCM_PLAYBACK, //PCM回放
SNDRV_DEVICE_TYPE_PCM_CAPTURE, //PCM捕捉
};1.2 全局snd_minors全局数组,数组项最大值SNDRV_OS_MINORS为256
[cpp]
static struct snd_minor *snd_minors[SNDRV_OS_MINORS];

static struct snd_minor *snd_minors[SNDRV_OS_MINORS];

2.注册设备文件snd_register_device
封装了(2.1)snd_register_device_for_dev函数
[cpp]
static inline int snd_register_device(int type, struct snd_card *card, int dev,const struct file_operations *f_ops,void *private_data,const char *name)
{
return snd_register_device_for_dev(type, card, dev, f_ops,private_data, name,snd_card_get_device_link(card));
}

static inline int snd_register_device(int type, struct snd_card *card, int dev,const struct file_operations *f_ops,void *private_data,const char *name)
{
return snd_register_device_for_dev(type, card, dev, f_ops,private_data, name,snd_card_get_device_link(card));
}2.1注册设备文件

[cpp]
int snd_register_device_for_dev(int type, struct snd_card *card, int dev,const struct file_operations *f_ops,
void *private_data,const char *name, struct device *device)
{
int minor; //次设备号
struct snd_minor *preg; //声明一个snd_minor结构体

if (snd_BUG_ON(!name))
return -EINVAL;
preg = kmalloc(sizeof *preg, GFP_KERNEL); //分配snd_minor结构体内存
if (preg == NULL)
return -ENOMEM;
preg->type = type; //设置snd_minor类型
preg->card = card card->number : -1; //声卡索引号
preg->device = dev; //设备文件
preg->f_ops = f_ops; //文件操作函数集合
preg->private_data = private_data; //私有数据
mutex_lock(&sound_mutex);
#ifdef CONFIG_SND_DYNAMIC_MINORS
minor = snd_find_free_minor();
#else
minor = snd_kernel_minor(type, card, dev); //获取次设备号
if (minor >= 0 && snd_minors[minor])
minor = -EBUSY;
#endif
if (minor < 0) {
mutex_unlock(&sound_mutex);