alsa driver--card
https://www.kernel.org/doc/html/v4.11/sound/kernel-api/writing-an-alsa-driver.html
1.创建声卡
snd_card是对声卡硬件抽象出来的结构体,几乎所有与声音相关的逻辑设备都是在snd_card的管理之下,声卡驱动的第一个动作通常就是创建一个snd_card结构体。
我们可以通过调用snd_card_new来创建一个snd_card结构体。
struct snd_card *card;
int err;
err = snd_card_new(&pci->dev, index, id, module, extra_size, &card);
/**
* snd_card_new - create and initialize a soundcard structure
* @parent: the parent device object
* @idx: card index (address) [0 ... (SNDRV_CARDS-1)]
* @xid: card identification (ASCII string)
* @module: top level module for locking
* @extra_size: allocate this extra size after the main soundcard structure
* @card_ret: the pointer to store the created card instance
*/
int snd_card_new(struct device *parent, int idx, const char *xid, struct module *module, int extra_size, struct snd_card **card_ret)
这里extra_size是为card->private_data分配的内存大小。通常private_data保存chip-specifc data.
2.创建声卡的芯片专用数据
chip-specific data包含I/O port address, its resource pointer, or the irq number等信息。
有两种方法可以来分配chip specific data.
1).通过snd_card_new实现:
struct mychip {
struct snd_card *card;
....
};
err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
sizeof(struct mychip), &card);
struct mychip *chip = card->private_data;
chip->card = card;
在snd_card_new中分配chip。并将chip和card关联起来。card结构中的private_data就是chip,chip中又包含card。
2).通过snd_device_new来将chip作为一个低阶device注册到card上。
在snd_device_new中指定extra_size为0.
struct snd_card *card;
struct mychip *chip;
err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
0, &card);
.....
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
chip->card = card;
static struct snd_device_ops ops = {
.dev_free = snd_mychip_dev_free,
};
....
snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
static int snd_mychip_dev_free(struct snd_device *device)
{
return snd_mychip_free(device->device_data);
}
/**
* snd_device_new - create an ALSA device component
* @card: the card instance
* @type: the device type, SNDRV_DEV_XXX
* @device_data: the data pointer of this device
* @ops: the operator table
*/
int snd_device_new(struct snd_card *card, enum snd_device_type type,
void *device_data, struct snd_device_ops *ops)
snd_device_new不为芯片专用数据device_data分配空间,因此在调用之前,必须为芯片专用分配空间,在ops的dev_free中定义析构函数对芯片专用数据进行析构。dev_free会在调用snd_card_free时自动调用。对于用户自定义的 device, type可以使用SNDRV_DEV_LOWLEVEL。
snd_mychip_dev_free() 是用来free前面kzmalloc的空间。
3.设置声卡驱动名字和声卡名字。
strcpy(card->driver, "My Chip");
strcpy(card->shortname, "My Own Chip 123");
sprintf(card->longname, "%s at 0x%lx irq %i",
card->shortname, chip->ioport, chip->irq);
.每一种部件的创建最终会调用snd_device_new()来生成一个snd_device实例,并把该实例链接到snd_card的devices链表中。
通常,alsa-driver的已经提供了一些常用的部件的创建函数,而不必直接调用snd_device_new(),比如: snd_pcm_new()
5.注册声卡
err = snd_card_register(card);
if (err < 0) {
snd_card_free(card);
return err;
}
具体声卡创建的例子可参考sound/sparc/amd9730.c

