Commit graph

25 commits

Author SHA1 Message Date
Chao Song
88c6dd6cf4 topology: pre-process-object: add support for updating automatic attributes
Classes definitions in Topology2.0 can have attributes
qualified with the "automatic" constraint. Values for
these attributes will be calculated by the compiler.
This patch provides a generic method for defining automatic
attributes computation logic for different classes.

To update automatic attributes for a class, add an item
in object_build_map with auto_attr_updater defined, and then
add updating logic in the custom auto_attr_updater function.

Signed-off-by: Chao Song <chao.song@linux.intel.com>
Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2021-08-23 16:49:56 +02:00
Jaroslav Kysela
f076518254 alsatplg: do not do NULL check for string arrays
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2021-06-18 10:15:46 +02:00
Jaroslav Kysela
0b8d2dfdcc alsatplg: fix memory-leak in tplg_construct_object_name()
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2021-06-18 10:11:34 +02:00
Jaroslav Kysela
c58f981e15 topology: fix few coverity detected defects
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2021-06-04 10:19:41 +02:00
Chao Song
3d7a6facd9 topology: fix potential null pointer from strchr
This patch adds check to the return pointer from strchr,
because it may be null and cause segment fault, if component
is not properly constructed.

Fixes: https://github.com/alsa-project/alsa-utils/pull/91
Signed-off-by: Chao Song <chao.song@linux.intel.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2021-06-02 16:55:57 +02:00
Jaroslav Kysela
8037d4812e topology: some whitespace fixups
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2021-05-25 18:36:46 +02:00
Ranjani Sridharan
1832f6f254 topology: pre-process-object: add support for prepocessing child objects
Add support for processing object instances embedded
within objects and classes. For example:
		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
			}
		}

and pga class embeds the mixer objects as follows:
Class.Widget."pga" {
...
Object.Control {
		mixer."0" {...}
		mixer."1" {...}
}

The pre-processor starts with the top-pevel PGA widget object
and processes the mixer objects in the class definition.
This will recursively pre-processes its child objects to add the channels,
tlv and ops.

Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2021-05-25 18:26:51 +02:00
Ranjani Sridharan
df6cfa77e3 topology: pre-process-dai: add support for pcm_caps objects
Add support for processing pcm_caps objects.
For ex:

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"
	}
}

Would convert into:
SectionPCMCapabilities {
        'Port0 Playback' {
                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
        }
        'Port0 Capture' {
                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
        }
}

and the SectionPCM updated as follows:
SectionPCM {
        Port0 {
                id 0
                dai {
                        'Port 0' {
                                id 0
                        }
                }
                pcm {
                        playback {
                                capabilities 'Port0 Playback'
                        }
                        capture {
                                capabilities 'Port0 Capture'
                        }
                }
        }
}

Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2021-05-25 18:26:51 +02:00
Ranjani Sridharan
3719c80a4d topology: pre-process-dai: add support for fe_dai objects
Add support for fe_dai objects:

For ex:

Object.PCM.pcm."0" {
	name	"Port0"
	direction	"duplex"
	Object.Base.fe_dai."Port 0" {}
}

will be converted to update the SectionPCM as follows:

SectionPCM {
        Port0 {
                id 0
                dai {
                        'Port 0' {
				id 0
			}
                }
}

Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2021-05-25 18:26:51 +02:00
Ranjani Sridharan
4bc386bb71 topology: pre-process-dai: add support for hwcfg objects
Add supprt for hwcfg objects:
For ex:
Object.Base.hw_config."SSP0 hw_config 0" {
		id		0
		mclk_freq	24000000
		bclk_freq	4800000
		tdm_slot_width	25
	}

would get converted to:

SectionHWConfig {
        'SSP0 hw_config 0' {
                id 0
                format I2S
                bclk codec_consumer
                bclk_freq 4800000
                fsync codec_consumer
                fsync_freq 48000
                mclk codec_mclk_in
                mclk_freq 24000000
                tdm_slots 2
                tdm_slot_width 25
                tx_slots 3
                rx_slots 3
        }
}

and the corresponding SectionBE will be updated with the hwcfgs reference as:

	hw_configs [
		'SSP0 hw_config 0'
        ]

Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2021-05-25 18:26:51 +02:00
Ranjani Sridharan
b0be235024 topology: pre-process-dai: add support for PCM and BE DAI objects
Add support for pre-processing PCM and BE DAI objects:

Object.PCM.pcm."0" {
	name	"Port0"
	direction	"duplex"
}

will be converted to:

SectionPCM.'Port0' {}

The capabilities and dai configs will be added those objects are pre-processed.

An ex of DAI object would be:
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
}

