linux-doc.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2] Docs/sound: Update codec-to-codec documentation
@ 2024-10-20 16:37 anish kumar
  2024-10-23 16:10 ` Charles Keepax
  0 siblings, 1 reply; 7+ messages in thread
From: anish kumar @ 2024-10-20 16:37 UTC (permalink / raw)
  To: perex, tiwai, corbet; +Cc: linux-sound, linux-doc, linux-kernel, anish kumar

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset=y, Size: 12545 bytes --]

Updated documentation to provide more details
for codec-to-codec connection.

Signed-off-by: anish kumar <yesanishhere@gmail.com>
---
v2: Fixed the compilation error reported by Sphinx
 Documentation/sound/soc/codec-to-codec.rst | 296 +++++++++++++--------
 1 file changed, 190 insertions(+), 106 deletions(-)

diff --git a/Documentation/sound/soc/codec-to-codec.rst b/Documentation/sound/soc/codec-to-codec.rst
index 0418521b6e03..9d65fc74856a 100644
--- a/Documentation/sound/soc/codec-to-codec.rst
+++ b/Documentation/sound/soc/codec-to-codec.rst
@@ -1,115 +1,199 @@
-==============================================
-Creating codec to codec dai link for ALSA dapm
-==============================================
+Codec-to-Codec Connections in ALSA
+====================================
 
-Mostly the flow of audio is always from CPU to codec so your system
-will look as below:
-::
+An ALSA-based audio system typically involves playback and capture
+functionalities, where users may require audio file playback through
+speakers or recording from microphones. However, certain systems
+necessitate audio data routing directly between components, such as FM
+radio to speakers, without CPU involvement. For such scenarios, ALSA
+provides a mechanism known as codec-to-codec connections, leveraging
+the Dynamic Audio Power Management (DAPM) framework to facilitate
+direct data transfers between codecs.
 
-   ---------          ---------
-  |         |  dai   |         |
-      CPU    ------->    codec
-  |         |        |         |
-   ---------          ---------
+Introduction
+------------
 
-In case your system looks as below:
-::
+In most audio systems, audio data flows from the CPU to the codec. In
+specific configurations, such as those involving Bluetooth codecs,
+audio can be transmitted directly between codecs without CPU
+intervention. ALSA supports both architectures, and for systems that
+do not involve the CPU, it utilizes codec-to-codec digital audio
+interface (DAI) connections. This document discusses the procedure
+for establishing codec-to-codec DAI links to enable such
+functionalities.
 
+Audio Data Flow Paths
+----------------------
+
+In a typical configuration, audio flow can be visualized as follows:
+
+.. code-block:: text
+
+    ---------          ---------
+   |         |  dai   |         |
+       CPU    ------->    codec
+   |         |        |         |
+    ---------          ---------
+
+In more intricate setups, the system may not involve the CPU but
+instead utilizes multiple codecs as shown below. For instance,
+Codec-2 acts as a cellular modem, while Codec-3 connects to a
+speaker. Audio data can be received by Codec-2 and transmitted to
+Codec-3 without CPU intervention, demonstrating the ideal conditions
+for establishing a codec-to-codec DAI connection.
+
+.. code-block:: text
+
+                        ---------
+                       |         |
+                         codec-1 <---cellular modem
+                       |         |
                        ---------
-                      |         |
-                        codec-2
-                      |         |
-                      ---------
-                           |
-                         dai-2
-                           |
-   ----------          ---------
-  |          |  dai-1 |         |
-      CPU     ------->  codec-1
-  |          |        |         |
-   ----------          ---------
-                           |
-                         dai-3
-                           |
-                       ---------
-                      |         |
-                        codec-3
-                      |         |
+                            |
+                          dai-1
+                            ↓
+    ----------          ---------
+   |          |cpu_dai |         |
+    dummy CPU  ------->  codec-2
+   |          |        |         |
+    ----------          ---------
+                            |
+                          dai-3
+                            ↓
+                        ---------
+                       |         |
+                         codec-3 ---->speaker
+                       |         |
                        ---------
 
-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,
-    .c2c_params = &dsp_codec_params,
-    .num_c2c_params = 1,
- },
- {
-    .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,
-    .c2c_params = &dsp_codec_params,
-    .num_c2c_params = 1,
- },
-
-Above code snippet is motivated from sound/soc/samsung/speyside.c.
-
-Note the "c2c_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
+Creating Codec-to-Codec Connections in ALSA
+----------------------------------------------
+
+To create a codec-to-codec DAI in ALSA, a ``snd_soc_dai_link`` must be
+added to the machine driver before registering the sound card.
+During this registration, the core checks for the presence of
+``c2c_params`` within the ``snd_soc_dai_link``, determining whether
+to classify the DAI link as codec-to-codec.
+
+While establishing the PCM node, the ALSA core inspects this
+parameter. Instead of generating a user-space PCM node, it creates
+an internal PCM node utilized by kernel drivers. Consequently,
+running ``cat /proc/asound/pcm`` will yield no visible PCM nodes.
+
+After this setup, the ALSA core invokes the DAPM core to connect a
+single ``cpu_dai`` with both ``codec_dais``. Boot-up logs will
+display messages similar to:
+
+.. code-block:: bash
+
+   ASoC: registered pcm #0 codec2codec(Playback Codec)
+   multicodec <-> cpu_dai mapping ok
+   connected DAI link Dummy-CPU:cpu_dai -> codec-1:dai_1
+   connected DAI link Dummy-CPU:cpu_dai -> codec-2:dai_2
+
+To trigger this DAI link, a control interface is established by the
+DAPM core during internal DAI creation. This interface links to
+the ``snd_soc_dai_link_event`` function, which is invoked when a
+path connects in the DAPM core. A mixer must be created to trigger
+the connection, prompting the DAPM core to evaluate path
+connections and call the ``snd_soc_dai_link_event`` callback with
+relevant events.
+
+It is important to note that not all operations defined in
+``snd_soc_dai_ops`` are invoked as codec-to-codec connections offer
+limited control over DAI configuration. For greater control, a
+hostless configuration is recommended. The operations typically
+executed in codec-to-codec setups include startup, ``hw_params``,
+``hw_free``, digital mute, and shutdown from the
+``snd_soc_dai_ops`` structure.
+
+Code Changes for Codec-to-Codec
+----------------------------------
+
+The DAI link configuration in the machine file should resemble the
+following code snippet:
+
+.. code-block:: c
+
+   /*
+    * This PCM stream only supports 24-bit, 2 channels, and
+    * 48kHz 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,
+   };
+
+   static struct snd_soc_dai_link dai_links[] = {
+   {
+       .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,
+       .c2c_params = &dsp_codec_params,
+       .num_c2c_params = 1,
+   },
+   {
+       .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,
+       .c2c_params = &dsp_codec_params,
+       .num_c2c_params = 1,
+   },
+   };
+
+This snippet draws inspiration from the configuration found in
+``sound/soc/samsung/speyside.c``. The inclusion of the
+``c2c_params`` indicates to the DAPM core that the DAI link is a
+codec-to-codec connection.
+
+In the DAPM core, a route is established between the CPU DAI
+playback widget and the codec DAI capture widget for playback, with
+the reverse applying to the capture path. To trigger these routes,
+DAPM requires valid endpoints, which can be either sink or source
+widgets corresponding to the playback and capture paths,
 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.
-
-A dai_link in a "simple-audio-card" will automatically be detected as
-codec to codec when all DAIs on the link belong to codec components.
-The dai_link will be initialized with the subset of stream parameters
-(channels, format, sample rate) supported by all DAIs on the link. Since
-there is no way to provide these parameters in the device tree, this is
-mostly useful for communication with simple fixed-function codecs, such
-as a Bluetooth controller or cellular modem.
+To activate this DAI link widget, a lightweight codec driver for
+the speaker amplifier can be implemented, following a similar
+strategy to that in ``wm8727.c``. This driver should set the
+necessary constraints for the device, even with minimal control
+requirements.
+
+It's crucial to append “Playback” and “Capture” suffixes to the
+respective CPU and codec DAI names for playback and capture, as
+the DAPM core links and powers these DAIs based on their naming
+conventions.
+
+In a codec-to-codec scenario involving multiple codecs (above
+bootup logs are for multicodec scenario), it is not feasible to
+control individual codecs using dummy kcontrols or DAPM widgets.
+This limitation arises because the CPU DAI is statically
+connected to all codecs. Consequently, when a path is enabled,
+the DAPM core does not verify all the widgets that may be linked
+to the mixer widget. It’s important to note that the mixer widget
+serves as the trigger for these paths.
+
+Simple-audio-card configuration
+----------------------------------
+A dai_link in a "simple-audio-card" will automatically be
+detected as codec-to-codec when all DAIs on the link belong to
+codec components. The dai_link will be initialized with the
+subset of stream parameters (channels, format, sample rate)
+supported by all DAIs on the link. Since there is no way to
+provide these parameters in the device tree, this is mostly useful
+for communication with simple fixed-function codecs, such as a
+Bluetooth controller or cellular modem.
-- 
2.39.3 (Apple Git-146)


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH v2] Docs/sound: Update codec-to-codec documentation
  2024-10-20 16:37 [PATCH v2] Docs/sound: Update codec-to-codec documentation anish kumar
@ 2024-10-23 16:10 ` Charles Keepax
  2024-10-23 16:15   ` Jonathan Corbet
  2024-10-24 20:27   ` anish kumar
  0 siblings, 2 replies; 7+ messages in thread
From: Charles Keepax @ 2024-10-23 16:10 UTC (permalink / raw)
  To: anish kumar; +Cc: perex, tiwai, corbet, linux-sound, linux-doc, linux-kernel

On Sun, Oct 20, 2024 at 09:37:06AM -0700, anish kumar wrote:
> Updated documentation to provide more details
> for codec-to-codec connection.
> 
> Signed-off-by: anish kumar <yesanishhere@gmail.com>
> ---

The patch doesn't seem to apply cleanly for me, my system doesn't
seem to like:

Content-Type: text/plain; charset="y"

Not sure if that is a problem on my end or yours, but I am not
familiar with that encoding.

> v2: Fixed the compilation error reported by Sphinx
>  Documentation/sound/soc/codec-to-codec.rst | 296 +++++++++++++--------
>  1 file changed, 190 insertions(+), 106 deletions(-)
> 
> diff --git a/Documentation/sound/soc/codec-to-codec.rst b/Documentation/sound/soc/codec-to-codec.rst
> index 0418521b6e03..9d65fc74856a 100644
> --- a/Documentation/sound/soc/codec-to-codec.rst
> +++ b/Documentation/sound/soc/codec-to-codec.rst
> @@ -1,115 +1,199 @@
> -==============================================
> -Creating codec to codec dai link for ALSA dapm
> -==============================================
> +Codec-to-Codec Connections in ALSA
> +====================================
>  
> -Mostly the flow of audio is always from CPU to codec so your system
> -will look as below:
> -::
> +An ALSA-based audio system typically involves playback and capture
> +functionalities, where users may require audio file playback through

functionality would probably parse slightly better.

> +speakers or recording from microphones. However, certain systems
> +necessitate audio data routing directly between components, such as FM
> +radio to speakers, without CPU involvement. For such scenarios, ALSA

It would probably be more accurate to say "ASoC provides", I mean
I guess ASoC is a part of ALSA but this is definitely an ASoC
level feature.

> +provides a mechanism known as codec-to-codec connections, leveraging
> +the Dynamic Audio Power Management (DAPM) framework to facilitate
> +direct data transfers between codecs.
>  
> -   ---------          ---------
> -  |         |  dai   |         |
> -      CPU    ------->    codec
> -  |         |        |         |
> -   ---------          ---------
> +Introduction
> +------------
>  
> -In case your system looks as below:
> -::
> +In most audio systems, audio data flows from the CPU to the codec. In
> +specific configurations, such as those involving Bluetooth codecs,
> +audio can be transmitted directly between codecs without CPU
> +intervention. ALSA supports both architectures, and for systems that
> +do not involve the CPU, it utilizes codec-to-codec digital audio
> +interface (DAI) connections. This document discusses the procedure
> +for establishing codec-to-codec DAI links to enable such
> +functionalities.
>  
> +Audio Data Flow Paths
> +----------------------
> +
> +In a typical configuration, audio flow can be visualized as follows:
> +
> +.. code-block:: text
> +
> +    ---------          ---------
> +   |         |  dai   |         |
> +       CPU    ------->    codec
> +   |         |        |         |
> +    ---------          ---------
> +
> +In more intricate setups, the system may not involve the CPU but
> +instead utilizes multiple codecs as shown below. For instance,
> +Codec-2 acts as a cellular modem, while Codec-3 connects to a
> +speaker. Audio data can be received by Codec-2 and transmitted to
> +Codec-3 without CPU intervention, demonstrating the ideal conditions
> +for establishing a codec-to-codec DAI connection.
> +
> +.. code-block:: text
> +
> +                        ---------
> +                       |         |
> +                         codec-1 <---cellular modem
> +                       |         |
>                         ---------
> -                      |         |
> -                        codec-2
> -                      |         |
> -                      ---------
> -                           |
> -                         dai-2
> -                           |
> -   ----------          ---------
> -  |          |  dai-1 |         |
> -      CPU     ------->  codec-1
> -  |          |        |         |
> -   ----------          ---------
> -                           |
> -                         dai-3
> -                           |
> -                       ---------
> -                      |         |
> -                        codec-3
> -                      |         |
> +                            |
> +                          dai-1
> +                            ↓
> +    ----------          ---------
> +   |          |cpu_dai |         |
> +    dummy CPU  ------->  codec-2

Bringing the "dummy" into this is quite misleading, that really
relates to DPCM setups. DPCM lets one select any number of back
ends to service a given front end PCM, and often are abused to
achieve things that should really be implemented as C2C links.

