[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