参照元

説明

引数

返り値

参考

実装

static int snd_soc_instantiate_card(struct snd_soc_card *card)
{
        struct snd_soc_codec *codec;
        int ret, i, order;
        mutex_lock(&client_mutex);
        mutex_lock_nested(&card->mutex, SND_SOC_CARD_CLASS_INIT);
        /* bind DAIs */
        for (i = 0; i < card->num_links; i++) {
                ret = soc_bind_dai_link(card, i);
                if (ret != 0)
                        goto base_error;
        }
        /* bind aux_devs too */
        for (i = 0; i < card->num_aux_devs; i++) {
                ret = soc_bind_aux_dev(card, i);
                if (ret != 0)
                        goto base_error;
        }
        /* initialize the register cache for each available codec */
        list_for_each_entry(codec, &codec_list, list) {
                if (codec->cache_init)
                        continue;
                ret = snd_soc_init_codec_cache(codec);
                if (ret < 0)
                        goto base_error;
        }
        /* card bind complete so register a sound card */
        ret = snd_card_new(card->dev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
                        card->owner, 0, &card->snd_card);
        if (ret < 0) {
                dev_err(card->dev,
                        "ASoC: can't create sound card for card %s: %d\n",
                        card->name, ret);
                goto base_error;
        }
        soc_init_card_debugfs(card);
        card->dapm.bias_level = SND_SOC_BIAS_OFF;
        card->dapm.dev = card->dev;
        card->dapm.card = card;
        list_add(&card->dapm.list, &card->dapm_list);
#ifdef CONFIG_DEBUG_FS
        snd_soc_dapm_debugfs_init(&card->dapm, card->debugfs_card_root);
#endif

#ifdef CONFIG_PM_SLEEP
        /* deferred resume work */
        INIT_WORK(&card->deferred_resume_work, soc_resume_deferred);
#endif

        if (card->dapm_widgets)
                snd_soc_dapm_new_controls(&card->dapm, card->dapm_widgets,
                                          card->num_dapm_widgets);

        if (card->of_dapm_widgets)
                snd_soc_dapm_new_controls(&card->dapm, card->of_dapm_widgets,
                                          card->num_of_dapm_widgets);
        /* initialise the sound card only once */
        if (card->probe) {
                ret = card->probe(card);
                if (ret < 0)
                        goto card_probe_error;
        }

        /* probe all components used by DAI links on this card */
        for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST;
                        order++) {
                for (i = 0; i < card->num_links; i++) {
                        ret = soc_probe_link_components(card, i, order);
                        if (ret < 0) {
                                dev_err(card->dev,
                                        "ASoC: failed to instantiate card %d\n",
                                        ret);
                                goto probe_dai_err;
                        }
                }
        }

        /* probe all DAI links on this card */
        for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST;
                        order++) {
                for (i = 0; i < card->num_links; i++) {
                        ret = soc_probe_link_dais(card, i, order);
                        if (ret < 0) {
                                dev_err(card->dev,
                                        "ASoC: failed to instantiate card %d\n",
                                        ret);
                                goto probe_dai_err;
                        }
                }
        }

        for (i = 0; i < card->num_aux_devs; i++) {
                ret = soc_probe_aux_dev(card, i);
                if (ret < 0) {
                        dev_err(card->dev,
                                "ASoC: failed to add auxiliary devices %d\n",
                                ret);
                        goto probe_aux_dev_err;
                }
        }

        snd_soc_dapm_link_dai_widgets(card);
        snd_soc_dapm_connect_dai_link_widgets(card);
        if (card->controls)
                snd_soc_add_card_controls(card, card->controls, card->num_controls);
        if (card->dapm_routes)
                snd_soc_dapm_add_routes(&card->dapm, card->dapm_routes,
                                        card->num_dapm_routes);

        if (card->of_dapm_routes)
                snd_soc_dapm_add_routes(&card->dapm, card->of_dapm_routes,
                                        card->num_of_dapm_routes);
        snprintf(card->snd_card->shortname, sizeof(card->snd_card->shortname),
                 "%s", card->name);
        snprintf(card->snd_card->longname, sizeof(card->snd_card->longname),
                 "%s", card->long_name ? card->long_name : card->name);
        snprintf(card->snd_card->driver, sizeof(card->snd_card->driver),
                 "%s", card->driver_name ? card->driver_name : card->name);
        for (i = 0; i < ARRAY_SIZE(card->snd_card->driver); i++) {
                switch (card->snd_card->driver[i]) {
                case '_':
                case '-':
                case '\0':
                        break;
                default:
                        if (!isalnum(card->snd_card->driver[i]))
                                card->snd_card->driver[i] = '_';
                        break;
                }
        }
        if (card->late_probe) {
                ret = card->late_probe(card);
                if (ret < 0) {
                        dev_err(card->dev, "ASoC: %s late_probe() failed: %d\n",
                                card->name, ret);
                        goto probe_aux_dev_err;
                }
        }

        snd_soc_dapm_new_widgets(card);
        ret = snd_card_register(card->snd_card);
        if (ret < 0) {
                dev_err(card->dev, "ASoC: failed to register soundcard %d\n",
                                ret);
                goto probe_aux_dev_err;
        }
        card->instantiated = 1;
        snd_soc_dapm_sync(&card->dapm);
        mutex_unlock(&card->mutex);
        mutex_unlock(&client_mutex);
        return 0;

probe_aux_dev_err:
        for (i = 0; i < card->num_aux_devs; i++)
                soc_remove_aux_dev(card, i);
probe_dai_err:
        soc_remove_dai_links(card);
card_probe_error:
        if (card->remove)
                card->remove(card);

        snd_soc_dapm_free(&card->dapm);
        soc_cleanup_card_debugfs(card);
        snd_card_free(card->snd_card);
base_error:
        mutex_unlock(&card->mutex);
        mutex_unlock(&client_mutex);

        return ret;
}

コメント


トップ   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS