13 Aug, 2015

1 commit

  • After the recent cleanups and generalizations of the DAPM algorithm the
    handling of input and output paths is now fully symmetric. This means by
    making some slight changes to the data structure and using arrays with one
    entry for each direction, rather than separate fields, it is possible to
    create a generic implementation that is capable of handling both input and
    output paths.

    Unfortunately this generalization significantly increases the code size on
    the hot path of is_connected_{input,output}_ep() and
    dapm_widget_invalidate_{input,output}_paths(), which has a negative impact
    on the overall performance. The inner loops of those functions are quite
    small and the generic implementation adds extra pointer arithmetic in a few
    places.

    Testing on ARM shows that the combined code size of the specialized
    functions is about 50% larger than the generalized function in relative
    numbers. But in absolute numbers its less than 200 bytes, which is still
    quite small. On the other hand the generalized function increases the
    execution time of dapm_power_one_widget() by 30%. Given that this function
    is one of the most often called functions of the DAPM framework the
    trade-off of getting better performance at expense of generating slightly
    larger code at seems to be worth it.

    To avoid this still keep two versions of these functions around, one for
    input and one for output. But have a generic implementation of the
    algorithm which gets inlined by those two versions. And then let the
    compiler take care of optimizing it and removing he extra instructions.

    This still reduces the source code size as well as the makes making changes
    to the implementation more straight forward since the same change does no
    longer need to be done in two separate places. Also on the slow paths we
    can use a generic implementations that handle both input and output paths.

    Signed-off-by: Lars-Peter Clausen
    Signed-off-by: Mark Brown

    Lars-Peter Clausen
     

29 Jul, 2015

1 commit


22 Jul, 2015

1 commit

  • snd_soc_tplg_widget_remove_all() has a verbatim copy of an older version of
    the widget freeing code from dapm_free_widgets(). Add a new helper function
    that takes care of freeing a widget and use it in both places.

    This removes the duplicated code and also makes sure that future changes to
    the widget freeing code only have to be made in one location.

    Signed-off-by: Lars-Peter Clausen
    Signed-off-by: Mark Brown

    Lars-Peter Clausen
     

06 Jun, 2015

2 commits


04 Jun, 2015

2 commits

  • The topology core parses the FW topology file for known block types and
    instanciates any common ALSA/ASoC objects that it discovers. The core
    also passes any block that is does not understand to client component
    drivers for enumeration.

    The core exports some APIs to client drivers in order to load and unload
    firmware topology data as use case require.

    Currently the core deals with the following object types :-

    o kcontrols. This includes TLV, enumerated and bytes controls.
    o DAPM widgets. All types with any associated kcontrol.
    o DAPM graph.
    o FE PCM. FE PCM capabilities and configuration can be defined.
    o BE DAI Link. BE DAI link capabilities and configuration can be defined.
    o Codec codec style links capabilities and configuration.

    Signed-off-by: Liam Girdwood
    Signed-off-by: Mark Brown

    Liam Girdwood
     
  • The ASoC topology UAPI header defines the structures
    required to define any DSP firmware audio topology and control objects from
    userspace.

    The following objects are supported :-
    o kcontrols including TLV controls.
    o DAPM widgets and graph elements
    o Vendor bespoke objects.
    o Coefficient data
    o FE PCM capabilities and config.
    o BE link capabilities and config.
    o Codec codec link capabilities and config.
    o Topology object manifest.

    The file format is simple and divided into blocks for each object type and
    each block has a header that defines it's size and type. Blocks can be in
    any order of type and can either all be in a single file or spread across
    more than one file. Blocks also have a group identifier ID so that they can
    be loaded and unloaded by ID.

    Signed-off-by: Liam Girdwood
    Signed-off-by: Mark Brown

    Liam Girdwood
     

12 May, 2015

1 commit

  • Some CODECs have a significant number of DAPM routes and for each route,
    when it is added to the card, the entire card widget list must be
    searched. When adding routes it is very likely, however, that adjacent
    routes will require adjacent widgets. For example all the routes for a
    mux are likely added in a block and the sink widget will be the same
    each time and it is also quite likely that the source widgets are
    sequential located in the widget list.

    This patch adds a cache to the DAPM context, this cache will hold the
    source and sink widgets from the last call to snd_soc_dapm_add_route for
    that context. A small search of the widget list will be made from those
    points for both the sink and source. Currently this search only checks
    both the last widget and the one adjacent to it.

    On wm8280 which has approximately 500 widgets and 30000 routes (one of
    the largest CODECs in mainline), the number of paths that hit the cache
    is 24000, which significantly improves probe time.

    Signed-off-by: Charles Keepax
    Signed-off-by: Mark Brown

    Charles Keepax
     

