DSP

linux Documents sound/alsa/soc codec.txt翻译

2019-07-13 20:28发布

Asoc Codec类驱动

Codec类驱动程序是通用的并且相对硬件平台独立的程序,用于配置Codec、FM、modem、BT和外部DSP以提供音频录制和播放。它不应该包含特定的目标平台或机器的代码。所有平台和特定机器的代码都应该相应的添加到平台和目标板相关的驱动程序中。
每一个codec类驱动都应该提供以下的功能:
  1. Codec 数字音频接口(DAI and PCM) 配置。
  2. Codec 控制 IO - 使用 RegMap API接口。
  3. 混音器和音频控制器。
  4. Codec 音频控制接口。
  5. 动态电源管理模块描述。
  6. 动态电源管理事件的响应。
    另外,codec驱动也能提供:
  7. DAC 数字静音控制.
    最好是结合使用说明和sound/soc/codecs/目录中已存在的codec代码和使用。

ASoC Codec 驱动解析

1 -编解码器的数字音频接口配置

每个编解码器驱动程序都必须有一个snd_soc_dai_driver结构体来定义它的数字音频接口和文件操作指针。这个结构体被导出以便注册到你的目标板(machine)的驱动中。
例如:
static struct snd_soc_dai_ops wm8731_dai_ops = {
.prepare = wm8731_pcm_prepare,
.hw_params = wm8731_hw_params,
.shutdown = wm8731_shutdown,
.digital_mute = wm8731_mute,
.set_sysclk = wm8731_set_dai_sysclk,
.set_fmt = wm8731_set_dai_fmt,
}; struct snd_soc_dai_driver wm8731_dai = {
.name = “wm8731-hifi”,
.playback = {
.stream_name = “Playback”,
.channels_min = 1,
.channels_max = 2,
.rates = WM8731_RATES,
.formats = WM8731_FORMATS,},
.capture = {
.stream_name = “Capture”,
.channels_min = 1,
.channels_max = 2,
.rates = WM8731_RATES,
.formats = WM8731_FORMATS,},
.ops = &wm8731_dai_ops,
.symmetric_rates = 1,
}; 2 -编解码器控制IO
编解码器通常可以通过I2C或SPI接口来控制(AC97的控制在DAI中)。编解码器驱动程序应该使用所有编解码器IO的Regmap API。请参阅包括/ linux / regmap.h和现有编解码器驱动程序,例如regmap的使用。 3 -混音器和音频控件
所有的混音器和音频控件都可以使用soc.h中的宏来定义。
#define SOC_SINGLE(xname, reg, shift, mask, invert)
定义了一个单独的控件如下:
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
其他的宏包含:
#define SOC_DOUBLE(xname, reg, shift_left, shift_right, mask, invert)
–>定义了一个立体声控件
#define SOC_DOUBLE_R(xname, reg_left, reg_right, shift, mask, invert)
–>定义了一个立体声控件占两个寄存器
#define SOC_ENUM_SINGLE(xreg, xshift, xmask, xtexts)
–>定义一个单声道枚举控件如下:
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)
–>定义了一个多声道枚举控件 4 -Codec音频文件指针
Codec驱动也支持以下ALSA PCM文件指针:
/* 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 *);
};
请参考ALSA驱动PCM 相关文件中详细说明 :
http://www.alsa-project.org/~iwai/writing-an-alsa-driver/ 5 -动态音频电源管理描述
动态音频电源管理模块描述codec的电源部件及部件之间相互关系以及Asoc内对应的寄存器 。
请阅读dapm.txt来获取更详尽的描述。
也可以从其他Codec驱动的例子中查看。 6 -动态音频电源事件处理
这个功能是处理codec及系统域电源的回调函数(例如休眠和唤醒函数)。它的作用是当Codec没有使用时使其进入睡眠状态。
电源状态:
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 数字静音控制
大多数Codec在DACs之前都有一个数字静音单元来尽量减少系统噪音。静音单元会阻止任何数字数据
进入DAC。
当数字静音被应用或释放时可以为每个Codec DAI创建由内核调用的回调函数。
例如
static int wm8974_mute(struct snd_soc_dai *dai, int mute)
{
struct snd_soc_codec *codec = dai->codec;
u16 mute_reg = snd_soc_read(codec, WM8974_DAC) & 0xffbf;
if (mute)
snd_soc_write(codec, WM8974_DAC, mute_reg | 0x40);
else
snd_soc_write(codec, WM8974_DAC, mute_reg);
return 0;
}