From 21d50c9d1f7dbeb6e0d214ac3c8a5c2d57c529e6 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Thu, 13 Aug 2026 11:22:44 +0300 Subject: [PATCH 1/3] ipc: ipc4: dai: do not set the direction bit for UAOL The link_config computed here is handed to the UAOL driver as the stream channel map and written to UAOLxPCMSyCM. On ACE 2.x and later that register only defines the lchan, hchan and strm fields, its two upper bits are reserved, and union hdalink_cfg keeps the direction in the topmost of them. Setting the direction therefore wrote a reserved bit for every capture stream, after which the link transferred no data at all and reported no error. Playback was unaffected because its direction is zero. The link does not need to be told the direction: transmit and receive streams have separate indices, so the stream already implies it. Fixes: ddd5c6442915 ("dai: uaol: add support for Intel UAOL") Signed-off-by: Peter Ujfalusi --- src/ipc/ipc4/dai.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ipc/ipc4/dai.c b/src/ipc/ipc4/dai.c index ee5821ad31c0..c0ed1f52c3a1 100644 --- a/src/ipc/ipc4/dai.c +++ b/src/ipc/ipc4/dai.c @@ -66,7 +66,7 @@ void dai_set_link_hda_config(uint16_t *link_config, case SOF_DAI_INTEL_UAOL: link_cfg.full = 0; link_cfg.part.hchan = gtw_fmt->channels_count - 1; - link_cfg.part.dir = common_config->direction; + /* UAOLxPCMSyCM has no direction bit, the stream selects it */ link_cfg.part.stream = common_config->host_dma_config[0]->stream_id; break; default: From 127f9f6e68548b604ad7fa4dc022fbddb9721e9d Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Thu, 13 Aug 2026 15:26:31 +0300 Subject: [PATCH 2/3] topology2: Add the UAOL DAI type The USB Audio Offload Link is an ACE2+ alt link. The firmware enumerates its gateways in the ALH class family, but the ALH DAI class carries SoundWire specific attributes, so UAOL is described by a DAI class of its own. Allow "UAOL" as a dai type and as a copier type, and let the dai-copier take the two UAOL node types which common_definitions.conf already defines. Signed-off-by: Peter Ujfalusi --- .../include/components/dai-copier.conf | 4 + .../topology2/include/components/dai.conf | 1 + .../topology/topology2/include/dais/uaol.conf | 95 +++++++++++++++++++ 3 files changed, 100 insertions(+) create mode 100644 tools/topology/topology2/include/dais/uaol.conf diff --git a/tools/topology/topology2/include/components/dai-copier.conf b/tools/topology/topology2/include/components/dai-copier.conf index e5508ada3df5..3b97ff0b4adf 100644 --- a/tools/topology/topology2/include/components/dai-copier.conf +++ b/tools/topology/topology2/include/components/dai-copier.conf @@ -44,6 +44,7 @@ Class.Widget."dai-copier" { "HDA" "SSP" "DMIC" + "UAOL" "SAI" ] } @@ -57,6 +58,7 @@ Class.Widget."dai-copier" { "SSP" "DMIC" "HDA" + "UAOL" "SAI" ] } @@ -103,6 +105,8 @@ Class.Widget."dai-copier" { $DMIC_LINK_INPUT_CLASS # DMIC link input (DSP <-) $I2S_LINK_OUTPUT_CLASS # I2S link output (DSP ->) $I2S_LINK_INPUT_CLASS # I2S link input (DSP <-) + $ALH_UAOL_STREAM_LINK_OUTPUT_CLASS # UAOL link output (DSP ->) + $ALH_UAOL_STREAM_LINK_INPUT_CLASS # UAOL link input (DSP <-) $IPC_OUTPUT_CLASS # IPC output (DSP ->) $IPC_INPUT_CLASS # IPC input (DSP <-) $I2S_MULTILINK_OUTPUT_CLASS # I2S Multi gtw output (DSP ->) diff --git a/tools/topology/topology2/include/components/dai.conf b/tools/topology/topology2/include/components/dai.conf index 4a34594b5eb0..41f884b4e9f9 100644 --- a/tools/topology/topology2/include/components/dai.conf +++ b/tools/topology/topology2/include/components/dai.conf @@ -28,6 +28,7 @@ Class.Widget."dai" { "DMIC" "HDA" "ALH" + "UAOL" "SAI" "ESAI" ] diff --git a/tools/topology/topology2/include/dais/uaol.conf b/tools/topology/topology2/include/dais/uaol.conf new file mode 100644 index 000000000000..56d8dd726481 --- /dev/null +++ b/tools/topology/topology2/include/dais/uaol.conf @@ -0,0 +1,95 @@ +# +# UAOL DAI +# +# All attributes defined herein are namespaced by alsatplg to +# "Object.Dai.UAOL.attribute_name" +# +# UAOL (USB Audio Offload Link) is an ACE2+ alt link. It belongs to the ALH +# class family in the firmware gateway enumeration, but it is described by its +# own DAI class because the ALH class carries SoundWire specific attributes. +# +# Usage: this component can be used by declaring as follows: +# +# For Playback +#Object.Dai.UAOL."N" { +# direction "playback" +# name "UAOL0" +# id 0 +# Object.Base.hw_config."0" {} +# } +# For Capture +#Object.Dai.UAOL."N" { +# direction "capture" +# name "UAOL0" +# id 0 +# Object.Base.hw_config."1" {} +# } +# +# Where N is the dai index of the UAOL DAI in the firmware + +Class.Dai."UAOL" { + # + # instance ID of UAOL DAI object + # + DefineAttribute."instance" {} + + # + # UAOL link index in the firmware + # + DefineAttribute."dai_index" { + token_ref "dai.word" + } + + DefineAttribute."direction" { + type "string" + constraints { + !valid_values [ + "playback" + "capture" + "duplex" + ] + } + } + + # type of DAI + DefineAttribute.dai_type { + type "string" + token_ref "dai.string" + } + + # Backend DAI Link ID matching with the machine driver + DefineAttribute.id {} + + DefineAttribute."default_hw_config_id" {} + + DefineAttribute.name { + type "string" + } + + DefineAttribute.rate {} + + DefineAttribute.ch {} + + attributes { + !constructor [ + "name" + ] + !mandatory [ + "id" + "dai_index" + ] + !immutable [ + "type" + ] + # + # UAOL DAI objects instantiated within the same alsaconf node must + # have unique instance attribute + # + unique "instance" + } + + dai_type "UAOL" + default_hw_config_id 0 + rate 48000 + ch 2 +} From e35615b9a8debe55196b8e459c478179dc0f3c41 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Thu, 13 Aug 2026 15:26:43 +0300 Subject: [PATCH 3/3] topology2: Add the cavs-uaol function topology The sof_sdw machine driver creates a backend DAI link for the USB Audio Offload Link when the platform reports one. Add the function topology which is loaded next to the other function topologies of that card. The playback path is a mixer based one, so a deep buffer PCM can share the link with the normal playback PCM. The capture path is a straight one with a high pass EQ IIR, matching what the SoundWire jack does, because the number of captured channels follows the USB device while a mixer only handles a fixed channel count. What the link is run at is decided by the USB device that happens to be plugged in, which is not known when the topology is built, so every widget of both paths carries the whole set of formats a USB device may ask for: S16_LE, S24_LE and S32_LE, 1 to 8 channels and the standard rates from 8 to 192 kHz, which is as far as UAOL goes. The kernel narrows the PCM down to what the connected device actually supports. The matrix is spelled out with CombineArrays in include/formats/uaol_*.conf, one file for the wire formats and one for the 32 bit only modules in between. 7 channels is left out, it is the one count in the range with no channel config and no channel map defined. The deep buffer PCM stays at 48 kHz stereo, it comes from the shared platform/intel/deep-buffer.conf, so it can only join the mixer while the normal playback PCM runs at that format, or is not running at all. The two directions are separate DAI links so that the format fixup of a link is decided by the DAI copier of that direction alone. Their names are kept short because alsatplg drops the widget tuples once the generated widget name exceeds 36 characters. The UAOL backend is the last one the machine driver creates, so its DAI link ID depends on the composition of the board. Build the ID variants which the SoundWire boards can produce. Signed-off-by: Peter Ujfalusi --- tools/topology/topology2/README.md | 5 + tools/topology/topology2/cavs-uaol.conf | 86 +++++ .../formats/uaol_input_audio_formats.conf | 344 ++++++++++++++++++ .../formats/uaol_input_audio_formats_s32.conf | 176 +++++++++ .../formats/uaol_output_audio_formats.conf | 344 ++++++++++++++++++ .../uaol_output_audio_formats_s32.conf | 176 +++++++++ .../platform/intel/uaol-generic.conf | 204 +++++++++++ .../tplg-targets-sdca-generic.cmake | 13 + 8 files changed, 1348 insertions(+) create mode 100644 tools/topology/topology2/cavs-uaol.conf create mode 100644 tools/topology/topology2/include/formats/uaol_input_audio_formats.conf create mode 100644 tools/topology/topology2/include/formats/uaol_input_audio_formats_s32.conf create mode 100644 tools/topology/topology2/include/formats/uaol_output_audio_formats.conf create mode 100644 tools/topology/topology2/include/formats/uaol_output_audio_formats_s32.conf create mode 100644 tools/topology/topology2/platform/intel/uaol-generic.conf diff --git a/tools/topology/topology2/README.md b/tools/topology/topology2/README.md index bea7ffcfdcde..759867a47d1c 100644 --- a/tools/topology/topology2/README.md +++ b/tools/topology/topology2/README.md @@ -242,6 +242,8 @@ default ID ranges for the same endpoint types. | Jack Echo Ref | 11 | `SDW_JACK_ECHO_REF_PCM_ID` | | Speaker Echo Ref | 12 | `SDW_SPK_ECHO_REF_PCM_ID` | | Bluetooth | 2 or 20 | `BT_PCM_ID` | +| USB Audio Offload (UAOL) | 21 | `UAOL_PCM_ID` | +| Deepbuffer UAOL | 22 | `DEEP_BUFFER_PCM_ID` | | Deep Buffer (Jack) | 31 | `DEEP_BUFFER_PCM_ID` | | Deep Buffer (Speaker) | 35 | `DEEP_BUFFER_PCM_ID_2` | | DMIC Deep Buffer | 46 | `DMIC0_DEEP_BUFFER_PCM_ID` | @@ -301,6 +303,9 @@ is at N1 (50/51, 60/61, 70/71, 80/81). | HDMI 4 Host / DAI | 80 / 81 | `HDMI4_HOST_PIPELINE_ID` / `HDMI4_DAI_PIPELINE_ID` | | Compress Jack / Speaker | 90 / 92 | `COMPR_PIPELINE_ID` / `COMPR_2_PIPELINE_ID` | | PCH DMIC0 Host / DAI | 100 / 101 | `DMIC0_HOST_PIPELINE_ID` / `DMIC0_DAI_PIPELINE_ID` | +| UAOL Playback Host / DAI | 210 / 211 | `UAOL_PB_HOST_PIPELINE_ID` / `UAOL_PB_DAI_PIPELINE_ID` | +| UAOL Capture Host / DAI | 212 / 213 | `UAOL_CP_HOST_PIPELINE_ID` / `UAOL_CP_DAI_PIPELINE_ID` | +| UAOL Deepbuffer | 214 | `DEEP_BUFFER_PIPELINE_ID` | **Intel HDA Pipeline IDs:** diff --git a/tools/topology/topology2/cavs-uaol.conf b/tools/topology/topology2/cavs-uaol.conf new file mode 100644 index 000000000000..0baa4cb28f74 --- /dev/null +++ b/tools/topology/topology2/cavs-uaol.conf @@ -0,0 +1,86 @@ +# Basic USB Audio Offload Link (UAOL) topology. +# +# This is a function topology, loaded next to the other function topologies of +# the sof_sdw card, so its PCM and pipeline IDs must not collide with theirs. +# +# The UAOL function itself lives in platform/intel/uaol-generic.conf. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Define { + UAOL_PLAYBACK_PCM 'UAOL Playback' + UAOL_CAPTURE_PCM 'UAOL Capture' + # The two directions are separate DAI links so that the format fixup of + # a link is decided by the DAI copier of that direction alone. The names + # are abbreviated because alsatplg drops widget tuples above 36 characters + # and the dai-copier name is 'dai-copier.UAOL..' + UAOL_PB_DAI_NAME 'UAOL0-Play' + UAOL_CP_DAI_NAME 'UAOL0-Cap' + # The BE IDs are the dai link IDs that are matched with the machine + # driver, which creates the playback link first + UAOL_PB_BE_ID 9 + UAOL_CP_BE_ID 10 + # UAOL_DAI_INDEX is the UAOL link the DSP uses, only link 0 is addressable + UAOL_DAI_INDEX 0 + UAOL_PCM_NAME 'UAOL' + UAOL_PCM_ID 21 + UAOL_PB_HOST_PIPELINE_ID 210 + UAOL_PB_DAI_PIPELINE_ID 211 + UAOL_CP_HOST_PIPELINE_ID 212 + UAOL_CP_DAI_PIPELINE_ID 213 + # Both paths pass through whatever the offloaded USB device asks for, so + # the PCM advertises everything a USB device may support. 7 channels is + # left out of the widget formats, it has no channel config and no channel + # map, so it is the one count in the range which cannot be run. + UAOL_CHANNELS_MIN 1 + UAOL_CHANNELS_MAX 8 + # UAOL supports up to 192 kHz + UAOL_RATE_MIN 8000 + UAOL_RATE_MAX 192000 + UAOL_RATES '8000,11025,12000,16000,22050,24000,32000,44100,48000,64000,88200,96000,128000,176400,192000' + + # The deep buffer PCM feeds the same mixer as the normal playback PCM. It + # takes the source and the sink as plain widget names, so it repeats the + # pipeline IDs defined above. + DEEP_BUFFER_PCM_NAME 'Deepbuffer UAOL' + DEEP_BUFFER_PCM_ID 22 + DEEP_BUFFER_PIPELINE_ID 214 + DEEP_BUFFER_PIPELINE_SRC 'mixin.214.1' + DEEP_BUFFER_PIPELINE_SINK 'mixout.211.1' +} + + diff --git a/tools/topology/topology2/include/formats/uaol_input_audio_formats.conf b/tools/topology/topology2/include/formats/uaol_input_audio_formats.conf new file mode 100644 index 000000000000..4a8ca0c0c9f0 --- /dev/null +++ b/tools/topology/topology2/include/formats/uaol_input_audio_formats.conf @@ -0,0 +1,344 @@ + # Every format the offloaded USB endpoint can carry: S16_LE, S24_LE and + # S32_LE, 1 to 8 channels and every standard rate from 8 to 192 kHz. + # + # 7 channels is left out, it has no channel config and no channel map in + # common_definitions.conf. + num_input_audio_formats 315 + CombineArrays.Object.Base.input_audio_format [ + { + in_rate [ + 8000 + 11025 + 12000 + 16000 + 22050 + 24000 + 32000 + 44100 + 48000 + 64000 + 88200 + 96000 + 128000 + 176400 + 192000 + ] + in_bit_depth [ 16 ] + in_valid_bit_depth [ 16 ] + in_channels [ 1 ] + in_ch_cfg [ $CHANNEL_CONFIG_MONO ] + in_ch_map [ $CHANNEL_MAP_MONO ] + } + { + in_rate [ + 8000 + 11025 + 12000 + 16000 + 22050 + 24000 + 32000 + 44100 + 48000 + 64000 + 88200 + 96000 + 128000 + 176400 + 192000 + ] + in_bit_depth [ 32 ] + in_valid_bit_depth [ 24 32 ] + in_channels [ 1 ] + in_ch_cfg [ $CHANNEL_CONFIG_MONO ] + in_ch_map [ $CHANNEL_MAP_MONO ] + } + { + in_rate [ + 8000 + 11025 + 12000 + 16000 + 22050 + 24000 + 32000 + 44100 + 48000 + 64000 + 88200 + 96000 + 128000 + 176400 + 192000 + ] + in_bit_depth [ 16 ] + in_valid_bit_depth [ 16 ] + in_channels [ 2 ] + in_ch_cfg [ $CHANNEL_CONFIG_STEREO ] + in_ch_map [ $CHANNEL_MAP_STEREO ] + } + { + in_rate [ + 8000 + 11025 + 12000 + 16000 + 22050 + 24000 + 32000 + 44100 + 48000 + 64000 + 88200 + 96000 + 128000 + 176400 + 192000 + ] + in_bit_depth [ 32 ] + in_valid_bit_depth [ 24 32 ] + in_channels [ 2 ] + in_ch_cfg [ $CHANNEL_CONFIG_STEREO ] + in_ch_map [ $CHANNEL_MAP_STEREO ] + } + { + in_rate [ + 8000 + 11025 + 12000 + 16000 + 22050 + 24000 + 32000 + 44100 + 48000 + 64000 + 88200 + 96000 + 128000 + 176400 + 192000 + ] + in_bit_depth [ 16 ] + in_valid_bit_depth [ 16 ] + in_channels [ 3 ] + in_ch_cfg [ $CHANNEL_CONFIG_2_POINT_1 ] + in_ch_map [ $CHANNEL_MAP_2_POINT_1 ] + } + { + in_rate [ + 8000 + 11025 + 12000 + 16000 + 22050 + 24000 + 32000 + 44100 + 48000 + 64000 + 88200 + 96000 + 128000 + 176400 + 192000 + ] + in_bit_depth [ 32 ] + in_valid_bit_depth [ 24 32 ] + in_channels [ 3 ] + in_ch_cfg [ $CHANNEL_CONFIG_2_POINT_1 ] + in_ch_map [ $CHANNEL_MAP_2_POINT_1 ] + } + { + in_rate [ + 8000 + 11025 + 12000 + 16000 + 22050 + 24000 + 32000 + 44100 + 48000 + 64000 + 88200 + 96000 + 128000 + 176400 + 192000 + ] + in_bit_depth [ 16 ] + in_valid_bit_depth [ 16 ] + in_channels [ 4 ] + in_ch_cfg [ $CHANNEL_CONFIG_3_POINT_1 ] + in_ch_map [ $CHANNEL_MAP_3_POINT_1 ] + } + { + in_rate [ + 8000 + 11025 + 12000 + 16000 + 22050 + 24000 + 32000 + 44100 + 48000 + 64000 + 88200 + 96000 + 128000 + 176400 + 192000 + ] + in_bit_depth [ 32 ] + in_valid_bit_depth [ 24 32 ] + in_channels [ 4 ] + in_ch_cfg [ $CHANNEL_CONFIG_3_POINT_1 ] + in_ch_map [ $CHANNEL_MAP_3_POINT_1 ] + } + { + in_rate [ + 8000 + 11025 + 12000 + 16000 + 22050 + 24000 + 32000 + 44100 + 48000 + 64000 + 88200 + 96000 + 128000 + 176400 + 192000 + ] + in_bit_depth [ 16 ] + in_valid_bit_depth [ 16 ] + in_channels [ 5 ] + in_ch_cfg [ $CHANNEL_CONFIG_5_POINT_0 ] + in_ch_map [ $CHANNEL_MAP_5_POINT_0 ] + } + { + in_rate [ + 8000 + 11025 + 12000 + 16000 + 22050 + 24000 + 32000 + 44100 + 48000 + 64000 + 88200 + 96000 + 128000 + 176400 + 192000 + ] + in_bit_depth [ 32 ] + in_valid_bit_depth [ 24 32 ] + in_channels [ 5 ] + in_ch_cfg [ $CHANNEL_CONFIG_5_POINT_0 ] + in_ch_map [ $CHANNEL_MAP_5_POINT_0 ] + } + { + in_rate [ + 8000 + 11025 + 12000 + 16000 + 22050 + 24000 + 32000 + 44100 + 48000 + 64000 + 88200 + 96000 + 128000 + 176400 + 192000 + ] + in_bit_depth [ 16 ] + in_valid_bit_depth [ 16 ] + in_channels [ 6 ] + in_ch_cfg [ $CHANNEL_CONFIG_5_POINT_1 ] + in_ch_map [ $CHANNEL_MAP_5_POINT_1 ] + } + { + in_rate [ + 8000 + 11025 + 12000 + 16000 + 22050 + 24000 + 32000 + 44100 + 48000 + 64000 + 88200 + 96000 + 128000 + 176400 + 192000 + ] + in_bit_depth [ 32 ] + in_valid_bit_depth [ 24 32 ] + in_channels [ 6 ] + in_ch_cfg [ $CHANNEL_CONFIG_5_POINT_1 ] + in_ch_map [ $CHANNEL_MAP_5_POINT_1 ] + } + { + in_rate [ + 8000 + 11025 + 12000 + 16000 + 22050 + 24000 + 32000 + 44100 + 48000 + 64000 + 88200 + 96000 + 128000 + 176400 + 192000 + ] + in_bit_depth [ 16 ] + in_valid_bit_depth [ 16 ] + in_channels [ 8 ] + in_ch_cfg [ $CHANNEL_CONFIG_7_POINT_1 ] + in_ch_map [ $CHANNEL_MAP_7_POINT_1 ] + } + { + in_rate [ + 8000 + 11025 + 12000 + 16000 + 22050 + 24000 + 32000 + 44100 + 48000 + 64000 + 88200 + 96000 + 128000 + 176400 + 192000 + ] + in_bit_depth [ 32 ] + in_valid_bit_depth [ 24 32 ] + in_channels [ 8 ] + in_ch_cfg [ $CHANNEL_CONFIG_7_POINT_1 ] + in_ch_map [ $CHANNEL_MAP_7_POINT_1 ] + } + ] diff --git a/tools/topology/topology2/include/formats/uaol_input_audio_formats_s32.conf b/tools/topology/topology2/include/formats/uaol_input_audio_formats_s32.conf new file mode 100644 index 000000000000..a98428ba1533 --- /dev/null +++ b/tools/topology/topology2/include/formats/uaol_input_audio_formats_s32.conf @@ -0,0 +1,176 @@ + # The formats of a module which only processes 32 bit samples, for every + # channel count and rate the offloaded USB endpoint can carry. + # + # 7 channels is left out, it has no channel config and no channel map in + # common_definitions.conf. + num_input_audio_formats 105 + CombineArrays.Object.Base.input_audio_format [ + { + in_rate [ + 8000 + 11025 + 12000 + 16000 + 22050 + 24000 + 32000 + 44100 + 48000 + 64000 + 88200 + 96000 + 128000 + 176400 + 192000 + ] + in_bit_depth [ 32 ] + in_valid_bit_depth [ 32 ] + in_channels [ 1 ] + in_ch_cfg [ $CHANNEL_CONFIG_MONO ] + in_ch_map [ $CHANNEL_MAP_MONO ] + } + { + in_rate [ + 8000 + 11025 + 12000 + 16000 + 22050 + 24000 + 32000 + 44100 + 48000 + 64000 + 88200 + 96000 + 128000 + 176400 + 192000 + ] + in_bit_depth [ 32 ] + in_valid_bit_depth [ 32 ] + in_channels [ 2 ] + in_ch_cfg [ $CHANNEL_CONFIG_STEREO ] + in_ch_map [ $CHANNEL_MAP_STEREO ] + } + { + in_rate [ + 8000 + 11025 + 12000 + 16000 + 22050 + 24000 + 32000 + 44100 + 48000 + 64000 + 88200 + 96000 + 128000 + 176400 + 192000 + ] + in_bit_depth [ 32 ] + in_valid_bit_depth [ 32 ] + in_channels [ 3 ] + in_ch_cfg [ $CHANNEL_CONFIG_2_POINT_1 ] + in_ch_map [ $CHANNEL_MAP_2_POINT_1 ] + } + { + in_rate [ + 8000 + 11025 + 12000 + 16000 + 22050 + 24000 + 32000 + 44100 + 48000 + 64000 + 88200 + 96000 + 128000 + 176400 + 192000 + ] + in_bit_depth [ 32 ] + in_valid_bit_depth [ 32 ] + in_channels [ 4 ] + in_ch_cfg [ $CHANNEL_CONFIG_3_POINT_1 ] + in_ch_map [ $CHANNEL_MAP_3_POINT_1 ] + } + { + in_rate [ + 8000 + 11025 + 12000 + 16000 + 22050 + 24000 + 32000 + 44100 + 48000 + 64000 + 88200 + 96000 + 128000 + 176400 + 192000 + ] + in_bit_depth [ 32 ] + in_valid_bit_depth [ 32 ] + in_channels [ 5 ] + in_ch_cfg [ $CHANNEL_CONFIG_5_POINT_0 ] + in_ch_map [ $CHANNEL_MAP_5_POINT_0 ] + } + { + in_rate [ + 8000 + 11025 + 12000 + 16000 + 22050 + 24000 + 32000 + 44100 + 48000 + 64000 + 88200 + 96000 + 128000 + 176400 + 192000 + ] + in_bit_depth [ 32 ] + in_valid_bit_depth [ 32 ] + in_channels [ 6 ] + in_ch_cfg [ $CHANNEL_CONFIG_5_POINT_1 ] + in_ch_map [ $CHANNEL_MAP_5_POINT_1 ] + } + { + in_rate [ + 8000 + 11025 + 12000 + 16000 + 22050 + 24000 + 32000 + 44100 + 48000 + 64000 + 88200 + 96000 + 128000 + 176400 + 192000 + ] + in_bit_depth [ 32 ] + in_valid_bit_depth [ 32 ] + in_channels [ 8 ] + in_ch_cfg [ $CHANNEL_CONFIG_7_POINT_1 ] + in_ch_map [ $CHANNEL_MAP_7_POINT_1 ] + } + ] diff --git a/tools/topology/topology2/include/formats/uaol_output_audio_formats.conf b/tools/topology/topology2/include/formats/uaol_output_audio_formats.conf new file mode 100644 index 000000000000..0ff39effcd62 --- /dev/null +++ b/tools/topology/topology2/include/formats/uaol_output_audio_formats.conf @@ -0,0 +1,344 @@ + # Every format the offloaded USB endpoint can carry: S16_LE, S24_LE and + # S32_LE, 1 to 8 channels and every standard rate from 8 to 192 kHz. + # + # 7 channels is left out, it has no channel config and no channel map in + # common_definitions.conf. + num_output_audio_formats 315 + CombineArrays.Object.Base.output_audio_format [ + { + out_rate [ + 8000 + 11025 + 12000 + 16000 + 22050 + 24000 + 32000 + 44100 + 48000 + 64000 + 88200 + 96000 + 128000 + 176400 + 192000 + ] + out_bit_depth [ 16 ] + out_valid_bit_depth [ 16 ] + out_channels [ 1 ] + out_ch_cfg [ $CHANNEL_CONFIG_MONO ] + out_ch_map [ $CHANNEL_MAP_MONO ] + } + { + out_rate [ + 8000 + 11025 + 12000 + 16000 + 22050 + 24000 + 32000 + 44100 + 48000 + 64000 + 88200 + 96000 + 128000 + 176400 + 192000 + ] + out_bit_depth [ 32 ] + out_valid_bit_depth [ 24 32 ] + out_channels [ 1 ] + out_ch_cfg [ $CHANNEL_CONFIG_MONO ] + out_ch_map [ $CHANNEL_MAP_MONO ] + } + { + out_rate [ + 8000 + 11025 + 12000 + 16000 + 22050 + 24000 + 32000 + 44100 + 48000 + 64000 + 88200 + 96000 + 128000 + 176400 + 192000 + ] + out_bit_depth [ 16 ] + out_valid_bit_depth [ 16 ] + out_channels [ 2 ] + out_ch_cfg [ $CHANNEL_CONFIG_STEREO ] + out_ch_map [ $CHANNEL_MAP_STEREO ] + } + { + out_rate [ + 8000 + 11025 + 12000 + 16000 + 22050 + 24000 + 32000 + 44100 + 48000 + 64000 + 88200 + 96000 + 128000 + 176400 + 192000 + ] + out_bit_depth [ 32 ] + out_valid_bit_depth [ 24 32 ] + out_channels [ 2 ] + out_ch_cfg [ $CHANNEL_CONFIG_STEREO ] + out_ch_map [ $CHANNEL_MAP_STEREO ] + } + { + out_rate [ + 8000 + 11025 + 12000 + 16000 + 22050 + 24000 + 32000 + 44100 + 48000 + 64000 + 88200 + 96000 + 128000 + 176400 + 192000 + ] + out_bit_depth [ 16 ] + out_valid_bit_depth [ 16 ] + out_channels [ 3 ] + out_ch_cfg [ $CHANNEL_CONFIG_2_POINT_1 ] + out_ch_map [ $CHANNEL_MAP_2_POINT_1 ] + } + { + out_rate [ + 8000 + 11025 + 12000 + 16000 + 22050 + 24000 + 32000 + 44100 + 48000 + 64000 + 88200 + 96000 + 128000 + 176400 + 192000 + ] + out_bit_depth [ 32 ] + out_valid_bit_depth [ 24 32 ] + out_channels [ 3 ] + out_ch_cfg [ $CHANNEL_CONFIG_2_POINT_1 ] + out_ch_map [ $CHANNEL_MAP_2_POINT_1 ] + } + { + out_rate [ + 8000 + 11025 + 12000 + 16000 + 22050 + 24000 + 32000 + 44100 + 48000 + 64000 + 88200 + 96000 + 128000 + 176400 + 192000 + ] + out_bit_depth [ 16 ] + out_valid_bit_depth [ 16 ] + out_channels [ 4 ] + out_ch_cfg [ $CHANNEL_CONFIG_3_POINT_1 ] + out_ch_map [ $CHANNEL_MAP_3_POINT_1 ] + } + { + out_rate [ + 8000 + 11025 + 12000 + 16000 + 22050 + 24000 + 32000 + 44100 + 48000 + 64000 + 88200 + 96000 + 128000 + 176400 + 192000 + ] + out_bit_depth [ 32 ] + out_valid_bit_depth [ 24 32 ] + out_channels [ 4 ] + out_ch_cfg [ $CHANNEL_CONFIG_3_POINT_1 ] + out_ch_map [ $CHANNEL_MAP_3_POINT_1 ] + } + { + out_rate [ + 8000 + 11025 + 12000 + 16000 + 22050 + 24000 + 32000 + 44100 + 48000 + 64000 + 88200 + 96000 + 128000 + 176400 + 192000 + ] + out_bit_depth [ 16 ] + out_valid_bit_depth [ 16 ] + out_channels [ 5 ] + out_ch_cfg [ $CHANNEL_CONFIG_5_POINT_0 ] + out_ch_map [ $CHANNEL_MAP_5_POINT_0 ] + } + { + out_rate [ + 8000 + 11025 + 12000 + 16000 + 22050 + 24000 + 32000 + 44100 + 48000 + 64000 + 88200 + 96000 + 128000 + 176400 + 192000 + ] + out_bit_depth [ 32 ] + out_valid_bit_depth [ 24 32 ] + out_channels [ 5 ] + out_ch_cfg [ $CHANNEL_CONFIG_5_POINT_0 ] + out_ch_map [ $CHANNEL_MAP_5_POINT_0 ] + } + { + out_rate [ + 8000 + 11025 + 12000 + 16000 + 22050 + 24000 + 32000 + 44100 + 48000 + 64000 + 88200 + 96000 + 128000 + 176400 + 192000 + ] + out_bit_depth [ 16 ] + out_valid_bit_depth [ 16 ] + out_channels [ 6 ] + out_ch_cfg [ $CHANNEL_CONFIG_5_POINT_1 ] + out_ch_map [ $CHANNEL_MAP_5_POINT_1 ] + } + { + out_rate [ + 8000 + 11025 + 12000 + 16000 + 22050 + 24000 + 32000 + 44100 + 48000 + 64000 + 88200 + 96000 + 128000 + 176400 + 192000 + ] + out_bit_depth [ 32 ] + out_valid_bit_depth [ 24 32 ] + out_channels [ 6 ] + out_ch_cfg [ $CHANNEL_CONFIG_5_POINT_1 ] + out_ch_map [ $CHANNEL_MAP_5_POINT_1 ] + } + { + out_rate [ + 8000 + 11025 + 12000 + 16000 + 22050 + 24000 + 32000 + 44100 + 48000 + 64000 + 88200 + 96000 + 128000 + 176400 + 192000 + ] + out_bit_depth [ 16 ] + out_valid_bit_depth [ 16 ] + out_channels [ 8 ] + out_ch_cfg [ $CHANNEL_CONFIG_7_POINT_1 ] + out_ch_map [ $CHANNEL_MAP_7_POINT_1 ] + } + { + out_rate [ + 8000 + 11025 + 12000 + 16000 + 22050 + 24000 + 32000 + 44100 + 48000 + 64000 + 88200 + 96000 + 128000 + 176400 + 192000 + ] + out_bit_depth [ 32 ] + out_valid_bit_depth [ 24 32 ] + out_channels [ 8 ] + out_ch_cfg [ $CHANNEL_CONFIG_7_POINT_1 ] + out_ch_map [ $CHANNEL_MAP_7_POINT_1 ] + } + ] diff --git a/tools/topology/topology2/include/formats/uaol_output_audio_formats_s32.conf b/tools/topology/topology2/include/formats/uaol_output_audio_formats_s32.conf new file mode 100644 index 000000000000..8dea01de8020 --- /dev/null +++ b/tools/topology/topology2/include/formats/uaol_output_audio_formats_s32.conf @@ -0,0 +1,176 @@ + # The formats of a module which only processes 32 bit samples, for every + # channel count and rate the offloaded USB endpoint can carry. + # + # 7 channels is left out, it has no channel config and no channel map in + # common_definitions.conf. + num_output_audio_formats 105 + CombineArrays.Object.Base.output_audio_format [ + { + out_rate [ + 8000 + 11025 + 12000 + 16000 + 22050 + 24000 + 32000 + 44100 + 48000 + 64000 + 88200 + 96000 + 128000 + 176400 + 192000 + ] + out_bit_depth [ 32 ] + out_valid_bit_depth [ 32 ] + out_channels [ 1 ] + out_ch_cfg [ $CHANNEL_CONFIG_MONO ] + out_ch_map [ $CHANNEL_MAP_MONO ] + } + { + out_rate [ + 8000 + 11025 + 12000 + 16000 + 22050 + 24000 + 32000 + 44100 + 48000 + 64000 + 88200 + 96000 + 128000 + 176400 + 192000 + ] + out_bit_depth [ 32 ] + out_valid_bit_depth [ 32 ] + out_channels [ 2 ] + out_ch_cfg [ $CHANNEL_CONFIG_STEREO ] + out_ch_map [ $CHANNEL_MAP_STEREO ] + } + { + out_rate [ + 8000 + 11025 + 12000 + 16000 + 22050 + 24000 + 32000 + 44100 + 48000 + 64000 + 88200 + 96000 + 128000 + 176400 + 192000 + ] + out_bit_depth [ 32 ] + out_valid_bit_depth [ 32 ] + out_channels [ 3 ] + out_ch_cfg [ $CHANNEL_CONFIG_2_POINT_1 ] + out_ch_map [ $CHANNEL_MAP_2_POINT_1 ] + } + { + out_rate [ + 8000 + 11025 + 12000 + 16000 + 22050 + 24000 + 32000 + 44100 + 48000 + 64000 + 88200 + 96000 + 128000 + 176400 + 192000 + ] + out_bit_depth [ 32 ] + out_valid_bit_depth [ 32 ] + out_channels [ 4 ] + out_ch_cfg [ $CHANNEL_CONFIG_3_POINT_1 ] + out_ch_map [ $CHANNEL_MAP_3_POINT_1 ] + } + { + out_rate [ + 8000 + 11025 + 12000 + 16000 + 22050 + 24000 + 32000 + 44100 + 48000 + 64000 + 88200 + 96000 + 128000 + 176400 + 192000 + ] + out_bit_depth [ 32 ] + out_valid_bit_depth [ 32 ] + out_channels [ 5 ] + out_ch_cfg [ $CHANNEL_CONFIG_5_POINT_0 ] + out_ch_map [ $CHANNEL_MAP_5_POINT_0 ] + } + { + out_rate [ + 8000 + 11025 + 12000 + 16000 + 22050 + 24000 + 32000 + 44100 + 48000 + 64000 + 88200 + 96000 + 128000 + 176400 + 192000 + ] + out_bit_depth [ 32 ] + out_valid_bit_depth [ 32 ] + out_channels [ 6 ] + out_ch_cfg [ $CHANNEL_CONFIG_5_POINT_1 ] + out_ch_map [ $CHANNEL_MAP_5_POINT_1 ] + } + { + out_rate [ + 8000 + 11025 + 12000 + 16000 + 22050 + 24000 + 32000 + 44100 + 48000 + 64000 + 88200 + 96000 + 128000 + 176400 + 192000 + ] + out_bit_depth [ 32 ] + out_valid_bit_depth [ 32 ] + out_channels [ 8 ] + out_ch_cfg [ $CHANNEL_CONFIG_7_POINT_1 ] + out_ch_map [ $CHANNEL_MAP_7_POINT_1 ] + } + ] diff --git a/tools/topology/topology2/platform/intel/uaol-generic.conf b/tools/topology/topology2/platform/intel/uaol-generic.conf new file mode 100644 index 000000000000..b1e56ad90b21 --- /dev/null +++ b/tools/topology/topology2/platform/intel/uaol-generic.conf @@ -0,0 +1,204 @@ +# USB Audio Offload Link (UAOL) function. +# +# The offloaded USB endpoint is driven by the UAOL gateway in the firmware: +# +# PCM ---------------> gain ---> mixin ---+ +# | +# Deepbuffer PCM ----> gain ---> mixin ---+--> mixout --> gain --> UAOL0-Play +# +# PCM <------------ module-copier <--- eqiir <---------------- UAOL0-Cap +# +# The capture path carries no mixer, as the number of channels follows the USB +# device and a mixer only handles a fixed channel count. +# +# What the endpoint can be run at is decided by the USB device, which is only +# known once one is plugged in, so every widget of both paths carries the whole +# set of formats a USB device may ask for: S16_LE, S24_LE and S32_LE, 1 to 8 +# channels and the standard rates from 8 to 192 kHz, which is as far as UAOL +# goes. The kernel narrows the PCM down to what the connected device actually +# supports. +# +# The deep buffer PCM is left at 48 kHz stereo, as it comes from the shared +# platform/intel/deep-buffer.conf. It can only join the mixer while the normal +# playback PCM runs at that format, or is not running at all. + +# Deep buffer playback, included when the DMA buffer is 1 - 1000 ms +IncludeByKey.DEEPBUFFER_FW_DMA_MS { + "([1-9]|[1-9][0-9]|[1-9][0-9][0-9]|1000)" "platform/intel/deep-buffer.conf" +} + +Object.Dai.UAOL [ + { + name $UAOL_PB_DAI_NAME + dai_index $UAOL_DAI_INDEX + id $UAOL_PB_BE_ID + default_hw_conf_id 0 + Object.Base.hw_config.1 { + name "UAOL0-Play" + } + direction playback + } + { + name $UAOL_CP_DAI_NAME + dai_index $UAOL_DAI_INDEX + id $UAOL_CP_BE_ID + default_hw_conf_id 0 + Object.Base.hw_config.1 { + name "UAOL0-Cap" + } + direction capture + } +] + +Object.Pipeline { + host-copier-gain-mixin-playback [ + { + index $UAOL_PB_HOST_PIPELINE_ID + + Object.Widget.host-copier.1 { + stream_name $UAOL_PLAYBACK_PCM + pcm_id $UAOL_PCM_ID + + + } + Object.Widget.gain.1 { + Object.Control.mixer.1 { + name 'Pre Mixer $UAOL_PCM_NAME Playback Volume' + } + + + } + Object.Widget.mixin.1 { + + + } + } + ] + + mixout-gain-dai-copier-playback [ + { + index $UAOL_PB_DAI_PIPELINE_ID + + Object.Widget.mixout.1 { + + + } + Object.Widget.dai-copier.1 { + node_type $ALH_UAOL_STREAM_LINK_OUTPUT_CLASS + stream_name $UAOL_PB_DAI_NAME + dai_type "UAOL" + copier_type "UAOL" + + + } + Object.Widget.gain.1 { + Object.Control.mixer.1 { + name 'Post Mixer $UAOL_PCM_NAME Playback Volume' + } + + + } + } + ] + + host-gateway-capture [ + { + index $UAOL_CP_HOST_PIPELINE_ID + + Object.Widget.host-copier.1 { + stream_name $UAOL_CAPTURE_PCM + pcm_id $UAOL_PCM_ID + + + } + } + ] + + dai-copier-eqiir-module-copier-capture [ + { + index $UAOL_CP_DAI_PIPELINE_ID + + Object.Widget.dai-copier.1 { + node_type $ALH_UAOL_STREAM_LINK_INPUT_CLASS + stream_name $UAOL_CP_DAI_NAME + dai_type "UAOL" + type dai_out + copier_type "UAOL" + num_output_pins 1 + + + } + + # The coefficients are designed for 48 kHz, so the corner + # frequency scales with the rate the device is run at + Object.Widget.eqiir.1 { + Object.Control.bytes.1 { + name '$UAOL_PCM_NAME Capture IIR Eq' + + } + + + } + + Object.Widget.module-copier.2 { + + + } + } + ] +} + +Object.PCM.pcm [ + { + name $UAOL_PCM_NAME + id $UAOL_PCM_ID + direction "duplex" + Object.Base.fe_dai.1 { + name $UAOL_PCM_NAME + } + Object.PCM.pcm_caps.1 { + direction "playback" + name $UAOL_PLAYBACK_PCM + formats 'S16_LE,S24_LE,S32_LE' + channels_min $UAOL_CHANNELS_MIN + channels_max $UAOL_CHANNELS_MAX + rates $UAOL_RATES + rate_min $UAOL_RATE_MIN + rate_max $UAOL_RATE_MAX + } + Object.PCM.pcm_caps.2 { + direction "capture" + name $UAOL_CAPTURE_PCM + formats 'S16_LE,S24_LE,S32_LE' + channels_min $UAOL_CHANNELS_MIN + channels_max $UAOL_CHANNELS_MAX + rates $UAOL_RATES + rate_min $UAOL_RATE_MIN + rate_max $UAOL_RATE_MAX + } + } +] + +# top-level pipeline connections +Object.Base.route [ + { + source "host-copier.$UAOL_PCM_ID.playback" + sink "gain.$UAOL_PB_HOST_PIPELINE_ID.1" + } + { + source "mixin.$UAOL_PB_HOST_PIPELINE_ID.1" + sink "mixout.$UAOL_PB_DAI_PIPELINE_ID.1" + } + { + source "gain.$UAOL_PB_DAI_PIPELINE_ID.1" + sink "dai-copier.UAOL.$UAOL_PB_DAI_NAME.playback" + } + { + source "dai-copier.UAOL.$UAOL_CP_DAI_NAME.capture" + sink "eqiir.$UAOL_CP_DAI_PIPELINE_ID.1" + } + { + source "module-copier.$UAOL_CP_DAI_PIPELINE_ID.2" + sink "host-copier.$UAOL_PCM_ID.capture" + } +] diff --git a/tools/topology/topology2/production/tplg-targets-sdca-generic.cmake b/tools/topology/topology2/production/tplg-targets-sdca-generic.cmake index c7d5b5d8af1b..7979d2d07255 100644 --- a/tools/topology/topology2/production/tplg-targets-sdca-generic.cmake +++ b/tools/topology/topology2/production/tplg-targets-sdca-generic.cmake @@ -37,6 +37,19 @@ SDW_DMIC_STREAM=Capture-SmartMic" "cavs-sdw\;sof-hdmi-pcm5-id6\;SDW_JACK=false,HDMI1_ID=6,HDMI2_ID=7,HDMI3_ID=8" "cavs-sdw\;sof-hdmi-pcm5-id7\;SDW_JACK=false,HDMI1_ID=7,HDMI2_ID=8,HDMI3_ID=9" +# USB Audio Offload Link function topology. The UAOL backend is the last one +# sof_sdw creates, so its dai link ID depends on the composition of the board: +# it follows the SoundWire links, the PCH DMIC pair, the three HDMI links and +# the BT link. Each direction is a separate link, so two consecutive IDs are +# taken. The range below covers a jack and amplifier board without DMIC and BT +# (6) up to a jack, amplifier with feedback, PCH DMIC and BT board (10). +# Add a variant here for every further ID that is needed. +"cavs-uaol\;sof-uaol-id6\;UAOL_PB_BE_ID=6,UAOL_CP_BE_ID=7" +"cavs-uaol\;sof-uaol-id7\;UAOL_PB_BE_ID=7,UAOL_CP_BE_ID=8" +"cavs-uaol\;sof-uaol-id8\;UAOL_PB_BE_ID=8,UAOL_CP_BE_ID=9" +"cavs-uaol\;sof-uaol-id9\;UAOL_PB_BE_ID=9,UAOL_CP_BE_ID=10" +"cavs-uaol\;sof-uaol-id10\;UAOL_PB_BE_ID=10,UAOL_CP_BE_ID=11" + # Feature topologies which should work with the function topologies above "cavs-sdw\;sof-sdca-amp-ref\;SDW_JACK=false,NUM_HDMIS=0,JACK_RATE=48000,\ SDW_AMP_FEEDBACK=false,SDW_SPK_ECHO_REF=true,SDW_SPK_ECHO_REF_PCM_ID=12"