07 May, 2015

1 commit

  • A demux is conceptually similar to a mux. Where a mux has multiple input
    and one output and selects one of the inputs to be connected to the output,
    the demux has one input and multiple outputs and selects one of the outputs
    to which the input gets connected.

    This similarity makes it straight forward to support them in DAPM using the
    existing mux support, we only need to swap sinks and sources when initially
    setting up the paths.

    The only slightly tricky part is that there can only be one control per
    path. Since mixers/muxes are at the sink of a path and a demux is at the
    source and both types want a control it is not possible to directly connect
    a demux output to a mixer/mux input. The patch adds some sanity checks to
    make sure that this does not happen.

    Drivers who want to model hardware which directly connects a demux output
    to a mixer/mux input can do this by inserting a dummy widget between the
    two. E.g.:

    { "Dummy", "Demux Control", "Demux" },
    { "Mixer", "Mixer Control", "Dummy" },

    Signed-off-by: Lars-Peter Clausen
    Signed-off-by: Mark Brown

    Lars-Peter Clausen
     

29 Apr, 2015

1 commit


28 Apr, 2015

1 commit

  • Currently drivers are responsible for managing the bias_level field of
    their DAPM context. The DAPM state itself is managed by the DAPM core
    though and the core has certain expectations on how and when the bias_level
    field should be updated. If drivers don't adhere to these undefined
    behavior can occur.

    This patch adds a few helper functions for manipulating the DAPM context
    state, each function with a description on when it should be used and what
    its effects are. This will also help us to move more of the bias_level
    management from drivers to the DAPM core.

    For convenience also add snd_soc_codec_* wrappers around these helpers.

    Signed-off-by: Lars-Peter Clausen
    Signed-off-by: Mark Brown

    Lars-Peter Clausen
     

23 Apr, 2015

1 commit


13 Apr, 2015

2 commits


02 Apr, 2015

2 commits


18 Mar, 2015

1 commit

  • dai-link params for codec-codec links were fixed. The fixed
    link between codec and another chip which may be another codec,
    baseband, bluetooth codec etc may require run time configuaration
    changes. This change provides an optional alsa control to select
    one of the params from a list of params.

    Signed-off-by: Nikesh Oswal
    Signed-off-by: Mark Brown

    Nikesh Oswal
     

16 Mar, 2015

1 commit


05 Feb, 2015

2 commits


03 Feb, 2015

1 commit


15 Jan, 2015

1 commit

  • There are no more users of this field left so it can finally be removed.
    New users should use snd_soc_dapm_to_codec(w->dapm);

    The reason why it is removed is because it doesn't fit to well anymore in
    the componentized ASoC hierarchy, where DAPM works on the snd_soc_component
    level. And the alternative of snd_soc_dapm_to_codec(w->dapm) typically
    generates the same amount of code, so there is really no reason to keep it.

    For automatic conversion the following coccinelle semantic patch can be used:
    //
    @@
    struct snd_soc_dapm_widget *w;
    @@
    -w->codec
    +snd_soc_dapm_to_codec(w->dapm)
    //

    Signed-off-by: Lars-Peter Clausen
    Signed-off-by: Mark Brown

    Lars-Peter Clausen
     

22 Dec, 2014

1 commit

  • For legacy reasons the ASoC framework assumes that a CODEC INPUT or OUTPUT
    widget that is not explicitly connected to a external source or sink is
    potentially connected to a source or a sink and hence the framework treats
    the widget itself as source (for INPUT) or sink (for OUTPUT). For this
    reason a INPUT or OUTPUT widget that is really not connected needs to be
    explicitly marked as so.

    Setting the card's fully_routed flag will cause the ASoC core, once that all
    widgets and routes have been registered, to go through the list of all
    widgets and mark all INPUT and OUTPUT that are not externally connected as
    non-connected. This essentially negates the default behaviour of treating
    INPUT or OUTPUT widgets without external routes as sources or sinks.

    This patch takes a different approach while getting the same result. Instead
    of first marking INPUT and OUTPUT widgets as sinks/sources and then later
    marking them as non-connected, just never mark them as a sink or a source if
    the fully_routed flag is set on a card.

    This requires a lot less code and also results in a slightly faster card
    initialization since there is no need to iterate over all widgets and check
    whether the INPUT and OUTPUT widgets are connected or not.

    Signed-off-by: Lars-Peter Clausen
    Signed-off-by: Mark Brown

    Lars-Peter Clausen
     

28 Oct, 2014

