对技术执着
分类: LINUX
2015-03-14 15:26:04
ASoC Codec Driver ASoC解码器驱动 ================= The codec driver is generic and hardware independent code that configures the codec to provide audio capture and playback. It should contain no code that is specific to the target platform or machine. All platform and machine specific code should be added to the platform and machine drivers respectively. 解码器驱动是通用、硬件无关的代码,它配置解码器以支持音频捕获与回放。它不应包含任何与目标平台或机器相关的代码。平台或机器相关代码应该分别加 入到平台和机器驱动中去。 Each codec driver *must* provide the following features:- 各解码器驱动必须提供如下特性: 1) Codec DAI and PCM configuration 2) Codec control IO - using I2C, 3 Wire(SPI) or both APIs 3) Mixers and audio controls 4) Codec audio operations 1)解码器数字音频接口和PCM配置。 2)解码器控制IO-使用I2C,3总线(SPI)或两个都有。 3)混音器和音频控制。 4)解码器音频操作。 Optionally, codec drivers can also provide:- 解码器驱动可以选择性提供: 5) DAPM description. 6) DAPM event handler. 7) DAC Digital mute control. 5)动态音频电源管理描述。 6)动态音频电源管理事件控制。 7)数模转换数字消音控制。 Its probably best to use this guide in conjunction with the existing codec driver code in sound/soc/codecs/ 大家也许最好联同己存在于sound/soc/codecs/中的驱动代码一起来使用这个指导书。 ASoC Codec driver breakdown ASoC 解码器解析 =========================== 1 - Codec DAI and PCM configuration 1-解码器数字音频接口和PCM配置 ----------------------------------- Each codec driver must have a struct snd_soc_codec_dai to define its DAI and PCM capabilities and operations. This struct is exported so that it can be registered with the core by your machine driver. 各解码器驱动必须有一个snd_soc_codec_dai数据结构,它用来定义DAI和PCM提供的功能和操作。这个数据结构要导出,好让你的机器驱动程序将它注册到ALSA核心中去。 e.g. 例如: struct snd_soc_codec_dai wm8731_dai = { .name = "WM8731", /* playback capabilities */ .playback = { .stream_name = "Playback", .channels_min = 1, .channels_max = 2, .rates = WM8731_RATES, .formats = WM8731_FORMATS,}, /* capture capabilities */ .capture = { .stream_name = "Capture", .channels_min = 1, .channels_max = 2, .rates = WM8731_RATES, .formats = WM8731_FORMATS,}, /* pcm operations - see section 4 below */ .ops = { .prepare = wm8731_pcm_prepare, .hw_params = wm8731_hw_params, .shutdown = wm8731_shutdown, }, /* DAI operations - see DAI.txt */ .dai_ops = { .digital_mute = wm8731_mute, .set_sysclk = wm8731_set_dai_sysclk, .set_fmt = wm8731_set_dai_fmt, } }; EXPORT_SYMBOL_GPL(wm8731_dai); 2 - Codec control IO 2-解码器控制IO -------------------- The codec can usually be controlled via an I2C or SPI style interface (AC97 combines control with data in the DAI). The codec drivers provide functions to read and write the codec registers along with supplying a register cache:- 解码器通常可以通过I2C或SPI类型的接器进行控制(AC97 的数字音频接口中把数据和控制结合在了一起)。解码器驱动提供读写解码器寄存器和供应寄存器缓存的功能。 /* IO control data and register cache */ void *control_data; /* codec control (i2c/3wire) data */ void *reg_cache; Codec read/write should do any data formatting and call the hardware read write below to perform the IO. These functions are called by the core and ALSA when performing DAPM or changing the mixer:- 解码器读写要可以作用于任何格式,调用底层硬件的读写功能操作IO。 ALSA核或ALSA在动态音频电源管理或改变混音器时会调用这些函数。 unsigned int (*read)(struct snd_soc_codec *, unsigned int); int (*write)(struct snd_soc_codec *, unsigned int, unsigned int); Codec hardware IO functions - usually points to either the I2C, SPI or AC97 read/write:- 解码器硬件IO函数-通常指向I2C,SPI或AC97的读写: hw_write_t hw_write; hw_read_t hw_read; 3 - Mixers and audio controls 3-混音器和音频控制 ----------------------------- All the codec mixers and audio controls can be defined using the convenience macros defined in soc.h. 所有解码器混音器和音频控制都可以通过使用soc.h中定义的宏而带来方便。 #define SOC_SINGLE(xname, reg, shift, mask, invert) Defines a single control as follows:- 这个宏可以定义一个单次操作: xname = Control name e.g. "Playback Volume" reg = codec register shift = control bit(s) offset in register mask = control bit size(s) e.g. mask of 7 = 3 bits invert = the control is inverted Other macros include:- 其它的宏还有: #define SOC_DOUBLE(xname, reg, shift_left, shift_right, mask, invert) A stereo control 下面是一个立体声控制: #define SOC_DOUBLE_R(xname, reg_left, reg_right, shift, mask, invert) A stereo control spanning 2 registers 扩用两个寄存器的立体声控制如下: #define SOC_ENUM_SINGLE(xreg, xshift, xmask, xtexts) Defines an single enumerated control as follows:- 定义一个枚举控制如下: xreg = register xshift = control bit(s) offset in register xmask = control bit(s) size xtexts = pointer to array of strings that describe each setting #define SOC_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, xtexts) Defines a stereo enumerated control 上面的宏定义一个立体声枚举控制。 4 - Codec Audio Operations 4-解码器音频操作 -------------------------- The codec driver also supports the following ALSA operations:- 解码器驱动还支持下面的ALSA操作: /* SoC audio ops */ struct snd_soc_ops { int (*startup)(struct snd_pcm_substream *); void (*shutdown)(struct snd_pcm_substream *); int (*hw_params)(struct snd_pcm_substream *, struct snd_pcm_hw_params *); int (*hw_free)(struct snd_pcm_substream *); int (*prepare)(struct snd_pcm_substream *); }; Please refer to the ALSA driver PCM documentation for details. 详情请参考ALSA驱动PCM文档: ~iwai/writing-an-alsa-driver/c436.htm 5 - DAPM description. 5-动态音频电源管理 --------------------- The Dynamic Audio Power Management description describes the codec power components and their relationships and registers to the ASoC core. Please read dapm.txt for details of building the description. 动态音频电源管理描述的是解码器电源组件和它们的关系,和向ASoC核注册的方法。详情请阅dapm.txt。 Please also see the examples in other codec drivers. 也请参照其它解码器的例子。 6 - DAPM event handler 6-动态音频电源管理事件句柄 ---------------------- This function is a callback that handles codec domain PM calls and system domain PM calls (e.g. suspend and resume). It is used to put the codec to sleep when not in use. 该功能是一个回调函数,用来处理解码器域的电源管理调用和系统域的电源管理调用(如挂起和恢复)。它用来在不用时使解码器进入休眠状态。 Power states:- 电源状态: SNDRV_CTL_POWER_D0: /* full On */ /* vref/mid, clk and osc on, active */ SNDRV_CTL_POWER_D1: /* partial On */ SNDRV_CTL_POWER_D2: /* partial On */ SNDRV_CTL_POWER_D3hot: /* Off, with power */ /* everything off except vref/vmid, inactive */ SNDRV_CTL_POWER_D3cold: /* Everything Off, without power */ 7 - Codec DAC digital mute control 7-解码器数模转换消音控制 ---------------------------------- Most codecs have a digital mute before the DACs that can be used to minimise any system noise. The mute stops any digital data from entering the DAC. 多数解码器都有一个数字消音装置放在数模转换器前面。它可以用来最小化系统躁声。消音器不让任何数字数据进入DAC。 A callback can be created that is called by the core for each codec DAI when the mute is applied or freed. 消音器使用或释放时会创造一个回调。ASoC核会为每个解码器数字音频接口调用这个回调函数。 i.e. static int wm8974_mute(struct snd_soc_codec *codec, struct snd_soc_codec_dai *dai, int mute) { u16 mute_reg = wm8974_read_reg_cache(codec, WM8974_DAC) & 0xffbf; if(mute) wm8974_write(codec, WM8974_DAC, mute_reg | 0x40); else wm8974_write(codec, WM8974_DAC, mute_reg); return 0; } |