ASoC Codec类驱动程序

编解码器类驱动程序是通用的,与硬件无关的代码,用于配置编解码器,FM,MODEM,BT或外部DSP,以提供音频捕获和回放。它不应包含特定于目标平台或计算机的代码。应将所有平台和机器特定代码分别添加到平台和机器驱动程序中。

每个编解码器类驱动程序必须提供以下功能: -

  1. 编解码器DAI和PCM配置
  2. 编解码器控制IO - 使用RegMap API
  3. 调音台和音频控制
  4. 编解码器音频操作
  5. DAPM描述。
  6. DAPM事件处理程序。

可选的,编解码器驱动程序还可以提供: -

  1. DAC数字静音控制。

最好将本指南与sound / soc / codecs /中的现有编解码器驱动程序代码结合使用

ASoC Codec驱动程序故障

编解码器DAI和PCM配置

每个编解码器驱动程序必须具有struct snd_soc_dai_driver来定义其DAI和PCM功能和操作。导出此结构,以便您的计算机驱动程序可以将其注册到核心。

例如

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,
};

编解码器控制IO

编解码器通常可以通过I2C或SPI样式接口进行控制(AC97将控制与DAI中的数据相结合)。编解码器驱动程序应该将Regmap API用于所有编解码器IO。请参阅include / linux / regmap.h和现有的编解码器驱动程序,例如regmap用法。

调音台和音频控制

所有编解码器混音器和音频控件都可以使用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)

一个跨越2个寄存器的立体声控制

#define SOC_ENUM_SINGLE(xreg,xshift,xmask,xtexts)

定义单个枚举控件,如下所示: -

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_ENUM_DOUBLE(xreg,xshift_l,xshift_r,xmask,xtexts)

定义立体声枚举控件

编解码器音频操作

编解码器驱动程序还支持以下ALSA PCM操作: -

/ * SoC音频操作* /
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描述

动态音频电源管理描述描述了编解码器电源组件及其与ASoC内核的关系和寄存器。有关构建描述的详细信息,请阅读dapm.txt。

另请参阅其他编解码器驱动程序中的示例。

DAPM事件处理程序

此函数是一个回调函数,用于处理编解码器域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数字静音控制

大多数编解码器在DAC之前都有数字静音,可用于最小化任何系统噪声。静音可以阻止任何数字数据进入DAC。

当应用或释放静音时,可以为每个编解码器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;
}
Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