ASoC: Move DAPM paths from DAPM context to snd_soc_card
authorJarkko Nikula <jhnikula@gmail.com>
Tue, 14 Dec 2010 10:18:30 +0000 (12:18 +0200)
committerMark Brown <broonie@opensource.wolfsonmicro.com>
Wed, 15 Dec 2010 18:00:41 +0000 (18:00 +0000)
Decoupling DAPM paths from DAPM context is a first prerequisite when
extending ASoC core to cross-device paths. This patch is almost a nullop and
does not allow to construct cross-device setup but the path clean-up part in
dapm_free_widgets is prepared to remove cross-device paths between a device
being removed and others.

Signed-off-by: Jarkko Nikula <jhnikula@gmail.com>
Acked-by: Liam Girdwood <lrg@slimlogic.co.uk>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
include/sound/soc-dapm.h
include/sound/soc.h
sound/soc/codecs/tlv320aic3x.c
sound/soc/soc-core.c
sound/soc/soc-dapm.c

index aef975f47bad9f7171aeed2a2bc1607161b9f715..2c1e0eed43d56840550e0812c95077a2677c4f99 100644 (file)
@@ -463,7 +463,6 @@ struct snd_soc_dapm_widget {
 /* DAPM context */
 struct snd_soc_dapm_context {
        struct list_head widgets;
-       struct list_head paths;
        enum snd_soc_bias_level bias_level;
        enum snd_soc_bias_level suspend_bias_level;
        struct delayed_work delayed_work;
index 7e65b015f8dd37f3c323e2b65b72a7ab4fa5876a..466895b627b5f44f19ebd29a274cee79fe50e988 100644 (file)
@@ -661,6 +661,8 @@ struct snd_soc_card {
        struct list_head platform_dev_list;
        struct list_head dai_dev_list;
 
+       struct list_head paths;
+
 #ifdef CONFIG_DEBUG_FS
        struct dentry *debugfs_card_root;
        struct dentry *debugfs_pop_time;
index fc5abdf0bcb03d11ec59b95985a3bb0319385299..899af41787c1fa440b130afd0da3af169f19f3aa 100644 (file)
@@ -185,7 +185,7 @@ static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol,
 
        if (snd_soc_test_bits(widget->codec, reg, val_mask, val)) {
                /* find dapm widget path assoc with kcontrol */
-               list_for_each_entry(path, &widget->dapm->paths, list) {
+               list_for_each_entry(path, &widget->dapm->card->paths, list) {
                        if (path->kcontrol != kcontrol)
                                continue;
 
index 1dc4b11c19886d8d3b0a2390436e67ac62163a89..bdb2ca9da58bb75cd6c96b71b62e810d551c3b7e 100644 (file)
@@ -1879,6 +1879,7 @@ static int soc_probe(struct platform_device *pdev)
        INIT_LIST_HEAD(&card->dai_dev_list);
        INIT_LIST_HEAD(&card->codec_dev_list);
        INIT_LIST_HEAD(&card->platform_dev_list);
+       INIT_LIST_HEAD(&card->paths);
 
        soc_init_card_debugfs(card);
 
@@ -3481,7 +3482,6 @@ int snd_soc_register_codec(struct device *dev,
                codec->compress_type = SND_SOC_FLAT_COMPRESSION;
 
        INIT_LIST_HEAD(&codec->dapm.widgets);
-       INIT_LIST_HEAD(&codec->dapm.paths);
        codec->write = codec_drv->write;
        codec->read = codec_drv->read;
        codec->dapm.bias_level = SND_SOC_BIAS_OFF;
index 3d310af289074aec507484aec56408ece645c580..5d9ec4a3a9f12c756dd2c2661f839b599f1a9e7d 100644 (file)
@@ -272,7 +272,7 @@ static int dapm_connect_mux(struct snd_soc_dapm_context *dapm,
 
        for (i = 0; i < e->max; i++) {
                if (!(strcmp(control_name, e->texts[i]))) {
-                       list_add(&path->list, &dapm->paths);
+                       list_add(&path->list, &dapm->card->paths);
                        list_add(&path->list_sink, &dest->sources);
                        list_add(&path->list_source, &src->sinks);
                        path->name = (char*)e->texts[i];
@@ -294,7 +294,7 @@ static int dapm_connect_mixer(struct snd_soc_dapm_context *dapm,
        /* search for mixer kcontrol */
        for (i = 0; i < dest->num_kcontrols; i++) {
                if (!strcmp(control_name, dest->kcontrols[i].name)) {
-                       list_add(&path->list, &dapm->paths);
+                       list_add(&path->list, &dapm->card->paths);
                        list_add(&path->list_sink, &dest->sources);
                        list_add(&path->list_source, &src->sinks);
                        path->name = dest->kcontrols[i].name;
@@ -453,7 +453,7 @@ static inline void dapm_clear_walk(struct snd_soc_dapm_context *dapm)
 {
        struct snd_soc_dapm_path *p;
 
-       list_for_each_entry(p, &dapm->paths, list)
+       list_for_each_entry(p, &dapm->card->paths, list)
                p->walked = 0;
 }
 
@@ -1180,7 +1180,7 @@ static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
                return 0;
 
        /* find dapm widget path assoc with kcontrol */
-       list_for_each_entry(path, &widget->dapm->paths, list) {
+       list_for_each_entry(path, &widget->dapm->card->paths, list) {
                if (path->kcontrol != kcontrol)
                        continue;
 
@@ -1214,7 +1214,7 @@ static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget,
                return -ENODEV;
 
        /* find dapm widget path assoc with kcontrol */
-       list_for_each_entry(path, &widget->dapm->paths, list) {
+       list_for_each_entry(path, &widget->dapm->card->paths, list) {
                if (path->kcontrol != kcontrol)
                        continue;
 
@@ -1305,15 +1305,28 @@ static void dapm_free_widgets(struct snd_soc_dapm_context *dapm)
 
        list_for_each_entry_safe(w, next_w, &dapm->widgets, list) {
                list_del(&w->list);
+               /*
+                * remove source and sink paths associated to this widget.
+                * While removing the path, remove reference to it from both
+                * source and sink widgets so that path is removed only once.
+                */
+               list_for_each_entry_safe(p, next_p, &w->sources, list_sink) {
+                       list_del(&p->list_sink);
+                       list_del(&p->list_source);
+                       list_del(&p->list);
+                       kfree(p->long_name);
+                       kfree(p);
+               }
+               list_for_each_entry_safe(p, next_p, &w->sinks, list_source) {
+                       list_del(&p->list_sink);
+                       list_del(&p->list_source);
+                       list_del(&p->list);
+                       kfree(p->long_name);
+                       kfree(p);
+               }
                kfree(w->name);
                kfree(w);
        }
-
-       list_for_each_entry_safe(p, next_p, &dapm->paths, list) {
-               list_del(&p->list);
-               kfree(p->long_name);
-               kfree(p);
-       }
 }
 
 static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm,
@@ -1420,7 +1433,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm,
 
        /* connect static paths */
        if (control == NULL) {
-               list_add(&path->list, &dapm->paths);
+               list_add(&path->list, &dapm->card->paths);
                list_add(&path->list_sink, &wsink->sources);
                list_add(&path->list_source, &wsource->sinks);
                path->connect = 1;
@@ -1442,7 +1455,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm,
        case snd_soc_dapm_supply:
        case snd_soc_dapm_aif_in:
        case snd_soc_dapm_aif_out:
-               list_add(&path->list, &dapm->paths);
+               list_add(&path->list, &dapm->card->paths);
                list_add(&path->list_sink, &wsink->sources);
                list_add(&path->list_source, &wsource->sinks);
                path->connect = 1;
@@ -1465,7 +1478,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm,
        case snd_soc_dapm_mic:
        case snd_soc_dapm_line:
        case snd_soc_dapm_spk:
-               list_add(&path->list, &dapm->paths);
+               list_add(&path->list, &dapm->card->paths);
                list_add(&path->list_sink, &wsink->sources);
                list_add(&path->list_source, &wsource->sinks);
                path->connect = 0;