-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Introducing Topology 2.0 #2
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Really great work. I think the firts patch probably needs split and it's probably benefition to show the config you are adding in the commit message (as a example is always helpful).
src/topology/tplg_local.h
Outdated
|
||
/* type-specific control lists */ | ||
struct list_head mixer_list; | ||
struct list_head enum_list; | ||
struct list_head bytes_ext_list; | ||
}; | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can be deleted.
@@ -288,7 +292,6 @@ int tplg_parse_dai(snd_tplg_t *tplg, snd_config_t *cfg, void *priv); | |||
int tplg_parse_link(snd_tplg_t *tplg, snd_config_t *cfg, void *priv); | |||
int tplg_parse_cc(snd_tplg_t *tplg, snd_config_t *cfg, void *priv); | |||
int tplg_parse_hw_config(snd_tplg_t *tplg, snd_config_t *cfg, void *priv); | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto
@@ -766,6 +766,7 @@ enum snd_tplg_type { | |||
SND_TPLG_TYPE_LINK, /*!< Physical DAI link */ | |||
SND_TPLG_TYPE_HW_CONFIG, /*!< Link HW config */ | |||
SND_TPLG_TYPE_DAI, /*!< Physical DAI */ | |||
SND_TPLG_TYPE_CLASS, /*!< Class */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is class sent as a ABI object ? I think this is for ABI types only ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also my be worth an example class def in your commit message.
!attr->found) { | ||
SNDERR("Mandatory immutable attribute '%s' not provide for class '%s'", | ||
attr->name, class->name); | ||
return false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
btw, do we have the full attribute name here i.e. so we can figure out th elocation of the error ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if not, we can add a TODO: to these.
return class_map[i].id; | ||
} | ||
|
||
return -EINVAL; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"can't find class X" error would be useful ?
Expose the lookup_channel() so that it can be reused in topology2.0. Signed-off-by: Ranjani Sridharan <[email protected]>
@lgirdwood @perexg this PR is now ready for review. Its a lot of commits but the changes are incremental and reasonably well documented. Let me know what you think. |
Split the logic for parsing each hw_config parameter into a separate function tplg_set_hw_config_param() and expose it so that they can be reused in topology2.0. Signed-off-by: Ranjani Sridharan <[email protected]>
Expose the tplg_parse_pcm_param(), tplg_parse_link_param() tplg_parse_stream_caps_param() functions for parsing the PCM params, link params and PCM capabilities. These will be reused in Topology2.0. Signed-off-by: Ranjani Sridharan <[email protected]>
This will be reused in topology2.0 Signed-off-by: Ranjani Sridharan <[email protected]>
Expose some functions needed for parsing mixer and byte controls. These will be reused for topology2.0. Signed-off-by: Ranjani Sridharan <[email protected]>
Expose multiple functions that will be reused to parse tuples and private data in Topology2.0. Signed-off-by: Ranjani Sridharan <[email protected]>
Split the widget param parser and expose the function to be reuse for Topology2.0. Signed-off-by: Ranjani Sridharan <[email protected]>
Add 2 new fields to struct tplg_tuple_set. The token_ref field will be used to save the reference to the token set name. And the list elem will be used to add the tuple_sets to a list of tuples sets that will be created in Topology2.0. Signed-off-by: Ranjani Sridharan <[email protected]>
Topology 2.0 will introduce a new element named object. In preparation for that, replave the references to object with element where applicable. Signed-off-by: Ranjani Sridharan <[email protected]>
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 definitions that can be used to create topology objects e.g. Class.Component - Class for widgets that can be included within Class.Pipeline. Class definitions typically contain arguments and attributes. It also adds support for creating a new class topology element and saving it to the class_list. This will be used as the template when creating objects of this class type. A class typically consists of arguments and attributes. Arguments and attributes both refer to parameters associated with the class or its object. The difference is that the arguments are also used for naming the object. For ex:, a simple class definition would be Class.Base."data" { DefineArgument."name" { type "string" } DefineArgument."index" {} DefineAttribute."bytes" {} } The argument "name" would be used to build the name of the data object as "data.<name>.<index>". When parsing the class definition, the arguments and attributes are stored as part of the attribute_list in struct tplg_class. Ad attribute/argument can have values that can be of type integer, long, double or a string. Signed-off-by: Ranjani Sridharan <[email protected]>
Attributes/arguments in a class could refer to tuple values that need to be added to the private data. Add a field called token_ref to struct tplg_attribute stores the name of SectionVendorTokens and the tuple type that will be used to build the tuple value for the attribute. For ex: "sof_tkn_dai.word" refers to the SectionVendorTokens with the name "sof_tkn_dai" and "word" refers to the tuple type. Signed-off-by: Ranjani Sridharan <[email protected]>
One of the main advantages with Topology2.0 is the ability to validate the types and values for the arguments and attributes for a class instance. Add the constraint field for struct tplg_attribute that will be used to parse and save the constraints specified for the attribute/argument in the class definition. Typical constraints include min/max value or a set of valid values allowed for the attribute. The set of valid values can also be translated from a string value to an integer value during topology build. An example for attribute constraint would be: DefineAttribute."direction" { token_ref "sof_tkn_dai.word" constraints { value_ref "sof_tkn_direction" values [ "playback" "capture" ] } } where the value_ref "sof_tkn_direction" would translate the values as follows: SectionVendorTokens."sof_tkn_direction" { playback "0" capture "1" } Signed-off-by: Ranjani Sridharan <[email protected]>
Class definitions may also provide default values for some attributes. Parse and save these values. Attributes/arguments that have constraints are validated against the set constraints. The following example shows a class definition with default attribute values: Class.Base."hw_config" { # # Argument used to construct hw config (hw config ID) # DefineArgument."id" {} 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" {} format "I2S" mclk "codec_mclk_in" bclk "codec_consumer" fsync "codec_consumer" fsync_freq 48000 tdm_slots 2 tx_slots 3 rx_slots 3 } Signed-off-by: Ranjani Sridharan <[email protected]>
Another type of constraint the attributes can have is whether their value is immutable (fixed in class definition), mandatory, automatic or deprecated. Class definitions categorize attributes by specifying the attribute name in the attributes.mandatory/immutable/deprecated array. An example for this is: attributes { mandatory [ "no_pm" "uuid" "widget_type" ] immutable [ "uuid" ] automatic [ "stream_name" ] deprecated [ "preload_count" ] } Signed-off-by: Ranjani Sridharan <[email protected]>
The Object keyword is used to instantiate a class. When an object is instantiated, it must be provided with arguments and mandatory attributes. Example object instantiation: Object.host."N" { direction "playback" period_sink_count 2 period_source_count 0 widget_type "aif_in" } where 'N' is a unique identifier for this object in the parent alsaconf node. For objects that have an index attribute, this value is copied to the index attribute by the compiler. The default attributes values for a class are copied over to the object when the object is created. But these will be overriden when they are explictly set during object instantation as above. Signed-off-by: Ranjani Sridharan <[email protected]>
Apart from attributes, arguments and constraints, a class definition could also include child objects. Parse these child objects and save them in the class' object_list. An example of this would be a PGA widget class with 2 mixer controls as follows: Class.Component."pga" { /* PGA arguments and attribute definitions (not shown) */ Object.mixer."0" { name "Master Playback Volume" } Object.mixer."1" { name "Mute Switch" } /* PGA default values(not shown) */ } Signed-off-by: Ranjani Sridharan <[email protected]>
When creating an object, also copy all the child objects that the class definitions may include. This has to be done recursively until all the child objects within objects are copied. Signed-off-by: Ranjani Sridharan <[email protected]>
Just like classes, objects can have other objects when they are instantiated. Parse these(recursively) and add them to the object's object_list. For ex: mixer objects could have child objects for specifying the ops, channels, tlv etc. 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" alsa-project#256 binds the mixer control to volume get/put handlers get 256 put 256 } } Signed-off-by: Ranjani Sridharan <[email protected]>
Add a couple of helper functions to look up objects within a prent's object_list or the global topology object list based on class_name and the value for the unique attribute in the class. Signed-off-by: Ranjani Sridharan <[email protected]>
One of the key features of Topology2.0 is the concept of inheriting object attribute values from parent attribute values. Inheritance is implicit when an attribute in a child object shares the same name as an attribute in the parent object. When creating an object, make sure to pass down the attribute values to all its child objects recursively. Alternatively, a parent object can also explictly set an attribute for its child object by using the object's class name and index attribute as follows: Object.volume-playback."1" { pipeline_id 1 pcm_id 0 pcm_name "Port0" format "s24le" # Set value for mixer.0 in pga.0 pga.0.mixer.0.name "1 Master Playback Volume" } The last line in the above object instance, sets the mixer name for the mixer object with index 0 in the PGA object with index 0 in the volume-playback object. As a rule of thumb, the attribute value set for an object always overrides inherited values from parent or the ones explicitly set in the parent. Signed-off-by: Ranjani Sridharan <[email protected]>
Once an object is created, the next step is to create the topology element for the topology builder. This patch adds support for build BASE type objects specifically for manifest and data objects. Before building the topology elements, the compiler needs to ensure that all the mandatory attributes have been provided. Also, if attributes have references for valid values, they need to be translated to the appropriate tuple value. Signed-off-by: Ranjani Sridharan <[email protected]>
Many topology elements pack tuple data in their private data. Iterate through the attribute list of an object and build tuple sets for those attributes that have the token_ref field set. Add a new field, tuple_set_list to struct objects and add the tuple sets to the list. Once the tuple_sets are built for an object, the compiler scans the tuple sets against the provided token reference and builds the private data array. Signed-off-by: Ranjani Sridharan <[email protected]>
Add some commonly used Classes such as Component, DAI, Pipeline PCM as pre-defined class types. Update the struct tplg_object to include type-specific data based on class type for some classes. Signed-off-by: Ranjani Sridharan <[email protected]>
Add support for building DAPM widget/component type class objects by creating the topology element of type SND_TPLG_TYPE_DAPM_WIDGET and setting the widget params based on the object attributes. Signed-off-by: Ranjani Sridharan <[email protected]>
SND_TPLG_TYPE_DAPM_WIDGET type topology elements can contaim kcontrols associated with them. Add support for building the controls of type mixer/bytes when building the widget. ENum control support will be addded later. Signed-off-by: Ranjani Sridharan <[email protected]>
Add support for SND_TPLG_TYPE_STREAM_CAPS and SND_TPLG_TYPE_PCM type topology elements by parsing the PCM class objects and their attributes. Signed-off-by: Ranjani Sridharan <[email protected]>
Add support for building SND_TPLG_TYPE_BE type topology elements by parsing the SND_TPLG_CLASS_TYPE_DAI type objects and their attributes. Signed-off-by: Ranjani Sridharan <[email protected]>
Sanity check while creating SND_TPLG_CLASS_TYPE_PIPELINE type objects. Signed-off-by: Ranjani Sridharan <[email protected]>
Add support for building SND_TPLG_TYPE_DAPM_GRAPH type topology elements by pasring the objects of class "connection" and their attributes. Signed-off-by: Ranjani Sridharan <[email protected]>
Attributes have a constraint called TPLG_CLASS_ATTRIBUTE_MASK_AUTOMATIC that allows the values to be updated by the alsatplg compiler when the object containing the attribute is built. One example of an automatic attribute is the "stream_name" attribute for "host" and "copier" class objects. Add the logic to update the stream name for such objects. Signed-off-by: Ranjani Sridharan <[email protected]>
The buffer class's "size" attribute is an autmatic attribute. It needs to computed using the pipeline attributes along with some of the buffer object attributes. Add support for updating it. Signed-off-by: Ranjani Sridharan <[email protected]>
Endpoint class' "widget_name" attribute is an automatic attribute. It's value should be set after resolving the object reference in the "widget" attribute. If the "widget" attribute value does not contain the "Object." prefix, its value is simply copied to the widget_name attribute. Signed-off-by: Ranjani Sridharan <[email protected]>
The source_widget and sink_widget attributes in the connection class are automatic attributes. Their values need to be updated based on the "source" and "sink" attribute values. Signed-off-by: Ranjani Sridharan <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ranj063 I think we are good to split up the PR and start upstreaming into alsa-lib.
alsatplg parser support for thesofproject/sof#3211