Skip to content

Commit 686403c

Browse files
committed
feat(linux): Add audio-graph-card2 support documentation as part of McASP machine driver binding specifics
Signed-off-by: Sen Wang <sen@ti.com>
1 parent 4dfe056 commit 686403c

1 file changed

Lines changed: 213 additions & 2 deletions

File tree

  • source/linux/Foundational_Components/Kernel/Kernel_Drivers

source/linux/Foundational_Components/Kernel/Kernel_Drivers/Audio.rst

Lines changed: 213 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ in board-level device trees:
9090
- uint32
9191
- No :sup:`1`
9292
- | A fixed multiplier to sampling rate (𝑓\ :sub:`s`) for a given AUXCLK frequency for TX (and RX if ``auxclk-fs-ratio-rx`` not specified).
93-
| :sup:`1` If not specified, dividers are calculated from ``.set_sysclk`` via the ASoC machine driver. (For common machine driver such as simple-audio-card or audio-graph-card, this is set via the ``system-clock-frequency = <>`` property in the DAI link).
93+
| :sup:`1` If not specified, dividers are calculated from ``.set_sysclk`` via the ASoC machine driver. (For common machine driver such as simple-audio-card, audio-graph-card, or audio-graph-card2, this is set via the ``system-clock-frequency = <>`` property in the DAI link or endpoint).
9494
| Only applicable when McASP is the master which produces the bit clock.
9595
| See :ref:`Configuration Guidelines <mcasp-configuration-guidelines>` for details on usage and calculation.
9696
* - **serial-dir**
@@ -346,7 +346,12 @@ via a sound card definition in the device tree.
346346

347347
The **simple-audio-card** is a generic machine driver and establishes Digital Audio Interface (DAI)
348348
links that connect the McASP (CPU-side) to codec(s). These DAI links operate within the ASoC framework, which constitutes part of the ALSA stack.
349-
Most TI EVMs use simple-audio-card for its simplicity, though audio-graph-card or custom machine drivers are also supported.
349+
Most TI EVMs use simple-audio-card for its simplicity, though audio-graph-card, audio-graph-card2, or custom machine drivers are also supported.
350+
audio-graph-card2 describes DAI links through the generic OF-graph ``ports``/``port``/``endpoint`` bindings
351+
on the McASP node instead of ``simple-audio-card``'s ``cpu``/``codec`` phandle pairs (see the example
352+
below). It also handles a DPCM topology, where one front-end stream fans out to, or fans in from, more
353+
than one backend codec DAI. ``simple-audio-card`` has no mechanism for that: it only ever builds fixed
354+
one-to-one DAI links. See :ref:`DPCM Topology <mcasp-dpcm-topology>` below.
350355
All DAI link properties McASP relies on are part of the generic ASoC framework, not specific to any particular machine driver.
351356

352357
The DAI link configuration provides the following intrinsics to the McASP driver:
@@ -537,6 +542,212 @@ In this multi-codec configuration:
537542
* ``system-clock-direction-out`` is required for McASP to generate clocks, which is required when McASP is driving the signals in master mode
538543
* Since McASP is in master mode, ``auxclk-fs-ratio`` should be defined in the McASP node, otherwise ``system-clock-frequency`` must be set in the DAI link to provide a fixed clock source
539544

