[alsa-devel] [RFC 3/5] ASoC multi-component support : core

Lars-Peter Clausen lars at metafoo.de
Sun Jun 27 21:25:49 CEST 2010


Hi

Liam Girdwood wrote:
> This patch adds multi-component support to the ASoC core and
> reflects the new ASoC driver/device structure model defined in soc.h
> and soc-dai.h. i.e.
> 
>  struct snd_soc_codec    --->  struct snd_soc_codec (device data)
>                           +->  struct snd_soc_codec_driver (driver data)
> 
>  struct snd_soc_platform --->  struct snd_soc_platform (device data)
>                           +->  struct snd_soc_platform_driver (driver data)
> 
>  struct snd_soc_dai      --->  struct snd_soc_dai (device data)
>                           +->  struct snd_soc_dai_driver (driver data)
> 
>  struct snd_soc_device   --->  deleted
> 
> Other notable multi-component changes:-
> 
>  * Stream operations now de-reference less structures.
>  * close_delayed work() now runs on a DAI basis rather than looping all DAIs
>    in a card.
>  * PM suspend()/resume() operations can now handle N CODECs and Platforms
>    per sound card.
>  * Added soc_bind_dai_link() to bind the component devices to the sound card.
>  * Added soc_dai_link_probe() and soc_dai_link_remove() to probe and remove
>    DAI link components.
>  * sysfs entries can now be registered per component per card.
>  * snd_soc_new_pcms() functionailty rolled into dai_link_probe().
>  * snd_soc_register_codec() now does all the codec list and mutex init.
> 
> Signed-off-by: Liam Girdwood <lrg at slimlogic.co.uk>
> ---
>  sound/soc/soc-core.c | 1595 +++++++++++++++++++++++++++++---------------------
>  1 files changed, 914 insertions(+), 681 deletions(-)
> 
> diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
> index 3deb226..280c2f0 100644
> --- a/sound/soc/soc-core.c
> +++ b/sound/soc/soc-core.c
> [...]
> +static int soc_probe_dai_link(struct snd_soc_card *card, int num)
> +{
> [...]
> +	/* probe the CODEC */
> +	if (!codec->probed) {
> +		if (codec->driver->probe) {
> +			ret = codec->driver->probe(codec);
> +			if (ret < 0)
> +				return ret;
> +		}
> +		/* Make sure all DAPM widgets are instantiated */
> +		snd_soc_dapm_new_widgets(codec);
> +
> +		/* mark codec as probed and add to card codec list */
> +		codec->probed = 1;
> +		list_add(&codec->card_list, &card->codec_dev_list);
> +
> +		/* add DAPM sysfs entries for this codec */
> +		ret = snd_soc_dapm_sys_add(codec->dev);
>  		if (ret < 0)
> -			goto cpu_dai_err;
> -	}
> -	codec = card->codec;
> +			printk(KERN_WARNING "asoc: failed to add codec dapm sysfs entries\n");
>  
> -	if (platform->probe) {
> -		ret = platform->probe(pdev);
> +		/* add codec sysfs entries */
> +		ret = device_create_file(codec->dev, &dev_attr_codec_reg);
>  		if (ret < 0)
> -			goto platform_err;
> +			printk(KERN_WARNING "asoc: failed to add codec sysfs files\n");
> +
> +		soc_init_codec_debugfs(codec);
>  	}
>  
> -	/* DAPM stream work */
> -	INIT_DELAYED_WORK(&card->delayed_work, close_delayed_work);
> -#ifdef CONFIG_PM
> -	/* deferred resume work */
> -	INIT_WORK(&card->deferred_resume_work, soc_resume_deferred);
> -#endif
> +	/* probe the platform */
> +	if (!platform->probed) {
> +		if (platform->driver->probe) {
> +			ret = platform->driver->probe(platform);
> +			if (ret < 0)
> +				return ret;
> +		}
> +		/* mark platform as probed and add to card platform list */
> +		platform->probed = 1;
> +		list_add(&platform->card_list, &card->platform_dev_list);
> +	}
>  
> -	for (i = 0; i < card->num_links; i++) {
> -		if (card->dai_link[i].init) {
> -			ret = card->dai_link[i].init(codec);
> -			if (ret < 0) {
> -				printk(KERN_ERR "asoc: failed to init %s\n",
> -					card->dai_link[i].stream_name);
> -				continue;
> -			}
> +	/* probe the CODEC DAI */
> +	if (!codec_dai->probed) {
> +		if (codec_dai->driver->probe) {
> +			ret = codec_dai->driver->probe(codec_dai);
> +			if (ret < 0)
> +				return ret;
>  		}
> -		if (card->dai_link[i].codec_dai->ac97_control)
> -			ac97 = 1;
> +
> +		/* mark cpu_dai as probed and add to card cpu_dai list */
> +		codec_dai->probed = 1;
> +		list_add(&codec_dai->card_list, &card->dai_dev_list);
>  	}
>  
> -	snprintf(codec->card->shortname, sizeof(codec->card->shortname),
> -		 "%s",  card->name);
> -	snprintf(codec->card->longname, sizeof(codec->card->longname),
> -		 "%s (%s)", card->name, codec->name);
> +	/* DAPM dai link stream work */
> +	INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work);
>  
> -	/* Make sure all DAPM widgets are instantiated */
> -	snd_soc_dapm_new_widgets(codec);
> +	/* now that all clients have probed, initialise the DAI link */
> +	if (dai_link->init) {
> +		ret = dai_link->init(rtd);
> +		if (ret < 0) {
> +			printk(KERN_ERR "asoc: failed to init %s\n", dai_link->stream_name);
> +			return ret;
> +		}
> +	}
>  
> [...]

Boards usually add board specific widgets and routes in their dai_link init callback.
In the multi-component branch those widgets don't have a debugfs entry nor are they
properly initialized. Thats because snd_soc_dapm_new_widgets used to get called after
the dai_link init callback had been called, now it is before.

- Lars


More information about the Alsa-devel mailing list