Audio Codec 架构
ALSA 软件架构
Linux 中的音频采用 ALSA 驱动框架,该框架管理 Linux 下所有与音频相关的资源,codec 的驱动按照 ALSA 框架进行设计开发。ALSA 整体框架如下图:
如上图,ALSA 音频框架将底层的硬件驱动分为三部分:machine、platform 与 codec。三者的关系如下图所示:
platform driver 包含了 soc 平台的音频 DMA 和数字音频接口 (I2S、PCM、SPDIF、AC97 等)的配置和管理,它不包含任何与板子或机器相关的代码,该部分驱动由 SoC 厂商实现。
codec driver 的一个重要原则就是要求 codec 驱动的平台无关性。它包含音频控件、音频接口、DAPM 的定义等。codec 的驱动一般由 IC 厂商实现。
machine driver 主要是针对设备的,主要作用有三个: 1. 实现 codec 和 platform 的耦合,machine driver 是板级上的 codec 和 SOC 之间的桥梁,描述二者如何连接。 2. 负责处理机器特有的的一些控件和音频事件(如板子上需要打开放大器等)。 3. 创建声卡。一般板卡的设计者只需要实现这部分的驱动。
单独的 driver 和 codec driver 是不能工作的,必须由 driver 把它们结合在一起才能完成整个设备的音频处理工作。ALSA 框架将底层硬件划分为三部分后,使得 platform 和 codec 的驱动实现变得更加简单,二者依靠 dai 和 codec_dai 进行数据传输。这种结构下的音频数据流通路径如下:
AIC 实现架构
与常见的 codec 芯片不同,AIC 的 AudioCodec 是 SOC 内置的一个模块,音频数据可以直接传输到 AudioCodec 模块,而不需要 S 这类音频接口。AudioCodec 的音频数据流通路径如下:
若是一颗单独的 codec 芯片,只需要实现相应的 driver,platform driver 由 SOC 厂商实现,machine driver 由板级开发者实现,并最终创建声卡。但是 AudioCodec 本身就是 SOC 中的一个模块,不需要 S 等音频接口进行数据传输,也不需要再单独实现 driver,所以在实现 SOC 内置的 AudioCodec 模块的驱动时,除了实现音频通路控制和音频控件外,还需要实现声卡的创建,以便用户可以直接使用 AudioCodec 模块的驱动进行录音和播放。
AudioCodec 模块不需要 S 接口,所以在驱动实现中并没有严格意义上的 dai。但是 ALSA 框架在创建声卡时,需要根据 dai 和 codec_dai 的名字进行查找匹配,查找不到则不能创建声卡。所以为了能成功创建声卡,在 AudioCodec 的驱动实现中需要创建一个 dai,该 dai 的作用是为了 platform 和 codec 的耦合,并不能对该 dai 进行任何操作。
综上,AIC 的 AudioCodec 模块的驱动实现可以分为三部分:
-
platform driver 的实现:
-
dma 的注册和管理,用于在内存和 AudioCodec 之间传输数据
-
cpu_dai 部分的定义,用于实现和 driver 的耦合
-
-
codec driver 的实现:
-
codec_dai 的注册和管理,用于实现和 driver 的耦合,以及对 AudioCodec 模块频率、采样率、采样深度的设置
-
DAPM 音频路径和音频控件的管理
-
-
machine driver 的实现:
-
用于实现 platform 和 codec 的耦合,并创建声卡
-