diff --git a/topology/m4/bytecontrol.m4 b/topology/m4/bytecontrol.m4 index d36b93f..22a7b6f 100644 --- a/topology/m4/bytecontrol.m4 +++ b/topology/m4/bytecontrol.m4 @@ -27,7 +27,12 @@ define(`CONTROLBYTES_EXTOPS', ` put STR($3)' ` }') -dnl C_CONTROLMIXER(name, index, ops, base, num_regs, mask, max, tlv) +define(`CONTROLBYTES_PRIV', +`SectionData.STR($1) {' +` $2' +`}') + +dnl C_CONTROLMIXER(name, index, ops, base, num_regs, mask, max, tlv, priv) define(`C_CONTROLBYTES', `SectionControlBytes.STR($1) {' `' @@ -49,6 +54,9 @@ define(`C_CONTROLBYTES', ` tlv_read' ` tlv_callback' ` ]' +` data [' +` $10' +` ]' `}') divert(0)dnl diff --git a/topology/m4/eq.m4 b/topology/m4/eq.m4 deleted file mode 100644 index d9efee3..0000000 --- a/topology/m4/eq.m4 +++ /dev/null @@ -1,43 +0,0 @@ -divert(-1) - -dnl Define macro for Eq effect widget - -dnl EQ name) -define(`N_EQ', `EQ'PIPELINE_ID`.'$1) - -dnl W_EQ(name, format, periods_sink, periods_source, preload, kcontrols_list) -define(`W_EQ', -`SectionVendorTuples."'N_EQ($1)`_tuples_w" {' -` tokens "sof_comp_tokens"' -` tuples."word" {' -` SOF_TKN_COMP_PERIOD_SINK_COUNT' STR($3) -` SOF_TKN_COMP_PERIOD_SOURCE_COUNT' STR($4) -` SOF_TKN_COMP_PRELOAD_COUNT' STR($5) -` }' -`}' -`SectionData."'N_EQ($1)`_data_w" {' -` tuples "'N_EQ($1)`_tuples_w"' -`}' -`SectionVendorTuples."'N_EQ($1)`_tuples_str" {' -` tokens "sof_comp_tokens"' -` tuples."string" {' -` SOF_TKN_COMP_FORMAT' STR($2) -` }' -`}' -`SectionData."'N_EQ($1)`_data_str" {' -` tuples "'N_EQ($1)`_tuples_str"' -`}' -`SectionWidget."'N_EQ($1)`" {' -` index "'PIPELINE_ID`"' -` type "effect"' -` no_pm "true"' -` data [' -` "'N_EQ($1)`_data_w"' -` "'N_EQ($1)`_data_str"' -` ]' -` bytes [' - $6 -` ]' -`}') - -divert(0)dnl diff --git a/topology/m4/eq_fir.m4 b/topology/m4/eq_fir.m4 new file mode 100644 index 0000000..75d1d9f --- /dev/null +++ b/topology/m4/eq_fir.m4 @@ -0,0 +1,53 @@ +divert(-1) + +dnl Define macro for Eq effect widget + +dnl EQ name) +define(`N_EQ_FIR', `EQFIR'PIPELINE_ID`.'$1) + +dnl W_EQ(name, format, periods_sink, periods_source, preload, kcontrols_list) +define(`W_EQ_FIR', +`SectionVendorTuples."'N_EQ_FIR($1)`_tuples_w" {' +` tokens "sof_comp_tokens"' +` tuples."word" {' +` SOF_TKN_COMP_PERIOD_SINK_COUNT' STR($3) +` SOF_TKN_COMP_PERIOD_SOURCE_COUNT' STR($4) +` SOF_TKN_COMP_PRELOAD_COUNT' STR($5) +` }' +`}' +`SectionData."'N_EQ_FIR($1)`_data_w" {' +` tuples "'N_EQ_FIR($1)`_tuples_w"' +`}' +`SectionVendorTuples."'N_EQ_FIR($1)`_tuples_str" {' +` tokens "sof_comp_tokens"' +` tuples."string" {' +` SOF_TKN_COMP_FORMAT' STR($2) +` }' +`}' +`SectionData."'N_EQ_FIR($1)`_data_str" {' +` tuples "'N_EQ_FIR($1)`_tuples_str"' +`}' +`SectionVendorTuples."'N_EQ_FIR($1)`_tuples_str_type" {' +` tokens "sof_effect_tokens"' +` tuples."string" {' +` SOF_TKN_EFFECT_TYPE' "EQFIR" +` }' +`}' +`SectionData."'N_EQ_FIR($1)`_data_str_type" {' +` tuples "'N_EQ_FIR($1)`_tuples_str_type"' +`}' +`SectionWidget."'N_EQ_FIR($1)`" {' +` index "'PIPELINE_ID`"' +` type "effect"' +` no_pm "true"' +` data [' +` "'N_EQ_FIR($1)`_data_w"' +` "'N_EQ_FIR($1)`_data_str"' +` "'N_EQ_FIR($1)`_data_str_type"' +` ]' +` bytes [' + $6 +` ]' +`}') + +divert(0)dnl diff --git a/topology/m4/eq_iir.m4 b/topology/m4/eq_iir.m4 new file mode 100644 index 0000000..1f6466b --- /dev/null +++ b/topology/m4/eq_iir.m4 @@ -0,0 +1,53 @@ +divert(-1) + +dnl Define macro for Eq effect widget + +dnl EQ name) +define(`N_EQ_IIR', `EQIIR'PIPELINE_ID`.'$1) + +dnl W_EQ(name, format, periods_sink, periods_source, preload, kcontrols_list) +define(`W_EQ_IIR', +`SectionVendorTuples."'N_EQ_IIR($1)`_tuples_w" {' +` tokens "sof_comp_tokens"' +` tuples."word" {' +` SOF_TKN_COMP_PERIOD_SINK_COUNT' STR($3) +` SOF_TKN_COMP_PERIOD_SOURCE_COUNT' STR($4) +` SOF_TKN_COMP_PRELOAD_COUNT' STR($5) +` }' +`}' +`SectionData."'N_EQ_IIR($1)`_data_w" {' +` tuples "'N_EQ_IIR($1)`_tuples_w"' +`}' +`SectionVendorTuples."'N_EQ_IIR($1)`_tuples_str" {' +` tokens "sof_comp_tokens"' +` tuples."string" {' +` SOF_TKN_COMP_FORMAT' STR($2) +` }' +`}' +`SectionData."'N_EQ_IIR($1)`_data_str" {' +` tuples "'N_EQ_IIR($1)`_tuples_str"' +`}' +`SectionVendorTuples."'N_EQ_IIR($1)`_tuples_str_type" {' +` tokens "sof_effect_tokens"' +` tuples."string" {' +` SOF_TKN_EFFECT_TYPE' "EQIIR" +` }' +`}' +`SectionData."'N_EQ_IIR($1)`_data_str_type" {' +` tuples "'N_EQ_IIR($1)`_tuples_str_type"' +`}' +`SectionWidget."'N_EQ_IIR($1)`" {' +` index "'PIPELINE_ID`"' +` type "effect"' +` no_pm "true"' +` data [' +` "'N_EQ_IIR($1)`_data_w"' +` "'N_EQ_IIR($1)`_data_str"' +` "'N_EQ_IIR($1)`_data_str_type"' +` ]' +` bytes [' + $6 +` ]' +`}') + +divert(0)dnl diff --git a/topology/sof/pipe-eq-fir-volume-playback.m4 b/topology/sof/pipe-eq-fir-volume-playback.m4 new file mode 100644 index 0000000..da66d6c --- /dev/null +++ b/topology/sof/pipe-eq-fir-volume-playback.m4 @@ -0,0 +1,97 @@ +# Low Latency Passthrough with volume Pipeline and PCM +# +# Pipeline Endpoints for connection are :- +# +# host PCM_P --> B0 --> EQ 0 --> B1 --> Volume 0 --> B2 --> sink DAI0 + +# Include topology builder +include(`utils.m4') +include(`buffer.m4') +include(`pcm.m4') +include(`pga.m4') +include(`dai.m4') +include(`mixercontrol.m4') +include(`bytecontrol.m4') +include(`pipeline.m4') +include(`eq_fir.m4') + +# +# Controls +# +# 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_MAX(, 32), + false, + CONTROLMIXER_TLV(TLV 32 steps from -90dB to +6dB for 3dB, vtlv_m90s3), + Channel register and shift for Front Left/Right, + LIST(` ', KCONTROL_CHANNEL(FL, 1, 0), KCONTROL_CHANNEL(FR, 1, 1))) + +# EQ initial parameters, in this case flat response +CONTROLBYTES_PRIV(EQFIR_priv, +` bytes "0x18,0x00,0x00,0x00,0x02,0x00,0x01,0x00,' +` 0x00,0x00,0x00,0x00,0x04,0x00,0xff,0xff,' +` 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00"' +) + +# 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), + , , , + CONTROLBYTES_MAX(, 316), + , + EQFIR_priv) + +# +# Components and Buffers +# + +# Host "Passthrough Playback" PCM +# with 2 sink and 0 source periods +W_PCM_PLAYBACK(PCM_ID, Passthrough Playback, 2, 0, 2) + +# "Volume" has 2 source and 2 sink periods +W_PGA(0, PIPELINE_FORMAT, 2, 2, 2, LIST(` ', "Master Playback Volume PIPELINE_ID")) + +# "EQ 0" has 2 sink period and 2 source periods +W_EQ_FIR(0, PIPELINE_FORMAT, 2, 2, 2, LIST(` ', "EQFIR")) + +# Playback Buffers +W_BUFFER(0, COMP_BUFFER_SIZE(2, + COMP_SAMPLE_SIZE(PIPELINE_FORMAT), PIPELINE_CHANNELS, SCHEDULE_FRAMES), + PLATFORM_HOST_MEM_CAP) +W_BUFFER(1, COMP_BUFFER_SIZE(2, + COMP_SAMPLE_SIZE(PIPELINE_FORMAT), PIPELINE_CHANNELS, SCHEDULE_FRAMES), + PLATFORM_HOST_MEM_CAP) +W_BUFFER(2, COMP_BUFFER_SIZE(2, + COMP_SAMPLE_SIZE(DAI_FORMAT), PIPELINE_CHANNELS, SCHEDULE_FRAMES), + PLATFORM_DAI_MEM_CAP) + +# +# Pipeline Graph +# +# host PCM_P --> B0 --> EQ 0 --> B1 --> Volume 0 --> B2 --> sink DAI0 + +P_GRAPH(pipe-pass-vol-playback-PIPELINE_ID, PIPELINE_ID, + LIST(` ', + `dapm(N_PCMP(PCM_ID), Passthrough Playback PCM_ID)', + `dapm(N_BUFFER(0), N_PCMP(PCM_ID))', + `dapm(N_EQ_FIR(0), N_BUFFER(0))', + `dapm(N_BUFFER(1), N_EQ_FIR(0))', + `dapm(N_PGA(0), N_BUFFER(1))', + `dapm(N_BUFFER(2), N_PGA(0))')) + +# +# Pipeline Source and Sinks +# +indir(`define', concat(`PIPELINE_SOURCE_', PIPELINE_ID), N_BUFFER(2)) +indir(`define', concat(`PIPELINE_PCM_', PIPELINE_ID), Passthrough Playback PCM_ID) + + +# +# PCM Configuration + +# +PCM_CAPABILITIES(Passthrough Playback PCM_ID, `S32_LE,S24_LE,S16_LE', 48000, 48000, 2, 8, 2, 16, 192, 16384, 65536, 65536) + diff --git a/topology/sof/pipe-eq-iir-volume-playback.m4 b/topology/sof/pipe-eq-iir-volume-playback.m4 new file mode 100644 index 0000000..3b93f3c --- /dev/null +++ b/topology/sof/pipe-eq-iir-volume-playback.m4 @@ -0,0 +1,101 @@ +# Low Latency Passthrough with volume Pipeline and PCM +# +# Pipeline Endpoints for connection are :- +# +# host PCM_P --> B0 --> EQ 0 --> B1 --> Volume 0 --> B2 --> sink DAI0 + +# Include topology builder +include(`utils.m4') +include(`buffer.m4') +include(`pcm.m4') +include(`pga.m4') +include(`dai.m4') +include(`mixercontrol.m4') +include(`bytecontrol.m4') +include(`pipeline.m4') +include(`eq_iir.m4') + +# +# Controls +# +# 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_MAX(, 32), + false, + CONTROLMIXER_TLV(TLV 32 steps from -90dB to +6dB for 3dB, vtlv_m90s3), + Channel register and shift for Front Left/Right, + LIST(` ', KCONTROL_CHANNEL(FL, 1, 0), KCONTROL_CHANNEL(FR, 1, 1))) + +# EQ initial parameters, in this case flat response +CONTROLBYTES_PRIV(EQIIR_priv, +` bytes "0x38,0x00,0x00,0x00,0x02,0x00,0x00,0x00,' +` 0x01,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,0x00,0x00,0x00,0x00,' +` 0x00,0x00,0x00,0x00,0x9e,0x73,0x13,0x20,' +` 0x00,0x00,0x00,0x00,0xb2,0x7f,0x00,0x00"' +) + +# 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), + , , , + CONTROLBYTES_MAX(, 316), + , + EQIIR_priv) + +# +# Components and Buffers +# + +# Host "Passthrough Playback" PCM +# with 2 sink and 0 source periods +W_PCM_PLAYBACK(PCM_ID, Passthrough Playback, 2, 0, 2) + +# "Volume" has 2 source and 2 sink periods +W_PGA(0, PIPELINE_FORMAT, 2, 2, 2, LIST(` ', "Master Playback Volume PIPELINE_ID")) + +# "EQ 0" has 2 sink period and 2 source periods +W_EQ_IIR(0, PIPELINE_FORMAT, 2, 2, 2, LIST(` ', "EQIIR")) + +# Playback Buffers +W_BUFFER(0, COMP_BUFFER_SIZE(2, + COMP_SAMPLE_SIZE(PIPELINE_FORMAT), PIPELINE_CHANNELS, SCHEDULE_FRAMES), + PLATFORM_HOST_MEM_CAP) +W_BUFFER(1, COMP_BUFFER_SIZE(2, + COMP_SAMPLE_SIZE(PIPELINE_FORMAT), PIPELINE_CHANNELS, SCHEDULE_FRAMES), + PLATFORM_HOST_MEM_CAP) +W_BUFFER(2, COMP_BUFFER_SIZE(2, + COMP_SAMPLE_SIZE(DAI_FORMAT), PIPELINE_CHANNELS, SCHEDULE_FRAMES), + PLATFORM_DAI_MEM_CAP) + +# +# Pipeline Graph +# +# host PCM_P --> B0 --> EQ 0 --> B1 --> Volume 0 --> B2 --> sink DAI0 + +P_GRAPH(pipe-pass-vol-playback-PIPELINE_ID, PIPELINE_ID, + LIST(` ', + `dapm(N_PCMP(PCM_ID), Passthrough Playback PCM_ID)', + `dapm(N_BUFFER(0), N_PCMP(PCM_ID))', + `dapm(N_EQ_IIR(0), N_BUFFER(0))', + `dapm(N_BUFFER(1), N_EQ_IIR(0))', + `dapm(N_PGA(0), N_BUFFER(1))', + `dapm(N_BUFFER(2), N_PGA(0))')) + +# +# Pipeline Source and Sinks +# +indir(`define', concat(`PIPELINE_SOURCE_', PIPELINE_ID), N_BUFFER(2)) +indir(`define', concat(`PIPELINE_PCM_', PIPELINE_ID), Passthrough Playback PCM_ID) + + +# +# PCM Configuration + +# +PCM_CAPABILITIES(Passthrough Playback PCM_ID, `S32_LE,S24_LE,S16_LE', 48000, 48000, 2, 8, 2, 16, 192, 16384, 65536, 65536) + diff --git a/topology/sof/pipe-eq-volume-playback.m4 b/topology/sof/pipe-eq-volume-playback.m4 index 4b7cb32..c3ca5b7 100644 --- a/topology/sof/pipe-eq-volume-playback.m4 +++ b/topology/sof/pipe-eq-volume-playback.m4 @@ -2,7 +2,7 @@ # # Pipeline Endpoints for connection are :- # -# host PCM_P --> B0 --> EQ 0 --> B1 --> Volume 0 --> B2 --> 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') @@ -13,7 +13,8 @@ include(`dai.m4') include(`mixercontrol.m4') include(`bytecontrol.m4') include(`pipeline.m4') -include(`eq.m4') +include(`eq_iir.m4') +include(`eq_fir.m4') # # Controls @@ -27,12 +28,41 @@ C_CONTROLMIXER(Master Playback Volume, PIPELINE_ID, Channel register and shift for Front Left/Right, LIST(` ', KCONTROL_CHANNEL(FL, 1, 0), KCONTROL_CHANNEL(FR, 1, 1))) +# EQ initial parameters, in this case flat response +CONTROLBYTES_PRIV(EQIIR_priv, +` bytes "0x38,0x00,0x00,0x00,0x02,0x00,0x00,0x00,' +` 0x01,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,0x00,0x00,0x00,0x00,' +` 0x00,0x00,0x00,0x00,0x9e,0x73,0x13,0x20,' +` 0x00,0x00,0x00,0x00,0xb2,0x7f,0x00,0x00"' +) + # EQ Bytes control with max value of 255 -C_CONTROLBYTES(EQ, PIPELINE_ID, +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), , , , - CONTROLBYTES_MAX(, 10)) + CONTROLBYTES_MAX(, 316), + , + EQIIR_priv) + +# EQ initial parameters, in this case flat response +CONTROLBYTES_PRIV(EQFIR_priv, +` bytes "0x18,0x00,0x00,0x00,0x02,0x00,0x01,0x00,' +` 0x00,0x00,0x00,0x00,0x04,0x00,0xff,0xff,' +` 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00"' +) + +# 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), + , , , + CONTROLBYTES_MAX(, 316), + , + EQFIR_priv) # # Components and Buffers @@ -46,7 +76,10 @@ W_PCM_PLAYBACK(PCM_ID, Passthrough Playback, 2, 0, 2) W_PGA(0, PIPELINE_FORMAT, 2, 2, 2, LIST(` ', "Master Playback Volume PIPELINE_ID")) # "EQ 0" has 2 sink period and 2 source periods -W_EQ(0, PIPELINE_FORMAT, 2, 2, 2, LIST(` ', "EQ")) +W_EQ_IIR(0, PIPELINE_FORMAT, 2, 2, 2, LIST(` ', "EQIIR")) + +# "EQ 0" has 2 sink period and 2 source periods +W_EQ_FIR(0, PIPELINE_FORMAT, 2, 2, 2, LIST(` ', "EQFIR")) # Playback Buffers W_BUFFER(0, COMP_BUFFER_SIZE(2, @@ -56,30 +89,34 @@ W_BUFFER(1, COMP_BUFFER_SIZE(2, COMP_SAMPLE_SIZE(PIPELINE_FORMAT), PIPELINE_CHANNELS, SCHEDULE_FRAMES), PLATFORM_HOST_MEM_CAP) W_BUFFER(2, COMP_BUFFER_SIZE(2, + COMP_SAMPLE_SIZE(PIPELINE_FORMAT), PIPELINE_CHANNELS, SCHEDULE_FRAMES), + PLATFORM_HOST_MEM_CAP) +W_BUFFER(3, COMP_BUFFER_SIZE(2, COMP_SAMPLE_SIZE(DAI_FORMAT), PIPELINE_CHANNELS, SCHEDULE_FRAMES), PLATFORM_DAI_MEM_CAP) # # Pipeline Graph # -# host PCM_P --> B0 --> EQ 0 --> B1 --> Volume 0 --> B2 --> 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(` ', `dapm(N_PCMP(PCM_ID), Passthrough Playback PCM_ID)', `dapm(N_BUFFER(0), N_PCMP(PCM_ID))', - `dapm(N_EQ(0), N_BUFFER(0))', - `dapm(N_BUFFER(1), N_EQ(0))', - `dapm(N_PGA(0), N_BUFFER(1))', - `dapm(N_BUFFER(2), N_PGA(0))')) + `dapm(N_EQ_IIR(0), N_BUFFER(0))', + `dapm(N_BUFFER(1), N_EQ_IIR(0))', + `dapm(N_EQ_FIR(0), N_BUFFER(1))', + `dapm(N_BUFFER(2), N_EQ_FIR(0))', + `dapm(N_PGA(0), N_BUFFER(2))', + `dapm(N_BUFFER(3), N_PGA(0))')) # # Pipeline Source and Sinks # -indir(`define', concat(`PIPELINE_SOURCE_', PIPELINE_ID), N_BUFFER(2)) +indir(`define', concat(`PIPELINE_SOURCE_', PIPELINE_ID), N_BUFFER(3)) indir(`define', concat(`PIPELINE_PCM_', PIPELINE_ID), Passthrough Playback PCM_ID) - # # PCM Configuration diff --git a/topology/sof/tokens.m4 b/topology/sof/tokens.m4 index 4aa2fea..b584f56 100644 --- a/topology/sof/tokens.m4 +++ b/topology/sof/tokens.m4 @@ -82,3 +82,7 @@ SectionVendorTokens."sof_dmic_pdm_tokens" { SectionVendorTokens."sof_tone_tokens" { SOF_TKN_TONE_SAMPLE_RATE "800" } + +SectionVendorTokens."sof_effect_tokens" { + SOF_TKN_EFFECT_TYPE "900" +}