参照元

説明

引数

返り値

参考

実装

static void snd_soc_instantiate_card(struct snd_soc_card *card)
{
	struct platform_device *pdev = container_of(card->dev,
						    struct platform_device,
						    dev);
	struct snd_soc_codec_device *codec_dev = card->socdev->codec_dev;
	struct snd_soc_codec *codec;
	struct snd_soc_platform *platform;
	struct snd_soc_dai *dai;
	int i, found, ret, ac97;
	if (card->instantiated)
		return;

	found = 0;
	list_for_each_entry(platform, &platform_list, list)
		if (card->platform == platform) {
			found = 1;
			break;
		}
	if (!found) {
		dev_dbg(card->dev, "Platform %s not registered\n",
			card->platform->name);
		return;
	}
	ac97 = 0;
	for (i = 0; i < card->num_links; i++) {
		found = 0;
		list_for_each_entry(dai, &dai_list, list)
			if (card->dai_link[i].cpu_dai == dai) {
				found = 1;
				break;
			}
		if (!found) {
			dev_dbg(card->dev, "DAI %s not registered\n",
				card->dai_link[i].cpu_dai->name);
			return;
		}

		if (card->dai_link[i].cpu_dai->ac97_control)
			ac97 = 1;
	}
	for (i = 0; i < card->num_links; i++) {
		if (!card->dai_link[i].codec_dai->ops)
			card->dai_link[i].codec_dai->ops = &null_dai_ops;
	}

	/* If we have AC97 in the system then don't wait for the
	 * codec.  This will need revisiting if we have to handle
	 * systems with mixed AC97 and non-AC97 parts.  Only check for
	 * DAIs currently; we can't do this per link since some AC97
	 * codecs have non-AC97 DAIs.
	 */
	if (!ac97)
		for (i = 0; i < card->num_links; i++) {
			found = 0;
			list_for_each_entry(dai, &dai_list, list)
				if (card->dai_link[i].codec_dai == dai) {
					found = 1;
					break;
				}
			if (!found) {
				dev_dbg(card->dev, "DAI %s not registered\n",
					card->dai_link[i].codec_dai->name);
				return;
			}
		}

	/* Note that we do not current check for codec components */

	dev_dbg(card->dev, "All components present, instantiating\n");

	/* Found everything, bring it up */
	if (card->probe) {
		ret = card->probe(pdev);
		if (ret < 0)
			return;
	}

	for (i = 0; i < card->num_links; i++) {
		struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai;
		if (cpu_dai->probe) {
			ret = cpu_dai->probe(pdev, cpu_dai);
			if (ret < 0)
				goto cpu_dai_err;
		}
	}

	if (codec_dev->probe) {
		ret = codec_dev->probe(pdev);
		if (ret < 0)
			goto cpu_dai_err;
	}
	codec = card->codec;

	if (platform->probe) {
		ret = platform->probe(pdev);
		if (ret < 0)
			goto platform_err;
	}

	/* 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
	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;
			}
		}
		if (card->dai_link[i].codec_dai->ac97_control)
			ac97 = 1;
	}
	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);
	/* Make sure all DAPM widgets are instantiated */
	snd_soc_dapm_new_widgets(codec);
	ret = snd_card_register(codec->card);
	if (ret < 0) {
		printk(KERN_ERR "asoc: failed to register soundcard for %s\n",
				codec->name);
		goto card_err;
	}
	mutex_lock(&codec->mutex);
#ifdef CONFIG_SND_SOC_AC97_BUS
	/* Only instantiate AC97 if not already done by the adaptor
	 * for the generic AC97 subsystem.
	 */
	if (ac97 && strcmp(codec->name, "AC97") != 0) {
		ret = soc_ac97_dev_register(codec);
		if (ret < 0) {
			printk(KERN_ERR "asoc: AC97 device register failed\n");
			snd_card_free(codec->card);
			mutex_unlock(&codec->mutex);
			goto card_err;
		}
	}
#endif

	ret = snd_soc_dapm_sys_add(card->socdev->dev);
	if (ret < 0)
		printk(KERN_WARNING "asoc: failed to add dapm sysfs entries\n");
	ret = device_create_file(card->socdev->dev, &dev_attr_codec_reg);
	if (ret < 0)
		printk(KERN_WARNING "asoc: failed to add codec sysfs files\n");
	soc_init_codec_debugfs(codec);
	mutex_unlock(&codec->mutex);
	card->instantiated = 1;

	return;

card_err:
	if (platform->remove)
		platform->remove(pdev);

platform_err:
	if (codec_dev->remove)
		codec_dev->remove(pdev);

cpu_dai_err:
	for (i--; i >= 0; i--) {
		struct snd_soc_dai *cpu_dai = card->dai_link[i].cpu_dai;
		if (cpu_dai->remove)
			cpu_dai->remove(pdev, cpu_dai);
	}

	if (card->remove)
		card->remove(pdev);
}

コメント


トップ   編集 凍結 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2014-09-13 (土) 08:26:43