To allow for more flexibility i.e. populating component DAIs dynamically
during its initialization, without being limited to topology loading
procedure, expose snd_soc_register(), snd_soc_dapm_new_dai_widgets() and
snd_soc_dapm_free_widget() functions.
Allows users to first check available resources e.g. number of PCMs
supported by HDAudio codec before allocating the number of DAPM
widgets needed. This prevents superfluous objects from being created or
allows driver to adjust to situation when resources are limited.
Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
Link: https://lore.kernel.org/r/20220311153544.136854-3-cezary.rojewski@intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
To fix compilation warnings:
- struct 'snd_soc_pcm_runtime' declared inside parameter list will not
be visible outside of this definition or declaration
- struct 'soc_enum' declared inside parameter list will not be visible
outside of this definition or declaration
Declares the missing structure prototypes.
Signed-off-by: Tzung-Bi Shih <tzungbi@google.com>
Link: https://lore.kernel.org/r/20200625153543.85039-3-tzungbi@google.com
Signed-off-by: Mark Brown <broonie@kernel.org>
To fix compilation error:
- error: field 'XXX' has incomplete type
Moves definition of enum snd_soc_bias_level from soc.h to soc-dapm.h.
Signed-off-by: Tzung-Bi Shih <tzungbi@google.com>
Link: https://lore.kernel.org/r/20200625153543.85039-2-tzungbi@google.com
Signed-off-by: Mark Brown <broonie@kernel.org>
The current codebase makes use of the zero-length array language
extension to the C90 standard, but the preferred mechanism to declare
variable-length types such as these ones is a flexible array member[1][2],
introduced in C99:
struct foo {
int stuff;
struct boo array[];
};
By making use of the mechanism above, we will get a compiler warning
in case the flexible array does not occur last in the structure, which
will help us prevent some kind of undefined behavior bugs from being
inadvertently introduced[3] to the codebase from now on.
Also, notice that, dynamic memory allocations won't be affected by
this change:
"Flexible array members have incomplete type, and so the sizeof operator
may not be applied. As a quirk of the original implementation of
zero-length arrays, sizeof evaluates to zero."[1]
sizeof(flexible-array-member) triggers a warning because flexible array
members have incomplete type[1]. There are some instances of code in
which the sizeof operator is being incorrectly/erroneously applied to
zero-length arrays and the result is zero. Such instances may be hiding
some bugs. So, this work (flexible-array member conversions) will also
help to get completely rid of those sorts of issues.
This issue was found with the help of Coccinelle.
[1] https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html
[2] https://github.com/KSPP/linux/issues/21
[3] commit 7649773293 ("cxgb3/l2t: Fix undefined behaviour")
Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
Link: https://lore.kernel.org/r/20200507192228.GA16355@embeddedor
Signed-off-by: Mark Brown <broonie@kernel.org>
dpcm_path_put() (A) is calling kfree(*list).
The freed list is created by dapm_widget_list_create() (B) which is called
from snd_soc_dapm_dai_get_connected_widgets() (C) which is called from
dpcm_path_get() (D).
(B) dapm_widget_list_create(**list, ...)
{
...
=> *list = kzalloc();
...
}
(C) snd_soc_dapm_dai_get_connected_widgets(..., **list, ...)
{
...
dapm_widget_list_create(list, ...);
...
}
(D) dpcm_path_get(..., **list)
{
...
snd_soc_dapm_dai_get_connected_widgets(..., list, ...);
...
}
(A) dpcm_path_put(**list)
{
=> kfree(*list);
}
This kind of unbalance code is very difficult to read/understand.
To avoid this issue, this patch adds each missing paired function
dapm_widget_list_free() for dapm_widget_list_create() (B), and
snd_soc_dapm_dai_free_widgets() for snd_soc_dapm_dai_get_connected_widgets() (C).
This patch uses these, and moves dpcm_path_put() next to dpcm_path_get().
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87a75fjc9q.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
This patch adds new for_each_dapm_widgets() macro and use it.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Link: https://lore.kernel.org/r/878slbceyg.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
When we stop stream, if it was Playback, we might need to care
about power down time. In such case, we need to use delayed work.
We have same implementation for it at soc-pcm.c and soc-compress.c,
but we don't want to have duplicate code.
This patch adds snd_soc_dapm_stream_stop(), and share same code.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Reviewed-By: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Link: https://lore.kernel.org/r/871rs8t4uw.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
It is easy to read code if it is cleanly using paired function/naming,
like start <-> stop, register <-> unregister, etc, etc.
But, current ALSA SoC code is very random, unbalance, not paired, etc.
It is easy to create bug at the such code, and it will be difficult to
debug.
soc-dapm has snd_soc_dapm_free() which cleanups debugfs, widgets, list.
But, there is no paired initialize function.
This patch adds snd_soc_dapm_init() and initilaizing dapm
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87pnkw7lbj.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
We use snd_soc_dapm_new_control_unlocked for topology and have local
declaration, instead declare it properly in header like already declared
snd_soc_dapm_new_control.
Signed-off-by: Amadeusz Sławiński <amadeuszx.slawinski@intel.com>
Link: https://lore.kernel.org/r/20190827141712.21015-4-amadeuszx.slawinski@linux.intel.com
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Current soc-dapm / soc-core are using a long way round to call
.set_bias_level.
if (driver->set_bias_level)
dapm->set_bias_level = ...;
...
if (dapm->set_bias_level)
ret = dapm->set_bias_level(...);
We can directly call it via driver->set_bias_level.
One note here is that both Card and Component have dapm,
but, Card's dapm doesn't have dapm->component.
We need to check it.
This patch moves snd_soc_component_set_bias_level() to soc-component.c
and updates parameters.
dapm->set_bias_level is no longer needed
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87tvb94d0n.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Current soc-dapm / soc-core are using a long way round to call
.stream_event.
if (driver->stream_event)
dapm->stream_event = ...;
...
if (dapm->stream_event)
ret = dapm->stream_event(...);
We can directly call it via driver->stream_event.
One note here is that both Card and Component have dapm,
but, Card's dapm doesn't have dapm->component.
We need to check it.
This patch moves snd_soc_component_stream_event() to soc-component.c
and updates parameters.
dapm->stream_event is no longer needed
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87v9vp4d0r.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Current soc-dapm / soc-core are using a long way round to call
.seq_notifier.
if (driver->seq_notifier)
dapm->seq_notifier = ...;
...
if (dapm->seq_notifier)
ret = dapm->seq_notifier(...);
We can directly call it via driver->seq_notifier.
One note here is that both Card and Component have dapm,
but, Card's dapm doesn't have dapm->component.
We need to check it.
This patch moves snd_soc_component_seq_notifier() to soc-component.c,
and updates parameters.
dapm->seq_notifier is no longer needed
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Link: https://lore.kernel.org/r/87wog54d0v.wl-kuninori.morimoto.gx@renesas.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Prepare to use SND_SOC_DAPM_PRE_POST_PMU definition to
reduce coming code size and make it more readable.
Cc: stable@vger.kernel.org
Signed-off-by: Oleksandr Suvorov <oleksandr.suvorov@toradex.com>
Reviewed-by: Marcel Ziswiler <marcel.ziswiler@toradex.com>
Reviewed-by: Igor Opaniuk <igor.opaniuk@toradex.com>
Reviewed-by: Fabio Estevam <festevam@gmail.com>
Link: https://lore.kernel.org/r/20190719100524.23300-2-oleksandr.suvorov@toradex.com
Signed-off-by: Mark Brown <broonie@kernel.org>
To detect potential errors, let's add:
a) build-time warnings when the table size isn't aligned with the enum
list
b) run-time warnings when the values are not initialized. This
requires an increase by one of all values to avoid the default 0.
Suggested-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Currently all widgets attached to a DAI link will be powered
up when the DAI is active, however this may include routes
that are not actually in use if there are unused channels
available on the DAI.
The macros for creating AIF widgets already include an entry for
slot, it is proposed to change that to channel. The effective
difference here being respresenting the logical channel index
rather than the physical slot index. The CODECs currently
using the slot entry on the DAPM_AIF macros are using it in
a manner consistent with this, the CODECs not using it just
have the field set to zero.
A variable is added to snd_soc_dapm_widget to represent
this channel index and then for each AIF widget attached to
a DAI this is compared against the number of channels on
the stream. Enabling the links for those which will be in
use. This has the nice property that the CODECs which haven't
used the slot/channel entry in the macro will function exactly
as before due to all the AIF widgets having a channel of zero
and a stream by definition having at least one channel.
Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Add a new dobj type SND_SOC_DOBJ_GRAPH for dapm routes
and add snd_soc_dobj member to struct snd_soc_dapm_route.
This enables device drivers to save driver specific
data pertaining to dapm routes and also be able
to clean up the data when the driver module is unloaded.
Also, reorder the snd_soc_dobj_type types to align with
matching topology header types.
Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Larger CODECs may contain many several hundred widgets and which set of
parameters is selected only needs to be recorded on a per DAI basis. As
such move the selected CODEC to CODEC link params to be stored in the
runtime rather than the DAPM widget, to save some memory.
Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Currently, snd_soc_dapm_connect_dai_link_widgets connects up the routes
representing normal DAIs, however CODEC to CODEC links are hooked up
through separate infrastructure in soc_link_dai_widgets. Improve the
consistency of the code by using snd_soc_dapm_connect_dai_link for both
types of DAIs.
Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Commit a655de808c ("ASoC: core: Allow topology to override
machine driver FE DAI link config.") caused soc_dai_hw_params to
be come dependent on the substream private_data being set with
a pointer to the snd_soc_pcm_runtime. Currently, CODEC to CODEC
links don't set this, which causes a NULL pointer dereference:
[<4069de54>] (soc_dai_hw_params) from
[<40694b68>] (snd_soc_dai_link_event+0x1a0/0x380)
Since the ASoC core in general assumes that the substream
private_data will be set to a pointer to the snd_soc_pcm_runtime,
update the CODEC to CODEC links to respect this.
Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Purpose of having pinctrl dapm is to dynamically put the pins in
low power state when they are not actively used by the audio and
saving power.
Without this each driver has to set the pinctrl states, either
during probe or dynamically depending on the callbacks received
from ASoC core.
Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
Add some DAPM widget types to better support the construction of DAPM
graphs within DSPs.
Signed-off-by: Liam Girdwood <liam.r.girdwood@linux.intel.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
A DAPM_DOUBLE_R control type can be used for dual channel mixer input
selectors / mute controls across 2 registers, possibly toggling both
channels together.
The control is meant to be shared by 2 widgets, 1 for each channel,
such that the mixer control exposed to userspace remains a combined
stereo control.
Signed-off-by: Chen-Yu Tsai <wens@csie.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
A DAPM_DOUBLE control type can be used for dual channel mixer input
selectors / mute controls in one register, possibly toggling both
channels together.
The control is meant to be shared by 2 widgets, 1 for each channel,
such that the mixer control exposed to userspace remains a combined
stereo control.
Signed-off-by: Chen-Yu Tsai <wens@csie.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
To support double channel shared controls split across 2 registers, one
for each channel, we must be able to update both registers together.
Add a second set of register fields to struct snd_soc_dapm_update, and
update the DAPM control writeback (put) callbacks to support this.
For codecs that use custom events which call into DAPM to do updates,
also clear struct snd_soc_dapm_update before using it, so the second
set of fields remains clean.
Signed-off-by: Chen-Yu Tsai <wens@csie.org>
Signed-off-by: Mark Brown <broonie@kernel.org>
This is useful outside the core, when one dapm element is added
at a time.
Signed-off-by: Subhransu S. Prusty <subhransu.s.prusty@intel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Certain situations may warrant examining DAPM paths only to a certain
arbitrary point, as opposed to always following them to the end. For
instance, when establishing a connection between a front-end DAI link
and a back-end DAI link in a DPCM path, it does not make sense to walk
the DAPM graph beyond the first widget associated with a back-end link.
This patch introduces a mechanism which lets a user of
dai_get_connected_widgets supply a function which will be called for
every node during the graph walk. When invoked, this function can
execute arbitrary logic to decide whether the walk, given a DAPM widget
and walk direction, should be terminated at that point or continued
as normal.
Signed-off-by: Piotr Stankiewicz <piotrs@opensource.wolfsonmicro.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Commit 086d7f804e ("ASoC: Convert WM8962 MICBIAS to a supply widget",
2011-09-23) says:
A supply widget is generally clearer than a MICBIAS widget and a
mic bias is just a type of supply so use a supply widget for the
MICBIAS. This also avoids confusion with the routing when
connected to multiple inputs.
but this has never been documented as a policy. Add some comments to
make it clear.
Signed-off-by: John Keeping <john@metanate.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
DAPM models various widgets but lacks a sink widget.
DSPs can have modules which take audio data, process it and are
capable of generating events thus acting as a sink of data.
To make the dapm graph complete for such paths we need a dapm
sink widget for these modules, so add a SND_SOC_DAPM_SINK to
declare such a widget. This widget will be treated as
SND_SOC_DAPM_EP_SINK endpoint in the dapm graph
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Reviewed-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Mark Brown <broonie@kernel.org>
If there is anything in damp->path_source_cache or
damp->path_sink_cache, it can not be valid after the widgets have been
freed. Without this patch a repeated remove and load of a machine
driver may cause NULL pointer reference in dapm_wcache_lookup() when a
freed widget, not belonging to any list, is haunting in the wcache.
Signed-off-by: Jyri Sarha <jsarha@ti.com>
Reported-by: Felipe Balbi <balbi@ti.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Given a kcontrol, we may want to access the parent widget
and it's associated data. So export function to return it.
Signed-off-by: Mythri P K <mythri.p.k@intel.com>
Signed-off-by: Jeeja KP <jeeja.kp@intel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
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 <lars@metafoo.de>
Signed-off-by: Mark Brown <broonie@kernel.org>
Add helper iterator macros for iterating over the source and sink paths of
widget. This will make it easier to change the implementation later on.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Mark Brown <broonie@kernel.org>
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 <lars@metafoo.de>
Signed-off-by: Mark Brown <broonie@kernel.org>
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 <liam.r.girdwood@linux.intel.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
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 <liam.r.girdwood@linux.intel.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
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 <ckeepax@opensource.wolfsonmicro.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
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 <lars@metafoo.de>
Signed-off-by: Mark Brown <broonie@kernel.org>
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 <lars@metafoo.de>
Signed-off-by: Mark Brown <broonie@kernel.org>
Correct small copy and paste error where autodisable was not being
enabled for the SOC_DAPM_SINGLE_TLV_AUTODISABLE control.
Signed-off-by: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Cc: stable@vger.kernel.org