Linux kernel version:3.4.5

SoC:Samsung exynos

Userspace:tinyalsa


音频驱动主要有三部分组成:

1、 Platform:通常指某款SoC平台,如exynos、omap等等。Platform又可细分两部分:

1.1、CPU DAI:在嵌入式系统里面通常指CPU的I2S、PCM总线接口,负责将音频数据从AIF FIFO搬运到CODEC(Playback的情形,Capture则方向相反)。CPU DAI通过snd_soc_register_dai()来注册。注:DAI是Digital Audio Interface的缩写,分为CPU DAI和CODEC DAI,这两者通过I2S/PCM总线连接;AIF是Audio Interface的缩写,一般分为I2S和PCM接口。

1.2、DMA:负责将音频数据从userspace通过DMA操作搬运到AIF FIFO,这部分的逻辑比较复杂,以下几篇会对它详细阐述。DMA操作通过snd_soc_register_platform()来注册。值得留意的是:某些情形下是不需要DMA操作的,比如Modem和CODEC直连,因为Modem本身已经把数据送到它的PCM接口FIFO了,这时只需启动PCM接口把数据搬运到CODEC即可;在这种情形下,Machine驱动snd_soc_dai_link中需要指定.platform_name = "snd-soc-dummy", 这是虚拟出来的DMA驱动。

2、CODEC:对于Playback来说,userspace送过来的PCM数据是经过抽样量化出来的数字信号,在codec经过DAC转换成模拟信号送到外放耳机输出,这样我们就可以听到声音了。Codec字面意思是编解码器,但芯片里面的部件很多,常见的有AIF(音频接口)、DAC、ADC、Mixer、PGA、Line-in、Line-out,有些高端的codec芯片还有EQ、DSP、SRC、DRC、AGC、Echo canceller、Noise suppression等功能。

3、Machine:指某一款机器,它把CPU DAI、CODEC DAI、MODEM DAI各个音频总线接口通过定义dai_link链结起来,然后注册snd_soc_card。和上面两个不一样,Platform和CODEC驱动一般是可以重用的,而Machine有它特定的硬件特性,几乎是不可重用的。所谓的硬件特性指:DAIs之间的链结;通过某个GPIO打开Amplifier;通过某个GPIO检测耳机插拔;使用某个时钟如MCLK/External OSC作为I2S、CODEC模块的基准时钟源等等。


因此从上面的描述来看,对于Playback,PCM数据流向大致是:

  1. | DMA |                 | I2S/PCM |        | AIF->DAC->PGA/Mixer |  
  2. -----------> AIF FIFO ----------------> CODEC ----------------> SPK/HS/Earpiece  
              | DMA |                 | I2S/PCM |        | AIF->DAC->PGA/Mixer |
userspace----------------> AIF FIFO ----------------> CODEC ----------------> SPK/HS/Earpiece


我们这系列的内容主要讲述pcm数据如何从userspace如何通过DMA搬运到AIF FIFO的。至于I2S控制方面,逻辑是非常简单的,读写寄存器启动I2S传输即可。

这系列初步定为如下几个部分:

1、 当pcm_open时,如何检查hw constraints(硬件特性限制,如支持的通道数/采样率/数据格式、DMA的period size和period count等);如何设置hw params(channels/sample rate/pcm format/period size/period count等);如何设置sw params(start_threshold/stop_threshold/silence_threshold等);如何调用platform/codec/machine的hw_params()回调函数。

2、 当pcm_write时,如何把pcm数据从userspace拷贝到dma_alloc_writecombine()分配出来的dma buffer中;如何触发platform/codec/machine的trigger()函数去启动DMA,把数据从dma buffer搬运到AIF FIFO。但在这之前,会先分析dma buffer分配过程,还有dma搬运的src源地址和dst目的地址如何设定,这部分平台相关。

3、 xrun出现的根源是什么?有些资料这样提及:“xrun指的是,声卡period一到,引发一个中断,告诉alsa驱动,要填入数据,或读走数据,但是问题在于alsa的读取和写入操作必须用户调用writei和readi才会发生的,它不会去缓存数据;如果上层没有用户调用writei和readi,那么就会产生 overrun(录制时,数据都满了,还没被读走)和underrun(需要数据来播放,却不写入数据),统称为xrun”。这里源码上分析它是如何产生的,这样我们知道需要正确配置好哪个参数才能更好避免xrun或取得更好的表现性能。


涉及到的源码文件:

  1. sound/core/pcm_native.c  
  2. sound/core/pcm_lib.c  
  3. sound/soc/samsung/i2s.c  
  4. sound/soc/samsung/dma.c  
  5. arch/arm/mm/dma-mapping.c  
  6. arch/arm/plat-samsung/dma-ops.c  
sound/core/pcm_native.c
sound/core/pcm_lib.c
sound/soc/samsung/i2s.c
sound/soc/samsung/dma.c
arch/arm/mm/dma-mapping.c
arch/arm/plat-samsung/dma-ops.c

可以看到只有pcm_native.c和pcm_lib.c是平台无关的,其他都平台相关。但不要紧,平台相关部分仅仅是dma的初始化和它的操作函数,这一部分在其他平台也是类似的,只是实现不大一致。

GitHub 加速计划 / li / linux-dash
6
1
下载
A beautiful web dashboard for Linux
最近提交(Master分支:3 个月前 )
186a802e added ecosystem file for PM2 4 年前
5def40a3 Add host customization support for the NodeJS version 4 年前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