ALSA ASoc 架构
- 一、ASOC 由来
- 二、从 HW 角度
- 三、从 SW 角度
- 四、重要数据结构关联图
- 1、基于 Linux 3.0 数据结构图
- 2、基于 Linux 4.0 数据结构图
一、ASOC 由来
ASoC–ALSA System on Chip,是建立在标准 ALSA 驱动层上,为了更好地支持嵌入式处理器和移动设备中的音频 Codec 的一套软件体系,它依赖于标准 ALSA 驱动框架。内核文档 https://www.kernel.org/doc/html/v5.4/sound/soc/overview.html中详细介绍了 ASoc 的设计初衷,ASoc 正是为了解决下面种种问题而提出的:
- Codec 驱动与 SoC CPU 的底层耦合过于紧密,这种不理想会导致代码的重复。例如,仅是 wm8731 的驱动,当前 Linux 中有分别针对 4个平台的驱动代码。
- 音频事件没有标准的方法来通知用户,例如耳机、麦克风的插拔和检测,这些事件在移动设备中都是非常普通的,而且通常都需要特定于机器的代码进行重新对音频路径进行配置。
- 当进行播放或录音时,驱动会让整个 codec 处于上电状态,这对于 PC 没问题,但对于移动设备来说,这意味着浪费大量的电量。同时也不支持通过改变采样频率和偏置电流来达到省电的目的。
二、从 HW 角度
ASoC 硬件设备驱动的三大构成:Codec、Soc(Platform) 和板载硬件 Machine
三大部分。
Machine
:是指某一款机器,可以是某款设备,某款开发板,又或者是某款智能手机,由此可以看出 Machine 几乎是不可重用的,每个 Machine 上的硬件实现可能都不一样,CPU 不一样,Codec 不一样,音频的输入、输出设备也不一样。Machine 为 CPU、Codec、输入输出设备提供了一个载体,可以认为是 Platform 和 Codec 之间的粘合剂。Platform
:一般是指某一个 SoC 平台,比如 MT8167,MT8173 等等,与音频相关的通常包含该 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 对内部寄存器进行控制。
三、从 SW 角度
在软件层面,ASoC 也把嵌入式设备的音频系统同样分为 3 大部分,Machine,Platform 和 Codec.
Machine Driver
:负责处理机器特有 Machine control (如 AMP on/off);单独的 Platform 和 Codec Driver 是不能工作的,它必须
由 Machine Driver 把它们结合在一起才能完成整个设备的音频处理工作。Platform Driver
:包含了该 SoC 平台的音频 DMA 和音频接口的配置和控制(I2S,PCM,AC97 等等)。它也不能包含任何与板子或机器相关的代码。Codec Driver
:ASoC 中的一个重要设计原则就是要求 Codec 驱动是平台无关的。任何特定于平台和机器的代码都要移到 Platform 和 Machine 驱动中。所有的 Codec 驱动都要提供以下特性:
① Codec DAI 和 PCM 的配置信息;
② Codec 的 IO 控制方式(I2C,SPI 等等);
③ Mixer 和其他的音频控件;
④ Codec 的 ALSA 音频操作接口;
四、重要数据结构关联图
在分析整个 ASoC 的过程中,出现了众多的数据结构,在此先理清重要的数据结构的关系,如下图:
1、基于 Linux 3.0 数据结构图
2、基于 Linux 4.0 数据结构图
基于 linux-4.0 之后对于 platform & codec driver 均使用 component driver 来定义,其数据结构关系如下图所示:
ASoc 将声卡实现为一个 Platform Device(Machine Driver),然后利用 platform_device 结构中的 dev 字段:dev_set_drvdata(card->dev,card)
,即指向一个 snd_soc_card
结构。可以认为 snd_soc_card 是整个 ASoc 数据结构的根本,由它开始,引出一系列的数据结构用于表述音频的各个特性和功能。snd_soc_card 结构引出 snc_soc_dai_link 结构,而 snd_soc_dai_link 结构中又根据 cpu_dai_name、codec_dai_name、platform_name(platform_of_node)
匹配到相应的 Platform(PCM DMA & CPUDAI)和 Codec DAI
. 在 Machine 中会对 num_link 分配 snd_soc_pcm_runtime,将成功匹配的 snd_soc_dai & component 填充到 snd_soc_pcm_runtime
,最后将所有的 snd_soc_pcm_runtime 都通过 list 形式 add 到 snd_soc_card->rtd_list
中。
参考链接:
linux-alsa详解4 ASOC介绍