return minor;
}
snd_minors[minor] = preg; //填充全局snd_minors数组项
preg->dev = device_create(sound_class, device, MKDEV(major, minor),private_data, "%s", name); //创建"/dev/snd/XXX"
if (IS_ERR(preg->dev)) {
snd_minors[minor] = NULL;
mutex_unlock(&sound_mutex);
minor = PTR_ERR(preg->dev);
kfree(preg);
return minor;
}
mutex_unlock(&sound_mutex);
return 0;
}
EXPORT_SYMBOL(snd_register_device_for_dev);
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);
kfree(preg);
return minor;
}
snd_minors[minor] = preg; //填充全局snd_minors数组项
preg->dev = device_create(sound_class, device, MKDEV(major, minor),private_data, "%s", name); //创建"/dev/snd/XXX"
if (IS_ERR(preg->dev)) {
snd_minors[minor] = NULL;
mutex_unlock(&sound_mutex);
minor = PTR_ERR(preg->dev);
kfree(preg);
return minor;
}
mutex_unlock(&sound_mutex);
return 0;
}
EXPORT_SYMBOL(snd_register_device_for_dev);主要是获取次设备号,并创建设备文件,捆绑文件操作函数集合
第六部分 声卡驱动的编写框架
综合上面五个部分得出下图
编写过程为先调用snd_card_create创建声卡,接着调用创建声卡设备的API创建不同类型的声卡设备组件,接着调用snd_card_register注册声卡就行.
大致走完上面的流程后系统的框图
第七部分 声卡核心子系统的初始化工作
1.声明子系统
[cpp]
subsys_initcall(init_soundcore);
subsys_initcall(init_soundcore);2.子系统初始化
[cpp]
static int __init init_soundcore(void)
{
int rc;
rc = init_oss_soundcore();//初始化oss子系统部分
if (rc)
return rc;
sound_class = class_create(THIS_MODULE, "sound"); //创建设备类"/sys/class/sound/"
if (IS_ERR(sound_class)) {
cleanup_oss_soundcore();
return PTR_ERR(sound_class);
}
sound_class->devnode = sound_devnode; //创建设备节点的方法
return 0;
}
static int __init init_soundcore(void)
{
int rc;
rc = init_oss_soundcore();//初始化oss子系统部分
if (rc)
return rc;
sound_class = class_create(THIS_MODULE, "sound"); //创建设备类"/sys/class/sound/"
if (IS_ERR(sound_class)) {
cleanup_oss_soundcore();
return PTR_ERR(sound_class);
}
sound_class->devnode = sound_devnode; //创建设备节点的方法
return 0;
}主要初始化oss子系统部分
2.1 oss子系统初始化
[cpp]
static int __init init_oss_soundcore(void)
{
if (preclaim_oss && register_chrdev(SOUND_MAJOR, "sound", &soundcore_fops) == -1) {//创建字符设备
printk(KERN_ERR "soundcore: sound device already in use.\n");
return -EBUSY;
}
return 0;
}
static int __init init_oss_soundcore(void)
{
if (preclaim_oss && register_chrdev(SOUND_MAJOR, "sound", &soundcore_fops) == -1) {//创建字符设备
printk(KERN_ERR "soundcore: sound device already in use.\n");
r