Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
215 changes: 213 additions & 2 deletions source/linux/Foundational_Components/Kernel/Kernel_Drivers/Audio.rst
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@
- uint32
- No :sup:`1`
- | A fixed multiplier to sampling rate (𝑓\ :sub:`s`) for a given AUXCLK frequency for TX (and RX if ``auxclk-fs-ratio-rx`` not specified).
| :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).
| :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).

Check warning on line 93 in source/linux/Foundational_Components/Kernel/Kernel_Drivers/Audio.rst

View workflow job for this annotation

GitHub Actions / vale

[vale] reported by reviewdog 🐶 [RedHat.PassiveVoice] 'is set' is passive voice. In general, use active voice. Consult the style guide for acceptable use of passive voice. Raw Output: {"message": "[RedHat.PassiveVoice] 'is set' is passive voice. In general, use active voice. Consult the style guide for acceptable use of passive voice.", "location": {"path": "source/linux/Foundational_Components/Kernel/Kernel_Drivers/Audio.rst", "range": {"start": {"line": 93, "column": 210}}}, "severity": "INFO"}

Check warning on line 93 in source/linux/Foundational_Components/Kernel/Kernel_Drivers/Audio.rst

View workflow job for this annotation

GitHub Actions / vale

[vale] reported by reviewdog 🐶 [RedHat.TermsSuggestions] Depending on the context, consider using 'through', 'by', 'from', 'on', or 'by using' rather than 'via'. Raw Output: {"message": "[RedHat.TermsSuggestions] Depending on the context, consider using 'through', 'by', 'from', 'on', or 'by using' rather than 'via'.", "location": {"path": "source/linux/Foundational_Components/Kernel/Kernel_Drivers/Audio.rst", "range": {"start": {"line": 93, "column": 82}}}, "severity": "INFO"}

Check warning on line 93 in source/linux/Foundational_Components/Kernel/Kernel_Drivers/Audio.rst

View workflow job for this annotation

GitHub Actions / vale

[vale] reported by reviewdog 🐶 [RedHat.PassiveVoice] 'are calculated' is passive voice. In general, use active voice. Consult the style guide for acceptable use of passive voice. Raw Output: {"message": "[RedHat.PassiveVoice] 'are calculated' is passive voice. In general, use active voice. Consult the style guide for acceptable use of passive voice.", "location": {"path": "source/linux/Foundational_Components/Kernel/Kernel_Drivers/Audio.rst", "range": {"start": {"line": 93, "column": 46}}}, "severity": "INFO"}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
| :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).
| :sup:`1` If not specified, dividers are calculated from ``.set_sysclk`` via the ASoC machine driver. The ``system-clock-frequency`` property in the DAI link or endpoint sets this value for common machine drivers such as simple-audio-card, audio-graph-card, or audio-graph-card2).

| Only applicable when McASP is the master which produces the bit clock.
| See :ref:`Configuration Guidelines <mcasp-configuration-guidelines>` for details on usage and calculation.
* - **serial-dir**
Expand Down Expand Up @@ -346,7 +346,12 @@

The **simple-audio-card** is a generic machine driver and establishes Digital Audio Interface (DAI)
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.
Most TI EVMs use simple-audio-card for its simplicity, though audio-graph-card or custom machine drivers are also supported.
Most TI EVMs use simple-audio-card for its simplicity, though audio-graph-card2 or custom machine drivers are also supported.

Check warning on line 349 in source/linux/Foundational_Components/Kernel/Kernel_Drivers/Audio.rst

View workflow job for this annotation

GitHub Actions / vale

[vale] reported by reviewdog 🐶 [RedHat.Definitions] Define acronyms and abbreviations (such as 'EVMs') on first occurrence if they're likely to be unfamiliar. Raw Output: {"message": "[RedHat.Definitions] Define acronyms and abbreviations (such as 'EVMs') on first occurrence if they're likely to be unfamiliar.", "location": {"path": "source/linux/Foundational_Components/Kernel/Kernel_Drivers/Audio.rst", "range": {"start": {"line": 349, "column": 9}}}, "severity": "INFO"}
audio-graph-card2 describes DAI links through the generic OF-graph ``ports``/``port``/``endpoint`` bindings
on the McASP node instead of ``simple-audio-card``'s ``cpu``/``codec`` phandle pairs (see the example

