From a9ff662362c808448651843cbfb6d6558e14a042 Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Thu, 18 Mar 2021 20:36:07 -0700 Subject: [PATCH 01/12] topology2: Introduction to Topology2.0 About ----- This is a high level keyword extension on top of the existing ALSA conf topology format designed to: 1) Simplify the ALSA conf topology definitions by providing high level "classes" so topology designers need to write less config for common object definitions. 2) Allow simple reuse of objects. Define once and reuse (like M4) with the ability to alter objects configuration attributes from defaults. 3) Allow data type and value verification. This is not done today and frequently crops up in FW bug reports. Common Topology Classes ----------------------- Topology today has some common classes that are often reused throughout with slightly altered configurations. i.e. widgets (components), pipelines, dais and controls. This PR introduces the high level concept of reusable "class" like definition for a AIF_IN/AIF_OUT type object that can be used to create topology objects. Common Topology Attributes -------------------------- Topology defines a lot of attributes per object with different types and constraints. Today there is no easy way to validate type or constraints and this can lead to many hard to find problems in FW at runtime. A new keyword "DefineAttribute" has been added to define attribute type, size, min value, max value, enum_values. This then allows alsatplg to validate each topology object attribute. Topology Classes define the list of attributes that they use and whether the attribute is mandatory, can be overridden by parent users or is immutable. This also helps alsatplg emit the appropriate errors for attribute misuse. Common Topology Arguments ------------------------- Arguments are used to pass essential data needed for instantiating an object particularly needed for the object name. A new keyword "DefineArgument" has been added to define the arguments. The order in which the arguments are defined determines the name for the widget. For example, in the case of the host widget, the name would be constructed as "host.1.playback" where "1" is the pipeline_id argument value and "playback" is the direction argument value. Attribute Inheritance: ---------------------- One of the key features of Topology2.0 is howthe attribute values are propagated from a parent object to a child object. This is accomplished by adding attributes/arguments with the same name for a parent and an object. By doing so, when creating a child object, the value for the common attribute is populated from the parent. If the value is provided in the child object instance, then it overrides the value coming from the parent. ALSA Conf Parser ---------------- All the changes being proposed and discussed here must be 100% compliant with the ALSA conf parser. i.e. no syntax changes or changes to semantics for any existing keyword. It's intended that there will be NO changes to the ALSA conf parser (unless new keywords require this ?) and all topology building changes will be in the alsatplg compiler. Signed-off-by: Ranjani Sridharan --- tools/topology2/include/common/tokens.conf | 13 +++ .../include/common/vendor-token.conf | 22 +++++ .../include/components/component.conf | 80 +++++++++++++++++++ tools/topology2/include/components/host.conf | 77 ++++++++++++++++++ 4 files changed, 192 insertions(+) create mode 100644 tools/topology2/include/common/tokens.conf create mode 100644 tools/topology2/include/common/vendor-token.conf create mode 100644 tools/topology2/include/components/component.conf create mode 100644 tools/topology2/include/components/host.conf diff --git a/tools/topology2/include/common/tokens.conf b/tools/topology2/include/common/tokens.conf new file mode 100644 index 000000000000..f54091b4bcaa --- /dev/null +++ b/tools/topology2/include/common/tokens.conf @@ -0,0 +1,13 @@ + + +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 + } +} 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/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/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" +} From 64b39a6da6b16e7b02bf66dbdff9abb48bbf7518 Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Thu, 18 Mar 2021 21:02:15 -0700 Subject: [PATCH 02/12] topology2: Add DAI widget class Add the class definition for DAI widgets. A DAI widget can be instantiated as follows: Object.Widget.dai."playback" { type SSP index "1" period_sink_count "2" period_source_count "0" widget_type "dai_in" } Signed-off-by: Ranjani Sridharan --- tools/topology2/include/common/tokens.conf | 8 ++ tools/topology2/include/components/dai.conf | 123 ++++++++++++++++++++ 2 files changed, 131 insertions(+) create mode 100644 tools/topology2/include/components/dai.conf diff --git a/tools/topology2/include/common/tokens.conf b/tools/topology2/include/common/tokens.conf index f54091b4bcaa..b473d50b2565 100644 --- a/tools/topology2/include/common/tokens.conf +++ b/tools/topology2/include/common/tokens.conf @@ -10,4 +10,12 @@ Object.Base.VendorToken { 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 + } } 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" +} From fdf5d778898075dc522d123ac7bf7db2f282ac91 Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Thu, 18 Mar 2021 21:08:55 -0700 Subject: [PATCH 03/12] topology2: Add buffer class Add the definition for the buffer class. A buffer object can be instantiated as follows: Object.Widget.buffer."N" { pipeline_id 1 index 0 size 384 caps "host" } where 'N' is a unique instance number for the buffer object within the same alsaconf node. Signed-off-by: Ranjani Sridharan --- tools/topology2/include/common/tokens.conf | 5 + .../topology2/include/components/buffer.conf | 113 ++++++++++++++++++ 2 files changed, 118 insertions(+) create mode 100644 tools/topology2/include/components/buffer.conf diff --git a/tools/topology2/include/common/tokens.conf b/tools/topology2/include/common/tokens.conf index b473d50b2565..a2b7db875da3 100644 --- a/tools/topology2/include/common/tokens.conf +++ b/tools/topology2/include/common/tokens.conf @@ -18,4 +18,9 @@ Object.Base.VendorToken { dai_index 155 direction 156 } + + "sof_tkn_buffer" { + size 100 + caps 101 + } } 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" +} From 9a40029813c0a9eedb8142d1527820f523f864c7 Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Thu, 18 Mar 2021 22:48:49 -0700 Subject: [PATCH 04/12] topology2: Add pga class Add the class definition for PGA widget. It can be instantiated as follows: Object.Widget.pga."N" { pipeline_id 1 index 0 } Where N is the unique instance number for pga widget in the same alsaconf node. Signed-off-by: Ranjani Sridharan --- tools/topology2/include/common/tokens.conf | 5 + .../topology2/include/components/volume.conf | 96 +++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 tools/topology2/include/components/volume.conf diff --git a/tools/topology2/include/common/tokens.conf b/tools/topology2/include/common/tokens.conf index a2b7db875da3..1fd683b23cc7 100644 --- a/tools/topology2/include/common/tokens.conf +++ b/tools/topology2/include/common/tokens.conf @@ -23,4 +23,9 @@ Object.Base.VendorToken { size 100 caps 101 } + + "sof_tkn_volume" { + ramp_step_type 250 + ramp_step_ms 251 + } } diff --git a/tools/topology2/include/components/volume.conf b/tools/topology2/include/components/volume.conf new file mode 100644 index 000000000000..bc07b79887ff --- /dev/null +++ b/tools/topology2/include/components/volume.conf @@ -0,0 +1,96 @@ +# +# 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" + } + + # 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 +} From b94549c6093435aca95f957775ecad06e7992453 Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Thu, 18 Mar 2021 22:49:37 -0700 Subject: [PATCH 05/12] topology2: Add mixer control class Add the class definition for a mixer control. A mixer control can be instantiated as follows: Object.Control.mixer."0" { Object.Base.channel."fr" { shift 0 } Object.Base.channel."fl" {} Object.Base.tlv."vtlv_m64s2" { Object.scale."0" { mute 1 } } Object.ops."ctl" { info "volsw" get 256 put 256 } } Also add the other commonly used class definitions that will be used to instantiate the mixer object such as, channel, TLV, ops, scale etc. Signed-off-by: Ranjani Sridharan --- tools/topology2/include/controls/common.conf | 158 +++++++++++++++++++ tools/topology2/include/controls/mixer.conf | 85 ++++++++++ 2 files changed, 243 insertions(+) create mode 100644 tools/topology2/include/controls/common.conf create mode 100644 tools/topology2/include/controls/mixer.conf 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" +} From 3c378824ee3417e74d0594f0da494692a1408af3 Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Thu, 18 Mar 2021 22:57:50 -0700 Subject: [PATCH 06/12] topology2: pga: Add mixer controls Add the volume and switch mixer control objects for the PGA class. The mixers will be added to the PGA widget if the pga widget is instantiated with the volume_mixer_name and switch_mixer_name attributes set. Signed-off-by: Ranjani Sridharan --- .../topology2/include/components/volume.conf | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/tools/topology2/include/components/volume.conf b/tools/topology2/include/components/volume.conf index bc07b79887ff..d9228f3a2618 100644 --- a/tools/topology2/include/components/volume.conf +++ b/tools/topology2/include/components/volume.conf @@ -87,6 +87,60 @@ Class.Widget."pga" { 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" From 3da75fe1261de6b48d8760af3e6c671b75bd10e4 Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Thu, 18 Mar 2021 23:26:41 -0700 Subject: [PATCH 07/12] topology2: Add class for DAPM route Add a route class that will be used for creating DAPM routes between widgets. A route can be between 2 widgets or between a widget and pipeline endpoint as follows: Object.Base.route."N" { source "dai.SSP.1.dai.capture" sink "buffer.0.1" } Object.Base.route."N" { source "buffer.2.1" sink "pga.2.0" } Signed-off-by: Ranjani Sridharan --- tools/topology2/include/common/route.conf | 48 +++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 tools/topology2/include/common/route.conf diff --git a/tools/topology2/include/common/route.conf b/tools/topology2/include/common/route.conf new file mode 100644 index 000000000000..406db6e8d0aa --- /dev/null +++ b/tools/topology2/include/common/route.conf @@ -0,0 +1,48 @@ +# Class definition for DAPM graph route objects +# These are instantiated as follows: +# Example: +# Object.Base.route."N" { +# source "Object.SSP.1.dai.capture" +# sink "Object.volume-playback.0.endpoint.0" +# } +# The above object specifies a DAPM graph route: +# "SSP.1 capture DAI -> 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" + } +} From dca9f24ede51fc10b297673c47447c16d1288416 Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Thu, 18 Mar 2021 23:41:52 -0700 Subject: [PATCH 08/12] topology2: Add pipeline classes Add 2 pipeline classes for Volume playback and Volume Capture. Each of these classes includes the widget objects, their connections and define attributes for the pipeline. A volume playback pipeline can be instanted as follows: Object.Pipeline.pipeline-volume-playback."2" { channels 2 channels_min 2 channels_max 2 rate 48000 rate_min 48000 rate_max 48000 format "s32le" } Every pipeline class is associated with a pipeline widget, so add the class definition for the pipeline widget as well. Signed-off-by: Ranjani Sridharan --- tools/topology2/include/common/tokens.conf | 11 ++ .../include/components/pipeline.conf | 118 ++++++++++++++++++ .../include/pipelines/pipeline-common.conf | 91 ++++++++++++++ .../pipelines/pipeline-volume-capture.conf | 103 +++++++++++++++ .../pipelines/pipeline-volume-playback.conf | 105 ++++++++++++++++ 5 files changed, 428 insertions(+) create mode 100644 tools/topology2/include/components/pipeline.conf create mode 100644 tools/topology2/include/pipelines/pipeline-common.conf create mode 100644 tools/topology2/include/pipelines/pipeline-volume-capture.conf create mode 100644 tools/topology2/include/pipelines/pipeline-volume-playback.conf diff --git a/tools/topology2/include/common/tokens.conf b/tools/topology2/include/common/tokens.conf index 1fd683b23cc7..7dc10c7346c9 100644 --- a/tools/topology2/include/common/tokens.conf +++ b/tools/topology2/include/common/tokens.conf @@ -28,4 +28,15 @@ Object.Base.VendorToken { 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 + } } 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/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 +} From 55405c5afac7a8f2921b2f48ff1a96f1819ac27d Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Mon, 22 Mar 2021 10:00:36 -0700 Subject: [PATCH 09/12] topology2: Add SSP DAI class Add the definitions SSP DAI and the hw_config classes. These are used for instantiating the DAI objects in the top-level topology file as follows: Object.Dai.SSP."0" { index 0 direction "duplex" stream_name "NoCodec-0" id 0 default_hw_config 0 format "s24le" quirks "lbm_mode" sample_bits 24 Object.Base.hw_config."0" { id 0 mclk_freq 24000000 bclk_freq 4800000 tdm_slot_width 25 } #Add DAI widgets Object.Widget.dai."playback" { direction "playback" period_source_count 2 period_sink_count 0 } Object.Widget.dai."capture" { direction "capture" period_source_count 0 period_sink_count 2 } } Signed-off-by: Ranjani Sridharan --- tools/topology2/include/common/tokens.conf | 10 ++ tools/topology2/include/dais/hw_config.conf | 83 +++++++++++ tools/topology2/include/dais/ssp.conf | 150 ++++++++++++++++++++ 3 files changed, 243 insertions(+) create mode 100644 tools/topology2/include/dais/hw_config.conf create mode 100644 tools/topology2/include/dais/ssp.conf diff --git a/tools/topology2/include/common/tokens.conf b/tools/topology2/include/common/tokens.conf index 7dc10c7346c9..451b111c1810 100644 --- a/tools/topology2/include/common/tokens.conf +++ b/tools/topology2/include/common/tokens.conf @@ -39,4 +39,14 @@ Object.Base.VendorToken { 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 + } } 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 +} From cee5d8b4b02d39e91f63b1a0665854b3867abcfb Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Mon, 22 Mar 2021 10:01:18 -0700 Subject: [PATCH 10/12] topology2: Add PCM and PCM Caps classes Add class definitions for PCM, PCM Capabilities and FE DAI objects. These can be instantiated as: Object.PCM.pcm."N" { name "Headset" direction "capture" Object.fe_dai."Port 0" { id "0" } Object.PCM.pcm_caps."capture" { capabilities "Port0 Capture" formats "S32_LE,S24_LE,S16_LE" rate_min 48000 rate_max 48000 channels_min 2 channels_max 2 periods_min 2 } } Signed-off-by: Ranjani Sridharan --- tools/topology2/include/common/fe_dai.conf | 27 ++++++ tools/topology2/include/common/pcm.conf | 54 ++++++++++++ tools/topology2/include/common/pcm_caps.conf | 86 ++++++++++++++++++++ tools/topology2/include/common/tokens.conf | 5 ++ 4 files changed, 172 insertions(+) create mode 100644 tools/topology2/include/common/fe_dai.conf create mode 100644 tools/topology2/include/common/pcm.conf create mode 100644 tools/topology2/include/common/pcm_caps.conf diff --git a/tools/topology2/include/common/fe_dai.conf b/tools/topology2/include/common/fe_dai.conf new file mode 100644 index 000000000000..0826c797cfdd --- /dev/null +++ b/tools/topology2/include/common/fe_dai.conf @@ -0,0 +1,27 @@ +# Class definition for data object +# FE DAI objects can be instantiated as +# Object.Base.fe_dai."Port 0" { +# id "0" +# } +Class.Base."fe_dai" { + + DefineAttribute."name" { + type "string" + } + + DefineAttribute."id" {} + + attributes { + constructor [ + "name" + ] + mandatory [ + "id" + ] + # + # name attribute values for fe_dai 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..94519750c732 --- /dev/null +++ b/tools/topology2/include/common/pcm.conf @@ -0,0 +1,54 @@ +# PCM Class definition. PCM object can be instantiated as: +# PCM +# Object.pcm."N" { +# pcm_name "Headset" +# direction "playback" +# 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 + # + DefineAttribute."name" {} + + DefineAttribute."direction" { + constraints { + valid_values [ + playback + capture + duplex + ] + } + } + + DefineAttribute."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 { + constructor [ + "name" + "id" + "direction" + ] + # + # pcm objects instantiated within the same alsaconf node must have unique + # id attribute + # + unique "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..73380bd494ea --- /dev/null +++ b/tools/topology2/include/common/pcm_caps.conf @@ -0,0 +1,86 @@ +# PCM Capabilities Class definition. PCM object can be instantiated as: + +# Object.pcm_caps."N" { +# name "Headset" +# capabilities "Headset Playback" +# direction "playback" +# 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 + # + DefineAttribute."name" { + type "string" + } + + DefineAttribute."direction" { + type "string" + valid_values [ + playback + capture + ] + } + + DefineAttribute."formats" { + type "string" + } + + DefineAttribute."rates" { + type "string" + } + + 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 { + constructor [ + "name" + "direction" + ] + # + # pcm_caps objects instantiated within the same alsaconf node must have unique + # direction attribute + # + unique "direction" + } + + # 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/tokens.conf b/tools/topology2/include/common/tokens.conf index 451b111c1810..d0e85521006d 100644 --- a/tools/topology2/include/common/tokens.conf +++ b/tools/topology2/include/common/tokens.conf @@ -49,4 +49,9 @@ Object.Base.VendorToken { tdm_padding_per_slot 505 bclk_delay 506 } + + "sof_tkn_stream" { + playback_compatible_d0i3 1200 + capture_compatible_d0i3 1201 + } } From 11f33e152f186da73e2e9d1872df2c8ec576a778 Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Mon, 22 Mar 2021 10:12:34 -0700 Subject: [PATCH 11/12] topology2: add class definitions for data and manifest These will be used to add the ABI to the topology manifest section. Signed-off-by: Ranjani Sridharan --- tools/topology2/include/common/data.conf | 28 ++++++++++++++++++++ tools/topology2/include/common/manifest.conf | 18 +++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 tools/topology2/include/common/data.conf create mode 100644 tools/topology2/include/common/manifest.conf diff --git a/tools/topology2/include/common/data.conf b/tools/topology2/include/common/data.conf new file mode 100644 index 000000000000..e56bb9bb825a --- /dev/null +++ b/tools/topology2/include/common/data.conf @@ -0,0 +1,28 @@ +# Class definition for data object +# Data objects can be instantiated as: +# +# Object.Base.data."SOF ABI" { +# bytes "0x3, 0x12,0x1" +# } +# +Class.Base."data" { + + DefineAttribute."name" { + type "string" + } + + DefineAttribute."bytes" { + type "string" + } + + attributes { + constructor [ + "name" + ] + # + # data objects instantiated within the same alsaconf node must have unique + # name attribute + # + unique "name" + } +} diff --git a/tools/topology2/include/common/manifest.conf b/tools/topology2/include/common/manifest.conf new file mode 100644 index 000000000000..fcb4c54819c2 --- /dev/null +++ b/tools/topology2/include/common/manifest.conf @@ -0,0 +1,18 @@ +# Class definition for manifest object +Class.Base."manifest" { + DefineAttribute."name" { + type "string" + } + + attributes { + constructor [ + "name" + ] + # + # name attribute values for manifest objects must be unique in the same alsaconf + # node + # + unique "name" + } + +} From 92a320572597ecbb395d207b96adb77a7332a573 Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Mon, 22 Mar 2021 10:02:36 -0700 Subject: [PATCH 12/12] topology2: Add the sof-cnl-nocodec machine topology Add a simple machine topology showing 2 pipelines, an SSP DAI and the connections between the DAI endpoints and the pipeline endpoints. Add the manifest and data objects for adding ABI to the generated tplg file. Also add support for building the topology2 conf files. Signed-off-by: Ranjani Sridharan --- scripts/build-tools.sh | 10 +- tools/CMakeLists.txt | 1 + tools/topology2/CMakeLists.txt | 31 ++++++ tools/topology2/get_abi.sh | 20 ++++ tools/topology2/sof-cnl-nocodec.conf | 142 +++++++++++++++++++++++++++ 5 files changed, 201 insertions(+), 3 deletions(-) create mode 100644 tools/topology2/CMakeLists.txt create mode 100755 tools/topology2/get_abi.sh create mode 100644 tools/topology2/sof-cnl-nocodec.conf 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 < 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" + } +} +