From c29476bde221381aabac18793a5692d5addc63f3 Mon Sep 17 00:00:00 2001 From: Pan Xiuli Date: Tue, 22 Oct 2019 17:13:13 +0800 Subject: [PATCH] topology: add smart amp for apl pcm512x Add smart amp topology macro and an example tplg for apl pcm512x. only s16le/s32le format is support for amp now. Signed-off-by: Pan Xiuli --- tools/topology/CMakeLists.txt | 1 + tools/topology/m4/smart_amp.m4 | 46 ++++++++ tools/topology/m4/smart_amp_demux.m4 | 46 ++++++++ tools/topology/sof-apl-smart-amp-pcm512x.m4 | 99 +++++++++++++++++ .../sof/pipe-volume-smart-amp-capture.m4 | 100 ++++++++++++++++++ .../sof/pipe-volume-smart-amp-playback.m4 | 91 ++++++++++++++++ 6 files changed, 383 insertions(+) create mode 100644 tools/topology/m4/smart_amp.m4 create mode 100644 tools/topology/m4/smart_amp_demux.m4 create mode 100644 tools/topology/sof-apl-smart-amp-pcm512x.m4 create mode 100644 tools/topology/sof/pipe-volume-smart-amp-capture.m4 create mode 100644 tools/topology/sof/pipe-volume-smart-amp-playback.m4 diff --git a/tools/topology/CMakeLists.txt b/tools/topology/CMakeLists.txt index 23e7a9b09477..a0768a4bcc09 100644 --- a/tools/topology/CMakeLists.txt +++ b/tools/topology/CMakeLists.txt @@ -51,6 +51,7 @@ set(TPLGS "sof-glk-rt5682\;sof-glk-rt5682" "sof-icl-nocodec\;sof-icl-nocodec" "sof-apl-eq-pcm512x\;sof-apl-eq-pcm512x" + "sof-apl-smart-amp-pcm512x\;sof-apl-smart-amp-pcm512x" "sof-apl-eq-dmic\;sof-apl-eq-dmic" "sof-apl-src-dmic\;sof-apl-src-dmic" "sof-apl-dmic-a2ch\;sof-apl-dmic-a2ch" diff --git a/tools/topology/m4/smart_amp.m4 b/tools/topology/m4/smart_amp.m4 new file mode 100644 index 000000000000..8a8c1e00717a --- /dev/null +++ b/tools/topology/m4/smart_amp.m4 @@ -0,0 +1,46 @@ +divert(-1) + +dnl Define macro for smart amplifier component widget + +dnl smartamp Name) +define(`N_SMART_AMP', `SMART_AMP'PIPELINE_ID`.'$1) + +dnl W_SMART_AMP(name, format, periods_sink, periods_source) +define(`W_SMART_AMP', +`SectionVendorTuples."'N_SMART_AMP($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) +` }' +`}' +`SectionData."'N_SMART_AMP($1)`_data_w" {' +` tuples "'N_SMART_AMP($1)`_tuples_w"' +`}' +`SectionVendorTuples."'N_SMART_AMP($1)`_tuples_str" {' +` tokens "sof_comp_tokens"' +` tuples."string" {' +` SOF_TKN_COMP_FORMAT' STR($2) +` }' +`}' +`SectionVendorTuples."'N_SMART_AMP($1)`_process_tuples_str" {' +` tokens "sof_process_tokens"' +` tuples."string" {' +` SOF_TKN_PROCESS_TYPE' "SMART_AMP" +` }' +`}' +`SectionData."'N_SMART_AMP($1)`_data_str" {' +` tuples "'N_SMART_AMP($1)`_tuples_str"' +` tuples "'N_SMART_AMP($1)`_process_tuples_str"' +`}' +`SectionWidget."'N_SMART_AMP($1)`" {' +` index "'PIPELINE_ID`"' +` type "effect"' +` no_pm "true"' +` data [' +` "'N_SMART_AMP($1)`_data_w"' +` "'N_SMART_AMP($1)`_data_str"' +` ]' +`}') + +divert(0)dnl diff --git a/tools/topology/m4/smart_amp_demux.m4 b/tools/topology/m4/smart_amp_demux.m4 new file mode 100644 index 000000000000..14c2dbcc858b --- /dev/null +++ b/tools/topology/m4/smart_amp_demux.m4 @@ -0,0 +1,46 @@ +divert(-1) + +dnl Define macro for smart amplifier demux component widget + +dnl smartamp demux Name) +define(`N_SMART_AMP_DEMUX', `SMART_AMP_DEMUX'PIPELINE_ID`.'$1) + +dnl W_SMART_AMP_DEMUX(name, format, periods_sink, periods_source) +define(`W_SMART_AMP_DEMUX', +`SectionVendorTuples."'N_SMART_AMP_DEMUX($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) +` }' +`}' +`SectionData."'N_SMART_AMP_DEMUX($1)`_data_w" {' +` tuples "'N_SMART_AMP_DEMUX($1)`_tuples_w"' +`}' +`SectionVendorTuples."'N_SMART_AMP_DEMUX($1)`_tuples_str" {' +` tokens "sof_comp_tokens"' +` tuples."string" {' +` SOF_TKN_COMP_FORMAT' STR($2) +` }' +`}' +`SectionVendorTuples."'N_SMART_AMP_DEMUX($1)`_process_tuples_str" {' +` tokens "sof_process_tokens"' +` tuples."string" {' +` SOF_TKN_PROCESS_TYPE' "SMART_AMP_DEMUX" +` }' +`}' +`SectionData."'N_SMART_AMP_DEMUX($1)`_data_str" {' +` tuples "'N_SMART_AMP_DEMUX($1)`_tuples_str"' +` tuples "'N_SMART_AMP_DEMUX($1)`_process_tuples_str"' +`}' +`SectionWidget."'N_SMART_AMP_DEMUX($1)`" {' +` index "'PIPELINE_ID`"' +` type "effect"' +` no_pm "true"' +` data [' +` "'N_SMART_AMP_DEMUX($1)`_data_w"' +` "'N_SMART_AMP_DEMUX($1)`_data_str"' +` ]' +`}') + +divert(0)dnl diff --git a/tools/topology/sof-apl-smart-amp-pcm512x.m4 b/tools/topology/sof-apl-smart-amp-pcm512x.m4 new file mode 100644 index 000000000000..c8e1b12812ec --- /dev/null +++ b/tools/topology/sof-apl-smart-amp-pcm512x.m4 @@ -0,0 +1,99 @@ +# +# Topology for generic Apollolake UP^2 with pcm512x codec with equalizer components. +# + +# Include topology builder +include(`utils.m4') +include(`dai.m4') +include(`pipeline.m4') +include(`ssp.m4') + +# Include TLV library +include(`common/tlv.m4') + +# Include Token library +include(`sof/tokens.m4') + +# Include Apollolake DSP configuration +include(`platform/intel/bxt.m4') + +# +# Define the pipelines +# +# PCM0 --> buf --> volume --> Smart AMP --> buf --> SSP5 (pcm512x) +# ^ +# | +# buf +# ^ +# | +# PCM0 --> buf --> volume --> Smart AMP --> buf --> SSP5 (pcm512x) +# + +dnl PIPELINE_PCM_DAI_ADD(pipeline, +dnl pipe id, pcm, max channels, format, +dnl period, priority, core, +dnl dai type, dai_index, dai format, +dnl dai periods, pcm_min_rate, pcm_max_rate, +dnl pipeline_rate, time_domain) + +# Smart AMP playback pipeline 1 on PCM 0 using max 2 channels of s16le. +# Set 1000us deadline on core 0 with priority 0 +PIPELINE_PCM_DAI_ADD(sof/pipe-volume-smart-amp-playback.m4, + 1, 0, 2, s16le, + 1000, 0, 0, SSP, 5, s16le, 3, + 48000, 48000, 48000) + +# Smart AMP capture pipeline 2 on PCM 0 using max 2 channels of s16le. +# Set 1000us deadline on core 0 with priority 0 +PIPELINE_PCM_DAI_ADD(sof/pipe-volume-smart-amp-capture.m4, + 2, 0, 2, s16le, + 1000, 0, 0, SSP, 5, s16le, 3, + 48000, 48000, 48000) + +# +# DAIs configuration +# + +dnl DAI_ADD(pipeline, +dnl pipe id, dai type, dai_index, dai_be, +dnl buffer, periods, format, +dnl deadline, priority, core, time_domain) + +# playback DAI is SSP5 using 3 periods +# Buffers use s16le format, 1000us deadline on core 0 with priority 0 +DAI_ADD(sof/pipe-dai-playback.m4, + 1, SSP, 5, SSP5-Codec, + PIPELINE_SOURCE_1, 3, s16le, + 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) + +# capture DAI is SSP5 using 3 periods +# Buffers use s16le format, 1000us deadline on core 0 with priority 0 +DAI_ADD(sof/pipe-dai-capture.m4, + 2, SSP, 5, SSP5-Codec, + PIPELINE_SINK_2, 3, s16le, + 1000, 0, 0, SCHEDULE_TIME_DOMAIN_TIMER) + + +# PCM Low Latency, id 0 +PCM_DUPLEX_ADD(Port5, 0, PIPELINE_PCM_1, PIPELINE_PCM_2) + +# Connect pipelines together +SectionGraph."smart-amp-pipeline" { + index "0" + + lines [ + dapm(PIPELINE_SMART_AMP_1, PIPELINE_SMART_AMP_2) + ] +} + + +# +# BE configurations - overrides config in ACPI if present +# + +DAI_CONFIG(SSP, 5, 0, SSP5-Codec, + SSP_CONFIG(I2S, SSP_CLOCK(mclk, 24576000, codec_mclk_in), + SSP_CLOCK(bclk, 1536000, codec_slave), + SSP_CLOCK(fsync, 48000, codec_slave), + SSP_TDM(2, 16, 3, 3), + SSP_CONFIG_DATA(SSP, 5, 16, 0, SSP_QUIRK_LBM))) diff --git a/tools/topology/sof/pipe-volume-smart-amp-capture.m4 b/tools/topology/sof/pipe-volume-smart-amp-capture.m4 new file mode 100644 index 000000000000..225551fa489d --- /dev/null +++ b/tools/topology/sof/pipe-volume-smart-amp-capture.m4 @@ -0,0 +1,100 @@ +# Capture Smart AMP Pipeline and PCM +# +# Pipeline Endpoints for connection are :- +# +# host PCM_C <-- B0 <-- Volume 0 <-- B1 <-- Smart AMP 0 <-- B2 <-- sink DAI0 +# | +# v +# B3 + +# Include topology builder +include(`utils.m4') +include(`buffer.m4') +include(`pcm.m4') +include(`pga.m4') +include(`dai.m4') +include(`pipeline.m4') +include(`mixercontrol.m4') +include(`smart_amp_demux.m4') + +# +# Controls +# + +# Volume Mixer control with max value of 80 +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 +# +W_VENDORTUPLES(capture_pga_tokens, sof_volume_tokens, +LIST(` ', `SOF_TKN_VOLUME_RAMP_STEP_TYPE "0"' + ` ', `SOF_TKN_VOLUME_RAMP_STEP_MS "250"')) + +W_DATA(capture_pga_conf, capture_pga_tokens) + +# +# Components and Buffers +# + +# Host "Smart AMP Capture" PCM +# with 0 sink and 2 source periods +W_PCM_CAPTURE(PCM_ID, Smart AMP Capture, 0, 2) + +# "Volume" has 2 source and x sink periods +W_PGA(0, PIPELINE_FORMAT, 2, DAI_PERIODS, capture_pga_conf, LIST(` ', "PIPELINE_ID Master Capture Volume")) + +# "smart AMP demux" has x source and x sink periods +W_SMART_AMP_DEMUX(0, PIPELINE_FORMAT, DAI_PERIODS, DAI_PERIODS) + +# 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(DAI_PERIODS, + COMP_SAMPLE_SIZE(PIPELINE_FORMAT), PIPELINE_CHANNELS, COMP_PERIOD_FRAMES(PCM_MAX_RATE, SCHEDULE_PERIOD)), + PLATFORM_COMP_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) +W_BUFFER(3, COMP_BUFFER_SIZE(DAI_PERIODS, + COMP_SAMPLE_SIZE(DAI_FORMAT), PIPELINE_CHANNELS, COMP_PERIOD_FRAMES(PCM_MAX_RATE, SCHEDULE_PERIOD)), + PLATFORM_COMP_MEM_CAP) + +# +# Pipeline Graph +# +# host PCM_C <-- B0 <-- Volume 0 <-- B1 <-- Smart AMP 0 <-- B2 <-- sink DAI0 +# | +# v +# B3 + +P_GRAPH(pipe-vol-smartamp-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_SMART_AMP_DEMUX(0))', + `dapm(N_BUFFER(3), N_SMART_AMP_DEMUX(0))', + `dapm(N_SMART_AMP_DEMUX(0), N_BUFFER(2))')) + +# +# Pipeline Source and Sinks +# +indir(`define', concat(`PIPELINE_SINK_', PIPELINE_ID), N_BUFFER(2)) +indir(`define', concat(`PIPELINE_SMART_AMP_', PIPELINE_ID), N_BUFFER(3)) +indir(`define', concat(`PIPELINE_PCM_', PIPELINE_ID), Smart AMP Capture PCM_ID) + +# +# PCM Configuration +# + +PCM_CAPABILITIES(Smart AMP Capture PCM_ID, `S32_LE,S24_LE,S16_LE', PCM_MIN_RATE, PCM_MAX_RATE, 2, PIPELINE_CHANNELS, 2, 16, 192, 16384, 65536, 65536) diff --git a/tools/topology/sof/pipe-volume-smart-amp-playback.m4 b/tools/topology/sof/pipe-volume-smart-amp-playback.m4 new file mode 100644 index 000000000000..576f3c0dbd7f --- /dev/null +++ b/tools/topology/sof/pipe-volume-smart-amp-playback.m4 @@ -0,0 +1,91 @@ +# Playback Smart AMP Pipeline and PCM +# +# Pipeline Endpoints for connection are :- +# +# host PCM_P --> B0 --> Volume 0 --> B1 --> Smart AMP 0 --> B2 --> sink DAI0 + +# Include topology builder +include(`utils.m4') +include(`buffer.m4') +include(`pcm.m4') +include(`pga.m4') +include(`dai.m4') +include(`pipeline.m4') +include(`mixercontrol.m4') +include(`smart_amp.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 -64dB to 0dB for 2dB, vtlv_m64s2), + Channel register and shift for Front Left/Right, + LIST(` ', KCONTROL_CHANNEL(FL, 1, 0), KCONTROL_CHANNEL(FR, 1, 1))) + +# +# Volume configuration +# + +W_VENDORTUPLES(playback_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) + +# +# Components and Buffers +# + +# Host "Smart AMP Playback" PCM +# with 2 sink and 0 source periods +W_PCM_PLAYBACK(PCM_ID, Smart AMP 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")) + +# "smart AMP" has x source and x sink periods +W_SMART_AMP(0, PIPELINE_FORMAT, DAI_PERIODS, DAI_PERIODS) + +# Playback 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(DAI_PERIODS, + COMP_SAMPLE_SIZE(PIPELINE_FORMAT), PIPELINE_CHANNELS, COMP_PERIOD_FRAMES(PCM_MAX_RATE, SCHEDULE_PERIOD)), + PLATFORM_COMP_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_P --> B0 --> Volume 0 --> B1 --> Smart AMP 0 --> B2 --> sink DAI0 + +P_GRAPH(pipe-vol-smartamp-playback-PIPELINE_ID, PIPELINE_ID, + LIST(` ', + `dapm(N_BUFFER(0), N_PCMP(PCM_ID))', + `dapm(N_PGA(0), N_BUFFER(0))', + `dapm(N_BUFFER(1), N_PGA(0))', + `dapm(N_SMART_AMP(0), N_BUFFER(1))', + `dapm(N_BUFFER(2), N_SMART_AMP(0))')) + +# +# Pipeline Source and Sinks +# +indir(`define', concat(`PIPELINE_SOURCE_', PIPELINE_ID), N_BUFFER(2)) +indir(`define', concat(`PIPELINE_SMART_AMP_', PIPELINE_ID), N_SMART_AMP(0)) +indir(`define', concat(`PIPELINE_PCM_', PIPELINE_ID), Smart AMP Playback PCM_ID) + + +# +# PCM Configuration + +# +PCM_CAPABILITIES(Smart AMP Playback PCM_ID, `S32_LE,S24_LE,S16_LE', PCM_MIN_RATE, PCM_MAX_RATE, 2, PIPELINE_CHANNELS, 2, 16, 192, 16384, 65536, 65536) +