]> Git Repo - linux.git/blobdiff - sound/soc/soc-core.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/hid/hid
[linux.git] / sound / soc / soc-core.c
index 843b8b1c89d41082c034b30788a0e793c5c36d2b..b07eca2c6cccbd56da13a3453f1dac9fb92ad1e9 100644 (file)
@@ -38,6 +38,7 @@
 #include <sound/soc.h>
 #include <sound/soc-dpcm.h>
 #include <sound/soc-topology.h>
+#include <sound/soc-link.h>
 #include <sound/initval.h>
 
 #define CREATE_TRACE_POINTS
@@ -364,7 +365,7 @@ EXPORT_SYMBOL_GPL(snd_soc_get_pcm_runtime);
  */
 void snd_soc_close_delayed_work(struct snd_soc_pcm_runtime *rtd)
 {
-       struct snd_soc_dai *codec_dai = rtd->codec_dai;
+       struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
        int playback = SNDRV_PCM_STREAM_PLAYBACK;
 
        mutex_lock_nested(&rtd->card->pcm_mutex, rtd->card->pcm_subclass);
@@ -372,7 +373,8 @@ void snd_soc_close_delayed_work(struct snd_soc_pcm_runtime *rtd)
        dev_dbg(rtd->dev,
                "ASoC: pop wq checking: %s status: %s waiting: %s\n",
                codec_dai->driver->playback.stream_name,
-               codec_dai->stream_active[playback] ? "active" : "inactive",
+               snd_soc_dai_stream_active(codec_dai, playback) ?
+               "active" : "inactive",
                rtd->pop_wait ? "yes" : "no");
 
        /* are we waiting on this codec DAI stream */
@@ -487,20 +489,18 @@ static struct snd_soc_pcm_runtime *soc_new_pcm_runtime(
         * dais = [][][][][][][][][][][][][][][][][][]
         *        ^cpu_dais         ^codec_dais
         *        |--- num_cpus ---|--- num_codecs --|
+        * see
+        *      asoc_rtd_to_cpu()
+        *      asoc_rtd_to_codec()
         */
-       rtd->cpu_dais   = &rtd->dais[0];
-       rtd->codec_dais = &rtd->dais[dai_link->num_cpus];
-
-       /*
-        * rtd remaining settings
-        */
-       rtd->card = card;
-       rtd->dai_link = dai_link;
+       rtd->num_cpus   = dai_link->num_cpus;
+       rtd->num_codecs = dai_link->num_codecs;
+       rtd->card       = card;
+       rtd->dai_link   = dai_link;
+       rtd->num        = card->num_rtd++;
 
        /* see for_each_card_rtds */
        list_add_tail(&rtd->list, &card->rtd_list);
-       rtd->num = card->num_rtd;
-       card->num_rtd++;
 
        return rtd;
 
@@ -548,7 +548,7 @@ int snd_soc_suspend(struct device *dev)
                        continue;
 
                for_each_rtd_codec_dais(rtd, i, dai) {
-                       if (dai->stream_active[playback])
+                       if (snd_soc_dai_stream_active(dai, playback))
                                snd_soc_dai_digital_mute(dai, 1, playback);
                }
        }
@@ -561,8 +561,7 @@ int snd_soc_suspend(struct device *dev)
                snd_pcm_suspend_all(rtd->pcm);
        }
 
-       if (card->suspend_pre)
-               card->suspend_pre(card);
+       snd_soc_card_suspend_pre(card);
 
        /* close any waiting streams */
        snd_soc_flush_all_delayed_work(card);
@@ -632,8 +631,7 @@ int snd_soc_suspend(struct device *dev)
                }
        }
 
-       if (card->suspend_post)
-               card->suspend_post(card);
+       snd_soc_card_suspend_post(card);
 
        return 0;
 }
@@ -662,8 +660,7 @@ static void soc_resume_deferred(struct work_struct *work)
        /* Bring us up into D2 so that DAPM starts enabling things */
        snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D2);
 
