Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1412861
  • 博文数量: 1334
  • 博客积分: 645
  • 博客等级: 上士
  • 技术积分: 5762
  • 用 户 组: 普通用户
  • 注册时间: 2012-07-25 16:56
文章分类

全部博文(1334)

文章存档

2014年(108)

2013年(1059)

2012年(169)

分类: LINUX

2014-02-18 17:08:57

 linux音频alsa-uda134x驱动分析之三(解码器)

, , , 
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;
}
阅读(1098) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~