ALSA驱动抽象:ASoc理解与分析

最近一直在研究 alsa 驱动,停了一段时间,突然发现asla 驱动不是一天两天能讲清楚的。
1. asoc 概述
asoc (alsa system on chip) ,是建立在标准alsa驱动层上,为了更好地支持嵌入式处理器和移动设备中的音频codec的一套软件体系。在asoc出现之前,内核对于soc中的音频已经有部分的支持,不过会有一些局限性:
codec驱动与soc cpu的底层耦合过于紧密,这种不理想会导致代码的重复。
音频事件没有标准的方法来通知用户,例如耳机、麦克风的插拔和检测,这些事件在移动设备中是非常普通的,而且通常都需要特定于机器的代码重新对音频路劲进行配置。
当进行播放或录音时,驱动会让整个codec处于上电状态,这对于pc没问题,但对于移动设备来说,这意味着浪费大量的电量。同时也不支持通过改变过取样频率和偏置电流来达到省电的目的。
asoc正是为了解决上述种种问题而提出的,目前已经被整合至内核的代码树中:sound/soc。asoc不能单独存在,他只是建立在标准alsa驱动上的一个它必须和标准的alsa驱动框架相结合才能工作。
2. 硬件架构
嵌入式设备的音频系统可以被划分为板载硬件(machine)、soc(platform)、codec三大部分,如下图所示:
machine :是指某一款机器,可以是某款设备,某款开发板,由此可以看出machine几乎是不可重用的,每个machine上的硬件实现可能都不一样,cpu不一样,codec不一样,音频的输入、输出设备也不一样,machine为cpu、codec、输入输出设备提供了一个载体。
platform:一般是指某一个soc平台,比如s3cxxxx,与音频相关的通常包含该soc中的时钟、dma、i2s、pcm等等,只要指定了soc,那么我们可以认为它会有一个对应的platform,它只与soc相关,与machine无关,这样我们就可以把platform抽象出来,使得同一款soc不用做任何的改动,就可以用在不同的machine中。实际上,把platform认为是某个soc更好理解。
codec:字面上的意思就是编解码器,codec里面包含了i2s接口、d/a、a/d、mixer、pa(功放),通常包含多种输入(mic、line-in、i2s、pcm)和多个输出(耳机、喇叭、听筒,line-out),codec和platform一样,是可重用的部件,同一个codec可以被不同的machine使用。嵌入式codec通常通过i2c对内部的寄存器进行控制。
注释:对于现在的很多嵌入式平台,内部集成了codec,我们在分析时也可以将其划分到codec 上,不同的soc 内部codec 有所不同,同时亦可兼容内部codec 和 外部codec。
3. 软件架构
在软件层面,asoc也把嵌入式设备的音频系统同样分为3大部分,machine,platform和codec。
machine: machine 驱动负责处理机器特有的一些控件和音频事件(例如,当播放音频时,需要先行打开一个放大器);单独的platform 和 codec驱动是不能工作的,它必须由machine驱动把它们结合在一起才能完成整个设备的音频处理工作。
platform:它包含了该soc平台的音频 dma 和音频接口的配置和控制(i2s,pcm,ac97等等);它也不能包含任何与板子或机器相关的代码。
codec : asoc 中的一个重要设计原则就是要求codec驱动是平台无关的,它包含了一些音频的控件(controls),音频接口,damp(动态音频电源管理)的定义和某些codec io功能。为了保证硬件无关性,任何特定于平台和机器的代码都要移到 platform 和machine驱动中。所有的codec驱动都要提供以下特性:
codec dai 和 pcm的配置信息;codec的io控制方式(i2c,spi等);mixer和其他的音频控件;codec的alsa音频操作接口;
必要时,也可以提供以下功能:
dapm描述信息;
dapm事件处理程序;
dac数字静音控制
4. asoc 分析
4.1 硬件抽象
通常一个声卡设备,大概包含以下几个物理设备或者外设:
codec:音频编解码控制器,可以是内部codec(soc 集成),也可以是外部codec. codec 通过支持音频编解码,包括模拟麦或者spk, 有的甚至支持数字麦。
amic/spk/dmic:纯硬件电路。麦克风或者spk,软件无需干预。
dma:对于硬件设备的数据量,大多数情况都是通过dma 搬运来提高效率。
cpu:整个soc 平台,主要提供音频通信接口来实现和codec 传输。比如(i2s/pdm等)
dai:音频接口,抽象概念,比如i2s等。
card:抽象概念,声卡。
capture:抽象概念,表示录音设备
playback:抽象概念,表示软件设备
对于大多数平台,dma 和 i2s/pdm 等集成在一个soc 上,有些甚至集成了codec。
4.2 音频数据流
音频数据的数据流,大致如下。我们可以看到,不同的硬件平台,其声卡设备的硬件逻辑和数据流大致一致,故抽象asoc 很有必要。
4.3 asoc 软件抽象
如下是笔者根据自己理解划分 alsa 声卡驱动各个部分:
machine:驱动顶层和入口,处理声卡操作。包括声卡创建,音频流的传输与控制。
platform:主要负责soc 平台的dma 和 cpu_dai 操作。
codec:主要负责codec driver 和 codec_dai 操作。
可以看到一个alsa 声卡驱动是十分复杂的,包含了各种复杂驱动。
codec driver:音频配置和传输
dma:dma 处理
dai:i2s等接口配置
pcm:和上层应用交互的中间层
control:和上层应用交互的中间层
其他:比如i2c/spi ,codec 控制操作。
4.4 asoc 驱动分析
我们以 linux-kernel-4.4.94 为例子来分析 asoc 驱动。限于篇幅,我们只分析 machine 驱动框架,对于codec 驱动和其他设备驱动,有时间再分析。
asoc machine 驱动调用如下:
/* asoc platform driver */static struct platform_driver soc_driver = {        .driver         = {                  .name           = soc-audio,                .pm             = &snd_soc_pm_ops,        },        .probe          = soc_probe, .remove         = soc_remove,};  
最顶层入口是soc_probe,位于 sound/soc/soc-core.c,不同的machine 位置可能不同。大部分在soc/xxx/下。
/* probes a new socdev */static int soc_probe(struct platform_device *pdev){        struct snd_soc_card *card = platform_get_drvdata(pdev);        /*        ¦* no card, so machine driver should be registering card        ¦* we should not be here in that case so ret error        ¦*/        if (!card)                return -einval;        dev_warn(&pdev->dev,                ¦asoc: machine %s should use snd_soc_register_card(),                ¦card->name);        /* bodge while we unpick instantiation */        card->dev = &pdev->dev;        return snd_soc_register_card(card);}  
最关键的就是 snd_soc_register_card 这个函数了。详细分析看上图uml 时许图。
4.5 asoc 数据结构
asoc 数据结构如上图。最顶层我们构建了snd_soc_card。贯穿整个驱动生命周期中,snd_soc_pcm_runtime,至关重要。
dai_link 关联着dai_driver 和 compoent_driver
snd_soc_codec:codec 相关
snd_soc_paltform:platform 相关
snd_soc_dai:cpu_dai 和 codec_dai 相关操作
snd_soc_component:关联dai_driver 和 component_driver。关联platform_driver 和 component_driver
snd_soc_ops/snd_soc_dai_ops/snd_pcm_ops:比较关键的几个ops
对于刚开始学习asla 驱动时,我们先关注这几个结构体就行。后续将从音频流和控制两大块,详细分析整个数据流和控制的调用过程。
5. 总结
本文详细的介绍了alsa 驱动最关键的一环asoc ,理解了asoc 顶层设计框架对于我们后续深入学习asla 驱动至关重要。
当我们熟悉了一个平台的驱动框架后,再去看另外一个平台就知道哪些是我们需要关注的,哪些是linux 内核已经实现的,从而达到事半功倍的作用。
希望本文,对读者朋友学习理解alsa 驱动有所帮助!