-       if (card->resume_pre)
-               card->resume_pre(card);
+       snd_soc_card_resume_pre(card);
 
        for_each_card_components(card, component) {
                if (snd_soc_component_is_suspended(component))
@@ -690,13 +687,12 @@ static void soc_resume_deferred(struct work_struct *work)
                        continue;
 
                for_each_rtd_codec_dais(rtd, i, dai) {
-                       if (dai->stream_active[playback])
+                       if (snd_soc_dai_stream_active(dai, playback))
                                snd_soc_dai_digital_mute(dai, 0, playback);
                }
        }
 
-       if (card->resume_post)
-               card->resume_post(card);
+       snd_soc_card_resume_post(card);
 
        dev_dbg(card->dev, "ASoC: resume work completed\n");
 
@@ -720,7 +716,7 @@ int snd_soc_resume(struct device *dev)
 
        /* activate pins from sleep state */
        for_each_card_components(card, component)
-               if (component->active)
+               if (snd_soc_component_active(component))
                        pinctrl_pm_select_default_state(component->dev);
 
        dev_dbg(dev, "ASoC: Scheduling resume work\n");
@@ -744,9 +740,6 @@ static inline void soc_resume_init(struct snd_soc_card *card)
 }
 #endif
 
-static const struct snd_soc_dai_ops null_dai_ops = {
-};
-
 static struct device_node
 *soc_component_to_node(struct snd_soc_component *component)
 {
@@ -865,8 +858,12 @@ static int soc_dai_link_sanity_check(struct snd_soc_card *card,
                 * Defer card registration if codec component is not added to
                 * component list.
                 */
-               if (!soc_find_component(codec))
+               if (!soc_find_component(codec)) {
+                       dev_dbg(card->dev,
+                               "ASoC: codec component %s not found for link %s\n",
+                               codec->name, link->name);
                        return -EPROBE_DEFER;
+               }
        }
 
        for_each_link_platforms(link, i, platform) {
@@ -886,8 +883,12 @@ static int soc_dai_link_sanity_check(struct snd_soc_card *card,
                 * Defer card registration if platform component is not added to
                 * component list.
                 */
-               if (!soc_find_component(platform))
+               if (!soc_find_component(platform)) {
+                       dev_dbg(card->dev,
+                               "ASoC: platform component %s not found for link %s\n",
+                               platform->name, link->name);
                        return -EPROBE_DEFER;
+               }
        }
 
        for_each_link_cpus(link, i, cpu) {
@@ -908,8 +909,12 @@ static int soc_dai_link_sanity_check(struct snd_soc_card *card,
                 * component list.
                 */
                if ((cpu->of_node || cpu->name) &&
-                   !soc_find_component(cpu))
+                   !soc_find_component(cpu)) {
+                       dev_dbg(card->dev,
+                               "ASoC: cpu component %s not found for link %s\n",
+                               cpu->name, link->name);
                        return -EPROBE_DEFER;
+               }
 
                /*
                 * At least one of CPU DAI name or CPU device name/node must be
@@ -942,8 +947,7 @@ void snd_soc_remove_pcm_runtime(struct snd_soc_card *card,
        /*
         * Notify the machine driver for extra destruction
         */
-       if (card->remove_dai_link)
-               card->remove_dai_link(card, rtd->dai_link);
+       snd_soc_card_remove_dai_link(card, rtd->dai_link);
 
        soc_free_pcm_runtime(rtd);
 }
@@ -973,8 +977,9 @@ int snd_soc_add_pcm_runtime(struct snd_soc_card *card,
        /*
         * Notify the machine driver for extra initialization
         */
-       if (card->add_dai_link)
-               card->add_dai_link(card, dai_link);
+       ret = snd_soc_card_add_dai_link(card, dai_link);
+       if (ret < 0)
+               return ret;
 
        if (dai_link->ignore)
                return 0;
@@ -989,36 +994,28 @@ int snd_soc_add_pcm_runtime(struct snd_soc_card *card,
        if (!rtd)
                return -ENOMEM;
 
-       rtd->num_cpus = dai_link->num_cpus;
        for_each_link_cpus(dai_link, i, cpu) {
-               rtd->cpu_dais[i] = snd_soc_find_dai(cpu);
-               if (!rtd->cpu_dais[i]) {
+               asoc_rtd_to_cpu(rtd, i) = snd_soc_find_dai(cpu);
+               if (!asoc_rtd_to_cpu(rtd, i)) {
                        dev_info(card->dev, "ASoC: CPU DAI %s not registered\n",
                                 cpu->dai_name);
                        goto _err_defer;
                }
-               snd_soc_rtd_add_component(rtd, rtd->cpu_dais[i]->component);
+               snd_soc_rtd_add_component(rtd, asoc_rtd_to_cpu(rtd, i)->component);
        }
 
-       /* Single cpu links expect cpu and cpu_dai in runtime data */
-       rtd->cpu_dai = rtd->cpu_dais[0];
-
        /* Find CODEC from registered CODECs */
-       rtd->num_codecs = dai_link->num_codecs;
        for_each_link_codecs(dai_link, i, codec) {
-               rtd->codec_dais[i] = snd_soc_find_dai(codec);
-               if (!rtd->codec_dais[i]) {
+               asoc_rtd_to_codec(rtd, i) = snd_soc_find_dai(codec);
+               if (!asoc_rtd_to_codec(rtd, i)) {
                        dev_info(card->dev, "ASoC: CODEC DAI %s not registered\n",
                                 codec->dai_name);
                        goto _err_defer;
                }
 
-               snd_soc_rtd_add_component(rtd, rtd->codec_dais[i]->component);
+               snd_soc_rtd_add_component(rtd, asoc_rtd_to_codec(rtd, i)->component);
        }
 
-       /* Single codec links expect codec and codec_dai in runtime data */
-       rtd->codec_dai = rtd->codec_dais[0];
-
        /* Find PLATFORM from registered PLATFORMs */
        for_each_link_platforms(dai_link, i, platform) {
                for_each_component(component) {
@@ -1037,32 +1034,11 @@ _err_defer:
 }
 EXPORT_SYMBOL_GPL(snd_soc_add_pcm_runtime);
 
-static int soc_dai_pcm_new(struct snd_soc_pcm_runtime *rtd)
-{
-       struct snd_soc_dai *dai;
-       int i, ret = 0;
-
-       for_each_rtd_dais(rtd, i, dai) {
-               struct snd_soc_dai_driver *drv = dai->driver;
-
-               if (drv->pcm_new)
-                       ret = drv->pcm_new(rtd, dai);
-               if (ret < 0) {
-                       dev_err(dai->dev,
-                               "ASoC: Failed to bind %s with pcm device\n",
-                               dai->name);
-                       return ret;
-               }
-       }
-
-       return 0;
-}
-
 static int soc_init_pcm_runtime(struct snd_soc_card *card,
                                struct snd_soc_pcm_runtime *rtd)
 {
        struct snd_soc_dai_link *dai_link = rtd->dai_link;
-       struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+       struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
        struct snd_soc_component *component;
        int ret, num, i;
 
@@ -1070,14 +1046,9 @@ static int soc_init_pcm_runtime(struct snd_soc_card *card,
        rtd->pmdown_time = pmdown_time;
 
        /* do machine specific initialization */
-       if (dai_link->init) {
-               ret = dai_link->init(rtd);
-               if (ret < 0) {
-                       dev_err(card->dev, "ASoC: failed to init %s: %d\n",
-                               dai_link->name, ret);
-                       return ret;
-               }
-       }
+       ret = snd_soc_link_init(rtd);
+       if (ret < 0)
+               return ret;
 
        if (dai_link->dai_fmt) {
                ret = snd_soc_runtime_set_dai_fmt(rtd, dai_link->dai_fmt);
@@ -1122,7 +1093,7 @@ static int soc_init_pcm_runtime(struct snd_soc_card *card,
                return ret;
        }
 
-       return soc_dai_pcm_new(rtd);
+       return snd_soc_pcm_dai_new(rtd);
 }
 
 static void soc_set_name_prefix(struct snd_soc_card *card,
@@ -1278,64 +1249,23 @@ err_probe:
        return ret;
 }
 
-static void soc_remove_dai(struct snd_soc_dai *dai, int order)
-{
-       int err;
-
-       if (!dai || !dai->probed || !dai->driver ||
-           dai->driver->remove_order != order)
-               return;
-
-       err = snd_soc_dai_remove(dai);
-       if (err < 0)
-               dev_err(dai->dev,
-                       "ASoC: failed to remove %s: %d\n",
-                       dai->name, err);
-
-       dai->probed = 0;
-}
-
-static int soc_probe_dai(struct snd_soc_dai *dai, int order)
-{
-       int ret;
-
-       if (dai->probed ||
-           dai->driver->probe_order != order)
-               return 0;
-
-       ret = snd_soc_dai_probe(dai);
-       if (ret < 0) {
-               dev_err(dai->dev, "ASoC: failed to probe DAI %s: %d\n",
-                       dai->name, ret);
-               return ret;
-       }
-
-       dai->probed = 1;
-
-       return 0;
-}
-
 static void soc_remove_link_dais(struct snd_soc_card *card)
 {
-       int i;
-       struct snd_soc_dai *dai;
        struct snd_soc_pcm_runtime *rtd;
        int order;
 
        for_each_comp_order(order) {
                for_each_card_rtds(card, rtd) {
-                       /* remove DAIs */
-                       for_each_rtd_dais(rtd, i, dai)
-                               soc_remove_dai(dai, order);
+                       /* remove all rtd connected DAIs in good order */
+                       snd_soc_pcm_dai_remove(rtd, order);
                }
        }
 }
 
 static int soc_probe_link_dais(struct snd_soc_card *card)
 {
-       struct snd_soc_dai *dai;
        struct snd_soc_pcm_runtime *rtd;
-       int i, order, ret;
+       int order, ret;
 
        for_each_comp_order(order) {
                for_each_card_rtds(card, rtd) {
@@ -1344,12 +1274,10 @@ static int soc_probe_link_dais(struct snd_soc_card *card)
                                "ASoC: probe %s dai link %d late %d\n",
                                card->name, rtd->num, order);
 
-                       /* probe the CPU DAI */
-                       for_each_rtd_dais(rtd, i, dai) {
-                               ret = soc_probe_dai(dai, order);
-                               if (ret)
-                                       return ret;
-                       }
+                       /* probe all rtd connected DAIs in good order */
+                       ret = snd_soc_pcm_dai_probe(rtd, order);
+                       if (ret)
+                               return ret;
                }
        }
 
@@ -1724,7 +1652,11 @@ match:
                        dai_link->dpcm_playback = 1;
                        dai_link->dpcm_capture = 1;
 
-                       /* override any BE fixups */
+                       /*
+                        * override any BE fixups
+                        * see
+                        *      snd_soc_link_be_hw_params_fixup()
+                        */
                        dai_link->be_hw_params_fixup =
                                component->driver->be_hw_params_fixup;
 
@@ -1791,8 +1723,7 @@ static void __soc_setup_card_name(char *name, int len,
        }
 }
 
-static void soc_cleanup_card_resources(struct snd_soc_card *card,
-                                      int card_probed)
+static void soc_cleanup_card_resources(struct snd_soc_card *card)
 {
        struct snd_soc_pcm_runtime *rtd, *n;
 
@@ -1816,8 +1747,7 @@ static void soc_cleanup_card_resources(struct snd_soc_card *card,
        soc_cleanup_card_debugfs(card);
 
        /* remove the card */
-       if (card_probed && card->remove)
-               card->remove(card);
+       snd_soc_card_remove(card);
 
        if (card->snd_card) {
                snd_card_free(card->snd_card);
@@ -1828,12 +1758,10 @@ static void soc_cleanup_card_resources(struct snd_soc_card *card,
 static void snd_soc_unbind_card(struct snd_soc_card *card, bool unregister)
 {
        if (card->instantiated) {
-               int card_probed = 1;
-
                card->instantiated = false;
                snd_soc_flush_all_delayed_work(card);
 
-               soc_cleanup_card_resources(card, card_probed);
+               soc_cleanup_card_resources(card);
                if (!unregister)
                        list_add(&card->list, &unbind_card_list);
        } else {
@@ -1847,7 +1775,7 @@ static int snd_soc_bind_card(struct snd_soc_card *card)
        struct snd_soc_pcm_runtime *rtd;
        struct snd_soc_component *component;
        struct snd_soc_dai_link *dai_link;
-       int ret, i, card_probed = 0;
+       int ret, i;
 
        mutex_lock(&client_mutex);
        mutex_lock_nested(&card->mutex, SND_SOC_CARD_CLASS_INIT);
@@ -1895,12 +1823,9 @@ static int snd_soc_bind_card(struct snd_soc_card *card)
                goto probe_end;
 
        /* initialise the sound card only once */
-       if (card->probe) {
-               ret = card->probe(card);
-               if (ret < 0)
-                       goto probe_end;
-               card_probed = 1;
-       }
+       ret = snd_soc_card_probe(card);
+       if (ret < 0)
+               goto probe_end;
 
        /* probe all components used by DAI links on this card */
        ret = soc_probe_link_components(card);
@@ -1983,15 +1908,9 @@ static int snd_soc_bind_card(struct snd_soc_card *card)
                }
        }
 
-       if (card->late_probe) {
-               ret = card->late_probe(card);
-               if (ret < 0) {
-                       dev_err(card->dev, "ASoC: %s late_probe() failed: %d\n",
-                               card->name, ret);
-                       goto probe_end;
-               }
-       }
-       card_probed = 1;
+       ret = snd_soc_card_late_probe(card);
+       if (ret < 0)
+               goto probe_end;
 
        snd_soc_dapm_new_widgets(card);
 
@@ -2008,12 +1927,12 @@ static int snd_soc_bind_card(struct snd_soc_card *card)
 
        /* deactivate pins to sleep state */
        for_each_card_components(card, component)
-               if (!component->active)
+               if (!snd_soc_component_active(component))
                        pinctrl_pm_select_sleep_state(component->dev);
 
 probe_end:
        if (ret < 0)
-               soc_cleanup_card_resources(card, card_probed);
+               soc_cleanup_card_resources(card);
 
        mutex_unlock(&card->mutex);
        mutex_unlock(&client_mutex);
@@ -2160,22 +2079,6 @@ static int snd_soc_add_controls(struct snd_card *card, struct device *dev,
        return 0;
 }
 
-struct snd_kcontrol *snd_soc_card_get_kcontrol(struct snd_soc_card *soc_card,
-                                              const char *name)
-{
-       struct snd_card *card = soc_card->snd_card;
-       struct snd_kcontrol *kctl;
-
-       if (unlikely(!name))
-               return NULL;
-
-       list_for_each_entry(kctl, &card->controls, list)
-               if (!strncmp(kctl->id.name, name, sizeof(kctl->id.name)))
-                       return kctl;
-       return NULL;
-}
-EXPORT_SYMBOL_GPL(snd_soc_card_get_kcontrol);
-
 /**
  * snd_soc_add_component_controls - Add an array of controls to a component.
  *
@@ -2404,8 +2307,6 @@ struct snd_soc_dai *snd_soc_register_dai(struct snd_soc_component *component,
        dai->component = component;
        dai->dev = dev;
        dai->driver = dai_drv;
-       if (!dai->driver->ops)
-               dai->driver->ops = &null_dai_ops;
 
        /* see for_each_component_dais */
        list_add_tail(&dai->list, &component->dai_list);
This page took 0.048132 seconds and 4 git commands to generate.