converted to:
SectionBE {
        'SSP.0.duplex' {
                id 0
                stream_name NoCodec-0
                default_hw_conf_id 0
                data [
                        'SSP.0.duplex.sof_tkn_intel_ssp.word'
                        'SSP.0.duplex.sof_tkn_dai.word'
                        'SSP.0.duplex.sof_tkn_dai.string'
                        'SSP.0.duplex.sof_tkn_intel_ssp.short'
                ]
}

Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2021-05-25 18:26:51 +02:00
Ranjani Sridharan
758e4dba81 topology: pre-process-dapm: add support for route objects
DAPM route objects such as:
Object.Base.route."1" {
	source	"dai.SSP.0.dai.capture"
	sink	"buffer.2.1"
}

will be converted to:

SectionGraph."Endpoint.route.1" {
	index 0
	lines [
		"dai.SSP.0.capture, , buffer.2.1"
	]
}

If the source/sink names are references to objects within a parent pipeline
object, the index attribute value can be skipped and it will be
populated when the object is pre-processed

Object.Pipeline.volume-capture."1" {
	Object.Base.route."1" {
		source	"pga..0"
		sink	"buffer..0"
	}
}

The reference pga..0 will need to be resolved to
get the widget name pga.1.0 and buffer..0 will
be resolved to buffer.1.0 before creating the SectionGraph as follows:

SectionGraph."volume-capture.1.route.1" {
	index 2
	lines [
		"pga.1.0, , buffer.1.0"
	]
}

Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2021-05-25 18:26:51 +02:00
Ranjani Sridharan
79033ceae4 topology: pre-process-dapm: add support for widget control objects
Add support for pre-processing mixer and byte control objects.
For ex: a pga widget with a mixer control as follows:

Object.pga"0" {
	...
	mixer.0 {
		index 2
		max 32
		name "2 MasterPlaybackControl"
			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
			}

		access [
			read_write
			tlv_read
		]
	}
}

Would be converted to:

SectionControlMixer.'2 Master Playback Volume' {
	index 2
	max 32
	channel {
		fl {
			reg 1
		}
		fr {
			reg 1
			shift 1
		}
	}
	tlv	"vtlv_m64s2"
	ops.0 {
		info volsw
		get 256
		put 256
	}
	access [
		read_write
		tlv_read
	]
}

and the SectionWidget for pga.2.0 would be updated to add the mixer references as follows:
SectionWidget.'pga.2.0' {
...
	mixer [
		"2 Master Playback Volume"
	]
}

Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2021-05-25 18:26:51 +02:00
Ranjani Sridharan
082015dc95 topology: pre-process-dapm: add support for scale/ops/channel objects
Add support for pre-processing scale/ops/channel objects
and adding the converted config to the relevant sections.

For ex:
	Object.Base.channel."fl" {
		shift	0
		reg 1
	}
	Object.Base.channel."fr" {
		reg 1
		shift 1
	}

Will be converted to:

	channel {
		fl {
			reg 1
			shift 0
		}
		fr {
			reg 1
			shift 1
		}
	}

