요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
=======================
ASoC Codec Class Driver
=======================
The codec class driver is generic and hardware independent code that configures
the codec, FM, MODEM, BT or external DSP 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 class driver *must* provide the following features:-
1. Codec DAI and PCM configuration
2. Codec control IO - using RegMap API
3. Mixers and audio controls
4. Codec audio operations
5. DAPM description.
6. DAPM event handler.
Optionally, codec drivers can also provide:-
7. DAC Digital mute control.
Its probably best to use this guide in conjunction with the existing codec
driver code in sound/soc/codecs/
ASoC Codec driver breakdown
===========================
Codec DAI and PCM configuration
-------------------------------
Each codec driver must have a struct snd_soc_dai_driver 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.
e.g.
::
static struct snd_soc_dai_ops wm8731_dai_ops = {
.prepare = wm8731_pcm_prepare,
.hw_params = wm8731_hw_params,
.shutdown = wm8731_shutdown,
.mute_stream = 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_rate = 1,
};
Codec control IO
----------------
The codec can usually be controlled via an I2C or SPI style interface
(AC97 combines control with data in the DAI). The codec driver should use the
Regmap API for all codec IO. Please see include/linux/regmap.h and existing
codec drivers for example regmap usage.
Mixers and audio controls
-------------------------
All the codec mixers and audio controls can be defined using the convenience
macros defined in 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
Codec Audio Operations
----------------------
The codec driver also supports the following ALSA PCM operations:-
::
/* 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 :doc:`ALSA driver PCM documentation
<../kernel-api/writing-an-alsa-driver>` for details.
DAPM description
----------------
The Dynamic Audio Power Management description describes the codec power
components and their relationships and registers to the ASoC core.
Please read dapm.rst for details of building the description.
Please also see the examples in other codec drivers.
DAPM event handler
------------------
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 */
Codec DAC digital mute control
------------------------------
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.
A callback can be created that is called by the core for each codec DAI
when the mute is applied or freed.
i.e.
::
static int wm8974_mute(struct snd_soc_dai *dai, int mute, int direction)
{
struct snd_soc_component *component = dai->component;
u16 mute_reg = snd_soc_component_read(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;
}
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
Codec class driver의 역할과 필수 기능
1-29Codec class driver는 codec, FM, MODEM, BT 또는 외부 DSP를 설정해 오디오 capture와 playback을 제공하는 범용 하드웨어 독립 코드다. 대상 platform이나 machine에만 해당하는 코드를 포함해서는 안 되며, 그런 코드는 각각 platform driver와 machine driver에 넣어야 한다.
각 codec class driver는 codec DAI와 PCM 설정, Regmap 기반 control I/O, mixer와 audio control, codec audio operation, DAPM description, DAPM event handler를 반드시 제공해야 한다. DAC 앞의 digital mute control은 선택 기능이다.
이 안내서는 `sound/soc/codecs/`에 있는 기존 codec driver 코드와 함께 보는 것이 좋다.
필수 항목과 선택 항목을 구분한다.
=======================
ASoC Codec Class Driver
=======================
The codec class driver is generic and hardware independent code that configures
the codec, FM, MODEM, BT or external DSP 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 class driver *must* provide the following features:-
1. Codec DAI and PCM configuration
2. Codec control IO - using RegMap API
3. Mixers and audio controls
4. Codec audio operations
5. DAPM description.
6. DAPM event handler.
Optionally, codec drivers can also provide:-
7. DAC Digital mute control.
Its probably best to use this guide in conjunction with the existing codec
driver code in sound/soc/codecs/
ASoC Codec driver breakdown
===========================
Codec DAI와 PCM 설정
30-66각 codec driver에는 DAI와 PCM의 capability 및 operation을 정의하는 `struct snd_soc_dai_driver`가 있어야 한다. 이 구조체를 export하면 machine driver가 ASoC core에 등록할 수 있다.
WM8731 예제의 `struct snd_soc_dai_ops`는 `prepare`, `hw_params`, `shutdown`, `mute_stream`, `set_sysclk`, `set_fmt` callback을 연결한다. `struct snd_soc_dai_driver wm8731_dai`는 DAI 이름, playback·capture stream 이름, channel 범위, rate와 format을 정의하고 앞의 operation 표를 지정한다.
Playback과 capture는 모두 1~2 channel을 지원하며 `WM8731_RATES`, `WM8731_FORMATS`를 공유한다. `symmetric_rate = 1`은 두 방향이 대칭적인 rate를 사용하도록 요구한다.
예제 DAI operation과 처리 시점을 연결한다.
Playback과 capture에 공통으로 선언한 범위다.
Codec DAI and PCM configuration
-------------------------------
Each codec driver must have a struct snd_soc_dai_driver 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.
e.g.
::
static struct snd_soc_dai_ops wm8731_dai_ops = {
.prepare = wm8731_pcm_prepare,
.hw_params = wm8731_hw_params,
.shutdown = wm8731_shutdown,
.mute_stream = 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_rate = 1,
};
Regmap 기반 codec control I/O
67-74Codec은 보통 I2C 또는 SPI 계열 interface로 제어한다. AC97은 DAI에서 control과 data를 함께 운반한다는 차이가 있다.
Codec driver는 모든 codec I/O에 Regmap API를 사용해야 한다. 사용 예제는 `include/linux/regmap.h`와 기존 codec driver에서 확인할 수 있다.
Bus 차이는 Regmap 계층 아래로 숨기고 driver는 공통 API를 사용한다.
Codec control IO
----------------
The codec can usually be controlled via an I2C or SPI style interface
(AC97 combines control with data in the DAI). The codec driver should use the
Regmap API for all codec IO. Please see include/linux/regmap.h and existing
codec drivers for example regmap usage.
Mixer와 audio control macro
75-119모든 codec mixer와 audio control은 `soc.h`의 편의 macro로 정의할 수 있다. `SOC_SINGLE(xname, reg, shift, mask, invert)`는 단일 control을 만든다.
`xname`은 `Playback Volume` 같은 control 이름, `reg`는 codec register, `shift`는 register 안의 control bit offset, `mask`는 control bit 크기를 나타내는 mask다. 예를 들어 mask 7은 3 bit를 뜻한다. `invert`는 control 값의 반전 여부다.
`SOC_DOUBLE`은 한 register의 left·right shift를 사용하는 stereo control이고, `SOC_DOUBLE_R`은 left와 right가 서로 다른 두 register에 걸친 stereo control이다.
`SOC_ENUM_SINGLE`은 하나의 enumerated control을 정의한다. `xreg`, `xshift`, `xmask`는 register와 bit 위치·크기를 나타내며, `xtexts`는 각 설정을 설명하는 문자열 배열의 pointer다. `SOC_ENUM_DOUBLE`은 stereo enumerated control을 정의한다.
Control의 channel 구성과 register 배치를 비교한다.
단일 control 정의에 사용되는 다섯 인자의 의미다.
Mixers and audio controls
-------------------------
All the codec mixers and audio controls can be defined using the convenience
macros defined in 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
Codec audio operation
120-137Codec driver는 `struct snd_soc_ops`로 ALSA PCM operation도 지원한다. `startup`과 `shutdown`은 substream의 시작·종료 수명 주기를 처리하고, `hw_params`는 `struct snd_pcm_hw_params`를 적용하며, `hw_free`는 hardware resource를 해제하고, `prepare`는 실행 전 stream을 준비한다.
세부 동작은 `../kernel-api/writing-an-alsa-driver`의 ALSA driver PCM 문서를 참조한다.
Codec PCM operation의 호출 목적을 정리한다.
Codec Audio Operations
----------------------
The codec driver also supports the following ALSA PCM operations:-
::
/* 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 :doc:`ALSA driver PCM documentation
<../kernel-api/writing-an-alsa-driver>` for details.
DAPM description
138-146Dynamic Audio Power Management description은 codec의 전원 component와 component 사이의 관계를 기술하고 이를 ASoC core에 등록한다.
Description을 만드는 자세한 방법은 `dapm.rst`를 읽고, 다른 codec driver의 예제도 함께 참조한다.
Codec 내부의 전원 요소와 signal 관계를 core가 관리할 수 있는 형태로 제공한다.
DAPM description
----------------
The Dynamic Audio Power Management description describes the codec power
components and their relationships and registers to the ASoC core.
Please read dapm.rst for details of building the description.
Please also see the examples in other codec drivers.
DAPM event handler와 전원 상태
147-167DAPM event handler는 codec domain PM 호출과 suspend·resume 같은 system domain PM 호출을 처리하는 callback이다. Codec을 사용하지 않을 때 sleep 상태로 전환하는 데 사용한다.
`SNDRV_CTL_POWER_D0`은 vref/vmid, clock, oscillator가 켜진 완전 활성 상태다. `D1`과 `D2`는 부분 활성 상태다. `D3hot`은 전원은 공급되지만 vref/vmid를 제외한 기능이 꺼진 비활성 상태이며, `D3cold`는 전원까지 제거한 완전 off 상태다.
원문의 ALSA control power state와 활성 수준을 정리한다.
활성 상태에서 전원 제거 상태로 내려가는 개념적 순서다.
DAPM event handler
------------------
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 */
DAC digital mute control
168-190대부분의 codec에는 DAC 앞에 digital mute가 있어 시스템 noise를 줄일 수 있다. Mute는 digital data가 DAC로 들어가는 것을 막는다.
Core가 각 codec DAI의 mute 적용 또는 해제 시 호출할 callback을 만들 수 있다. `wm8974_mute()` 예제는 `dai->component`에서 component를 얻고 `snd_soc_component_read()`로 `WM8974_DAC` register를 읽어 mute bit 0x40을 제외한 값을 보존한다.
`mute`가 참이면 `snd_soc_component_write()`로 0x40 bit를 설정하고, 거짓이면 해당 bit가 제거된 값을 기록한다. 처리가 끝나면 0을 반환한다. `direction` 인자는 callback signature에 유지된다.
Mute flag에 따라 WM8974_DAC의 bit 0x40을 갱신한다.
DAC 앞의 mute bit가 digital sample 유입을 제어한다.
Codec DAC digital mute control
------------------------------
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.
A callback can be created that is called by the core for each codec DAI
when the mute is applied or freed.
i.e.
::
static int wm8974_mute(struct snd_soc_dai *dai, int mute, int direction)
{
struct snd_soc_component *component = dai->component;
u16 mute_reg = snd_soc_component_read(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;
}
요약·해설
codec.rst:1-190ASoC codec class driver가 platform·machine 종속 코드와 분리해 제공해야 하는 DAI·PCM capability, Regmap I/O, mixer control macro, PCM operation, DAPM description·event와 DAC digital mute를 설명합니다. WM8731 및 WM8974 예제를 원문 좌표와 함께 정리합니다.