> +   |          |        |         |
> +    ----------          ---------
> +                            |
> +                          dai-3
> +                            ↓
> +                        ---------
> +                       |         |
> +                         codec-3 ---->speaker
> +                       |         |
>                         ---------
>  
> -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,
> -    .c2c_params = &dsp_codec_params,
> -    .num_c2c_params = 1,
> - },
> - {
> -    .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,
> -    .c2c_params = &dsp_codec_params,
> -    .num_c2c_params = 1,
> - },
> -
> -Above code snippet is motivated from sound/soc/samsung/speyside.c.
> -
> -Note the "c2c_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
> +Creating Codec-to-Codec Connections in ALSA
> +----------------------------------------------
> +
> +To create a codec-to-codec DAI in ALSA, a ``snd_soc_dai_link`` must be
> +added to the machine driver before registering the sound card.
> +During this registration, the core checks for the presence of
> +``c2c_params`` within the ``snd_soc_dai_link``, determining whether
> +to classify the DAI link as codec-to-codec.
> +
> +While establishing the PCM node, the ALSA core inspects this
> +parameter. Instead of generating a user-space PCM node, it creates
> +an internal PCM node utilized by kernel drivers. Consequently,

I am not sure I like the description of this as an internal PCM
node, I guess in some ways the core does use the same structures
it would for a PCM node, but it isn't really a PCM node. I
do like that you have added the additional note this will not be
visible through procfs though.

> +running ``cat /proc/asound/pcm`` will yield no visible PCM nodes.
> +
> +After this setup, the ALSA core invokes the DAPM core to connect a

Again really ASoC core here.

> +single ``cpu_dai`` with both ``codec_dais``. Boot-up logs will
> +display messages similar to:

That is definitely not what should be happening with a C2C link.
In the system you showed the diagram for above there should be a
connection between the CPU and codec-2, then two separate links
between codec-2 and codecs 1 and 3. No links should be present
between the CPU and codecs 1 or 3.

> +
> +.. code-block:: bash
> +
> +   ASoC: registered pcm #0 codec2codec(Playback Codec)
> +   multicodec <-> cpu_dai mapping ok
> +   connected DAI link Dummy-CPU:cpu_dai -> codec-1:dai_1
> +   connected DAI link Dummy-CPU:cpu_dai -> codec-2:dai_2
> +

Yeah this is definitely mixing in a fair amount of DPCM stuff and
does not match the rest of the description.

> +To trigger this DAI link, a control interface is established by the
> +DAPM core during internal DAI creation. This interface links to
> +the ``snd_soc_dai_link_event`` function, which is invoked when a
> +path connects in the DAPM core. A mixer must be created to trigger
> +the connection, prompting the DAPM core to evaluate path
> +connections and call the ``snd_soc_dai_link_event`` callback with
> +relevant events.
> +
> +It is important to note that not all operations defined in
> +``snd_soc_dai_ops`` are invoked as codec-to-codec connections offer
> +limited control over DAI configuration. For greater control, a
> +hostless configuration is recommended. The operations typically

It is not clear to me what a "hostless configuration" is here.

