Skip to content

Commit

Permalink
ASoC: dapm: Keep a list of paths per kcontrol
Browse files Browse the repository at this point in the history
Currently we store for each path which control (if any at all) is associated
with that control. But we are only ever interested in the reverse relationship,
i.e. we want to know all the paths a certain control is associated with. This is
currently implemented by always iterating over all paths. This patch updates the
code to keep a list for each control which contains all the paths that are
associated with that control. This improves the run time of e.g.
soc_dapm_mixer_update_power() and soc_dapm_mux_update_power() from O(n) (with n
being the number of paths for the card) to O(1).

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Mark Brown <broonie@linaro.org>
  • Loading branch information
Lars-Peter Clausen authored and Mark Brown committed Jul 29, 2013
1 parent cf7c1de commit 5106b92
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 13 deletions.
2 changes: 1 addition & 1 deletion include/sound/soc-dapm.h
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,6 @@ struct snd_soc_dapm_path {
/* source (input) and sink (output) widgets */
struct snd_soc_dapm_widget *source;
struct snd_soc_dapm_widget *sink;
struct snd_kcontrol *kcontrol;

/* status */
u32 connect:1; /* source and sink widgets are connected */
Expand All @@ -503,6 +502,7 @@ struct snd_soc_dapm_path {

struct list_head list_source;
struct list_head list_sink;
struct list_head list_kcontrol;
struct list_head list;
};

Expand Down
40 changes: 28 additions & 12 deletions sound/soc/soc-dapm.c
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ static inline struct snd_soc_dapm_widget *dapm_cnew_widget(

struct dapm_kcontrol_data {
unsigned int value;
struct list_head paths;
struct snd_soc_dapm_widget_list wlist;
};

Expand All @@ -194,6 +195,7 @@ static int dapm_kcontrol_data_alloc(struct snd_soc_dapm_widget *widget,

data->wlist.widgets[0] = widget;
data->wlist.num_widgets = 1;
INIT_LIST_HEAD(&data->paths);

kcontrol->private_data = data;

Expand Down Expand Up @@ -234,6 +236,26 @@ static int dapm_kcontrol_add_widget(struct snd_kcontrol *kcontrol,
return 0;
}

static void dapm_kcontrol_add_path(const struct snd_kcontrol *kcontrol,
struct snd_soc_dapm_path *path)
{
struct dapm_kcontrol_data *data = snd_kcontrol_chip(kcontrol);

list_add_tail(&path->list_kcontrol, &data->paths);
}

static struct list_head *dapm_kcontrol_get_path_list(
const struct snd_kcontrol *kcontrol)
{
struct dapm_kcontrol_data *data = snd_kcontrol_chip(kcontrol);

return &data->paths;
}

#define dapm_kcontrol_for_each_path(path, kcontrol) \
list_for_each_entry(path, dapm_kcontrol_get_path_list(kcontrol), \
list_kcontrol)

static unsigned int dapm_kcontrol_get_value(const struct snd_kcontrol *kcontrol)
{
struct dapm_kcontrol_data *data = snd_kcontrol_chip(kcontrol);
Expand Down Expand Up @@ -671,7 +693,7 @@ static int dapm_create_or_share_mixmux_kcontrol(struct snd_soc_dapm_widget *w,
}

w->kcontrols[kci] = kcontrol;
path->kcontrol = kcontrol;
dapm_kcontrol_add_path(kcontrol, path);

return 0;
}
Expand All @@ -691,7 +713,7 @@ static int dapm_new_mixer(struct snd_soc_dapm_widget *w)
continue;

if (w->kcontrols[i]) {
path->kcontrol = w->kcontrols[i];
dapm_kcontrol_add_path(w->kcontrols[i], path);
continue;
}

Expand Down Expand Up @@ -730,7 +752,7 @@ static int dapm_new_mux(struct snd_soc_dapm_widget *w)
return ret;

list_for_each_entry(path, &w->sources, list_sink)
path->kcontrol = w->kcontrols[0];
dapm_kcontrol_add_path(w->kcontrols[0], path);

return 0;
}
Expand Down Expand Up @@ -1990,10 +2012,7 @@ static int soc_dapm_mux_update_power(struct snd_soc_card *card,
int found = 0;

/* find dapm widget path assoc with kcontrol */
list_for_each_entry(path, &card->paths, list) {
if (path->kcontrol != kcontrol)
continue;

dapm_kcontrol_for_each_path(path, kcontrol) {
if (!path->name || !e->texts[mux])
continue;

Expand Down Expand Up @@ -2043,11 +2062,7 @@ static int soc_dapm_mixer_update_power(struct snd_soc_card *card,
int found = 0;

/* find dapm widget path assoc with kcontrol */
list_for_each_entry(path, &card->paths, list) {
if (path->kcontrol != kcontrol)
continue;

/* found, now check type */
dapm_kcontrol_for_each_path(path, kcontrol) {
found = 1;
path->connect = connect;
dapm_mark_dirty(path->source, "mixer connection");
Expand Down Expand Up @@ -2152,6 +2167,7 @@ static void dapm_free_path(struct snd_soc_dapm_path *path)
{
list_del(&path->list_sink);
list_del(&path->list_source);
list_del(&path->list_kcontrol);
list_del(&path->list);
kfree(path);
}
Expand Down

0 comments on commit 5106b92

Please sign in to comment.