目录
1. 简介
在内核源码Documentation/sound/alsa/soc/overview.txt中,对Codec驱动有如下论述:
Codec驱动程序独立于平台,包含音频控件,音频接口功能,编解码器DAPM定义和编解码器IO功能。如果需要,该类可扩展至BT,FM和MODEM IC。Codec类驱动程序应该是可以在任何体系结构和机器上运行的通用代码。
注:DAPM,Dynamic Audio Power Management,动态音频电源管理,为移动Linux设备设计,使得音频系统任何时候都工作在最低功耗状态。
对于Playback来说,user space送过来的PCM数据是经过抽样量化出来的数字信号,在codec经过DAC转换成模拟信号送到外放耳机输出,这样我们就可以听到声音了。
Codec字面意思是编解码器,但芯片里面的功能部件很多,常见的有AIF、DAC、ADC、Mixer、PGA、Line-in、Line-out,有些高端的codec芯片还有EQ、DSP、SRC、DRC、AGC、Echo canceller、Noise suppression等部件。
本文重点关注codec_daiI驱动和codec驱动。
Codec指音频codec共有的部分,包括codec初始化函数、控制接口、寄存器缓存、控件列表、dapm部件列表、音频路由列表、偏置电压设置函数等描述信息.
Codec_dai指codec上的数字音频接口DAI驱动描述,各个接口的描述信息不一定都是一致的,所以各个音频接口都有它自身的驱动描述,包括音频接口的初始化函数、操作函数集、能力描述等。
2. 源码分析
Kernel 版本:3.10
Codec驱动是编解码器部分的控制代码,其抽象出两个结构体分别为snd_soc_codec_driver和snd_soc_dai_driver。
2.1. Codec
2.1.1. 数据结构struct snd_soc_codec_driver
struct snd_soc_codec_driver {
/* driver ops */
int (*probe)(struct snd_soc_codec *);
int (*remove)(struct snd_soc_codec *);
int (*suspend)(struct snd_soc_codec *);
int (*resume)(struct snd_soc_codec *);
/* Default control and setup, added after probe() is run */
const struct snd_kcontrol_new *controls;
int num_controls;
const struct snd_soc_dapm_widget *dapm_widgets;
int num_dapm_widgets;
const struct snd_soc_dapm_route *dapm_routes;
int num_dapm_routes;
/* codec wide operations */
int (*set_sysclk)(struct snd_soc_codec *codec,
int clk_id, int source, unsigned int freq, int dir);
int (*set_pll)(struct snd_soc_codec *codec, int pll_id, int source,
unsigned int freq_in, unsigned int freq_out);
/* codec IO */
unsigned int (*read)(struct snd_soc_codec *, unsigned int);
int (*write)(struct snd_soc_codec *, unsigned int, unsigned int);
int (*display_register)(struct snd_soc_codec *, char *,
size_t, unsigned int);
int (*volatile_register)(struct snd_soc_codec *, unsigned int);
int (*readable_register)(struct snd_soc_codec *, unsigned int);
int (*writable_register)(struct snd_soc_codec *, unsigned int);</