545+
**Multiple Codecs via audio-graph-card2**
546+
547+
``simple-audio-card`` can already share one McASP instance across multiple independent codec links (see
548+
the ``simple-audio-card`` multi-codec example above), using its ``cpu``/``codec`` phandle pairs.
549+
**audio-graph-card2** describes the same kind of topology through the generic OF-graph ``ports``/``port``
550+
bindings directly on the McASP node instead. The following example is from AM62P5-SK
551+
(``k3-am62p5-sk.dts``), where one McASP instance serves both a TLV320AIC3106 codec and the on-board
552+
sii9022 HDMI bridge:
553+
554+
.. code-block:: devicetree
555+
556+
/* Example from AM62P5-SK (k3-am62p5-sk.dts) */
557+
sound0 {
558+
compatible = "audio-graph-card2";
559+
label = "AM62x-SKEVM";
560+
links = <&mcasp1_codec>, <&mcasp1_hdmi>;
561+
};
562+
563+
&mcasp1 {
564+
ports {
565+
#address-cells = <1>;
566+
#size-cells = <0>;
567+
568+
/* Codec link: TLV320AIC3106, codec is clock master */
569+
mcasp1_codec: port@0 {
570+
reg = <0>;
571+
572+
mcasp1_codec_endpoint: endpoint {
573+
remote-endpoint = <&aic3x_endpoint>;
574+
dai-format = "dsp_b";
575+
bitclock-inversion;
576+
};
577+
};
578+
579+
/* HDMI link: SII9022, McASP is clock master */
580+
mcasp1_hdmi: port@1 {
581+
reg = <1>;
582+
583+
mcasp1_hdmi_endpoint: endpoint {
584+
remote-endpoint = <&hdmi_audio_endpoint>;
585+
dai-format = "i2s";
586+
bitclock-master;
587+
frame-master;
588+
system-clock-direction-out;
589+
};
590+
};
591+
};
592+
};
593+
594+
In this configuration:
595+
596+
* One McASP DAI serves both codec links (here, a headphone codec and HDMI), each exposed as its own ``port@N`` endpoint under the McASP node's ``ports`` container
597+
* Each ``port@N`` endpoint carries its own ``dai-format`` and clock-role properties. The driver re-applies the active link's format on every ``hw_params`` call, since the shared DAI would otherwise keep the format from whichever link initialized last
598+
* The sound card node's ``links`` property lists the participating McASP ports, in the order they should appear as ALSA PCM devices
599+
* This is backward compatible with boards still using ``simple-audio-card``. No McASP-level configuration change is needed to switch machine drivers
600+
601+
.. _mcasp-dpcm-topology:
602+
603+
**DPCM Topology (Up to Two Front-Ends, One Direction Each)**
604+
605+
audio-graph-card2 also supports a DPCM (Dynamic PCM) topology on the same McASP ``ports`` binding, fanning
606+
one McASP instance out to several backend (BE) codec DAIs. On the McASP side this supports up to two
607+
front-ends (FE): one playback-only, one capture-only, since one McASP instance only has one TX data path
608+
and one RX data path. The driver does not support two FEs in the same direction.
609+
610+
The non-DPCM topology shown above maps each ``port``/``link`` to its own independent ALSA PCM device, one
611+
codec DAI at a time. It has no way to route a single userspace stream to more than one BE codec DAI, or to
612+
merge several BE codec DAIs into one userspace stream. DPCM's ``routing`` property connects FE widgets to
613+
BE widgets through DAPM instead of a fixed one-to-one DAI link, so it can do both. Without it, a board like
614+
this would need userspace to open several independent PCM devices, one per BE codec DAI, and keep them
615+
synchronized by hand, instead of one playback device and one capture device.
616+
617+
The following is based on the TAS67CD-AEC daughter card overlay for AM62D-EVM
618+
(``k3-am62d-evm-tas67cd-aec.dtso``), which drives two TAS6754 quad-channel amplifiers, TAS0 and TAS1, off a
619+
single McASP instance. Each chip exposes an audio, ANC, and feedback DAI. TAS0 and TAS1 play the same
620+
program audio at the same time, so the one FE playback stream fans out to both chips' audio and ANC BE
621+
DAIs. Both chips' feedback BE DAIs fan in to the single FE capture stream. TAS1's BE port block is omitted
622+
below, since it mirrors TAS0's:
623+
624+
.. code-block:: devicetree
625+
626+
&mcasp1 {
627+
ports {
628+
#address-cells = <1>;
629+
#size-cells = <0>;
630+
631+
/* Port 0: FE playback DAI, McASP is bus/frame provider */
632+
port@0 {
633+
reg = <0>;
634+
635+
mcasp1_port0_ep: endpoint {
636+
dai-format = "dsp_b";
637+
bitclock-master;
638+
frame-master;
639+
remote-endpoint = <&fe_pb_ep>;
640+
};
641+
};
642+
643+
/* Port 1: FE capture DAI */
644+
port@1 {
645+
reg = <1>;
646+
647+
mcasp1_port1_ep: endpoint {
648+
dai-format = "dsp_b";
649+
bitclock-master;
650+
frame-master;
651+
remote-endpoint = <&fe_cap_ep>;
652+
};
653+
};
654+
};
655+
};
656+
657+
/* audio-graph-card2 DPCM sound card */
658+
sound_tas67cd: sound-tas67cd {
659+
compatible = "audio-graph-card2";
660+
label = "TAS67CD-AEC";
661+
662+
routing =
663+
/* FE playback fans out to both chips' audio + ANC BE DAIs */
664+
"TAS0 Playback", "Playback Port 0",
665+
"TAS1 Playback", "Playback Port 0",
666+
"TAS0 ANC Playback", "Playback Port 0",
667+
"TAS1 ANC Playback", "Playback Port 0",
668+
669+
/* Both chips' feedback BE DAIs fan in to the single FE capture stream */
670+
"Capture Port 1", "TAS0 Feedback Capture",
671+
"Capture Port 1", "TAS1 Feedback Capture";
672+
673+
links = <&mcasp1_fe_pb>, <&mcasp1_fe_cap>,
674+
<&be_tas0_audio>, <&be_tas0_anc>, <&be_tas0_fb>,
675+
<&be_tas1_audio>, <&be_tas1_anc>, <&be_tas1_fb>;
676+
677+
dpcm {
678+
#address-cells = <1>;
679+
#size-cells = <0>;
680+
681+
/* Front-End: 2 FE DAIs on McASP1 */
682+
ports@0 {
683+
reg = <0>;
684+
#address-cells = <1>;
685+
#size-cells = <0>;
686+
687+
mcasp1_fe_pb: port@0 {
688+
reg = <0>;
689+
playback-only;
690+
691+
fe_pb_ep: endpoint {
692+
remote-endpoint = <&mcasp1_port0_ep>;
693+
};
694+
};
695+
696+
mcasp1_fe_cap: port@1 {
697+
reg = <1>;
698+
capture-only;
699+
700+
fe_cap_ep: endpoint {
701+
remote-endpoint = <&mcasp1_port1_ep>;
702+
};
703+
};
704+
};
705+
706+
/* Back-End: 6 BE links (2 chips x 3 DAIs); TAS1 block mirrors TAS0, omitted here */
707+
ports@1 {
708+
reg = <1>;
709+
#address-cells = <1>;
710+
#size-cells = <0>;
711+
712+
be_tas0_audio: port@0 {
713+
reg = <0>;
714+
715+
be_tas0_audio_ep: endpoint {
716+
remote-endpoint = <&tas0_audio_ep>;
717+
};
718+
};
719+
720+
be_tas0_anc: port@1 {
721+
reg = <1>;
722+
723+
be_tas0_anc_ep: endpoint {
724+
remote-endpoint = <&tas0_anc_ep>;
725+
};
726+
};
727+
728+
be_tas0_fb: port@2 {
729+
reg = <2>;
730+
731+
be_tas0_fb_ep: endpoint {
732+
remote-endpoint = <&tas0_fb_ep>;
733+
};
734+
};
735+
};
736+
};
737+
};
738+
739+
In this configuration:
740+
741+
* The two FE ports on the McASP node (``port@0``/``port@1``) use the same flat, non-DPCM ``ports`` binding as the previous example. DPCM fan-out is defined on the **card** side, in the ``dpcm`` sub-node, not on the McASP node itself
742+
* ``dpcm { ports@0 {...}; }`` holds the FE DAIs. ``dpcm { ports@1 {...}; }`` holds the BE DAIs. Each BE ``port@N`` links to a codec-side DAI endpoint, here one of the six TAS6754 DAIs across both chips
743+
* Each FE port is restricted with ``playback-only`` or ``capture-only``. Both FEs map to the same physical McASP instance, registered as separate DAIs (``davinci-mcasp.0``, ``davinci-mcasp.1``), so each FE is limited to one direction to avoid a conflict on that shared hardware
744+
* The card's ``routing`` property does the fan-out and fan-in. It connects the single "Playback Port 0" FE widget to four BE playback widgets, and both chips' feedback BE widgets to the single "Capture Port 1" FE widget. That many-to-one, one-to-many wiring is not possible with the non-DPCM binding shown earlier
745+
746+
.. attention::
747+
748+
This DPCM topology supports up to **two** front-ends sharing one McASP instance: one playback-only,
749+
one capture-only. It does not support two front-ends in the same direction.
750+
540751
For more information on DAI link configuration and ASoC machine drivers, refer to ALSA links in the :ref:`Additional Information <additional-information-alsa-links>` section below.
541752

542753
.. _mcasp-runtime-behavior:

0 commit comments

Comments
 (0)