This series applies various improvements to the DAPM documentation: a
rewrite of a few sections for clarity, style improvements and typo fixes.
Signed-off-by: Luca Ceresoli <[email protected]>
---
Changes in v2:
- avoid wrapping in patch 3 as suggested by Alex
- Link to v1: https://lore.kernel.org/r/[email protected]
---
Luca Ceresoli (12):
ASoC: doc: dapm: fix typos
ASoC: doc: dapm: fix struct name
ASoC: doc: dapm: minor rewording
ASoC: doc: dapm: remove dash after colon
ASoC: doc: dapm: clarify it's an internal API
ASoC: doc: dapm: replace "map" with "graph"
ASoC: doc: dapm: extend initial descrption
ASoC: doc: dapm: describe how widgets and routes are registered
ASoC: doc: dapm: fix and improve section "Registering DAPM controls"
ASoC: doc: dapm: improve section "Codec/DSP Widget Interconnections"
ASoC: doc: dapm: update section "DAPM Widget Events"
ASoC: doc: dapm: update event types
Documentation/sound/soc/dapm-graph.svg | 375 +++++++++++++++++++++++++++++++++
Documentation/sound/soc/dapm.rst | 174 ++++++++++-----
2 files changed, 492 insertions(+), 57 deletions(-)
---
base-commit: c942a0cd3603e34dd2d7237e064d9318cb7f9654
change-id: 20240315-dapm-docs-79bd51f267db
Best regards,
--
Luca Ceresoli <[email protected]>
Fix various typos.
Reviewed-by: Alexandre Belloni <[email protected]>
Reviewed-by: Bagas Sanjaya <[email protected]>
Signed-off-by: Luca Ceresoli <[email protected]>
---
Documentation/sound/soc/dapm.rst | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/Documentation/sound/soc/dapm.rst b/Documentation/sound/soc/dapm.rst
index c3154ce6e1b2..59f65b181828 100644
--- a/Documentation/sound/soc/dapm.rst
+++ b/Documentation/sound/soc/dapm.rst
@@ -50,7 +50,7 @@ Stream domain
All DAPM power switching decisions are made automatically by consulting an audio
routing map of the whole machine. This map is specific to each machine and
consists of the interconnections between every audio component (including
-internal codec components). All audio components that effect power are called
+internal codec components). All audio components that affect power are called
widgets hereafter.
@@ -221,7 +221,7 @@ when the Mic is inserted:-::
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 codec DAPM
event handler. This handler is called when the codec powerstate is changed wrt
to any stream event or by kernel PM events.
@@ -236,7 +236,7 @@ a virtual widget - a widget with no control bits e.g.
SND_SOC_DAPM_MIXER("AC97 Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
-This can be used to merge to signal paths together in software.
+This can be used to merge two signal paths together in software.
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().
--
2.34.1
struct snd_soc_codec_dai does not exist.
Reviewed-by: Alexandre Belloni <[email protected]>
Signed-off-by: Luca Ceresoli <[email protected]>
---
Documentation/sound/soc/dapm.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Documentation/sound/soc/dapm.rst b/Documentation/sound/soc/dapm.rst
index 59f65b181828..68ef79f539f2 100644
--- a/Documentation/sound/soc/dapm.rst
+++ b/Documentation/sound/soc/dapm.rst
@@ -148,7 +148,7 @@ Stream widgets have the following format:-
SND_SOC_DAPM_AIF_IN(name, stream, slot, reg, shift, invert)
NOTE: the stream name must match the corresponding stream name in your codec
-snd_soc_codec_dai.
+snd_soc_dai_driver.
e.g. stream widgets for HiFi playback and capture
::
--
2.34.1
Slightly reword for better readability: replace "PM" -> "power management
frameworks", add missing comma.
Reviewed-by: Alexandre Belloni <[email protected]>
Reviewed-by: Bagas Sanjaya <[email protected]>
Signed-off-by: Luca Ceresoli <[email protected]>
---
Changed in v2:
- don't rewrap the whole paragraph (no change to the actual patch content)
---
Documentation/sound/soc/dapm.rst | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Documentation/sound/soc/dapm.rst b/Documentation/sound/soc/dapm.rst
index 68ef79f539f2..479c010d2dac 100644
--- a/Documentation/sound/soc/dapm.rst
+++ b/Documentation/sound/soc/dapm.rst
@@ -7,8 +7,8 @@ Description
Dynamic Audio Power Management (DAPM) is designed to allow portable
Linux devices to use the minimum amount of power within the audio
-subsystem at all times. It is independent of other kernel PM and as
-such, can easily co-exist with the other PM systems.
+subsystem at all times. It is independent of other kernel power
+management frameworks and, as such, can easily co-exist with them.
DAPM is also completely transparent to all user space applications as
all power switching is done within the ASoC core. No code changes or
--
2.34.1
There is no need for a dash after colons. Also fix an incorrect ":-::"
sequence.
Reviewed-by: Alexandre Belloni <[email protected]>
Signed-off-by: Luca Ceresoli <[email protected]>
---
Documentation/sound/soc/dapm.rst | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/Documentation/sound/soc/dapm.rst b/Documentation/sound/soc/dapm.rst
index 479c010d2dac..be849879274d 100644
--- a/Documentation/sound/soc/dapm.rst
+++ b/Documentation/sound/soc/dapm.rst
@@ -20,7 +20,7 @@ DAPM spans the whole machine. It covers power control within the entire
audio subsystem, this includes internal codec power blocks and machine
level power systems.
-There are 4 power domains within DAPM
+There are 4 power domains within DAPM:
Codec bias domain
VREF, VMID (core codec and audio power)
@@ -57,7 +57,7 @@ widgets hereafter.
DAPM Widgets
============
-Audio DAPM widgets fall into a number of types:-
+Audio DAPM widgets fall into a number of types:
Mixer
Mixes several analog signals into a single analog signal.
@@ -141,7 +141,7 @@ Stream Widgets relate to the stream power domain and only consist of ADCs
(analog to digital converters), DACs (digital to analog converters),
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),
@@ -167,7 +167,7 @@ Path Domain Widgets
-------------------
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)
@@ -207,7 +207,7 @@ powered. e.g.
A machine widget can have an optional call back.
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)
{
@@ -271,7 +271,7 @@ connect the destination widget (wrt audio signal) with its source widgets.
{"Output Mixer", "HiFi Playback Switch", "DAC"},
{"Output Mixer", "Mic Sidetone Switch", "Mic Bias"},
-So we have :-
+So we have :
* Destination Widget <=== Path Name <=== Source Widget, or
* Sink, Path, Source, or
@@ -280,7 +280,7 @@ So we have :-
When there is no path name connecting widgets (e.g. a direct connection) we
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);
--
2.34.1
Clarify DAPM does not expose any API to user space, and adapt the paragraph
accordingly.
Reviewed-by: Alexandre Belloni <[email protected]>
Reviewed-by: Bagas Sanjaya <[email protected]>
Signed-off-by: Luca Ceresoli <[email protected]>
---
Documentation/sound/soc/dapm.rst | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/Documentation/sound/soc/dapm.rst b/Documentation/sound/soc/dapm.rst
index be849879274d..f96a32f137aa 100644
--- a/Documentation/sound/soc/dapm.rst
+++ b/Documentation/sound/soc/dapm.rst
@@ -11,9 +11,10 @@ subsystem at all times. It is independent of other kernel power
management frameworks and, as such, can easily co-exist with them.
DAPM is also completely transparent to all user space applications as
-all power switching is done within the ASoC core. No code changes or
-recompiling are required for user space applications. DAPM makes power
-switching decisions based upon any audio stream (capture/playback)
+all power switching is done internally to the ASoC core. For this reason
+DAPM does not expose a kernel API to user space and no code changes or
+recompiling are required for user space applications to use it. DAPM makes
+power switching decisions based upon any audio stream (capture/playback)
activity and audio mixer settings within the device.
DAPM spans the whole machine. It covers power control within the entire
--
2.34.1
The small paragraph describing how to register widgets is incomplete (does
not mention routes) and mentions snd_soc_dapm_new_control() which is not
really used. Moreover it appears as a part of the "Virtual Widgets"
subsection.
Replace it with a detailed and current description of how widgets and
routes are registered, mentioning both static declaration and runtime
registration. Also make this a section on its own.
Reviewed-by: Alexandre Belloni <[email protected]>
Reviewed-by: Bagas Sanjaya <[email protected]>
Signed-off-by: Luca Ceresoli <[email protected]>
---
Documentation/sound/soc/dapm.rst | 38 ++++++++++++++++++++++++++++++++++++--
1 file changed, 36 insertions(+), 2 deletions(-)
diff --git a/Documentation/sound/soc/dapm.rst b/Documentation/sound/soc/dapm.rst
index 58ef880ac8b6..4b094c3d7942 100644
--- a/Documentation/sound/soc/dapm.rst
+++ b/Documentation/sound/soc/dapm.rst
@@ -251,8 +251,42 @@ a virtual widget - a widget with no control bits e.g.
This can be used to merge two signal paths together in software.
-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().
+Registering DAPM controls
+=========================
+
+In many cases the DAPM widgets implemented statically in a ``static const
+struct snd_soc_dapm_widget`` array and the routes connecting them in a
+``static const struct snd_soc_dapm_route`` array in a codec driver, and
+simply declared via the ``dapm_widgets`` and ``num_dapm_widgets`` fields of
+the ``struct snd_soc_component_driver`` so the driver registration will
+take care of populating them::
+
+ static const struct snd_soc_dapm_widget wm2000_dapm_widgets[] = {
+ SND_SOC_DAPM_OUTPUT("SPKN"),
+ SND_SOC_DAPM_OUTPUT("SPKP"),
+ ...
+ };
+
+ /* Target, Path, Source */
+ static const struct snd_soc_dapm_route wm2000_audio_map[] = {
+ { "SPKN", NULL, "ANC Engine" },
+ { "SPKP", NULL, "ANC Engine" },
+ ...
+ };
+
+ static const struct snd_soc_component_driver soc_component_dev_wm2000 = {
+ ...
+ .dapm_widgets = wm2000_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(wm2000_dapm_widgets),
+ ...
+ };
+
+In more complex cases the list of DAPM widgets and/or routes can be only
+known at build time. This happens for example when a driver supports
+different models having a different set of features. In those cases
+separate widgets and routes arrays implementing the case-specific features
+can be registered programmatically by calling snd_soc_dapm_new_controls()
+and snd_soc_dapm_add_routes().
Codec/DSP Widget Interconnections
--
2.34.1
Extend the first paragraph to mention the {,num_}dapm_routes fields just
like the widget conterparts. Mention the route fields also in the code
example. Fix "at build time", this really means "at probe time".
Reviewed-by: Alexandre Belloni <[email protected]>
Reviewed-by: Bagas Sanjaya <[email protected]>
Signed-off-by: Luca Ceresoli <[email protected]>
---
Documentation/sound/soc/dapm.rst | 21 ++++++++++++++-------
1 file changed, 14 insertions(+), 7 deletions(-)
diff --git a/Documentation/sound/soc/dapm.rst b/Documentation/sound/soc/dapm.rst
index 4b094c3d7942..2831b00ae4e2 100644
--- a/Documentation/sound/soc/dapm.rst
+++ b/Documentation/sound/soc/dapm.rst
@@ -254,12 +254,17 @@ This can be used to merge two signal paths together in software.
Registering DAPM controls
=========================
-In many cases the DAPM widgets implemented statically in a ``static const
-struct snd_soc_dapm_widget`` array and the routes connecting them in a
-``static const struct snd_soc_dapm_route`` array in a codec driver, and
-simply declared via the ``dapm_widgets`` and ``num_dapm_widgets`` fields of
-the ``struct snd_soc_component_driver`` so the driver registration will
-take care of populating them::
+In many cases the DAPM widgets are implemented statically in a ``static
+const struct snd_soc_dapm_widget`` array in a codec driver, and simply
+declared via the ``dapm_widgets`` and ``num_dapm_widgets`` fields of the
+``struct snd_soc_component_driver``.
+
+Similarly, routes connecting them are implemented statically in a ``static
+const struct snd_soc_dapm_route`` array and declared via the
+``dapm_routes`` and ``num_dapm_routes`` fields of the same struct.
+
+With the above declared, the driver registration will take care of
+populating them::
static const struct snd_soc_dapm_widget wm2000_dapm_widgets[] = {
SND_SOC_DAPM_OUTPUT("SPKN"),
@@ -278,11 +283,13 @@ take care of populating them::
...
.dapm_widgets = wm2000_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(wm2000_dapm_widgets),
+ .dapm_routes = wm2000_audio_map,
+ .num_dapm_routes = ARRAY_SIZE(wm2000_audio_map),
...
};
In more complex cases the list of DAPM widgets and/or routes can be only
-known at build time. This happens for example when a driver supports
+known at probe time. This happens for example when a driver supports
different models having a different set of features. In those cases
separate widgets and routes arrays implementing the case-specific features
can be registered programmatically by calling snd_soc_dapm_new_controls()
--
2.34.1
Improve wording in a few places, cleanup ReST colon syntax, remove space
before colon, and remove the "codec" parameter in the parentheses of
snd_soc_dapm_new_widgets() (there should be no parameters in the docs, and
that function takes a card, not a codec).
Reviewed-by: Alexandre Belloni <[email protected]>
Signed-off-by: Luca Ceresoli <[email protected]>
---
Documentation/sound/soc/dapm.rst | 19 ++++++++-----------
1 file changed, 8 insertions(+), 11 deletions(-)
diff --git a/Documentation/sound/soc/dapm.rst b/Documentation/sound/soc/dapm.rst
index 2831b00ae4e2..6096334226c0 100644
--- a/Documentation/sound/soc/dapm.rst
+++ b/Documentation/sound/soc/dapm.rst
@@ -307,25 +307,23 @@ This is easiest with a diagram of the codec or DSP (and schematic of the machine
audio system), as it requires joining widgets together via their audio signal
paths.
-e.g., from the WM8731 output mixer (wm8731.c)
-
-The WM8731 output mixer has 3 inputs (sources)
+For example the WM8731 output mixer (wm8731.c) has 3 inputs (sources):
1. Line Bypass Input
2. DAC (HiFi playback)
3. Mic Sidetone Input
-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
-connect the destination widget (wrt audio signal) with its source widgets.
-::
+Each input in this example has a kcontrol associated with it (defined in
+the example 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. ::
/* output mixer */
{"Output Mixer", "Line Bypass Switch", "Line Input"},
{"Output Mixer", "HiFi Playback Switch", "DAC"},
{"Output Mixer", "Mic Sidetone Switch", "Mic Bias"},
-So we have :
+So we have:
* Destination Widget <=== Path Name <=== Source Widget, or
* Sink, Path, Source, or
@@ -334,12 +332,11 @@ So we have :
When there is no path name connecting widgets (e.g. a direct connection) we
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);
-Finally, snd_soc_dapm_new_widgets(codec) must be called after all widgets and
+Finally, snd_soc_dapm_new_widgets() must be called after all widgets and
interconnections have been registered with the core. This causes the core to
scan the codec and machine so that the internal DAPM state matches the
physical state of the machine.
--
2.34.1
The example in this section is not in the kernel sources anymore. Replace
it with an up to date code fragment. Reword the initial paragraph. Remove
"Please" which is not standard practice in documentation.
Reviewed-by: Alexandre Belloni <[email protected]>
Signed-off-by: Luca Ceresoli <[email protected]>
---
Documentation/sound/soc/dapm.rst | 30 ++++++++++++++++++------------
1 file changed, 18 insertions(+), 12 deletions(-)
diff --git a/Documentation/sound/soc/dapm.rst b/Documentation/sound/soc/dapm.rst
index 6096334226c0..da9313e10fd4 100644
--- a/Documentation/sound/soc/dapm.rst
+++ b/Documentation/sound/soc/dapm.rst
@@ -377,23 +377,29 @@ jacks can also be switched OFF.
DAPM Widget 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
-powered only when the spk is in use.
-::
+Widgets needing to implement a more complex behaviour than what DAPM can do
+can set a custom "event handler" by setting a function pointer. An example
+is a power supply needing to enable a GPIO::
- /* turn speaker amplifier on/off depending on use */
- static int corgi_amp_event(struct snd_soc_dapm_widget *w, int event)
+ static int sof_es8316_speaker_power_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
{
- gpio_set_value(CORGI_GPIO_APM_ON, SND_SOC_DAPM_EVENT_ON(event));
- return 0;
+ if (SND_SOC_DAPM_EVENT_ON(event))
+ gpiod_set_value_cansleep(gpio_pa, true);
+ else
+ gpiod_set_value_cansleep(gpio_pa, false);
+
+ return 0;
}
- /* corgi machine dapm widgets */
- static const struct snd_soc_dapm_widget wm8731_dapm_widgets =
- SND_SOC_DAPM_SPK("Ext Spk", corgi_amp_event);
+ static const struct snd_soc_dapm_widget st_widgets[] = {
+ ...
+ SND_SOC_DAPM_SUPPLY("Speaker Power", SND_SOC_NOPM, 0, 0,
+ sof_es8316_speaker_power_event,
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
+ };
-Please see soc-dapm.h for all other widgets that support events.
+See soc-dapm.h for all other widgets that support events.
Event types
--
2.34.1
Some new event types now exist, so update the code fragment.
Reviewed-by: Alexandre Belloni <[email protected]>
Signed-off-by: Luca Ceresoli <[email protected]>
---
Documentation/sound/soc/dapm.rst | 19 +++++++++++--------
1 file changed, 11 insertions(+), 8 deletions(-)
diff --git a/Documentation/sound/soc/dapm.rst b/Documentation/sound/soc/dapm.rst
index da9313e10fd4..574667f3aabe 100644
--- a/Documentation/sound/soc/dapm.rst
+++ b/Documentation/sound/soc/dapm.rst
@@ -405,13 +405,16 @@ See soc-dapm.h for all other widgets that support events.
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 */
- #define SND_SOC_DAPM_POST_PMU 0x2 /* after widget power up */
- #define SND_SOC_DAPM_PRE_PMD 0x4 /* before widget power down */
- #define SND_SOC_DAPM_POST_PMD 0x8 /* after widget power down */
- #define SND_SOC_DAPM_PRE_REG 0x10 /* before audio path setup */
- #define SND_SOC_DAPM_POST_REG 0x20 /* after audio path setup */
+ #define SND_SOC_DAPM_PRE_PMU 0x1 /* before widget power up */
+ #define SND_SOC_DAPM_POST_PMU 0x2 /* after widget power up */
+ #define SND_SOC_DAPM_PRE_PMD 0x4 /* before widget power down */
+ #define SND_SOC_DAPM_POST_PMD 0x8 /* after widget power down */
+ #define SND_SOC_DAPM_PRE_REG 0x10 /* before audio path setup */
+ #define SND_SOC_DAPM_POST_REG 0x20 /* after audio path setup */
+ #define SND_SOC_DAPM_WILL_PMU 0x40 /* called at start of sequence */
+ #define SND_SOC_DAPM_WILL_PMD 0x80 /* called at start of sequence */
+ #define SND_SOC_DAPM_PRE_POST_PMD (SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD)
+ #define SND_SOC_DAPM_PRE_POST_PMU (SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU)
--
2.34.1
DAPM is actually based on a graph, so use this specific term instead of the
more generic "map".
Reviewed-by: Alexandre Belloni <[email protected]>
Signed-off-by: Luca Ceresoli <[email protected]>
---
Documentation/sound/soc/dapm.rst | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/Documentation/sound/soc/dapm.rst b/Documentation/sound/soc/dapm.rst
index f96a32f137aa..11f7f2f685af 100644
--- a/Documentation/sound/soc/dapm.rst
+++ b/Documentation/sound/soc/dapm.rst
@@ -49,7 +49,7 @@ Stream domain
stopped respectively. e.g. aplay, arecord.
All DAPM power switching decisions are made automatically by consulting an audio
-routing map of the whole machine. This map is specific to each machine and
+routing graph of the whole machine. This graph is specific to each machine and
consists of the interconnections between every audio component (including
internal codec components). All audio components that affect power are called
widgets hereafter.
@@ -230,7 +230,7 @@ to any stream event or by kernel PM events.
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 graph that don't have any
corresponding soft power control. In this case it is necessary to create
a virtual widget - a widget with no control bits e.g.
::
@@ -248,7 +248,7 @@ Codec/DSP Widget Interconnections
Widgets are connected to each other within the codec, platform and machine by
audio paths (called interconnections). Each interconnection must be defined in
-order to create a map of all audio paths between widgets.
+order to create a graph of all audio paths between widgets.
This is easiest with a diagram of the codec or DSP (and schematic of the machine
audio system), as it requires joining widgets together via their audio signal
--
2.34.1
Extend the initial description providing clearer definitions of "widget"
and "route", and to stop using the word "component" to mean "widget". Give
more details and clarify wording and add a picture representing a real DAPM
graph.
Group all the introductory paragraphs before the "DAPM power domains", and
split the latter to a specific section.
Reviewed-by: Alexandre Belloni <[email protected]>
Reviewed-by: Bagas Sanjaya <[email protected]>
Signed-off-by: Luca Ceresoli <[email protected]>
---
Documentation/sound/soc/dapm-graph.svg | 375 +++++++++++++++++++++++++++++++++
Documentation/sound/soc/dapm.rst | 30 ++-
2 files changed, 396 insertions(+), 9 deletions(-)
diff --git a/Documentation/sound/soc/dapm-graph.svg b/Documentation/sound/soc/dapm-graph.svg
new file mode 100644
index 000000000000..d783672db815
--- /dev/null
+++ b/Documentation/sound/soc/dapm-graph.svg
@@ -0,0 +1,375 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
+ "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<!-- Generated by graphviz version 2.43.0 (0)
+ -->
+<!-- Title: G Pages: 1 -->
+<svg width="900pt" height="630pt"
+ viewBox="0.00 0.00 900.00 630.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 626)">
+<title>G</title>
+<polygon fill="white" stroke="transparent" points="-4,4 -4,-626 896,-626 896,4 -4,4"/>
+<g id="clust1" class="cluster">
+<title>ROOT</title>
+<polygon fill="none" stroke="dodgerblue" points="8,-537 8,-614 102,-614 102,-537 8,-537"/>
+<text text-anchor="middle" x="55" y="-598.8" font-family="sans-serif" font-size="14.00">ROOT</text>
+</g>
+<g id="clust2" class="cluster">
+<title>4000b000.audio-controller</title>
+<polygon fill="none" stroke="dodgerblue" points="120,-378 120,-455 312,-455 312,-378 120,-378"/>
+<text text-anchor="middle" x="216" y="-439.8" font-family="sans-serif" font-size="14.00">4000b000.audio-controller</text>
+</g>
+<g id="clust5" class="cluster">
+<title>cs42l51.0-004a</title>
+<polygon fill="none" stroke="dodgerblue" points="330,-8 330,-614 884,-614 884,-8 330,-8"/>
+<text text-anchor="middle" x="607" y="-598.8" font-family="sans-serif" font-size="14.00">cs42l51.0-004a</text>
+</g>
+<g id="clust9" class="cluster">
+<title>hdmi-audio-codec.1.auto</title>
+<polygon fill="none" stroke="dodgerblue" points="110,-463 110,-614 314,-614 314,-463 110,-463"/>
+<text text-anchor="middle" x="212" y="-598.8" font-family="sans-serif" font-size="14.00">hdmi-audio-codec.1.auto</text>
+</g>
+<!-- ROOT_Amplifier -->
+<g id="node1" class="node">
+<title>ROOT_Amplifier</title>
+<polygon fill="#f2f2f2" stroke="#4d4d4d" points="93.5,-583 16.5,-583 16.5,-545 93.5,-545 93.5,-583"/>
+<text text-anchor="middle" x="55" y="-567.8" font-family="sans-serif" font-size="14.00">Amplifier</text>
+<text text-anchor="middle" x="55" y="-552.8" font-family="sans-serif" font-size="14.00">[out_drv]</text>
+</g>
+<!-- 4000b000.audio-controller_capture -->
+<g id="node2" class="node">
+<title>4000b000.audio-controller_capture</title>
+<polygon fill="#f2f2f2" stroke="#4d4d4d" points="202,-424 128,-424 128,-386 202,-386 202,-424"/>
+<text text-anchor="middle" x="165" y="-408.8" font-family="sans-serif" font-size="14.00">capture</text>
+<text text-anchor="middle" x="165" y="-393.8" font-family="sans-serif" font-size="14.00">[dai_out]</text>
+</g>
+<!-- 4000b000.audio-controller_playback -->
+<g id="node3" class="node">
+<title>4000b000.audio-controller_playback</title>
+<polygon fill="#f2f2f2" stroke="#4d4d4d" points="304,-424 230,-424 230,-386 304,-386 304,-424"/>
+<text text-anchor="middle" x="267" y="-408.8" font-family="sans-serif" font-size="14.00">playback</text>
+<text text-anchor="middle" x="267" y="-393.8" font-family="sans-serif" font-size="14.00">[dai_in]</text>
+</g>
+<!-- hdmi-audio-codec.1.auto_I2S Playback -->
+<g id="node28" class="node">
+<title>hdmi-audio-codec.1.auto_I2S Playback</title>
+<polygon fill="#f2f2f2" stroke="#4d4d4d" points="306,-583 208,-583 208,-545 306,-545 306,-583"/>
+<text text-anchor="middle" x="257" y="-567.8" font-family="sans-serif" font-size="14.00">I2S Playback</text>
+<text text-anchor="middle" x="257" y="-552.8" font-family="sans-serif" font-size="14.00">[dai_in]</text>
+</g>
+<!-- 4000b000.audio-controller_playback->hdmi-audio-codec.1.auto_I2S Playback -->
+<g id="edge21" class="edge">
+<title>4000b000.audio-controller_playback->hdmi-audio-codec.1.auto_I2S Playback</title>
+<path fill="none" stroke="black" d="M276.84,-424.14C282.19,-435.06 288.26,-449.42 291,-463 295.05,-483.04 296.67,-489.36 291,-509 288.25,-518.54 283.26,-528.01 277.93,-536.3"/>
+<polygon fill="black" stroke="black" points="274.89,-534.55 272.11,-544.78 280.66,-538.51 274.89,-534.55"/>
+</g>
+<!-- hdmi-audio-codec.1.auto_Capture -->
+<g id="node4" class="node">
+<title>hdmi-audio-codec.1.auto_Capture</title>
+<polygon fill="#f2f2f2" stroke="#4d4d4d" points="192,-509 118,-509 118,-471 192,-471 192,-509"/>
+<text text-anchor="middle" x="155" y="-493.8" font-family="sans-serif" font-size="14.00">Capture</text>
+<text text-anchor="middle" x="155" y="-478.8" font-family="sans-serif" font-size="14.00">[dai_out]</text>
+</g>
+<!-- hdmi-audio-codec.1.auto_Capture->4000b000.audio-controller_capture -->
+<g id="edge1" class="edge">
+<title>hdmi-audio-codec.1.auto_Capture->4000b000.audio-controller_capture</title>
+<path fill="none" stroke="black" d="M157.17,-470.99C158.46,-460.3 160.12,-446.5 161.58,-434.37"/>
+<polygon fill="black" stroke="black" points="165.08,-434.61 162.8,-424.26 158.13,-433.77 165.08,-434.61"/>
+</g>
+<!-- cs42l51.0-004a_AIN1L -->
+<g id="node5" class="node">
+<title>cs42l51.0-004a_AIN1L</title>
+<polygon fill="#f2f2f2" stroke="#4d4d4d" points="836.5,-583 775.5,-583 775.5,-545 836.5,-545 836.5,-583"/>
+<text text-anchor="middle" x="806" y="-567.8" font-family="sans-serif" font-size="14.00">AIN1L</text>
+<text text-anchor="middle" x="806" y="-552.8" font-family="sans-serif" font-size="14.00">[input]</text>
+</g>
+<!-- cs42l51.0-004a_PGA-ADC Mux Left -->
+<g id="node22" class="node">
+<title>cs42l51.0-004a_PGA-ADC Mux Left</title>
+<polygon fill="#f2f2f2" stroke="#4d4d4d" points="876,-509 736,-509 736,-471 876,-471 876,-509"/>
+<text text-anchor="middle" x="806" y="-493.8" font-family="sans-serif" font-size="14.00">PGA-ADC Mux Left</text>
+<text text-anchor="middle" x="806" y="-478.8" font-family="sans-serif" font-size="14.00">[mux]</text>
+</g>
+<!-- cs42l51.0-004a_AIN1L->cs42l51.0-004a_PGA-ADC Mux Left -->
+<g id="edge14" class="edge">
+<title>cs42l51.0-004a_AIN1L->cs42l51.0-004a_PGA-ADC Mux Left</title>
+<path fill="none" stroke="black" d="M806,-544.83C806,-537.13 806,-527.97 806,-519.42"/>
+<polygon fill="black" stroke="black" points="809.5,-519.41 806,-509.41 802.5,-519.41 809.5,-519.41"/>
+</g>
+<!-- cs42l51.0-004a_AIN1R -->
+<g id="node6" class="node">
+<title>cs42l51.0-004a_AIN1R</title>
+<polygon fill="#f2f2f2" stroke="#4d4d4d" points="738.5,-583 677.5,-583 677.5,-545 738.5,-545 738.5,-583"/>
+<text text-anchor="middle" x="708" y="-567.8" font-family="sans-serif" font-size="14.00">AIN1R</text>
+<text text-anchor="middle" x="708" y="-552.8" font-family="sans-serif" font-size="14.00">[input]</text>
+</g>
+<!-- cs42l51.0-004a_PGA-ADC Mux Right -->
+<g id="node23" class="node">
+<title>cs42l51.0-004a_PGA-ADC Mux Right</title>
+<polygon fill="#f2f2f2" stroke="#4d4d4d" points="717.5,-509 568.5,-509 568.5,-471 717.5,-471 717.5,-509"/>
+<text text-anchor="middle" x="643" y="-493.8" font-family="sans-serif" font-size="14.00">PGA-ADC Mux Right</text>
+<text text-anchor="middle" x="643" y="-478.8" font-family="sans-serif" font-size="14.00">[mux]</text>
+</g>
+<!-- cs42l51.0-004a_AIN1R->cs42l51.0-004a_PGA-ADC Mux Right -->
+<g id="edge15" class="edge">
+<title>cs42l51.0-004a_AIN1R->cs42l51.0-004a_PGA-ADC Mux Right</title>
+<path fill="none" stroke="black" d="M691.6,-544.83C683.96,-536.37 674.73,-526.15 666.38,-516.9"/>
+<polygon fill="black" stroke="black" points="668.92,-514.49 659.62,-509.41 663.73,-519.18 668.92,-514.49"/>
+</g>
+<!-- cs42l51.0-004a_AIN2L -->
+<g id="node7" class="node">
+<title>cs42l51.0-004a_AIN2L</title>
+<polygon fill="#f2f2f2" stroke="#4d4d4d" points="659.5,-583 598.5,-583 598.5,-545 659.5,-545 659.5,-583"/>
+<text text-anchor="middle" x="629" y="-567.8" font-family="sans-serif" font-size="14.00">AIN2L</text>
+<text text-anchor="middle" x="629" y="-552.8" font-family="sans-serif" font-size="14.00">[input]</text>
+</g>
+<!-- cs42l51.0-004a_AIN2R -->
+<g id="node8" class="node">
+<title>cs42l51.0-004a_AIN2R</title>
+<polygon fill="#f2f2f2" stroke="#4d4d4d" points="580.5,-583 519.5,-583 519.5,-545 580.5,-545 580.5,-583"/>
+<text text-anchor="middle" x="550" y="-567.8" font-family="sans-serif" font-size="14.00">AIN2R</text>
+<text text-anchor="middle" x="550" y="-552.8" font-family="sans-serif" font-size="14.00">[input]</text>
+</g>
+<!-- cs42l51.0-004a_Capture -->
+<g id="node9" class="node">
+<title>cs42l51.0-004a_Capture</title>
+<polygon fill="#f2f2f2" stroke="#4d4d4d" points="692,-276 618,-276 618,-238 692,-238 692,-276"/>
+<text text-anchor="middle" x="655" y="-260.8" font-family="sans-serif" font-size="14.00">Capture</text>
+<text text-anchor="middle" x="655" y="-245.8" font-family="sans-serif" font-size="14.00">[dai_out]</text>
+</g>
+<!-- cs42l51.0-004a_DAC Mux -->
+<g id="node10" class="node">
+<title>cs42l51.0-004a_DAC Mux</title>
+<polygon fill="none" stroke="#008b00" stroke-width="2" points="598.5,-202 521.5,-202 521.5,-164 598.5,-164 598.5,-202"/>
+<text text-anchor="middle" x="560" y="-186.8" font-family="sans-serif" font-size="14.00">DAC Mux</text>
+<text text-anchor="middle" x="560" y="-171.8" font-family="sans-serif" font-size="14.00">[mux]</text>
+</g>
+<!-- cs42l51.0-004a_Left DAC -->
+<g id="node14" class="node">
+<title>cs42l51.0-004a_Left DAC</title>
+<polygon fill="none" stroke="#008b00" stroke-width="2" points="548,-128 474,-128 474,-90 548,-90 548,-128"/>
+<text text-anchor="middle" x="511" y="-112.8" font-family="sans-serif" font-size="14.00">Left DAC</text>
+<text text-anchor="middle" x="511" y="-97.8" font-family="sans-serif" font-size="14.00">[dac]</text>
+</g>
+<!-- cs42l51.0-004a_DAC Mux->cs42l51.0-004a_Left DAC -->
+<g id="edge9" class="edge">
+<title>cs42l51.0-004a_DAC Mux->cs42l51.0-004a_Left DAC</title>
+<path fill="none" stroke="black" d="M547.64,-163.83C542.05,-155.62 535.34,-145.76 529.19,-136.73"/>
+<polygon fill="black" stroke="black" points="532.05,-134.71 523.53,-128.41 526.26,-138.65 532.05,-134.71"/>
+</g>
+<!-- cs42l51.0-004a_Right DAC -->
+<g id="node26" class="node">
+<title>cs42l51.0-004a_Right DAC</title>
+<polygon fill="none" stroke="#008b00" stroke-width="2" points="649.5,-128 566.5,-128 566.5,-90 649.5,-90 649.5,-128"/>
+<text text-anchor="middle" x="608" y="-112.8" font-family="sans-serif" font-size="14.00">Right DAC</text>
+<text text-anchor="middle" x="608" y="-97.8" font-family="sans-serif" font-size="14.00">[dac]</text>
+</g>
+<!-- cs42l51.0-004a_DAC Mux->cs42l51.0-004a_Right DAC -->
+<g id="edge18" class="edge">
+<title>cs42l51.0-004a_DAC Mux->cs42l51.0-004a_Right DAC</title>
+<path fill="none" stroke="black" d="M572.11,-163.83C577.53,-155.71 584.02,-145.96 589.99,-137.01"/>
+<polygon fill="black" stroke="black" points="593.09,-138.68 595.72,-128.41 587.27,-134.79 593.09,-138.68"/>
+</g>
+<!-- cs42l51.0-004a_HPL -->
+<g id="node11" class="node">
+<title>cs42l51.0-004a_HPL</title>
+<polygon fill="none" stroke="#008b00" stroke-width="2" points="546.5,-54 475.5,-54 475.5,-16 546.5,-16 546.5,-54"/>
+<text text-anchor="middle" x="511" y="-38.8" font-family="sans-serif" font-size="14.00">HPL</text>
+<text text-anchor="middle" x="511" y="-23.8" font-family="sans-serif" font-size="14.00">[output]</text>
+</g>
+<!-- cs42l51.0-004a_HPR -->
+<g id="node12" class="node">
+<title>cs42l51.0-004a_HPR</title>
+<polygon fill="none" stroke="#008b00" stroke-width="2" points="643.5,-54 572.5,-54 572.5,-16 643.5,-16 643.5,-54"/>
+<text text-anchor="middle" x="608" y="-38.8" font-family="sans-serif" font-size="14.00">HPR</text>
+<text text-anchor="middle" x="608" y="-23.8" font-family="sans-serif" font-size="14.00">[output]</text>
+</g>
+<!-- cs42l51.0-004a_Left ADC -->
+<g id="node13" class="node">
+<title>cs42l51.0-004a_Left ADC</title>
+<polygon fill="#f2f2f2" stroke="#4d4d4d" points="822,-350 748,-350 748,-312 822,-312 822,-350"/>
+<text text-anchor="middle" x="785" y="-334.8" font-family="sans-serif" font-size="14.00">Left ADC</text>
+<text text-anchor="middle" x="785" y="-319.8" font-family="sans-serif" font-size="14.00">[adc]</text>
+</g>
+<!-- cs42l51.0-004a_Left ADC->cs42l51.0-004a_Capture -->
+<g id="edge4" class="edge">
+<title>cs42l51.0-004a_Left ADC->cs42l51.0-004a_Capture</title>
+<path fill="none" stroke="black" d="M752.2,-311.83C735.41,-302.54 714.8,-291.12 696.88,-281.2"/>
+<polygon fill="black" stroke="black" points="698.24,-277.95 687.79,-276.16 694.85,-284.07 698.24,-277.95"/>
+</g>
+<!-- cs42l51.0-004a_Left DAC->cs42l51.0-004a_HPL -->
+<g id="edge6" class="edge">
+<title>cs42l51.0-004a_Left DAC->cs42l51.0-004a_HPL</title>
+<path fill="none" stroke="black" d="M511,-89.83C511,-82.13 511,-72.97 511,-64.42"/>
+<polygon fill="black" stroke="black" points="514.5,-64.41 511,-54.41 507.5,-64.41 514.5,-64.41"/>
+</g>
+<!-- cs42l51.0-004a_Left PGA -->
+<g id="node15" class="node">
+<title>cs42l51.0-004a_Left PGA</title>
+<polygon fill="#f2f2f2" stroke="#4d4d4d" points="838,-424 764,-424 764,-386 838,-386 838,-424"/>
+<text text-anchor="middle" x="801" y="-408.8" font-family="sans-serif" font-size="14.00">Left PGA</text>
+<text text-anchor="middle" x="801" y="-393.8" font-family="sans-serif" font-size="14.00">[pga]</text>
+</g>
+<!-- cs42l51.0-004a_Left PGA->cs42l51.0-004a_Left ADC -->
+<g id="edge8" class="edge">
+<title>cs42l51.0-004a_Left PGA->cs42l51.0-004a_Left ADC</title>
+<path fill="none" stroke="black" d="M796.96,-385.83C795.25,-378.13 793.22,-368.97 791.31,-360.42"/>
+<polygon fill="black" stroke="black" points="794.68,-359.42 789.09,-350.41 787.84,-360.93 794.68,-359.42"/>
+</g>
+<!-- cs42l51.0-004a_MCLK -->
+<g id="node16" class="node">
+<title>cs42l51.0-004a_MCLK</title>
+<polygon fill="none" stroke="#008b00" stroke-width="2" points="594.5,-350 525.5,-350 525.5,-312 594.5,-312 594.5,-350"/>
+<text text-anchor="middle" x="560" y="-334.8" font-family="sans-serif" font-size="14.00">MCLK</text>
+<text text-anchor="middle" x="560" y="-319.8" font-family="sans-serif" font-size="14.00">[supply]</text>
+</g>
+<!-- cs42l51.0-004a_MCLK->cs42l51.0-004a_Capture -->
+<g id="edge2" class="edge">
+<title>cs42l51.0-004a_MCLK->cs42l51.0-004a_Capture</title>
+<path fill="none" stroke="black" d="M583.97,-311.83C595.79,-302.88 610.2,-291.96 622.94,-282.3"/>
+<polygon fill="black" stroke="black" points="625.18,-284.99 631.04,-276.16 620.95,-279.41 625.18,-284.99"/>
+</g>
+<!-- cs42l51.0-004a_Playback -->
+<g id="node24" class="node">
+<title>cs42l51.0-004a_Playback</title>
+<polygon fill="none" stroke="#008b00" stroke-width="2" points="597,-276 523,-276 523,-238 597,-238 597,-276"/>
+<text text-anchor="middle" x="560" y="-260.8" font-family="sans-serif" font-size="14.00">Playback</text>
+<text text-anchor="middle" x="560" y="-245.8" font-family="sans-serif" font-size="14.00">[dai_in]</text>
+</g>
+<!-- cs42l51.0-004a_MCLK->cs42l51.0-004a_Playback -->
+<g id="edge16" class="edge">
+<title>cs42l51.0-004a_MCLK->cs42l51.0-004a_Playback</title>
+<path fill="none" stroke="black" d="M560,-311.83C560,-304.13 560,-294.97 560,-286.42"/>
+<polygon fill="black" stroke="black" points="563.5,-286.41 560,-276.41 556.5,-286.41 563.5,-286.41"/>
+</g>
+<!-- cs42l51.0-004a_MICL -->
+<g id="node17" class="node">
+<title>cs42l51.0-004a_MICL</title>
+<polygon fill="#f2f2f2" stroke="#4d4d4d" points="399.5,-509 338.5,-509 338.5,-471 399.5,-471 399.5,-509"/>
+<text text-anchor="middle" x="369" y="-493.8" font-family="sans-serif" font-size="14.00">MICL</text>
+<text text-anchor="middle" x="369" y="-478.8" font-family="sans-serif" font-size="14.00">[input]</text>
+</g>
+<!-- cs42l51.0-004a_Mic Preamp Left -->
+<g id="node20" class="node">
+<title>cs42l51.0-004a_Mic Preamp Left</title>
+<polygon fill="#f2f2f2" stroke="#4d4d4d" points="461.5,-424 338.5,-424 338.5,-386 461.5,-386 461.5,-424"/>
+<text text-anchor="middle" x="400" y="-408.8" font-family="sans-serif" font-size="14.00">Mic Preamp Left</text>
+<text text-anchor="middle" x="400" y="-393.8" font-family="sans-serif" font-size="14.00">[mixer]</text>
+</g>
+<!-- cs42l51.0-004a_MICL->cs42l51.0-004a_Mic Preamp Left -->
+<g id="edge12" class="edge">
+<title>cs42l51.0-004a_MICL->cs42l51.0-004a_Mic Preamp Left</title>
+<path fill="none" stroke="black" d="M375.73,-470.99C379.8,-460.08 385.08,-445.94 389.68,-433.64"/>
+<polygon fill="black" stroke="black" points="392.96,-434.85 393.18,-424.26 386.4,-432.4 392.96,-434.85"/>
+</g>
+<!-- cs42l51.0-004a_MICR -->
+<g id="node18" class="node">
+<title>cs42l51.0-004a_MICR</title>
+<polygon fill="#f2f2f2" stroke="#4d4d4d" points="501.5,-583 440.5,-583 440.5,-545 501.5,-545 501.5,-583"/>
+<text text-anchor="middle" x="471" y="-567.8" font-family="sans-serif" font-size="14.00">MICR</text>
+<text text-anchor="middle" x="471" y="-552.8" font-family="sans-serif" font-size="14.00">[input]</text>
+</g>
+<!-- cs42l51.0-004a_Mic Preamp Right -->
+<g id="node21" class="node">
+<title>cs42l51.0-004a_Mic Preamp Right</title>
+<polygon fill="#f2f2f2" stroke="#4d4d4d" points="550.5,-509 417.5,-509 417.5,-471 550.5,-471 550.5,-509"/>
+<text text-anchor="middle" x="484" y="-493.8" font-family="sans-serif" font-size="14.00">Mic Preamp Right</text>
+<text text-anchor="middle" x="484" y="-478.8" font-family="sans-serif" font-size="14.00">[mixer]</text>
+</g>
+<!-- cs42l51.0-004a_MICR->cs42l51.0-004a_Mic Preamp Right -->
+<g id="edge13" class="edge">
+<title>cs42l51.0-004a_MICR->cs42l51.0-004a_Mic Preamp Right</title>
+<path fill="none" stroke="black" d="M474.28,-544.83C475.67,-537.13 477.32,-527.97 478.87,-519.42"/>
+<polygon fill="black" stroke="black" points="482.34,-519.88 480.68,-509.41 475.45,-518.63 482.34,-519.88"/>
+</g>
+<!-- cs42l51.0-004a_Mic Bias -->
+<g id="node19" class="node">
+<title>cs42l51.0-004a_Mic Bias</title>
+<polygon fill="#f2f2f2" stroke="#4d4d4d" points="409.5,-583 338.5,-583 338.5,-545 409.5,-545 409.5,-583"/>
+<text text-anchor="middle" x="374" y="-567.8" font-family="sans-serif" font-size="14.00">Mic Bias</text>
+<text text-anchor="middle" x="374" y="-552.8" font-family="sans-serif" font-size="14.00">[supply]</text>
+</g>
+<!-- cs42l51.0-004a_Mic Bias->cs42l51.0-004a_MICL -->
+<g id="edge11" class="edge">
+<title>cs42l51.0-004a_Mic Bias->cs42l51.0-004a_MICL</title>
+<path fill="none" stroke="black" d="M372.74,-544.83C372.2,-537.13 371.57,-527.97 370.97,-519.42"/>
+<polygon fill="black" stroke="black" points="374.46,-519.15 370.28,-509.41 367.48,-519.63 374.46,-519.15"/>
+</g>
+<!-- cs42l51.0-004a_PGA-ADC Mux Left->cs42l51.0-004a_Left PGA -->
+<g id="edge10" class="edge">
+<title>cs42l51.0-004a_PGA-ADC Mux Left->cs42l51.0-004a_Left PGA</title>
+<path fill="none" stroke="black" d="M804.92,-470.99C804.27,-460.3 803.44,-446.5 802.71,-434.37"/>
+<polygon fill="black" stroke="black" points="806.2,-434.03 802.1,-424.26 799.21,-434.45 806.2,-434.03"/>
+</g>
+<!-- cs42l51.0-004a_Right PGA -->
+<g id="node27" class="node">
+<title>cs42l51.0-004a_Right PGA</title>
+<polygon fill="#f2f2f2" stroke="#4d4d4d" points="688.5,-424 605.5,-424 605.5,-386 688.5,-386 688.5,-424"/>
+<text text-anchor="middle" x="647" y="-408.8" font-family="sans-serif" font-size="14.00">Right PGA</text>
+<text text-anchor="middle" x="647" y="-393.8" font-family="sans-serif" font-size="14.00">[pga]</text>
+</g>
+<!-- cs42l51.0-004a_PGA-ADC Mux Right->cs42l51.0-004a_Right PGA -->
+<g id="edge19" class="edge">
+<title>cs42l51.0-004a_PGA-ADC Mux Right->cs42l51.0-004a_Right PGA</title>
+<path fill="none" stroke="black" d="M643.87,-470.99C644.38,-460.3 645.05,-446.5 645.63,-434.37"/>
+<polygon fill="black" stroke="black" points="649.13,-434.42 646.12,-424.26 642.14,-434.08 649.13,-434.42"/>
+</g>
+<!-- cs42l51.0-004a_Playback->cs42l51.0-004a_DAC Mux -->
+<g id="edge5" class="edge">
+<title>cs42l51.0-004a_Playback->cs42l51.0-004a_DAC Mux</title>
+<path fill="none" stroke="black" d="M560,-237.83C560,-230.13 560,-220.97 560,-212.42"/>
+<polygon fill="black" stroke="black" points="563.5,-212.41 560,-202.41 556.5,-212.41 563.5,-212.41"/>
+</g>
+<!-- cs42l51.0-004a_Right ADC -->
+<g id="node25" class="node">
+<title>cs42l51.0-004a_Right ADC</title>
+<polygon fill="#f2f2f2" stroke="#4d4d4d" points="697,-350 613,-350 613,-312 697,-312 697,-350"/>
+<text text-anchor="middle" x="655" y="-334.8" font-family="sans-serif" font-size="14.00">Right ADC</text>
+<text text-anchor="middle" x="655" y="-319.8" font-family="sans-serif" font-size="14.00">[adc]</text>
+</g>
+<!-- cs42l51.0-004a_Right ADC->cs42l51.0-004a_Capture -->
+<g id="edge3" class="edge">
+<title>cs42l51.0-004a_Right ADC->cs42l51.0-004a_Capture</title>
+<path fill="none" stroke="black" d="M655,-311.83C655,-304.13 655,-294.97 655,-286.42"/>
+<polygon fill="black" stroke="black" points="658.5,-286.41 655,-276.41 651.5,-286.41 658.5,-286.41"/>
+</g>
+<!-- cs42l51.0-004a_Right DAC->cs42l51.0-004a_HPR -->
+<g id="edge7" class="edge">
+<title>cs42l51.0-004a_Right DAC->cs42l51.0-004a_HPR</title>
+<path fill="none" stroke="black" d="M608,-89.83C608,-82.13 608,-72.97 608,-64.42"/>
+<polygon fill="black" stroke="black" points="611.5,-64.41 608,-54.41 604.5,-64.41 611.5,-64.41"/>
+</g>
+<!-- cs42l51.0-004a_Right PGA->cs42l51.0-004a_Right ADC -->
+<g id="edge17" class="edge">
+<title>cs42l51.0-004a_Right PGA->cs42l51.0-004a_Right ADC</title>
+<path fill="none" stroke="black" d="M649.02,-385.83C649.87,-378.13 650.89,-368.97 651.84,-360.42"/>
+<polygon fill="black" stroke="black" points="655.33,-360.74 652.95,-350.41 648.37,-359.97 655.33,-360.74"/>
+</g>
+<!-- hdmi-audio-codec.1.auto_TX -->
+<g id="node30" class="node">
+<title>hdmi-audio-codec.1.auto_TX</title>
+<polygon fill="#f2f2f2" stroke="#4d4d4d" points="281.5,-509 210.5,-509 210.5,-471 281.5,-471 281.5,-509"/>
+<text text-anchor="middle" x="246" y="-493.8" font-family="sans-serif" font-size="14.00">TX</text>
+<text text-anchor="middle" x="246" y="-478.8" font-family="sans-serif" font-size="14.00">[output]</text>
+</g>
+<!-- hdmi-audio-codec.1.auto_I2S Playback->hdmi-audio-codec.1.auto_TX -->
+<g id="edge22" class="edge">
+<title>hdmi-audio-codec.1.auto_I2S Playback->hdmi-audio-codec.1.auto_TX</title>
+<path fill="none" stroke="black" d="M254.22,-544.83C253.05,-537.13 251.65,-527.97 250.34,-519.42"/>
+<polygon fill="black" stroke="black" points="253.78,-518.77 248.81,-509.41 246.86,-519.83 253.78,-518.77"/>
+</g>
+<!-- hdmi-audio-codec.1.auto_RX -->
+<g id="node29" class="node">
+<title>hdmi-audio-codec.1.auto_RX</title>
+<polygon fill="#f2f2f2" stroke="#4d4d4d" points="189.5,-583 118.5,-583 118.5,-545 189.5,-545 189.5,-583"/>
+<text text-anchor="middle" x="154" y="-567.8" font-family="sans-serif" font-size="14.00">RX</text>
+<text text-anchor="middle" x="154" y="-552.8" font-family="sans-serif" font-size="14.00">[output]</text>
+</g>
+<!-- hdmi-audio-codec.1.auto_RX->hdmi-audio-codec.1.auto_Capture -->
+<g id="edge20" class="edge">
+<title>hdmi-audio-codec.1.auto_RX->hdmi-audio-codec.1.auto_Capture</title>
+<path fill="none" stroke="black" d="M154.25,-544.83C154.36,-537.13 154.49,-527.97 154.61,-519.42"/>
+<polygon fill="black" stroke="black" points="158.1,-519.46 154.74,-509.41 151.11,-519.36 158.1,-519.46"/>
+</g>
+</g>
+</svg>
diff --git a/Documentation/sound/soc/dapm.rst b/Documentation/sound/soc/dapm.rst
index 11f7f2f685af..58ef880ac8b6 100644
--- a/Documentation/sound/soc/dapm.rst
+++ b/Documentation/sound/soc/dapm.rst
@@ -17,9 +17,27 @@ recompiling are required for user space applications to use it. DAPM makes
power switching decisions based upon any audio stream (capture/playback)
activity and audio mixer settings within the device.
-DAPM spans the whole machine. It covers power control within the entire
-audio subsystem, this includes internal codec power blocks and machine
-level power systems.
+DAPM is based on two basic elements, called widgets and routes:
+
+ * a **widget** is every part of the audio hardware that can be enabled by
+ software when in use and disabled to save power when not in use
+ * a **route** is an interconnection between widgets that exists when sound
+ can flow from one widget to the other
+
+All DAPM power switching decisions are made automatically by consulting an
+audio routing graph. This graph is specific to each sound card and spans
+the whole sound card, so some DAPM routes connect two widgets belonging to
+different components (e.g. the LINE OUT pin of a CODEC and the input pin of
+an amplifier).
+
+The graph for the STM32MP1-DK1 sound card is shown in picture:
+
+.. kernel-figure:: dapm-graph.svg
+ :alt: Example DAPM graph
+ :align: center
+
+DAPM power domains
+==================
There are 4 power domains within DAPM:
@@ -48,12 +66,6 @@ Stream domain
Enabled and disabled when stream playback/capture is started and
stopped respectively. e.g. aplay, arecord.
-All DAPM power switching decisions are made automatically by consulting an audio
-routing graph of the whole machine. This graph is specific to each machine and
-consists of the interconnections between every audio component (including
-internal codec components). All audio components that affect power are called
-widgets hereafter.
-
DAPM Widgets
============
--
2.34.1
On Fri, Apr 26, 2024 at 06:56:38PM +0200, Luca Ceresoli wrote:
> Clarify DAPM does not expose any API to user space, and adapt the paragraph
> accordingly.
That's not strictly true, there's a couple of sysfs tuneables and all
the routing is via userspace controls plus we've got stuff like pin
switches.
On Fri, 26 Apr 2024 18:56:33 +0200, Luca Ceresoli wrote:
> This series applies various improvements to the DAPM documentation: a
> rewrite of a few sections for clarity, style improvements and typo fixes.
>
>
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
Thanks!
[01/12] ASoC: doc: dapm: fix typos
commit: 534e0cd89baf74c22ca55b442fb4add8d844e272
[02/12] ASoC: doc: dapm: fix struct name
commit: eaf84bda623e0a034fe03b871addf7dc4f70dfff
[03/12] ASoC: doc: dapm: minor rewording
commit: 610277caa77f07997857ab2e31a073d8ad7ed090
[04/12] ASoC: doc: dapm: remove dash after colon
commit: 3233a68fcb216a2d8615862841c1fca7a940fc5c
[06/12] ASoC: doc: dapm: replace "map" with "graph"
commit: 7d0e76107894377a14f211c85a821a53416d5ab2
[07/12] ASoC: doc: dapm: extend initial descrption
commit: dd5f36e59134654f9fd7b39d4d66327a1a2db82d
[08/12] ASoC: doc: dapm: describe how widgets and routes are registered
commit: 36de8c0e26793beeda1d6a7592f44b4551271469
[09/12] ASoC: doc: dapm: fix and improve section "Registering DAPM controls"
commit: d40e82194423c9d058bdeff863373b7da9f7045b
[10/12] ASoC: doc: dapm: improve section "Codec/DSP Widget Interconnections"
commit: 057acfb460d6792c7d3ec088f57c411fb0e4d395
[11/12] ASoC: doc: dapm: update section "DAPM Widget Events"
commit: ce5a4f101cd0dfbda391d4f1815222d82a9d8a5a
[12/12] ASoC: doc: dapm: update event types
commit: 4155a82f6af8068473cd66b55da56fd379835fb0
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark