diff --git a/scripts/build-tools.sh b/scripts/build-tools.sh index 1edee2c513e2..ccd5bf6deb69 100755 --- a/scripts/build-tools.sh +++ b/scripts/build-tools.sh @@ -16,6 +16,7 @@ usage: $0 [-c|-f|-h|-l|-p|-t|-T] -p Rebuild probes -t Rebuild test topologies -T Rebuild topologies + -z Rebuild topology2 -C No build, only CMake re-configuration EOFUSAGE } @@ -62,6 +63,7 @@ Build commands for respective tools: probes: make -C "$BUILD_TOOLS_DIR" sof-probes topologies: make -C "$BUILD_TOOLS_DIR" topologies test tplgs: make -C "$BUILD_TOOLS_DIR" tests + topology2: make -C "$BUILD_TOOLS_DIR" topology2 fuzzer: make -C "$BUILD_TOOLS_DIR/fuzzer" EOFUSAGE } @@ -70,7 +72,7 @@ main() { local DO_BUILD_ctl DO_BUILD_fuzzer DO_BUILD_logger DO_BUILD_probes \ DO_BUILD_tests DO_BUILD_topologies SCRIPT_DIR SOF_REPO CMAKE_ONLY \ - BUILD_ALL + DO_BUILD_topology2 BUILD_ALL SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd) SOF_REPO=$(dirname "$SCRIPT_DIR") : "${BUILD_TOOLS_DIR:=$SOF_REPO/tools/build_tools}" @@ -87,11 +89,12 @@ main() DO_BUILD_probes=false DO_BUILD_tests=false DO_BUILD_topologies=false + DO_BUILD_topology2=false CMAKE_ONLY=false # eval is a sometimes necessary evil # shellcheck disable=SC2034 - while getopts "cfhlptTC" OPTION; do + while getopts "cfhlptTzC" OPTION; do case "$OPTION" in c) DO_BUILD_ctl=true ;; f) DO_BUILD_fuzzer=true ;; @@ -99,6 +102,7 @@ main() p) DO_BUILD_probes=true ;; t) DO_BUILD_tests=true ;; T) DO_BUILD_topologies=true ;; + z) DO_BUILD_topology2=true ;; C) CMAKE_ONLY=true ;; h) print_usage; exit 1;; *) print_usage; exit 1;; @@ -124,7 +128,7 @@ main() fi done - for util in tests topologies; do + for util in tests topologies topology2; do if eval '$DO_BUILD_'$util; then make_tool $util fi diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 076dd3e5a83b..ffce01e72e84 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -26,4 +26,5 @@ add_subdirectory(probes) add_subdirectory(logger) add_subdirectory(ctl) add_subdirectory(topology) +add_subdirectory(topology2) add_subdirectory(test) diff --git a/tools/topology2/CMakeLists.txt b/tools/topology2/CMakeLists.txt new file mode 100644 index 000000000000..3979f00cc2a1 --- /dev/null +++ b/tools/topology2/CMakeLists.txt @@ -0,0 +1,31 @@ +# SPDX-License-Identifier: BSD-3-Clause + +# Array of "input-file-name;output-file-name;" +set(TPLGS + "sof-cnl-nocodec\;sof-cnl-nocodec\;" +) + +add_custom_target(topology2 ALL) + +foreach(tplg ${TPLGS}) + list(GET tplg 0 input) + list(GET tplg 1 output) + + add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${output}.conf + COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/get_abi.sh ${SOF_ROOT_SOURCE_DIRECTORY} + ${CMAKE_CURRENT_SOURCE_DIR}/${input}.conf > ${CMAKE_CURRENT_BINARY_DIR}/${output}.conf + USES_TERMINAL + ) + +# Note: this does NOT use VERBATIM, see explanation in ../topology/CMakeLists.txt + add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${output}.tplg + COMMAND alsatplg \$\${VERBOSE:+-v 1} -p -c ${CMAKE_CURRENT_BINARY_DIR}/${output}.conf -o ${output}.tplg + DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${output}.conf + USES_TERMINAL + ) + + add_custom_target(topology2_${output} DEPENDS ${output}.tplg) + add_dependencies(topology2 topology2_${output}) +endforeach() diff --git a/tools/topology2/get_abi.sh b/tools/topology2/get_abi.sh new file mode 100755 index 000000000000..ba7ab3e8ac3f --- /dev/null +++ b/tools/topology2/get_abi.sh @@ -0,0 +1,20 @@ +#!/bin/bash +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(c) 2019 Intel Corporation. All rights reserved. +set -e + +ABI_MAJOR=$(awk '/^ *# *define *SOF_ABI_MAJOR / { print $3 }' $1/src/include/kernel/abi.h) +ABI_MINOR=$(awk '/^ *# *define *SOF_ABI_MINOR / { print $3 }' $1/src/include/kernel/abi.h) +ABI_PATCH=$(awk '/^ *# *define *SOF_ABI_PATCH / { print $3 }' $1/src/include/kernel/abi.h) + +cat $2 +cat < volume-playback pipeline endpoint 0" +# The alsatplg compiler will look up the widget that the pipeline endpoint refers to. +# and N is the unique instance number for the route object within the same alsaconf node. +# +# +# +Class.Base."route" { + + + # control name for the route + DefineAttribute."control" {} + + # source and sink attributes should refer an object of a certain class with a unique value + # in the parent object_list + DefineAttribute."sink" {} + DefineAttribute."source" {} + + # + # Pipeline ID of the pipeline the route object belongs to + # + DefineAttribute."index" {} + + DefineAttribute."instance" {} + + attributes { + constructor [ + "instance" + ] + mandatory [ + "instance" + "source" + "sink" + ] + # + # route objects instantiated within the same alsaconf node must have unique + # index attribute + # + unique "instance" + } +} diff --git a/tools/topology2/include/common/tokens.conf b/tools/topology2/include/common/tokens.conf new file mode 100644 index 000000000000..d0e85521006d --- /dev/null +++ b/tools/topology2/include/common/tokens.conf @@ -0,0 +1,57 @@ + + +Object.Base.VendorToken { + "sof_tkn_comp" { + period_sink_count 400 + period_source_count 401 + format 402 + # Token retired with ABI 3.2, do not use for new capabilities + preload_count 403 + core_id 404 + uuid 405 + } + + "sof_tkn_dai" { + # Token retired with ABI 3.2, do not use for new capabilities + dmac_config 153 + dai_type 154 + dai_index 155 + direction 156 + } + + "sof_tkn_buffer" { + size 100 + caps 101 + } + + "sof_tkn_volume" { + ramp_step_type 250 + ramp_step_ms 251 + } + + "sof_tkn_scheduler" { + period 200 + priority 201 + mips 202 + core 203 + frames 204 + time_domain 205 + dynamic 206 + lp_mode 207 + } + + "sof_tkn_intel_ssp" { + clks_control 500 + mclk_id 501 + sample_bits 502 + frame_pulse_width 503 + quirks 504 + tdm_padding_per_slot 505 + bclk_delay 506 + } + + "sof_tkn_stream" { + playback_compatible_d0i3 1200 + capture_compatible_d0i3 1201 + } +} diff --git a/tools/topology2/include/common/vendor-token.conf b/tools/topology2/include/common/vendor-token.conf new file mode 100644 index 000000000000..488b4253daf6 --- /dev/null +++ b/tools/topology2/include/common/vendor-token.conf @@ -0,0 +1,22 @@ +# Class definition for data object +Class.Base.VendorToken { + + DefineAttribute."name" { + type "string" + } + + DefineAttribute."type" { + type "string" + } + + attributes { + constructor [ + "name" + ] + # + # name attribute values for VendorToken objects must be unique in the same alsaconf + # node + # + unique "name" + } +} diff --git a/tools/topology2/include/components/buffer.conf b/tools/topology2/include/components/buffer.conf new file mode 100644 index 000000000000..479f51222dc0 --- /dev/null +++ b/tools/topology2/include/components/buffer.conf @@ -0,0 +1,113 @@ +# Common pipeline buffer +# +# A generic buffer component. All attributes defined herein are namespaced +# by alsatplg to "buffer.N.attribute_name" +# +# Usage: this component can be used by instantiating it in the parent object. i.e. +# +# Object.Widget.buffer."N" { +# pipeline_id 1 +# index 0 +# size 384 +# caps "host" +# } +# +# Where N is the unique instance number for the buffer object within the same alsaconf node. + + +Class.Widget."buffer" { + + # + # The buffer widget name would be constructed using the pipeline_id and index arguments. + # For ex: "buffer.1.1" or "buffer.10.2" etc. + # + DefineAttribute."index" {} + # + # Unique index per widget type in pipeline. + # + DefineAttribute."instance" {} + + #include common component definition + + + DefineAttribute."uuid" { + # Token set reference name and type + token_ref "sof_tkn_comp.uuid" + } + + # + # Bespoke Attribute Definitions for Buffers + # + + # Buffer size in bytes. Will be calculated based on pipeline parameters in which the + # buffer object belongs. + DefineAttribute."size" { + # Token reference and type + token_ref "sof_tkn_buffer.word" + } + + # Number of periods + DefineAttribute."periods" {} + + # Number of channels + DefineAttribute."channels" {} + + # Buffer memory capabilities. The values provided will be translated to integer values + # as specified by the value token reference "sof_tkn_mem". + # For example: "dai" will be translated to 113 depending on the platform. + DefineAttribute."caps" { + type "string" + # Token reference and type + token_ref "sof_tkn_buffer.word" + constraints { + value_ref "sof_tkn_mem" + valid_values [ + "dai" + "host" + "pass" + "comp" + ] + tuple_values [ + 113 + 113 + 113 + 65 + ] + } + } + + # Attribute categories + attributes { + constructor [ + "index" + "instance" + ] + mandatory [ + "periods" + "caps" + "channels" + ] + immutable [ + "uuid" + "type" + ] + automatic [ + "size" + ] + deprecated [ + "preload_count" + ] + # + # buffer widget objects instantiated within the same alsaconf node must have unique + # index attribute + # + unique "instance" + } + + # + # Default attributes for buffer objects + # + type "buffer" + uuid "92:4c:54:42:92:8e:41:4e:b6:79:34:51:9f:1c:1d:28" + no_pm "true" +} diff --git a/tools/topology2/include/components/component.conf b/tools/topology2/include/components/component.conf new file mode 100644 index 000000000000..e01165a3ad3b --- /dev/null +++ b/tools/topology2/include/components/component.conf @@ -0,0 +1,80 @@ +# +# Common widget attribute definitions +# + +# +# no_pm - maps to the DAPM widget's reg field +# "false" value indicates that there is no direct DAPM for this widget +# +DefineAttribute."no_pm" { + type "string" + constraints { + valid_values [ + "true" + "false" + ] + } +} + +# +# Widget Type - maps to the widget ID with values of type enum SND_SOC_TPLG_DAPM_* +# +DefineAttribute."type" { + type "string" +} + +# +# Stream name - maps to the DAPM widget's stream name +# +DefineAttribute."stream_name" { + type "string" +} + +# +# Widget events to bind to +# +DefineAttribute.event_flags {} +DefineAttribute.event_type {} + +# +# Tuple definitions added to widget's private data if set +# + +# number of sink periods +DefineAttribute."period_sink_count" { + # Token set reference name and type + token_ref "sof_tkn_comp.word" +} + +# number of source periods +DefineAttribute."period_source_count" { + # Token set reference name and type + token_ref "sof_tkn_comp.word" +} + +# audio format +DefineAttribute."format" { + type "string" + # Token set reference name and type + token_ref "sof_tkn_comp.string" + constraints { + valid_values [ + "s16le" + "s24le" + "s32le" + "float" + ] + } +} + +# ID of the core this widget should be executed on +DefineAttribute."core_id" { + # Token set reference name and type + token_ref "sof_tkn_comp.word" +} + +# number of periods to preload +DefineAttribute."preload_count" { + # Token set reference name and type + token_ref "sof_tkn_comp.word" +} diff --git a/tools/topology2/include/components/dai.conf b/tools/topology2/include/components/dai.conf new file mode 100644 index 000000000000..247647a12f16 --- /dev/null +++ b/tools/topology2/include/components/dai.conf @@ -0,0 +1,123 @@ +# +# A generic dai widget. All attributes defined herein are namespaced +# by alsatplg to "dai.N.attribute_name" +# +# For playback +# Object.Widget.dai."playback" { +# type SSP +# index 1 +# period_sink_count 2 +# period_source_count 0 +# type dai_in +# } +# +# For Capture +# Object.Widget.dai."capture" { +# type SSP +# index 2 +# period_sink_count 0 +# period_source_count 2 +# type dai_out +# } +# +# The widget_type for DAI should be specified when the object is created based on the direction. + +Class.Widget."dai" { + # + # The DAI widget name would be constructed using the type, index and direction + # arguments. For ex: "dai.SSP.1.capture" or "dai.ALH.2.playback" etc. + # + + # Type of DAI + DefineAttribute."dai_type" { + type "string" + token_ref "sof_tkn_dai.string" + constraints { + values [ + "SSP" + "DMIC" + "HDA" + "ALH" + "ESAI" + ] + } + } + + # DAI Index in the firmware + DefineAttribute."dai_index" { + # Token reference and type + token_ref "sof_tkn_dai.word" + } + + # + # DAI direction. The string values will be converted to 0/1 and added as tuple data + # + DefineAttribute."direction" { + type "string" + token_ref "sof_tkn_dai.word" + constraints { + valid_values [ + "playback" + "capture" + ] + tuple_values [ + 0 + 1 + ] + } + } + + #include common component definition + + + # + # Pipeline ID that the dai widget belongs to + # + DefineAttribute."index" {} + + DefineAttribute.uuid { + type "string" + # Token set reference name and type + token_ref "sof_tkn_comp.uuid" + } + + # Bespoke attributes for DAI + DefineAttribute."format" { + type "string" + # Token reference and type + token_ref "sof_tkn_comp.string" + } + + # Attribute categories + attributes { + constructor [ + "dai_type" + "dai_index" + "direction" + ] + mandatory [ + "type" + "stream_name" + "format" + "index" + "period_sink_count" + "period_source_count" + "format" + ] + immutable [ + "uuid" + ] + deprecated [ + "preload_count" + ] + # + # dai widget objects instantiated within the same alsaconf node must have unique + # direction attribute + # + unique "direction" + } + + # Default attributes for DAI + uuid "27:0d:b0:c2:bc:ff:50:41:a5:1a:24:5c:79:c5:e5:4b" + no_pm "true" +} diff --git a/tools/topology2/include/components/host.conf b/tools/topology2/include/components/host.conf new file mode 100644 index 000000000000..e1fe6211a0f7 --- /dev/null +++ b/tools/topology2/include/components/host.conf @@ -0,0 +1,77 @@ +# A generic host widget. All attributes defined herein are namespaced +# by alsatplg to "host.playback/capture.attribute_name" +# +# Usage: this widget can be used by declaring in a parent object as: +# +# For playback +# Object.Widget.host."playback" { +# pipeline_id 3 +# period_sink_count 2 +# period_source_count 0 +# type aif_in +# } +# +# For Capture +# Object.Widget.host."capture" { +# pipeline_id 4 +# period_sink_count 0 +# period_source_count 2 +# type aif_out +# } + +Class.Widget."host" { + # + # The host object name would be constructed using the pipeline_id and direction arguments. + # E.g. "host.0.capture" or "host.2.playback" etc + # + + # + # Pipeline ID that the host widget belongs to + # + DefineAttribute."index" {} + + # + # PCM direction + # + DefineAttribute."direction" { + type "string" + } + + #include common component definition + + + DefineAttribute.uuid { + type "string" + # Token set reference name and type + token_ref "sof_tkn_comp.uuid" + } + + # Attribute categories + attributes { + # + # host objects instantiated within the same alsaconf node must have unique + # direction attribute + # + unique "direction" + constructor [ + "index" + "direction" + ] + mandatory [ + "type" + "stream_name" + ] + immutable [ + "uuid" + ] + deprecated [ + "preload_count" + ] + } + + # + # Default attributes for host + # + uuid "0c:10:9d:8b:78:6d:8f:41:90:a3:e0:e8:05:d0:85:2b" + no_pm "true" +} diff --git a/tools/topology2/include/components/pipeline.conf b/tools/topology2/include/components/pipeline.conf new file mode 100644 index 000000000000..8b539ea205f6 --- /dev/null +++ b/tools/topology2/include/components/pipeline.conf @@ -0,0 +1,118 @@ +# +# Class definition for pipeline widget +# +# This should be included within a pipeline class +# +# Usage: this component can be used by declaring in a parent object. i.e. +# +# Object.Widget.pipeline."N" { +# index 1 +# time_domain 0 +# period 1000 +# } +# +# Where N is the unique instance number for pipeline widget in the same alsaconf node. + +Class.Widget."pipeline" { + # pipeline_id for the pipeline widget + DefineAttribute."index" {} + + #include common component definition + + + # + # Bespoke Tuples for Pipelines + # + + DefineAttribute."instance" {} + + # Scheduling period + DefineAttribute."period" { + # Token reference and type + token_ref "sof_tkn_scheduler.word" + constraints { + min 333 + max 1000 + } + } + + # Scheduler time domain. The value provided will be translated to 0/1 based on + # sof_tkn_scheduler_time_domain. For exameple: "timer" will be converted to 0. + DefineAttribute."time_domain" { + # Token reference and type + token_ref "sof_tkn_scheduler.word" + constraints { + # Acceptable values + value_ref "sof_tkn_scheduler_time_domain" + valid_values [ + "timer" + "dma" + ] + tuple_values [ + 0 + 1 + ] + } + } + + DefineAttribute."priority" { + # Token reference and type + token_ref "sof_tkn_scheduler.word" + } + + DefineAttribute."lp_mode" { + # Token reference and type + token_ref "sof_tkn_scheduler.word" + } + + DefineAttribute."core" { + # Token reference and type + token_ref "sof_tkn_scheduler.word" + } + + DefineAttribute."frames" { + # Token reference and type + token_ref "sof_tkn_scheduler.word" + } + + DefineAttribute."mips" { + # Token reference and type + token_ref "sof_tkn_scheduler.word" + } + + DefineAttribute."dynamic" { + # Token reference and type + token_ref "sof_tkn_scheduler.word" + constraints { + value_ref "sof_tkn_bool" + valid_values [ + "true" + "false" + ] + } + } + + attributes { + constructor [ + "index" + ] + mandatory [ + "format" + "instance" + ] + immutable [ + "type" + ] + deprecated [ + "preload_count" + ] + # + # pipeline widget objects instantiated within the same alsaconf node must have + # unique instance attribute + unique instance + } + + # Default attributes for pipeline + type "scheduler" + no_pm "true" +} diff --git a/tools/topology2/include/components/volume.conf b/tools/topology2/include/components/volume.conf new file mode 100644 index 000000000000..d9228f3a2618 --- /dev/null +++ b/tools/topology2/include/components/volume.conf @@ -0,0 +1,150 @@ +# +# Common pipeline volume +# +# A generic volume widget. All attributes defined herein are namespaced +# by alsatplg to "pga.N.attribute_name" +# +# Usage: this component can be used by declaring int a parent object. i.e. +# +# Object.Widget.pga."N" { +# pipeline_id 1 +# index 0 +# } +# +# Where N is the unique instance number for pga widget in the same alsaconf node. + +Class.Widget."pga" { + # + # The PGA widget name would be constructed using the pipeline_id and index arguments. + # For ex: "pga.1.1" or "pga.10.2" etc. + # + DefineAttribute."index" {} + + # + # Unique index per widget type in pipeline. + # + DefineAttribute."instance" {} + + #include common component definition + + + DefineAttribute."uuid" { + type "string" + # Token set reference name and type + token_ref "sof_tkn_comp.uuid" + } + + # + # Bespoke attributes for PGA + # + + # Volume ramp step type. The values provided will be translated to integer values + # as specified by the value token reference "sof_tkn_volume_ramp". + # For example: "linear" is translated to 0, "log" to 1 etc. + DefineAttribute."ramp_step_type" { + type "string" + # Token set reference name + token_ref "sof_tkn_volume.word" + constraints { + valid_values [ + "linear" + "log" + "linear_zc" + "log_zc" + ] + tuple_values [ + 0 + 1 + 2 + 3 + ] + } + } + + # Volume ramp step in milliseconds + DefineAttribute."ramp_step_ms" { + # Token set reference name + token_ref "sof_tkn_volume.word" + } + + # Attribute categories + attributes { + constructor [ + "index" + "instance" + ] + immutable [ + "uuid" + "type" + ] + deprecated [ + "preload_count" + ] + # + # pga widget objects instantiated within the same alsaconf node must have unique + # index attribute + # + unique "instance" + } + + Object.Control { + mixer."0" { + #Channel register and shift for Front Left/Right + Object.Base.channel."fl" { + shift 0 + } + Object.Base.channel."fr" { + } + + Object.Base.tlv."vtlv_m64s2" { + Object.Base.scale."m64s2" { + mute 1 + } + } + + Object.Base.ops."ctl" { + info "volsw" + #256 binds the mixer control to volume get/put handlers + get 256 + put 256 + } + } + + mixer."1" { + Object.Base.channel."flw" { + reg 2 + shift 0 + } + Object.Base.channel."fl" { + reg 2 + shift 1 + } + Object.Base.channel."fr" { + reg 2 + shift 2 + } + Object.Base.channel."frw" { + reg 2 + shift 3 + } + + Object.Base.ops."ctl" { + info "volsw" + #259 binds the mixer control to switch get/put handlers + get "259" + put "259" + } + + #max 1 indicates switch type control + max 1 + invert "false" + } + } + + # Set default attribute values for Volume + type "pga" + uuid "7e:67:7e:b7:f4:5f:88:41:af:14:fb:a8:bd:bf:86:82" + no_pm "true" + period_sink_count 2 + period_source_count 2 +} diff --git a/tools/topology2/include/controls/common.conf b/tools/topology2/include/controls/common.conf new file mode 100644 index 000000000000..c799ff567f8a --- /dev/null +++ b/tools/topology2/include/controls/common.conf @@ -0,0 +1,158 @@ +# Common class definitions for controls + +# +# Class for channel objects. These are instantiated as: +# Object.Base.channel."fl" { +# reg 1 +# shift 0 +# } +# +Class.Base."channel" { + + # name of the channel + DefineAttribute."name" { + type "string" + } + + DefineAttribute."reg" {} + + DefineAttribute."shift" {} + + attributes { + constructor [ + "name" + ] + # + # scale objects instantiated within the same alsaconf node must have unique + # name attribute + # + unique "name" + } + + reg 1 + shift 1 +} + +# Class definition for control ops. These are instantiated as: +# Object.Base.ops."ctl" { +# info "volsw" +# get "259" +# put "259" +# } +# +Class.Base."ops" { + # ops name + DefineAttribute."name" { + type "string" + } + + DefineAttribute."info" {} + + DefineAttribute."get" {} + + DefineAttribute."put" {} + + attributes { + constructor [ + "name" + ] + mandatory [ + "info" + ] + # + # ops objects instantiated within the same alsaconf node must have unique + # name attribute + # + unique "name" + } +} + +# Class definition for control extops. These are instantiated as: +# Object.Base.extops."ctl" { +# info "volsw" +# get "258" +# put "258" +# } +# +Class.Base."extops" { + # extops name + DefineAttribute."name" { + type "string" + } + + DefineAttribute."info" {} + + DefineAttribute."get" {} + + DefineAttribute."put" {} + + attributes { + constructor [ + "name" + ] + mandatory [ + "get" + "put" + ] + # + # extops objects instantiated within the same alsaconf node must have unique + # name attribute + # + unique "name" + } +} + +# +# Class definition for scale objects. These are instantiated as follows: +# Object.Base.scale."name" { +# mute 1 +# } +# +Class.Base."scale" { + DefineAttribute."name" { + type "string" + } + + DefineAttribute."min" {} + + DefineAttribute."step" {} + + DefineAttribute."mute" {} + + attributes { + constructor [ + "name" + ] + # + # scale objects instantiated within the same alsaconf node must have unique + # name attribute + # + unique "name" + } + + # Default scale attributes: "-64dB step 2dB" + min -6400 + step 200 + mute 1 +} + +# +# Class definition for tlv objects. These are instantiated as follows: +# Object.Base.tlv."vtlv_m64s2" { +# Object.Base.scale."0" {} +# } +Class.Base."tlv" { + DefineAttribute."name" { + type "string" + } + attributes { + constructor [ + "name" + ] + # + # TLV objects instantiated within the same alsaconf node must have unique + # name attribute + # + unique "name" + } +} diff --git a/tools/topology2/include/controls/mixer.conf b/tools/topology2/include/controls/mixer.conf new file mode 100644 index 000000000000..b7cff1e7e4b4 --- /dev/null +++ b/tools/topology2/include/controls/mixer.conf @@ -0,0 +1,85 @@ +# +# Mixer control. All attributes defined herein are namespaced +# by alsatplg to "mixer.N.attribute_name" +# +# Usage: this component can be used by instantiating it in the parent object. i.e. +# +# Object.Control.mixer."N" { +# pipeline_id 1 +# index 0 +# } +# +# Where N is the unique instance number for the buffer object within the same alsaconf node. +# The mixer control object should also include the ops, channels and tlv objects. + + + +Class.Control."mixer" { + # + # The Mixer object name would be constructed using the pipeline_id and index arguments. + # For ex: "mixer.1.1" or "mixer.10.2" etc. + # + DefineAttribute."index" {} + DefineAttribute."instance" {} + + DefineAttribute."name" { + type "string" + } + + DefineAttribute."max" {} + + DefineAttribute."invert" { + type "string" + constraints { + valid_values [ + "true" + "false" + ] + } + } + + DefineAttribute."access" { + type "compound" + constraints { + valid_values [ + "read_write" + "tlv_read_write" + "read" + "write" + "volatile" + "tlv_read" + "tlv_write" + "tlv_command" + "inactive" + "lock" + "owner" + "tlv_callback" + ] + } + } + + attributes { + constructor [ + "index" + "instance" + ] + mandatory [ + "instance" + "index" + ] + # + # mixer control objects instantiated within the same alsaconf node must have unique + # index attribute + # + unique "instance" + } + + # Default attribute values for mixer control + access [ + "read" + "write" + ] + + max 32 + invert "false" +} diff --git a/tools/topology2/include/dais/hw_config.conf b/tools/topology2/include/dais/hw_config.conf new file mode 100644 index 000000000000..027e8924a55e --- /dev/null +++ b/tools/topology2/include/dais/hw_config.conf @@ -0,0 +1,83 @@ +# Class definition for hw_config objects for DAIs +# These are instantiated as follows: +#Object.hw_config."N" { +# id 0 +# mclk_freq 24000000 +# bclk_freq 4800000 +# tdm_slot_width 25 +# } +# where N is the unique instance number for the hw_config object within the same alsaconf node. +Class.Base."hw_config" { + # + # Argument used to construct hw config (hw config ID) + # + DefineAttribute."id" {} + DefineAttribute."name" { + type "string" + } + + # All attributes are only used for SSP. + + DefineAttribute."format" { + type "string" + constraints { + valid_values [ + "I2S" + "DSP_A" + "DSP_B" + ] + } + } + + DefineAttribute."mclk" { + type "string" + } + + DefineAttribute."mclk_freq" {} + + DefineAttribute."bclk" { + type "string" + } + + DefineAttribute."bclk_freq" {} + + DefineAttribute."fsync" { + type "string" + } + + DefineAttribute."fsync_freq" {} + + DefineAttribute."tdm_slots" {} + + DefineAttribute."tdm_slot_width" {} + + DefineAttribute."tx_slots" {} + + DefineAttribute."rx_slots" {} + + attributes { + constructor [ + "id" + ] + mandatory [ + "bclk_freq" + "tdm_slot_width" + ] + # + # hw_cfg objects instantiated within the same alsaconf node must have unique + # 'name' attribute + # + unique "name" + } + + #TODO: Add link flags + + format "I2S" + mclk "codec_mclk_in" + bclk "codec_consumer" + fsync "codec_consumer" + fsync_freq 48000 + tdm_slots 2 + tx_slots 3 + rx_slots 3 +} diff --git a/tools/topology2/include/dais/ssp.conf b/tools/topology2/include/dais/ssp.conf new file mode 100644 index 000000000000..bb00a26780f3 --- /dev/null +++ b/tools/topology2/include/dais/ssp.conf @@ -0,0 +1,150 @@ +# +# Intel SSP DAI +# +# All attributes defined herein are namespaced +# by alsatplg to "ssp.N.attribute_name" +# +# Usage: this component can be used by declaring in the "dais" field of +# a parent object. i.e. +# +# For Capture +# Object.SSP."N" { +# direction "capture" +# stream_name "NoCodec-0" +# id 0 +# format "s24le" +# quirks "lbm_mode" +# sample_bits 24 +# Object.hw_config."0" { +# mclk_freq 24000000 +# bclk_freq 4800000 +# tdm_slot_width 25 +# } +# Object.dai."capture" { +# period_source_count 0 +# period_sink_count 2 +# } +# } +# +# For Duplex +# Object.SSP."N" { +# direction "duplex" +# dai_name "NoCodec-0" +# id 0 +# format "s24le" +# quirks "lbm_mode" +# sample_bits 24 +# Object.hw_config."0" { +# mclk_freq 24000000 +# bclk_freq 4800000 +# tdm_slot_width 25 +# } +# Object.dai."playback" { +# period_source_count 2 +# period_sink_count 0 +# } +# } +# +# where N is the unique instance number for the SSP object within the same alsaconf node. + +# SSP port definition +Class.Dai."SSP" { + + # + # Argument used to construct DAI widget + # + # Playback DAI Index + DefineAttribute."dai_index" { + token_ref "sof_tkn_dai.word" + } + + DefineAttribute."direction" { + type "string" + } + + DefineAttribute."dai_type" { + type "string" + token_ref "sof_tkn_dai.string" + } + + DefineAttribute."default_hw_config_id" {} + + DefineAttribute."stream_name" { + type "string" + } + + DefineAttribute."format" { + type "string" + constraints { + valid_values [ + "s32le" + "s24le" + "s16le" + "float" + ] + } + } + + # Backend DAI Link ID matching with the machine driver + DefineAttribute."id" {} + + DefineAttribute."sample_bits" { + # Token reference and type + token_ref "sof_tkn_intel_ssp.word" + } + + DefineAttribute."bclk_delay" { + # Token reference and type + token_ref "sof_tkn_intel_ssp.word" + } + + # SSP quirks. Value will translated based on sof_tkn_ssp_quirks. For ex: lb_mode will + # be converted to 64. + DefineAttribute."quirks" { + # Token reference and type + token_ref "sof_tkn_intel_ssp.word" + constraints { + value_ref "sof_tkn_intel_ssp_quirks" + valid_values [ + "lbm_mode" + ] + tuple_values [ + 64 + ] + + } + } + + DefineAttribute."mclk_id" { + # Token reference and type + token_ref "sof_tkn_intel_ssp.short" + } + + attributes { + constructor [ + "dai_index" + "direction" + ] + mandatory [ + "stream_name" + "format" + "id" + "sample_bits" + "index" + "default_hw_config_id" + ] + immutable [ + "dai_type" + ] + # + # SSP DAI objects instantiated within the same alsaconf node must have unique + # index attribute + # + unique "dai_index" + } + + dai_type "SSP" + bclk_delay 0 + mclk_id 0 + default_hw_config_id 0 +} diff --git a/tools/topology2/include/pipelines/pipeline-common.conf b/tools/topology2/include/pipelines/pipeline-common.conf new file mode 100644 index 000000000000..220b0ec1fbb3 --- /dev/null +++ b/tools/topology2/include/pipelines/pipeline-common.conf @@ -0,0 +1,91 @@ +# +# Common pipeline definitions. To be included in Class.Pipeline definitions +# + +# Number of channels +DefineAttribute."channels" { + constraints { + min 2 + max 8 + } +} + +DefineAttribute."channels_min" { +} +DefineAttribute."channels_max" { +} + +# Pipeline format +DefineAttribute."format" { + type "string" + constraints { + valid_values [ + "s32le" + "s24le" + "s16le" + "float" + ] + } +} + +# Sampling rate +DefineAttribute."rate" { + constraints { + min 48000 + max 196000 + } +} + +DefineAttribute."rate_min" {} +DefineAttribute."rate_max" {} + +# Pipeline direction +DefineAttribute."direction" { + type "string" + constraints { + valid_values [ + "playback" + "capture" + ] + } +} + +# Scheduling period +DefineAttribute."period" { + # Token reference and type + token_ref "sof_tkn_scheduler.word" + constraints { + min 333 + max 1000 + } +} + +# Scheduler time domain. The value provided will be translated to 0/1 based on +# sof_tkn_scheduler_time_domain. For exameple: "timer" will be converted to 0. +DefineAttribute."time_domain" { + # Token reference and type + type "string" + token_ref "sof_tkn_scheduler.word" + constraints { + # Acceptable values for time_domain + valid_values [ + "timer" + "dma" + ] + } +} + +# Boolean flag to indicate if the pipeline is dynamic. +DefineAttribute."dynamic" { + type "string" + constraints { + valid_values [ + "true" + "false" + ] + } +} + +# by default all pipelines should be dynamic and should be explicitly set to false if needed when +# instantiating the pipeline object +dynamic "true" diff --git a/tools/topology2/include/pipelines/pipeline-volume-capture.conf b/tools/topology2/include/pipelines/pipeline-volume-capture.conf new file mode 100644 index 000000000000..bbed51a38845 --- /dev/null +++ b/tools/topology2/include/pipelines/pipeline-volume-capture.conf @@ -0,0 +1,103 @@ +# +# Volume capture pipeline +# +# A simple pipeline. All attributes defined herein are namespaced by alsatplg to +# "pipeline-volume-capture.N.attribute_name" +# +# Usage: this component can be used by declaring in the top-level topology conf file as follows: +# +# Object.volume-capture."N" { +# format "s16le" +# period 1000 +# time_domain "timer" +# channels 2 +# rate 48000 +# } +# +# and N is the unique pipeline_id for this pipeline object within the same alsaconf node. +# +# +# (sink) host.N.playback <- buffer.N.0 <- volume.N.0 <- buffer.N.1 (source endpoint) +# +Class.Pipeline."volume-capture" { + + DefineAttribute."index" {} + + + + attributes { + constructor [ + "index" + ] + mandatory [ + "format" + ] + immutable [ + "direction" + ] + # + # volume-capture objects instantiated within the same alsaconf node must have + # unique index attribute + # + unique "index" + } + + Object.Widget { + pipeline."0" { + core 0 + frames 0 + priority 0 + mips 5000 + } + + host."capture" { + period_sink_count 0 + period_source_count 2 + type "aif_out" + } + + buffer."0" { + periods 2 + caps "host" + } + + pga."0" { + ramp_step_type "linear" + ramp_step_ms 250 + } + + buffer."1" { + periods 2 + caps "dai" + } + } + + # Pipeline connections + Object.Base { + route."0" { + source "buffer..0" + sink "host..capture" + } + + route."1" { + source "pga..0" + sink "buffer..0" + } + + route."2" { + source "buffer..1" + sink "pga..0" + } + } + + # Default attribute values + direction "capture" + time_domain "timer" + period 1000 + channels 2 + channels_min 2 + channels_max 2 + rate 48000 + rate_min 48000 + rate_max 48000 +} diff --git a/tools/topology2/include/pipelines/pipeline-volume-playback.conf b/tools/topology2/include/pipelines/pipeline-volume-playback.conf new file mode 100644 index 000000000000..e82232fb9260 --- /dev/null +++ b/tools/topology2/include/pipelines/pipeline-volume-playback.conf @@ -0,0 +1,105 @@ +# +# Volume playback pipeline +# +# A simple pipeline. All attributes defined herein are namespaced by alsatplg to +# "pipeline-volume-playback.N.attribute_name" +# +# Usage: this component can be used by declaring in the top-level topology conf file as follows: +# +# Object.pipeline-volume-playback."N" { +# format "s16le" +# period 1000 +# time_domain "timer" +# channels 2 +# rate 48000 +# } +# +# where N is the unique pipeline_id for this pipeline object within the same alsaconf node. +# +# +# (source) host.N.playback -> buffer.N.0 -> volume.N.0 -> buffer.N.1 (sink endpoint) +# +Class.Pipeline."volume-playback" { + + DefineAttribute."index" {} + + + + attributes { + constructor [ + "index" + ] + mandatory [ + "format" + ] + immutable [ + "direction" + ] + # + # volume-playback objects instantiated within the same alsaconf node must have + # unique pipeline_id attribute + # + unique "index" + } + + Object.Widget { + pipeline."0" { + core 0 + frames 0 + priority 0 + mips 5000 + } + + host."playback" { + period_sink_count 2 + period_source_count 0 + type "aif_in" + } + + buffer."0" { + periods 2 + caps "host" + } + + pga."0" { + ramp_step_type "linear" + ramp_step_ms 250 + } + + buffer."1" { + periods 2 + caps "dai" + } + } + + # Pipeline connections + # The index attribute values for the source/sink widgets will be populated + # when the route objects are built + Object.Base { + route."0" { + source "host..playback" + sink "buffer..0" + } + + route."1" { + source "buffer..0" + sink "pga..0" + } + + route."2" { + source "pga..0" + sink "buffer..1" + } + } + + # Default attribute values + direction "playback" + time_domain "timer" + period 1000 + channels 2 + channels_min 2 + channels_max 2 + rate 48000 + rate_min 48000 + rate_max 48000 +} diff --git a/tools/topology2/sof-cnl-nocodec.conf b/tools/topology2/sof-cnl-nocodec.conf new file mode 100644 index 000000000000..989022c759d1 --- /dev/null +++ b/tools/topology2/sof-cnl-nocodec.conf @@ -0,0 +1,142 @@ + +# +# Simple Machine - High level topology - Maps to machine driver. +# +# +# PCM 0 <-> bufferN.0 <-> volumeN.0 <-> bufferN.1 -> SSP0 +# + + + + + + + + + + + + + + + + + + + + + + +# +# Pipeline definitions +# + +# Pipeline ID:1 +Object.Pipeline.volume-playback."1" { + format "s24le" + + # set the mixer name for PGA.0 + Object.Widget.pga.0 { + Object.Control.mixer.0 { + name "1 Master Playback Volume" + } + } + + # set pipeline stream_name + Object.Widget.pipeline.0.stream_name "dai.SSP.0.playback" + + # set host stream_name to be same as the playback PCM caps + Object.Widget.host.playback.stream_name "Port0 Playback" +} + +# Pipeline ID:2 +Object.Pipeline.volume-capture."2" { + pipeline_id 2 + format "s24le" + + # set the mixer name for PGA.0 + Object.Widget.pga.0 { + Object.Control.mixer.0 { + name "2 Master Capture Volume" + } + Object.Control.mixer.1 { + name "2 Master Capture Switch" + } + } + + # set pipeline stream_name + Object.Widget.pipeline.0.stream_name "dai.SSP.0.capture" + + # set host stream_name to be same as the capture PCM caps + Object.Widget.host.capture.stream_name "Port0 Capture" +} + +# +# PCM Definitions +# +# PCM ID: 0 +Object.PCM.pcm."0" { + name "Port0" + direction "duplex" + Object.Base.fe_dai."Port 0" {} + Object.PCM.pcm_caps."playback" { + name "Port0 Playback" + } + Object.PCM.pcm_caps."capture" { + name "Port0 Capture" + } +} + +# +# List of all DAI's +# +# SSP Index: 0, Direction: duplex +# +Object.Dai.SSP."0" { + direction "duplex" + stream_name "NoCodec-0" + id 0 + default_hw_conf_id 0 + format "s24le" + quirks "lbm_mode" + sample_bits 24 + Object.Base.hw_config."SSP0 hw_config 0" { + id 0 + mclk_freq 24000000 + bclk_freq 4800000 + tdm_slot_width 25 + } + + #Add DAI widgets + Object.Widget.dai."playback" { + type "dai_in" + period_source_count 2 + period_sink_count 0 + index 1 + } + + Object.Widget.dai."capture" { + type "dai_out" + period_source_count 0 + period_sink_count 2 + index 2 + } +} + +# +# List of all endpoint connections +# +Object.Base { + # Connect: Pipeline 1 Buffer 1 -> SSP 0 Playback DAI + route."0" { + source "buffer.1.1" + sink "dai.SSP.0.playback" + } + + # Connect: SSP 0 Capture DAI -> Pipeline 2 Buffer 1 + route."1" { + source "dai.SSP.0.capture" + sink "buffer.2.1" + } +} +