mirror of
				git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
				synced 2025-10-31 16:54:21 +00:00 
			
		
		
		
	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 99b04f4c40 ("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@renesas.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
			
			
This commit is contained in:
		
							parent
							
								
									3b1b3a7ba5
								
							
						
					
					
						commit
						f523acebbb
					
				
					 3 changed files with 69 additions and 8 deletions
				
			
		|  | @ -795,6 +795,10 @@ struct snd_soc_component_driver { | ||||||
| 	int (*suspend)(struct snd_soc_component *); | 	int (*suspend)(struct snd_soc_component *); | ||||||
| 	int (*resume)(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 */ | 	/* component wide operations */ | ||||||
| 	int (*set_sysclk)(struct snd_soc_component *component, | 	int (*set_sysclk)(struct snd_soc_component *component, | ||||||
| 			  int clk_id, int source, unsigned int freq, int dir); | 			  int clk_id, int source, unsigned int freq, int dir); | ||||||
|  | @ -872,6 +876,8 @@ struct snd_soc_component { | ||||||
| 	void (*remove)(struct snd_soc_component *); | 	void (*remove)(struct snd_soc_component *); | ||||||
| 	int (*suspend)(struct snd_soc_component *); | 	int (*suspend)(struct snd_soc_component *); | ||||||
| 	int (*resume)(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 (*set_sysclk)(struct snd_soc_component *component, | ||||||
| 			  int clk_id, int source, unsigned int freq, int dir); | 			  int clk_id, int source, unsigned int freq, int dir); | ||||||
|  |  | ||||||
|  | @ -3254,6 +3254,22 @@ static int snd_soc_component_stream_event(struct snd_soc_dapm_context *dapm, | ||||||
| 	return component->driver->stream_event(component, event); | 	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, | static int snd_soc_component_initialize(struct snd_soc_component *component, | ||||||
| 	const struct snd_soc_component_driver *driver, struct device *dev) | 	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_sysclk = component->driver->set_sysclk; | ||||||
| 	component->set_pll = component->driver->set_pll; | 	component->set_pll = component->driver->set_pll; | ||||||
| 	component->set_jack = component->driver->set_jack; | 	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 = snd_soc_component_get_dapm(component); | ||||||
| 	dapm->dev = dev; | 	dapm->dev = dev; | ||||||
|  | @ -3466,6 +3484,26 @@ static void snd_soc_platform_drv_remove(struct snd_soc_component *component) | ||||||
| 	platform->driver->remove(platform); | 	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 |  * snd_soc_add_platform - Add a platform to the ASoC core | ||||||
|  * @dev: The parent device for the platform |  * @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; | 		platform->component.probe = snd_soc_platform_drv_probe; | ||||||
| 	if (platform_drv->remove) | 	if (platform_drv->remove) | ||||||
| 		platform->component.remove = snd_soc_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 | #ifdef CONFIG_DEBUG_FS | ||||||
| 	platform->component.debugfs_prefix = "platform"; | 	platform->component.debugfs_prefix = "platform"; | ||||||
|  |  | ||||||
|  | @ -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) | static void soc_pcm_private_free(struct snd_pcm *pcm) | ||||||
| { | { | ||||||
| 	struct snd_soc_pcm_runtime *rtd = pcm->private_data; | 	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 */ | 		/* need to sync the delayed work before releasing resources */ | ||||||
|  | 
 | ||||||
| 		flush_delayed_work(&rtd->delayed_work); | 		flush_delayed_work(&rtd->delayed_work); | ||||||
| 	if (platform->driver->pcm_free) | 		component = rtdcom->component; | ||||||
| 		platform->driver->pcm_free(pcm); | 
 | ||||||
|  | 		if (component->pcm_free) | ||||||
|  | 			component->pcm_free(component, pcm); | ||||||
|  | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* create a new 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_platform *platform = rtd->platform; | ||||||
| 	struct snd_soc_dai *codec_dai; | 	struct snd_soc_dai *codec_dai; | ||||||
| 	struct snd_soc_dai *cpu_dai = rtd->cpu_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; | 	struct snd_pcm *pcm; | ||||||
| 	char new_name[64]; | 	char new_name[64]; | ||||||
| 	int ret = 0, playback = 0, capture = 0; | 	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) | 	if (capture) | ||||||
| 		snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &rtd->ops); | 		snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &rtd->ops); | ||||||
| 
 | 
 | ||||||
| 	if (platform->driver->pcm_new) { | 	for_each_rtdcom(rtd, rtdcom) { | ||||||
| 		ret = platform->driver->pcm_new(rtd); | 		component = rtdcom->component; | ||||||
|  | 
 | ||||||
|  | 		if (!component->pcm_new) | ||||||
|  | 			continue; | ||||||
|  | 
 | ||||||
|  | 		ret = component->pcm_new(component, rtd); | ||||||
| 		if (ret < 0) { | 		if (ret < 0) { | ||||||
| 			dev_err(platform->dev, | 			dev_err(component->dev, | ||||||
| 				"ASoC: pcm constructor failed: %d\n", | 				"ASoC: pcm constructor failed: %d\n", | ||||||
| 				ret); | 				ret); | ||||||
| 			return ret; | 			return ret; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Kuninori Morimoto
						Kuninori Morimoto