广明源家用定时遥控紫外线消毒灯:更智能、更安全
芯片板块股票有哪些 芯片板块股票一览
基于Proteus与单片机的交通灯控制电路设计
基于BS45F,BS83B,HT67的无线遥控浴霸方案
WiFi~5G,国产射频前端芯片厂商迎来新机遇!
ALSA驱动抽象:ASoc理解与分析
纵行科技以Sub-GHz M-FSK芯片打造低成本LPWAN方案,拓展多样IoT应用
线路板可靠性与微切片术语手册
Amazon Web Services与SpringPeople合作 以缩小云计算技术差距
中国移动与中国华录在北京签署战略合作框架协议
创造石黑浩:20年打造30多款网红机器人
华为Mate40新功能将于10月30日国内发布会揭晓,机皇配置或成绝唱
村田首款V2X通信模块“Type 1YL”和“Type 2AN”
Nacos实现原理:SpringCloud集成Nacos的实现过程
讯维无纸化会议系统案例分享
人工智能学会发布系列AI皮书
20张图文告诉您什么是智能水/气表存储关键数据的最佳解决方案
展锐携手产业伙伴推动智能电网标准落地
带你详细了解科沃斯机器人DEEBOT T5
Keyssa推出用于非接触高速数据和视频传输的“Kiss Connector”