summaryrefslogtreecommitdiffstats
path: root/sound/soc/soc-core.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/soc-core.c')
-rw-r--r--sound/soc/soc-core.c245
1 files changed, 73 insertions, 172 deletions
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 843b8b1c89d4..b07eca2c6ccc 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -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);