Check warning on line 351 in source/linux/Foundational_Components/Kernel/Kernel_Drivers/Audio.rst

View workflow job for this annotation

GitHub Actions / vale

[vale] reported by reviewdog 🐶 [RedHat.Spelling] Verify the word 'phandle'. It is not in the American English or Red Hat terminology spelling dictionaries used by Vale. Raw Output: {"message": "[RedHat.Spelling] Verify the word 'phandle'. It is not in the American English or Red Hat terminology spelling dictionaries used by Vale.", "location": {"path": "source/linux/Foundational_Components/Kernel/Kernel_Drivers/Audio.rst", "range": {"start": {"line": 351, "column": 72}}}, "severity": "WARNING"}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm. The term phandle seems to be a colloquialism in the kernel for device tree references. It's well known enough to be used in the bindings, but not actually described in their documentation. Fun. Guess we should incorporate it in the accept list?

https://github.com/TexasInstruments/processor-sdk-doc/blob/master/CONTRIBUTING.md#vale-grammar-spelling-and-prose-checking

below). It also handles a DPCM (Dynamic PCM) topology, where one front-end stream fans out to, or fans in from, more

Check warning on line 352 in source/linux/Foundational_Components/Kernel/Kernel_Drivers/Audio.rst

View workflow job for this annotation

GitHub Actions / vale

[vale] reported by reviewdog 🐶 [RedHat.Definitions] Define acronyms and abbreviations (such as 'PCM') on first occurrence if they're likely to be unfamiliar. Raw Output: {"message": "[RedHat.Definitions] Define acronyms and abbreviations (such as 'PCM') on first occurrence if they're likely to be unfamiliar.", "location": {"path": "source/linux/Foundational_Components/Kernel/Kernel_Drivers/Audio.rst", "range": {"start": {"line": 352, "column": 41}}}, "severity": "INFO"}

Check warning on line 352 in source/linux/Foundational_Components/Kernel/Kernel_Drivers/Audio.rst

View workflow job for this annotation

GitHub Actions / vale

[vale] reported by reviewdog 🐶 [RedHat.Definitions] Define acronyms and abbreviations (such as 'DPCM') on first occurrence if they're likely to be unfamiliar. Raw Output: {"message": "[RedHat.Definitions] Define acronyms and abbreviations (such as 'DPCM') on first occurrence if they're likely to be unfamiliar.", "location": {"path": "source/linux/Foundational_Components/Kernel/Kernel_Drivers/Audio.rst", "range": {"start": {"line": 352, "column": 27}}}, "severity": "INFO"}

Check warning on line 352 in source/linux/Foundational_Components/Kernel/Kernel_Drivers/Audio.rst

View workflow job for this annotation

GitHub Actions / vale

[vale] reported by reviewdog 🐶 [RedHat.TermsSuggestions] Depending on the context, consider using 'after', 'later', or 'following' rather than 'below'. Raw Output: {"message": "[RedHat.TermsSuggestions] Depending on the context, consider using 'after', 'later', or 'following' rather than 'below'.", "location": {"path": "source/linux/Foundational_Components/Kernel/Kernel_Drivers/Audio.rst", "range": {"start": {"line": 352, "column": 1}}}, "severity": "INFO"}
Comment on lines +351 to +352

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
on the McASP node instead of ``simple-audio-card``'s ``cpu``/``codec`` phandle pairs (see the example
below). It also handles a DPCM (Dynamic PCM) topology, where one front-end stream fans out to, or fans in from, more
on the McASP node instead of ``simple-audio-card``'s ``cpu``/``codec`` phandle pairs (see the following
example). It also handles a DPCM (Dynamic PCM) topology, where one front-end stream fans out to, or fans in from, more

than one backend codec DAI. ``simple-audio-card`` has no mechanism for that: it only ever builds fixed
one-to-one DAI links. See :ref:`DPCM Topology <mcasp-dpcm-topology>` below.

Check warning on line 354 in source/linux/Foundational_Components/Kernel/Kernel_Drivers/Audio.rst

View workflow job for this annotation

GitHub Actions / vale

