Commit f523aceb authored by Kuninori Morimoto's avatar Kuninori Morimoto Committed by Mark Brown
Browse files

ASoC: add Component level pcm_new/pcm_free v2



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 99b04f4c ("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: default avatarKuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 3b1b3a7b
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -795,6 +795,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 *);

	/* component wide operations */
	int (*set_sysclk)(struct snd_soc_component *component,
			  int clk_id, int source, unsigned int freq, int dir);
@@ -872,6 +876,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 *);

	int (*set_sysclk)(struct snd_soc_component *component,
			  int clk_id, int source, unsigned int freq, int dir);
+42 −0
Original line number Diff line number Diff line
@@ -3254,6 +3254,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)
{
@@ -3274,6 +3290,8 @@ static int snd_soc_component_initialize(struct snd_soc_component *component,
	component->set_sysclk = component->driver->set_sysclk;
	component->set_pll = component->driver->set_pll;
	component->set_jack = component->driver->set_jack;
	component->pcm_new = snd_soc_component_drv_pcm_new;
	component->pcm_free = snd_soc_component_drv_pcm_free;

	dapm = snd_soc_component_get_dapm(component);
	dapm->dev = dev;
@@ -3466,6 +3484,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
@@ -3489,6 +3527,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";
+21 −8
Original line number Diff line number Diff line
@@ -2633,12 +2633,18 @@ static int dpcm_fe_dai_close(struct snd_pcm_substream *fe_substream)
static void soc_pcm_private_free(struct snd_pcm *pcm)
{
	struct snd_soc_pcm_runtime *rtd = pcm->private_data;
	struct snd_soc_platform *platform = rtd->platform;
	struct snd_soc_rtdcom_list *rtdcom;
	struct snd_soc_component *component;

	for_each_rtdcom(rtd, rtdcom) {
		/* need to sync the delayed work before releasing resources */

		flush_delayed_work(&rtd->delayed_work);
	if (platform->driver->pcm_free)
		platform->driver->pcm_free(pcm);
		component = rtdcom->component;

		if (component->pcm_free)
			component->pcm_free(component, pcm);
	}
}

/* create a new pcm */
@@ -2647,6 +2653,8 @@ 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;
@@ -2756,10 +2764,15 @@ 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;