And added to the SectionControlMixer that this object belongs to.

Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2021-05-25 18:26:51 +02:00
Ranjani Sridharan
96b5e5a875 topology: pre-process-dapm: Add support for tlv objects
Add support for pre-processing TLV objects
For example:

	Object.Base.tlv."vtlv_m64s2" {}

will be converted to:

SectionTLV.'vtlv_m64s2' {}

And the mixer controle section will be updated to add
the reference to the tlv object.

Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2021-05-25 18:26:51 +02:00
Ranjani Sridharan
032d1250c7 topology: pre-process-dapm: Add support for DAPM Widget objects
Add support for pre-processing DAPM widget opbects.
For ex:

Object.Widget.pga."0" {
        pipeline_id     1
	no_pm		true
	type		pga
}

will be converted to:

SectionWidget.'pga.0' {
	index 1
	type pga
	no_pm 1
}

Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2021-05-25 18:26:51 +02:00
Ranjani Sridharan
d271972177 topology: pre-process-base: add support for VendorToken objects
Add support for pre-processing VendorToken objects.
For ex:
Object.Base.VendorToken."sof_tkn_dai" {
	dmac_config		153
	dai_type		154
	index			155
	direction		156
}

would be converted to:

SectionVendorTokens."sof_tkn_dai" {
	dmac_config 153
	dai_type 154
	index 155
	direction 156
}

Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2021-05-25 18:26:51 +02:00
Ranjani Sridharan
cb65ce0195 topology: pre-process-object: Add support for data objects
Pre-process data objects, create the SectionData and update
the parent object with the reference to the object.
For example, the following object instance:

	Object.Base.data."SOF_ABI" {
		bytes	"0x03,0x12,0x01"
	}

would update the SectionManifest as follows:
SectionManifest."sof_manifest" {
	data [
		"SOF_ABI"
	]
}

Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2021-05-25 18:26:51 +02:00
Ranjani Sridharan
48fef7a811 topology: pre-process-obejct: add helper function to get the section config
Add a helper function to retrieve the config node
pointing to the section name for a given object.
For ex: for the object, Object.Widget.pga.1{},
the function returns the config with id, "SectionWidget"
in the output config.

Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2021-05-25 18:26:51 +02:00
Ranjani Sridharan
571d1fe871 topology: pre-process-object: add data section for attributes with token reference
Objects that have attributes with token_ref need
to have separate SectionData and SectionVendorTuples
for each unique token_ref based on the attribute_sets
in the object's attribute_set_list.

Add the tplg_pp_add_object_data()
function to add the data[] refs in the object and also
the respective SectionData and SectionVendorTuples.

For example for the pga object:

Object.Widget.pga."0" {
	pipeline_id 2
	format s24le
	type pga
	no_pm 1
	uuid    "7e:67:7e:b7:f4:5f:88:41:af:14:fb:a8:bd:bf:8"
	period_sink_count 2
	period_source_count 2
	ramp_step_ms 250
        ramp_step_type "linear"
	mixer.0 {
		....
	}
	mixer.0.name "2 Master Playback Volume"
}

The following sections will be added:
SectionWidget.'pga.2.0' {
	index 2
	type pga
	no_pm 1
	mixer [
		"2 Master Playback Volume"
	]
	bytes [
	]
	data [
		"pga.2.0.sof_tkn_comp.word"
		"pga.2.0.sof_tkn_comp.string"
		"pga.2.0.sof_tkn_comp.uuid"
		"pga.2.0.sof_tkn_volume.word"
	]
}

SectionData."pga.2.0.sof_tkn_comp.word" {
	tuples	"pga.2.0.sof_tkn_comp.word"
}

SectionData."pga.2.0.sof_tkn_comp.string" {
	tuples	"pga.2.0.sof_tkn_comp.string"
}

SectionData."pga.2.0.sof_tkn_comp.uuid" {
	tuples	"pga.2.0.sof_tkn_comp.uuid"
}

SectionData."pga.2.0.sof_tkn_volume.word" {
	tuples	"pga.2.0.sof_tkn_volume.word"
}

