参照元

説明

引数

返り値

参考

実装

static int snd_soc_dapm_add_path(struct snd_soc_dapm_context *dapm,
	struct snd_soc_dapm_widget *wsource, struct snd_soc_dapm_widget *wsink,
	const char *control,
	int (*connected)(struct snd_soc_dapm_widget *source,
			 struct snd_soc_dapm_widget *sink))
{
	struct snd_soc_dapm_widget *widgets[2];
	enum snd_soc_dapm_direction dir;
	struct snd_soc_dapm_path *path;
	int ret;
	if (wsink->is_supply && !wsource->is_supply) {
		dev_err(dapm->dev,
			"Connecting non-supply widget to supply widget is not supported (%s -> %s)\n",
			wsource->name, wsink->name);
		return -EINVAL;
	}

	if (connected && !wsource->is_supply) {
		dev_err(dapm->dev,
			"connected() callback only supported for supply widgets (%s -> %s)\n",
			wsource->name, wsink->name);
		return -EINVAL;
	}

	if (wsource->is_supply && control) {
		dev_err(dapm->dev,
			"Conditional paths are not supported for supply widgets (%s -> [%s] -> %s)\n",
			wsource->name, control, wsink->name);
		return -EINVAL;
	}
	ret = snd_soc_dapm_check_dynamic_path(dapm, wsource, wsink, control);
	if (ret)
		return ret;
	path = kzalloc(sizeof(struct snd_soc_dapm_path), GFP_KERNEL);
	if (!path)
		return -ENOMEM;
	path->node[SND_SOC_DAPM_DIR_IN] = wsource;
	path->node[SND_SOC_DAPM_DIR_OUT] = wsink;
	widgets[SND_SOC_DAPM_DIR_IN] = wsource;
	widgets[SND_SOC_DAPM_DIR_OUT] = wsink;

	path->connected = connected;
	INIT_LIST_HEAD(&path->list);
	INIT_LIST_HEAD(&path->list_kcontrol);

	if (wsource->is_supply || wsink->is_supply)
		path->is_supply = 1;

	/* connect static paths */
	if (control == NULL) {
		path->connect = 1;
	} else {
		switch (wsource->id) {
		case snd_soc_dapm_demux:
			ret = dapm_connect_mux(dapm, path, control, wsource);
			if (ret)
				goto err;
			break;
		default:
			break;
		}
		switch (wsink->id) {
		case snd_soc_dapm_mux:
			ret = dapm_connect_mux(dapm, path, control, wsink);
			if (ret != 0)
				goto err;
			break;
		case snd_soc_dapm_switch:
		case snd_soc_dapm_mixer:
		case snd_soc_dapm_mixer_named_ctl:
			ret = dapm_connect_mixer(dapm, path, control);
			if (ret != 0)
				goto err;
			break;
		default:
			break;
		}
	}

	list_add(&path->list, &dapm->card->paths);
	snd_soc_dapm_for_each_direction(dir)
		list_add(&path->list_node[dir], &widgets[dir]->edges[dir]);
	snd_soc_dapm_for_each_direction(dir) {
		dapm_update_widget_flags(widgets[dir]);
		dapm_mark_dirty(widgets[dir], "Route added");
	}
	if (dapm->card->instantiated && path->connect)
		dapm_path_invalidate(path);
	return 0;
err:
	kfree(path);
	return ret;
}

コメント


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