Re: [PATCH v2] Docs/sound: Update codec-to-codec documentation

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]



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@xxxxxxxxx>
> ---

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




[Index of Archives]     [Pulseaudio]     [Linux Audio Users]     [ALSA Devel]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]

  Powered by Linux