4 commits

  • Currently we cache the number of input and output paths going to/from a
    widget only within a power update sequence. But not in between power update
    sequences.

    But we know how changes to the DAPM graph affect the number of input (form a
    source) and output (to a sink) paths of a widget and only need to
    recalculate them if a operation has been performed that might have changed
    them.
    * Adding/removing or connecting/disconnecting a path means that the for
    the source of the path the number of output paths can change and for
    the sink the number of input paths can change.
    * Connecting/disconnecting a widget has the same effect has connecting/
    disconnecting all paths of the widget. So for the widget itself the
    number of inputs and outputs can change, for all sinks of the widget
    the number of inputs can change and for all sources of the widget the
    number of outputs can change.
    * Activating/Deactivating a stream can either change the number of
    outputs on the sources of the widget associated with the stream or the
    number of inputs on the sinks.

    Instead of always invalidating all cached numbers of input and output paths
    for each power up or down sequence this patch restructures the code to only
    invalidate the cached numbers when a operation that might change them has
    been performed. This can greatly reduce the number of DAPM power checks for
    some very common operations.

    Since per DAPM operation typically only either change the number of inputs
    or outputs the number of path checks is reduced by at least 50%. The number
    of neighbor checks is also reduced about the same percentage, but since the
    number of neighbors encountered when walking from sink to source is not the
    same as when walking from source to sink the actual numbers will slightly
    vary from card to card (e.g. for a mixer we see 1 neighbor when walking from
    source to sink, but the number of inputs neighbors when walking from source
    to sink).

    Bigger improvements can be observed for widgets with multiple connected
    inputs and output (e.g. mixers probably being the most widespread form of
    this). Previously we had to re-calculate the number of inputs and outputs
    on all input and output paths. With this change we only have to re-calculate
    the number of outputs on the input path that got changed and the number of
    inputs on the output paths.

    E.g. imagine the following example:

    A --> B ----.
    v
    M --> N --> Z
    Signed-off-by: Mark Brown

    Lars-Peter Clausen
     
  • The state of endpoint widgets is affected by that card's power state.
    Endpoint widgets that do no have the ignore_suspend flag set will be
    considered inactive during suspend. So they have to be re-checked and marked
    dirty after the card's power state changes. Currently the input and output
    widgets are marked dirty instead, this works most of the time since
    typically a path from one endpoint to another will go via a input or output
    widget. But marking the endpoints dirty is technically more correct and will
    also work for odd corner cases.

    Signed-off-by: Lars-Peter Clausen
    Signed-off-by: Mark Brown

    Lars-Peter Clausen
     
  • Supply widgets do not count towards the input and output widgets of their
    neighbors and for supply widgets themselves we do not care for the number
    of input or output paths. This means that a path that connects to a supply
    widget effectively behaves the same as a path that as the weak property set.
    This patch adds a new path flag that gets set to true when the path is
    connected to at least one supply widget. If a path with the flag set is
    encountered in is_connected_{input,output}_ep() is is skipped in the same
    way that weak paths are skipped. This slightly brings down the number of
    path checks.

    Since both the weak and the supply flag are implemented as bitfields which
    are stored in the same word there is no runtime overhead due to checking
    both rather than just one and also the size of the path struct is not
    increased by this patch. Another advantage is that we do not have to handle
    supply widgets in is_connected_{input,output}_ep() anymore since it will
    never be called for supply widgets. The only exception is from
    dapm_widget_power_read_file() where a check is added to special case supply
    widgets.

    Testing with the ADAU1761, which has a handful of supply widgets, shows the
    following changes in the DAPM stats for a playback stream start.

    Power Path Neighbour
    Before: 34 78 117
    After: 34 48 117

    Signed-off-by: Lars-Peter Clausen
    Signed-off-by: Mark Brown

    Lars-Peter Clausen
     
  • DAPM widgets can be classified into four categories:
    * supply: Supply widgets do not affect the power state of their
    non-supply widget neighbors and unlike other widgets a
    supply widget is not powered up when it is on an active
    path, but when at least on of its neighbors is powered up.
    * source: A source is a widget that receives data from outside the
    DAPM graph or generates data. This can for example be a
    microphone, the playback DMA or a signal generator. A source
    widget will be considered powered up if there is an active
    path to a sink widget.
    * sink: A sink is a widget that transmits data to somewhere outside
    of the DAPM graph. This can e.g. be a speaker or the capture
    DMA. A sink widget will be considered powered up if there is
    an active path from a source widget.
    * normal: Normal widgets are widgets not covered by the categories
    above. A normal widget will be considered powered up if it
    is on an active path between a source widget and a sink
    widget.

    The way the number of input and output paths for a widget is calculated
    depends on its category. There are a bunch of factors which decide which
    category a widget is. Currently there is no formal classification of these
    categories and we calculate the category of the widget based on these
    factors whenever we want to know it. This is at least once for every widget
    during each power update sequence. The factors which determine the category
    of the widgets are mostly static though and if at all change rather seldom.
    This patch introduces three new per widget flags, one for each of non-normal
    widgets categories. Instead of re-computing the category each time we want
    to know them the flags will be checked. For the majority of widgets the
    category is solely determined by the widget id, which means it never changes
    and only has to be set once when the widget is created. The only widgets
    with dynamic categories are:

    snd_soc_dapm_dai_out: Is considered a sink iff the capture stream is
    active, otherwise normal.
    snd_soc_dapm_dai_in: Is considered a source iff the playback stream
    is active, otherwise normal.
    snd_soc_dapm_input: Is considered a sink iff it has no outgoing
    paths, otherwise normal.
    snd_soc_dapm_output: Is considered a source iff it has no incoming
    paths, otherwise normal.
    snd_soc_dapm_line: Is considered a sink iff it has no outgoing paths
    and is considered a source iff it has no incoming paths,
    otherwise normal.

    For snd_soc_dapm_dai_out/snd_soc_dapm_dai_in widgets the category will be
    updated when a stream is started or stopped. For the other dynamic widgets
    the category will be updated when a path connecting to it is added or
    removed.

    Introducing those new widget categories allows to make
    is_connected_{output,input}_ep, which are among the hottest paths of the
    DAPM algorithm, more generic and significantly shorter.

    The before and after sizes for is_connected_{output,input}_ep are:

    On ARM (defconfig + CONFIG_SND_SOC):
    function old new delta
    is_connected_output_ep 480 340 -140
    is_connected_input_ep 456 352 -104

    On amd64 (defconfig + CONFIG_SND_SOC):
    function old new delta
    is_connected_output_ep 579 427 -152
    is_connected_input_ep 563 427 -136

    Which is about a 25%-30% decrease, other architectures are expected to have
    similar numbers. At the same time the size of the snd_soc_dapm_widget struct
    does not change since the new flags are stored in the same word as the
    existing flags.

    Note: that since the per widget 'ext' flag was only used to decide whether a
    snd_soc_dapm_input or snd_soc_dapm_output widget was a source or a sink it
    is now unused and can be removed.

    Signed-off-by: Lars-Peter Clausen
    Signed-off-by: Mark Brown

    Lars-Peter Clausen
     