[vale] reported by reviewdog 🐶 [RedHat.UserReplacedValues] Separate words by underscores in user-replaced values. Raw Output: {"message": "[RedHat.UserReplacedValues] Separate words by underscores in user-replaced values.", "location": {"path": "source/linux/Foundational_Components/Kernel/Kernel_Drivers/Audio.rst", "range": {"start": {"line": 354, "column": 47}}}, "severity": "INFO"}
All DAI link properties McASP relies on are part of the generic ASoC framework, not specific to any particular machine driver.

The DAI link configuration provides the following intrinsics to the McASP driver:
Expand Down Expand Up @@ -537,6 +542,212 @@
* ``system-clock-direction-out`` is required for McASP to generate clocks, which is required when McASP is driving the signals in master mode
* 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

**Multiple Codecs Using audio-graph-card2**

Check warning on line 545 in source/linux/Foundational_Components/Kernel/Kernel_Drivers/Audio.rst

View workflow job for this annotation

GitHub Actions / vale

[vale] reported by reviewdog 🐶 [RedHat.SimpleWords] Use simple language. Consider using 'many' rather than 'Multiple'. Raw Output: {"message": "[RedHat.SimpleWords] Use simple language. Consider using 'many' rather than 'Multiple'.", "location": {"path": "source/linux/Foundational_Components/Kernel/Kernel_Drivers/Audio.rst", "range": {"start": {"line": 545, "column": 3}}}, "severity": "INFO"}

``simple-audio-card`` can already share one McASP instance across multiple independent codec links (see
the ``simple-audio-card`` multi-codec example above), using its ``cpu``/``codec`` phandle pairs.
**audio-graph-card2** describes the same kind of topology through the generic OF-graph ``ports``/``port``

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Highlight when user should switch to audio graph card2 and what are its advantages .

I think it helps avoid a system reboot when switching form tlv to HDMI codec as you had mentioned earlier as user just need to change the jumper right?

bindings directly on the McASP node instead. The following example is from AM62P5-SK
(``k3-am62p5-sk.dts``), where one McASP instance serves both a TLV320AIC3106 codec and the on-board
sii9022 HDMI bridge:

.. code-block:: devicetree

/* Example from AM62P5-SK (k3-am62p5-sk.dts) */
sound0 {
compatible = "audio-graph-card2";
label = "AM62x-SKEVM";
links = <&mcasp1_codec>, <&mcasp1_hdmi>;
};

&mcasp1 {
ports {
#address-cells = <1>;
#size-cells = <0>;

/* Codec link: TLV320AIC3106, codec is clock master */
mcasp1_codec: port@0 {
reg = <0>;

mcasp1_codec_endpoint: endpoint {
remote-endpoint = <&aic3x_endpoint>;
dai-format = "dsp_b";
bitclock-inversion;
};
};

/* HDMI link: SII9022, McASP is clock master */
mcasp1_hdmi: port@1 {
reg = <1>;

mcasp1_hdmi_endpoint: endpoint {
remote-endpoint = <&hdmi_audio_endpoint>;
dai-format = "i2s";
bitclock-master;
frame-master;
system-clock-direction-out;
};
};
};
};

In this configuration:

* 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

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good to give execution steps too, ideally an overlay would have been better.

  1. User applies this DT change
  2. User plays using TLV codec path -> steps and cmd
  3. User wants to play HDMI audio -> steps (Jumper change) and cmd to select hdmi dai link

* 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
* The sound card node's ``links`` property lists the participating McASP ports, in the order they should appear as ALSA PCM devices
* This is compatible with earlier boards still using ``simple-audio-card``. No McASP-level configuration change is needed to switch machine drivers

.. _mcasp-dpcm-topology:

**DPCM Topology (Up to Two Front-Ends, One Direction Each)**

audio-graph-card2 also supports a DPCM (Dynamic PCM) topology on the same McASP ``ports`` binding, fanning
one McASP instance out to several backend (BE) codec DAIs. On the McASP side this supports up to two
front-ends (FE): one playback and one capture, since one McASP instance only has one TX data path
and one RX data path. The driver does not support two FEs in the same direction.

