ASoC Codec Class Driver
编解码器类驱动程序是通用且独立于硬件的代码,用于配置编解码器、FM、调制解调器、BT或外部DSP以提供音频捕获和播放。它不应包含特定于目标平台或机器的代码。所有平台和机器特定代码应分别添加到平台和机器驱动程序中。
每个编解码器类驱动程序必须提供以下功能:-
- Codec DAI and PCM configuration
- Codec control IO - using RegMap API
- Mixers and audio controls
- Codec audio operations
- DAPM description.
- DAPM event handler.
或者,编解码器驱动程序还可以提供:-
- DAC Digital mute control.
最好将本指南与sound/soc/codec中现有的编解码器驱动程序代码结合使用/
ASoC Codec driver breakdown
Codec DAI and PCM configuration
每个Codec driver必须有一个结构snd_soc_dai_driver
,以定义其dai和PCM功能和操作。此结构被导出,以便您的machine driver.可以将其注册到core。
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,
};
Codec control IO
编解码器通常可以通过I2C或SPI风格的接口进行控制(AC97将控制与DAI中的数据相结合)。编解码器驱动程序应为所有编解码器IO使用Regmap API。请参阅include/linux/regmap.h和现有编解码器驱动程序以了解regmap的用法示例。
Codec ic 的寄存器设置 使用的是通常外设的总线驱动;
Mixers and audio controls
所有codec mixers and audio controls都可以使用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)
定义立体声枚举控件
Codec Audio Operations
编解码器驱动程序还支持以下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/
DAPM description
动态音频电源管理描述描述编解码器电源组件及其与ASoC核心的关系和寄存器。有关构建说明的详细信息,请阅读dapm.rst。
请参阅其他编解码器驱动程序中的示例。
DAPM event handler
此函数是一个回调函数,用于处理编解码器域PM调用和系统域PM调用(例如挂起和恢复)。它用于在不使用时使编解码器处于休眠状态。
电源状态:-
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 */
Codec DAC digital mute control
大多数编解码器在DAC之前都有一个数字静音,可用于最小化任何系统噪声。静音可阻止任何数字数据进入DAC。
可以创建一个回调,当应用或释放静音时,内核将为每个编解码器DAI调用该回调。
eg:
static int wm8974_mute(struct snd_soc_dai *dai, int mute)
{
struct snd_soc_component *component = dai->component;
u16 mute_reg = snd_soc_component_read32(component, WM8974_DAC) & 0xffbf;
if (mute)
snd_soc_component_write(component, WM8974_DAC, mute_reg | 0x40);
else
snd_soc_component_write(component, WM8974_DAC, mute_reg);
return 0;
}