22 Oct, 2014

1 commit

  • The 'walked' flag was used to avoid walking paths that have already been
    walked. But since we started caching the number of inputs and outputs of a
    path we never actually get into a situation where we try to walk a path that
    has the 'walked' flag set.

    There are two cases in which we can end up walking a path multiple times
    within a single run of is_connected_output_ep() or is_connected_input_ep().

    1) If a path splits up and rejoins later:

    .--> C ---v
    A -> B E --> F
    '--> D ---^

    When walking from A to F we'll end up at E twice, once via C and once via D.
    But since we do a depth first search we'll fully discover the path and
    initialize the number of outputs/inputs of the widget the first time we get
    there. The second time we get there we'll use the cached value and not
    bother to check any of the paths again. So we'll never see a path where
    'walked' is set in this case.

    2) If there is a circle:

    A --> B F
    '--> D ---'

    When walking from A to F we'll end up twice at B. But since there is a
    circle the 'walking' flag will still be set on B once we get there the
    second time. This means we won't look at any of it's outgoing paths. So in
    this case we won't ever see a path where 'walked' is set either.

    So it is safe to remove the flag. This on one hand means we remove some
    always true checks from one of the hottest paths of the DAPM algorithm and
    on the other hand means we do not have to do the tedious clearing of the
    flag after checking the number inputs or outputs of a widget.

    Signed-off-by: Lars-Peter Clausen
    Signed-off-by: Mark Brown

    Lars-Peter Clausen
     

06 Oct, 2014

2 commits


03 Oct, 2014

1 commit


30 Sep, 2014

1 commit


05 Sep, 2014

1 commit

  • There is a substantial amount of drivers that in go to SND_SOC_BIAS_OFF on
    suspend and go back to SND_SOC_BIAS_SUSPEND on resume (Often this is even
    the only thing done in the suspend and resume handlers). This patch
    introduces a new suspend_bias_off flag, which when set by a driver will let
    the ASoC core automatically put the device's DAPM context at the
    SND_SOC_BIAS_OFF level during suspend. Once the device is resumed the DAPM
    context will go back to SND_SOC_BIAS_STANDBY (if the context is idle,
    otherwise to SND_SOC_BIAS_ON).

    This will allow us to remove a fair bit of duplicated code from the drivers.

    Signed-off-by: Lars-Peter Clausen
    Signed-off-by: Mark Brown

    Lars-Peter Clausen
     

