From 22f75892673ef176e910395809b0ee520e974c4b 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 | 9 ++ .../include/components/component.conf | 74 ++++++++++++++++ tools/topology2/include/components/host.conf | 86 +++++++++++++++++++ 3 files changed, 169 insertions(+) create mode 100644 tools/topology2/include/common/tokens.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..ac66d851a52b --- /dev/null +++ b/tools/topology2/include/common/tokens.conf @@ -0,0 +1,9 @@ +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" +} 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/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" +} From 309ec68623a8bf2122ba3abc3b724dc03dae4c4b 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 class Add the class definition for DAI components. A DAI widget would be constructed as follows: Object.dai."playback" { type SSP index 1 direction "playback" period_sink_count "2" period_source_count "0" widget_type "dai_in" } Signed-off-by: Ranjani Sridharan --- tools/topology2/include/common/tokens.conf | 13 +++ tools/topology2/include/components/dai.conf | 111 ++++++++++++++++++++ 2 files changed, 124 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 ac66d851a52b..5ffb8b0a9c8a 100644 --- a/tools/topology2/include/common/tokens.conf +++ b/tools/topology2/include/common/tokens.conf @@ -7,3 +7,16 @@ SectionVendorTokens."sof_tkn_comp" { 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" +} 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" +} From 3505483fa0489eff488cccbbdef0b9e493a0ee57 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.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 | 106 ++++++++++++++++++ .../topology2/include/platform/intel/bxt.conf | 21 ++++ 3 files changed, 132 insertions(+) create mode 100644 tools/topology2/include/components/buffer.conf create mode 100644 tools/topology2/include/platform/intel/bxt.conf diff --git a/tools/topology2/include/common/tokens.conf b/tools/topology2/include/common/tokens.conf index 5ffb8b0a9c8a..4678bd663f89 100644 --- a/tools/topology2/include/common/tokens.conf +++ b/tools/topology2/include/common/tokens.conf @@ -20,3 +20,8 @@ SectionVendorTokens."sof_tkn_direction" { playback "0" capture "1" } + +SectionVendorTokens."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..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/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" +} From 8f86357f530e5c90d3a9afb73cafda38fb975f03 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.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. Signed-off-by: Ranjani Sridharan --- tools/topology2/include/common/tokens.conf | 12 +++ .../topology2/include/components/volume.conf | 96 +++++++++++++++++++ 2 files changed, 108 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 4678bd663f89..2449f53f9764 100644 --- a/tools/topology2/include/common/tokens.conf +++ b/tools/topology2/include/common/tokens.conf @@ -25,3 +25,15 @@ 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" +} diff --git a/tools/topology2/include/components/volume.conf b/tools/topology2/include/components/volume.conf new file mode 100644 index 000000000000..548c205a7cc1 --- /dev/null +++ b/tools/topology2/include/components/volume.conf @@ -0,0 +1,96 @@ +# +# 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" + } + + # 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 +} From 4799431a297b3eb90294e8492950f0baec98e1e0 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.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 } } 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 | 152 +++++++++++++++++++ tools/topology2/include/controls/mixer.conf | 69 +++++++++ 2 files changed, 221 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..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" +} From 0b70cd9d7f2e64e9d01d26834b880a0eaa80c78d 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 | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/tools/topology2/include/components/volume.conf b/tools/topology2/include/components/volume.conf index 548c205a7cc1..1ac5b64dd32b 100644 --- a/tools/topology2/include/components/volume.conf +++ b/tools/topology2/include/components/volume.conf @@ -16,6 +16,7 @@ # # Where N is the unique instance number for pga widget in the same alsaconf node. + Class.Component."pga" { # @@ -87,6 +88,68 @@ Class.Component."pga" { 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" From 14ad70871343c1be5fd0574d6240b59db8822634 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 classes for DAPM routes Add a connection 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.connection."N" { source "Object.SSP.1.dai.capture" sink "Object.volume-playback.0.endpoint.0" } Object.connection."N" { source "Object.buffer.2.1" sink "Object.pga.2.1" } Also, add a helper class for creating pipeline endpoints. Signed-off-by: Ranjani Sridharan --- .../topology2/include/common/connection.conf | 54 +++++++++++++++++++ .../include/common/pipe_endpoint.conf | 41 ++++++++++++++ 2 files changed, 95 insertions(+) create mode 100644 tools/topology2/include/common/connection.conf create mode 100644 tools/topology2/include/common/pipe_endpoint.conf diff --git a/tools/topology2/include/common/connection.conf b/tools/topology2/include/common/connection.conf new file mode 100644 index 000000000000..6cf1eda452a2 --- /dev/null +++ b/tools/topology2/include/common/connection.conf @@ -0,0 +1,54 @@ +# Class definition for DAPM graph connection objects +# These are instantiated as follows: +# Example: +# Object.connection."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 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/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" + } +} From ed4467351c94f63159f1fa5e7a25b10dec3ff5b9 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-volume-playback."2" { pipeline_id 2 pcm_id 1 channels 2 channels_min 2 channels_max 2 rate 48000 rate_min 48000 rate_max 48000 pcm_name "Headset" format "s32le" volume_mixer_name "2 Master Playback Volume" } 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 | 21 +++ .../include/components/pipeline.conf | 108 ++++++++++++++ .../include/pipelines/pipeline-common.conf | 89 ++++++++++++ .../pipelines/pipeline-volume-capture.conf | 135 ++++++++++++++++++ .../pipelines/pipeline-volume-playback.conf | 135 ++++++++++++++++++ 5 files changed, 488 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 2449f53f9764..451e0b125a62 100644 --- a/tools/topology2/include/common/tokens.conf +++ b/tools/topology2/include/common/tokens.conf @@ -21,6 +21,11 @@ SectionVendorTokens."sof_tkn_direction" { capture "1" } +SectionVendorTokens."sof_tkn_bool" { + false "0" + true "1" +} + SectionVendorTokens."sof_tkn_buffer" { size "100" caps "101" @@ -37,3 +42,19 @@ 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" +} 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/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 +} From a95c79120e9b54e1c96ec80ca06a852c802eeb2d 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.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.hw_config."0" { id 0 mclk_freq 24000000 bclk_freq 4800000 tdm_slot_width 25 } #Add DAI widgets Object.dai."playback" { direction "playback" period_source_count 2 period_sink_count 0 } Object.dai."capture" { direction "capture" period_source_count 0 period_sink_count 2 } } Signed-off-by: Ranjani Sridharan --- tools/topology2/include/common/tokens.conf | 14 ++ tools/topology2/include/dais/hw_config.conf | 69 ++++++++++ tools/topology2/include/dais/ssp.conf | 140 ++++++++++++++++++++ 3 files changed, 223 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 451e0b125a62..0e482d05df91 100644 --- a/tools/topology2/include/common/tokens.conf +++ b/tools/topology2/include/common/tokens.conf @@ -58,3 +58,17 @@ 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" +} 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 +} From 28a830bbe53159fc068b74c9f5a2fc029ae9a5c2 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 and PCM Capabilities. These can be instantiated as: Object.pcm."N" { pcm_name "Headset" direction "playback" pcm_id 2 } 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 } Signed-off-by: Ranjani Sridharan --- tools/topology2/include/common/pcm.conf | 47 +++++++++++ tools/topology2/include/common/pcm_caps.conf | 88 ++++++++++++++++++++ tools/topology2/include/common/tokens.conf | 5 ++ 3 files changed, 140 insertions(+) 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/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/tokens.conf b/tools/topology2/include/common/tokens.conf index 0e482d05df91..80f5d6c8e09d 100644 --- a/tools/topology2/include/common/tokens.conf +++ b/tools/topology2/include/common/tokens.conf @@ -72,3 +72,8 @@ SectionVendorTokens."sof_tkn_intel_ssp" { tdm_padding_per_slot "505" bclk_delay "506" } + +SectionVendorTokens."sof_tkn_stream" { + playback_compatible_d0i3 "1200" + capture_compatible_d0i3 "1201" +} From 4a66f777706e7ad4c3cbae94ca8de8df0c4992f5 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 | 18 ++++++++++++++++++ tools/topology2/include/common/manifest.conf | 16 ++++++++++++++++ 2 files changed, 34 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..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" + } + +} From 67b2868548f98d3e297739508a0f1bc0b38a5eba 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 | 22 ++++++ tools/topology2/sof-cnl-nocodec.conf | 102 +++++++++++++++++++++++++++ 5 files changed, 163 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 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 < 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" +}