[alsa-devel] [PATCH 3/3 v2] ASoC: add Component level pcm_new/pcm_free v2
Kuninori Morimoto
kuninori.morimoto.gx at renesas.com
Tue Jul 25 06:09:55 CEST 2017
From: Kuninori Morimoto <kuninori.morimoto.gx at renesas.com>
In current ALSA SoC, Platform only has pcm_new/pcm_free feature,
but it should be supported on Component level. This patch adds it.
The v1 was added commit 99b04f4c4051f7 ("ASoC: add Component level
pcm_new/pcm_free") but it called all "card" connected component's
pcm_new/free, it was wrong.
This patch calls "rtd" connected component.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx at renesas.com>
Tested-by: Arnaud Pouliquen <arnaud.pouliquen at st.com>
---
include/sound/soc.h | 6 ++++++
sound/soc/soc-core.c | 42 ++++++++++++++++++++++++++++++++++++++++++
sound/soc/soc-pcm.c | 30 +++++++++++++++++++++++++-----
3 files changed, 73 insertions(+), 5 deletions(-)
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 963eef6..ff5773d 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -806,6 +806,10 @@ struct snd_soc_component_driver {
int (*suspend)(struct snd_soc_component *);
int (*resume)(struct snd_soc_component *);
+ /* pcm creation and destruction */
+ int (*pcm_new)(struct snd_soc_pcm_runtime *);
+ void (*pcm_free)(struct snd_pcm *);
+
/* DT */
int (*of_xlate_dai_name)(struct snd_soc_component *component,
struct of_phandle_args *args,
@@ -881,6 +885,8 @@ struct snd_soc_component {
void (*remove)(struct snd_soc_component *);
int (*suspend)(struct snd_soc_component *);
int (*resume)(struct snd_soc_component *);
+ int (*pcm_new)(struct snd_soc_component *, struct snd_soc_pcm_runtime *);
+ void (*pcm_free)(struct snd_soc_component *, struct snd_pcm *);
/* machine specific init */
int (*init)(struct snd_soc_component *component);
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index d65520c..800c5b5 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -3197,6 +3197,22 @@ static int snd_soc_component_stream_event(struct snd_soc_dapm_context *dapm,
return component->driver->stream_event(component, event);
}
+static int snd_soc_component_drv_pcm_new(struct snd_soc_component *component,
+ struct snd_soc_pcm_runtime *rtd)
+{
+ if (component->driver->pcm_new)
+ return component->driver->pcm_new(rtd);
+
+ return 0;
+}
+
+static void snd_soc_component_drv_pcm_free(struct snd_soc_component *component,
+ struct snd_pcm *pcm)
+{
+ if (component->driver->pcm_free)
+ component->driver->pcm_free(pcm);
+}
+
static int snd_soc_component_initialize(struct snd_soc_component *component,
const struct snd_soc_component_driver *driver, struct device *dev)
{
@@ -3214,6 +3230,8 @@ static int snd_soc_component_initialize(struct snd_soc_component *component,
component->remove = component->driver->remove;
component->suspend = component->driver->suspend;
component->resume = component->driver->resume;
+ component->pcm_new = snd_soc_component_drv_pcm_new;
+ component->pcm_free= snd_soc_component_drv_pcm_free;
dapm = &component->dapm;
dapm->dev = dev;
@@ -3443,6 +3461,26 @@ static void snd_soc_platform_drv_remove(struct snd_soc_component *component)
platform->driver->remove(platform);
}
+static int snd_soc_platform_drv_pcm_new(struct snd_soc_component *component,
+ struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_platform *platform = snd_soc_component_to_platform(component);
+
+ if (platform->driver->pcm_new)
+ return platform->driver->pcm_new(rtd);
+
+ return 0;
+}
+
+static void snd_soc_platform_drv_pcm_free(struct snd_soc_component *component,
+ struct snd_pcm *pcm)
+{
+ struct snd_soc_platform *platform = snd_soc_component_to_platform(component);
+
+ if (platform->driver->pcm_free)
+ platform->driver->pcm_free(pcm);
+}
+
/**
* snd_soc_add_platform - Add a platform to the ASoC core
* @dev: The parent device for the platform
@@ -3466,6 +3504,10 @@ int snd_soc_add_platform(struct device *dev, struct snd_soc_platform *platform,
platform->component.probe = snd_soc_platform_drv_probe;
if (platform_drv->remove)
platform->component.remove = snd_soc_platform_drv_remove;
+ if (platform_drv->pcm_new)
+ platform->component.pcm_new = snd_soc_platform_drv_pcm_new;
+ if (platform_drv->pcm_free)
+ platform->component.pcm_free = snd_soc_platform_drv_pcm_free;
#ifdef CONFIG_DEBUG_FS
platform->component.debugfs_prefix = "platform";
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index df1587c..844bbd5 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -2632,12 +2632,28 @@ static int dpcm_fe_dai_close(struct snd_pcm_substream *fe_substream)
return ret;
}
+static void soc_pcm_free(struct snd_pcm *pcm)
+{
+ struct snd_soc_pcm_runtime *rtd = pcm->private_data;
+ struct snd_soc_rtdcom_list *rtdcom;
+ struct snd_soc_component *component;
+
+ for_each_rtdcom(rtd, rtdcom) {
+ component = rtdcom->component;
+
+ if (component->pcm_free)
+ component->pcm_free(component, pcm);
+ }
+}
+
/* create a new pcm */
int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
{
struct snd_soc_platform *platform = rtd->platform;
struct snd_soc_dai *codec_dai;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct snd_soc_component *component;
+ struct snd_soc_rtdcom_list *rtdcom;
struct snd_pcm *pcm;
char new_name[64];
int ret = 0, playback = 0, capture = 0;
@@ -2747,17 +2763,21 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
if (capture)
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &rtd->ops);
- if (platform->driver->pcm_new) {
- ret = platform->driver->pcm_new(rtd);
+ for_each_rtdcom(rtd, rtdcom) {
+ component = rtdcom->component;
+
+ if (!component->pcm_new)
+ continue;
+
+ ret = component->pcm_new(component, rtd);
if (ret < 0) {
- dev_err(platform->dev,
+ dev_err(component->dev,
"ASoC: pcm constructor failed: %d\n",
ret);
return ret;
}
}
-
- pcm->private_free = platform->driver->pcm_free;
+ pcm->private_free = soc_pcm_free;
out:
dev_info(rtd->card->dev, "%s <-> %s mapping ok\n",
(rtd->num_codecs > 1) ? "multicodec" : rtd->codec_dai->name,
--
1.9.1
More information about the Alsa-devel
mailing list