Overview¶
A component adds audio signal processing to a pipeline that’s running on the DSP. An instance of the component, called a component device (components are implemented in the driver-device model), is chained with other component devices and builds an audio processing path organized as a pipeline.
Component driver¶
Every component must implement a driver (see the comp_driver
) which
creates instances by handling new component requests coming from the
command handlers.
The driver must be registered on the system component driver list by calling
comp_register(comp_driver *)
and providing a unique component id in
order to receive the requests.
Each component driver declares its unique type
that is later used by the
uAPI to create a component of that type
. It also provides an entry point
to the component ops implementation.
UUIDs (Universally Unique Identifiers) provide a more scalable and
collision-free way of component identification. UUIDs are currently used as
the standard interface by all users of the SOF firmware, including the
tracing subsystem, the topology .m4 files, and the Linux topology driver.
Using the type
to define topology and create components is still
supported today; however, the type
will be moved out of the IPC struct
in the future. Therefore, be sure to allocate UUIDs for all newly-added component drivers.
The UUID entry declared in the FW code contains the identifier value as well
as the object which is the component name in this case. Both are
provided as the arguments to the DECLARE_SOF_RT_UUID()
macro. For
example, the volume component provides the following declaration:
/* b77e677e-5ff4-4188-af14-fba8bdbf8682 */
DECLARE_SOF_RT_UUID("volume", volume_uuid, 0xb77e677e, 0x5ff4, 0x4188,
0xaf, 0x14, 0xfb, 0xa8, 0xbd, 0xbf, 0x86, 0x82);
Note how the af14
16bit segment is split into two bytes at the beginning
of the second line.
volume
is the component name used by the sof-logger while printing the
trace source name. volume_uuid
is the symbol used later to associate the
declared UUID with the volume of the component driver:
static const struct comp_driver comp_volume = {
.type = SOF_COMP_VOLUME,
.uid = SOF_RT_UUID(volume_uuid),
...
};
See the UUID API for more details on UUID generation and declaration.
Create a component device¶
When a new component device is requested, the system comp_new()
function
finds the driver that’s registered with the requested unique component type
and calls the new()
function pointed by the registered driver’s data in
order to instantiate the device.
Following is the entry called to create a new component device:
struct comp_dev* comp_new(sof_ipc_comp *comp);
Handle the component device state¶
Note
COMP_STATE_SUSPEND is not used currently.
Refer to comp_set_state()
in Component API for details.
Implement the component API (comp_ops)¶
Every component driver implements the comp_ops
API.
Note
Some API functions are mandatory for specific component types since
the infrastructure code calls them selectively based on the target
component type. For instance, dai_config()
is only called for
SOF_COMP_DAI
and SOF_COMP_SG_DAI
and cannot be called for other
component types.
See struct comp_ops
documentation in Component API for details.