SectionVendorTuples."pga.2.0.sof_tkn_comp.word" {
	tokens	"sof_tkn_comp"
	tuples."word" {
		period_source_count	"2"
		period_sink_count	"2"
	}
}

SectionVendorTuples."pga.2.0.sof_tkn_comp.string" {
	tokens	"sof_tkn_comp"
	tuples."string" {
		format	"s24le"
	}
}

SectionVendorTuples."pga.2.0.sof_tkn_comp.uuid" {
	tokens	"sof_tkn_comp"
	tuples."uuid" {
		uuid	"7e:67:7e:b7:f4:5f:88:41:af:14:fb:a8:bd:bf:8"
	}
}

SectionVendorTuples."pga.2.0.sof_tkn_volume.word" {
	tokens	"sof_tkn_volume"
	tuples."word" {
		ramp_step_ms	"250"
		ramp_step_type	"0"
	}
}

Note that the ramp_step_type of "linear" is converted
to the tuple value 0.

Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2021-05-25 18:26:51 +02:00
Ranjani Sridharan
d999c267d3 topology: pre-process-object: Add support for processing Manifest object
The pre-processor converts the Topology2.0 objects into
the relevant sections by looking for attributes defined
in the template config for the section and reading the
attribute values from the object instance config.

The structure struct build_function_map contains the
mapping of the build function to use for each object
based on the type and name for the class that the object
belongs to. The manifest object is the simplest with
no attributes. So, the build function simply creates
a new Section called SectionManifest which will be
populated with the data section in the following patches.

Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2021-05-25 18:26:51 +02:00
Ranjani Sridharan
1ca07d8dbc topology: pre-process-object: construct object name from its constructor attributes
An object's name is derived from its constructor attribute
values separated by '.'. For example, the name for the
host widget objects is derived from its index and direction
attribute values as follows:
Object.Widget.host."playback" {
	index 2
}

The name for the host widget object would be host.2.playback.

Alternatively, if the object has a name attribute, the class
definition may skip the constructor attributes and the name attribute
value will be used instead.

Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2021-05-25 18:26:51 +02:00
Ranjani Sridharan
b2e85be668 topology: pre-process-object: check attribute validity
Attributes can have constraints set for valid values, min
or max values. If the attribute value is set in an object,
the value must be validated against the set constraints.

An example for attribute constraint would be:
DefineAttribute."direction" {
		constraints {
			valid_values [
				"playback"
				"capture"
			]
			tuple_values [
				0
				1
			]
		}
}

where the tuple_values array would translate the valid_values of
playback as 0 and capture as 1.

Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2021-05-25 18:26:51 +02:00
Ranjani Sridharan
624c814c65 topology/pre-process-object: update object config with attributes
Object attributes can be set in multiple places. Search for
the attribute value in the following order:
1. Value set in object instance
2. Default value set in the object's class definition
3. Inherited value from the parent object
4. Value set in the object instance embedded in the parent object
5. Value set in the object instance embedded in the parent class definition

Mandatory attributes must be found in one of the above, resulting
in an error if not found.

Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2021-05-25 18:26:51 +02:00
Ranjani Sridharan
4d413567b0 topology: pre-process-object: Add support for pre-processing Objects
Add support for pre-processing object instances in the input
config. An object's attributes can be set in multiple places
such as, within the object instance, default values in the class
defnition, inherited from a parent object or explicitly set
in a parent object. Before converting the object config into
the relevant section in the existing syntax, all the attribute
values must be consolidated into one place so that it is easy
to verify if all mandatory attributes are set.
Also, the name of the object will be constructed from the
attributes defined in the attributes.constructor[] config
in the class definition and the unique attribute's value
must be set from the value passed in the object instance.

This patch create a temporary config for each object instance
and populates its unique attribute value. The rest of the steps
will be added in the following patches.

Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
2021-05-25 18:26:51 +02:00