alsa driver--card的更多相关文章
- ALSA driver基本概念
https://blog.csdn.net/zyuanyun/article/details/59180272#t6 1.Card For each soundcard, a “card” recor ...
- ALSA driver --PCM 实例创建过程
前面已经写过PCM 实例的创建框架,我们现在来看看PCM 实例是如何创建的. 在调用snd_pcm_new时就会创建一个snd_pcm类型的PCM 实例. struct snd_pcm { struc ...
- ALSA 学习小记
对于playback snd_pcm_begin snd_pcm_commit, 貌似 commit给的frame才会使得alsa去把数据填充 转自 http://magodo.github.io/ ...
- ALSA声卡11_从零编写之调试——学习笔记
1.调试 (1)把程序拷贝到服务器上进行编译 (2)把程序放到内核上面去 重新配置内核,吧原来的声卡驱动程序去掉 a. 修改语法错误 11th_myalsa b. 配置内核去掉原来的声卡驱动 -> ...
- 36、ALSA声卡驱动和应用
(注意:内核上电的时候会把一些没运行的控制器模块的时钟都关掉,所有在写驱动的时候需要在使用的使用使用clk_get和clk_enable使能时钟) (说明:与ALSA声卡对应的是OSS架构,第二期视频 ...
- ALSA driver--Asoc
https://blog.csdn.net/zyuanyun/article/details/59170418 ALSA Asoc框架如下图: Asoc分为machine,platform,codec ...
- ALSA driver--PCM实例创建框架
在介绍PCM 之前,我们先给出创建PCM实例的框架. #include <sound/pcm.h> .... /* hardware definition */ static struct ...
- ALSA学习资料
一.内核文档 Linux Sound Subsystem Documentation 二.一些API 1.snd_pcm_period_elapsed 2.snd_pcm_lib_buffer_by ...
- Linux ALSA声卡驱动之八:ASoC架构中的Platform
1. Platform驱动在ASoC中的作用 前面几章内容已经说过,ASoC被分为Machine,Platform和Codec三大部件,Platform驱动的主要作用是完成音频数据的管理,最终通过C ...
- ALSA driver--HW Buffer
当app在调用snd_pcm_writei时,alsa core将app传来的数据搬到HW buffer(即DMA buffer)中,alsa driver从HW buffer中读取数据传输到硬件播放 ...
随机推荐
- 使用VSCode创建简单的Razor Webapp--1.入门
1.下载vscode,安装dotnet core sdk 在cmd中使用命令dotnet --version可以查看当前安装的版本 2.打开vscode,设置语言和扩展 在最左边的工具栏,点击最下面的 ...
- 机器学习作业(四)神经网络参数的拟合——Matlab实现
题目下载[传送门] 题目简述:识别图片中的数字,训练该模型,求参数θ. 第1步:读取数据文件: %% Setup the parameters you will use for this exerci ...
- [ZJOI2011] 最小割 - 最小割树
最小割树裸题 建树后,以每个点为根跑DFS求出距离矩阵,然后暴力回答询问即可 #include <bits/stdc++.h> using namespace std; #define i ...
- Redis 数据总结 (2.命令实现逻辑)
1.通过合理的Redis数据分布,实现逻辑的简化,即将部分逻辑纳入redis 连个sort表的合并,相关的资料见 http://www.redis.net.cn/order/3613.html ZIN ...
- Linux - mysql 异常:登录不上mysql数据库
问题描述 重启虚拟机之后,用命令 mysql -u root -p 登录不上 mysql 数据库,页面显示: 但是,用命令 service mysqld status 可以查看状态 解决方案 1.查看 ...
- 【动态规划】【C/C++】简单的背包问题
简单的背包问题 背包问题动态规划中非常经典的一个问题,本文只包含01背包,完全背包和多重背包.更加详尽的背包问题的讲解请参考崔添翼大神的<背包九讲> 简单的01背包 问题导入:新年到了,m ...
- js中迭代方法
基础遍历数组: for() for( in ) for(var i = 0;i<arr.length;i++){ ...
- springmvc 整合 redis
引入依赖 <!--redis--> <dependency> <groupId>redis.clients</groupId> <artifact ...
- .NET知识梳理——3.面向对象
1. 面向对象 1.1 封装.继承.多态理解 1.1.1 封装 封装就是将抽象得到的数据和行为(或功能)相结合,形成一个有机的整体,也就是将数据与操作数据的源代码进行有机的结合,形成“ ...
- 关于KMP的next函数的原理分析
KMP是上学期学数据结构时候学的,当时就没学太明白,后来又自己琢磨了几次,但始终是一知半解.今天起床了又想起来KMP,以下是思考得到的一点东西. 首先学过kmp的都知道要写两个函数,一个计算next数 ...