diff --git a/tools/topology/m4/eq_fir_coef_flat.m4 b/tools/topology/m4/eq_fir_coef_flat.m4 index a8f4119d11af..de51f6b68713 100644 --- a/tools/topology/m4/eq_fir_coef_flat.m4 +++ b/tools/topology/m4/eq_fir_coef_flat.m4 @@ -1,7 +1,7 @@ -# Flat FIR EQ 19-Dec-2018 -CONTROLBYTES_PRIV(EQFIR_priv, +# Flat FIR EQ 25-Feb-2020 +CONTROLBYTES_PRIV(MY_EQFIR_PRIV, ` bytes "0x53,0x4f,0x46,0x00,0x00,0x00,0x00,0x00,' -` 0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x03,' +` 0x38,0x00,0x00,0x00,0x00,0xc0,0x00,0x03,' ` 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,' ` 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,' ` 0x38,0x00,0x00,0x00,0x02,0x00,0x01,0x00,' diff --git a/tools/topology/m4/eq_fir_coef_lowpass_7khz_40db_48khz.m4 b/tools/topology/m4/eq_fir_coef_lowpass_7khz_40db_48khz.m4 new file mode 100644 index 000000000000..ddaac0470ab8 --- /dev/null +++ b/tools/topology/m4/eq_fir_coef_lowpass_7khz_40db_48khz.m4 @@ -0,0 +1,40 @@ +# Low-pass FIR 7 kHz BW 40 dB stopband 25-Feb-2020 +CONTROLBYTES_PRIV(MY_EQFIR_PRIV, +` bytes "0x53,0x4f,0x46,0x00,0x00,0x00,0x00,0x00,' +` 0x08,0x01,0x00,0x00,0x00,0xc0,0x00,0x03,' +` 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,' +` 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,' +` 0x08,0x01,0x00,0x00,0x02,0x00,0x01,0x00,' +` 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,' +` 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,' +` 0x00,0x00,0x00,0x00,0x6c,0x00,0x01,0x00,' +` 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,' +` 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,' +` 0x32,0x00,0x3a,0x00,0x0a,0x00,0xc3,0xff,' +` 0xa8,0xff,0xde,0xff,0x42,0x00,0x79,0x00,' +` 0x45,0x00,0xc3,0xff,0x64,0xff,0x8a,0xff,' +` 0x2a,0x00,0xbc,0x00,0xb2,0x00,0xfb,0xff,' +` 0x2b,0xff,0x06,0xff,0xca,0xff,0xe0,0x00,' +` 0x4a,0x01,0x8a,0x00,0x2a,0xff,0x62,0xfe,' +` 0x07,0xff,0xb1,0x00,0xef,0x01,0x85,0x01,' +` 0x9a,0xff,0xca,0xfd,0xd0,0xfd,0xeb,0xff,' +` 0x6a,0x02,0xfb,0x02,0xcb,0x00,0x84,0xfd,' +` 0x18,0xfc,0x2e,0xfe,0x5e,0x02,0x01,0x05,' +` 0x49,0x03,0x0c,0xfe,0xa5,0xf9,0x86,0xfa,' +` 0x08,0x01,0x31,0x08,0x1e,0x09,0xf3,0x00,' +` 0xaa,0xf4,0x12,0xef,0x94,0xf9,0x9e,0x14,' +` 0x7e,0x35,0xe8,0x4b,0xe8,0x4b,0x7e,0x35,' +` 0x9e,0x14,0x94,0xf9,0x12,0xef,0xaa,0xf4,' +` 0xf3,0x00,0x1e,0x09,0x31,0x08,0x08,0x01,' +` 0x86,0xfa,0xa5,0xf9,0x0c,0xfe,0x49,0x03,' +` 0x01,0x05,0x5e,0x02,0x2e,0xfe,0x18,0xfc,' +` 0x84,0xfd,0xcb,0x00,0xfb,0x02,0x6a,0x02,' +` 0xeb,0xff,0xd0,0xfd,0xca,0xfd,0x9a,0xff,' +` 0x85,0x01,0xef,0x01,0xb1,0x00,0x07,0xff,' +` 0x62,0xfe,0x2a,0xff,0x8a,0x00,0x4a,0x01,' +` 0xe0,0x00,0xca,0xff,0x06,0xff,0x2b,0xff,' +` 0xfb,0xff,0xb2,0x00,0xbc,0x00,0x2a,0x00,' +` 0x8a,0xff,0x64,0xff,0xc3,0xff,0x45,0x00,' +` 0x79,0x00,0x42,0x00,0xde,0xff,0xa8,0xff,' +` 0xc3,0xff,0x0a,0x00,0x3a,0x00,0x32,0x00"' +) diff --git a/tools/topology/m4/eq_iir_coef_flat.m4 b/tools/topology/m4/eq_iir_coef_flat.m4 index 72e104f3d0e3..0a7e7cc92b61 100644 --- a/tools/topology/m4/eq_iir_coef_flat.m4 +++ b/tools/topology/m4/eq_iir_coef_flat.m4 @@ -1,5 +1,5 @@ # Flat IIR EQ 18-Dec-2018 -CONTROLBYTES_PRIV(EQIIR_priv, +CONTROLBYTES_PRIV(MY_EQIIR_PRIV, ` bytes "0x53,0x4f,0x46,0x00,0x00,0x00,0x00,0x00,' ` 0x58,0x00,0x00,0x00,0x00,0x00,0x00,0x03,' ` 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,' diff --git a/tools/topology/m4/pipeline.m4 b/tools/topology/m4/pipeline.m4 index 37c5ca8d80ad..008b40311645 100644 --- a/tools/topology/m4/pipeline.m4 +++ b/tools/topology/m4/pipeline.m4 @@ -42,7 +42,8 @@ dnl PIPELINE_PCM_ADD(pipeline, dnl pipe id, pcm, max channels, format, dnl period, priority, core, dnl pcm_min_rate, pcm_max_rate, pipeline_rate, -dnl time_domain, sched_comp) +dnl time_domain, sched_comp, +dnl pipeline_filter1, pipeline_filter2) define(`PIPELINE_PCM_ADD', `ifelse(eval(`$# > 10'), `1', `undefine(`PCM_ID')' @@ -59,6 +60,8 @@ define(`PIPELINE_PCM_ADD', `undefine(`DAI_FORMAT')' `undefine(`SCHED_COMP')' `undefine(`DAI_PERIODS')' +`undefine(`PIPELINE_FILTER1')' +`undefine(`PIPELINE_FILTER2')' `define(`PIPELINE_ID', $2)' `define(`PCM_ID', $3)' `define(`PIPELINE_CHANNELS', $4)' @@ -72,6 +75,8 @@ define(`PIPELINE_PCM_ADD', `define(`SCHEDULE_TIME_DOMAIN', $12)' `define(`DAI_FORMAT', $5)' `define(`SCHED_COMP', $13)' +`define(`PIPELINE_FILTER1', $14)' +`define(`PIPELINE_FILTER2', $15)' `define(`DAI_PERIODS', DAI_DEFAULT_PERIODS)' `include($1)' `DEBUG_PCM_ADD($1, $3)' diff --git a/tools/topology/sof-cml-rt5682.m4 b/tools/topology/sof-cml-rt5682.m4 index f3bbe0b82ba8..81df2a2ce786 100644 --- a/tools/topology/sof-cml-rt5682.m4 +++ b/tools/topology/sof-cml-rt5682.m4 @@ -63,10 +63,10 @@ PIPELINE_PCM_ADD(sof/pipe-volume-playback.m4, # Low Latency capture pipeline 2 on PCM 0 using max 2 channels of s24le. # 1000us deadline on core 0 with priority 0 -PIPELINE_PCM_ADD(sof/pipe-volume-capture.m4, +PIPELINE_PCM_ADD(sof/pipe-eq-fir-volume-capture.m4, 2, 0, 2, s24le, 1000, 0, 0, - 48000, 48000, 48000) + 48000, 48000, 48000,,, eq_fir_coef_lowpass_7khz_40db_48khz.m4) # Passthrough capture pipeline 3 on PCM 1 using max 4 channels. # 1000us deadline on core 0 with priority 0 diff --git a/tools/topology/sof/pipe-eq-fir-volume-capture.m4 b/tools/topology/sof/pipe-eq-fir-volume-capture.m4 new file mode 100644 index 000000000000..af838c86260e --- /dev/null +++ b/tools/topology/sof/pipe-eq-fir-volume-capture.m4 @@ -0,0 +1,130 @@ +# Passthrough with volume Pipeline and PCM +# +# Pipeline Endpoints for connection are :- +# +# host PCM_C <-- B0 <-- Volume 0 <-- B1 <-- EQ-FIR <-- B2 <-- source DAI0 + +# Include topology builder +include(`utils.m4') +include(`buffer.m4') +include(`pcm.m4') +include(`pga.m4') +include(`dai.m4') +include(`mixercontrol.m4') +include(`pipeline.m4') +include(`bytecontrol.m4') +include(`eq_fir.m4') + +# +# Controls +# +# Volume Mixer control with max value of 32 +C_CONTROLMIXER(Master Capture Volume, PIPELINE_ID, + CONTROLMIXER_OPS(volsw, + 256 binds the mixer control to volume get/put handlers, + 256, 256), + CONTROLMIXER_MAX(, 80), + false, + CONTROLMIXER_TLV(TLV 80 steps from -50dB to +30dB for 1dB, vtlv_m50s1), + Channel register and shift for Front Left/Right, + LIST(` ', KCONTROL_CHANNEL(FL, 1, 0), KCONTROL_CHANNEL(FR, 1, 1))) + +# +# Volume Configuration +# + +define(MY_PGA_TOKENS, concat(`pga_tokens_', PIPELINE_ID)) +define(MY_PGA_CONF, concat(`pga_conf_', PIPELINE_ID)) + +W_VENDORTUPLES(MY_PGA_TOKENS, sof_volume_tokens, +LIST(` ', `SOF_TKN_VOLUME_RAMP_STEP_TYPE "0"' + ` ', `SOF_TKN_VOLUME_RAMP_STEP_MS "250"')) + +W_DATA(MY_PGA_CONF, MY_PGA_TOKENS) + +# +# FIR EQ +# + +define(MY_EQFIR_COEF, concat(`eqfir_coef_', PIPELINE_ID)) +define(MY_EQFIR_PRIV, concat(`eqfir_priv_', PIPELINE_ID)) + +ifelse(PIPELINE_FILTER1, `', + `include(`eq_fir_coef_flat.m4')', + `include(PIPELINE_FILTER1)' +) + +# EQ Bytes control with max value of 255 +C_CONTROLBYTES(MY_EQFIR_COEF, PIPELINE_ID, + CONTROLBYTES_OPS(bytes, + 258 binds the mixer control to bytes get/put handlers, + 258, 258), + CONTROLBYTES_EXTOPS( + 258 binds the mixer control to bytes get/put handlers, + 258, 258), + , , , + CONTROLBYTES_MAX(, 4096), + , + MY_EQFIR_PRIV) + +# +# Components and Buffers +# + +# Host "Passthrough Capture" PCM +# with 0 sink and 2 source periods +W_PCM_CAPTURE(PCM_ID, Passthrough Capture, 0, 2) + +# "Volume" has 2 sink and 2 source periods +W_PGA(0, PIPELINE_FORMAT, 2, 2, MY_PGA_CONF, + LIST(` ', "PIPELINE_ID Master Capture Volume")) + +# "EQ 0" has 2 sink period and x source periods +W_EQ_FIR(0, PIPELINE_FORMAT, 2, DAI_PERIODS, + LIST(` ', "MY_EQFIR_COEF")) + +# Capture Buffers +W_BUFFER(0, COMP_BUFFER_SIZE(2, + COMP_SAMPLE_SIZE(PIPELINE_FORMAT), PIPELINE_CHANNELS, + COMP_PERIOD_FRAMES(PCM_MAX_RATE, SCHEDULE_PERIOD)), + PLATFORM_HOST_MEM_CAP) +W_BUFFER(1, COMP_BUFFER_SIZE(2, + COMP_SAMPLE_SIZE(PIPELINE_FORMAT), PIPELINE_CHANNELS, + COMP_PERIOD_FRAMES(PCM_MAX_RATE, SCHEDULE_PERIOD)), + PLATFORM_HOST_MEM_CAP) +W_BUFFER(2, COMP_BUFFER_SIZE(DAI_PERIODS, + COMP_SAMPLE_SIZE(DAI_FORMAT), PIPELINE_CHANNELS, + COMP_PERIOD_FRAMES(PCM_MAX_RATE, SCHEDULE_PERIOD)), + PLATFORM_DAI_MEM_CAP) + +# +# Pipeline Graph +# +# host PCM_C <-- B0 <-- Volume 0 <-- B1 <-- EQ-FIR 0 <-- B2 <-- sink DAI0 + +P_GRAPH(pipe-pass-vol-capture-PIPELINE_ID, PIPELINE_ID, + LIST(` ', + `dapm(N_PCMC(PCM_ID), N_BUFFER(0))', + `dapm(N_BUFFER(0), N_PGA(0))', + `dapm(N_PGA(0), N_BUFFER(1))', + `dapm(N_BUFFER(1), N_EQ_FIR(0))', + `dapm(N_EQ_FIR(0), N_BUFFER(2))')) + +# +# Pipeline Source and Sinks +# +indir(`define', concat(`PIPELINE_SINK_', PIPELINE_ID), N_BUFFER(2)) +indir(`define', concat(`PIPELINE_PCM_', PIPELINE_ID), Passthrough Capture PCM_ID) + +# +# PCM Configuration +# + +PCM_CAPABILITIES(Passthrough Capture PCM_ID, `S32_LE,S24_LE,S16_LE', + PCM_MIN_RATE, PCM_MAX_RATE, PIPELINE_CHANNELS, PIPELINE_CHANNELS, + 2, 16, 192, 16384, 65536, 65536) + +undefine(`MY_PGA_TOKENS') +undefine(`MY_PGA_CONF') +undefine(`MY_EQFIR_COEF') +undefine(`MY_EQFIR_PRIV') diff --git a/tools/topology/sof/pipe-eq-volume-playback.m4 b/tools/topology/sof/pipe-eq-volume-playback.m4 index 930c30efc316..a68d0cb588f9 100644 --- a/tools/topology/sof/pipe-eq-volume-playback.m4 +++ b/tools/topology/sof/pipe-eq-volume-playback.m4 @@ -2,7 +2,8 @@ # # Pipeline Endpoints for connection are :- # -# host PCM_P --> B0 --> EQ_IIR 0 --> B1 --> EQ_FIR 0 --> B2 --> Volume 0 --> B3 --> sink DAI0 +# host PCM_P --> B0 --> EQ_IIR 0 --> B1 --> EQ_FIR 0 --> B2 +# --> Volume 0 --> B3 --> sink DAI0 # Include topology builder include(`utils.m4') @@ -21,7 +22,9 @@ include(`eq_fir.m4') # # Volume Mixer control with max value of 32 C_CONTROLMIXER(Master Playback Volume, PIPELINE_ID, - CONTROLMIXER_OPS(volsw, 256 binds the mixer control to volume get/put handlers, 256, 256), + CONTROLMIXER_OPS(volsw, + 256 binds the mixer control to volume get/put handlers, + 256, 256), CONTROLMIXER_MAX(, 32), false, CONTROLMIXER_TLV(TLV 32 steps from -64dB to 0dB for 2dB, vtlv_m64s2), @@ -33,35 +36,60 @@ C_CONTROLMIXER(Master Playback Volume, PIPELINE_ID, # Volume configuration # -W_VENDORTUPLES(playback_pga_tokens, sof_volume_tokens, +define(MY_PGA_TOKENS, concat(`pga_tokens_', PIPELINE_ID)) +define(MY_PGA_CONF, concat(`pga_conf_', PIPELINE_ID)) + +W_VENDORTUPLES(MY_PGA_TOKENS, sof_volume_tokens, LIST(` ', `SOF_TKN_VOLUME_RAMP_STEP_TYPE "0"' ` ', `SOF_TKN_VOLUME_RAMP_STEP_MS "250"')) -W_DATA(playback_pga_conf, playback_pga_tokens) +W_DATA(MY_PGA_CONF, MY_PGA_TOKENS) + +# +# IIR EQ +# + +define(MY_EQIIR_COEF, concat(`eqiir_coef_', PIPELINE_ID)) +define(MY_EQIIR_PRIV, concat(`eqiir_priv_', PIPELINE_ID)) -# Use coefficients for flat frequency response -include(`eq_iir_coef_flat.m4') +ifelse(PIPELINE_FILTER1, `', + `include(`eq_iir_coef_flat.m4')', + `include(PIPELINE_FILTER1)' +) # EQ Bytes control with max value of 255 -C_CONTROLBYTES(EQIIR, PIPELINE_ID, - CONTROLBYTES_OPS(bytes, 258 binds the mixer control to bytes get/put handlers, 258, 258), - CONTROLBYTES_EXTOPS(258 binds the mixer control to bytes get/put handlers, 258, 258), +C_CONTROLBYTES(MY_EQIIR_COEF, PIPELINE_ID, + CONTROLBYTES_OPS(bytes, + 258 binds the mixer control to bytes get/put handlers, 258, 258), + CONTROLBYTES_EXTOPS(258 binds the mixer control to bytes get/put handlers, + 258, 258), , , , - CONTROLBYTES_MAX(, 304), + CONTROLBYTES_MAX(, 1024), , - EQIIR_priv) + MY_EQIIR_PRIV) + +# +# FIR EQ +# + +define(MY_EQFIR_COEF, concat(`eqfir_coef_', PIPELINE_ID)) +define(MY_EQFIR_PRIV, concat(`eqfir_priv_', PIPELINE_ID)) -# Use coefficients for flat frequency response -include(`eq_fir_coef_flat.m4') +ifelse(PIPELINE_FILTER2, `', + `include(`eq_fir_coef_flat.m4')', + `include(PIPELINE_FILTER2)' +) # EQ Bytes control with max value of 255 -C_CONTROLBYTES(EQFIR, PIPELINE_ID, - CONTROLBYTES_OPS(bytes, 258 binds the mixer control to bytes get/put handlers, 258, 258), - CONTROLBYTES_EXTOPS(258 binds the mixer control to bytes get/put handlers, 258, 258), +C_CONTROLBYTES(MY_EQFIR_COEF, PIPELINE_ID, + CONTROLBYTES_OPS(bytes, + 258 binds the mixer control to bytes get/put handlers, 258, 258), + CONTROLBYTES_EXTOPS(258 binds the mixer control to bytes get/put handlers, + 258, 258), , , , CONTROLBYTES_MAX(, 4096), , - EQFIR_priv) + MY_EQFIR_PRIV) # # Components and Buffers @@ -71,33 +99,39 @@ C_CONTROLBYTES(EQFIR, PIPELINE_ID, # with 2 sink and 0 source periods W_PCM_PLAYBACK(PCM_ID, Passthrough Playback, 2, 0) -# "Volume" has 2 source and x sink periods -W_PGA(0, PIPELINE_FORMAT, DAI_PERIODS, 2, playback_pga_conf, LIST(` ', "PIPELINE_ID Master Playback Volume")) - # "EQ 0" has 2 sink period and 2 source periods -W_EQ_IIR(0, PIPELINE_FORMAT, 2, 2, LIST(` ', "EQIIR")) +W_EQ_IIR(0, PIPELINE_FORMAT, 2, 2, LIST(` ', "MY_EQIIR_COEF")) # "EQ 0" has 2 sink period and 2 source periods -W_EQ_FIR(0, PIPELINE_FORMAT, 2, 2, LIST(` ', "EQFIR")) +W_EQ_FIR(0, PIPELINE_FORMAT, 2, 2, LIST(` ', "MY_EQFIR_COEF")) + +# "Volume" has x sink and 2 source periods +W_PGA(0, PIPELINE_FORMAT, DAI_PERIODS, 2, MY_PGA_CONF, + LIST(` ', "PIPELINE_ID Master Playback Volume")) # Playback Buffers W_BUFFER(0, COMP_BUFFER_SIZE(2, - COMP_SAMPLE_SIZE(PIPELINE_FORMAT), PIPELINE_CHANNELS, COMP_PERIOD_FRAMES(PCM_MAX_RATE, SCHEDULE_PERIOD)), + COMP_SAMPLE_SIZE(PIPELINE_FORMAT), PIPELINE_CHANNELS, + COMP_PERIOD_FRAMES(PCM_MAX_RATE, SCHEDULE_PERIOD)), PLATFORM_HOST_MEM_CAP) W_BUFFER(1, COMP_BUFFER_SIZE(2, - COMP_SAMPLE_SIZE(PIPELINE_FORMAT), PIPELINE_CHANNELS, COMP_PERIOD_FRAMES(PCM_MAX_RATE, SCHEDULE_PERIOD)), + COMP_SAMPLE_SIZE(PIPELINE_FORMAT), PIPELINE_CHANNELS, + COMP_PERIOD_FRAMES(PCM_MAX_RATE, SCHEDULE_PERIOD)), PLATFORM_HOST_MEM_CAP) W_BUFFER(2, COMP_BUFFER_SIZE(2, - COMP_SAMPLE_SIZE(PIPELINE_FORMAT), PIPELINE_CHANNELS, COMP_PERIOD_FRAMES(PCM_MAX_RATE, SCHEDULE_PERIOD)), + COMP_SAMPLE_SIZE(PIPELINE_FORMAT), PIPELINE_CHANNELS, + COMP_PERIOD_FRAMES(PCM_MAX_RATE, SCHEDULE_PERIOD)), PLATFORM_HOST_MEM_CAP) W_BUFFER(3, COMP_BUFFER_SIZE(DAI_PERIODS, - COMP_SAMPLE_SIZE(DAI_FORMAT), PIPELINE_CHANNELS, COMP_PERIOD_FRAMES(PCM_MAX_RATE, SCHEDULE_PERIOD)), + COMP_SAMPLE_SIZE(DAI_FORMAT), PIPELINE_CHANNELS, + COMP_PERIOD_FRAMES(PCM_MAX_RATE, SCHEDULE_PERIOD)), PLATFORM_DAI_MEM_CAP) # # Pipeline Graph # -# host host PCM_P --> B0 --> EQ_IIR 0 --> B1 --> EQ_FIR 0 --> B2 --> Volume 0 --> B3 --> sink DAI0 +# host host PCM_P --> B0 --> EQ_IIR 0 --> B1 --> EQ_FIR 0 --> B2 +# --> Volume 0 --> B3 --> sink DAI0 P_GRAPH(pipe-pass-vol-playback-PIPELINE_ID, PIPELINE_ID, LIST(` ', @@ -119,5 +153,13 @@ indir(`define', concat(`PIPELINE_PCM_', PIPELINE_ID), Passthrough Playback PCM_I # PCM Configuration # -PCM_CAPABILITIES(Passthrough Playback PCM_ID, `S32_LE,S24_LE,S16_LE', PCM_MIN_RATE, PCM_MAX_RATE, 2, PIPELINE_CHANNELS, 2, 16, 192, 16384, 65536, 65536) - +PCM_CAPABILITIES(Passthrough Playback PCM_ID, `S32_LE,S24_LE,S16_LE', + PCM_MIN_RATE, PCM_MAX_RATE, 2, PIPELINE_CHANNELS, + 2, 16, 192, 16384, 65536, 65536) + +undefine(`MY_PGA_TOKENS') +undefine(`MY_PGA_CONF') +undefine(`MY_EQIIR_COEF') +undefine(`MY_EQIIR_PRIV') +undefine(`MY_EQFIR_COEF') +undefine(`MY_EQFIR_PRIV')