Making the Most of Dynamic Audio Power Management – Lars-Peter Clausen, Analog Devices

Each component driver describes it hardware as a piece of graph, with special widgets (= nodes) for its inputs and output. A board driver describes how the components are connected.
Each widget has a type, e.g. speaker, amp, …
DAPM (Dynamic Audio Power Management) detects the active data paths on the graph and manager the power states of the widgets on the active paths, and also manages their dependencies (e.g. clocks). It first determines target power state, then power sequencing.
For finding the target power state, three categories of widgets are considered. Endpoint widgets are e.g. PCM device, speaker, micropohone, tone generator: points where data is inserted into the data path or where it comes out. The endpoints are the things that are explicitly activated or deactivated. In addition, endpoints can be marked as disconnected. Pass-through widgets are in-between end points. They are only powered on if they are on an active path between a source and sink endpoint. Some of these have dynamic routing, i.e. the path can change, e.g. a switch can be closed or open (in which case there is no output). Supply widgets are not on the data path, but support it, e.g. a clock. They are only powered up if they are connected to something that is active. To determine power state, the number of connected inputs and outputs (over the whole path) is determined for each widgets. Sources have a fixed 1 #conn_inputs, sinks fixed 1 #conn_outputs. If either #conn_inputs or #conn_outputs is zero, the path is not active (e.g. there’s an open switch on it) and the target power state is off. Finally, the supply widgets are considered: if one of their consumers is powered up, they are powered up as well.
For power sequencing, first a diff is made between the current state and the target state. Then the changes are made in a certain sequence to avoid popping. First, anything that is newly disabled is powered down. Then, any routing changes are executed (this is the point where the minimum number of widgets are powered up so changes will have the minimal number of artefacts). Finally, widgets are powered on. Each widget type has a sequence ID to determine the order in which to power widgets on or off (different ID for on and off). In addition, a driver can assign a sub-sequence ID to specify ordering within the same type (this is only valid for widgets controlled by the same driver). Within the same sub-sequence ID, changes that can be done with a single IO register update are collected together. Note that the IO register manipulations are handled directly by DAPM, i.e. the driver specifies register offset and mask. In most cases, no callback functions are necessary. This makes it possible to optimize register accesses by coalescing, especially important for slow IO like I2C – and it doesn’t have to be redone for all drivers.
Dynamic graph changes are also possible. Adding/removing edges (= routing changes), it’s also possible to just mark an edge as inactive. Builtin support for mixers, muxers, demuxers, which can be “shared” i.e. with single control for multiple widgets (e.g. for stereo). Mixers can auto-mute, i.e. DAPM will switch input off by itself when it’s not on an active path – avoids clicking – and v.v. when powering up. Similar for mux. Enabling/disabling an endpoint e.g. when a jack is not connected. Starting/stopping streams. Hotplug of components is not well supported.
In V4L there is something similar, it would be nice if this could be factored out. Compared to traditional run-time PM, DAPM can handle cyclic dependencies and can handle a number of complexities autonomously (without involving the driver).
It is not possible to disable DAPM, but it’s fairly small. It’s using strings all over the place, removing that would make it even smaller. It could also be converted to an object-oriented approach, right now the widget struct contains info for all widget types.
Is it possible to add more power states than just on or off? Yes, but this should be managed by userspace, they should make sure it’s kept on if it takes too long to warm up.


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s