安卓声卡驱动:5.dai驱动
一 dai驱动简介
dai驱动用于驱动component上的音频接口,dai驱动通常不会单独存在,dai驱动会与component驱动一起注册。
在注册codec时,就要求提供dai驱动,而platform驱动在编写时也会根据需要,在注册platform驱动的同时调用devm_snd_soc_register_component或snd_soc_register_dais来为dai驱动单独注册。
这两个函数的差异就是snd_soc_register_dais需要自己创建一个component,而devm_snd_soc_register_component则会自动为dai创建一个单独的component。
dai driver用于管理数字音频接口,所以dai驱动中除了管理接口的函数,还会有各种音频属性,如采样率,位宽等。
dai按方向可以分为playback和capture两种,一个dai driver可以同时有playback和Capture两种接口。
二 dai驱动重要结构体
dai driver有2个重要的结构体struct snd_soc_dai_driver和dai的操作函数struct snd_soc_dai_ops
struct snd_soc_dai_driver {/* DAI description */const char *name;unsigned int id;unsigned int base;/* DAI driver callbacks */int (*probe)(struct snd_soc_dai *dai);int (*remove)(struct snd_soc_dai *dai);int (*suspend)(struct snd_soc_dai *dai);int (*resume)(struct snd_soc_dai *dai);/* compress dai */int (*compress_new)(struct snd_soc_pcm_runtime *rtd, int num);/* DAI is also used for the control bus */bool bus_control;/* ops */const struct snd_soc_dai_ops *ops;/* DAI capabilities */struct snd_soc_pcm_stream capture;struct snd_soc_pcm_stream playback;unsigned int symmetric_rates:1;unsigned int symmetric_channels:1;unsigned int symmetric_samplebits:1;/* probe ordering - for components with runtime dependencies */int probe_order;int remove_order;
};struct snd_soc_dai_ops {/** DAI clocking configuration, all optional.* Called by soc_card drivers, normally in their hw_params.*/int (*set_sysclk)(struct snd_soc_dai *dai,int clk_id, unsigned int freq, int dir);int (*set_pll)(struct snd_soc_dai *dai, int pll_id, int source,unsigned int freq_in, unsigned int freq_out);int (*set_clkdiv)(struct snd_soc_dai *dai, int div_id, int div);int (*set_bclk_ratio)(struct snd_soc_dai *dai, unsigned int ratio);/** DAI format configuration* Called by soc_card drivers, normally in their hw_params.*/int (*set_fmt)(struct snd_soc_dai *dai, unsigned int fmt);int (*xlate_tdm_slot_mask)(unsigned int slots,unsigned int *tx_mask, unsigned int *rx_mask);int (*set_tdm_slot)(struct snd_soc_dai *dai,unsigned int tx_mask, unsigned int rx_mask,int slots, int slot_width);int (*set_channel_map)(struct snd_soc_dai *dai,unsigned int tx_num, unsigned int *tx_slot,unsigned int rx_num, unsigned int *rx_slot);int (*set_tristate)(struct snd_soc_dai *dai, int tristate);/** DAI digital mute - optional.* Called by soc-core to minimise any pops.*/int (*digital_mute)(struct snd_soc_dai *dai, int mute);int (*mute_stream)(struct snd_soc_dai *dai, int mute, int stream);/** ALSA PCM audio operations - all optional.* Called by soc-core during audio PCM operations.*/int (*startup)(struct snd_pcm_substream *,struct snd_soc_dai *);void (*shutdown)(struct snd_pcm_substream *,struct snd_soc_dai *);int (*hw_params)(struct snd_pcm_substream *,struct snd_pcm_hw_params *, struct snd_soc_dai *);int (*hw_free)(struct snd_pcm_substream *,struct snd_soc_dai *);int (*prepare)(struct snd_pcm_substream *,struct snd_soc_dai *);/** NOTE: Commands passed to the trigger function are not necessarily* compatible with the current state of the dai. For example this* sequence of commands is possible: START STOP STOP.* So do not unconditionally use refcounting functions in the trigger* function, e.g. clk_enable/disable.*/int (*trigger)(struct snd_pcm_substream *, int,struct snd_soc_dai *);int (*bespoke_trigger)(struct snd_pcm_substream *, int,struct snd_soc_dai *);/** For hardware based FIFO caused delay reporting.* Optional.*/snd_pcm_sframes_t (*delay)(struct snd_pcm_substream *,struct snd_soc_dai *);
};
- name:dai的名字,在dai_link中就是依赖这个名字来指定dai接口
- ops:接口操作函数,如果是I2S接口则是I2S的控制函数,PCM接口则是PCM的控制函数。
- capture:描述dai接口的录音能力,指定声道数,采样率,位深等
- playback:描述dai接口的播放能力
- probe_order:初始化声卡时该component的probe函数调用顺序
- remove_order:卸载时的顺序
dai的注册过程
dai注册的函数是snd_soc_register_dais
/*** snd_soc_register_dais - Register a DAI with the ASoC core** @component: The component the DAIs are registered for* @dai_drv: DAI driver to use for the DAIs* @count: Number of DAIs* @legacy_dai_naming: Use the legacy naming scheme and let the DAI inherit the* parent's name.*/
static int snd_soc_register_dais(struct snd_soc_component *component,struct snd_soc_dai_driver *dai_drv, size_t count,bool legacy_dai_naming)
{struct device *dev = component->dev;struct snd_soc_dai *dai;unsigned int i;int ret;dev_dbg(dev, "ASoC: dai register %s #%Zu\n", dev_name(dev), count);component->dai_drv = dai_drv;component->num_dai = count;for (i = 0; i < count; i++) { //可以一次注册多个daidai = kzalloc(sizeof(struct snd_soc_dai), GFP_KERNEL); //为dai分配内存if (dai == NULL) {ret = -ENOMEM;goto err;}/** Back in the old days when we still had component-less DAIs,* instead of having a static name, component-less DAIs would* inherit the name of the parent device so it is possible to* register multiple instances of the DAI. We still need to keep* the same naming style even though those DAIs are not* component-less anymore.*/if (count == 1 && legacy_dai_naming && //格式化名称(dai_drv[i].id == 0 || dai_drv[i].name == NULL)) {dai->name = fmt_single_name(dev, &dai->id);} else {dai->name = fmt_multiple_name(dev, &dai_drv[i]);if (dai_drv[i].id)dai->id = dai_drv[i].id;elsedai->id = i;}if (dai->name == NULL) {kfree(dai);ret = -ENOMEM;goto err;}dai->component = component;dai->dev = dev;dai->driver = &dai_drv[i];if (!dai->driver->ops)dai->driver->ops = &null_dai_ops;list_add(&dai->list, &component->dai_list); //把dai挂到component的dai_list链表上去dev_dbg(dev, "ASoC: Registered DAI '%s'\n", dai->name);}return 0;err:snd_soc_unregister_dais(component);return ret;
}
dai driver的注册需要一个component,这个component可以是单独的component,也可以是和platform/codec共用
安卓声卡驱动:5.dai驱动相关推荐
- 安卓声卡驱动:1.ALSA简介
一 概述 安卓内核采用的是Linux内核,所以安卓也沿用了Linux内核内置的音频子系统. Linux内核的音频子系统全称是Advanced Linux Sound Architecture,简称AL ...
- 安卓声卡驱动:3.platform驱动
一 platform驱动简介 按我的理解platform驱动在ALSA里面起管理FE的作用. 什么是FE,FE即Front End,与FE相对应的另一个名词时叫BE,即Back End. 通常认为音频 ...
- linux音频驱动修复工具,Linux声卡驱动(4)——音频驱动实战
一.应用测试工具的使用 1.在external/tinyalsa下有以C语言实现的alsa的测试程序,编译后生成tinypcminfo tinyplay tinycap tinymix 四个elf格式 ...
- beast软件linux用法,声卡驱动设置 - 黑苹果驱动高手篇 MultiBeast用法进阶_Linux教程_Linux公社-Linux系统门户网站...
声卡驱动设置 Audio自然是声卡驱动设置项,这个选项包括众多板载声卡驱动,选择之前最好仔细阅读描述文件,并选择正确的声卡型号. ▲ Realtek ALC8xx 项(包括ALC8xxHDA和Appl ...
- win7(windows7旗舰版)声卡High Definition Audio驱动 (安装失败)解决方法
win7(windows7旗舰版)声卡High Definition Audio驱动 (安装失败)解决方案 前几天装了一下windows7体验一下,结果声卡驱动安装有问题,这电脑没声音我可没法活啊. ...
- 安卓驱动和linux驱动有什么不同
安卓系统可以认为是定制化的linux系统. 因而安卓驱动就是linux驱动. 相对通常所说linux系统,安卓系统多了安卓专有驱动,多了JAVA虚拟机,JAVA虚拟机,虚拟机上的应用框架和框架之上的应 ...
- win7(windows7旗舰版)声卡High Definition Audio驱动(安装失败)解决方案(Thinkpad)
申精, Definition, 声卡, 旗舰, Audio 你看到我这篇文章时候估计你快被windows7无法安装声卡驱动而崩溃了,呵呵,别急,这篇文章是你的救星,本人已经试验多台电脑,完美解决win ...
- linux驱动:音频驱动(二)ASoc
五.[ASoC声卡驱动框架] 1.ASoC将嵌入式设备的音频系统从软件层面划分为3个组件 1.1 codec驱动:音频编解码器驱动,与平台无关,实现音频控制项添加.音频接口实现.DAPM(动态音频电源 ...
- Linux 音频驱动(四) ASoC音频驱动之Machine驱动
目录 1. 基本介绍 2. 源码分析 2.1. Machine数据结构 struct snd_soc_dai_link 3. 声卡 3.1. 数据结构struct snd_soc_card 3.2. ...
最新文章
- 如何查看Linux系统下程序运行时使用的库?
- 详细解读 Prometheus 的指标类型
- 处理JSON格式的数据
- cs4 php,php dreamweaver cs4
- 【性能优化】 之 10053 事件
- java实现rtsp转rtmp
- python中的参数
- Enews博客/CMS/双模式主题源码
- 第四篇:决策树分类算法原理分析与代码实现
- Template parse errors: The pipe 'translate' could not be found
- 程序员辞职回老家山洞写代码,二年敲了 45 万行!
- 宏碁掠夺者Predator首款RGB内存条即将发售,特挑三星B-Die颗粒
- 使用vba操作工作表,实现报表汇总
- 非华为电脑使用华为一碰传破解教程
- 微信共享停车场小程序开发设计方案
- HTML网页版雷电游戏
- p5.js 交互应用实战 —— 音乐可视化(案例)
- ClickHouse在工业互联网场景的OLAP平台建设实践
- 图论及其应用 2010年期末考试 答案 总结
- Screen.SetResolution 设置分辨率
热门文章
- python 2017年12月七学习笔记
- Springboot整合WebSocket实现网页版聊天,快来围观!
- stm32 薄膜键盘原理_6.4 STM32F103ZET独立按键功能深入剖析(神舟III号)
- ULua与Unity交互原理
- ccproject西西进度计划编制软件最新版11.35发布
- 项目管理中,项目干系人的角色和责任
- coreldraw2019天气滤镜_cdr2019下载-CorelDRAW2019下载-独木成林
- 利用EXCEL提取出生年月(格式自定义)、计算年龄、判断性别
- 浅谈系统架构设计-从架构设计原理、架构设计原则、架构设计方法展开
- 如何排除网络二层环路