22 Jun, 2014

4 commits

  • The platform field in the snd_soc_dapm_widget and snd_soc_dapm_context structs
    is now unused can be removed. New code that wants to get the platform for a
    widget or dapm context should use snd_soc_dapm_to_platform(w->dapm) or
    snd_soc_dapm_to_platform(dapm).

    Signed-off-by: Lars-Peter Clausen
    Signed-off-by: Mark Brown

    Lars-Peter Clausen
     
  • This patch adds full DAPM support at the component level. Previously there was
    only full DAPM support for CODECs and partial DAPM support (e.g. no Mixers nor
    MUXs) for platforms. Having DAPM support at the component level will allow all
    types of components to use DAPM and also help in consolidating the DAPM support
    between CODECs and platforms.

    Since the DAPM context is directly embedded into the snd_soc_codec and
    snd_soc_platform struct and the 'dapm' field is directly referenced in a lot of
    drivers moving the field just right now is not possible without causing code
    churn. The approach this patch takes is to add two new fields to the component
    struct. One field which is the pointer to the actual DAPM context used by the
    component and one DAPM context that will be used as the default if no other
    context was specified. For CODECs and platforms the pointer is initialized to
    point to the CODEC or platform DAPM context. All generic code when referencing
    a component's DAPM struct will go via the pointer. This will make it possible to
    eventually seamlessly move the DAPM context from snd_soc_codec and
    snd_soc_platform struct over once all direct references have been eliminated.

    Signed-off-by: Lars-Peter Clausen
    Signed-off-by: Mark Brown

    Lars-Peter Clausen
     
  • Currently the DAPM code directly looks at the CODEC driver struct to get a
    handle to the set_bias_level() callback. This patch adds a new set_bias_level()
    callback to the DAPM context struct. The DAPM code will use this new callback
    instead of the CODEC callback. For CODECs the new callback is set up to call the
    CODEC specific set_bias_level callback(). Not looking directly at the CODEC
    driver struct will allow non CODEC DAPM contexts to implement a set_bias_level()
    callback.

    This is also similar to how the seq_notifier() and stream_event() callbacks are
    currently handled.

    Signed-off-by: Lars-Peter Clausen
    Signed-off-by: Mark Brown

    Lars-Peter Clausen
     
  • Currently only pins in CODEC DAPM contexts are automatically marked as
    non-connected if the card has the fully_routed flag set. This makes sense since
    widgets which qualify for auto-disconnection are only found in CODEC DAPM
    contexts. But with componentisation this is going to change, so consider all
    widgets for auto-disconnection.

    Also it is probably faster to walk the widgets list only once rather than once
    for each CODEC.

    Signed-off-by: Lars-Peter Clausen
    Signed-off-by: Mark Brown

    Lars-Peter Clausen
     

22 May, 2014

1 commit


13 May, 2014

1 commit

  • Commit commit de9ba98b6d ("ASoC: dapm: Make widget power register settings more
    flexible") added generic support for on_val/off_val in the DAPM core. With this
    in place there is no need anymore for having a special event callback for
    SND_SOC_DAPM_REG() widgets.

    Signed-off-by: Lars-Peter Clausen
    Signed-off-by: Mark Brown

    Lars-Peter Clausen
     

22 Apr, 2014

1 commit

  • We currently have two very similar IO abstractions in ASoC, one for CODECs, the
    other for platforms. Moving this to the component level will allow us to unify
    those two. It will also enable us to move the standard kcontrol helpers as well
    as DAPM support to the component level.

    The new component level abstraction layer is primarily build around regmap.
    There is a per component pointer for the regmap instance for the underlying
    device. There are four new function snd_soc_component_read(),
    snd_soc_component_write(), snd_soc_component_update_bits() and
    snd_soc_component_update_bits_async(). They have the same signature as their
    regmap counter-part and will internally forward the call one-to-one to regmap.
    If the component it not using regmap it will fallback to using the custom IO
    callbacks. This is done to be able to support drivers that haven't been
    converted to regmap yet, but it is expected that this will eventually be removed
    in the future once all component drivers have been converted to regmap.

    Signed-off-by: Lars-Peter Clausen
    Signed-off-by: Mark Brown

    Lars-Peter Clausen