From: Charles Keepax <ckeepax@opensource.cirrus.com>
To: anish kumar <yesanishhere@gmail.com>
Cc: <perex@perex.cz>, <tiwai@suse.com>, <corbet@lwn.net>,
<linux-sound@vger.kernel.org>, <linux-doc@vger.kernel.org>,
<linux-kernel@vger.kernel.org>
Subject: Re: [PATCH v2] Docs/sound: Update codec-to-codec documentation
Date: Wed, 23 Oct 2024 17:10:48 +0100 [thread overview]
Message-ID: <ZxkgCL2/JtDDJ9N1@opensource.cirrus.com> (raw)
In-Reply-To: <20241020163706.87123-1-yesanishhere@gmail.com>
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
next prev parent reply other threads:[~2024-10-23 16:11 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-10-20 16:37 [PATCH v2] Docs/sound: Update codec-to-codec documentation anish kumar
2024-10-23 16:10 ` Charles Keepax [this message]
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
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ZxkgCL2/JtDDJ9N1@opensource.cirrus.com \
--to=ckeepax@opensource.cirrus.com \
--cc=corbet@lwn.net \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-sound@vger.kernel.org \
--cc=perex@perex.cz \
--cc=tiwai@suse.com \
--cc=yesanishhere@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.