> +executed in codec-to-codec setups include startup, ``hw_params``,
> +``hw_free``, digital mute, and shutdown from the
> +``snd_soc_dai_ops`` structure.
> +
> +Code Changes for Codec-to-Codec
> +----------------------------------
> +
> +The DAI link configuration in the machine file should resemble the
> +following code snippet:
> +
> +.. code-block:: c
> +
> +   /*
> +    * This PCM stream only supports 24-bit, 2 channels, and
> +    * 48kHz 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,
> +   };
> +
> +   static struct snd_soc_dai_link dai_links[] = {
> +   {
> +       .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,
> +       .c2c_params = &dsp_codec_params,
> +       .num_c2c_params = 1,
> +   },
> +   {
> +       .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,
> +       .c2c_params = &dsp_codec_params,
> +       .num_c2c_params = 1,
> +   },
> +   };
> +
> +This snippet draws inspiration from the configuration found in
> +``sound/soc/samsung/speyside.c``. The inclusion of the
> +``c2c_params`` indicates to the DAPM core that the DAI link is a
> +codec-to-codec connection.
> +
> +In the DAPM core, a route is established between the CPU DAI
> +playback widget and the codec DAI capture widget for playback, with
> +the reverse applying to the capture path. To trigger these routes,
> +DAPM requires valid endpoints, which can be either sink or source
> +widgets corresponding to the playback and capture paths,
>  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.
> -
> -A dai_link in a "simple-audio-card" will automatically be detected as
> -codec to codec when all DAIs on the link belong to codec components.
> -The dai_link will be initialized with the subset of stream parameters
> -(channels, format, sample rate) supported by all DAIs on the link. Since
> -there is no way to provide these parameters in the device tree, this is
> -mostly useful for communication with simple fixed-function codecs, such
> -as a Bluetooth controller or cellular modem.
> +To activate this DAI link widget, a lightweight codec driver for
> +the speaker amplifier can be implemented, following a similar
> +strategy to that in ``wm8727.c``. This driver should set the
> +necessary constraints for the device, even with minimal control
> +requirements.

Would actually be nice to include the note that any codec driver
should be fine, the original text does kinda give the impression
one would have to write a "thin codec driver" but if you already
have a driver thin or otherwise that would be fine. Perhaps
better to rephrase as a codec driver being required.

> +
> +It's crucial to append “Playback” and “Capture” suffixes to the
> +respective CPU and codec DAI names for playback and capture, as
> +the DAPM core links and powers these DAIs based on their naming
> +conventions.

Are you sure this is true? I could be wrong but I don't expect
the naming is critical in hooking up a c2c DAI.

> +
> +In a codec-to-codec scenario involving multiple codecs (above
> +bootup logs are for multicodec scenario), it is not feasible to
> +control individual codecs using dummy kcontrols or DAPM widgets.

I really am not sure what this means. What are we controlling
using dummy kcontrols? Why are we not using the real kcontrols
from the codec to control the codec?

> +This limitation arises because the CPU DAI is statically
> +connected to all codecs. Consequently, when a path is enabled,

Which it shouldn't be?

> +the DAPM core does not verify all the widgets that may be linked
> +to the mixer widget. It’s important to note that the mixer widget
> +serves as the trigger for these paths.
> +
> +Simple-audio-card configuration
> +----------------------------------
> +A dai_link in a "simple-audio-card" will automatically be
> +detected as codec-to-codec when all DAIs on the link belong to
> +codec components. The dai_link will be initialized with the
> +subset of stream parameters (channels, format, sample rate)
> +supported by all DAIs on the link. Since there is no way to
> +provide these parameters in the device tree, this is mostly useful
> +for communication with simple fixed-function codecs, such as a
> +Bluetooth controller or cellular modem.
> -- 
> 2.39.3 (Apple Git-146)
> 
> 

Thanks,
Charles

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v2] Docs/sound: Update codec-to-codec documentation
  2024-10-23 16:10 ` Charles Keepax
@ 2024-10-23 16:15   ` Jonathan Corbet
  2024-10-24 10:07     ` Bagas Sanjaya
  2024-10-24 20:27   ` anish kumar
  1 sibling, 1 reply; 7+ messages in thread
From: Jonathan Corbet @ 2024-10-23 16:15 UTC (permalink / raw)
  To: Charles Keepax, anish kumar
  Cc: perex, tiwai, linux-sound, linux-doc, linux-kernel

Charles Keepax <ckeepax@opensource.cirrus.com> writes:

> On Sun, Oct 20, 2024 at 09:37:06AM -0700, anish kumar wrote:
>> Updated documentation to provide more details
>> for codec-to-codec connection.
>> 
>> Signed-off-by: anish kumar <yesanishhere@gmail.com>
>> ---
>
> The patch doesn't seem to apply cleanly for me, my system doesn't
> seem to like:
>
> Content-Type: text/plain; charset="y"
>
> Not sure if that is a problem on my end or yours, but I am not
> familiar with that encoding.

That's something that "git send-email" does occasionally.  At some point
I remember that somebody figured out why that was, but it escapes me
now...

jon

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v2] Docs/sound: Update codec-to-codec documentation
  2024-10-23 16:15   ` Jonathan Corbet
@ 2024-10-24 10:07     ` Bagas Sanjaya
  0 siblings, 0 replies; 7+ messages in thread
From: Bagas Sanjaya @ 2024-10-24 10:07 UTC (permalink / raw)
  To: Jonathan Corbet, Charles Keepax, anish kumar
  Cc: perex, tiwai, linux-sound, linux-doc, linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1077 bytes --]

On Wed, Oct 23, 2024 at 10:15:08AM -0600, Jonathan Corbet wrote:
> Charles Keepax <ckeepax@opensource.cirrus.com> writes:
> 
> > On Sun, Oct 20, 2024 at 09:37:06AM -0700, anish kumar wrote:
> >> Updated documentation to provide more details
> >> for codec-to-codec connection.
> >> 
> >> Signed-off-by: anish kumar <yesanishhere@gmail.com>
> >> ---
> >
> > The patch doesn't seem to apply cleanly for me, my system doesn't
> > seem to like:
> >
> > Content-Type: text/plain; charset="y"
> >
> > Not sure if that is a problem on my end or yours, but I am not
> > familiar with that encoding.
> 
> That's something that "git send-email" does occasionally.  At some point
> I remember that somebody figured out why that was, but it escapes me
> now...

AFAIK in this case, when sending patches with non-ASCII characters in them,
git-send-email(1) will try figuring out the encoding, which will often
assumed to be UTF-8. You can simply hit Enter when it asks the correct
encoding.

Thanks.

-- 
An old man doll... just what I always wanted! - Clara

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v2] Docs/sound: Update codec-to-codec documentation
  2024-10-23 16:10 ` Charles Keepax
  2024-10-23 16:15   ` Jonathan Corbet
@ 2024-10-24 20:27   ` anish kumar
  2024-10-25  8:58     ` Charles Keepax
  1 sibling, 1 reply; 7+ messages in thread
From: anish kumar @ 2024-10-24 20:27 UTC (permalink / raw)
  To: Charles Keepax; +Cc: perex, tiwai, corbet, linux-sound, linux-doc, linux-kernel

On Wed, Oct 23, 2024 at 9:10 AM Charles Keepax
<ckeepax@opensource.cirrus.com> wrote:
>
> On Sun, Oct 20, 2024 at 09:37:06AM -0700, anish kumar wrote:
> > Updated documentation to provide more details
> > for codec-to-codec connection.
> >
> > Signed-off-by: anish kumar <yesanishhere@gmail.com>
> > ---
>
> The patch doesn't seem to apply cleanly for me, my system doesn't
> seem to like:
>
> Content-Type: text/plain; charset="y"
>
> Not sure if that is a problem on my end or yours, but I am not
> familiar with that encoding.
>
> > v2: Fixed the compilation error reported by Sphinx
> >  Documentation/sound/soc/codec-to-codec.rst | 296 +++++++++++++--------
> >  1 file changed, 190 insertions(+), 106 deletions(-)
> >
> > diff --git a/Documentation/sound/soc/codec-to-codec.rst b/Documentation/sound/soc/codec-to-codec.rst
> > index 0418521b6e03..9d65fc74856a 100644
> > --- a/Documentation/sound/soc/codec-to-codec.rst
> > +++ b/Documentation/sound/soc/codec-to-codec.rst
> > @@ -1,115 +1,199 @@
> > -==============================================
> > -Creating codec to codec dai link for ALSA dapm
> > -==============================================
> > +Codec-to-Codec Connections in ALSA
> > +====================================
> >
> > -Mostly the flow of audio is always from CPU to codec so your system
> > -will look as below:
> > -::
> > +An ALSA-based audio system typically involves playback and capture
> > +functionalities, where users may require audio file playback through
>
> functionality would probably parse slightly better.
>
> > +speakers or recording from microphones. However, certain systems
> > +necessitate audio data routing directly between components, such as FM
> > +radio to speakers, without CPU involvement. For such scenarios, ALSA
>
> It would probably be more accurate to say "ASoC provides", I mean
> I guess ASoC is a part of ALSA but this is definitely an ASoC
> level feature.
>
> > +provides a mechanism known as codec-to-codec connections, leveraging
> > +the Dynamic Audio Power Management (DAPM) framework to facilitate
> > +direct data transfers between codecs.
> >
> > -   ---------          ---------
> > -  |         |  dai   |         |
> > -      CPU    ------->    codec
> > -  |         |        |         |
> > -   ---------          ---------
> > +Introduction
> > +------------
> >
> > -In case your system looks as below:
> > -::
> > +In most audio systems, audio data flows from the CPU to the codec. In
> > +specific configurations, such as those involving Bluetooth codecs,
> > +audio can be transmitted directly between codecs without CPU
> > +intervention. ALSA supports both architectures, and for systems that
> > +do not involve the CPU, it utilizes codec-to-codec digital audio
> > +interface (DAI) connections. This document discusses the procedure
> > +for establishing codec-to-codec DAI links to enable such
> > +functionalities.
> >
> > +Audio Data Flow Paths
> > +----------------------
> > +
> > +In a typical configuration, audio flow can be visualized as follows:
> > +
> > +.. code-block:: text
> > +
> > +    ---------          ---------
> > +   |         |  dai   |         |
> > +       CPU    ------->    codec
> > +   |         |        |         |
> > +    ---------          ---------
> > +
> > +In more intricate setups, the system may not involve the CPU but
> > +instead utilizes multiple codecs as shown below. For instance,
> > +Codec-2 acts as a cellular modem, while Codec-3 connects to a
> > +speaker. Audio data can be received by Codec-2 and transmitted to
> > +Codec-3 without CPU intervention, demonstrating the ideal conditions
> > +for establishing a codec-to-codec DAI connection.
> > +
> > +.. code-block:: text
> > +
> > +                        ---------
> > +                       |         |
> > +                         codec-1 <---cellular modem
> > +                       |         |
> >                         ---------
> > -                      |         |
> > -                        codec-2
> > -                      |         |
> > -                      ---------
> > -                           |
> > -                         dai-2
> > -                           |
> > -   ----------          ---------
> > -  |          |  dai-1 |         |
> > -      CPU     ------->  codec-1
> > -  |          |        |         |
> > -   ----------          ---------
> > -                           |
> > -                         dai-3
> > -                           |
> > -                       ---------
> > -                      |         |
> > -                        codec-3
> > -                      |         |
> > +                            |
> > +                          dai-1
> > +                            ↓
> > +    ----------          ---------
> > +   |          |cpu_dai |         |
> > +    dummy CPU  ------->  codec-2
>
> Bringing the "dummy" into this is quite misleading, that really
> relates to DPCM setups. DPCM lets one select any number of back
> ends to service a given front end PCM, and often are abused to
> achieve things that should really be implemented as C2C links.

Aha, understood. For C2C we need a thin dummy codec driver
which acts as a cpu driver in the ASoC code right?

Based on the code from bells.c, below is the C2C and we do provide
a CPU driver, even though in actual it is a codec driver.

SND_SOC_DAILINK_DEFS(wm2200_dsp_codec,
DAILINK_COMP_ARRAY(COMP_CPU("wm0010-sdi2")),
DAILINK_COMP_ARRAY(COMP_CODEC("wm2200.1-003a", "wm2200")));

Perhaps, I can just remove the "dummy" from the diagram above.

>
> > +   |          |        |         |
> > +    ----------          ---------
> > +                            |
> > +                          dai-3
> > +                            ↓
> > +                        ---------
> > +                       |         |
> > +                         codec-3 ---->speaker
> > +                       |         |
> >                         ---------
> >
> > -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,
> > -    .c2c_params = &dsp_codec_params,
> > -    .num_c2c_params = 1,
> > - },
> > - {
> > -    .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,
> > -    .c2c_params = &dsp_codec_params,
> > -    .num_c2c_params = 1,
> > - },
> > -
> > -Above code snippet is motivated from sound/soc/samsung/speyside.c.
> > -
> > -Note the "c2c_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
> > +Creating Codec-to-Codec Connections in ALSA
> > +----------------------------------------------
> > +
> > +To create a codec-to-codec DAI in ALSA, a ``snd_soc_dai_link`` must be
> > +added to the machine driver before registering the sound card.
> > +During this registration, the core checks for the presence of
> > +``c2c_params`` within the ``snd_soc_dai_link``, determining whether
> > +to classify the DAI link as codec-to-codec.
> > +
> > +While establishing the PCM node, the ALSA core inspects this
> > +parameter. Instead of generating a user-space PCM node, it creates
> > +an internal PCM node utilized by kernel drivers. Consequently,
>
> I am not sure I like the description of this as an internal PCM
> node, I guess in some ways the core does use the same structures
> it would for a PCM node, but it isn't really a PCM node. I
> do like that you have added the additional note this will not be
> visible through procfs though.

thanks.
>
> > +running ``cat /proc/asound/pcm`` will yield no visible PCM nodes.
> > +
> > +After this setup, the ALSA core invokes the DAPM core to connect a
>
> Again really ASoC core here.
>
> > +single ``cpu_dai`` with both ``codec_dais``. Boot-up logs will
> > +display messages similar to:
>
> That is definitely not what should be happening with a C2C link.
> In the system you showed the diagram for above there should be a
> connection between the CPU and codec-2, then two separate links
> between codec-2 and codecs 1 and 3. No links should be present
> between the CPU and codecs 1 or 3.

Got it, I will try to convey the same in the diagram but ascii art is hard :)

Can you help clarify my understanding (based on the dapm code walkthrough),
when the mixer control is triggered, the CPU widgets gets triggered
thereby triggering codec2 widgets and as there is a static connection
between codec1 and codec2 it gets also triggered and the same thing
happens to codec3 as it is also linked to codec2?

Also, as the widgets are linked to dai ops, all the ops gets triggered as well.

>
> > +
> > +.. code-block:: bash
> > +
> > +   ASoC: registered pcm #0 codec2codec(Playback Codec)
> > +   multicodec <-> cpu_dai mapping ok
> > +   connected DAI link Dummy-CPU:cpu_dai -> codec-1:dai_1
> > +   connected DAI link Dummy-CPU:cpu_dai -> codec-2:dai_2
> > +
>
> Yeah this is definitely mixing in a fair amount of DPCM stuff and
> does not match the rest of the description.

I guess what you meant is that C2C doesn't care about the above
connection as it uses DAPM widget connection to trigger the path
right? So, even if this connection doesn't exist C2C will still work.

Reason why I am asking is that I saw the above logs when I
added a C2C connection.

>
> > +To trigger this DAI link, a control interface is established by the
> > +DAPM core during internal DAI creation. This interface links to
> > +the ``snd_soc_dai_link_event`` function, which is invoked when a
> > +path connects in the DAPM core. A mixer must be created to trigger
> > +the connection, prompting the DAPM core to evaluate path
> > +connections and call the ``snd_soc_dai_link_event`` callback with
> > +relevant events.
> > +
> > +It is important to note that not all operations defined in
> > +``snd_soc_dai_ops`` are invoked as codec-to-codec connections offer
> > +limited control over DAI configuration. For greater control, a
> > +hostless configuration is recommended. The operations typically
>
> It is not clear to me what a "hostless configuration" is here.

What I meant to convey is, if the user wants all pcm ops to get called in
order then he can use "Hostless FE" and connect to backend use as a normal PCM.

>
> > +executed in codec-to-codec setups include startup, ``hw_params``,
> > +``hw_free``, digital mute, and shutdown from the
> > +``snd_soc_dai_ops`` structure.
> > +
> > +Code Changes for Codec-to-Codec
> > +----------------------------------
> > +
> > +The DAI link configuration in the machine file should resemble the
> > +following code snippet:
> > +
> > +.. code-block:: c
> > +
> > +   /*
> > +    * This PCM stream only supports 24-bit, 2 channels, and
> > +    * 48kHz 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,
> > +   };
> > +
> > +   static struct snd_soc_dai_link dai_links[] = {
> > +   {
> > +       .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,
> > +       .c2c_params = &dsp_codec_params,
> > +       .num_c2c_params = 1,
> > +   },
> > +   {
> > +       .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,
> > +       .c2c_params = &dsp_codec_params,
> > +       .num_c2c_params = 1,
> > +   },
> > +   };
> > +
> > +This snippet draws inspiration from the configuration found in
> > +``sound/soc/samsung/speyside.c``. The inclusion of the
> > +``c2c_params`` indicates to the DAPM core that the DAI link is a
> > +codec-to-codec connection.
> > +
> > +In the DAPM core, a route is established between the CPU DAI
> > +playback widget and the codec DAI capture widget for playback, with
> > +the reverse applying to the capture path. To trigger these routes,
> > +DAPM requires valid endpoints, which can be either sink or source
> > +widgets corresponding to the playback and capture paths,
> >  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.
> > -
> > -A dai_link in a "simple-audio-card" will automatically be detected as
> > -codec to codec when all DAIs on the link belong to codec components.
> > -The dai_link will be initialized with the subset of stream parameters
> > -(channels, format, sample rate) supported by all DAIs on the link. Since
> > -there is no way to provide these parameters in the device tree, this is
> > -mostly useful for communication with simple fixed-function codecs, such
> > -as a Bluetooth controller or cellular modem.
> > +To activate this DAI link widget, a lightweight codec driver for
> > +the speaker amplifier can be implemented, following a similar
> > +strategy to that in ``wm8727.c``. This driver should set the
> > +necessary constraints for the device, even with minimal control
> > +requirements.
>
> Would actually be nice to include the note that any codec driver
> should be fine, the original text does kinda give the impression
> one would have to write a "thin codec driver" but if you already
> have a driver thin or otherwise that would be fine. Perhaps
> better to rephrase as a codec driver being required.

ok
>
> > +
> > +It's crucial to append “Playback” and “Capture” suffixes to the
> > +respective CPU and codec DAI names for playback and capture, as
> > +the DAPM core links and powers these DAIs based on their naming
> > +conventions.
>
> Are you sure this is true? I could be wrong but I don't expect
> the naming is critical in hooking up a c2c DAI.

tested this on my board and you are right. Will remove this.

>
> > +
> > +In a codec-to-codec scenario involving multiple codecs (above
> > +bootup logs are for multicodec scenario), it is not feasible to
> > +control individual codecs using dummy kcontrols or DAPM widgets.
>
> I really am not sure what this means. What are we controlling
> using dummy kcontrols? Why are we not using the real kcontrols
> from the codec to control the codec?

Our system includes a DSP that can generate audio(not audio to be
honest but can be considered as a audio channel) independently,
without CPU involvement. This audio needs to be sent to speakers
via codecs, even when playback isn't occurring.

We modeled all codecs as a C2C having one single snd_soc_dai_link
with multiple codecs. So, now we can control all codecs using mixer
control which we created as a part of C2C path completion.

However, we got a new usecase where we shouldn't turn on all the
codecs when mixer control is used for C2C, instead user should be able
to specify which codec should get turned on.

So, I attempted to add one more dummy mixer as part of C2C mixer
path, follishly thinking that if the dummy mixer is not enabled, C2C
won't allow the corresponding codec to get turned on. After reading
the code, I saw that in C2C implementation it doesn't check for
widget power status when turning on the path and nor check if the
path is complete or not before calling the pcm ops.

This is what I am listing as a drawback but I guess I can remove
that as it is by design because we can probably have multiple
snd_soc_dai_link C2C and then we can control them individually.

>
> > +This limitation arises because the CPU DAI is statically
> > +connected to all codecs. Consequently, when a path is enabled,
>
> Which it shouldn't be?
>
> > +the DAPM core does not verify all the widgets that may be linked
> > +to the mixer widget. It’s important to note that the mixer widget
> > +serves as the trigger for these paths.
> > +
> > +Simple-audio-card configuration
> > +----------------------------------
> > +A dai_link in a "simple-audio-card" will automatically be
> > +detected as codec-to-codec when all DAIs on the link belong to
> > +codec components. The dai_link will be initialized with the
> > +subset of stream parameters (channels, format, sample rate)
> > +supported by all DAIs on the link. Since there is no way to
> > +provide these parameters in the device tree, this is mostly useful
> > +for communication with simple fixed-function codecs, such as a
> > +Bluetooth controller or cellular modem.
> > --
> > 2.39.3 (Apple Git-146)
> >
> >
>
> Thanks,
> Charles

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v2] Docs/sound: Update codec-to-codec documentation
  2024-10-24 20:27   ` anish kumar
@ 2024-10-25  8:58     ` Charles Keepax
  2024-10-26 21:52       ` anish kumar
  0 siblings, 1 reply; 7+ messages in thread
From: Charles Keepax @ 2024-10-25  8:58 UTC (permalink / raw)
  To: anish kumar; +Cc: perex, tiwai, corbet, linux-sound, linux-doc, linux-kernel

On Thu, Oct 24, 2024 at 01:27:51PM -0700, anish kumar wrote:
> On Wed, Oct 23, 2024 at 9:10 AM Charles Keepax
> <ckeepax@opensource.cirrus.com> wrote:
> > Bringing the "dummy" into this is quite misleading, that really
> > relates to DPCM setups. DPCM lets one select any number of back
> > ends to service a given front end PCM, and often are abused to
> > achieve things that should really be implemented as C2C links.
> 
> Aha, understood. For C2C we need a thin dummy codec driver
> which acts as a cpu driver in the ASoC code right?
> 

No there is no need for any dummies or thins anywhere, a codec to
codec link is simply a mechanism for hooking two codec drivers
together.

> Based on the code from bells.c, below is the C2C and we do provide
> a CPU driver, even though in actual it is a codec driver.
> 
> SND_SOC_DAILINK_DEFS(wm2200_dsp_codec,
> DAILINK_COMP_ARRAY(COMP_CPU("wm0010-sdi2")),
> DAILINK_COMP_ARRAY(COMP_CODEC("wm2200.1-003a", "wm2200")));
> 

Yes you are providing a CPU side to the link, but as you say that
is actually a CODEC driver. Although I guess really this is really
more historical accident since links were originally defined between
CPUs and CODECs.

> Perhaps, I can just remove the "dummy" from the diagram above.
> 

Yeah it has no place in this document.

> > > +single ``cpu_dai`` with both ``codec_dais``. Boot-up logs will
> > > +display messages similar to:
> >
> > That is definitely not what should be happening with a C2C link.
> > In the system you showed the diagram for above there should be a
> > connection between the CPU and codec-2, then two separate links
> > between codec-2 and codecs 1 and 3. No links should be present
> > between the CPU and codecs 1 or 3.
> 
> Got it, I will try to convey the same in the diagram but ascii art is hard :)
> 

Apart from the dummy bit the diagram is fine here, it is the
description in the text that is wrong.

> Can you help clarify my understanding (based on the dapm code walkthrough),
> when the mixer control is triggered, the CPU widgets gets triggered
> thereby triggering codec2 widgets and as there is a static connection
> between codec1 and codec2 it gets also triggered and the same thing
> happens to codec3 as it is also linked to codec2?
> 
> Also, as the widgets are linked to dai ops, all the ops gets triggered as well.
> 

DAPM will power up anything that is between an active source and
an active sync. I would imagine from the diagram shown above
there would likely be two obvious use-cases:

Host music playback:
CPU -> CODEC2 -> CODEC3 -> Speaker

When something on the host plays some audio this will inform DAPM
that the main CPU DAI is now an active source. This will propogate
through the graph until it finds the speaker sink. The act of
playing music will power up the CPU -> CODEC2 dailink. Then DAPM
will power the C2C link between CODEC2 and 3 since it is on the
audio path.

Cellular call:
CODEC1 -> CODEC2 -> CODEC3 -> Speaker

In this case the host is not involved at all. The modem is audio
source and DAPM powers up everything between it and the sink ie.
the speaker. That would involve the two C2C links between CODEC1
and 2, and between CODEC2 and 3.

> >
> > > +
> > > +.. code-block:: bash
> > > +
> > > +   ASoC: registered pcm #0 codec2codec(Playback Codec)
> > > +   multicodec <-> cpu_dai mapping ok
> > > +   connected DAI link Dummy-CPU:cpu_dai -> codec-1:dai_1
> > > +   connected DAI link Dummy-CPU:cpu_dai -> codec-2:dai_2
> > > +
> >
> > Yeah this is definitely mixing in a fair amount of DPCM stuff and
> > does not match the rest of the description.
> 
> I guess what you meant is that C2C doesn't care about the above
> connection as it uses DAPM widget connection to trigger the path
> right? So, even if this connection doesn't exist C2C will still work.
> 
> Reason why I am asking is that I saw the above logs when I
> added a C2C connection.
> 

That I can't really be sure it depends on how your system was put
together.  There are two things that are reasonably likely:

As I said it is quite likely your system is using Dynamic PCM (DPCM)
this is a mechanism to attach multiple "Backend End" devices to a
single "Front End" DAI link. It is often used by systems that have
a DSP built into the host, which might select different places to
send the audio to. In many ways this accomplishes the same thing as
C2C links, such a system could equal well be represented with the
DSP being a codec driver and each of the "backends" being C2C links.

Alternatively, in the deep dark of history some people did implement
a "dummy link" from the host to the cellular for the purposes
of configuring the params on the modem, even though the audio
technically when through some other route. But this was always a
hack and we should probably not be detailing it in the documentation.

> >
> > > +To trigger this DAI link, a control interface is established by the
> > > +DAPM core during internal DAI creation. This interface links to
> > > +the ``snd_soc_dai_link_event`` function, which is invoked when a
> > > +path connects in the DAPM core. A mixer must be created to trigger
> > > +the connection, prompting the DAPM core to evaluate path
> > > +connections and call the ``snd_soc_dai_link_event`` callback with
> > > +relevant events.
> > > +
> > > +It is important to note that not all operations defined in
> > > +``snd_soc_dai_ops`` are invoked as codec-to-codec connections offer
> > > +limited control over DAI configuration. For greater control, a
> > > +hostless configuration is recommended. The operations typically
> >
> > It is not clear to me what a "hostless configuration" is here.
> 
> What I meant to convey is, if the user wants all pcm ops to get called in
> order then he can use "Hostless FE" and connect to backend use as a normal PCM.
> 

All the talk of front ends and back ends has nothing to do with
codec to codec links and should not be relevant for this
document.

> > > +In a codec-to-codec scenario involving multiple codecs (above
> > > +bootup logs are for multicodec scenario), it is not feasible to
> > > +control individual codecs using dummy kcontrols or DAPM widgets.
> >
> > I really am not sure what this means. What are we controlling
> > using dummy kcontrols? Why are we not using the real kcontrols
> > from the codec to control the codec?
> 
> Our system includes a DSP that can generate audio(not audio to be
> honest but can be considered as a audio channel) independently,
> without CPU involvement. This audio needs to be sent to speakers
> via codecs, even when playback isn't occurring.
> 
> We modeled all codecs as a C2C having one single snd_soc_dai_link
> with multiple codecs. So, now we can control all codecs using mixer
> control which we created as a part of C2C path completion.
> 

Have you by any chance tried to combine the usual DPCM
implementation for host side DSPs with a bunch of C2C links? It's
not necessarily wrong but it seems like an odd choice. Either
represent the DSP using DPCM or C2C links.

> However, we got a new usecase where we shouldn't turn on all the
> codecs when mixer control is used for C2C, instead user should be able
> to specify which codec should get turned on.
> 
> So, I attempted to add one more dummy mixer as part of C2C mixer
> path, follishly thinking that if the dummy mixer is not enabled, C2C
> won't allow the corresponding codec to get turned on. After reading
> the code, I saw that in C2C implementation it doesn't check for
> widget power status when turning on the path and nor check if the
> path is complete or not before calling the pcm ops.
> 

This doesn't seem accurate either, DAPM will only turn on things
between an active source and an active sink. So it should not be
enabling links that are not on a complete path. Although that
said the complete path might be one you didn't intent to exist
it will take any available route between a source and sink.

The more typical way to handle this would be to define a
PIN_SWITCH for the sink on each CODEC then you can enable/disable
those sinks and the CODECs in question should not get powered up
if they have no valid sinks.

Thanks,
Charles

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v2] Docs/sound: Update codec-to-codec documentation
  2024-10-25  8:58     ` Charles Keepax
@ 2024-10-26 21:52       ` anish kumar
  0 siblings, 0 replies; 7+ messages in thread
From: anish kumar @ 2024-10-26 21:52 UTC (permalink / raw)
  To: Charles Keepax; +Cc: perex, tiwai, corbet, linux-sound, linux-doc, linux-kernel

On Fri, Oct 25, 2024 at 1:58 AM Charles Keepax
<ckeepax@opensource.cirrus.com> wrote:
>
> On Thu, Oct 24, 2024 at 01:27:51PM -0700, anish kumar wrote:
> > On Wed, Oct 23, 2024 at 9:10 AM Charles Keepax
> > <ckeepax@opensource.cirrus.com> wrote:
> > > Bringing the "dummy" into this is quite misleading, that really
> > > relates to DPCM setups. DPCM lets one select any number of back
> > > ends to service a given front end PCM, and often are abused to
> > > achieve things that should really be implemented as C2C links.
> >
> > Aha, understood. For C2C we need a thin dummy codec driver
> > which acts as a cpu driver in the ASoC code right?
> >
>
> No there is no need for any dummies or thins anywhere, a codec to
> codec link is simply a mechanism for hooking two codec drivers
> together.
>
> > Based on the code from bells.c, below is the C2C and we do provide
> > a CPU driver, even though in actual it is a codec driver.
> >
> > SND_SOC_DAILINK_DEFS(wm2200_dsp_codec,
> > DAILINK_COMP_ARRAY(COMP_CPU("wm0010-sdi2")),
> > DAILINK_COMP_ARRAY(COMP_CODEC("wm2200.1-003a", "wm2200")));
> >
>
> Yes you are providing a CPU side to the link, but as you say that
> is actually a CODEC driver. Although I guess really this is really
> more historical accident since links were originally defined between
> CPUs and CODECs.
>
> > Perhaps, I can just remove the "dummy" from the diagram above.
> >
>
> Yeah it has no place in this document.
>
> > > > +single ``cpu_dai`` with both ``codec_dais``. Boot-up logs will
> > > > +display messages similar to:
> > >
> > > That is definitely not what should be happening with a C2C link.
> > > In the system you showed the diagram for above there should be a
> > > connection between the CPU and codec-2, then two separate links
> > > between codec-2 and codecs 1 and 3. No links should be present
> > > between the CPU and codecs 1 or 3.
> >
> > Got it, I will try to convey the same in the diagram but ascii art is hard :)
> >
>
> Apart from the dummy bit the diagram is fine here, it is the
> description in the text that is wrong.
>
> > Can you help clarify my understanding (based on the dapm code walkthrough),
> > when the mixer control is triggered, the CPU widgets gets triggered
> > thereby triggering codec2 widgets and as there is a static connection
> > between codec1 and codec2 it gets also triggered and the same thing
> > happens to codec3 as it is also linked to codec2?
> >
> > Also, as the widgets are linked to dai ops, all the ops gets triggered as well.
> >
>
> DAPM will power up anything that is between an active source and
> an active sync. I would imagine from the diagram shown above
> there would likely be two obvious use-cases:
>
> Host music playback:
> CPU -> CODEC2 -> CODEC3 -> Speaker
>
> When something on the host plays some audio this will inform DAPM
> that the main CPU DAI is now an active source. This will propogate
> through the graph until it finds the speaker sink. The act of
> playing music will power up the CPU -> CODEC2 dailink. Then DAPM
> will power the C2C link between CODEC2 and 3 since it is on the
> audio path.
>
> Cellular call:
> CODEC1 -> CODEC2 -> CODEC3 -> Speaker
>
> In this case the host is not involved at all. The modem is audio
> source and DAPM powers up everything between it and the sink ie.
> the speaker. That would involve the two C2C links between CODEC1
> and 2, and between CODEC2 and 3.

Thanks for the explanation and will add this beauty to the document.
>
> > >
> > > > +
> > > > +.. code-block:: bash
> > > > +
> > > > +   ASoC: registered pcm #0 codec2codec(Playback Codec)
> > > > +   multicodec <-> cpu_dai mapping ok
> > > > +   connected DAI link Dummy-CPU:cpu_dai -> codec-1:dai_1
> > > > +   connected DAI link Dummy-CPU:cpu_dai -> codec-2:dai_2
> > > > +
> > >
> > > Yeah this is definitely mixing in a fair amount of DPCM stuff and
> > > does not match the rest of the description.
> >
> > I guess what you meant is that C2C doesn't care about the above
> > connection as it uses DAPM widget connection to trigger the path
> > right? So, even if this connection doesn't exist C2C will still work.
> >
> > Reason why I am asking is that I saw the above logs when I
> > added a C2C connection.
> >
>
> That I can't really be sure it depends on how your system was put
> together.  There are two things that are reasonably likely:
>
> As I said it is quite likely your system is using Dynamic PCM (DPCM)
> this is a mechanism to attach multiple "Backend End" devices to a
> single "Front End" DAI link. It is often used by systems that have
> a DSP built into the host, which might select different places to
> send the audio to. In many ways this accomplishes the same thing as
> C2C links, such a system could equal well be represented with the
> DSP being a codec driver and each of the "backends" being C2C links.
>
> Alternatively, in the deep dark of history some people did implement
> a "dummy link" from the host to the cellular for the purposes
> of configuring the params on the modem, even though the audio
> technically when through some other route. But this was always a
> hack and we should probably not be detailing it in the documentation.
>

Let me start a new thread on this and start a different thread with relevant
logs and not muddle this documentation with my problem. However,
thanks for this explanation.
> > >
> > > > +To trigger this DAI link, a control interface is established by the
> > > > +DAPM core during internal DAI creation. This interface links to
> > > > +the ``snd_soc_dai_link_event`` function, which is invoked when a
> > > > +path connects in the DAPM core. A mixer must be created to trigger
> > > > +the connection, prompting the DAPM core to evaluate path
> > > > +connections and call the ``snd_soc_dai_link_event`` callback with
> > > > +relevant events.
> > > > +
> > > > +It is important to note that not all operations defined in
> > > > +``snd_soc_dai_ops`` are invoked as codec-to-codec connections offer
> > > > +limited control over DAI configuration. For greater control, a
> > > > +hostless configuration is recommended. The operations typically
> > >
> > > It is not clear to me what a "hostless configuration" is here.
> >
> > What I meant to convey is, if the user wants all pcm ops to get called in
> > order then he can use "Hostless FE" and connect to backend use as a normal PCM.
> >
>
> All the talk of front ends and back ends has nothing to do with
> codec to codec links and should not be relevant for this
> document.

Sure, will get rid of this.
>
> > > > +In a codec-to-codec scenario involving multiple codecs (above
> > > > +bootup logs are for multicodec scenario), it is not feasible to
> > > > +control individual codecs using dummy kcontrols or DAPM widgets.
> > >
> > > I really am not sure what this means. What are we controlling
> > > using dummy kcontrols? Why are we not using the real kcontrols
> > > from the codec to control the codec?
> >
> > Our system includes a DSP that can generate audio(not audio to be
> > honest but can be considered as a audio channel) independently,
> > without CPU involvement. This audio needs to be sent to speakers
> > via codecs, even when playback isn't occurring.
> >
> > We modeled all codecs as a C2C having one single snd_soc_dai_link
> > with multiple codecs. So, now we can control all codecs using mixer
> > control which we created as a part of C2C path completion.
> >
>
> Have you by any chance tried to combine the usual DPCM
> implementation for host side DSPs with a bunch of C2C links? It's
> not necessarily wrong but it seems like an odd choice. Either
> represent the DSP using DPCM or C2C links.
>
> > However, we got a new usecase where we shouldn't turn on all the
> > codecs when mixer control is used for C2C, instead user should be able
> > to specify which codec should get turned on.
> >
> > So, I attempted to add one more dummy mixer as part of C2C mixer
> > path, follishly thinking that if the dummy mixer is not enabled, C2C
> > won't allow the corresponding codec to get turned on. After reading
> > the code, I saw that in C2C implementation it doesn't check for
> > widget power status when turning on the path and nor check if the
> > path is complete or not before calling the pcm ops.
> >
>
> This doesn't seem accurate either, DAPM will only turn on things
> between an active source and an active sink. So it should not be
> enabling links that are not on a complete path. Although that
> said the complete path might be one you didn't intent to exist
> it will take any available route between a source and sink.
> The more typical way to handle this would be to define a
> PIN_SWITCH for the sink on each CODEC then you can enable/disable
> those sinks and the CODECs in question should not get powered up
> if they have no valid sinks.
>
> Thanks,
> Charles

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2024-10-26 21:53 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-10-20 16:37 [PATCH v2] Docs/sound: Update codec-to-codec documentation anish kumar
2024-10-23 16:10 ` Charles Keepax
2024-10-23 16:15   ` Jonathan Corbet
2024-10-24 10:07     ` Bagas Sanjaya
2024-10-24 20:27   ` anish kumar
2024-10-25  8:58     ` Charles Keepax
2024-10-26 21:52       ` anish kumar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).