The non-DPCM topology shown above maps each ``port``/``link`` to its own independent ALSA PCM device, one
codec DAI at a time. It has no way to route a single userspace stream to more than one BE codec DAI, or to
merge several BE codec DAIs into one userspace stream. DPCM's ``routing`` property connects FE widgets to
BE widgets through DAPM instead of a fixed one-to-one DAI link, so it can do both. Without it, a board like
this would need userspace to open several independent PCM devices, one per BE codec DAI, and keep them
synchronized by hand, instead of one playback device and one capture device.

The following is based on the TAS67CD-AEC daughter card overlay for AM62D-EVM
(``k3-am62d-evm-tas67cd-aec.dtso``), which drives two TAS6754 quad-channel amplifiers, TAS0 and TAS1, off a
single McASP instance. Each chip exposes an audio, ANC, and feedback DAI. TAS0 and TAS1 play the same
program audio at the same time, so the one FE playback stream fans out to both chips' audio and ANC BE
DAIs. Both chips' feedback BE DAIs fan in to the single FE capture stream. TAS1's BE port block is omitted
below, since it mirrors TAS0's:

.. code-block:: devicetree

&mcasp1 {
ports {
#address-cells = <1>;
#size-cells = <0>;

/* Port 0: FE playback DAI, McASP is bus/frame provider */
port@0 {
reg = <0>;

mcasp1_port0_ep: endpoint {
dai-format = "dsp_b";
bitclock-master;
frame-master;
remote-endpoint = <&fe_pb_ep>;
};
};

/* Port 1: FE capture DAI */
port@1 {
reg = <1>;

mcasp1_port1_ep: endpoint {
dai-format = "dsp_b";
bitclock-master;
frame-master;
remote-endpoint = <&fe_cap_ep>;
};
};
};
};

/* audio-graph-card2 DPCM sound card */
sound_tas67cd: sound-tas67cd {
compatible = "audio-graph-card2";
label = "TAS67CD-AEC";

routing =
/* FE playback fans out to both chips' audio + ANC BE DAIs */
"TAS0 Playback", "Playback Port 0",
"TAS1 Playback", "Playback Port 0",
"TAS0 ANC Playback", "Playback Port 0",
"TAS1 ANC Playback", "Playback Port 0",

/* Both chips' feedback BE DAIs fan in to the single FE capture stream */
"Capture Port 1", "TAS0 Feedback Capture",
"Capture Port 1", "TAS1 Feedback Capture";

links = <&mcasp1_fe_pb>, <&mcasp1_fe_cap>,
<&be_tas0_audio>, <&be_tas0_anc>, <&be_tas0_fb>,
<&be_tas1_audio>, <&be_tas1_anc>, <&be_tas1_fb>;

dpcm {
#address-cells = <1>;
#size-cells = <0>;

/* Front-End: 2 FE DAIs on McASP1 */
ports@0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <0>;

mcasp1_fe_pb: port@0 {
reg = <0>;
playback-only;

fe_pb_ep: endpoint {
remote-endpoint = <&mcasp1_port0_ep>;
};
};

mcasp1_fe_cap: port@1 {
reg = <1>;
capture-only;

fe_cap_ep: endpoint {
remote-endpoint = <&mcasp1_port1_ep>;
};
};
};

/* Back-End: 6 BE links (2 chips x 3 DAIs); TAS1 block mirrors TAS0, omitted here */
ports@1 {
reg = <1>;
#address-cells = <1>;
#size-cells = <0>;

be_tas0_audio: port@0 {
reg = <0>;

be_tas0_audio_ep: endpoint {
remote-endpoint = <&tas0_audio_ep>;
};
};

be_tas0_anc: port@1 {
reg = <1>;

be_tas0_anc_ep: endpoint {
remote-endpoint = <&tas0_anc_ep>;
};
};

be_tas0_fb: port@2 {
reg = <2>;

be_tas0_fb_ep: endpoint {
remote-endpoint = <&tas0_fb_ep>;
};
};
};
};
};

In this configuration:

* 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

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean by FE port?

* ``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
* 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
* 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

.. attention::

This DPCM topology supports up to **two** front-ends sharing one McASP instance: one playback and one
capture. It does not support two front-ends in the same direction.

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.

.. _mcasp-runtime-behavior:
Expand Down
Loading