From e63224c394c3f02f0ad417e552683e8648a03ebe Mon Sep 17 00:00:00 2001 From: Richard Fitzgerald Date: Fri, 11 Oct 2024 14:42:31 +0100 Subject: [PATCH] topology2: Support for NUM_SDW_AMP_LINKS=3 aggregation Add cases for NUM_SDW_AMP_LINKS=3 so that speaker playback and capture can be aggregated across 3 SoundWire buses. The target hardware configurations for this is a SmartCodec plus multiple buses of SmartAmps. Typically the codec drives tweeters and the amps drive woofer/midrange. This has been tested with the configuration: SDW0: 2x CS35L56 SDW1: 2x CS35L56 SDW3: CS42L43 with only speaker playback aggregated. It has also been tested with the configuration: SDW0: 2x CS35L56 SDW1: 2x CS35L56 SDW3: 2x CS35L56 with playback and amp feedback aggregated. Signed-off-by: Richard Fitzgerald --- tools/topology/topology2/cavs-sdw.conf | 2 +- .../platform/intel/sdw-amp-generic.conf | 197 ++++++++++++++++++ 2 files changed, 198 insertions(+), 1 deletion(-) diff --git a/tools/topology/topology2/cavs-sdw.conf b/tools/topology/topology2/cavs-sdw.conf index bc4a0a343a74..4e92671cf653 100644 --- a/tools/topology/topology2/cavs-sdw.conf +++ b/tools/topology/topology2/cavs-sdw.conf @@ -107,7 +107,7 @@ IncludeByKey.NUM_HDMIS { } IncludeByKey.NUM_SDW_AMP_LINKS { -"[1-2]" "platform/intel/sdw-amp-generic.conf" +"[1-3]" "platform/intel/sdw-amp-generic.conf" } IncludeByKey.SDW_DMIC { diff --git a/tools/topology/topology2/platform/intel/sdw-amp-generic.conf b/tools/topology/topology2/platform/intel/sdw-amp-generic.conf index 4589484e285f..f0232f71495f 100644 --- a/tools/topology/topology2/platform/intel/sdw-amp-generic.conf +++ b/tools/topology/topology2/platform/intel/sdw-amp-generic.conf @@ -4,7 +4,9 @@ Define { SDW_SPK_STREAM 'SDW1-Playback' SDW_SPK_IN_STREAM 'SDW1-Capture' ALH_2ND_SPK_ID 22 + ALH_3RD_SPK_ID 23 ALH_2ND_SPK_IN_ID 32 + ALH_3RD_SPK_IN_ID 33 SDW_AMP_BE_ID 2 SDW_AMP_IN_BE_ID 3 AMP_FEEDBACK_CH 2 @@ -300,6 +302,201 @@ IncludeByKey.NUM_SDW_AMP_LINKS { } ] } + +"3" { + Define { + AMP_FEEDBACK_CH 6 + AMP_FEEDBACK_CH_PER_LINK 2 + } + + Object.Widget { + alh-copier [ + { + index $ALH_2ND_SPK_ID + type dai_in + stream_name $SDW_SPK_STREAM + dai_index 1 + type "dai_in" + direction "playback" + node_type $ALH_LINK_OUTPUT_CLASS + num_input_audio_formats 1 + num_output_audio_formats 1 + num_input_pins 1 + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth $SDW_LINK_VALID_BITS + out_sample_type $SAMPLE_TYPE_MSB_INTEGER + out_fmt_cfg "$[($out_channels | ($out_valid_bit_depth * 256))]" + } + ] + } + { + index $ALH_3RD_SPK_ID + type dai_in + stream_name $SDW_SPK_STREAM + dai_index 2 + type "dai_in" + direction "playback" + node_type $ALH_LINK_OUTPUT_CLASS + num_input_audio_formats 1 + num_output_audio_formats 1 + num_input_pins 1 + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth $SDW_LINK_VALID_BITS + out_sample_type $SAMPLE_TYPE_MSB_INTEGER + out_fmt_cfg "$[($out_channels | ($out_valid_bit_depth * 256))]" + } + ] + } + ] + IncludeByKey.SDW_AMP_FEEDBACK { + "true" { + alh-copier [ + { + index $ALH_2ND_SPK_IN_ID + type dai_out + stream_name $SDW_SPK_IN_STREAM + dai_index 1 + type "dai_out" + direction "capture" + node_type $ALH_LINK_INPUT_CLASS + num_input_audio_formats 1 + num_output_audio_formats 1 + num_output_pins 1 + + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth $SDW_LINK_VALID_BITS + in_sample_type $SAMPLE_TYPE_MSB_INTEGER + in_fmt_cfg "$[($in_channels | ($in_valid_bit_depth * 256))]" + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + ] + } + { + index $ALH_3RD_SPK_IN_ID + type dai_out + stream_name $SDW_SPK_IN_STREAM + dai_index 2 + type "dai_out" + direction "capture" + node_type $ALH_LINK_INPUT_CLASS + num_input_audio_formats 1 + num_output_audio_formats 1 + num_output_pins 1 + + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth $SDW_LINK_VALID_BITS + in_sample_type $SAMPLE_TYPE_MSB_INTEGER + in_fmt_cfg "$[($in_channels | ($in_valid_bit_depth * 256))]" + } + ] + Object.Base.output_audio_format [ + { + out_bit_depth 32 + out_valid_bit_depth 32 + } + ] + } + ] + } + } + pipeline [ + { + index $ALH_2ND_SPK_ID + priority 0 + lp_mode 0 + dynamic_pipeline 1 + } + { + index $ALH_3RD_SPK_ID + priority 0 + lp_mode 0 + dynamic_pipeline 1 + } + { + index $ALH_2ND_SPK_IN_ID + priority 0 + lp_mode 0 + dynamic_pipeline 1 + } + { + index $ALH_3RD_SPK_IN_ID + priority 0 + lp_mode 0 + dynamic_pipeline 1 + } + ] + virtual [ + { + name 'virtual.sdw-amp' + type output + index $ALH_2ND_SPK_ID + } + { + name 'virtual.sdw-amp' + type output + index $ALH_3RD_SPK_ID + } + ] + } + + # Add the connection from the gain module to the aggregated 2nd DAI copier + # via the virtual widget. The virtual widget ensures that the routes between + # the gain and copier do not get established in the firmware. These are purely + # to show the existence of aggregation in the topology graph. + IncludeByKey.PASSTHROUGH { + "false" { + Object.Base.route [ + { + source "gain.21.1" + sink "virtual.sdw-amp" + } + ] + } + "true" { + Object.Base.route [ + { + source "host-copier.2.playback" + sink "virtual.sdw-amp" + } + ] + } + } + Object.Base.route [ + { + source "virtual.sdw-amp" + sink "alh-copier.$SDW_SPK_STREAM.1" + } + { + source "virtual.sdw-amp" + sink "alh-copier.$SDW_SPK_STREAM.2" + } + ] + } } Object.PCM.pcm [