Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
7f084afa
Commit
7f084afa
authored
Nov 11, 2016
by
Takashi Iwai
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'topic/restize-docs' into for-next
parents
a04dae9e
c6ab9e57
Changes
13
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
526 additions
and
349 deletions
+526
-349
Documentation/sound/index.rst
Documentation/sound/index.rst
+1
-0
Documentation/sound/soc/clocking.rst
Documentation/sound/soc/clocking.rst
+4
-9
Documentation/sound/soc/codec-to-codec.rst
Documentation/sound/soc/codec-to-codec.rst
+108
-0
Documentation/sound/soc/codec.rst
Documentation/sound/soc/codec.rst
+43
-32
Documentation/sound/soc/dai.rst
Documentation/sound/soc/dai.rst
+18
-10
Documentation/sound/soc/dapm.rst
Documentation/sound/soc/dapm.rst
+143
-106
Documentation/sound/soc/dpcm.rst
Documentation/sound/soc/dpcm.rst
+146
-134
Documentation/sound/soc/index.rst
Documentation/sound/soc/index.rst
+20
-0
Documentation/sound/soc/jack.rst
Documentation/sound/soc/jack.rst
+1
-0
Documentation/sound/soc/machine.rst
Documentation/sound/soc/machine.rst
+13
-9
Documentation/sound/soc/overview.rst
Documentation/sound/soc/overview.rst
+3
-29
Documentation/sound/soc/platform.rst
Documentation/sound/soc/platform.rst
+17
-14
Documentation/sound/soc/pops-clicks.rst
Documentation/sound/soc/pops-clicks.rst
+9
-6
No files found.
Documentation/sound/index.rst
View file @
7f084afa
...
@@ -7,6 +7,7 @@ Linux Sound Subsystem Documentation
...
@@ -7,6 +7,7 @@ Linux Sound Subsystem Documentation
kernel-api/index
kernel-api/index
designs/index
designs/index
soc/index
alsa-configuration
alsa-configuration
hd-audio/index
hd-audio/index
cards/index
cards/index
...
...
Documentation/sound/
alsa/soc/clocking.tx
t
→
Documentation/sound/
soc/clocking.rs
t
View file @
7f084afa
==============
Audio Clocking
Audio Clocking
==============
==============
...
@@ -30,15 +31,9 @@ runs at exactly the sample rate (LRC = Rate).
...
@@ -30,15 +31,9 @@ runs at exactly the sample rate (LRC = Rate).
Bit Clock can be generated as follows:-
Bit Clock can be generated as follows:-
BCLK = MCLK / x
- BCLK = MCLK / x, or
- BCLK = LRC * x, or
or
- BCLK = LRC * Channels * Word Size
BCLK = LRC * x
or
BCLK = LRC * Channels * Word Size
This relationship depends on the codec or SoC CPU in particular. In general
This relationship depends on the codec or SoC CPU in particular. In general
it is best to configure BCLK to the lowest possible speed (depending on your
it is best to configure BCLK to the lowest possible speed (depending on your
...
...
Documentation/sound/soc/codec-to-codec.rst
0 → 100644
View file @
7f084afa
==============================================
Creating codec to codec dai link for ALSA dapm
==============================================
Mostly the flow of audio is always from CPU to codec so your system
will look as below:
::
--------- ---------
| | dai | |
CPU -------> codec
| | | |
--------- ---------
In case your system looks as below:
::
---------
| |
codec-2
| |
---------
|
dai-2
|
---------- ---------
| | dai-1 | |
CPU -------> codec-1
| | | |
---------- ---------
|
dai-3
|
---------
| |
codec-3
| |
---------
Suppose codec-2 is a bluetooth chip and codec-3 is connected to
a speaker and you have a below scenario:
codec-2 will receive the audio data and the user wants to play that
audio through codec-3 without involving the CPU.This
aforementioned case is the ideal case when codec to codec
connection should be used.
Your dai_link should appear as below in your machine
file:
::
/*
* this pcm stream only supports 24 bit, 2 channel and
* 48k sampling rate.
*/
static const struct snd_soc_pcm_stream dsp_codec_params = {
.formats = SNDRV_PCM_FMTBIT_S24_LE,
.rate_min = 48000,
.rate_max = 48000,
.channels_min = 2,
.channels_max = 2,
};
{
.name = "CPU-DSP",
.stream_name = "CPU-DSP",
.cpu_dai_name = "samsung-i2s.0",
.codec_name = "codec-2,
.codec_dai_name = "codec-2-dai_name",
.platform_name = "samsung-i2s.0",
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
| SND_SOC_DAIFMT_CBM_CFM,
.ignore_suspend = 1,
.params = &dsp_codec_params,
},
{
.name = "DSP-CODEC",
.stream_name = "DSP-CODEC",
.cpu_dai_name = "wm0010-sdi2",
.codec_name = "codec-3,
.codec_dai_name = "codec-3-dai_name",
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
| SND_SOC_DAIFMT_CBM_CFM,
.ignore_suspend = 1,
.params = &dsp_codec_params,
},
Above code snippet is motivated from sound/soc/samsung/speyside.c.
Note the "params" callback which lets the dapm know that this
dai_link is a codec to codec connection.
In dapm core a route is created between cpu_dai playback widget
and codec_dai capture widget for playback path and vice-versa is
true for capture path. In order for this aforementioned route to get
triggered, DAPM needs to find a valid endpoint which could be either
a sink or source widget corresponding to playback and capture path
respectively.
In order to trigger this dai_link widget, a thin codec driver for
the speaker amp can be created as demonstrated in wm8727.c file, it
sets appropriate constraints for the device even if it needs no control.
Make sure to name your corresponding cpu and codec playback and capture
dai names ending with "Playback" and "Capture" respectively as dapm core
will link and power those dais based on the name.
Note that in current device tree there is no way to mark a dai_link
as codec to codec. However, it may change in future.
Documentation/sound/
alsa/soc/codec.tx
t
→
Documentation/sound/
soc/codec.rs
t
View file @
7f084afa
=======================
ASoC Codec Class Driver
ASoC Codec Class Driver
=======================
=======================
...
@@ -9,16 +10,16 @@ machine drivers respectively.
...
@@ -9,16 +10,16 @@ machine drivers respectively.
Each codec class driver *must* provide the following features:-
Each codec class driver *must* provide the following features:-
1)
Codec DAI and PCM configuration
1.
Codec DAI and PCM configuration
2)
Codec control IO - using RegMap API
2.
Codec control IO - using RegMap API
3)
Mixers and audio controls
3.
Mixers and audio controls
4)
Codec audio operations
4.
Codec audio operations
5)
DAPM description.
5.
DAPM description.
6)
DAPM event handler.
6.
DAPM event handler.
Optionally, codec drivers can also provide:-
Optionally, codec drivers can also provide:-
7)
DAC Digital mute control.
7.
DAC Digital mute control.
Its probably best to use this guide in conjunction with the existing codec
Its probably best to use this guide in conjunction with the existing codec
driver code in sound/soc/codecs/
driver code in sound/soc/codecs/
...
@@ -26,24 +27,25 @@ driver code in sound/soc/codecs/
...
@@ -26,24 +27,25 @@ driver code in sound/soc/codecs/
ASoC Codec driver breakdown
ASoC Codec driver breakdown
===========================
===========================
1 -
Codec DAI and PCM configuration
Codec DAI and PCM configuration
-------------------------------
----
-------------------------------
Each codec driver must have a struct snd_soc_dai_driver to define its DAI and
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
PCM capabilities and operations. This struct is exported so that it can be
registered with the core by your machine driver.
registered with the core by your machine driver.
e.g.
e.g.
::
static struct snd_soc_dai_ops wm8731_dai_ops = {
static struct snd_soc_dai_ops wm8731_dai_ops = {
.prepare = wm8731_pcm_prepare,
.prepare = wm8731_pcm_prepare,
.hw_params = wm8731_hw_params,
.hw_params = wm8731_hw_params,
.shutdown = wm8731_shutdown,
.shutdown = wm8731_shutdown,
.digital_mute = wm8731_mute,
.digital_mute = wm8731_mute,
.set_sysclk = wm8731_set_dai_sysclk,
.set_sysclk = wm8731_set_dai_sysclk,
.set_fmt = wm8731_set_dai_fmt,
.set_fmt = wm8731_set_dai_fmt,
};
};
struct snd_soc_dai_driver wm8731_dai = {
struct snd_soc_dai_driver wm8731_dai = {
.name = "wm8731-hifi",
.name = "wm8731-hifi",
.playback = {
.playback = {
.stream_name = "Playback",
.stream_name = "Playback",
...
@@ -59,25 +61,27 @@ struct snd_soc_dai_driver wm8731_dai = {
...
@@ -59,25 +61,27 @@ struct snd_soc_dai_driver wm8731_dai = {
.formats = WM8731_FORMATS,},
.formats = WM8731_FORMATS,},
.ops = &wm8731_dai_ops,
.ops = &wm8731_dai_ops,
.symmetric_rates = 1,
.symmetric_rates = 1,
};
};
2 -
Codec control IO
Codec control IO
----------------
----
----------------
The codec can usually be controlled via an I2C or SPI style interface
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
(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
Regmap API for all codec IO. Please see include/linux/regmap.h and existing
codec drivers for example regmap usage.
codec drivers for example regmap usage.
3 -
Mixers and audio controls
Mixers and audio controls
-------------------------
----
-------------------------
All the codec mixers and audio controls can be defined using the convenience
All the codec mixers and audio controls can be defined using the convenience
macros defined in soc.h.
macros defined in soc.h.
::
#define SOC_SINGLE(xname, reg, shift, mask, invert)
#define SOC_SINGLE(xname, reg, shift, mask, invert)
Defines a single control as follows:-
Defines a single control as follows:-
::
xname = Control name e.g. "Playback Volume"
xname = Control name e.g. "Playback Volume"
reg = codec register
reg = codec register
...
@@ -86,18 +90,22 @@ Defines a single control as follows:-
...
@@ -86,18 +90,22 @@ Defines a single control as follows:-
invert = the control is inverted
invert = the control is inverted
Other macros include:-
Other macros include:-
::
#define SOC_DOUBLE(xname, reg, shift_left, shift_right, mask, invert)
#define SOC_DOUBLE(xname, reg, shift_left, shift_right, mask, invert)
A stereo control
A stereo control
::
#define SOC_DOUBLE_R(xname, reg_left, reg_right, shift, mask, invert)
#define SOC_DOUBLE_R(xname, reg_left, reg_right, shift, mask, invert)
A stereo control spanning 2 registers
A stereo control spanning 2 registers
::
#define SOC_ENUM_SINGLE(xreg, xshift, xmask, xtexts)
#define SOC_ENUM_SINGLE(xreg, xshift, xmask, xtexts)
Defines an single enumerated control as follows:-
Defines an single enumerated control as follows:-
::
xreg = register
xreg = register
xshift = control bit(s) offset in register
xshift = control bit(s) offset in register
...
@@ -109,25 +117,26 @@ Defines an single enumerated control as follows:-
...
@@ -109,25 +117,26 @@ Defines an single enumerated control as follows:-
Defines a stereo enumerated control
Defines a stereo enumerated control
4 -
Codec Audio Operations
Codec Audio Operations
----------------------
----
----------------------
The codec driver also supports the following ALSA PCM operations:-
The codec driver also supports the following ALSA PCM operations:-
::
/* SoC audio ops */
/* SoC audio ops */
struct snd_soc_ops {
struct snd_soc_ops {
int (*startup)(struct snd_pcm_substream *);
int (*startup)(struct snd_pcm_substream *);
void (*shutdown)(struct snd_pcm_substream *);
void (*shutdown)(struct snd_pcm_substream *);
int (*hw_params)(struct snd_pcm_substream *, struct snd_pcm_hw_params *);
int (*hw_params)(struct snd_pcm_substream *, struct snd_pcm_hw_params *);
int (*hw_free)(struct snd_pcm_substream *);
int (*hw_free)(struct snd_pcm_substream *);
int (*prepare)(struct snd_pcm_substream *);
int (*prepare)(struct snd_pcm_substream *);
};
};
Please refer to the ALSA driver PCM documentation for details.
Please refer to the ALSA driver PCM documentation for details.
http://www.alsa-project.org/~iwai/writing-an-alsa-driver/
http://www.alsa-project.org/~iwai/writing-an-alsa-driver/
5 - DAPM description.
DAPM description
----------------
-----
----------------
The Dynamic Audio Power Management description describes the codec power
The Dynamic Audio Power Management description describes the codec power
components and their relationships and registers to the ASoC core.
components and their relationships and registers to the ASoC core.
Please read dapm.txt for details of building the description.
Please read dapm.txt for details of building the description.
...
@@ -135,13 +144,14 @@ Please read dapm.txt for details of building the description.
...
@@ -135,13 +144,14 @@ Please read dapm.txt for details of building the description.
Please also see the examples in other codec drivers.
Please also see the examples in other codec drivers.
6 -
DAPM event handler
DAPM event handler
------------------
----
------------------
This function is a callback that handles codec domain PM calls and system
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
domain PM calls (e.g. suspend and resume). It is used to put the codec
to sleep when not in use.
to sleep when not in use.
Power states:-
Power states:-
::
SNDRV_CTL_POWER_D0: /* full On */
SNDRV_CTL_POWER_D0: /* full On */
/* vref/mid, clk and osc on, active */
/* vref/mid, clk and osc on, active */
...
@@ -155,8 +165,8 @@ Power states:-
...
@@ -155,8 +165,8 @@ Power states:-
SNDRV_CTL_POWER_D3cold: /* Everything Off, without power */
SNDRV_CTL_POWER_D3cold: /* Everything Off, without power */
7 -
Codec DAC digital mute control
Codec DAC digital mute control
------------------------------
----
------------------------------
Most codecs have a digital mute before the DACs that can be used to
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
minimise any system noise. The mute stops any digital data from
entering the DAC.
entering the DAC.
...
@@ -165,9 +175,10 @@ A callback can be created that is called by the core for each codec DAI
...
@@ -165,9 +175,10 @@ A callback can be created that is called by the core for each codec DAI
when the mute is applied or freed.
when the mute is applied or freed.
i.e.
i.e.
::
static int wm8974_mute(struct snd_soc_dai *dai, int mute)
static int wm8974_mute(struct snd_soc_dai *dai, int mute)
{
{
struct snd_soc_codec *codec = dai->codec;
struct snd_soc_codec *codec = dai->codec;
u16 mute_reg = snd_soc_read(codec, WM8974_DAC) & 0xffbf;
u16 mute_reg = snd_soc_read(codec, WM8974_DAC) & 0xffbf;
...
@@ -176,4 +187,4 @@ static int wm8974_mute(struct snd_soc_dai *dai, int mute)
...
@@ -176,4 +187,4 @@ static int wm8974_mute(struct snd_soc_dai *dai, int mute)
else
else
snd_soc_write(codec, WM8974_DAC, mute_reg);
snd_soc_write(codec, WM8974_DAC, mute_reg);
return 0;
return 0;
}
}
Documentation/sound/
alsa/soc/DAI.tx
t
→
Documentation/sound/
soc/dai.rs
t
View file @
7f084afa
==================================
ASoC Digital Audio Interface (DAI)
==================================
ASoC currently supports the three main Digital Audio Interfaces (DAI) found on
ASoC currently supports the three main Digital Audio Interfaces (DAI) found on
SoC controllers and portable audio CODECs today, namely AC97, I2S and PCM.
SoC controllers and portable audio CODECs today, namely AC97, I2S and PCM.
...
@@ -5,21 +9,21 @@ SoC controllers and portable audio CODECs today, namely AC97, I2S and PCM.
...
@@ -5,21 +9,21 @@ SoC controllers and portable audio CODECs today, namely AC97, I2S and PCM.
AC97
AC97
====
====
AC97 is a five wire interface commonly found on many PC sound cards. It is
AC97 is a five wire interface commonly found on many PC sound cards. It is
now also popular in many portable devices. This DAI has a reset line and time
now also popular in many portable devices. This DAI has a reset line and time
multiplexes its data on its SDATA_OUT (playback) and SDATA_IN (capture) lines.
multiplexes its data on its SDATA_OUT (playback) and SDATA_IN (capture) lines.
The bit clock (BCLK) is always driven by the CODEC (usually 12.288MHz) and the
The bit clock (BCLK) is always driven by the CODEC (usually 12.288MHz) and the
frame (FRAME) (usually 48kHz) is always driven by the controller. Each AC97
frame (FRAME) (usually 48kHz) is always driven by the controller. Each AC97
frame is 21uS long and is divided into 13 time slots.
frame is 21uS long and is divided into 13 time slots.
The AC97 specification can be found at :
-
The AC97 specification can be found at :
http://www.intel.com/p/en_US/business/design
http://www.intel.com/p/en_US/business/design
I2S
I2S
===
===
I2S is a common 4 wire DAI used in HiFi, STB and portable devices. The Tx and
I2S is a common 4 wire DAI used in HiFi, STB and portable devices. The Tx and
Rx lines are used for audio transmission, whilst the bit clock (BCLK) and
Rx lines are used for audio transmission, whilst the bit clock (BCLK) and
left/right clock (LRC) synchronise the link. I2S is flexible in that either the
left/right clock (LRC) synchronise the link. I2S is flexible in that either the
controller or CODEC can drive (master) the BCLK and LRC clock lines. Bit clock
controller or CODEC can drive (master) the BCLK and LRC clock lines. Bit clock
...
@@ -30,13 +34,15 @@ different sample rates.
...
@@ -30,13 +34,15 @@ different sample rates.
I2S has several different operating modes:-
I2S has several different operating modes:-
o I2S - MSB is transmitted on the falling edge of the first BCLK after LRC
I2S
MSB is transmitted on the falling edge of the first BCLK after LRC
transition.
transition.
o Left Justified - MSB is transmitted on transition of LRC.
Left Justified
MSB is transmitted on transition of LRC.
o Right Justified - MSB is transmitted sample size BCLKs before LRC
Right Justified
transition.
MSB is transmitted sample size BCLKs before LRC
transition.
PCM
PCM
===
===
...
@@ -51,6 +57,8 @@ is sometimes referred to as network mode).
...
@@ -51,6 +57,8 @@ is sometimes referred to as network mode).
Common PCM operating modes:-
Common PCM operating modes:-
o Mode A - MSB is transmitted on falling edge of first BCLK after FRAME/SYNC.
Mode A
MSB is transmitted on falling edge of first BCLK after FRAME/SYNC.
o Mode B - MSB is transmitted on rising edge of FRAME/SYNC.
Mode B
MSB is transmitted on rising edge of FRAME/SYNC.
Documentation/sound/
alsa/soc/dapm.tx
t
→
Documentation/sound/
soc/dapm.rs
t
View file @
7f084afa
===================================================
Dynamic Audio Power Management for Portable Devices
Dynamic Audio Power Management for Portable Devices
===================================================
===================================================
1.
Description
Description
===========
===
===========
Dynamic Audio Power Management (DAPM) is designed to allow portable
Dynamic Audio Power Management (DAPM) is designed to allow portable
Linux devices to use the minimum amount of power within the audio
Linux devices to use the minimum amount of power within the audio
...
@@ -21,20 +22,28 @@ level power systems.
...
@@ -21,20 +22,28 @@ level power systems.
There are 4 power domains within DAPM
There are 4 power domains within DAPM
1. Codec bias domain - VREF, VMID (core codec and audio power)
Codec bias domain
VREF, VMID (core codec and audio power)
Usually controlled at codec probe/remove and suspend/resume, although
Usually controlled at codec probe/remove and suspend/resume, although
can be set at stream time if power is not needed for sidetone, etc.
can be set at stream time if power is not needed for sidetone, etc.
2. Platform/Machine domain - physically connected inputs and outputs
Platform/Machine domain
physically connected inputs and outputs
Is platform/machine and user action specific, is configured by the
Is platform/machine and user action specific, is configured by the
machine driver and responds to asynchronous events e.g when HP
machine driver and responds to asynchronous events e.g when HP
are inserted
are inserted
3. Path domain - audio subsystem signal paths
Path domain
audio subsystem signal paths
Automatically set when mixer and mux settings are changed by the user.
Automatically set when mixer and mux settings are changed by the user.
e.g. alsamixer, amixer.
e.g. alsamixer, amixer.
4. Stream domain - DACs and ADCs.
Stream domain
DACs and ADCs.
Enabled and disabled when stream playback/capture is started and
Enabled and disabled when stream playback/capture is started and
stopped respectively. e.g. aplay, arecord.
stopped respectively. e.g. aplay, arecord.
...
@@ -45,34 +54,57 @@ internal codec components). All audio components that effect power are called
...
@@ -45,34 +54,57 @@ internal codec components). All audio components that effect power are called
widgets hereafter.
widgets hereafter.
2.
DAPM Widgets
DAPM Widgets
============
===
============
Audio DAPM widgets fall into a number of types:-
Audio DAPM widgets fall into a number of types:-
o Mixer - Mixes several analog signals into a single analog signal.
Mixer
o Mux - An analog switch that outputs only one of many inputs.
Mixes several analog signals into a single analog signal.
o PGA - A programmable gain amplifier or attenuation widget.
Mux
o ADC - Analog to Digital Converter
An analog switch that outputs only one of many inputs.
o DAC - Digital to Analog Converter
PGA
o Switch - An analog switch
A programmable gain amplifier or attenuation widget.
o Input - A codec input pin
ADC
o Output - A codec output pin
Analog to Digital Converter
o Headphone - Headphone (and optional Jack)
DAC
o Mic - Mic (and optional Jack)
Digital to Analog Converter
o Line - Line Input/Output (and optional Jack)
Switch
o Speaker - Speaker
An analog switch
o Supply - Power or clock supply widget used by other widgets.
Input
o Regulator - External regulator that supplies power to audio components.
A codec input pin
o Clock - External clock that supplies clock to audio components.
Output
o AIF IN - Audio Interface Input (with TDM slot mask).
A codec output pin
o AIF OUT - Audio Interface Output (with TDM slot mask).
Headphone
o Siggen - Signal Generator.
Headphone (and optional Jack)
o DAI IN - Digital Audio Interface Input.
Mic
o DAI OUT - Digital Audio Interface Output.
Mic (and optional Jack)
o DAI Link - DAI Link between two DAI structures */
Line
o Pre - Special PRE widget (exec before all others)
Line Input/Output (and optional Jack)
o Post - Special POST widget (exec after all others)
Speaker
Speaker
Supply
Power or clock supply widget used by other widgets.
Regulator
External regulator that supplies power to audio components.
Clock
External clock that supplies clock to audio components.
AIF IN
Audio Interface Input (with TDM slot mask).
AIF OUT
Audio Interface Output (with TDM slot mask).
Siggen
Signal Generator.
DAI IN
Digital Audio Interface Input.
DAI OUT
Digital Audio Interface Output.
DAI Link
DAI Link between two DAI structures
Pre
Special PRE widget (exec before all others)
Post
Special POST widget (exec after all others)
(Widgets are defined in include/sound/soc-dapm.h)
(Widgets are defined in include/sound/soc-dapm.h)
...
@@ -84,52 +116,57 @@ Most widgets have a name, register, shift and invert. Some widgets have extra
...
@@ -84,52 +116,57 @@ Most widgets have a name, register, shift and invert. Some widgets have extra
parameters for stream name and kcontrols.
parameters for stream name and kcontrols.
2.1
Stream Domain Widgets
Stream Domain Widgets
---------------------
----
---------------------
Stream Widgets relate to the stream power domain and only consist of ADCs
Stream Widgets relate to the stream power domain and only consist of ADCs
(analog to digital converters), DACs (digital to analog converters),
(analog to digital converters), DACs (digital to analog converters),
AIF IN and AIF OUT.
AIF IN and AIF OUT.
Stream widgets have the following format:-
Stream widgets have the following format:-
::
SND_SOC_DAPM_DAC(name, stream name, reg, shift, invert),
SND_SOC_DAPM_DAC(name, stream name, reg, shift, invert),
SND_SOC_DAPM_AIF_IN(name, stream, slot, reg, shift, invert)
SND_SOC_DAPM_AIF_IN(name, stream, slot, reg, shift, invert)
NOTE: the stream name must match the corresponding stream name in your codec
NOTE: the stream name must match the corresponding stream name in your codec
snd_soc_codec_dai.
snd_soc_codec_dai.
e.g. stream widgets for HiFi playback and capture
e.g. stream widgets for HiFi playback and capture
::
SND_SOC_DAPM_DAC("HiFi DAC", "HiFi Playback", REG, 3, 1),
SND_SOC_DAPM_DAC("HiFi DAC", "HiFi Playback", REG, 3, 1),
SND_SOC_DAPM_ADC("HiFi ADC", "HiFi Capture", REG, 2, 1),
SND_SOC_DAPM_ADC("HiFi ADC", "HiFi Capture", REG, 2, 1),
e.g. stream widgets for AIF
e.g. stream widgets for AIF
::
SND_SOC_DAPM_AIF_IN("AIF1RX", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_AIF_IN("AIF1RX", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_AIF_OUT("AIF1TX", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_AIF_OUT("AIF1TX", "AIF1 Capture", 0, SND_SOC_NOPM, 0, 0),
2.2
Path Domain Widgets
Path Domain Widgets
-------------------
----
-------------------
Path domain widgets have a ability to control or affect the audio signal or
Path domain widgets have a ability to control or affect the audio signal or
audio paths within the audio subsystem. They have the following form:-
audio paths within the audio subsystem. They have the following form:-
::
SND_SOC_DAPM_PGA(name, reg, shift, invert, controls, num_controls)
SND_SOC_DAPM_PGA(name, reg, shift, invert, controls, num_controls)
Any widget kcontrols can be set using the controls and num_controls members.
Any widget kcontrols can be set using the controls and num_controls members.
e.g. Mixer widget (the kcontrols are declared first)
e.g. Mixer widget (the kcontrols are declared first)
::
/* Output Mixer */
/* Output Mixer */
static const snd_kcontrol_new_t wm8731_output_mixer_controls[] = {
static const snd_kcontrol_new_t wm8731_output_mixer_controls[] = {
SOC_DAPM_SINGLE("Line Bypass Switch", WM8731_APANA, 3, 1, 0),
SOC_DAPM_SINGLE("Line Bypass Switch", WM8731_APANA, 3, 1, 0),
SOC_DAPM_SINGLE("Mic Sidetone Switch", WM8731_APANA, 5, 1, 0),
SOC_DAPM_SINGLE("Mic Sidetone Switch", WM8731_APANA, 5, 1, 0),
SOC_DAPM_SINGLE("HiFi Playback Switch", WM8731_APANA, 4, 1, 0),
SOC_DAPM_SINGLE("HiFi Playback Switch", WM8731_APANA, 4, 1, 0),
};
};
SND_SOC_DAPM_MIXER("Output Mixer", WM8731_PWR, 4, 1, wm8731_output_mixer_controls,
SND_SOC_DAPM_MIXER("Output Mixer", WM8731_PWR, 4, 1, wm8731_output_mixer_controls,
ARRAY_SIZE(wm8731_output_mixer_controls)),
ARRAY_SIZE(wm8731_output_mixer_controls)),
If you don't want the mixer elements prefixed with the name of the mixer widget,
If you don't want the mixer elements prefixed with the name of the mixer widget,
...
@@ -137,48 +174,49 @@ you can use SND_SOC_DAPM_MIXER_NAMED_CTL instead. the parameters are the same
...
@@ -137,48 +174,49 @@ you can use SND_SOC_DAPM_MIXER_NAMED_CTL instead. the parameters are the same
as for SND_SOC_DAPM_MIXER.
as for SND_SOC_DAPM_MIXER.
2.3
Machine domain Widgets
Machine domain Widgets
----------------------
----
----------------------
Machine widgets are different from codec widgets in that they don't have a
Machine widgets are different from codec widgets in that they don't have a
codec register bit associated with them. A machine widget is assigned to each
codec register bit associated with them. A machine widget is assigned to each
machine audio component (non codec or DSP) that can be independently
machine audio component (non codec or DSP) that can be independently
powered. e.g.
powered. e.g.
o
Speaker Amp
*
Speaker Amp
o
Microphone Bias
*
Microphone Bias
o
Jack connectors
*
Jack connectors
A machine widget can have an optional call back.
A machine widget can have an optional call back.
e.g. Jack connector widget for an external Mic that enables Mic Bias
e.g. Jack connector widget for an external Mic that enables Mic Bias
when the Mic is inserted:-
when the Mic is inserted:-
::
static int spitz_mic_bias(struct snd_soc_dapm_widget* w, int event)
static int spitz_mic_bias(struct snd_soc_dapm_widget* w, int event)
{
{
gpio_set_value(SPITZ_GPIO_MIC_BIAS, SND_SOC_DAPM_EVENT_ON(event));
gpio_set_value(SPITZ_GPIO_MIC_BIAS, SND_SOC_DAPM_EVENT_ON(event));
return 0;
return 0;
}
}
SND_SOC_DAPM_MIC("Mic Jack", spitz_mic_bias),
SND_SOC_DAPM_MIC("Mic Jack", spitz_mic_bias),
2.4
Codec (BIAS) Domain
Codec (BIAS) Domain
-------------------
----
-------------------
The codec bias power domain has no widgets and is handled by the codecs DAPM
The codec bias power domain has no widgets and is handled by the codecs DAPM
event handler. This handler is called when the codec powerstate is changed wrt
event handler. This handler is called when the codec powerstate is changed wrt
to any stream event or by kernel PM events.
to any stream event or by kernel PM events.
2.5
Virtual Widgets
Virtual Widgets
---------------
----
---------------
Sometimes widgets exist in the codec or machine audio map that don't have any
Sometimes widgets exist in the codec or machine audio map that don't have any
corresponding soft power control. In this case it is necessary to create
corresponding soft power control. In this case it is necessary to create
a virtual widget - a widget with no control bits e.g.
a virtual widget - a widget with no control bits e.g.
::
SND_SOC_DAPM_MIXER("AC97 Mixer", SND_SOC_DAPM_NOPM, 0, 0, NULL, 0),
SND_SOC_DAPM_MIXER("AC97 Mixer", SND_SOC_DAPM_NOPM, 0, 0, NULL, 0),
This can be used to merge to signal paths together in software.
This can be used to merge to signal paths together in software.
...
@@ -186,8 +224,8 @@ After all the widgets have been defined, they can then be added to the DAPM
...
@@ -186,8 +224,8 @@ After all the widgets have been defined, they can then be added to the DAPM
subsystem individually with a call to snd_soc_dapm_new_control().
subsystem individually with a call to snd_soc_dapm_new_control().
3.
Codec/DSP Widget Interconnections
Codec/DSP Widget Interconnections
=================================
===
=================================
Widgets are connected to each other within the codec, platform and machine by
Widgets are connected to each other within the codec, platform and machine by
audio paths (called interconnections). Each interconnection must be defined in
audio paths (called interconnections). Each interconnection must be defined in
...
@@ -201,13 +239,14 @@ e.g., from the WM8731 output mixer (wm8731.c)
...
@@ -201,13 +239,14 @@ e.g., from the WM8731 output mixer (wm8731.c)
The WM8731 output mixer has 3 inputs (sources)
The WM8731 output mixer has 3 inputs (sources)
1. Line Bypass Input
1. Line Bypass Input
2. DAC (HiFi playback)
2. DAC (HiFi playback)
3. Mic Sidetone Input
3. Mic Sidetone Input
Each input in this example has a kcontrol associated with it (defined in example
Each input in this example has a kcontrol associated with it (defined in example
above) and is connected to the output mixer via its kcontrol name. We can now
above) and is connected to the output mixer via its kcontrol name. We can now
connect the destination widget (wrt audio signal) with its source widgets.
connect the destination widget (wrt audio signal) with its source widgets.
::
/* output mixer */
/* output mixer */
{"Output Mixer", "Line Bypass Switch", "Line Input"},
{"Output Mixer", "Line Bypass Switch", "Line Input"},
...
@@ -216,22 +255,17 @@ connect the destination widget (wrt audio signal) with its source widgets.
...
@@ -216,22 +255,17 @@ connect the destination widget (wrt audio signal) with its source widgets.
So we have :-
So we have :-
Destination Widget <=== Path Name <=== Source Widget
* Destination Widget <=== Path Name <=== Source Widget, or
* Sink, Path, Source, or
Or:-
* ``Output Mixer`` is connected to the ``DAC`` via the ``HiFi Playback Switch``.
Sink, Path, Source
Or :-
"Output Mixer" is connected to the "DAC" via the "HiFi Playback Switch".
When there is no path name connecting widgets (e.g. a direct connection) we
When there is no path name connecting widgets (e.g. a direct connection) we
pass NULL for the path name.
pass NULL for the path name.
Interconnections are created with a call to:-
Interconnections are created with a call to:-
::
snd_soc_dapm_connect_input(codec, sink, path, source);
snd_soc_dapm_connect_input(codec, sink, path, source);
Finally, snd_soc_dapm_new_widgets(codec) must be called after all widgets and
Finally, snd_soc_dapm_new_widgets(codec) must be called after all widgets and
interconnections have been registered with the core. This causes the core to
interconnections have been registered with the core. This causes the core to
...
@@ -239,12 +273,13 @@ scan the codec and machine so that the internal DAPM state matches the
...
@@ -239,12 +273,13 @@ scan the codec and machine so that the internal DAPM state matches the
physical state of the machine.
physical state of the machine.
3.1
Machine Widget Interconnections
Machine Widget Interconnections
-------------------------------
----
-------------------------------
Machine widget interconnections are created in the same way as codec ones and
Machine widget interconnections are created in the same way as codec ones and
directly connect the codec pins to machine level widgets.
directly connect the codec pins to machine level widgets.
e.g. connects the speaker out codec pins to the internal speaker.
e.g. connects the speaker out codec pins to the internal speaker.
::
/* ext speaker connected to codec pins LOUT2, ROUT2 */
/* ext speaker connected to codec pins LOUT2, ROUT2 */
{"Ext Spk", NULL , "ROUT2"},
{"Ext Spk", NULL , "ROUT2"},
...
@@ -254,52 +289,54 @@ This allows the DAPM to power on and off pins that are connected (and in use)
...
@@ -254,52 +289,54 @@ This allows the DAPM to power on and off pins that are connected (and in use)
and pins that are NC respectively.
and pins that are NC respectively.
4
Endpoint Widgets
Endpoint Widgets
================
===
================
An endpoint is a start or end point (widget) of an audio signal within the
An endpoint is a start or end point (widget) of an audio signal within the
machine and includes the codec. e.g.
machine and includes the codec. e.g.
o
Headphone Jack
*
Headphone Jack
o
Internal Speaker
*
Internal Speaker
o
Internal Mic
*
Internal Mic
o
Mic Jack
*
Mic Jack
o
Codec Pins
*
Codec Pins
Endpoints are added to the DAPM graph so that their usage can be determined in
Endpoints are added to the DAPM graph so that their usage can be determined in
order to save power. e.g. NC codecs pins will be switched OFF, unconnected
order to save power. e.g. NC codecs pins will be switched OFF, unconnected
jacks can also be switched OFF.
jacks can also be switched OFF.
5
DAPM Widget Events
DAPM Widget Events
==================
==
==================
Some widgets can register their interest with the DAPM core in PM events.
Some widgets can register their interest with the DAPM core in PM events.
e.g. A Speaker with an amplifier registers a widget so the amplifier can be
e.g. A Speaker with an amplifier registers a widget so the amplifier can be
powered only when the spk is in use.
powered only when the spk is in use.
::
/* turn speaker amplifier on/off depending on use */
/* turn speaker amplifier on/off depending on use */
static int corgi_amp_event(struct snd_soc_dapm_widget *w, int event)
static int corgi_amp_event(struct snd_soc_dapm_widget *w, int event)
{
{
gpio_set_value(CORGI_GPIO_APM_ON, SND_SOC_DAPM_EVENT_ON(event));
gpio_set_value(CORGI_GPIO_APM_ON, SND_SOC_DAPM_EVENT_ON(event));
return 0;
return 0;
}
}
/* corgi machine dapm widgets */
/* corgi machine dapm widgets */
static const struct snd_soc_dapm_widget wm8731_dapm_widgets =
static const struct snd_soc_dapm_widget wm8731_dapm_widgets =
SND_SOC_DAPM_SPK("Ext Spk", corgi_amp_event);
SND_SOC_DAPM_SPK("Ext Spk", corgi_amp_event);
Please see soc-dapm.h for all other widgets that support events.
Please see soc-dapm.h for all other widgets that support events.
5.1
Event types
Event types
-----------
----
-----------
The following event types are supported by event widgets.
The following event types are supported by event widgets.
::
/* dapm event types */
#define SND_SOC_DAPM_PRE_PMU 0x1 /* before widget power up */
/* dapm event types */
#define SND_SOC_DAPM_POST_PMU 0x2 /* after widget power up */
#define SND_SOC_DAPM_PRE_PMU 0x1 /* before widget power up */
#define SND_SOC_DAPM_PRE_PMD 0x4 /* before widget power down */
#define SND_SOC_DAPM_POST_PMU 0x2 /* after widget power up */
#define SND_SOC_DAPM_POST_PMD 0x8 /* after widget power down */
#define SND_SOC_DAPM_PRE_PMD 0x4 /* before widget power down */
#define SND_SOC_DAPM_PRE_REG 0x10 /* before audio path setup */
#define SND_SOC_DAPM_POST_PMD 0x8 /* after widget power down */
#define SND_SOC_DAPM_POST_REG 0x20 /* after audio path setup */
#define SND_SOC_DAPM_PRE_REG 0x10 /* before audio path setup */
#define SND_SOC_DAPM_POST_REG 0x20 /* after audio path setup */
Documentation/sound/
alsa/soc/DPCM.tx
t
→
Documentation/sound/
soc/dpcm.rs
t
View file @
7f084afa
===========
Dynamic PCM
Dynamic PCM
===========
===========
1.
Description
Description
===========
===
===========
Dynamic PCM allows an ALSA PCM device to digitally route its PCM audio to
Dynamic PCM allows an ALSA PCM device to digitally route its PCM audio to
various digital endpoints during the PCM stream runtime. e.g. PCM0 can route
various digital endpoints during the PCM stream runtime. e.g. PCM0 can route
...
@@ -23,17 +24,18 @@ Phone Audio System with SoC based DSP
...
@@ -23,17 +24,18 @@ Phone Audio System with SoC based DSP
Consider the following phone audio subsystem. This will be used in this
Consider the following phone audio subsystem. This will be used in this
document for all examples :-
document for all examples :-
::
| Front End PCMs | SoC DSP | Back End DAIs | Audio devices |
| Front End PCMs | SoC DSP | Back End DAIs | Audio devices |
*************
*************
PCM0 <------------> * * <----DAI0-----> Codec Headset
PCM0 <------------> * * <----DAI0-----> Codec Headset
* *
* *
PCM1 <------------> * * <----DAI1-----> Codec Speakers
PCM1 <------------> * * <----DAI1-----> Codec Speakers
* DSP *
* DSP *
PCM2 <------------> * * <----DAI2-----> MODEM
PCM2 <------------> * * <----DAI2-----> MODEM
* *
* *
PCM3 <------------> * * <----DAI3-----> BT
PCM3 <------------> * * <----DAI3-----> BT
* *
* *
* * <----DAI4-----> DMIC
* * <----DAI4-----> DMIC
* *
* *
...
@@ -55,15 +57,16 @@ Audio is being played to the Headset. After a while the user removes the headset
...
@@ -55,15 +57,16 @@ Audio is being played to the Headset. After a while the user removes the headset
and audio continues playing on the speakers.
and audio continues playing on the speakers.
Playback on PCM0 to Headset would look like :-
Playback on PCM0 to Headset would look like :-
::
*************
*************
PCM0 <============> * * <====DAI0=====> Codec Headset
PCM0 <============> * * <====DAI0=====> Codec Headset
* *
* *
PCM1 <------------> * * <----DAI1-----> Codec Speakers
PCM1 <------------> * * <----DAI1-----> Codec Speakers
* DSP *
* DSP *
PCM2 <------------> * * <----DAI2-----> MODEM
PCM2 <------------> * * <----DAI2-----> MODEM
* *
* *
PCM3 <------------> * * <----DAI3-----> BT
PCM3 <------------> * * <----DAI3-----> BT
* *
* *
* * <----DAI4-----> DMIC
* * <----DAI4-----> DMIC
* *
* *
...
@@ -71,15 +74,16 @@ PCM3 <------------> * * <----DAI3-----> BT
...
@@ -71,15 +74,16 @@ PCM3 <------------> * * <----DAI3-----> BT
*************
*************
The headset is removed from the jack by user so the speakers must now be used :-
The headset is removed from the jack by user so the speakers must now be used :-
::
*************
*************
PCM0 <============> * * <----DAI0-----> Codec Headset
PCM0 <============> * * <----DAI0-----> Codec Headset
* *
* *
PCM1 <------------> * * <====DAI1=====> Codec Speakers
PCM1 <------------> * * <====DAI1=====> Codec Speakers
* DSP *
* DSP *
PCM2 <------------> * * <----DAI2-----> MODEM
PCM2 <------------> * * <----DAI2-----> MODEM
* *
* *
PCM3 <------------> * * <----DAI3-----> BT
PCM3 <------------> * * <----DAI3-----> BT
* *
* *
* * <----DAI4-----> DMIC
* * <----DAI4-----> DMIC
* *
* *
...
@@ -88,16 +92,16 @@ PCM3 <------------> * * <----DAI3-----> BT
...
@@ -88,16 +92,16 @@ PCM3 <------------> * * <----DAI3-----> BT
The audio driver processes this as follows :-
The audio driver processes this as follows :-
1)
Machine driver receives Jack removal event.
1.
Machine driver receives Jack removal event.
2)
Machine driver OR audio HAL disables the Headset path.
2.
Machine driver OR audio HAL disables the Headset path.
3)
DPCM runs the PCM trigger(stop), hw_free(), shutdown() operations on DAI0
3.
DPCM runs the PCM trigger(stop), hw_free(), shutdown() operations on DAI0
for headset since the path is now disabled.
for headset since the path is now disabled.
4)
Machine driver or audio HAL enables the speaker path.
4.
Machine driver or audio HAL enables the speaker path.
5)
DPCM runs the PCM ops for startup(), hw_params(), prepapre() and
5.
DPCM runs the PCM ops for startup(), hw_params(), prepapre() and
trigger(start) for DAI1 Speakers since the path is enabled.
trigger(start) for DAI1 Speakers since the path is enabled.
In this example, the machine driver or userspace audio HAL can alter the routing
In this example, the machine driver or userspace audio HAL can alter the routing
...
@@ -112,26 +116,27 @@ DPCM machine driver
...
@@ -112,26 +116,27 @@ DPCM machine driver
The DPCM enabled ASoC machine driver is similar to normal machine drivers
The DPCM enabled ASoC machine driver is similar to normal machine drivers
except that we also have to :-
except that we also have to :-
1)
Define the FE and BE DAI links.
1.
Define the FE and BE DAI links.
2)
Define any FE/BE PCM operations.
2.
Define any FE/BE PCM operations.
3)
Define widget graph connections.
3.
Define widget graph connections.
1 FE and BE DAI links
FE and BE DAI links
---------------------
-------------------
::
| Front End PCMs | SoC DSP | Back End DAIs | Audio devices |
| Front End PCMs | SoC DSP | Back End DAIs | Audio devices |
*************
*************
PCM0 <------------> * * <----DAI0-----> Codec Headset
PCM0 <------------> * * <----DAI0-----> Codec Headset
* *
* *
PCM1 <------------> * * <----DAI1-----> Codec Speakers
PCM1 <------------> * * <----DAI1-----> Codec Speakers
* DSP *
* DSP *
PCM2 <------------> * * <----DAI2-----> MODEM
PCM2 <------------> * * <----DAI2-----> MODEM
* *
* *
PCM3 <------------> * * <----DAI3-----> BT
PCM3 <------------> * * <----DAI3-----> BT
* *
* *
* * <----DAI4-----> DMIC
* * <----DAI4-----> DMIC
* *
* *
...
@@ -140,8 +145,9 @@ PCM3 <------------> * * <----DAI3-----> BT
...
@@ -140,8 +145,9 @@ PCM3 <------------> * * <----DAI3-----> BT
For the example above we have to define 4 FE DAI links and 6 BE DAI links. The
For the example above we have to define 4 FE DAI links and 6 BE DAI links. The
FE DAI links are defined as follows :-
FE DAI links are defined as follows :-
::
static struct snd_soc_dai_link machine_dais[] = {
static struct snd_soc_dai_link machine_dais[] = {
{
{
.name = "PCM0 System",
.name = "PCM0 System",
.stream_name = "System Playback",
.stream_name = "System Playback",
...
@@ -154,11 +160,11 @@ static struct snd_soc_dai_link machine_dais[] = {
...
@@ -154,11 +160,11 @@ static struct snd_soc_dai_link machine_dais[] = {
.dpcm_playback = 1,
.dpcm_playback = 1,
},
},
.....< other FE and BE DAI links here >
.....< other FE and BE DAI links here >
};
};
This FE DAI link is pretty similar to a regular DAI link except that we also
This FE DAI link is pretty similar to a regular DAI link except that we also
set the DAI link to a DPCM FE with the
"dynamic = 1"
. The supported FE stream
set the DAI link to a DPCM FE with the
``dynamic = 1``
. The supported FE stream
directions should also be set with the
"dpcm_playback" and "dpcm_capture"
directions should also be set with the
``dpcm_playback`` and ``dpcm_capture``
flags. There is also an option to specify the ordering of the trigger call for
flags. There is also an option to specify the ordering of the trigger call for
each FE. This allows the ASoC core to trigger the DSP before or after the other
each FE. This allows the ASoC core to trigger the DSP before or after the other
components (as some DSPs have strong requirements for the ordering DAI/DSP
components (as some DSPs have strong requirements for the ordering DAI/DSP
...
@@ -168,8 +174,9 @@ The FE DAI above sets the codec and code DAIs to dummy devices since the BE is
...
@@ -168,8 +174,9 @@ The FE DAI above sets the codec and code DAIs to dummy devices since the BE is
dynamic and will change depending on runtime config.
dynamic and will change depending on runtime config.
The BE DAIs are configured as follows :-
The BE DAIs are configured as follows :-
::
static struct snd_soc_dai_link machine_dais[] = {
static struct snd_soc_dai_link machine_dais[] = {
.....< FE DAI links here >
.....< FE DAI links here >
{
{
.name = "Codec Headset",
.name = "Codec Headset",
...
@@ -186,24 +193,25 @@ static struct snd_soc_dai_link machine_dais[] = {
...
@@ -186,24 +193,25 @@ static struct snd_soc_dai_link machine_dais[] = {
.dpcm_capture = 1,
.dpcm_capture = 1,
},
},
.....< other BE DAI links here >
.....< other BE DAI links here >
};
};
This BE DAI link connects DAI0 to the codec (in this case RT5460 AIF1). It sets
This BE DAI link connects DAI0 to the codec (in this case RT5460 AIF1). It sets
the
"no_pcm"
flag to mark it has a BE and sets flags for supported stream
the
``no_pcm``
flag to mark it has a BE and sets flags for supported stream
directions using
"dpcm_playback" and "dpcm_capture"
above.
directions using
``dpcm_playback`` and ``dpcm_capture``
above.
The BE has also flags set for ignoring suspend and PM down time. This allows
The BE has also flags set for ignoring suspend and PM down time. This allows
the BE to work in a hostless mode where the host CPU is not transferring data
the BE to work in a hostless mode where the host CPU is not transferring data
like a BT phone call :-
like a BT phone call :-
::
*************
*************
PCM0 <------------> * * <----DAI0-----> Codec Headset
PCM0 <------------> * * <----DAI0-----> Codec Headset
* *
* *
PCM1 <------------> * * <----DAI1-----> Codec Speakers
PCM1 <------------> * * <----DAI1-----> Codec Speakers
* DSP *
* DSP *
PCM2 <------------> * * <====DAI2=====> MODEM
PCM2 <------------> * * <====DAI2=====> MODEM
* *
* *
PCM3 <------------> * * <====DAI3=====> BT
PCM3 <------------> * * <====DAI3=====> BT
* *
* *
* * <----DAI4-----> DMIC
* * <----DAI4-----> DMIC
* *
* *
...
@@ -220,10 +228,10 @@ Likewise a BE DAI can also set a dummy cpu DAI if the CPU DAI is managed by the
...
@@ -220,10 +228,10 @@ Likewise a BE DAI can also set a dummy cpu DAI if the CPU DAI is managed by the
DSP firmware.
DSP firmware.
2
FE/BE PCM operations
FE/BE PCM operations
--------------------
--
--------------------
The BE above also exports some PCM operations and a
"fixup"
callback. The fixup
The BE above also exports some PCM operations and a
``fixup``
callback. The fixup
callback is used by the machine driver to (re)configure the DAI based upon the
callback is used by the machine driver to (re)configure the DAI based upon the
FE hw params. i.e. the DSP may perform SRC or ASRC from the FE to BE.
FE hw params. i.e. the DSP may perform SRC or ASRC from the FE to BE.
...
@@ -231,10 +239,11 @@ e.g. DSP converts all FE hw params to run at fixed rate of 48k, 16bit, stereo fo
...
@@ -231,10 +239,11 @@ e.g. DSP converts all FE hw params to run at fixed rate of 48k, 16bit, stereo fo
DAI0. This means all FE hw_params have to be fixed in the machine driver for
DAI0. This means all FE hw_params have to be fixed in the machine driver for
DAI0 so that the DAI is running at desired configuration regardless of the FE
DAI0 so that the DAI is running at desired configuration regardless of the FE
configuration.
configuration.
::
static int dai0_fixup(struct snd_soc_pcm_runtime *rtd,
static int dai0_fixup(struct snd_soc_pcm_runtime *rtd,
struct snd_pcm_hw_params *params)
struct snd_pcm_hw_params *params)
{
{
struct snd_interval *rate = hw_param_interval(params,
struct snd_interval *rate = hw_param_interval(params,
SNDRV_PCM_HW_PARAM_RATE);
SNDRV_PCM_HW_PARAM_RATE);
struct snd_interval *channels = hw_param_interval(params,
struct snd_interval *channels = hw_param_interval(params,
...
@@ -249,21 +258,22 @@ static int dai0_fixup(struct snd_soc_pcm_runtime *rtd,
...
@@ -249,21 +258,22 @@ static int dai0_fixup(struct snd_soc_pcm_runtime *rtd,
SNDRV_PCM_HW_PARAM_FIRST_MASK],
SNDRV_PCM_HW_PARAM_FIRST_MASK],
SNDRV_PCM_FORMAT_S16_LE);
SNDRV_PCM_FORMAT_S16_LE);
return 0;
return 0;
}
}
The other PCM operation are the same as for regular DAI links. Use as necessary.
The other PCM operation are the same as for regular DAI links. Use as necessary.
3
Widget graph connections
Widget graph connections
------------------------
--
------------------------
The BE DAI links will normally be connected to the graph at initialisation time
The BE DAI links will normally be connected to the graph at initialisation time
by the ASoC DAPM core. However, if the BE codec or BE DAI is a dummy then this
by the ASoC DAPM core. However, if the BE codec or BE DAI is a dummy then this
has to be set explicitly in the driver :-
has to be set explicitly in the driver :-
::
/* BE for codec Headset - DAI0 is dummy and managed by DSP FW */
/* BE for codec Headset - DAI0 is dummy and managed by DSP FW */
{"DAI0 CODEC IN", NULL, "AIF1 Capture"},
{"DAI0 CODEC IN", NULL, "AIF1 Capture"},
{"AIF1 Playback", NULL, "DAI0 CODEC OUT"},
{"AIF1 Playback", NULL, "DAI0 CODEC OUT"},
Writing a DPCM DSP driver
Writing a DPCM DSP driver
...
@@ -273,24 +283,25 @@ The DPCM DSP driver looks much like a standard platform class ASoC driver
...
@@ -273,24 +283,25 @@ The DPCM DSP driver looks much like a standard platform class ASoC driver
combined with elements from a codec class driver. A DSP platform driver must
combined with elements from a codec class driver. A DSP platform driver must
implement :-
implement :-
1)
Front End PCM DAIs - i.e. struct snd_soc_dai_driver.
1.
Front End PCM DAIs - i.e. struct snd_soc_dai_driver.
2)
DAPM graph showing DSP audio routing from FE DAIs to BEs.
2.
DAPM graph showing DSP audio routing from FE DAIs to BEs.
3)
DAPM widgets from DSP graph.
3.
DAPM widgets from DSP graph.
4)
Mixers for gains, routing, etc.
4.
Mixers for gains, routing, etc.
5)
DMA configuration.
5.
DMA configuration.
6)
BE AIF widgets.
6.
BE AIF widgets.
Items 6 is important for routing the audio outside of the DSP. AIF need to be
Items 6 is important for routing the audio outside of the DSP. AIF need to be
defined for each BE and each stream direction. e.g for BE DAI0 above we would
defined for each BE and each stream direction. e.g for BE DAI0 above we would
have :-
have :-
::
SND_SOC_DAPM_AIF_IN("DAI0 RX", NULL, 0, SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_AIF_IN("DAI0 RX", NULL, 0, SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_AIF_OUT("DAI0 TX", NULL, 0, SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_AIF_OUT("DAI0 TX", NULL, 0, SND_SOC_NOPM, 0, 0),
The BE AIF are used to connect the DSP graph to the graphs for the other
The BE AIF are used to connect the DSP graph to the graphs for the other
component drivers (e.g. codec graph).
component drivers (e.g. codec graph).
...
@@ -301,16 +312,16 @@ Hostless PCM streams
...
@@ -301,16 +312,16 @@ Hostless PCM streams
A hostless PCM stream is a stream that is not routed through the host CPU. An
A hostless PCM stream is a stream that is not routed through the host CPU. An
example of this would be a phone call from handset to modem.
example of this would be a phone call from handset to modem.
::
*************
*************
PCM0 <------------> * * <----DAI0-----> Codec Headset
PCM0 <------------> * * <----DAI0-----> Codec Headset
* *
* *
PCM1 <------------> * * <====DAI1=====> Codec Speakers/Mic
PCM1 <------------> * * <====DAI1=====> Codec Speakers/Mic
* DSP *
* DSP *
PCM2 <------------> * * <====DAI2=====> MODEM
PCM2 <------------> * * <====DAI2=====> MODEM
* *
* *
PCM3 <------------> * * <----DAI3-----> BT
PCM3 <------------> * * <----DAI3-----> BT
* *
* *
* * <----DAI4-----> DMIC
* * <----DAI4-----> DMIC
* *
* *
...
@@ -322,12 +333,12 @@ is only used for control and can sleep during the runtime of the stream.
...
@@ -322,12 +333,12 @@ is only used for control and can sleep during the runtime of the stream.
The host can control the hostless link either by :-
The host can control the hostless link either by :-
1
)
Configuring the link as a CODEC <-> CODEC style link. In this case the link
1
.
Configuring the link as a CODEC <-> CODEC style link. In this case the link
is enabled or disabled by the state of the DAPM graph. This usually means
is enabled or disabled by the state of the DAPM graph. This usually means
there is a mixer control that can be used to connect or disconnect the path
there is a mixer control that can be used to connect or disconnect the path
between both DAIs.
between both DAIs.
2
)
Hostless FE. This FE has a virtual connection to the BE DAI links on the DAPM
2
.
Hostless FE. This FE has a virtual connection to the BE DAI links on the DAPM
graph. Control is then carried out by the FE as regular PCM operations.
graph. Control is then carried out by the FE as regular PCM operations.
This method gives more control over the DAI links, but requires much more
This method gives more control over the DAI links, but requires much more
userspace code to control the link. Its recommended to use CODEC<->CODEC
userspace code to control the link. Its recommended to use CODEC<->CODEC
...
@@ -339,16 +350,17 @@ CODEC <-> CODEC link
...
@@ -339,16 +350,17 @@ CODEC <-> CODEC link
This DAI link is enabled when DAPM detects a valid path within the DAPM graph.
This DAI link is enabled when DAPM detects a valid path within the DAPM graph.
The machine driver sets some additional parameters to the DAI link i.e.
The machine driver sets some additional parameters to the DAI link i.e.
::
static const struct snd_soc_pcm_stream dai_params = {
static const struct snd_soc_pcm_stream dai_params = {
.formats = SNDRV_PCM_FMTBIT_S32_LE,
.formats = SNDRV_PCM_FMTBIT_S32_LE,
.rate_min = 8000,
.rate_min = 8000,
.rate_max = 8000,
.rate_max = 8000,
.channels_min = 2,
.channels_min = 2,
.channels_max = 2,
.channels_max = 2,
};
};
static struct snd_soc_dai_link dais[] = {
static struct snd_soc_dai_link dais[] = {
< ... more DAI links above ... >
< ... more DAI links above ... >
{
{
.name = "MODEM",
.name = "MODEM",
...
...
Documentation/sound/soc/index.rst
0 → 100644
View file @
7f084afa
==============
ALSA SoC Layer
==============
The documentation is spilt into the following sections:-
.. toctree::
:maxdepth: 2
overview
codec
dai
dapm
platform
machine
pops-clicks
clocking
jack
dpcm
codec-to-codec
Documentation/sound/
alsa/soc/jack.tx
t
→
Documentation/sound/
soc/jack.rs
t
View file @
7f084afa
===================
ASoC jack detection
ASoC jack detection
===================
===================
...
...
Documentation/sound/
alsa/soc/machine.tx
t
→
Documentation/sound/
soc/machine.rs
t
View file @
7f084afa
===================
ASoC Machine Driver
ASoC Machine Driver
===================
===================
...
@@ -9,9 +10,10 @@ interrupts, clocking, jacks and voltage regulators.
...
@@ -9,9 +10,10 @@ interrupts, clocking, jacks and voltage regulators.
The machine driver can contain codec and platform specific code. It registers
The machine driver can contain codec and platform specific code. It registers
the audio subsystem with the kernel as a platform device and is represented by
the audio subsystem with the kernel as a platform device and is represented by
the following struct:-
the following struct:-
::
/* SoC machine */
/* SoC machine */
struct snd_soc_card {
struct snd_soc_card {
char *name;
char *name;
...
...
...
@@ -33,7 +35,7 @@ struct snd_soc_card {
...
@@ -33,7 +35,7 @@ struct snd_soc_card {
int num_links;
int num_links;
...
...
};
};
probe()/remove()
probe()/remove()
----------------
----------------
...
@@ -55,9 +57,10 @@ initialisation e.g. the machine audio map can be connected to the codec audio
...
@@ -55,9 +57,10 @@ initialisation e.g. the machine audio map can be connected to the codec audio
map, unconnected codec pins can be set as such.
map, unconnected codec pins can be set as such.
struct snd_soc_dai_link is used to set up each DAI in your machine. e.g.
struct snd_soc_dai_link is used to set up each DAI in your machine. e.g.
::
/* corgi digital audio interface glue - connects codec <--> CPU */
/* corgi digital audio interface glue - connects codec <--> CPU */
static struct snd_soc_dai_link corgi_dai = {
static struct snd_soc_dai_link corgi_dai = {
.name = "WM8731",
.name = "WM8731",
.stream_name = "WM8731",
.stream_name = "WM8731",
.cpu_dai_name = "pxa-is2-dai",
.cpu_dai_name = "pxa-is2-dai",
...
@@ -66,16 +69,17 @@ static struct snd_soc_dai_link corgi_dai = {
...
@@ -66,16 +69,17 @@ static struct snd_soc_dai_link corgi_dai = {
.codec_name = "wm8713-codec.0-001a",
.codec_name = "wm8713-codec.0-001a",
.init = corgi_wm8731_init,
.init = corgi_wm8731_init,
.ops = &corgi_ops,
.ops = &corgi_ops,
};
};
struct snd_soc_card then sets up the machine with its DAIs. e.g.
struct snd_soc_card then sets up the machine with its DAIs. e.g.
::
/* corgi audio machine driver */
/* corgi audio machine driver */
static struct snd_soc_card snd_soc_corgi = {
static struct snd_soc_card snd_soc_corgi = {
.name = "Corgi",
.name = "Corgi",
.dai_link = &corgi_dai,
.dai_link = &corgi_dai,
.num_links = 1,
.num_links = 1,
};
};
Machine Power Map
Machine Power Map
...
...
Documentation/sound/
alsa/soc/overview.tx
t
→
Documentation/sound/
soc/overview.rs
t
View file @
7f084afa
ALSA SoC Layer
=======================
==============
ALSA SoC Layer Overview
=======================
The overall project goal of the ALSA System on Chip (ASoC) layer is to
The overall project goal of the ALSA System on Chip (ASoC) layer is to
provide better ALSA support for embedded system-on-chip processors (e.g.
provide better ALSA support for embedded system-on-chip processors (e.g.
...
@@ -66,30 +67,3 @@ multiple re-usable component drivers :-
...
@@ -66,30 +67,3 @@ multiple re-usable component drivers :-
describes and binds the other component drivers together to form an ALSA
describes and binds the other component drivers together to form an ALSA
"sound card device". It handles any machine specific controls and
"sound card device". It handles any machine specific controls and
machine level audio events (e.g. turning on an amp at start of playback).
machine level audio events (e.g. turning on an amp at start of playback).
Documentation
=============
The documentation is spilt into the following sections:-
overview.txt: This file.
codec.txt: Codec driver internals.
DAI.txt: Description of Digital Audio Interface standards and how to configure
a DAI within your codec and CPU DAI drivers.
dapm.txt: Dynamic Audio Power Management
platform.txt: Platform audio DMA and DAI.
machine.txt: Machine driver internals.
pop_clicks.txt: How to minimise audio artifacts.
clocking.txt: ASoC clocking for best power performance.
jack.txt: ASoC jack detection.
DPCM.txt: Dynamic PCM - Describes DPCM with DSP examples.
Documentation/sound/
alsa/soc/platform.tx
t
→
Documentation/sound/
soc/platform.rs
t
View file @
7f084afa
====================
ASoC Platform Driver
ASoC Platform Driver
====================
====================
...
@@ -9,21 +10,23 @@ Audio DMA
...
@@ -9,21 +10,23 @@ Audio DMA
=========
=========
The platform DMA driver optionally supports the following ALSA operations:-
The platform DMA driver optionally supports the following ALSA operations:-
::
/* SoC audio ops */
/* SoC audio ops */
struct snd_soc_ops {
struct snd_soc_ops {
int (*startup)(struct snd_pcm_substream *);
int (*startup)(struct snd_pcm_substream *);
void (*shutdown)(struct snd_pcm_substream *);
void (*shutdown)(struct snd_pcm_substream *);
int (*hw_params)(struct snd_pcm_substream *, struct snd_pcm_hw_params *);
int (*hw_params)(struct snd_pcm_substream *, struct snd_pcm_hw_params *);
int (*hw_free)(struct snd_pcm_substream *);
int (*hw_free)(struct snd_pcm_substream *);
int (*prepare)(struct snd_pcm_substream *);
int (*prepare)(struct snd_pcm_substream *);
int (*trigger)(struct snd_pcm_substream *, int);
int (*trigger)(struct snd_pcm_substream *, int);
};
};
The platform driver exports its DMA functionality via struct
The platform driver exports its DMA functionality via struct
snd_soc_platform_driver:-
snd_soc_platform_driver:-
::
struct snd_soc_platform_driver {
struct snd_soc_platform_driver {
char *name;
char *name;
int (*probe)(struct platform_device *pdev);
int (*probe)(struct platform_device *pdev);
...
@@ -44,7 +47,7 @@ struct snd_soc_platform_driver {
...
@@ -44,7 +47,7 @@ struct snd_soc_platform_driver {
/* platform stream ops */
/* platform stream ops */
struct snd_pcm_ops *pcm_ops;
struct snd_pcm_ops *pcm_ops;
};
};
Please refer to the ALSA driver documentation for details of audio DMA.
Please refer to the ALSA driver documentation for details of audio DMA.
http://www.alsa-project.org/~iwai/writing-an-alsa-driver/
http://www.alsa-project.org/~iwai/writing-an-alsa-driver/
...
@@ -57,11 +60,11 @@ SoC DAI Drivers
...
@@ -57,11 +60,11 @@ SoC DAI Drivers
Each SoC DAI driver must provide the following features:-
Each SoC DAI driver must provide the following features:-
1)
Digital audio interface (DAI) description
1.
Digital audio interface (DAI) description
2)
Digital audio interface configuration
2.
Digital audio interface configuration
3)
PCM's description
3.
PCM's description
4)
SYSCLK configuration
4.
SYSCLK configuration
5)
Suspend and resume (optional)
5.
Suspend and resume (optional)
Please see codec.txt for a description of items 1 - 4.
Please see codec.txt for a description of items 1 - 4.
...
@@ -71,9 +74,9 @@ SoC DSP Drivers
...
@@ -71,9 +74,9 @@ SoC DSP Drivers
Each SoC DSP driver usually supplies the following features :-
Each SoC DSP driver usually supplies the following features :-
1)
DAPM graph
1.
DAPM graph
2)
Mixer controls
2.
Mixer controls
3)
DMA IO to/from DSP buffers (if applicable)
3.
DMA IO to/from DSP buffers (if applicable)
4)
Definition of DSP front end (FE) PCM devices.
4.
Definition of DSP front end (FE) PCM devices.
Please see DPCM.txt for a description of item 4.
Please see DPCM.txt for a description of item 4.
Documentation/sound/
alsa/soc/pops_clicks.tx
t
→
Documentation/sound/
soc/pops-clicks.rs
t
View file @
7f084afa
=====================
Audio Pops and Clicks
Audio Pops and Clicks
=====================
=====================
...
@@ -20,6 +21,7 @@ currently, however future audio codec hardware will have better pop and click
...
@@ -20,6 +21,7 @@ currently, however future audio codec hardware will have better pop and click
suppression. Pops can be reduced within playback by powering the audio
suppression. Pops can be reduced within playback by powering the audio
components in a specific order. This order is different for startup and
components in a specific order. This order is different for startup and
shutdown and follows some basic rules:-
shutdown and follows some basic rules:-
::
Startup Order :- DAC --> Mixers --> Output PGA --> Digital Unmute
Startup Order :- DAC --> Mixers --> Output PGA --> Digital Unmute
...
@@ -36,6 +38,7 @@ Capture artifacts are somewhat easier to get rid as we can delay activating the
...
@@ -36,6 +38,7 @@ Capture artifacts are somewhat easier to get rid as we can delay activating the
ADC until all the pops have occurred. This follows similar power rules to
ADC until all the pops have occurred. This follows similar power rules to
playback in that components are powered in a sequence depending upon stream
playback in that components are powered in a sequence depending upon stream
startup or shutdown.
startup or shutdown.
::
Startup Order - Input PGA --> Mixers --> ADC
Startup Order - Input PGA --> Mixers --> ADC
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment