aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars-Peter Clausen <lars@metafoo.de>2013-07-29 11:14:00 -0400
committerMark Brown <broonie@linaro.org>2013-07-29 13:41:00 -0400
commit5106b92f80a2cd37c52cffed80b4f5acfb77ccfd (patch)
tree609669cf0003ada313400b64be82feaa37b317ec
parentcf7c1de20c576477d42deae255cbc6e439bb5dc0 (diff)
ASoC: dapm: Keep a list of paths per kcontrol
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>
-rw-r--r--include/sound/soc-dapm.h2
-rw-r--r--sound/soc/soc-dapm.c40
2 files changed, 29 insertions, 13 deletions
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index d7d26cc8e3fc..693c75bbd5d1 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -490,7 +490,6 @@ struct snd_soc_dapm_path {
490 /* source (input) and sink (output) widgets */ 490 /* source (input) and sink (output) widgets */
491 struct snd_soc_dapm_widget *source; 491 struct snd_soc_dapm_widget *source;
492 struct snd_soc_dapm_widget *sink; 492 struct snd_soc_dapm_widget *sink;
493 struct snd_kcontrol *kcontrol;
494 493
495 /* status */ 494 /* status */
496 u32 connect:1; /* source and sink widgets are connected */ 495 u32 connect:1; /* source and sink widgets are connected */
@@ -503,6 +502,7 @@ struct snd_soc_dapm_path {
503 502
504 struct list_head list_source; 503 struct list_head list_source;
505 struct list_head list_sink; 504 struct list_head list_sink;
505 struct list_head list_kcontrol;
506 struct list_head list; 506 struct list_head list;
507}; 507};
508 508
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index bad6f6db74c9..b779d36d5b3a 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -176,6 +176,7 @@ static inline struct snd_soc_dapm_widget *dapm_cnew_widget(
176 176
177struct dapm_kcontrol_data { 177struct dapm_kcontrol_data {
178 unsigned int value; 178 unsigned int value;
179 struct list_head paths;
179 struct snd_soc_dapm_widget_list wlist; 180 struct snd_soc_dapm_widget_list wlist;
180}; 181};
181 182
@@ -194,6 +195,7 @@ static int dapm_kcontrol_data_alloc(struct snd_soc_dapm_widget *widget,
194 195
195 data->wlist.widgets[0] = widget; 196 data->wlist.widgets[0] = widget;
196 data->wlist.num_widgets = 1; 197 data->wlist.num_widgets = 1;
198 INIT_LIST_HEAD(&data->paths);
197 199
198 kcontrol->private_data = data; 200 kcontrol->private_data = data;
199 201
@@ -234,6 +236,26 @@ static int dapm_kcontrol_add_widget(struct snd_kcontrol *kcontrol,
234 return 0; 236 return 0;
235} 237}
236 238
239static void dapm_kcontrol_add_path(const struct snd_kcontrol *kcontrol,
240 struct snd_soc_dapm_path *path)
241{
242 struct dapm_kcontrol_data *data = snd_kcontrol_chip(kcontrol);
243
244 list_add_tail(&path->list_kcontrol, &data->paths);
245}
246
247static struct list_head *dapm_kcontrol_get_path_list(
248 const struct snd_kcontrol *kcontrol)
249{
250 struct dapm_kcontrol_data *data = snd_kcontrol_chip(kcontrol);
251
252 return &data->paths;
253}
254
255#define dapm_kcontrol_for_each_path(path, kcontrol) \
256 list_for_each_entry(path, dapm_kcontrol_get_path_list(kcontrol), \
257 list_kcontrol)
258
237static unsigned int dapm_kcontrol_get_value(const struct snd_kcontrol *kcontrol) 259static unsigned int dapm_kcontrol_get_value(const struct snd_kcontrol *kcontrol)
238{ 260{
239 struct dapm_kcontrol_data *data = snd_kcontrol_chip(kcontrol); 261 struct dapm_kcontrol_data *data = snd_kcontrol_chip(kcontrol);
@@ -671,7 +693,7 @@ static int dapm_create_or_share_mixmux_kcontrol(struct snd_soc_dapm_widget *w,
671 } 693 }
672 694
673 w->kcontrols[kci] = kcontrol; 695 w->kcontrols[kci] = kcontrol;
674 path->kcontrol = kcontrol; 696 dapm_kcontrol_add_path(kcontrol, path);
675 697
676 return 0; 698 return 0;
677} 699}
@@ -691,7 +713,7 @@ static int dapm_new_mixer(struct snd_soc_dapm_widget *w)
691 continue; 713 continue;
692 714
693 if (w->kcontrols[i]) { 715 if (w->kcontrols[i]) {
694 path->kcontrol = w->kcontrols[i]; 716 dapm_kcontrol_add_path(w->kcontrols[i], path);
695 continue; 717 continue;
696 } 718 }
697 719
@@ -730,7 +752,7 @@ static int dapm_new_mux(struct snd_soc_dapm_widget *w)
730 return ret; 752 return ret;
731 753
732 list_for_each_entry(path, &w->sources, list_sink) 754 list_for_each_entry(path, &w->sources, list_sink)
733 path->kcontrol = w->kcontrols[0]; 755 dapm_kcontrol_add_path(w->kcontrols[0], path);
734 756
735 return 0; 757 return 0;
736} 758}
@@ -1990,10 +2012,7 @@ static int soc_dapm_mux_update_power(struct snd_soc_card *card,
1990 int found = 0; 2012 int found = 0;
1991 2013
1992 /* find dapm widget path assoc with kcontrol */ 2014 /* find dapm widget path assoc with kcontrol */
1993 list_for_each_entry(path, &card->paths, list) { 2015 dapm_kcontrol_for_each_path(path, kcontrol) {
1994 if (path->kcontrol != kcontrol)
1995 continue;
1996
1997 if (!path->name || !e->texts[mux]) 2016 if (!path->name || !e->texts[mux])
1998 continue; 2017 continue;
1999 2018
@@ -2043,11 +2062,7 @@ static int soc_dapm_mixer_update_power(struct snd_soc_card *card,
2043 int found = 0; 2062 int found = 0;
2044 2063
2045 /* find dapm widget path assoc with kcontrol */ 2064 /* find dapm widget path assoc with kcontrol */
2046 list_for_each_entry(path, &card->paths, list) { 2065 dapm_kcontrol_for_each_path(path, kcontrol) {
2047 if (path->kcontrol != kcontrol)
2048 continue;
2049
2050 /* found, now check type */
2051 found = 1; 2066 found = 1;
2052 path->connect = connect; 2067 path->connect = connect;
2053 dapm_mark_dirty(path->source, "mixer connection"); 2068 dapm_mark_dirty(path->source, "mixer connection");
@@ -2152,6 +2167,7 @@ static void dapm_free_path(struct snd_soc_dapm_path *path)
2152{ 2167{
2153 list_del(&path->list_sink); 2168 list_del(&path->list_sink);
2154 list_del(&path->list_source); 2169 list_del(&path->list_source);
2170 list_del(&path->list_kcontrol);
2155 list_del(&path->list); 2171 list_del(&path->list);
2156 kfree(path); 2172 kfree(path);
2157} 2173}