From 90b26d0cc1517f3d2ed024c75928ed7570d31a44 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 13 Nov 2026 15:31:08 +0200 Subject: [PATCH 01/10] app: wov-d0i3-fake-wake.conf: Enable UAOL drop the n for the UAOL support. Signed-off-by: Peter Ujfalusi --- app/wov-d0i3-fake-wake.conf | 4 ---- 1 file changed, 4 deletions(-) diff --git a/app/wov-d0i3-fake-wake.conf b/app/wov-d0i3-fake-wake.conf index 8c506e9706a3..1f247d88f6a9 100644 --- a/app/wov-d0i3-fake-wake.conf +++ b/app/wov-d0i3-fake-wake.conf @@ -7,7 +7,3 @@ CONFIG_COMP_MWW_FAKE_WAKE_MS=5000 # LLEXT relocatable ELF format for loadable modules on Intel ADSP ACE 3.0 CONFIG_LLEXT_TYPE_ELF_RELOCATABLE=y -# Disable USB Audio Offload (UAOL) -CONFIG_UAOL=n -CONFIG_DAI_INTEL_UAOL=n - From 6ea30d65c52a73b5aa30fbe2050a08f9407b642e Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 13 Nov 2026 15:46:53 +0200 Subject: [PATCH 02/10] Revert "config: disable USB Audio Offload (UAOL) by default" This reverts commit d3a9b8afdfe6e36ed0465693a5b60bc43838eee4. Signed-off-by: Peter Ujfalusi --- app/boards/intel_adsp/Kconfig.defconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/boards/intel_adsp/Kconfig.defconfig b/app/boards/intel_adsp/Kconfig.defconfig index 4edb5b81e22b..0fd7126d58d1 100644 --- a/app/boards/intel_adsp/Kconfig.defconfig +++ b/app/boards/intel_adsp/Kconfig.defconfig @@ -121,7 +121,7 @@ config MM_DRV default y config UAOL - default n + default y if ACE # # Zephyr / power settings From 79d10ff1d0c19bd69b404462fd5f5c03d4da4922 Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Mon, 26 Oct 2026 20:00:46 +0000 Subject: [PATCH 03/10] audio: intel_uaol: include the logging header intel_uaol.c uses LOG_MODULE_REGISTER() but got zephyr/logging/log.h only indirectly. No functional change. Co-Authored-By: Claude Opus 5.5 Signed-off-by: Liam Girdwood Signed-off-by: Peter Ujfalusi --- src/audio/intel_uaol.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/audio/intel_uaol.c b/src/audio/intel_uaol.c index b6b50981c2c3..155787a33f9c 100644 --- a/src/audio/intel_uaol.c +++ b/src/audio/intel_uaol.c @@ -4,9 +4,9 @@ */ #include +#include #include #include -#include #include LOG_MODULE_REGISTER(uaol, CONFIG_SOF_LOG_LEVEL); From 08907f6ddb5e1dcef6188709b7c4a57b68e24531 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 26 Aug 2026 11:37:40 +0300 Subject: [PATCH 04/10] topology2: uaol-generic: Make the deep buffer optional platform/intel/deep-buffer.conf can only be included once per topology. It names the pipeline and the PCM it creates after the DEEP_BUFFER_* variables, and those are global to the topology, so a second include which redefines them relocates the first deep buffer on top of the second one, which then fails to build. A topology which brings the UAOL in next to a function that already has a deep buffer of its own therefore has to leave the UAOL deep buffer out. Add the UAOL_DEEP_BUFFER key for it, and keep it true in cavs-uaol, where the UAOL is the only function of the topology. No functional change, cavs-uaol.tplg is unchanged. Signed-off-by: Peter Ujfalusi --- tools/topology/topology2/cavs-uaol.conf | 1 + .../topology2/platform/intel/uaol-generic.conf | 17 ++++++++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/tools/topology/topology2/cavs-uaol.conf b/tools/topology/topology2/cavs-uaol.conf index 0baa4cb28f74..5546d5add486 100644 --- a/tools/topology/topology2/cavs-uaol.conf +++ b/tools/topology/topology2/cavs-uaol.conf @@ -76,6 +76,7 @@ Define { # 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. + UAOL_DEEP_BUFFER 'true' DEEP_BUFFER_PCM_NAME 'Deepbuffer UAOL' DEEP_BUFFER_PCM_ID 22 DEEP_BUFFER_PIPELINE_ID 214 diff --git a/tools/topology/topology2/platform/intel/uaol-generic.conf b/tools/topology/topology2/platform/intel/uaol-generic.conf index 6735827e52da..49b28ec99808 100644 --- a/tools/topology/topology2/platform/intel/uaol-generic.conf +++ b/tools/topology/topology2/platform/intel/uaol-generic.conf @@ -22,9 +22,20 @@ # 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" +# Deep buffer playback, included when the DMA buffer is 1 - 1000 ms. +# +# It is optional because platform/intel/deep-buffer.conf can only be pulled in +# once per topology: it takes the pipeline and the PCM it creates from the +# DEEP_BUFFER_* variables, and those are global, so a second include which +# redefines them moves the first deep buffer on top of the second one. A +# topology which already has a deep buffer of its own asks for +# UAOL_DEEP_BUFFER false. +IncludeByKey.UAOL_DEEP_BUFFER { + "true" { + 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 [ From 2b808195ea837f6183bf80f4d4eddd24e8400494 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 2 Sep 2026 14:42:05 +0300 Subject: [PATCH 05/10] topology2: uaol-generic: Advertise 384 kHz The UAOL PCM and the widget format tables stopped at 192 kHz, which capped an offloaded USB device below the rates it can run at. Nothing on the link itself limits it. Add 384000 to the PCM rate list in cavs-uaol.conf and to every widget format table. The tables are CombineArrays expansions, so going from 15 to 16 rates takes the S16/S24/S32 tables from 315 to 336 combinations and the 32 bit only ones from 105 to 112. Reaching the new rate additionally depends on the host side, where the UAOL backend narrows the frontend by the link FIFO budget. Signed-off-by: Peter Ujfalusi --- tools/topology/topology2/cavs-uaol.conf | 6 ++--- .../formats/uaol_input_audio_formats.conf | 18 +++++++++++-- .../formats/uaol_input_audio_formats_msb.conf | 25 +++++++++++++++++-- .../formats/uaol_input_audio_formats_s32.conf | 9 ++++++- .../formats/uaol_output_audio_formats.conf | 18 +++++++++++-- .../uaol_output_audio_formats_msb.conf | 25 +++++++++++++++++-- .../uaol_output_audio_formats_s32.conf | 9 ++++++- .../platform/intel/uaol-generic.conf | 2 +- 8 files changed, 98 insertions(+), 14 deletions(-) diff --git a/tools/topology/topology2/cavs-uaol.conf b/tools/topology/topology2/cavs-uaol.conf index 5546d5add486..f6a9dbe17f67 100644 --- a/tools/topology/topology2/cavs-uaol.conf +++ b/tools/topology/topology2/cavs-uaol.conf @@ -68,10 +68,10 @@ Define { # 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 supports up to 384 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' + UAOL_RATE_MAX 384000 + UAOL_RATES '8000,11025,12000,16000,22050,24000,32000,44100,48000,64000,88200,96000,128000,176400,192000,384000' # 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 diff --git a/tools/topology/topology2/include/formats/uaol_input_audio_formats.conf b/tools/topology/topology2/include/formats/uaol_input_audio_formats.conf index 4a8ca0c0c9f0..9312e9257845 100644 --- a/tools/topology/topology2/include/formats/uaol_input_audio_formats.conf +++ b/tools/topology/topology2/include/formats/uaol_input_audio_formats.conf @@ -1,9 +1,9 @@ # 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. + # S32_LE, 1 to 8 channels and every standard rate from 8 to 384 kHz. # # 7 channels is left out, it has no channel config and no channel map in # common_definitions.conf. - num_input_audio_formats 315 + num_input_audio_formats 336 CombineArrays.Object.Base.input_audio_format [ { in_rate [ @@ -22,6 +22,7 @@ 128000 176400 192000 + 384000 ] in_bit_depth [ 16 ] in_valid_bit_depth [ 16 ] @@ -46,6 +47,7 @@ 128000 176400 192000 + 384000 ] in_bit_depth [ 32 ] in_valid_bit_depth [ 24 32 ] @@ -70,6 +72,7 @@ 128000 176400 192000 + 384000 ] in_bit_depth [ 16 ] in_valid_bit_depth [ 16 ] @@ -94,6 +97,7 @@ 128000 176400 192000 + 384000 ] in_bit_depth [ 32 ] in_valid_bit_depth [ 24 32 ] @@ -118,6 +122,7 @@ 128000 176400 192000 + 384000 ] in_bit_depth [ 16 ] in_valid_bit_depth [ 16 ] @@ -142,6 +147,7 @@ 128000 176400 192000 + 384000 ] in_bit_depth [ 32 ] in_valid_bit_depth [ 24 32 ] @@ -166,6 +172,7 @@ 128000 176400 192000 + 384000 ] in_bit_depth [ 16 ] in_valid_bit_depth [ 16 ] @@ -190,6 +197,7 @@ 128000 176400 192000 + 384000 ] in_bit_depth [ 32 ] in_valid_bit_depth [ 24 32 ] @@ -214,6 +222,7 @@ 128000 176400 192000 + 384000 ] in_bit_depth [ 16 ] in_valid_bit_depth [ 16 ] @@ -238,6 +247,7 @@ 128000 176400 192000 + 384000 ] in_bit_depth [ 32 ] in_valid_bit_depth [ 24 32 ] @@ -262,6 +272,7 @@ 128000 176400 192000 + 384000 ] in_bit_depth [ 16 ] in_valid_bit_depth [ 16 ] @@ -286,6 +297,7 @@ 128000 176400 192000 + 384000 ] in_bit_depth [ 32 ] in_valid_bit_depth [ 24 32 ] @@ -310,6 +322,7 @@ 128000 176400 192000 + 384000 ] in_bit_depth [ 16 ] in_valid_bit_depth [ 16 ] @@ -334,6 +347,7 @@ 128000 176400 192000 + 384000 ] in_bit_depth [ 32 ] in_valid_bit_depth [ 24 32 ] diff --git a/tools/topology/topology2/include/formats/uaol_input_audio_formats_msb.conf b/tools/topology/topology2/include/formats/uaol_input_audio_formats_msb.conf index 2fc36190e00f..6e920a657d7e 100644 --- a/tools/topology/topology2/include/formats/uaol_input_audio_formats_msb.conf +++ b/tools/topology/topology2/include/formats/uaol_input_audio_formats_msb.conf @@ -1,5 +1,5 @@ # 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. + # S32_LE, 1 to 8 channels and every standard rate from 8 to 384 kHz. # # 7 channels is left out, it has no channel config and no channel map in # common_definitions.conf. @@ -13,7 +13,7 @@ # 32 valid bits stay LSB: the alignment is a no-op when every bit # is valid, and the driver only honours the tag at 8 and 32 bits, # so an MSB tag there would never match an S32_LE PCM. - num_input_audio_formats 315 + num_input_audio_formats 336 CombineArrays.Object.Base.input_audio_format [ { in_rate [ @@ -32,6 +32,7 @@ 128000 176400 192000 + 384000 ] in_bit_depth [ 16 ] in_valid_bit_depth [ 16 ] @@ -57,6 +58,7 @@ 128000 176400 192000 + 384000 ] in_bit_depth [ 32 ] in_valid_bit_depth [ 24 ] @@ -82,6 +84,7 @@ 128000 176400 192000 + 384000 ] in_bit_depth [ 32 ] in_valid_bit_depth [ 32 ] @@ -107,6 +110,7 @@ 128000 176400 192000 + 384000 ] in_bit_depth [ 16 ] in_valid_bit_depth [ 16 ] @@ -132,6 +136,7 @@ 128000 176400 192000 + 384000 ] in_bit_depth [ 32 ] in_valid_bit_depth [ 24 ] @@ -157,6 +162,7 @@ 128000 176400 192000 + 384000 ] in_bit_depth [ 32 ] in_valid_bit_depth [ 32 ] @@ -182,6 +188,7 @@ 128000 176400 192000 + 384000 ] in_bit_depth [ 16 ] in_valid_bit_depth [ 16 ] @@ -207,6 +214,7 @@ 128000 176400 192000 + 384000 ] in_bit_depth [ 32 ] in_valid_bit_depth [ 24 ] @@ -232,6 +240,7 @@ 128000 176400 192000 + 384000 ] in_bit_depth [ 32 ] in_valid_bit_depth [ 32 ] @@ -257,6 +266,7 @@ 128000 176400 192000 + 384000 ] in_bit_depth [ 16 ] in_valid_bit_depth [ 16 ] @@ -282,6 +292,7 @@ 128000 176400 192000 + 384000 ] in_bit_depth [ 32 ] in_valid_bit_depth [ 24 ] @@ -307,6 +318,7 @@ 128000 176400 192000 + 384000 ] in_bit_depth [ 32 ] in_valid_bit_depth [ 32 ] @@ -332,6 +344,7 @@ 128000 176400 192000 + 384000 ] in_bit_depth [ 16 ] in_valid_bit_depth [ 16 ] @@ -357,6 +370,7 @@ 128000 176400 192000 + 384000 ] in_bit_depth [ 32 ] in_valid_bit_depth [ 24 ] @@ -382,6 +396,7 @@ 128000 176400 192000 + 384000 ] in_bit_depth [ 32 ] in_valid_bit_depth [ 32 ] @@ -407,6 +422,7 @@ 128000 176400 192000 + 384000 ] in_bit_depth [ 16 ] in_valid_bit_depth [ 16 ] @@ -432,6 +448,7 @@ 128000 176400 192000 + 384000 ] in_bit_depth [ 32 ] in_valid_bit_depth [ 24 ] @@ -457,6 +474,7 @@ 128000 176400 192000 + 384000 ] in_bit_depth [ 32 ] in_valid_bit_depth [ 32 ] @@ -482,6 +500,7 @@ 128000 176400 192000 + 384000 ] in_bit_depth [ 16 ] in_valid_bit_depth [ 16 ] @@ -507,6 +526,7 @@ 128000 176400 192000 + 384000 ] in_bit_depth [ 32 ] in_valid_bit_depth [ 24 ] @@ -532,6 +552,7 @@ 128000 176400 192000 + 384000 ] in_bit_depth [ 32 ] in_valid_bit_depth [ 32 ] 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 index a98428ba1533..f5110ca2e957 100644 --- a/tools/topology/topology2/include/formats/uaol_input_audio_formats_s32.conf +++ b/tools/topology/topology2/include/formats/uaol_input_audio_formats_s32.conf @@ -3,7 +3,7 @@ # # 7 channels is left out, it has no channel config and no channel map in # common_definitions.conf. - num_input_audio_formats 105 + num_input_audio_formats 112 CombineArrays.Object.Base.input_audio_format [ { in_rate [ @@ -22,6 +22,7 @@ 128000 176400 192000 + 384000 ] in_bit_depth [ 32 ] in_valid_bit_depth [ 32 ] @@ -46,6 +47,7 @@ 128000 176400 192000 + 384000 ] in_bit_depth [ 32 ] in_valid_bit_depth [ 32 ] @@ -70,6 +72,7 @@ 128000 176400 192000 + 384000 ] in_bit_depth [ 32 ] in_valid_bit_depth [ 32 ] @@ -94,6 +97,7 @@ 128000 176400 192000 + 384000 ] in_bit_depth [ 32 ] in_valid_bit_depth [ 32 ] @@ -118,6 +122,7 @@ 128000 176400 192000 + 384000 ] in_bit_depth [ 32 ] in_valid_bit_depth [ 32 ] @@ -142,6 +147,7 @@ 128000 176400 192000 + 384000 ] in_bit_depth [ 32 ] in_valid_bit_depth [ 32 ] @@ -166,6 +172,7 @@ 128000 176400 192000 + 384000 ] in_bit_depth [ 32 ] in_valid_bit_depth [ 32 ] diff --git a/tools/topology/topology2/include/formats/uaol_output_audio_formats.conf b/tools/topology/topology2/include/formats/uaol_output_audio_formats.conf index 0ff39effcd62..6567ea3a15db 100644 --- a/tools/topology/topology2/include/formats/uaol_output_audio_formats.conf +++ b/tools/topology/topology2/include/formats/uaol_output_audio_formats.conf @@ -1,9 +1,9 @@ # 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. + # S32_LE, 1 to 8 channels and every standard rate from 8 to 384 kHz. # # 7 channels is left out, it has no channel config and no channel map in # common_definitions.conf. - num_output_audio_formats 315 + num_output_audio_formats 336 CombineArrays.Object.Base.output_audio_format [ { out_rate [ @@ -22,6 +22,7 @@ 128000 176400 192000 + 384000 ] out_bit_depth [ 16 ] out_valid_bit_depth [ 16 ] @@ -46,6 +47,7 @@ 128000 176400 192000 + 384000 ] out_bit_depth [ 32 ] out_valid_bit_depth [ 24 32 ] @@ -70,6 +72,7 @@ 128000 176400 192000 + 384000 ] out_bit_depth [ 16 ] out_valid_bit_depth [ 16 ] @@ -94,6 +97,7 @@ 128000 176400 192000 + 384000 ] out_bit_depth [ 32 ] out_valid_bit_depth [ 24 32 ] @@ -118,6 +122,7 @@ 128000 176400 192000 + 384000 ] out_bit_depth [ 16 ] out_valid_bit_depth [ 16 ] @@ -142,6 +147,7 @@ 128000 176400 192000 + 384000 ] out_bit_depth [ 32 ] out_valid_bit_depth [ 24 32 ] @@ -166,6 +172,7 @@ 128000 176400 192000 + 384000 ] out_bit_depth [ 16 ] out_valid_bit_depth [ 16 ] @@ -190,6 +197,7 @@ 128000 176400 192000 + 384000 ] out_bit_depth [ 32 ] out_valid_bit_depth [ 24 32 ] @@ -214,6 +222,7 @@ 128000 176400 192000 + 384000 ] out_bit_depth [ 16 ] out_valid_bit_depth [ 16 ] @@ -238,6 +247,7 @@ 128000 176400 192000 + 384000 ] out_bit_depth [ 32 ] out_valid_bit_depth [ 24 32 ] @@ -262,6 +272,7 @@ 128000 176400 192000 + 384000 ] out_bit_depth [ 16 ] out_valid_bit_depth [ 16 ] @@ -286,6 +297,7 @@ 128000 176400 192000 + 384000 ] out_bit_depth [ 32 ] out_valid_bit_depth [ 24 32 ] @@ -310,6 +322,7 @@ 128000 176400 192000 + 384000 ] out_bit_depth [ 16 ] out_valid_bit_depth [ 16 ] @@ -334,6 +347,7 @@ 128000 176400 192000 + 384000 ] out_bit_depth [ 32 ] out_valid_bit_depth [ 24 32 ] diff --git a/tools/topology/topology2/include/formats/uaol_output_audio_formats_msb.conf b/tools/topology/topology2/include/formats/uaol_output_audio_formats_msb.conf index 3f783df3270f..080cbc93a973 100644 --- a/tools/topology/topology2/include/formats/uaol_output_audio_formats_msb.conf +++ b/tools/topology/topology2/include/formats/uaol_output_audio_formats_msb.conf @@ -1,5 +1,5 @@ # 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. + # S32_LE, 1 to 8 channels and every standard rate from 8 to 384 kHz. # # 7 channels is left out, it has no channel config and no channel map in # common_definitions.conf. @@ -9,7 +9,7 @@ # matching the convention every other link type (HDA, SoundWire, # SSP, DMIC) uses so the copier left-justifies 24-bit samples # before handing them to the link. - num_output_audio_formats 315 + num_output_audio_formats 336 CombineArrays.Object.Base.output_audio_format [ { out_rate [ @@ -28,6 +28,7 @@ 128000 176400 192000 + 384000 ] out_bit_depth [ 16 ] out_valid_bit_depth [ 16 ] @@ -53,6 +54,7 @@ 128000 176400 192000 + 384000 ] out_bit_depth [ 32 ] out_valid_bit_depth [ 24 ] @@ -78,6 +80,7 @@ 128000 176400 192000 + 384000 ] out_bit_depth [ 32 ] out_valid_bit_depth [ 32 ] @@ -103,6 +106,7 @@ 128000 176400 192000 + 384000 ] out_bit_depth [ 16 ] out_valid_bit_depth [ 16 ] @@ -128,6 +132,7 @@ 128000 176400 192000 + 384000 ] out_bit_depth [ 32 ] out_valid_bit_depth [ 24 ] @@ -153,6 +158,7 @@ 128000 176400 192000 + 384000 ] out_bit_depth [ 32 ] out_valid_bit_depth [ 32 ] @@ -178,6 +184,7 @@ 128000 176400 192000 + 384000 ] out_bit_depth [ 16 ] out_valid_bit_depth [ 16 ] @@ -203,6 +210,7 @@ 128000 176400 192000 + 384000 ] out_bit_depth [ 32 ] out_valid_bit_depth [ 24 ] @@ -228,6 +236,7 @@ 128000 176400 192000 + 384000 ] out_bit_depth [ 32 ] out_valid_bit_depth [ 32 ] @@ -253,6 +262,7 @@ 128000 176400 192000 + 384000 ] out_bit_depth [ 16 ] out_valid_bit_depth [ 16 ] @@ -278,6 +288,7 @@ 128000 176400 192000 + 384000 ] out_bit_depth [ 32 ] out_valid_bit_depth [ 24 ] @@ -303,6 +314,7 @@ 128000 176400 192000 + 384000 ] out_bit_depth [ 32 ] out_valid_bit_depth [ 32 ] @@ -328,6 +340,7 @@ 128000 176400 192000 + 384000 ] out_bit_depth [ 16 ] out_valid_bit_depth [ 16 ] @@ -353,6 +366,7 @@ 128000 176400 192000 + 384000 ] out_bit_depth [ 32 ] out_valid_bit_depth [ 24 ] @@ -378,6 +392,7 @@ 128000 176400 192000 + 384000 ] out_bit_depth [ 32 ] out_valid_bit_depth [ 32 ] @@ -403,6 +418,7 @@ 128000 176400 192000 + 384000 ] out_bit_depth [ 16 ] out_valid_bit_depth [ 16 ] @@ -428,6 +444,7 @@ 128000 176400 192000 + 384000 ] out_bit_depth [ 32 ] out_valid_bit_depth [ 24 ] @@ -453,6 +470,7 @@ 128000 176400 192000 + 384000 ] out_bit_depth [ 32 ] out_valid_bit_depth [ 32 ] @@ -478,6 +496,7 @@ 128000 176400 192000 + 384000 ] out_bit_depth [ 16 ] out_valid_bit_depth [ 16 ] @@ -503,6 +522,7 @@ 128000 176400 192000 + 384000 ] out_bit_depth [ 32 ] out_valid_bit_depth [ 24 ] @@ -528,6 +548,7 @@ 128000 176400 192000 + 384000 ] out_bit_depth [ 32 ] out_valid_bit_depth [ 32 ] 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 index 8dea01de8020..1a6871ece1e2 100644 --- a/tools/topology/topology2/include/formats/uaol_output_audio_formats_s32.conf +++ b/tools/topology/topology2/include/formats/uaol_output_audio_formats_s32.conf @@ -3,7 +3,7 @@ # # 7 channels is left out, it has no channel config and no channel map in # common_definitions.conf. - num_output_audio_formats 105 + num_output_audio_formats 112 CombineArrays.Object.Base.output_audio_format [ { out_rate [ @@ -22,6 +22,7 @@ 128000 176400 192000 + 384000 ] out_bit_depth [ 32 ] out_valid_bit_depth [ 32 ] @@ -46,6 +47,7 @@ 128000 176400 192000 + 384000 ] out_bit_depth [ 32 ] out_valid_bit_depth [ 32 ] @@ -70,6 +72,7 @@ 128000 176400 192000 + 384000 ] out_bit_depth [ 32 ] out_valid_bit_depth [ 32 ] @@ -94,6 +97,7 @@ 128000 176400 192000 + 384000 ] out_bit_depth [ 32 ] out_valid_bit_depth [ 32 ] @@ -118,6 +122,7 @@ 128000 176400 192000 + 384000 ] out_bit_depth [ 32 ] out_valid_bit_depth [ 32 ] @@ -142,6 +147,7 @@ 128000 176400 192000 + 384000 ] out_bit_depth [ 32 ] out_valid_bit_depth [ 32 ] @@ -166,6 +172,7 @@ 128000 176400 192000 + 384000 ] out_bit_depth [ 32 ] out_valid_bit_depth [ 32 ] diff --git a/tools/topology/topology2/platform/intel/uaol-generic.conf b/tools/topology/topology2/platform/intel/uaol-generic.conf index 49b28ec99808..ed7c0f7b625b 100644 --- a/tools/topology/topology2/platform/intel/uaol-generic.conf +++ b/tools/topology/topology2/platform/intel/uaol-generic.conf @@ -14,7 +14,7 @@ # 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 +# channels and the standard rates from 8 to 384 kHz, which is as far as UAOL # goes. The kernel narrows the PCM down to what the connected device actually # supports. # From a0c25f359424f27072152015f45cbeb01dd837f0 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 26 Aug 2026 11:37:54 +0300 Subject: [PATCH 06/10] topology2: Add the sof-hda-generic-uaol development topology Add sof-hda-generic-uaol.tplg, sof-hda-generic with the USB Audio Offload Link (UAOL) function appended, to have something to test the offload with on a plain HDA machine. The UAOL cannot be part of sof-hda-generic itself. A backend declared by the topology which the machine driver did not create makes the whole topology fail to load, and the UAOL DAIs are only there on ACE2 and newer platforms, and only with a kernel built with USB audio offload support. sof-hda-generic has to stay loadable on everything from SKL up, so the UAOL gets a topology of its own, which is asked for explicitly: options snd_sof tplg_filename=sof-hda-generic-uaol.tplg The module parameter also stops the machine driver from appending the -idisp suffix, so the topology carries the iDisp backends, as sof-hda-generic does. The UAOL backend IDs are fixed at 9 and 10 by skl_hda_dsp_generic regardless of which other functions the board has, so a single topology covers every HDA machine, no per-board variants are needed. The UAOL function comes from platform/intel/uaol-generic.conf, shared with the cavs-uaol function topology of the sof_sdw card. Its deep buffer is left out, the HDA playback already has the one deep buffer PCM the topology can hold. Signed-off-by: Peter Ujfalusi --- .../development/sof-hda-generic-uaol.conf | 72 +++++++++++++++++++ .../topology2/development/tplg-targets.cmake | 5 ++ 2 files changed, 77 insertions(+) create mode 100644 tools/topology/topology2/development/sof-hda-generic-uaol.conf diff --git a/tools/topology/topology2/development/sof-hda-generic-uaol.conf b/tools/topology/topology2/development/sof-hda-generic-uaol.conf new file mode 100644 index 000000000000..c4f1653f6863 --- /dev/null +++ b/tools/topology/topology2/development/sof-hda-generic-uaol.conf @@ -0,0 +1,72 @@ +# HDA generic topology extended with the USB Audio Offload Link (UAOL). +# +# Development topology. The UAOL is not part of sof-hda-generic itself: the +# backend of a function which is not present on the machine makes the whole +# topology fail to load, and the UAOL DAIs only exist on ACE2 and newer +# platforms, with a kernel built for USB audio offload. Keeping it separate +# leaves sof-hda-generic loadable everywhere. +# +# Select it with: +# options snd_sof tplg_filename=sof-hda-generic-uaol.tplg +# +# The module parameter also stops the machine driver from appending the -idisp +# suffix, so this topology carries the iDisp backends unconditionally, as +# sof-hda-generic does. +# +# The UAOL function itself lives in platform/intel/uaol-generic.conf, and is +# shared with the cavs-uaol function topology of the sof_sdw card. + + + + + + + + + + + + + + + + +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. skl_hda_dsp_generic assigns fixed IDs, so these are the same + # whichever other functions the board has + 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 384 kHz + UAOL_RATE_MIN 8000 + UAOL_RATE_MAX 384000 + UAOL_RATES '8000,11025,12000,16000,22050,24000,32000,44100,48000,64000,88200,96000,128000,176400,192000,384000' + + # The HDA playback already has the one deep buffer PCM the topology can + # hold, so the UAOL runs without one here + UAOL_DEEP_BUFFER 'false' +} + + diff --git a/tools/topology/topology2/development/tplg-targets.cmake b/tools/topology/topology2/development/tplg-targets.cmake index a2f4f9eda740..e0e56af91150 100644 --- a/tools/topology/topology2/development/tplg-targets.cmake +++ b/tools/topology/topology2/development/tplg-targets.cmake @@ -316,6 +316,11 @@ PREPROCESS_PLUGINS=nhlt,NHLT_BIN=nhlt-sof-tgl-nocodec-crossover.bin,EFX_CROSSOVE "development/cavs-nocodec-rtcaec\;sof-tgl-nocodec-rtcaec\;PLATFORM=tgl,\ PREPROCESS_PLUGINS=nhlt,NHLT_BIN=nhlt-sof-tgl-nocodec-rtcaec.bin" +# Topology to test the USB audio offload on an HDA machine, load it with +# snd_sof.tplg_filename=sof-hda-generic-uaol.tplg +"development/sof-hda-generic-uaol\;sof-hda-generic-uaol\;HDA_CONFIG=mix,HDA_MIC_ENHANCED_CAPTURE=true,\ +EFX_HDA_MIC_TDFB_PARAMS=line2_pass,EFX_HDA_MIC_DRC_PARAMS=passthrough" + # SSP test topology for Data Processing SRC on MTL "cavs-nocodec\;sof-mtl-nocodec-dp-test\;PLATFORM=mtl,NUM_DMICS=4,PDM1_MIC_A_ENABLE=1,PDM1_MIC_B_ENABLE=1,\ PREPROCESS_PLUGINS=nhlt,NHLT_BIN=nhlt-sof-mtl-nocodec.bin,SRC_DOMAIN=DP" From 48312667849a7c83c456c59e9cad90bceb392cb9 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 3 Nov 2026 09:58:30 +0200 Subject: [PATCH 07/10] topology2: uaol: Add the second playback and capture stream pair A UAOL link runs two streams per direction on the current hardware, and the kernel creates a backend for each of them, named UAOL-Play and UAOL-Cap in the order Play0, Cap0, Play1, Cap1. The first pair keeps the two consecutive dai link IDs it had. Rename the backends of the UAOL function to UAOL0-Play0 and UAOL0-Cap0 and take the hw_config names from the same variables. Add the second pair of paths in platform/intel/uaol-stream1.conf, the same paths on the UAOL_*1_* variables, pulled in when UAOL_NUM_STREAMS is 2. Its deep buffer is a second instance of the deepbuffer-playback pipeline in platform/intel/uaol-deep-buffer1.conf, on the UAOL_DB1_* variables, because platform/intel/deep-buffer.conf works on the global DEEP_BUFFER_* variables and can only be pulled in once. Both the development sof-hda-generic-uaol topology and the cavs-uaol function topology of the sof_sdw card expose both pairs, UAOL0 on PCM 21 and UAOL1 on PCM 22, the PCM names carrying the same ordinal as the route kcontrols; the sof_sdw one has a deep buffer for each, on PCM 23 and 24. The sof-uaol-id variants take the IDs of all four backends. The backend names stay abbreviated: alsa-lib keeps element ids in SNDRV_CTL_ELEM_ID_NAME_MAXLEN bytes, so once the dai-copier widget name 'dai-copier.UAOL..' reaches 38 characters the ids of its 'dai.word' and 'dai.string' tuple sections collide and one set is silently dropped from the topology. Signed-off-by: Peter Ujfalusi --- tools/topology/topology2/README.md | 15 +- tools/topology/topology2/cavs-uaol.conf | 45 +++- .../development/sof-hda-generic-uaol.conf | 39 +++- .../platform/intel/uaol-deep-buffer1.conf | 59 ++++++ .../platform/intel/uaol-generic.conf | 26 ++- .../platform/intel/uaol-stream1.conf | 197 ++++++++++++++++++ .../tplg-targets-sdca-generic.cmake | 26 +-- 7 files changed, 365 insertions(+), 42 deletions(-) create mode 100644 tools/topology/topology2/platform/intel/uaol-deep-buffer1.conf create mode 100644 tools/topology/topology2/platform/intel/uaol-stream1.conf diff --git a/tools/topology/topology2/README.md b/tools/topology/topology2/README.md index 0d62fd859a08..5589cd0a3acd 100644 --- a/tools/topology/topology2/README.md +++ b/tools/topology/topology2/README.md @@ -243,8 +243,10 @@ 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` | +| USB Audio Offload (UAOL0) | 21 | `UAOL_PCM_ID` | +| USB Audio Offload (UAOL1) | 22 | `UAOL_PCM1_ID` | +| Deepbuffer UAOL0 | 23 | `DEEP_BUFFER_PCM_ID` | +| Deepbuffer UAOL1 | 24 | `UAOL_DB1_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` | @@ -304,9 +306,12 @@ 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` | +| UAOL0 Playback Host / DAI | 210 / 211 | `UAOL_PB_HOST_PIPELINE_ID` / `UAOL_PB_DAI_PIPELINE_ID` | +| UAOL0 Capture Host / DAI | 212 / 213 | `UAOL_CP_HOST_PIPELINE_ID` / `UAOL_CP_DAI_PIPELINE_ID` | +| UAOL0 Deepbuffer | 214 | `DEEP_BUFFER_PIPELINE_ID` | +| UAOL1 Playback Host / DAI | 215 / 216 | `UAOL_PB1_HOST_PIPELINE_ID` / `UAOL_PB1_DAI_PIPELINE_ID` | +| UAOL1 Capture Host / DAI | 217 / 218 | `UAOL_CP1_HOST_PIPELINE_ID` / `UAOL_CP1_DAI_PIPELINE_ID` | +| UAOL1 Deepbuffer | 219 | `UAOL_DB1_PIPELINE_ID` | **Intel HDA Pipeline IDs:** diff --git a/tools/topology/topology2/cavs-uaol.conf b/tools/topology/topology2/cavs-uaol.conf index f6a9dbe17f67..3f1cfa299f34 100644 --- a/tools/topology/topology2/cavs-uaol.conf +++ b/tools/topology/topology2/cavs-uaol.conf @@ -42,26 +42,44 @@ Define { - UAOL_PLAYBACK_PCM 'UAOL Playback' - UAOL_CAPTURE_PCM 'UAOL Capture' + UAOL_PLAYBACK_PCM 'UAOL0 Playback' + UAOL_CAPTURE_PCM 'UAOL0 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' + # a link is decided by the DAI copier of that direction alone, and the + # link carries two streams per direction, each with a backend of its + # own: UAOL-Play and UAOL-Cap. The names are abbreviated + # because alsa-lib drops widget tuples once the dai-copier name, + # 'dai-copier.UAOL..', exceeds 37 characters + UAOL_PB_DAI_NAME 'UAOL0-Play0' + UAOL_CP_DAI_NAME 'UAOL0-Cap0' # The BE IDs are the dai link IDs that are matched with the machine - # driver, which creates the playback link first + # driver, which creates the backends in the order Play0, Cap0, Play1, + # Cap1 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_NAME 'UAOL0' 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 + + # Second stream pair of the link, on its own PCM + UAOL_NUM_STREAMS 2 + UAOL_PLAYBACK1_PCM 'UAOL1 Playback' + UAOL_CAPTURE1_PCM 'UAOL1 Capture' + UAOL_PB1_DAI_NAME 'UAOL0-Play1' + UAOL_CP1_DAI_NAME 'UAOL0-Cap1' + UAOL_PB1_BE_ID 11 + UAOL_CP1_BE_ID 12 + UAOL_PCM1_NAME 'UAOL1' + UAOL_PCM1_ID 22 + UAOL_PB1_HOST_PIPELINE_ID 215 + UAOL_PB1_DAI_PIPELINE_ID 216 + UAOL_CP1_HOST_PIPELINE_ID 217 + UAOL_CP1_DAI_PIPELINE_ID 218 # 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 @@ -77,11 +95,16 @@ Define { # takes the source and the sink as plain widget names, so it repeats the # pipeline IDs defined above. UAOL_DEEP_BUFFER 'true' - DEEP_BUFFER_PCM_NAME 'Deepbuffer UAOL' - DEEP_BUFFER_PCM_ID 22 + DEEP_BUFFER_PCM_NAME 'Deepbuffer UAOL0' + DEEP_BUFFER_PCM_ID 23 DEEP_BUFFER_PIPELINE_ID 214 DEEP_BUFFER_PIPELINE_SRC 'mixin.214.1' DEEP_BUFFER_PIPELINE_SINK 'mixout.211.1' + # The second stream's deep buffer is a separate instance, so it routes + # itself to the UAOL1 mixer + UAOL_DB1_PCM_NAME 'Deepbuffer UAOL1' + UAOL_DB1_PCM_ID 24 + UAOL_DB1_PIPELINE_ID 219 } diff --git a/tools/topology/topology2/development/sof-hda-generic-uaol.conf b/tools/topology/topology2/development/sof-hda-generic-uaol.conf index c4f1653f6863..decdc8e5856f 100644 --- a/tools/topology/topology2/development/sof-hda-generic-uaol.conf +++ b/tools/topology/topology2/development/sof-hda-generic-uaol.conf @@ -32,27 +32,48 @@ Define { - UAOL_PLAYBACK_PCM 'UAOL Playback' - UAOL_CAPTURE_PCM 'UAOL Capture' + UAOL_PLAYBACK_PCM 'UAOL0 Playback' + UAOL_CAPTURE_PCM 'UAOL0 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' + # a link is decided by the DAI copier of that direction alone, and the + # link carries two streams per direction, each with a backend of its + # own: UAOL-Play and UAOL-Cap. The names are abbreviated + # because alsa-lib drops widget tuples once the dai-copier name, + # 'dai-copier.UAOL..', exceeds 37 characters + UAOL_PB_DAI_NAME 'UAOL0-Play0' + UAOL_CP_DAI_NAME 'UAOL0-Cap0' # The BE IDs are the dai link IDs that are matched with the machine # driver. skl_hda_dsp_generic assigns fixed IDs, so these are the same - # whichever other functions the board has + # whichever other functions the board has. The backends come in the + # order Play0, Cap0, Play1, Cap1 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_NAME 'UAOL0' 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 + + # Second stream pair of the link, on its own PCM. Each backend offloads + # the USB PCM its route kcontrol points at; with a single USB device both + # routes point at it and the second PCM fails with EBUSY while the first + # one runs, a second device or a second PCM of the first lets both run + UAOL_NUM_STREAMS 2 + UAOL_PLAYBACK1_PCM 'UAOL1 Playback' + UAOL_CAPTURE1_PCM 'UAOL1 Capture' + UAOL_PB1_DAI_NAME 'UAOL0-Play1' + UAOL_CP1_DAI_NAME 'UAOL0-Cap1' + UAOL_PB1_BE_ID 11 + UAOL_CP1_BE_ID 12 + UAOL_PCM1_NAME 'UAOL1' + UAOL_PCM1_ID 22 + UAOL_PB1_HOST_PIPELINE_ID 215 + UAOL_PB1_DAI_PIPELINE_ID 216 + UAOL_CP1_HOST_PIPELINE_ID 217 + UAOL_CP1_DAI_PIPELINE_ID 218 # 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 diff --git a/tools/topology/topology2/platform/intel/uaol-deep-buffer1.conf b/tools/topology/topology2/platform/intel/uaol-deep-buffer1.conf new file mode 100644 index 000000000000..e31f5a68f67a --- /dev/null +++ b/tools/topology/topology2/platform/intel/uaol-deep-buffer1.conf @@ -0,0 +1,59 @@ +# Deep buffer playback of the second UAOL stream pair. +# +# Included by platform/intel/uaol-stream1.conf under the same conditions as the +# first pair's deep buffer. platform/intel/deep-buffer.conf cannot be pulled in +# twice, it takes its pipeline and PCM from the global DEEP_BUFFER_* variables, +# so this is a second instance on the UAOL_DB1_* variables, the way +# platform/intel/deep-buffer-spk.conf is for the speaker. + +Object.Pipeline.deepbuffer-playback [ + { + index $UAOL_DB1_PIPELINE_ID + + Object.Widget.host-copier.1 { + stream_name $UAOL_DB1_PCM_NAME + pcm_id $UAOL_DB1_PCM_ID + } + Object.Widget.gain.1 { + Object.Control.mixer.1 { + name 'Pre Mixer $UAOL_DB1_PCM_NAME Volume' + } + } + } +] + +Object.PCM.pcm [ + { + name $UAOL_DB1_PCM_NAME + id $UAOL_DB1_PCM_ID + direction playback + playback_compatible_d0i3 $DEEPBUFFER_D0I3_COMPATIBLE + + Object.Base.fe_dai.1 { + name "$UAOL_DB1_PCM_NAME" + } + Object.PCM.pcm_caps.1 { + name $UAOL_DB1_PCM_NAME + formats 'S16_LE,S24_LE,S32_LE' + # To avoid DMA spinning on a buffer we need bigger + # buffer than the host buffer size, let's say twice as + # big + # (S16_LE, Stereo, 48KHz, DEEPBUFFER_FW_DMA_MS) * 2 + # + # Note: The lower limit for the buffer size is rate + # dependent + buffer_size_min "$[(((2 * $channels_min) * 48) * $DEEPBUFFER_FW_DMA_MS) * 2]" + } + } +] + +Object.Base.route [ + { + source mixin.$UAOL_DB1_PIPELINE_ID.1 + sink mixout.$UAOL_PB1_DAI_PIPELINE_ID.1 + } + { + source host-copier.$UAOL_DB1_PCM_ID.playback + sink gain.$UAOL_DB1_PIPELINE_ID.1 + } +] diff --git a/tools/topology/topology2/platform/intel/uaol-generic.conf b/tools/topology/topology2/platform/intel/uaol-generic.conf index ed7c0f7b625b..c71bb791f1c5 100644 --- a/tools/topology/topology2/platform/intel/uaol-generic.conf +++ b/tools/topology/topology2/platform/intel/uaol-generic.conf @@ -4,13 +4,23 @@ # # PCM ---------------> gain ---> mixin ---+ # | -# Deepbuffer PCM ----> gain ---> mixin ---+--> mixout --> gain --> UAOL0-Play +# Deepbuffer PCM ----> gain ---> mixin ---+--> mixout --> gain --> UAOL0-Play0 # -# PCM <------------ module-copier <--- eqiir <---------------- UAOL0-Cap +# PCM <------------ module-copier <--- eqiir <---------------- UAOL0-Cap0 # # The capture path carries no mixer, as the number of channels follows the USB # device and a mixer only handles a fixed channel count. # +# A UAOL link runs several streams at a time, and the kernel creates a backend +# for each of them: UAOL-Play and UAOL-Cap, n counting the +# streams of a direction. This file describes the paths of the first stream +# pair, with the PCM, pipeline and backend IDs taken from the UAOL_* variables. +# The second pair, platform/intel/uaol-stream1.conf, is pulled in when +# UAOL_NUM_STREAMS is 2; it is the same paths on the UAOL_*1_* variables, with +# a deep buffer of its own on UAOL_DB1_*. A topology only has to describe the +# streams it wants to expose, a backend the topology leaves out simply stays +# unused. +# # 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 @@ -29,7 +39,8 @@ # DEEP_BUFFER_* variables, and those are global, so a second include which # redefines them moves the first deep buffer on top of the second one. A # topology which already has a deep buffer of its own asks for -# UAOL_DEEP_BUFFER false. +# UAOL_DEEP_BUFFER false. The same key also decides the second stream's deep +# buffer, which is an instance of its own and does not have this limitation. IncludeByKey.UAOL_DEEP_BUFFER { "true" { IncludeByKey.DEEPBUFFER_FW_DMA_MS { @@ -45,7 +56,7 @@ Object.Dai.UAOL [ id $UAOL_PB_BE_ID default_hw_conf_id 0 Object.Base.hw_config.1 { - name "UAOL0-Play" + name $UAOL_PB_DAI_NAME } direction playback } @@ -55,7 +66,7 @@ Object.Dai.UAOL [ id $UAOL_CP_BE_ID default_hw_conf_id 0 Object.Base.hw_config.1 { - name "UAOL0-Cap" + name $UAOL_CP_DAI_NAME } direction capture } @@ -213,3 +224,8 @@ Object.Base.route [ sink "host-copier.$UAOL_PCM_ID.capture" } ] + +# The second stream pair of the link +IncludeByKey.UAOL_NUM_STREAMS { + "2" "platform/intel/uaol-stream1.conf" +} diff --git a/tools/topology/topology2/platform/intel/uaol-stream1.conf b/tools/topology/topology2/platform/intel/uaol-stream1.conf new file mode 100644 index 000000000000..c03c89fe700c --- /dev/null +++ b/tools/topology/topology2/platform/intel/uaol-stream1.conf @@ -0,0 +1,197 @@ +# Second stream pair of a USB Audio Offload Link (UAOL). +# +# Included by platform/intel/uaol-generic.conf when UAOL_NUM_STREAMS is 2. The +# same paths as the first pair, on the UAOL_*1_* variables. The deep buffer +# comes from platform/intel/uaol-deep-buffer1.conf, a second instance on the +# UAOL_DB1_* variables, as platform/intel/deep-buffer.conf can only be pulled +# in once per topology. +# +# PCM ---------------> gain ---> mixin ---+ +# | +# Deepbuffer PCM ----> gain ---> mixin ---+--> mixout --> gain --> UAOL0-Play1 +# +# PCM <------------ module-copier <--- eqiir <---------------- UAOL0-Cap1 + +IncludeByKey.UAOL_DEEP_BUFFER { + "true" { + IncludeByKey.DEEPBUFFER_FW_DMA_MS { + "([1-9]|[1-9][0-9]|[1-9][0-9][0-9]|1000)" "platform/intel/uaol-deep-buffer1.conf" + } + } +} + +Object.Dai.UAOL [ + { + name $UAOL_PB1_DAI_NAME + dai_index $UAOL_DAI_INDEX + id $UAOL_PB1_BE_ID + default_hw_conf_id 0 + Object.Base.hw_config.1 { + name $UAOL_PB1_DAI_NAME + } + direction playback + } + { + name $UAOL_CP1_DAI_NAME + dai_index $UAOL_DAI_INDEX + id $UAOL_CP1_BE_ID + default_hw_conf_id 0 + Object.Base.hw_config.1 { + name $UAOL_CP1_DAI_NAME + } + direction capture + } +] + +Object.Pipeline { + host-copier-gain-mixin-playback [ + { + index $UAOL_PB1_HOST_PIPELINE_ID + + Object.Widget.host-copier.1 { + stream_name $UAOL_PLAYBACK1_PCM + pcm_id $UAOL_PCM1_ID + + + } + Object.Widget.gain.1 { + Object.Control.mixer.1 { + name 'Pre Mixer $UAOL_PCM1_NAME Playback Volume' + } + + + } + Object.Widget.mixin.1 { + + + } + } + ] + + mixout-gain-dai-copier-playback [ + { + index $UAOL_PB1_DAI_PIPELINE_ID + + Object.Widget.mixout.1 { + + + } + Object.Widget.dai-copier.1 { + node_type $ALH_UAOL_STREAM_LINK_OUTPUT_CLASS + stream_name $UAOL_PB1_DAI_NAME + dai_type "UAOL" + copier_type "UAOL" + + + } + Object.Widget.gain.1 { + Object.Control.mixer.1 { + name 'Post Mixer $UAOL_PCM1_NAME Playback Volume' + } + + + } + } + ] + + host-gateway-capture [ + { + index $UAOL_CP1_HOST_PIPELINE_ID + + Object.Widget.host-copier.1 { + stream_name $UAOL_CAPTURE1_PCM + pcm_id $UAOL_PCM1_ID + + + } + } + ] + + dai-copier-eqiir-module-copier-capture [ + { + index $UAOL_CP1_DAI_PIPELINE_ID + + Object.Widget.dai-copier.1 { + node_type $ALH_UAOL_STREAM_LINK_INPUT_CLASS + stream_name $UAOL_CP1_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_PCM1_NAME Capture IIR Eq' + + } + + + } + + Object.Widget.module-copier.2 { + + + } + } + ] +} + +Object.PCM.pcm [ + { + name $UAOL_PCM1_NAME + id $UAOL_PCM1_ID + direction "duplex" + Object.Base.fe_dai.1 { + name $UAOL_PCM1_NAME + } + Object.PCM.pcm_caps.1 { + direction "playback" + name $UAOL_PLAYBACK1_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_CAPTURE1_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_PCM1_ID.playback" + sink "gain.$UAOL_PB1_HOST_PIPELINE_ID.1" + } + { + source "mixin.$UAOL_PB1_HOST_PIPELINE_ID.1" + sink "mixout.$UAOL_PB1_DAI_PIPELINE_ID.1" + } + { + source "gain.$UAOL_PB1_DAI_PIPELINE_ID.1" + sink "dai-copier.UAOL.$UAOL_PB1_DAI_NAME.playback" + } + { + source "dai-copier.UAOL.$UAOL_CP1_DAI_NAME.capture" + sink "eqiir.$UAOL_CP1_DAI_PIPELINE_ID.1" + } + { + source "module-copier.$UAOL_CP1_DAI_PIPELINE_ID.2" + sink "host-copier.$UAOL_PCM1_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 8bb6d700e1e3..ce63b75b002e 100644 --- a/tools/topology/topology2/production/tplg-targets-sdca-generic.cmake +++ b/tools/topology/topology2/production/tplg-targets-sdca-generic.cmake @@ -42,18 +42,20 @@ EFX_MIC_TDFB_PARAMS=line4_pass" "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" +# USB Audio Offload Link function topology. The UAOL backends are the last ones +# sof_sdw creates, so their dai link IDs depend on the composition of the board: +# they follow the SoundWire links, the PCH DMIC pair, the three HDMI links and +# the BT link. The link has two streams per direction and each gets a backend, +# in the order Play0, Cap0, Play1, Cap1, so four consecutive IDs are taken and +# the topology exposes a PCM per pair. 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,UAOL_PB1_BE_ID=8,UAOL_CP1_BE_ID=9" +"cavs-uaol\;sof-uaol-id7\;UAOL_PB_BE_ID=7,UAOL_CP_BE_ID=8,UAOL_PB1_BE_ID=9,UAOL_CP1_BE_ID=10" +"cavs-uaol\;sof-uaol-id8\;UAOL_PB_BE_ID=8,UAOL_CP_BE_ID=9,UAOL_PB1_BE_ID=10,UAOL_CP1_BE_ID=11" +"cavs-uaol\;sof-uaol-id9\;UAOL_PB_BE_ID=9,UAOL_CP_BE_ID=10,UAOL_PB1_BE_ID=11,UAOL_CP1_BE_ID=12" +"cavs-uaol\;sof-uaol-id10\;UAOL_PB_BE_ID=10,UAOL_CP_BE_ID=11,UAOL_PB1_BE_ID=12,UAOL_CP1_BE_ID=13" # 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,\ From b3689587750b737f86e5227750e5ed527273e334 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 3 Nov 2026 13:52:53 +0200 Subject: [PATCH 08/10] topology2: development: uaol: Add deep buffers to sof-hda-generic-uaol The development sof-hda-generic-uaol topology had no deep buffer for its UAOL PCMs: the first stream's deep buffer came from platform/intel/deep-buffer.conf, which builds its pipeline and PCM from the global DEEP_BUFFER_* variables and so can only be pulled in once per topology, and the HDA jack of sof-hda-generic already has that one. Give the first stream a deep buffer instance of its own, the way the second stream already has: platform/intel/uaol-deep-buffer.conf, the deepbuffer-playback pipeline on the UAOL_DB_* variables, routed into the mixer of the stream itself. UAOL_DEEP_BUFFER now only says whether a topology wants the UAOL deep buffers at all, independent of any other deep buffer it has. The cavs-uaol function topology keeps its two on PCM 23 and 24, and sof-hda-generic-uaol gets the same pair next to the Deepbuffer HDA Analog PCM. Signed-off-by: Peter Ujfalusi --- tools/topology/topology2/README.md | 4 +- tools/topology/topology2/cavs-uaol.conf | 15 ++--- .../development/sof-hda-generic-uaol.conf | 12 +++- .../platform/intel/uaol-deep-buffer.conf | 61 +++++++++++++++++++ .../platform/intel/uaol-deep-buffer1.conf | 6 +- .../platform/intel/uaol-generic.conf | 20 +++--- .../platform/intel/uaol-stream1.conf | 6 +- 7 files changed, 89 insertions(+), 35 deletions(-) create mode 100644 tools/topology/topology2/platform/intel/uaol-deep-buffer.conf diff --git a/tools/topology/topology2/README.md b/tools/topology/topology2/README.md index 5589cd0a3acd..10d587d8e35d 100644 --- a/tools/topology/topology2/README.md +++ b/tools/topology/topology2/README.md @@ -245,7 +245,7 @@ default ID ranges for the same endpoint types. | Bluetooth | 2 or 20 | `BT_PCM_ID` | | USB Audio Offload (UAOL0) | 21 | `UAOL_PCM_ID` | | USB Audio Offload (UAOL1) | 22 | `UAOL_PCM1_ID` | -| Deepbuffer UAOL0 | 23 | `DEEP_BUFFER_PCM_ID` | +| Deepbuffer UAOL0 | 23 | `UAOL_DB_PCM_ID` | | Deepbuffer UAOL1 | 24 | `UAOL_DB1_PCM_ID` | | Deep Buffer (Jack) | 31 | `DEEP_BUFFER_PCM_ID` | | Deep Buffer (Speaker) | 35 | `DEEP_BUFFER_PCM_ID_2` | @@ -308,7 +308,7 @@ is at N1 (50/51, 60/61, 70/71, 80/81). | PCH DMIC0 Host / DAI | 100 / 101 | `DMIC0_HOST_PIPELINE_ID` / `DMIC0_DAI_PIPELINE_ID` | | UAOL0 Playback Host / DAI | 210 / 211 | `UAOL_PB_HOST_PIPELINE_ID` / `UAOL_PB_DAI_PIPELINE_ID` | | UAOL0 Capture Host / DAI | 212 / 213 | `UAOL_CP_HOST_PIPELINE_ID` / `UAOL_CP_DAI_PIPELINE_ID` | -| UAOL0 Deepbuffer | 214 | `DEEP_BUFFER_PIPELINE_ID` | +| UAOL0 Deepbuffer | 214 | `UAOL_DB_PIPELINE_ID` | | UAOL1 Playback Host / DAI | 215 / 216 | `UAOL_PB1_HOST_PIPELINE_ID` / `UAOL_PB1_DAI_PIPELINE_ID` | | UAOL1 Capture Host / DAI | 217 / 218 | `UAOL_CP1_HOST_PIPELINE_ID` / `UAOL_CP1_DAI_PIPELINE_ID` | | UAOL1 Deepbuffer | 219 | `UAOL_DB1_PIPELINE_ID` | diff --git a/tools/topology/topology2/cavs-uaol.conf b/tools/topology/topology2/cavs-uaol.conf index 3f1cfa299f34..a351ca1e9f7a 100644 --- a/tools/topology/topology2/cavs-uaol.conf +++ b/tools/topology/topology2/cavs-uaol.conf @@ -91,17 +91,12 @@ Define { UAOL_RATE_MAX 384000 UAOL_RATES '8000,11025,12000,16000,22050,24000,32000,44100,48000,64000,88200,96000,128000,176400,192000,384000' - # 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. + # The deep buffer PCMs feed the same mixer as the normal playback PCM of + # their stream UAOL_DEEP_BUFFER 'true' - DEEP_BUFFER_PCM_NAME 'Deepbuffer UAOL0' - DEEP_BUFFER_PCM_ID 23 - DEEP_BUFFER_PIPELINE_ID 214 - DEEP_BUFFER_PIPELINE_SRC 'mixin.214.1' - DEEP_BUFFER_PIPELINE_SINK 'mixout.211.1' - # The second stream's deep buffer is a separate instance, so it routes - # itself to the UAOL1 mixer + UAOL_DB_PCM_NAME 'Deepbuffer UAOL0' + UAOL_DB_PCM_ID 23 + UAOL_DB_PIPELINE_ID 214 UAOL_DB1_PCM_NAME 'Deepbuffer UAOL1' UAOL_DB1_PCM_ID 24 UAOL_DB1_PIPELINE_ID 219 diff --git a/tools/topology/topology2/development/sof-hda-generic-uaol.conf b/tools/topology/topology2/development/sof-hda-generic-uaol.conf index decdc8e5856f..6ce68772c97b 100644 --- a/tools/topology/topology2/development/sof-hda-generic-uaol.conf +++ b/tools/topology/topology2/development/sof-hda-generic-uaol.conf @@ -85,9 +85,15 @@ Define { UAOL_RATE_MAX 384000 UAOL_RATES '8000,11025,12000,16000,22050,24000,32000,44100,48000,64000,88200,96000,128000,176400,192000,384000' - # The HDA playback already has the one deep buffer PCM the topology can - # hold, so the UAOL runs without one here - UAOL_DEEP_BUFFER 'false' + # The deep buffer PCMs feed the same mixer as the normal playback PCM of + # their stream, next to the one the HDA playback has + UAOL_DEEP_BUFFER 'true' + UAOL_DB_PCM_NAME 'Deepbuffer UAOL0' + UAOL_DB_PCM_ID 23 + UAOL_DB_PIPELINE_ID 214 + UAOL_DB1_PCM_NAME 'Deepbuffer UAOL1' + UAOL_DB1_PCM_ID 24 + UAOL_DB1_PIPELINE_ID 219 } diff --git a/tools/topology/topology2/platform/intel/uaol-deep-buffer.conf b/tools/topology/topology2/platform/intel/uaol-deep-buffer.conf new file mode 100644 index 000000000000..572c9fc57a78 --- /dev/null +++ b/tools/topology/topology2/platform/intel/uaol-deep-buffer.conf @@ -0,0 +1,61 @@ +# Deep buffer playback of the first UAOL stream pair. +# +# Included by platform/intel/uaol-generic.conf when UAOL_DEEP_BUFFER is true +# and the deep buffer DMA size is in range. An instance of the deepbuffer-playback +# pipeline on the UAOL_DB_* variables, routed into the mixer of the first +# playback stream, the way platform/intel/deep-buffer-spk.conf is for the +# speaker. platform/intel/deep-buffer.conf cannot be used, it works on the +# global DEEP_BUFFER_* variables, which the deep buffer of a jack or speaker the +# topology also has takes. + +Object.Pipeline.deepbuffer-playback [ + { + index $UAOL_DB_PIPELINE_ID + + Object.Widget.host-copier.1 { + stream_name $UAOL_DB_PCM_NAME + pcm_id $UAOL_DB_PCM_ID + } + Object.Widget.gain.1 { + Object.Control.mixer.1 { + name 'Pre Mixer $UAOL_DB_PCM_NAME Volume' + } + } + } +] + +Object.PCM.pcm [ + { + name $UAOL_DB_PCM_NAME + id $UAOL_DB_PCM_ID + direction playback + playback_compatible_d0i3 $DEEPBUFFER_D0I3_COMPATIBLE + + Object.Base.fe_dai.1 { + name "$UAOL_DB_PCM_NAME" + } + Object.PCM.pcm_caps.1 { + name $UAOL_DB_PCM_NAME + formats 'S16_LE,S24_LE,S32_LE' + # To avoid DMA spinning on a buffer we need bigger + # buffer than the host buffer size, let's say twice as + # big + # (S16_LE, Stereo, 48KHz, DEEPBUFFER_FW_DMA_MS) * 2 + # + # Note: The lower limit for the buffer size is rate + # dependent + buffer_size_min "$[(((2 * $channels_min) * 48) * $DEEPBUFFER_FW_DMA_MS) * 2]" + } + } +] + +Object.Base.route [ + { + source mixin.$UAOL_DB_PIPELINE_ID.1 + sink mixout.$UAOL_PB_DAI_PIPELINE_ID.1 + } + { + source host-copier.$UAOL_DB_PCM_ID.playback + sink gain.$UAOL_DB_PIPELINE_ID.1 + } +] diff --git a/tools/topology/topology2/platform/intel/uaol-deep-buffer1.conf b/tools/topology/topology2/platform/intel/uaol-deep-buffer1.conf index e31f5a68f67a..242912325a5f 100644 --- a/tools/topology/topology2/platform/intel/uaol-deep-buffer1.conf +++ b/tools/topology/topology2/platform/intel/uaol-deep-buffer1.conf @@ -1,10 +1,8 @@ # Deep buffer playback of the second UAOL stream pair. # # Included by platform/intel/uaol-stream1.conf under the same conditions as the -# first pair's deep buffer. platform/intel/deep-buffer.conf cannot be pulled in -# twice, it takes its pipeline and PCM from the global DEEP_BUFFER_* variables, -# so this is a second instance on the UAOL_DB1_* variables, the way -# platform/intel/deep-buffer-spk.conf is for the speaker. +# first pair's deep buffer, platform/intel/uaol-deep-buffer.conf, which this +# repeats on the UAOL_DB1_* variables. Object.Pipeline.deepbuffer-playback [ { diff --git a/tools/topology/topology2/platform/intel/uaol-generic.conf b/tools/topology/topology2/platform/intel/uaol-generic.conf index c71bb791f1c5..41816ca3e369 100644 --- a/tools/topology/topology2/platform/intel/uaol-generic.conf +++ b/tools/topology/topology2/platform/intel/uaol-generic.conf @@ -28,23 +28,19 @@ # 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 +# The deep buffer PCM is left at 48 kHz stereo, the default of the +# deepbuffer-playback pipeline. 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. -# -# It is optional because platform/intel/deep-buffer.conf can only be pulled in -# once per topology: it takes the pipeline and the PCM it creates from the -# DEEP_BUFFER_* variables, and those are global, so a second include which -# redefines them moves the first deep buffer on top of the second one. A -# topology which already has a deep buffer of its own asks for -# UAOL_DEEP_BUFFER false. The same key also decides the second stream's deep -# buffer, which is an instance of its own and does not have this limitation. +# Deep buffer playback, included when UAOL_DEEP_BUFFER is true and the DMA +# buffer is 1 - 1000 ms. The deep buffers of the UAOL streams are instances of +# their own, platform/intel/uaol-deep-buffer.conf and uaol-deep-buffer1.conf on +# the UAOL_DB_* and UAOL_DB1_* variables, so they sit next to the deep buffer a +# jack or speaker of the topology has on the global DEEP_BUFFER_* ones. IncludeByKey.UAOL_DEEP_BUFFER { "true" { IncludeByKey.DEEPBUFFER_FW_DMA_MS { - "([1-9]|[1-9][0-9]|[1-9][0-9][0-9]|1000)" "platform/intel/deep-buffer.conf" + "([1-9]|[1-9][0-9]|[1-9][0-9][0-9]|1000)" "platform/intel/uaol-deep-buffer.conf" } } } diff --git a/tools/topology/topology2/platform/intel/uaol-stream1.conf b/tools/topology/topology2/platform/intel/uaol-stream1.conf index c03c89fe700c..71475300b58a 100644 --- a/tools/topology/topology2/platform/intel/uaol-stream1.conf +++ b/tools/topology/topology2/platform/intel/uaol-stream1.conf @@ -1,10 +1,8 @@ # Second stream pair of a USB Audio Offload Link (UAOL). # # Included by platform/intel/uaol-generic.conf when UAOL_NUM_STREAMS is 2. The -# same paths as the first pair, on the UAOL_*1_* variables. The deep buffer -# comes from platform/intel/uaol-deep-buffer1.conf, a second instance on the -# UAOL_DB1_* variables, as platform/intel/deep-buffer.conf can only be pulled -# in once per topology. +# same paths as the first pair, on the UAOL_*1_* variables, the deep buffer +# from platform/intel/uaol-deep-buffer1.conf on UAOL_DB1_*. # # PCM ---------------> gain ---> mixin ---+ # | From 6283e72f97cb48979c1e1e63e400a9365f593974 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 3 Nov 2026 15:09:59 +0200 Subject: [PATCH 09/10] topology2: development: uaol: Add sof-hda-generic-idisp-uaol for HDMI-only machines sof-hda-generic-uaol carries the HDA codec paths, which the machine driver would have dropped by picking sof-hda-generic-idisp on a machine with only an iDisp codec; with the topology named through tplg_filename that selection does not happen, and a backend for a codec the machine does not have fails the whole topology. Build the same file once more without HDA_CONFIG as sof-hda-generic-idisp-uaol, the HDMI passthrough paths of sof-hda-generic-idisp plus the UAOL function, for testing the USB audio offload on such a machine. Signed-off-by: Peter Ujfalusi --- .../topology/topology2/development/sof-hda-generic-uaol.conf | 4 +++- tools/topology/topology2/development/tplg-targets.cmake | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/tools/topology/topology2/development/sof-hda-generic-uaol.conf b/tools/topology/topology2/development/sof-hda-generic-uaol.conf index 6ce68772c97b..bb3ffcd1501b 100644 --- a/tools/topology/topology2/development/sof-hda-generic-uaol.conf +++ b/tools/topology/topology2/development/sof-hda-generic-uaol.conf @@ -11,7 +11,9 @@ # # The module parameter also stops the machine driver from appending the -idisp # suffix, so this topology carries the iDisp backends unconditionally, as -# sof-hda-generic does. +# sof-hda-generic does. For a machine without an HDA codec, where the driver +# would have picked sof-hda-generic-idisp, use the sof-hda-generic-idisp-uaol variant +# instead, which is built from this file without the HDA codec paths. # # The UAOL function itself lives in platform/intel/uaol-generic.conf, and is # shared with the cavs-uaol function topology of the sof_sdw card. diff --git a/tools/topology/topology2/development/tplg-targets.cmake b/tools/topology/topology2/development/tplg-targets.cmake index e0e56af91150..be12c019fb9a 100644 --- a/tools/topology/topology2/development/tplg-targets.cmake +++ b/tools/topology/topology2/development/tplg-targets.cmake @@ -320,6 +320,9 @@ PREPROCESS_PLUGINS=nhlt,NHLT_BIN=nhlt-sof-tgl-nocodec-rtcaec.bin" # snd_sof.tplg_filename=sof-hda-generic-uaol.tplg "development/sof-hda-generic-uaol\;sof-hda-generic-uaol\;HDA_CONFIG=mix,HDA_MIC_ENHANCED_CAPTURE=true,\ EFX_HDA_MIC_TDFB_PARAMS=line2_pass,EFX_HDA_MIC_DRC_PARAMS=passthrough" +# The same for a machine without an HDA codec, HDMI only, load it with +# snd_sof.tplg_filename=sof-hda-generic-idisp-uaol.tplg +"development/sof-hda-generic-uaol\;sof-hda-generic-idisp-uaol\;" # SSP test topology for Data Processing SRC on MTL "cavs-nocodec\;sof-mtl-nocodec-dp-test\;PLATFORM=mtl,NUM_DMICS=4,PDM1_MIC_A_ENABLE=1,PDM1_MIC_B_ENABLE=1,\ From dc606171fb1978a4e274b79c45272dd5ed9e66e6 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Thu, 5 Nov 2026 13:56:36 +0200 Subject: [PATCH 10/10] topology2: uaol: Name the PCMs "USB Offload " The frontend PCMs of the UAOL topologies are named after the link they run on, "UAOL0" and "UAOL1". What the user sees in aplay -l should say what the PCM is for, not which link carries it: "UAOL" is the name of Intel's link in the specifications and in the DAI names, the function is USB audio offload. Name the PCMs "USB Offload 0" and "USB Offload 1", with the deep buffers following as "Deepbuffer USB Offload " like "Deepbuffer HDA Analog" does. This also pairs them by name with the kernel's "USB Offload Playback Route" / "USB Offload Capture Route" controls and the "USB Offload Jack", so that PCM, route control and jack of a stream share one name and the number tells them apart. The mixer volume controls derive their names from the PCM and follow along. The DAI copiers and the backend DAI links keep their UAOL names: those are the link and are matched by the machine driver. Signed-off-by: Peter Ujfalusi --- tools/topology/topology2/cavs-uaol.conf | 16 ++++++++-------- .../development/sof-hda-generic-uaol.conf | 16 ++++++++-------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/tools/topology/topology2/cavs-uaol.conf b/tools/topology/topology2/cavs-uaol.conf index a351ca1e9f7a..85ee38b5401e 100644 --- a/tools/topology/topology2/cavs-uaol.conf +++ b/tools/topology/topology2/cavs-uaol.conf @@ -42,8 +42,8 @@ Define { - UAOL_PLAYBACK_PCM 'UAOL0 Playback' - UAOL_CAPTURE_PCM 'UAOL0 Capture' + UAOL_PLAYBACK_PCM 'USB Offload 0 Playback' + UAOL_CAPTURE_PCM 'USB Offload 0 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, and the # link carries two streams per direction, each with a backend of its @@ -59,7 +59,7 @@ Define { 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 'UAOL0' + UAOL_PCM_NAME 'USB Offload 0' UAOL_PCM_ID 21 UAOL_PB_HOST_PIPELINE_ID 210 UAOL_PB_DAI_PIPELINE_ID 211 @@ -68,13 +68,13 @@ Define { # Second stream pair of the link, on its own PCM UAOL_NUM_STREAMS 2 - UAOL_PLAYBACK1_PCM 'UAOL1 Playback' - UAOL_CAPTURE1_PCM 'UAOL1 Capture' + UAOL_PLAYBACK1_PCM 'USB Offload 1 Playback' + UAOL_CAPTURE1_PCM 'USB Offload 1 Capture' UAOL_PB1_DAI_NAME 'UAOL0-Play1' UAOL_CP1_DAI_NAME 'UAOL0-Cap1' UAOL_PB1_BE_ID 11 UAOL_CP1_BE_ID 12 - UAOL_PCM1_NAME 'UAOL1' + UAOL_PCM1_NAME 'USB Offload 1' UAOL_PCM1_ID 22 UAOL_PB1_HOST_PIPELINE_ID 215 UAOL_PB1_DAI_PIPELINE_ID 216 @@ -94,10 +94,10 @@ Define { # The deep buffer PCMs feed the same mixer as the normal playback PCM of # their stream UAOL_DEEP_BUFFER 'true' - UAOL_DB_PCM_NAME 'Deepbuffer UAOL0' + UAOL_DB_PCM_NAME 'Deepbuffer USB Offload 0' UAOL_DB_PCM_ID 23 UAOL_DB_PIPELINE_ID 214 - UAOL_DB1_PCM_NAME 'Deepbuffer UAOL1' + UAOL_DB1_PCM_NAME 'Deepbuffer USB Offload 1' UAOL_DB1_PCM_ID 24 UAOL_DB1_PIPELINE_ID 219 } diff --git a/tools/topology/topology2/development/sof-hda-generic-uaol.conf b/tools/topology/topology2/development/sof-hda-generic-uaol.conf index bb3ffcd1501b..d997a90210a9 100644 --- a/tools/topology/topology2/development/sof-hda-generic-uaol.conf +++ b/tools/topology/topology2/development/sof-hda-generic-uaol.conf @@ -34,8 +34,8 @@ Define { - UAOL_PLAYBACK_PCM 'UAOL0 Playback' - UAOL_CAPTURE_PCM 'UAOL0 Capture' + UAOL_PLAYBACK_PCM 'USB Offload 0 Playback' + UAOL_CAPTURE_PCM 'USB Offload 0 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, and the # link carries two streams per direction, each with a backend of its @@ -52,7 +52,7 @@ Define { 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 'UAOL0' + UAOL_PCM_NAME 'USB Offload 0' UAOL_PCM_ID 21 UAOL_PB_HOST_PIPELINE_ID 210 UAOL_PB_DAI_PIPELINE_ID 211 @@ -64,13 +64,13 @@ Define { # routes point at it and the second PCM fails with EBUSY while the first # one runs, a second device or a second PCM of the first lets both run UAOL_NUM_STREAMS 2 - UAOL_PLAYBACK1_PCM 'UAOL1 Playback' - UAOL_CAPTURE1_PCM 'UAOL1 Capture' + UAOL_PLAYBACK1_PCM 'USB Offload 1 Playback' + UAOL_CAPTURE1_PCM 'USB Offload 1 Capture' UAOL_PB1_DAI_NAME 'UAOL0-Play1' UAOL_CP1_DAI_NAME 'UAOL0-Cap1' UAOL_PB1_BE_ID 11 UAOL_CP1_BE_ID 12 - UAOL_PCM1_NAME 'UAOL1' + UAOL_PCM1_NAME 'USB Offload 1' UAOL_PCM1_ID 22 UAOL_PB1_HOST_PIPELINE_ID 215 UAOL_PB1_DAI_PIPELINE_ID 216 @@ -90,10 +90,10 @@ Define { # The deep buffer PCMs feed the same mixer as the normal playback PCM of # their stream, next to the one the HDA playback has UAOL_DEEP_BUFFER 'true' - UAOL_DB_PCM_NAME 'Deepbuffer UAOL0' + UAOL_DB_PCM_NAME 'Deepbuffer USB Offload 0' UAOL_DB_PCM_ID 23 UAOL_DB_PIPELINE_ID 214 - UAOL_DB1_PCM_NAME 'Deepbuffer UAOL1' + UAOL_DB1_PCM_NAME 'Deepbuffer USB Offload 1' UAOL_DB1_PCM_ID 24 UAOL_DB1_PIPELINE_ID 219 }