diff --git a/src/audio/eq_iir/tune/sof_example_lr4.m b/src/audio/eq_iir/tune/sof_example_lr4.m new file mode 100644 index 000000000000..d38111da6b98 --- /dev/null +++ b/src/audio/eq_iir/tune/sof_example_lr4.m @@ -0,0 +1,183 @@ +% sof_example_lr4 - Design 4th order Linkwitz–Riley filter bank +% +% This script is run without arguments. It creates IIR equalizer +% blobs for crossover filter bank for 2-way speaker and four +% channels stream. The exported configurations are Linkwitz-Riley +% 4th order with crossover frequency at 2 kHz. The filters are +% in order: +% - low, high, low, high +% - low, low, high, high +% - high, high, low, low +% + +% SPDX-License-Identifier: BSD-3-Clause +% +% Copyright (c) 2025, Intel Corporation. +% +% Author: Seppo Ingalsuo + +function sof_example_lr4() + +%% Common definitions +fs = 48e3; +fc = 2e3; +sof_tools = '../../../../tools'; +tpath = fullfile(sof_tools, 'topology/topology2/include/components/eqiir'); +cpath = fullfile(sof_tools, 'ctl/ipc4/eq_iir'); + +sof_eq_paths(1); + +%% -------------------------------------------------- +%% Example: Band-split 2ch to 4ch low and high bands +%% -------------------------------------------------- +design_name = sprintf('xover_lr4_%dhz_lhlh_%dkhz', fc, round(fs/1000)); +blob_fn = fullfile(cpath, [design_name '.bin']); +alsa_fn = fullfile(cpath, [design_name '.txt']); +tplg_fn = fullfile(tpath, [design_name '.conf']); +comment = 'LR4 filter bank coefficients'; +howto = 'cd src/audio/eq_iir/tune; octave sof_example_lr4.m'; + +% Design low-pass and high-pass filters +eq_lo = lo_band_iir(fs, fc); +eq_hi = hi_band_iir(fs, fc); + +% Quantize and pack filter coefficients plus shifts etc. +bq_lo = sof_eq_iir_blob_quant(eq_lo.p_z, eq_lo.p_p, eq_lo.p_k); +bq_hi = sof_eq_iir_blob_quant(eq_hi.p_z, eq_hi.p_p, eq_hi.p_k); + +% Build blob +channels_in_config = 4; % Setup max 4 channels EQ +assign_response = [0 1 0 1]; % Order: lo, hi, lo, hi +num_responses = 2; % Two responses: lo, hi +bm = sof_eq_iir_blob_merge(channels_in_config, ... + num_responses, ... + assign_response, ... + [bq_lo bq_hi]); + +% Pack and write file +sof_eq_pack_export(bm, blob_fn, alsa_fn, tplg_fn, comment, howto) + +%% -------------------------------------------------- +%% Example: Same but filters order is lo, lo, hi, hi +%% -------------------------------------------------- + +design_name = sprintf('xover_lr4_%dhz_llhh_%dkhz', fc, round(fs/1000)); +blob_fn = fullfile(cpath, [design_name '.bin']); +alsa_fn = fullfile(cpath, [design_name '.txt']); +tplg_fn = fullfile(tpath, [design_name '.conf']); + +assign_response = [0 0 1 1]; +num_responses = 2; +bm = sof_eq_iir_blob_merge(channels_in_config, ... + num_responses, ... + assign_response, ... + [bq_lo bq_hi]); + +% Pack and write file +sof_eq_pack_export(bm, blob_fn, alsa_fn, tplg_fn, comment, howto) + +%% -------------------------------------------------- +%% Example: Same but filters order is hi, hi, lo, lo +%% -------------------------------------------------- + +design_name = sprintf('xover_lr4_%dhz_hhll_%dkhz', fc, round(fs/1000)); +blob_fn = fullfile(cpath, [design_name '.bin']); +alsa_fn = fullfile(cpath, [design_name '.txt']); +tplg_fn = fullfile(tpath, [design_name '.conf']); + +assign_response = [1 1 0 0]; +num_responses = 2; +bm = sof_eq_iir_blob_merge(channels_in_config, ... + num_responses, ... + assign_response, ... + [bq_lo bq_hi]); + +% Pack and write file +sof_eq_pack_export(bm, blob_fn, alsa_fn, tplg_fn, comment, howto) + +%% ------------------------------------ +%% Done. +%% ------------------------------------ + +sof_eq_paths(0); +end + +%% ------------------- +%% EQ design functions +%% ------------------- + +function eq = lo_band_iir(fs, fc) + + +%% Get defaults for equalizer design +eq = sof_eq_defaults(); +eq.fs = fs; +eq.enable_iir = 1; +eq.iir_norm_type = 'peak'; +eq.iir_norm_offs_db = 0; + +% Parametric EQs are PEQ_HP1, PEQ_HP2, PEQ_LP1, PEQ_LP2, PEQ_LS1, +% PEQ_LS2, PEQ_HS1, PEQ_HS2 = 8, PEQ_PN2, PEQ_LP4, and PEQ_HP4. +% +% Parametric EQs take as second argument the cutoff frequency in Hz +% and as second argument a dB value (can use 0 for LP2). The +% Third argument is a Q-value (can use 0 for LP2). + +% Two 2nd order butterworth low-pass filters for 4th order Linkwitz–Riley +eq.peq = [ ... + eq.PEQ_LP2 fc 0 0 ; ... + eq.PEQ_LP2 fc 0 0 ; ... + ]; + +%% Design EQ +eq = sof_eq_compute(eq); + +%% Plot +sof_eq_plot(eq); + +end + +function eq = hi_band_iir(fs, fc) + + +%% Get defaults for equalizer design +eq = sof_eq_defaults(); +eq.fs = fs; +eq.enable_iir = 1; +eq.iir_norm_type = 'peak'; +eq.iir_norm_offs_db = 0; + +% Two 2nd order high-pass filters for 4th order Linkwitz–Riley +eq.peq = [ ... + eq.PEQ_HP2 fc 0 0 ; ... + eq.PEQ_HP2 fc 0 0 ; ... + ]; + +%% Design EQ +eq = sof_eq_compute(eq); + +%% Plot +sof_eq_plot(eq); + +end + + + +% Pack and write file common function for all exports +function sof_eq_pack_export(bm, bin_fn, ascii_fn, tplg_fn, note, howto) + +bp = sof_eq_iir_blob_pack(bm, 4); % IPC4 + +if ~isempty(bin_fn) + sof_ucm_blob_write(bin_fn, bp); +end + +if ~isempty(ascii_fn) + sof_alsactl_write(ascii_fn, bp); +end + +if ~isempty(tplg_fn) + sof_tplg2_write(tplg_fn, bp, 'IIR', note, howto); +end + +end diff --git a/src/audio/selector/tune/sof_selector_blobs.m b/src/audio/selector/tune/sof_selector_blobs.m index 10ea1879b74a..83b38be64e3e 100644 --- a/src/audio/selector/tune/sof_selector_blobs.m +++ b/src/audio/selector/tune/sof_selector_blobs.m @@ -1,4 +1,13 @@ -% Export configuration blobs for Selector +% sof_selector_blobs - export configuration blobs for Selector +% +% This script is run without arguments. It exports a number of +% configuration blobs for selector/micsel component. The first +% category of blobs are for upmix and downmix between mono to +% 7.1 channel audio formats. +% +% The second category is for duplicating stereo to four channels +% for 2-way speaker crossover filter. +% % SPDX-License-Identifier: BSD-3-Clause % @@ -97,6 +106,39 @@ function sof_selector_blobs() write_blob(sel, "upmix_stereo_to_51"); write_blob(sel, "upmix_stereo_to_71"); + % Stereo to L,L,R,R + sel.coeffs = [ 1 0 0 0 0 0 0 0 ; ... + 1 0 0 0 0 0 0 0 ; ... + 0 1 0 0 0 0 0 0 ; ... + 0 1 0 0 0 0 0 0 ; ... + 0 0 0 0 0 0 0 0 ; ... + 0 0 0 0 0 0 0 0 ; ... + 0 0 0 0 0 0 0 0 ; ... + 0 0 0 0 0 0 0 0 ]; + write_blob(sel, "xover_selector_lr_to_llrr"); + + % Stereo to R,R,L,L + sel.coeffs = [ 0 1 0 0 0 0 0 0 ; ... + 0 1 0 0 0 0 0 0 ; ... + 1 0 0 0 0 0 0 0 ; ... + 1 0 0 0 0 0 0 0 ; ... + 0 0 0 0 0 0 0 0 ; ... + 0 0 0 0 0 0 0 0 ; ... + 0 0 0 0 0 0 0 0 ; ... + 0 0 0 0 0 0 0 0 ]; + write_blob(sel, "xover_selector_lr_to_rrll"); + + % Stereo to L,R,L,R + sel.coeffs = [ 1 0 0 0 0 0 0 0 ; ... + 0 1 0 0 0 0 0 0 ; ... + 1 0 0 0 0 0 0 0 ; ... + 0 1 0 0 0 0 0 0 ; ... + 0 0 0 0 0 0 0 0 ; ... + 0 0 0 0 0 0 0 0 ; ... + 0 0 0 0 0 0 0 0 ; ... + 0 0 0 0 0 0 0 0 ]; + write_blob(sel, "xover_selector_lr_to_lrlr"); + sof_selector_paths(false); end diff --git a/tools/topology/topology2/cavs-sdw.conf b/tools/topology/topology2/cavs-sdw.conf index 4a88c4bd0bad..25b30c227885 100644 --- a/tools/topology/topology2/cavs-sdw.conf +++ b/tools/topology/topology2/cavs-sdw.conf @@ -13,7 +13,9 @@ + + @@ -92,6 +94,11 @@ Define { EFX_MIC_TDFB_PARAMS "line2_generic_pm10deg" EFX_MIC_DRC_PARAMS "dmic_default" DMIC0_DAI_EQIIR "highpass_40hz_20db" + SDW_AMP_NUM_CHANNELS 2 + SDW_AMP_XOVER false + SDW_AMP_XOVER_SELECTOR_PARAMS default + SDW_AMP_XOVER_EQIIR_PARAMS default + SDW_AMP_XOVER_EQFIR_PARAMS default } # override defaults with platform-specific config @@ -119,8 +126,17 @@ IncludeByKey.NUM_HDMIS { "[3-4]" "platform/intel/hdmi-generic.conf" } -IncludeByKey.NUM_SDW_AMP_LINKS { -"[1-3]" "platform/intel/sdw-amp-generic.conf" +IncludeByKey.SDW_AMP_XOVER { + "false" { + IncludeByKey.NUM_SDW_AMP_LINKS { + "[1-3]" "platform/intel/sdw-amp-generic.conf" + } + } + "true" { + IncludeByKey.NUM_SDW_AMP_LINKS { + "[1-3]" "platform/intel/sdw-amp-xover.conf" + } + } } IncludeByKey.SDW_DMIC { diff --git a/tools/topology/topology2/include/components/eqiir/xover_lr4_2000hz_hhll_48khz.conf b/tools/topology/topology2/include/components/eqiir/xover_lr4_2000hz_hhll_48khz.conf new file mode 100644 index 000000000000..8338a33decb2 --- /dev/null +++ b/tools/topology/topology2/include/components/eqiir/xover_lr4_2000hz_hhll_48khz.conf @@ -0,0 +1,35 @@ +# LR4 filter bank coefficients 08-Sep-2025 +# cd src/audio/eq_iir/tune; octave sof_example_lr4.m +Object.Base.data."IIR" { + bytes " + 0x53,0x4f,0x46,0x34,0x00,0x00,0x00,0x00, + 0xcc,0x00,0x00,0x00,0x01,0xd0,0x01,0x03, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xcc,0x00,0x00,0x00,0x04,0x00,0x00,0x00, + 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00, + 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00, + 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x2d,0x3a,0xcd,0xd3, + 0xc0,0xf5,0x82,0x68,0xb9,0x41,0x76,0x00, + 0x72,0x83,0xec,0x00,0xb9,0x41,0x76,0x00, + 0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00, + 0x2d,0x3a,0xcd,0xd3,0xc0,0xf5,0x82,0x68, + 0xb9,0x41,0x76,0x00,0x72,0x83,0xec,0x00, + 0xb9,0x41,0x76,0x00,0xff,0xff,0xff,0xff, + 0x65,0x7f,0x00,0x00,0x02,0x00,0x00,0x00, + 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x7e,0x70,0xdd,0xd6, + 0xc0,0xf5,0x82,0x68,0xb6,0x9e,0x44,0x1a, + 0x94,0xc2,0x76,0xcb,0xb6,0x9e,0x44,0x1a, + 0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00, + 0x7e,0x70,0xdd,0xd6,0xc0,0xf5,0x82,0x68, + 0xb6,0x9e,0x44,0x1a,0x94,0xc2,0x76,0xcb, + 0xb6,0x9e,0x44,0x1a,0xfe,0xff,0xff,0xff, + 0x92,0x41,0x00,0x00" +} diff --git a/tools/topology/topology2/include/components/eqiir/xover_lr4_2000hz_lhlh_48khz.conf b/tools/topology/topology2/include/components/eqiir/xover_lr4_2000hz_lhlh_48khz.conf new file mode 100644 index 000000000000..a7c04f3372a7 --- /dev/null +++ b/tools/topology/topology2/include/components/eqiir/xover_lr4_2000hz_lhlh_48khz.conf @@ -0,0 +1,35 @@ +# LR4 filter bank coefficients 08-Sep-2025 +# cd src/audio/eq_iir/tune; octave sof_example_lr4.m +Object.Base.data."IIR" { + bytes " + 0x53,0x4f,0x46,0x34,0x00,0x00,0x00,0x00, + 0xcc,0x00,0x00,0x00,0x01,0xd0,0x01,0x03, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xcc,0x00,0x00,0x00,0x04,0x00,0x00,0x00, + 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x00,0x00,0x00,0x02,0x00,0x00,0x00, + 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x2d,0x3a,0xcd,0xd3, + 0xc0,0xf5,0x82,0x68,0xb9,0x41,0x76,0x00, + 0x72,0x83,0xec,0x00,0xb9,0x41,0x76,0x00, + 0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00, + 0x2d,0x3a,0xcd,0xd3,0xc0,0xf5,0x82,0x68, + 0xb9,0x41,0x76,0x00,0x72,0x83,0xec,0x00, + 0xb9,0x41,0x76,0x00,0xff,0xff,0xff,0xff, + 0x65,0x7f,0x00,0x00,0x02,0x00,0x00,0x00, + 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x7e,0x70,0xdd,0xd6, + 0xc0,0xf5,0x82,0x68,0xb6,0x9e,0x44,0x1a, + 0x94,0xc2,0x76,0xcb,0xb6,0x9e,0x44,0x1a, + 0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00, + 0x7e,0x70,0xdd,0xd6,0xc0,0xf5,0x82,0x68, + 0xb6,0x9e,0x44,0x1a,0x94,0xc2,0x76,0xcb, + 0xb6,0x9e,0x44,0x1a,0xfe,0xff,0xff,0xff, + 0x92,0x41,0x00,0x00" +} diff --git a/tools/topology/topology2/include/components/eqiir/xover_lr4_2000hz_llhh_48khz.conf b/tools/topology/topology2/include/components/eqiir/xover_lr4_2000hz_llhh_48khz.conf new file mode 100644 index 000000000000..8612f617c9be --- /dev/null +++ b/tools/topology/topology2/include/components/eqiir/xover_lr4_2000hz_llhh_48khz.conf @@ -0,0 +1,35 @@ +# LR4 filter bank coefficients 08-Sep-2025 +# cd src/audio/eq_iir/tune; octave sof_example_lr4.m +Object.Base.data."IIR" { + bytes " + 0x53,0x4f,0x46,0x34,0x00,0x00,0x00,0x00, + 0xcc,0x00,0x00,0x00,0x01,0xd0,0x01,0x03, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0xcc,0x00,0x00,0x00,0x04,0x00,0x00,0x00, + 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00, + 0x01,0x00,0x00,0x00,0x02,0x00,0x00,0x00, + 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x2d,0x3a,0xcd,0xd3, + 0xc0,0xf5,0x82,0x68,0xb9,0x41,0x76,0x00, + 0x72,0x83,0xec,0x00,0xb9,0x41,0x76,0x00, + 0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00, + 0x2d,0x3a,0xcd,0xd3,0xc0,0xf5,0x82,0x68, + 0xb9,0x41,0x76,0x00,0x72,0x83,0xec,0x00, + 0xb9,0x41,0x76,0x00,0xff,0xff,0xff,0xff, + 0x65,0x7f,0x00,0x00,0x02,0x00,0x00,0x00, + 0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x7e,0x70,0xdd,0xd6, + 0xc0,0xf5,0x82,0x68,0xb6,0x9e,0x44,0x1a, + 0x94,0xc2,0x76,0xcb,0xb6,0x9e,0x44,0x1a, + 0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00, + 0x7e,0x70,0xdd,0xd6,0xc0,0xf5,0x82,0x68, + 0xb6,0x9e,0x44,0x1a,0x94,0xc2,0x76,0xcb, + 0xb6,0x9e,0x44,0x1a,0xfe,0xff,0xff,0xff, + 0x92,0x41,0x00,0x00" +} diff --git a/tools/topology/topology2/include/components/micsel/xover_selector_lr_to_llrr.conf b/tools/topology/topology2/include/components/micsel/xover_selector_lr_to_llrr.conf new file mode 100644 index 000000000000..4b4be2b34840 --- /dev/null +++ b/tools/topology/topology2/include/components/micsel/xover_selector_lr_to_llrr.conf @@ -0,0 +1,26 @@ +# Exported with script sof_selector_blobs.m 08-Sep-2025 +# cd tools/tune/selector; octave sof_selector_blobs.m +Object.Base.data."selector_config" { + bytes " + 0x53,0x4f,0x46,0x34,0x00,0x00,0x00,0x00, + 0x84,0x00,0x00,0x00,0x01,0xd0,0x01,0x03, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00" +} diff --git a/tools/topology/topology2/include/components/micsel/xover_selector_lr_to_lrlr.conf b/tools/topology/topology2/include/components/micsel/xover_selector_lr_to_lrlr.conf new file mode 100644 index 000000000000..70489a0a0040 --- /dev/null +++ b/tools/topology/topology2/include/components/micsel/xover_selector_lr_to_lrlr.conf @@ -0,0 +1,26 @@ +# Exported with script sof_selector_blobs.m 08-Sep-2025 +# cd tools/tune/selector; octave sof_selector_blobs.m +Object.Base.data."selector_config" { + bytes " + 0x53,0x4f,0x46,0x34,0x00,0x00,0x00,0x00, + 0x84,0x00,0x00,0x00,0x01,0xd0,0x01,0x03, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00" +} diff --git a/tools/topology/topology2/include/components/micsel/xover_selector_lr_to_rrll.conf b/tools/topology/topology2/include/components/micsel/xover_selector_lr_to_rrll.conf new file mode 100644 index 000000000000..d88ba2063cd6 --- /dev/null +++ b/tools/topology/topology2/include/components/micsel/xover_selector_lr_to_rrll.conf @@ -0,0 +1,26 @@ +# Exported with script sof_selector_blobs.m 08-Sep-2025 +# cd tools/tune/selector; octave sof_selector_blobs.m +Object.Base.data."selector_config" { + bytes " + 0x53,0x4f,0x46,0x34,0x00,0x00,0x00,0x00, + 0x84,0x00,0x00,0x00,0x01,0xd0,0x01,0x03, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00" +} diff --git a/tools/topology/topology2/include/pipelines/cavs/mixout-gain-eqiir-eqfir-drc-micsel-eqiir-eqfir-alh-dai-copier-playback.conf b/tools/topology/topology2/include/pipelines/cavs/mixout-gain-eqiir-eqfir-drc-micsel-eqiir-eqfir-alh-dai-copier-playback.conf new file mode 100644 index 000000000000..cc95dd9799a7 --- /dev/null +++ b/tools/topology/topology2/include/pipelines/cavs/mixout-gain-eqiir-eqfir-drc-micsel-eqiir-eqfir-alh-dai-copier-playback.conf @@ -0,0 +1,132 @@ +# +# BE playback pipeline: mixout-gain-eqiir-eqfir-drc-micsel-eqiir-eqfir-alh-dai-copier. +# +# All attributes defined herein are namespaced +# by alsatplg to "Object.Pipeline.mixout-gain-eqiir-eqfir-drc-micsel-eqiir-eqfir-alh-dai-copier-playback.N.attribute_name" +# +# Usage: mixout-gain-eqiir-eqfir-drc-micsel-eqiir-eqfir-alh-dai-copier-playback pipeline object can be instantiated as: +# +# Object.Pipeline.mixout-gain-eqiir-eqfir-drc-micsel-eqiir-eqfir-alh-dai-copier-playback."N" { +# time_domain "timer" +# } +# +# Where N is the unique pipeline ID within the same alsaconf node. +# + + + + +Class.Pipeline."mixout-gain-eqiir-eqfir-drc-micsel-eqiir-eqfir-alh-dai-copier-playback" { + + SubTreeCopy.baseclass { + # this class extends the pipeline class. + source "Class.Pipeline.mixout-gain-eqiir-eqfir-drc-alh-dai-copier-playback" + + # target node is not defined which means that the new subtree will be copied to + # the parent node containing the SubTreeCopy node i.e in this case the + # Class.Pipeline.mixout-gain-eqiir-eqfir-drc-micsel-eqiir-eqfir-alh-dai-copier-playback {} node. + + # default copy type is to extend the base class ie the widgets and routes + # will be added to the existing list of widgets/routes in the base class + + tree { + Object.Widget { + micsel."1" { + num_input_audio_formats 1 + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + num_output_audio_formats 1 + Object.Base.output_audio_format [ + { + out_channels $SDW_AMP_NUM_CHANNELS + out_bit_depth 32 + out_valid_bit_depth 32 + } + ] + Object.Control { + bytes."1" { + IncludeByKey.SDW_AMP_XOVER_SELECTOR_PARAMS { + "default" "include/components/micsel/passthrough.conf" + "xover_selector_lr_to_llrr" "include/components/micsel/xover_selector_lr_to_llrr.conf" + "xover_selector_lr_to_lrlr" "include/components/micsel/xover_selector_lr_to_lrlr.conf" + } + } + } + } + + eqiir."2" { + num_input_audio_formats 1 + Object.Base.input_audio_format [ + { + in_channels $SDW_AMP_NUM_CHANNELS + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + num_output_audio_formats 1 + Object.Base.output_audio_format [ + { + out_channels $SDW_AMP_NUM_CHANNELS + out_bit_depth 32 + out_valid_bit_depth 32 + } + ] + Object.Control.bytes."1" { + IncludeByKey.SDW_AMP_XOVER_EQIIR_PARAMS { + "default" "include/components/eqiir/passthrough.conf" + "xover_lr4_2000hz_lhlh_48khz" "include/components/eqiir/xover_lr4_2000hz_lhlh_48khz.conf" + "xover_lr4_2000hz_llhh_48khz" "include/components/eqiir/xover_lr4_2000hz_llhh_48khz.conf" + "xover_lr4_2000hz_hhll_48khz" "include/components/eqiir/xover_lr4_2000hz_hhll_48khz.conf" + } + } + } + eqfir."2" { + num_input_audio_formats 1 + Object.Base.input_audio_format [ + { + in_channels $SDW_AMP_NUM_CHANNELS + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + num_output_audio_formats 1 + Object.Base.output_audio_format [ + { + out_channels $SDW_AMP_NUM_CHANNELS + out_bit_depth 32 + out_valid_bit_depth 32 + } + ] + Object.Control.bytes."1" { + IncludeByKey.SDW_AMP_XOVER_EQFIR_PARAMS { + "default" "include/components/eqfir/passthrough.conf" + "xover_dd00_100us_48khz.conf" "include/components/eqfir/xover_dd00_100us_48khz.conf" + "xover_00dd_100us_48khz.conf" "include/components/eqfir/xover_00dd_100us_48khz.conf" + } + } + } + } + + Object.Base { + !route [ + { + source drc.$index.1 + sink micsel.$index.1 + } + { + source micsel.$index.1 + sink eqiir.$index.2 + } + { + source eqiir.$index.2 + sink eqfir.$index.2 + } + ] + } + } + } +} diff --git a/tools/topology/topology2/include/pipelines/cavs/mixout-gain-micsel-eqiir-eqfir-alh-dai-copier-playback.conf b/tools/topology/topology2/include/pipelines/cavs/mixout-gain-micsel-eqiir-eqfir-alh-dai-copier-playback.conf new file mode 100644 index 000000000000..a12503d5d83a --- /dev/null +++ b/tools/topology/topology2/include/pipelines/cavs/mixout-gain-micsel-eqiir-eqfir-alh-dai-copier-playback.conf @@ -0,0 +1,132 @@ +# +# BE playback pipeline: mixout-gain-micsel-eqiir-eqfir-alh-dai-copier. +# +# All attributes defined herein are namespaced +# by alsatplg to "Object.Pipeline.mixout-gain-micsel-eqiir-eqfir-alh-dai-copier-playback.N.attribute_name" +# +# Usage: mixout-gain-micsel-eqiir-eqfir-alh-dai-copier-playback pipeline object can be instantiated as: +# +# Object.Pipeline.mixout-gain-micsel-eqiir-eqfir-alh-dai-copier-playback."N" { +# time_domain "timer" +# } +# +# Where N is the unique pipeline ID within the same alsaconf node. +# + + + + +Class.Pipeline."mixout-gain-micsel-eqiir-eqfir-alh-dai-copier-playback" { + + SubTreeCopy.baseclass { + # this class extends the pipeline class. + source "Class.Pipeline.mixout-gain-alh-dai-copier-playback" + + # target node is not defined which means that the new subtree will be copied to + # the parent node containing the SubTreeCopy node i.e in this case the + # Class.Pipeline.mixout-gain-micsel-eqiir-eqfir-alh-dai-copier-playback {} node. + + # default copy type is to extend the base class ie the widgets and routes + # will be added to the existing list of widgets/routes in the base class + + tree { + Object.Widget { + micsel."1" { + num_input_audio_formats 1 + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + num_output_audio_formats 1 + Object.Base.output_audio_format [ + { + out_channels $SDW_AMP_NUM_CHANNELS + out_bit_depth 32 + out_valid_bit_depth 32 + } + ] + Object.Control { + bytes."1" { + IncludeByKey.SDW_AMP_XOVER_SELECTOR_PARAMS { + "default" "include/components/micsel/passthrough.conf" + "xover_selector_lr_to_llrr" "include/components/micsel/xover_selector_lr_to_llrr.conf" + "xover_selector_lr_to_lrlr" "include/components/micsel/xover_selector_lr_to_lrlr.conf" + } + } + } + } + + eqiir."2" { + num_input_audio_formats 1 + Object.Base.input_audio_format [ + { + in_channels $SDW_AMP_NUM_CHANNELS + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + num_output_audio_formats 1 + Object.Base.output_audio_format [ + { + out_channels $SDW_AMP_NUM_CHANNELS + out_bit_depth 32 + out_valid_bit_depth 32 + } + ] + Object.Control.bytes."1" { + IncludeByKey.SDW_AMP_XOVER_EQIIR_PARAMS { + "default" "include/components/eqiir/passthrough.conf" + "xover_lr4_2000hz_lhlh_48khz" "include/components/eqiir/xover_lr4_2000hz_lhlh_48khz.conf" + "xover_lr4_2000hz_llhh_48khz" "include/components/eqiir/xover_lr4_2000hz_llhh_48khz.conf" + "xover_lr4_2000hz_hhll_48khz" "include/components/eqiir/xover_lr4_2000hz_hhll_48khz.conf" + } + } + } + eqfir."2" { + num_input_audio_formats 1 + Object.Base.input_audio_format [ + { + in_channels $SDW_AMP_NUM_CHANNELS + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + num_output_audio_formats 1 + Object.Base.output_audio_format [ + { + out_channels $SDW_AMP_NUM_CHANNELS + out_bit_depth 32 + out_valid_bit_depth 32 + } + ] + Object.Control.bytes."1" { + IncludeByKey.SDW_AMP_XOVER_EQFIR_PARAMS { + "default" "include/components/eqfir/passthrough.conf" + "xover_dd00_100us_48khz.conf" "include/components/eqfir/xover_dd00_100us_48khz.conf" + "xover_00dd_100us_48khz.conf" "include/components/eqfir/xover_00dd_100us_48khz.conf" + } + } + } + } + + Object.Base { + !route [ + { + source gain.$index.1 + sink micsel.$index.1 + } + { + source micsel.$index.1 + sink eqiir.$index.2 + } + { + source eqiir.$index.2 + sink eqfir.$index.2 + } + ] + } + } + } +} diff --git a/tools/topology/topology2/platform/intel/sdw-amp-xover.conf b/tools/topology/topology2/platform/intel/sdw-amp-xover.conf new file mode 100644 index 000000000000..3347d4911bc4 --- /dev/null +++ b/tools/topology/topology2/platform/intel/sdw-amp-xover.conf @@ -0,0 +1,1003 @@ +# route and pipeline index start from pcm id * 10 + +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 + AMP_FEEDBACK_CH_PER_LINK 2 + SDW_AMP_FEEDBACK true + AMP_PLAYBACK_NAME 'Speaker Playback' +} + +Object.Dai.ALH [ + { + dai_index 20 + id $SDW_AMP_BE_ID + direction "playback" + name $SDW_SPK_STREAM + default_hw_conf_id 0 + rate 48000 + + Object.Base.hw_config.1 { + id 0 + name "ALH514" + } + } +] + +Object.Pipeline { + host-copier-gain-mixin-playback [ + { + index 20 + + Object.Widget.host-copier.1 { + stream_name "sdw amplifiers" + pcm_id 2 + } + Object.Widget.gain.1 { + Object.Control.mixer.1 { + name 'Pre Mixer $AMP_PLAYBACK_NAME Volume' + } + } + } + ] + + IncludeByKey.SDW_SPK_ENHANCED_PLAYBACK { + "true" { + mixout-gain-eqiir-eqfir-drc-micsel-eqiir-eqfir-alh-dai-copier-playback [ + { + index 21 + Object.Widget.alh-copier.1 { + stream_name $SDW_SPK_STREAM + node_type $ALH_LINK_OUTPUT_CLASS + num_input_audio_formats 1 + Object.Base.input_audio_format [ + { + in_channels $SDW_AMP_NUM_CHANNELS + IncludeByKey.SDW_AMP_NUM_CHANNELS { + "2" { + in_ch_cfg $CHANNEL_CONFIG_STEREO + in_ch_map $CHANNEL_MAP_STEREO + } + "4" { + in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + in_ch_map $CHANNEL_MAP_3_POINT_1 + } + } + in_bit_depth 32 + in_valid_bit_depth 32 + in_fmt_cfg "$[($in_channels | ($in_valid_bit_depth * 256))]" + } + ] + num_output_audio_formats 1 + Object.Base.output_audio_format [ + { + out_channels $SDW_AMP_NUM_CHANNELS + IncludeByKey.SDW_AMP_NUM_CHANNELS { + "2" { + out_ch_cfg $CHANNEL_CONFIG_STEREO + out_ch_map $CHANNEL_MAP_STEREO + } + "4" { + out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + out_ch_map $CHANNEL_MAP_3_POINT_1 + } + } + 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))]" + } + ] + } + Object.Widget.gain.1 { + Object.Control.mixer.1 { + name 'Post Mixer $AMP_PLAYBACK_NAME Volume' + } + } + Object.Widget.eqiir.1 { + Object.Control.bytes."1" { + name 'Post Mixer $AMP_PLAYBACK_NAME IIR Eq bytes' + } + } + Object.Widget.eqfir.1 { + Object.Control.bytes."1" { + name 'Post Mixer $AMP_PLAYBACK_NAME FIR Eq bytes' + } + } + Object.Widget.drc.1 { + Object.Control { + bytes."1" { + name 'Post Mixer $AMP_PLAYBACK_NAME DRC bytes' + } + mixer."1" { + name 'Post Mixer $AMP_PLAYBACK_NAME DRC switch' + } + } + } + Object.Widget.micsel.1 { + num_input_audio_formats 1 + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + num_output_audio_formats 1 + Object.Base.output_audio_format [ + { + IncludeByKey.SDW_AMP_NUM_CHANNELS { + "2" { + out_ch_cfg $CHANNEL_CONFIG_STEREO + out_ch_map $CHANNEL_MAP_STEREO + } + "4" { + out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + out_ch_map $CHANNEL_MAP_3_POINT_1 + } + } + out_channels $SDW_AMP_NUM_CHANNELS + out_bit_depth 32 + out_valid_bit_depth 32 + } + ] + + Object.Control.bytes."1" { + name 'Post Mixer $AMP_PLAYBACK_NAME Xover Selector bytes' + } + } + Object.Widget.eqiir.2 { + num_input_audio_formats 1 + Object.Base.input_audio_format [ + { + IncludeByKey.SDW_AMP_NUM_CHANNELS { + "2" { + in_ch_cfg $CHANNEL_CONFIG_STEREO + in_ch_map $CHANNEL_MAP_STEREO + } + "4" { + in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + in_ch_map $CHANNEL_MAP_3_POINT_1 + } + } + in_channels $SDW_AMP_NUM_CHANNELS + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + num_output_audio_formats 1 + Object.Base.output_audio_format [ + { + IncludeByKey.SDW_AMP_NUM_CHANNELS { + "2" { + out_ch_cfg $CHANNEL_CONFIG_STEREO + out_ch_map $CHANNEL_MAP_STEREO + } + "4" { + out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + out_ch_map $CHANNEL_MAP_3_POINT_1 + } + } + out_channels $SDW_AMP_NUM_CHANNELS + out_bit_depth 32 + out_valid_bit_depth 32 + } + ] + Object.Control.bytes."1" { + name 'Post Mixer $AMP_PLAYBACK_NAME Xover IIR bytes' + } + } + Object.Widget.eqfir.2 { + num_input_audio_formats 1 + Object.Base.input_audio_format [ + { + IncludeByKey.SDW_AMP_NUM_CHANNELS { + "2" { + in_ch_cfg $CHANNEL_CONFIG_STEREO + in_ch_map $CHANNEL_MAP_STEREO + } + "4" { + in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + in_ch_map $CHANNEL_MAP_3_POINT_1 + } + } + in_channels $SDW_AMP_NUM_CHANNELS + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + num_output_audio_formats 1 + Object.Base.output_audio_format [ + { + IncludeByKey.SDW_AMP_NUM_CHANNELS { + "2" { + out_ch_cfg $CHANNEL_CONFIG_STEREO + out_ch_map $CHANNEL_MAP_STEREO + } + "4" { + out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + out_ch_map $CHANNEL_MAP_3_POINT_1 + } + } + out_channels $SDW_AMP_NUM_CHANNELS + out_bit_depth 32 + out_valid_bit_depth 32 + } + ] + Object.Control.bytes."1" { + name 'Post Mixer $AMP_PLAYBACK_NAME Xover FIR bytes' + } + } + } + ] + } + "false" { + mixout-gain-micsel-eqiir-eqfir-alh-dai-copier-playback [ + { + index 21 + Object.Widget.alh-copier.1 { + stream_name $SDW_SPK_STREAM + node_type $ALH_LINK_OUTPUT_CLASS + num_input_audio_formats 1 + Object.Base.input_audio_format [ + { + in_channels $SDW_AMP_NUM_CHANNELS + IncludeByKey.SDW_AMP_NUM_CHANNELS { + "2" { + in_ch_cfg $CHANNEL_CONFIG_STEREO + in_ch_map $CHANNEL_MAP_STEREO + } + "4" { + in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + in_ch_map $CHANNEL_MAP_3_POINT_1 + } + } + in_bit_depth 32 + in_valid_bit_depth 32 + in_fmt_cfg "$[($in_channels | ($in_valid_bit_depth * 256))]" + } + ] + num_output_audio_formats 1 + Object.Base.output_audio_format [ + { + out_channels $SDW_AMP_NUM_CHANNELS + IncludeByKey.SDW_AMP_NUM_CHANNELS { + "2" { + out_ch_cfg $CHANNEL_CONFIG_STEREO + out_ch_map $CHANNEL_MAP_STEREO + } + "4" { + out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + out_ch_map $CHANNEL_MAP_3_POINT_1 + } + } + 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))]" + } + ] + } + Object.Widget.gain.1 { + Object.Control.mixer.1 { + name 'Post Mixer $AMP_PLAYBACK_NAME Volume' + } + } + Object.Widget.micsel.1 { + num_input_audio_formats 1 + Object.Base.input_audio_format [ + { + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + num_output_audio_formats 1 + Object.Base.output_audio_format [ + { + IncludeByKey.SDW_AMP_NUM_CHANNELS { + "2" { + out_ch_cfg $CHANNEL_CONFIG_STEREO + out_ch_map $CHANNEL_MAP_STEREO + } + "4" { + out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + out_ch_map $CHANNEL_MAP_3_POINT_1 + } + } + out_channels $SDW_AMP_NUM_CHANNELS + out_bit_depth 32 + out_valid_bit_depth 32 + } + ] + + Object.Control.bytes."1" { + name 'Post Mixer $AMP_PLAYBACK_NAME Xover Selector bytes' + } + } + Object.Widget.eqiir.2 { + num_input_audio_formats 1 + Object.Base.input_audio_format [ + { + IncludeByKey.SDW_AMP_NUM_CHANNELS { + "2" { + in_ch_cfg $CHANNEL_CONFIG_STEREO + in_ch_map $CHANNEL_MAP_STEREO + } + "4" { + in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + in_ch_map $CHANNEL_MAP_3_POINT_1 + } + } + in_channels $SDW_AMP_NUM_CHANNELS + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + num_output_audio_formats 1 + Object.Base.output_audio_format [ + { + IncludeByKey.SDW_AMP_NUM_CHANNELS { + "2" { + out_ch_cfg $CHANNEL_CONFIG_STEREO + out_ch_map $CHANNEL_MAP_STEREO + } + "4" { + out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + out_ch_map $CHANNEL_MAP_3_POINT_1 + } + } + out_channels $SDW_AMP_NUM_CHANNELS + out_bit_depth 32 + out_valid_bit_depth 32 + } + ] + Object.Control.bytes."1" { + name 'Post Mixer $AMP_PLAYBACK_NAME Xover IIR bytes' + } + } + Object.Widget.eqfir.2 { + num_input_audio_formats 1 + Object.Base.input_audio_format [ + { + IncludeByKey.SDW_AMP_NUM_CHANNELS { + "2" { + in_ch_cfg $CHANNEL_CONFIG_STEREO + in_ch_map $CHANNEL_MAP_STEREO + } + "4" { + in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + in_ch_map $CHANNEL_MAP_3_POINT_1 + } + } + in_channels $SDW_AMP_NUM_CHANNELS + in_bit_depth 32 + in_valid_bit_depth 32 + } + ] + num_output_audio_formats 1 + Object.Base.output_audio_format [ + { + IncludeByKey.SDW_AMP_NUM_CHANNELS { + "2" { + out_ch_cfg $CHANNEL_CONFIG_STEREO + out_ch_map $CHANNEL_MAP_STEREO + } + "4" { + out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + out_ch_map $CHANNEL_MAP_3_POINT_1 + } + } + out_channels $SDW_AMP_NUM_CHANNELS + out_bit_depth 32 + out_valid_bit_depth 32 + } + ] + Object.Control.bytes."1" { + name 'Post Mixer $AMP_PLAYBACK_NAME Xover FIR bytes' + } + } + } + ] + } + } +} + +IncludeByKey.NUM_SDW_AMP_LINKS { +"2" { + Define { + AMP_FEEDBACK_CH 4 + 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 [ + { + IncludeByKey.SDW_AMP_NUM_CHANNELS { + "2" { + in_ch_cfg $CHANNEL_CONFIG_STEREO + in_ch_map $CHANNEL_MAP_STEREO + } + "4" { + in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + in_ch_map $CHANNEL_MAP_3_POINT_1 + } + } + in_bit_depth 32 + in_valid_bit_depth 32 + in_fmt_cfg "$[($in_channels | ($in_valid_bit_depth * 256))]" + } + ] + Object.Base.output_audio_format [ + { + IncludeByKey.SDW_AMP_NUM_CHANNELS { + "2" { + out_ch_cfg $CHANNEL_CONFIG_STEREO + out_ch_map $CHANNEL_MAP_STEREO + } + "4" { + out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + out_ch_map $CHANNEL_MAP_3_POINT_1 + } + } + 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_channels $AMP_FEEDBACK_CH + 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_channels $AMP_FEEDBACK_CH + 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_2ND_SPK_IN_ID + priority 0 + lp_mode 0 + dynamic_pipeline 1 + } + ] + # Add a virtual widget to connect the aggregated 2nd DAI copier + virtual [ + { + name 'virtual.sdw-amp' + type output + index $ALH_2ND_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. + Object.Base.route [ + { + source "eqfir.21.2" + sink "virtual.sdw-amp" + } + { + source "virtual.sdw-amp" + sink "alh-copier.$SDW_SPK_STREAM.1" + } + ] + } + +"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_channels $AMP_FEEDBACK_CH + 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_channels $AMP_FEEDBACK_CH + 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_channels $AMP_FEEDBACK_CH + 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. + Object.Base.route [ + { + source "gain.21.1" + sink "virtual.sdw-amp" + } + { + 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 [ + { + name "Speaker" + id 2 + direction "playback" + Object.Base.fe_dai.1 { + name "Speaker" + } + + Object.PCM.pcm_caps.1 { + name "sdw amplifiers" + formats 'S16_LE,S24_LE,S32_LE' + } + } +] + +Object.Base.route [ + { + source "eqfir.21.2" + sink "alh-copier.$SDW_SPK_STREAM.0" + } + { + source 'mixin.20.1' + sink 'mixout.21.1' + } + { + source 'host-copier.2.playback' + sink 'gain.20.1' + } +] + +IncludeByKey.SDW_AMP_FEEDBACK { + "true" { + Object.Dai.ALH [ + { + dai_index 30 + id $SDW_AMP_IN_BE_ID + direction "capture" + name $SDW_SPK_IN_STREAM + default_hw_conf_id 1 + rate 48000 + channels $AMP_FEEDBACK_CH_PER_LINK + + Object.Base.hw_config.1 { + id 1 + name "ALH515" + } + } + ] + Object.Pipeline { + host-gateway-capture [ + { + index 30 + + Object.Widget.host-copier.1 { + stream_name "amp feedback" + pcm_id 3 + + IncludeByKey.AMP_FEEDBACK_CH { + "4" { + num_input_audio_formats 1 + num_output_audio_formats 3 + Object.Base.input_audio_format [ + { + in_channels 4 + in_bit_depth 32 + in_valid_bit_depth 32 + in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + in_ch_map $CHANNEL_MAP_3_POINT_1 + } + ] + Object.Base.output_audio_format [ + { + out_channels 4 + out_bit_depth 32 + out_valid_bit_depth 24 + out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + out_ch_map $CHANNEL_MAP_3_POINT_1 + } + { + out_channels 4 + out_bit_depth 32 + out_valid_bit_depth 32 + out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + out_ch_map $CHANNEL_MAP_3_POINT_1 + } + { + out_channels 4 + out_bit_depth 16 + out_valid_bit_depth 16 + out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + out_ch_map $CHANNEL_MAP_3_POINT_1 + } + ] + } + "6" { + num_input_audio_formats 1 + num_output_audio_formats 3 + Object.Base.input_audio_format [ + { + in_channels 6 + in_bit_depth 32 + in_valid_bit_depth 32 + in_ch_cfg $CHANNEL_CONFIG_5_POINT_1 + in_ch_map $CHANNEL_MAP_5_POINT_1 + } + ] + Object.Base.output_audio_format [ + { + out_channels 6 + out_bit_depth 32 + out_valid_bit_depth 24 + out_ch_cfg $CHANNEL_CONFIG_5_POINT_1 + out_ch_map $CHANNEL_MAP_5_POINT_1 + } + { + out_channels 6 + out_bit_depth 32 + out_valid_bit_depth 32 + out_ch_cfg $CHANNEL_CONFIG_5_POINT_1 + out_ch_map $CHANNEL_MAP_5_POINT_1 + } + { + out_channels 6 + out_bit_depth 16 + out_valid_bit_depth 16 + out_ch_cfg $CHANNEL_CONFIG_5_POINT_1 + out_ch_map $CHANNEL_MAP_5_POINT_1 + } + ] + } + "8" { + num_input_audio_formats 1 + num_output_audio_formats 3 + Object.Base.input_audio_format [ + { + in_channels 8 + in_bit_depth 32 + in_valid_bit_depth 32 + in_ch_cfg $CHANNEL_CONFIG_7_POINT_1 + in_ch_map $CHANNEL_MAP_7_POINT_1 + } + ] + Object.Base.output_audio_format [ + { + out_channels 8 + out_bit_depth 32 + out_valid_bit_depth 24 + out_ch_cfg $CHANNEL_CONFIG_7_POINT_1 + out_ch_map $CHANNEL_MAP_7_POINT_1 + } + { + out_channels 8 + out_bit_depth 32 + out_valid_bit_depth 32 + out_ch_cfg $CHANNEL_CONFIG_7_POINT_1 + out_ch_map $CHANNEL_MAP_7_POINT_1 + } + { + out_channels 8 + out_bit_depth 16 + out_valid_bit_depth 16 + out_ch_cfg $CHANNEL_CONFIG_7_POINT_1 + out_ch_map $CHANNEL_MAP_7_POINT_1 + } + ] + } + } + } + } + ] + } + Object.Widget { + alh-copier [ + { + index 31 + type dai_out + stream_name $SDW_SPK_IN_STREAM + 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_channels $AMP_FEEDBACK_CH + in_bit_depth 32 + in_valid_bit_depth $SDW_LINK_VALID_BITS + + IncludeByKey.AMP_FEEDBACK_CH { + "2" { + in_ch_cfg $CHANNEL_CONFIG_STEREO + in_ch_map $CHANNEL_MAP_STEREO + } + "4" { + in_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + in_ch_map $CHANNEL_MAP_3_POINT_1 + } + "6" { + in_ch_cfg $CHANNEL_CONFIG_5_POINT_1 + in_ch_map $CHANNEL_MAP_5_POINT_1 + } + "8" { + in_ch_cfg $CHANNEL_CONFIG_7_POINT_1 + in_ch_map $CHANNEL_MAP_7_POINT_1 + } + } + + in_sample_type $SAMPLE_TYPE_MSB_INTEGER + in_fmt_cfg "$[($in_channels | ($in_valid_bit_depth * 256))]" + } + ] + Object.Base.output_audio_format [ + { + out_channels $AMP_FEEDBACK_CH + out_bit_depth 32 + out_valid_bit_depth 32 + + IncludeByKey.AMP_FEEDBACK_CH { + "2" { + out_ch_cfg $CHANNEL_CONFIG_STEREO + out_ch_map $CHANNEL_MAP_STEREO + } + "4" { + out_ch_cfg $CHANNEL_CONFIG_3_POINT_1 + out_ch_map $CHANNEL_MAP_3_POINT_1 + } + "6" { + out_ch_cfg $CHANNEL_CONFIG_5_POINT_1 + out_ch_map $CHANNEL_MAP_5_POINT_1 + } + "8" { + out_ch_cfg $CHANNEL_CONFIG_7_POINT_1 + out_ch_map $CHANNEL_MAP_7_POINT_1 + } + } + } + ] + } + ] + pipeline [ + { + index 31 + priority 0 + lp_mode 0 + dynamic_pipeline 1 + } + ] + } + Object.PCM.pcm [ + { + name "Amp feedback" + id 3 + direction "capture" + Object.Base.fe_dai.1 { + name "Amp feedback" + } + + Object.PCM.pcm_caps.1 { + name "amp feedback" + formats 'S16_LE,S24_LE,S32_LE' + channels_min $AMP_FEEDBACK_CH + channels_max $AMP_FEEDBACK_CH + } + } + ] + Object.Base.route [ + { + source "alh-copier.$SDW_SPK_IN_STREAM.0" + sink "host-copier.3.capture" + } + ] + } +} diff --git a/tools/topology/topology2/production/tplg-targets-sdca-generic.cmake b/tools/topology/topology2/production/tplg-targets-sdca-generic.cmake index 689439afd637..b07b26212c51 100644 --- a/tools/topology/topology2/production/tplg-targets-sdca-generic.cmake +++ b/tools/topology/topology2/production/tplg-targets-sdca-generic.cmake @@ -25,4 +25,18 @@ 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" +# Topology for speaker with 2-way crossover filter in SOF +# with channels order L-low, R-low, L-high, R-high +"cavs-sdw\;sof-sdca-2amp-id2-xover\;NUM_SDW_AMP_LINKS=2,SDW_JACK=false,\ +SDW_AMP_FEEDBACK=false,SDW_SPK_STREAM=Playback-SmartAmp,NUM_HDMIS=0,\ +SDW_AMP_NUM_CHANNELS=4,SDW_AMP_XOVER=true,\ +SDW_AMP_XOVER_SELECTOR_PARAMS=xover_selector_lr_to_lrlr,\ +SDW_AMP_XOVER_EQIIR_PARAMS=xover_lr4_2000hz_llhh_48khz" + +"cavs-sdw\;sof-sdca-2amp-feedback-id3-xover\;NUM_SDW_AMP_LINKS=2,\ +SDW_JACK=false,SDW_AMP_FEEDBACK=true,SDW_SPK_STREAM=Playback-SmartAmp,\ +SDW_SPK_IN_STREAM=Capture-SmartAmp,NUM_HDMIS=0,\ +SDW_AMP_NUM_CHANNELS=4,SDW_AMP_XOVER=true,\ +SDW_AMP_XOVER_SELECTOR_PARAMS=xover_selector_lr_to_lrlr,\ +SDW_AMP_XOVER_EQIIR_PARAMS=xover_lr4_2000hz_llhh_48khz" )