diff --git a/scripts/build-tools.sh b/scripts/build-tools.sh index 6718f915689d..15a137471f38 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 tests: make -C "$BUILD_TOOLS_DIR" tests topologies: make -C "$BUILD_TOOLS_DIR" topologies + 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..e8aee10c7073 --- /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} -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..46c4e70f96cb --- /dev/null +++ b/tools/topology2/get_abi.sh @@ -0,0 +1,22 @@ +#!/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 connection object within the same alsaconf node. +# +# Example: endpoint connection +# Object.connection."N" { +# source "Object.buffer.2" +# sink "Object.pga.2" +# } +# The above object specifies the route: "buffer.2 -> pga.2" where buffer.2 is the buffer object +# with index 2 and pga.2 refers to the PGA object with index 2 in the parent object. +# and N is the unique instance number for the connection object within the same alsaconf node. +# +# +Class.Base."connection" { + DefineArgument."index" {} + + # 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" {} + + # these attributes will be set by the alsatplg compiler after resolving the Object + # reference + DefineAttribute."source_widget" {} + DefineAttribute."sink_widget" {} + + attributes { + mandatory [ + "source" + "sink" + ] + automatic [ + "source_widget" + "sink_widget" + ] + # + # index attribute values for connection objects must be unique in the same alsaconf + # node + # + unique "index" + } +} diff --git a/tools/topology2/include/common/data.conf b/tools/topology2/include/common/data.conf new file mode 100644 index 000000000000..b57f4a8075e8 --- /dev/null +++ b/tools/topology2/include/common/data.conf @@ -0,0 +1,18 @@ +# Class definition for data object +Class.Base."data" { + + DefineArgument."name" {} + + DefineAttribute."bytes" {} + + attributes { + mandatory [ + "name" + ] + # + # name attribute values for data objects must be unique in the same alsaconf + # node + # + unique "name" + } +} diff --git a/tools/topology2/include/common/manifest.conf b/tools/topology2/include/common/manifest.conf new file mode 100644 index 000000000000..493ae26e1de8 --- /dev/null +++ b/tools/topology2/include/common/manifest.conf @@ -0,0 +1,16 @@ +# Class definition for manifest object +Class.Base."manifest" { + DefineArgument."name" {} + + attributes { + mandatory [ + "name" + ] + # + # name attribute values for manifest objects must be unique in the same alsaconf + # node + # + unique "name" + } + +} diff --git a/tools/topology2/include/common/pcm.conf b/tools/topology2/include/common/pcm.conf new file mode 100644 index 000000000000..5fa760d1229b --- /dev/null +++ b/tools/topology2/include/common/pcm.conf @@ -0,0 +1,47 @@ +# PCM Class definition. PCM object can be instantiated as: +# PCM +# Object.pcm."N" { +# pcm_name "Headset" +# direction "playback" +# pcm_id 2 +# } +# where N is the unique instance number for the PCM object within the same alsaconf node. +Class.PCM."pcm" { + # + # Argument used to construct PCM + # + DefineArgument."pcm_name" {} + + DefineArgument."direction" {} + + DefineArgument."pcm_id" {} + + DefineAttribute."compress" {} + + DefineAttribute."playback_compatible_d0i3" { + # Token reference and type + token_ref "sof_tkn_stream.bool" + } + + DefineAttribute."capture_compatible_d0i3" { + # Token reference and type + token_ref "sof_tkn_stream.bool" + } + + attributes { + mandatory [ + "compress" + "pcm_name" + "pcm_id" + "direction" + ] + # + # pcm_id attribute values for pcm objects must be unique in the same alsaconf + # node + # + unique "pcm_id" + } + + # Default values for PCM attributes + compress "false" +} diff --git a/tools/topology2/include/common/pcm_caps.conf b/tools/topology2/include/common/pcm_caps.conf new file mode 100644 index 000000000000..4b177356d460 --- /dev/null +++ b/tools/topology2/include/common/pcm_caps.conf @@ -0,0 +1,88 @@ +# PCM Capabilities Class definition. PCM object can be instantiated as: + +# Object.pcm_caps."N" { +# pcm_name "Headset" +# direction "playback" +# pcm_id 2 +# formats "S32_LE,S24_LE,S16_LE" +# rate_min 48000 +# rate_max 48000 +# channels_min 2 +# channels_max 2 +# periods_min 2 +# } +# where N is the unique instance number for the pcm_caps object within the same alsaconf node. + +Class.PCM."pcm_caps" { + # + # Argument used to construct PCM Capabilities + # + DefineArgument."pcm_name" {} + + DefineArgument."direction" {} + + DefineArgument."pcm_id" {} + + DefineAttribute."formats" {} + + DefineAttribute."rates" {} + + DefineAttribute."sigbits" {} + + DefineAttribute."rate_min" {} + + DefineAttribute."rate_max" {} + + DefineAttribute."channels_min" {} + + DefineAttribute."channels_max" {} + + DefineAttribute."periods_min" {} + + DefineAttribute."periods_max" {} + + DefineAttribute."period_size_min" {} + + DefineAttribute."period_size_max" {} + + DefineAttribute."buffer_size_min" {} + + DefineAttribute."buffer_size_max" {} + + attributes { + mandatory [ + "pcm_name" + "pcm_id" + "direction" + "formats " + "rate_min" + "rate_max" + "channels_min" + "channels_max" + "periods_min" + "periods_max" + "period_size_min" + "period_size_max" + "buffer_size_min" + "buffer_size_max" + ] + # + # pcm_id attribute values for pcm_caps objects must be unique in the same alsaconf + # node + # + unique "pcm_id" + } + + # Default attribute values for PCM capabilities + formats "S32_LE,S24_LE,S16_LE" + rate_min 48000 + rate_max 48000 + channels_min 2 + channels_max 2 + periods_min 2 + periods_max 16 + period_size_min 192 + period_size_max 16384 + buffer_size_min 65536 + buffer_size_max 65536 +} diff --git a/tools/topology2/include/common/pipe_endpoint.conf b/tools/topology2/include/common/pipe_endpoint.conf new file mode 100644 index 000000000000..b66ea099f6af --- /dev/null +++ b/tools/topology2/include/common/pipe_endpoint.conf @@ -0,0 +1,41 @@ +# Class definition for pipeline endpoint objects +# These are instantiated as follows: +# Object.endpoint."N" { +# widget "Object.buffer.0" +# } +# where N is the unique instance number for the endpoint object within the same alsaconf node. +# and widget refers to the buffer object with index 0 in the parent object that instantiates +# the endpoint. + +Class.Base."endpoint" { + DefineArgument."pipeline_id" { + type "integer" + } + + # unique identifier for endpoints in parent object + DefineArgument."index" { + type "integer" + } + + # widget attribute should refer to an Object of a certain class with a unique value. + # in the parent object_list + DefineAttribute."widget" {} + + # the widget_name will be set by the alsatplg compiler after resolving the object + # reference + DefineAttribute."widget_name" {} + + attributes { + mandatory [ + "widget" + ] + automatic [ + "widget_name" + ] + # + # index attribute values for endpoint objects must be unique in the same alsaconf + # node + # + unique "index" + } +} diff --git a/tools/topology2/include/common/tokens.conf b/tools/topology2/include/common/tokens.conf new file mode 100644 index 000000000000..80f5d6c8e09d --- /dev/null +++ b/tools/topology2/include/common/tokens.conf @@ -0,0 +1,79 @@ +SectionVendorTokens."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" +} + +SectionVendorTokens."sof_tkn_dai" { +# Token retired with ABI 3.2, do not use for new capabilities + dmac_config "153" + type "154" + index "155" + direction "156" +} + +SectionVendorTokens."sof_tkn_direction" { + playback "0" + capture "1" +} + +SectionVendorTokens."sof_tkn_bool" { + false "0" + true "1" +} + +SectionVendorTokens."sof_tkn_buffer" { + size "100" + caps "101" +} + +SectionVendorTokens."sof_tkn_volume_ramp_type" { + linear "0" + log "1" + linear_zc "2" + log_zc "3" +} + +SectionVendorTokens."sof_tkn_volume" { + ramp_step_type "250" + ramp_step_ms "251" +} + +SectionVendorTokens."sof_tkn_scheduler" { + period "200" + priority "201" + mips "202" + core "203" + frames "204" + time_domain "205" + dynamic "206" + lp_mode "207" +} + +SectionVendorTokens."sof_tkn_scheduler_time_domain" { + dma "0" + timer "1" +} + +SectionVendorTokens."sof_tkn_intel_ssp_quirks" { + lbm_mode "64" +} + +SectionVendorTokens."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" +} + +SectionVendorTokens."sof_tkn_stream" { + playback_compatible_d0i3 "1200" + capture_compatible_d0i3 "1201" +} diff --git a/tools/topology2/include/components/buffer.conf b/tools/topology2/include/components/buffer.conf new file mode 100644 index 000000000000..7700ef1197d6 --- /dev/null +++ b/tools/topology2/include/components/buffer.conf @@ -0,0 +1,106 @@ +# 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.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.Component."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. + # + DefineArgument."pipeline_id" {} + # + # Unique index per widget type in pipeline. + # + DefineArgument."index" {} + + #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" { + # Token reference and type + token_ref "sof_tkn_buffer.word" + constraints { + value_ref "sof_tkn_mem" + values [ + "dai" + "host" + "pass" + "comp" + ] + } + } + + # Attribute categories + attributes { + mandatory [ + "no_pm" + "uuid" + "widget_type" + "periods" + "caps" + "pipeline_id" + "index" + ] + immutable [ + "uuid" + "widget_type" + ] + automatic [ + "size" + ] + deprecated [ + "preload_count" + ] + # + # index attribute values for buffer objects must be unique in the same alsaconf + # node + # + unique "index" + } + + # + # Default attributes for Buffers + # + widget_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..ac43523485a0 --- /dev/null +++ b/tools/topology2/include/components/component.conf @@ -0,0 +1,74 @@ +# +# 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" { + constraints { + values [ + "true" + "false" + ] + } +} + +# +# Widget Type - maps to the widget ID with values of type enum SND_SOC_TPLG_DAPM_* +# +DefineAttribute."widget_type" {} + +# +# Stream name - maps to the DAPM widget's sname +# +DefineAttribute."stream_name" {} + +# +# Widget events to bind to +# +DefineAttribute.event_flags {} +DefineAttribute.event_type {} + +# +# Tuple definitions added to widget's private data +# + +# number of sink periods +DefineAttribute."period_sink_count" { + # Token set reference name and type + token_ref "sof_tkn_comp.word" +} + +# number of source preiods +DefineAttribute."period_source_count" { + # Token set reference name and type + token_ref "sof_tkn_comp.word" +} + +# audio format +DefineAttribute."format" { + # Token set reference name and type + token_ref "sof_tkn_comp.string" + constraints { + 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..7371fc543a22 --- /dev/null +++ b/tools/topology2/include/components/dai.conf @@ -0,0 +1,111 @@ +# +# A generic dai component. All attributes defined herein are namespaced +# by alsatplg to "dai.N.attribute_name" +# +# For playback +# Object.dai."playback" { +# type SSP +# index 1 +# direction "playback" +# period_sink_count "2" +# period_source_count "0" +# widget_type "dai_in" +# } +# +# For Capture +# Object.dai."capture" { +# type SSP +# index 2 +# direction "capture" +# period_sink_count "0" +# period_source_count "2" +# widget_type "dai_out" +# } +# +# The widget_type for DAI should be specified when the object is created based on the direction. + +Class.Component."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 + DefineArgument."type" { + token_ref "sof_tkn_dai.string" + constraints { + values [ + "SSP" + "DMIC" + "HDA" + "ALH" + "ESAI" + ] + } + } + + # DAI Index in the firmware + DefineArgument."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 + # + DefineArgument."direction" { + token_ref "sof_tkn_dai.word" + constraints { + value_ref "sof_tkn_direction" + values [ + "playback" + "capture" + ] + } + } + + #include common component definition + + + DefineAttribute."pipeline_id" {} + + DefineAttribute.uuid { + # Token set reference name and type + token_ref "sof_tkn_comp.uuid" + } + + # Bespoke attributes for DAI + DefineAttribute."format" { + # Token reference and type + token_ref "sof_tkn_comp.string" + } + + # Attribute categories + attributes { + mandatory [ + "no_pm" + "uuid" + "widget_type" + "type" + "stream_name" + "format" + "index" + "direction" + ] + immutable [ + "uuid" + ] + deprecated [ + "preload_count" + ] + # + # direction attribute values for dai objects must be unique in the same + # alsaconf node + # + 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..929c477265d0 --- /dev/null +++ b/tools/topology2/include/components/host.conf @@ -0,0 +1,86 @@ +# A generic host component. All attributes defined herein are namespaced +# by alsatplg to "host.N.attribute_name" +# +# Usage: this component can be used by declaring in the "widgets" field of +# a parent object. i.e. +# +# For playback +# Object.host."N" { +# pipeline_id 3 +# direction "playback" +# period_sink_count "2" +# period_source_count "2" +# widget_type "aif_in" +# } +# +# For Capture +# Object.host."N" { +# pipeline_id 4 +# direction "capture" +# period_sink_count "2" +# period_source_count "2" +# widget_type "aif_out" +# } +# where N a unique number for the host instance within the same alsaconf node +# and M is the pipeline_id +# The widget_type for host should be specified when the object is created based on the direction. + +Class.Component."host" { + # + # The host name would be constructed using the pipeline_id and direction arguments. + # For ex: "host.M.capture" or "host.N.playback" etc + # + DefineArgument."pipeline_id" {} + + # + # PCM direction + # + DefineArgument."direction" {} + + #include common component definition + + + DefineAttribute.index {} + + DefineAttribute.uuid { + # Token set reference name and type + token_ref "sof_tkn_comp.uuid" + } + + # + # Bespoke attributes for "host" + # + + # PCM_ID and PCM_NAME associated with the host widget are used to set its stream name + # If the stream_name attribute value is set, these are simply ignored. + DefineAttribute."pcm_id" {} + DefineAttribute."pcm_name" {} + + # Attributes constraints + attributes { + mandatory [ + "no_pm" + "uuid" + "widget_type" + "pipeline_id" + "direction" + ] + immutable [ + "uuid" + ] + automatic [ + "stream_name" + ] + deprecated [ + "preload_count" + ] + # index attribute values for host objects must be unique in the same alsaconf node + unique "index" + } + + # + # 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..9ed69e285ed5 --- /dev/null +++ b/tools/topology2/include/components/pipeline.conf @@ -0,0 +1,108 @@ + +# +# Class definition for pipeline widget +# +# This should be included within a pipeline class +# + +Class.Component."pipeline" { + # + # Argument used to construct component: pipeline ID + # + DefineArgument."pipeline_id" {} + + #include common component definition + + + # + # Bespoke Tuples for Pipelines + # + + DefineAttribute."index" {} + + # 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" + values [ + "timer" + "dma" + ] + } + } + + 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" + values [ + "true" + "false" + ] + } + } + + attributes { + mandatory [ + "no_pm" + "widget_type" + "dynamic" + "pipeline_id" + ] + immutable [ + "widget_type" + ] + deprecated [ + "preload_count" + ] + # + # index attribute values for pipeline objects must be unique in the same alsaconf + # node + # + unique "index" + } + + # Default attributes for pipeline + widget_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..1ac5b64dd32b --- /dev/null +++ b/tools/topology2/include/components/volume.conf @@ -0,0 +1,159 @@ +# +# Common pipeline volume +# +# A generic volume component. All attributes defined herein are namespaced +# by alsatplg to "pga.N.attribute_name" +# +# Usage: this component can be used by declaring in the "widgets" field of +# a parent object. i.e. +# +# Object.pga."N" { +# pipeline_id 1 +# index 0 +# period_source_count "2" +# period_sink_count "2" +# } +# +# Where N is the unique instance number for pga widget in the same alsaconf node. + + + +Class.Component."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. + # + DefineArgument."pipeline_id" {} + + # + # Unique index per widget type in pipeline. + # + DefineArgument."index" {} + + #include common component definition + + + DefineAttribute."uuid" { + # 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" { + # Token set reference name + token_ref "sof_tkn_volume.word" + constraints { + value_ref "sof_tkn_volume_ramp_type" + values [ + "linear" + "log" + "linear_zc" + "log_zc" + ] + } + } + + # Volume ramp step in milliseconds + DefineAttribute."ramp_step_ms" { + # Token set reference name + token_ref "sof_tkn_volume.word" + } + + # Attribute categories + attributes { + mandatory [ + "no_pm" + "uuid" + "widget_type" + "pipeline_id" + "index" + ] + immutable [ + "uuid" + "widget_type" + ] + deprecated [ + "preload_count" + ] + # + # index attribute values for pga objects must be unique in the same alsaconf + # node + # + unique "index" + } + + Object.mixer."0" { + #Channel register and shift for Front Left/Right + Object.channel."0" { + name "fl" + shift 0 + } + Object.channel."1" { + name "fr" + } + + Object.tlv."0" { + name "vtlv_m64s2" + Object.scale."0" { + name "m64s2" + mute 1 + } + } + + Object.ops."0" { + name "ctl" + info "volsw" + #256 binds the mixer control to volume get/put handlers + get 256 + put 256 + } + } + + Object.mixer."1" { + Object.channel."0" { + name "flw" + reg 2 + shift 0 + } + Object.channel."1" { + name "fl" + reg 2 + shift 1 + } + Object.channel."2" { + name "fr" + reg 2 + shift 2 + } + Object.channel."3" { + name "frw" + reg 2 + shift 3 + } + + Object.ops."0" { + mame "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 + widget_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..52f23a9a1a17 --- /dev/null +++ b/tools/topology2/include/controls/common.conf @@ -0,0 +1,152 @@ +# Common class definitions for controls + +# +# Class for channel objects. These are instantiated as: +# Object.channel."N" { +# name "fl" +# reg 1 +# shift 0 +# } +# Where N is the unique instance number for channel object in the same alsaconf node. +# +Class.Base."channel" { + + # name of the channel + DefineArgument."name" {} + + DefineAttribute."reg" {} + + DefineAttribute."shift" {} + + attributes { + mandatory [ + "reg" + "shift" + ] + # + # index attribute values for channel objects must be unique in the same alsaconf + # node + # + unique "name" + } + + reg 1 + shift 1 +} + +# Class definition for control ops. These are instantiated as: +# Object.ops."0" { +# name "ctl" +# info "volsw" +# get "259" +# put "259" +# } +# +Class.Base."ops" { + # ops name + DefineArgument."name" {} + + DefineAttribute."info" {} + + DefineAttribute."get" {} + + DefineAttribute."put" {} + + attributes { + mandatory [ + "info" + ] + # + # index attribute values for ops objects must be unique in the same alsaconf + # node + # + unique "name" + } +} + +# Class definition for control extops. These are instantiated as: +# Object.extops."0" { +# mame "ctl" +# info "volsw" +# get "258" +# put "258" +# } +# +Class.Base."extops" { + # extops name + DefineArgument."name" {} + + DefineAttribute."info" {} + + DefineAttribute."get" {} + + DefineAttribute."put" {} + + attributes { + mandatory [ + "get" + "put" + ] + # + # index attribute values for extops objects must be unique in the same alsaconf + # node + # + unique "name" + } +} + +# +# Class definition for scale objects. These are instantiated as follows: +# Object.scale."0" { +# name 0 +# mute 1 +# } +# +Class.Base."scale" { + DefineArgument."name" { + type "string" + } + + DefineAttribute."min" {} + + DefineAttribute."step" {} + + DefineAttribute."mute" {} + + attributes { + mandatory [ + "min" + "mute" + "step" + ] + # + # index attribute values for scale objects must be unique in the same alsaconf + # node + # + 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.tlv."0" { +# name "vtlv_m64s2" +# } +Class.Base."tlv" { + DefineArgument."name" {} + attributes { + mandatory [ + "name" + ] + # + # index attribute values for TLV objects must be unique in the same alsaconf + # node + # + unique "name" + } +} diff --git a/tools/topology2/include/controls/mixer.conf b/tools/topology2/include/controls/mixer.conf new file mode 100644 index 000000000000..11a0e0aee654 --- /dev/null +++ b/tools/topology2/include/controls/mixer.conf @@ -0,0 +1,69 @@ +# +# 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.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. + # The actual mixer control name as seen by alsamixer would be provided by the parent + #"pga" object that instantiates the mixer. + # + DefineArgument."pipeline_id" {} + + DefineAttribute."name" {} + + DefineAttribute."index" {} + + DefineAttribute."max" {} + + DefineAttribute."invert" {} + + DefineAttribute."access" { + constraints { + values [ + "read_write" + "tlv_read_write" + "read" + "write" + "volatile" + "tlv_read" + "tlv_write" + "tlv_command" + "inactive" + "lock" + "owner" + "tlv_callback" + ] + } + } + + attributes { + mandatory [ + "max" + "invert" + "pipeline_id" + ] + # + # index attribute values for mixer objects must be unique in the same alsaconf + # node + # + unique "index" + } + + # Default attribute values for mixer control + 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..9d18602a63fd --- /dev/null +++ b/tools/topology2/include/dais/hw_config.conf @@ -0,0 +1,69 @@ +# 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) + # + DefineArgument."id" {} + + # All attributes are only used for SSP. + + DefineAttribute."format" { + constraints { + values [ + "I2S" + "DSP_A" + "DSP_B" + ] + } + } + + DefineAttribute."mclk" {} + + DefineAttribute."mclk_freq" {} + + DefineAttribute."bclk" {} + + DefineAttribute."bclk_freq" {} + + DefineAttribute."fsync" {} + + DefineAttribute."fsync_freq" {} + + DefineAttribute."tdm_slots" {} + + DefineAttribute."tdm_slot_width" {} + + DefineAttribute."tx_slots" {} + + DefineAttribute."rx_slots" {} + + attributes { + mandatory [ + "id" + ] + # + # index attribute values for hw_config objects must be unique in the same alsaconf + # node + # + unique "id" + } + + #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..acc5166c17b2 --- /dev/null +++ b/tools/topology2/include/dais/ssp.conf @@ -0,0 +1,140 @@ +# +# Intel SSP DAI +# +# All attributes defined herein are namespaced +# by alsatplg to "ssp.attribute_name" +# +# Usage: this component can be used by declaring in the "dais" field of +# a parent object. i.e. +# +# For Capture +#Object.SSP."0" { +# index 0 +# 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.pipeline-dai-capture."0" { +# period_source_count 0 +# period_sink_count 2 +# } +#} +# +# For Duplex +#Object.SSP."N" { +# index 0 +# 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.pipeline-dai-playback."0" { +# 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 + DefineArgument."index" { + token_ref "sof_tkn_dai.word" + } + + DefineArgument."direction" {} + + DefineAttribute."type" { + token_ref "sof_tkn_dai.string" + } + + DefineAttribute."default_hw_config" {} + + DefineAttribute."stream_name" {} + + DefineAttribute."format" { + constraints { + 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" + values [ + "lbm_mode" + ] + } + } + + DefineAttribute."mclk_id" { + # Token reference and type + token_ref "sof_tkn_intel_ssp.short" + } + + attributes { + mandatory [ + "type" + "stream_name" + "format" + "id" + "sample_bits" + "index" + "direction" + ] + immutable [ + "type" + ] + # + # index attribute values for SSP objects must be unique in the same alsaconf + # node + # + unique "index" + } + + type "SSP" + bclk_delay 0 + mclk_id 0 + default_hw_config 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..dcbbc91f0cf1 --- /dev/null +++ b/tools/topology2/include/pipelines/pipeline-common.conf @@ -0,0 +1,89 @@ +# +# 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" { + constraints { + values [ + "s32le" + "s24le" + "s16le" + "float" + ] + } +} + +# Sampling rate +DefineAttribute."rate" { + constraints { + min 48000 + max 196000 + } +} + +DefineAttribute."rate_min" {} +DefineAttribute."rate_max" {} + +# Pipeline direction +DefineAttribute."direction" { + constraints { + 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 + token_ref "sof_tkn_scheduler.word" + constraints { + # Acceptable values for time_domain + value_ref "sof_tkn_scheduler_time_domain" + values [ + "timer" + "dma" + ] + } +} + +# Name of the PCM associated with the pipeline +DefineAttribute."pcm_name" {} + +# Boolean flag to indicate if the pipeline is dynamic. +DefineAttribute."dynamic" { + constraints { + 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..25712f817471 --- /dev/null +++ b/tools/topology2/include/pipelines/pipeline-volume-capture.conf @@ -0,0 +1,135 @@ +# +# Volume capture pipeline +# +# A simple pipeline. All attributes defined herein are namespaced by alsatplg to +# "pipeline-volume-capture.attribute_name" +# +# Usage: this component can be used by declaring in the top-level topology conf file as follows: +# +# Object.pipeline-volume-capture."N" { +# pipeline_id X +# pcm_id Y +# pcm_name "Headset" +# format "s16le" +# period 1000 +# time_domain "timer" +# channels 2 +# rate 48000 +# } +# +# Where X and Y are unique integers for pipeline ID and PCM ID in the parent object. +# and N is the unique instance number 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" { + + DefineArgument."pipeline_id" {} + + DefineArgument."pcm_id" {} + + + + DefineAttribute."index"{} + + attributes { + mandatory [ + "channels" + "format" + "rate" + "direction" + "dynamic" + "period" + "time_domain" + "pcm_name" + "volume_ctl_name" + "pipeline_id" + "pcm_id" + ] + immutable [ + "direction" + ] + # + # index attribute values for volume-capture objects must be unique in the same + # alsaconf node + # + unique "pipeline_id" + } + + Object.pipeline."0" { + core 0 + frames 0 + priority 0 + mips 5000 + } + + # Pipeline objects + Object.host."0" { + period_sink_count 0 + period_source_count 2 + widget_type "aif_out" + } + + Object.buffer."0" { + periods 2 + caps "host" + } + + Object.pga."0" { + ramp_step_type "linear" + ramp_step_ms 250 + } + + Object.buffer."1" { + periods 2 + caps "dai" + } + + # PCM + Object.pcm."0" {} + + # PCM Capabilities + Object.pcm_caps."0" {} + + # Pipeline connections + Object.connection."0" { + source "Object.buffer.0" + sink "Object.host.0" + } + + Object.connection."1" { + source "Object.pga.0" + sink "Object.buffer.0" + } + + Object.connection."2" { + source "Object.buffer.1" + sink "Object.pga.0" + } + + # Endpoint definitions + Object.endpoint."0" { + widget "Object.buffer.1" + } + + # 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..c6a9b1a9ef31 --- /dev/null +++ b/tools/topology2/include/pipelines/pipeline-volume-playback.conf @@ -0,0 +1,135 @@ +# +# Volume playback pipeline +# +# A simple pipeline. All attributes defined herein are namespaced by alsatplg to +# "pipeline-volume-playback.attribute_name" +# +# Usage: this component can be used by declaring in the top-level topology conf file as follows: +# +# Object.pipeline-volume-playback."N" { +# pipeline_id X +# pcm_id Y +# pcm_name "Headset" +# format "s16le" +# period 1000 +# time_domain "timer" +# channels 2 +# rate 48000 +# volume_mixer_name "X Master Playback" +# } +# +# Where X and Y are unique integers for pipeline ID and PCM ID in the parent object. +# and N is the unique instance number 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" { + + DefineArgument."pipeline_id" {} + + DefineArgument."pcm_id" {} + + + + attributes { + mandatory [ + "channels" + "format" + "rate" + "direction" + "dynamic" + "period" + "time_domain" + "pcm_name" + "volume_ctl_name" + "pipeline_id" + "pcm_id" + ] + immutable [ + "direction" + ] + # + # index attribute values for endpoint objects must be unique in the same alsaconf + # node + # + unique "pipeline_id" + } + + Object.pipeline."0" { + core 0 + frames 0 + priority 0 + mips 5000 + } + + # Pipeline objects + Object.host."0" { + period_sink_count 2 + period_source_count 0 + widget_type "aif_in" + } + + Object.buffer."0" { + periods 2 + caps "host" + } + + Object.pga."0" { + ramp_step_type "linear" + ramp_step_ms 250 + } + + Object.buffer."1" { + periods 2 + caps "dai" + } + + # PCM + Object.pcm."0" {} + + # PCM Capabilities + Object.pcm_caps."0" {} + + # Pipeline connections + Object.connection."0" { + source "Object.host.0" + sink "Object.buffer.0" + } + + Object.connection."1" { + source "Object.buffer.0" + sink "Object.pga.0" + } + + Object.connection."2" { + source "Object.pga.0" + sink "Object.buffer.1" + } + + # Endpoint definitions + Object.endpoint."0" { + widget "Object.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/include/platform/intel/bxt.conf b/tools/topology2/include/platform/intel/bxt.conf new file mode 100644 index 000000000000..af8c27f1bde1 --- /dev/null +++ b/tools/topology2/include/platform/intel/bxt.conf @@ -0,0 +1,21 @@ +# The memory caps definitions are based on the type of memory capability defined as below: +# These values must match SOF_MEM_CAPS_ values in ipc/topology.h +#SOF_MEM_CAPS_RAM "1" +#SOF_MEM_CAPS_ROM "2" +#SOF_MEM_CAPS_EXT "4" +#SOF_MEM_CAPS_LP "8" +#SOF_MEM_CAPS_HP "16" +#SOF_MEM_CAPS_DMA "32" +#SOF_MEM_CAPS_CACHE "64" + +#dai_mem_cap = SOF_MEM_CAPS_RAM | SOF_MEM_CAPS_DMA | SOF_MEM_CAPS_CACHE | SOF_MEM_CAPS_HP; +#host_mem_cap = SOF_MEM_CAPS_RAM | SOF_MEM_CAPS_DMA | SOF_MEM_CAPS_CACHE | SOF_MEM_CAPS_HP; +#pass_mem_cap = SOF_MEM_CAPS_RAM | SOF_MEM_CAPS_DMA | SOF_MEM_CAPS_CACHE | SOF_MEM_CAPS_HP; +#comp_mem_cap = SOF_MEM_CAPS_RAM | SOF_MEM_CAPS_CACHE; + +SectionVendorTokens."sof_tkn_mem" { + dai "113" + host "113" + pass "113" + comp "65" +} diff --git a/tools/topology2/sof-cnl-nocodec.conf b/tools/topology2/sof-cnl-nocodec.conf new file mode 100644 index 000000000000..2a09f9349540 --- /dev/null +++ b/tools/topology2/sof-cnl-nocodec.conf @@ -0,0 +1,102 @@ + +# +# Simple Machine - High level topology - Maps to machine driver. +# +# +# PCM 0 <-> bufferN.0 <-> volumeN.0 <-> bufferN.1 -> SSP0 +# + + + + + + + + + + + + +# +# Pipeline definitions +# + +# Pipeline ID:1 PCM ID: 0 +Object.volume-playback."1" { + pipeline_id 1 + pcm_id 0 + pcm_name "Port0" + format "s24le" + + # set the mixer name for PGA.0 + pga.0.mixer.0.name "1 Master Playback Volume" + + # set pipeline stream_name + pipeline.0.stream_name "dai.SSP.0.playback" +} + +# Pipeline ID:2 PCM ID: 0 +Object.volume-capture."2" { + pipeline_id 2 + pcm_id 0 + pcm_name "Port0" + format "s24le" + + # set the mixer name for PGA.0 + pga.0.mixer.0.name "2 Master Capture Volume" + + # set pipeline stream_name + pipeline.0.stream_name "dai.SSP.0.capture" +} + +# +# List of all DAIs +# +#SSP Index: 0, Direction: duplex +Object.SSP."0" { + direction "duplex" + stream_name "NoCodec-0" + id 0 + default_hw_config 0 + format "s24le" + quirks "lbm_mode" + sample_bits 24 + Object.hw_config."0" { + id 0 + mclk_freq 24000000 + bclk_freq 4800000 + tdm_slot_width 25 + } + + #Add DAI widgets + Object.dai."playback" { + direction "playback" + widget_type "dai_in" + period_source_count 2 + period_sink_count 0 + pipeline_id 1 + } + + Object.dai."capture" { + direction "capture" + widget_type "dai_out" + period_source_count 0 + period_sink_count 2 + pipeline_id 2 + } +} + +# +# List of all endpoint connections +# +# Connect: Pipeline 1 Endpoint 0 -> SSP 0 DAI_IN +Object.connection."0" { + source "Object.volume-playback.1.endpoint.0" + sink "Object.SSP.0.dai.playback" +} + +# Connect: SSP 0 DAI_OUT -> Pipeline 2 Endpoint 0 +Object.connection."1" { + source "Object.SSP.0.dai.capture" + sink "Object.volume-capture.2.endpoint.0" +}