Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 93b0f3ee authored by Jean-Francois Moine's avatar Jean-Francois Moine Committed by Mark Brown
Browse files

ASoC: core: add multi-codec support in DT



This patch exports a core function which handles the DT description
of multi-codec links (as: "sound-dai = <&hdmi 0>, <&spdif_codec>;")
and creates a CODEC component array in the DAI link.

Signed-off-by: default avatarJean-Francois Moine <moinejf@free.fr>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent f114040e
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -1451,6 +1451,9 @@ unsigned int snd_soc_of_parse_daifmt(struct device_node *np,
				     struct device_node **framemaster);
int snd_soc_of_get_dai_name(struct device_node *of_node,
			    const char **dai_name);
int snd_soc_of_get_dai_link_codecs(struct device *dev,
				   struct device_node *of_node,
				   struct snd_soc_dai_link *dai_link);

#include <sound/soc-dai.h>

+95 −15
Original line number Diff line number Diff line
@@ -4750,36 +4750,30 @@ unsigned int snd_soc_of_parse_daifmt(struct device_node *np,
}
EXPORT_SYMBOL_GPL(snd_soc_of_parse_daifmt);

int snd_soc_of_get_dai_name(struct device_node *of_node,
static int snd_soc_get_dai_name(struct of_phandle_args *args,
				const char **dai_name)
{
	struct snd_soc_component *pos;
	struct of_phandle_args args;
	int ret;

	ret = of_parse_phandle_with_args(of_node, "sound-dai",
					 "#sound-dai-cells", 0, &args);
	if (ret)
		return ret;

	ret = -EPROBE_DEFER;
	int ret = -EPROBE_DEFER;

	mutex_lock(&client_mutex);
	list_for_each_entry(pos, &component_list, list) {
		if (pos->dev->of_node != args.np)
		if (pos->dev->of_node != args->np)
			continue;

		if (pos->driver->of_xlate_dai_name) {
			ret = pos->driver->of_xlate_dai_name(pos, &args, dai_name);
			ret = pos->driver->of_xlate_dai_name(pos,
							     args,
							     dai_name);
		} else {
			int id = -1;

			switch (args.args_count) {
			switch (args->args_count) {
			case 0:
				id = 0; /* same as dai_drv[0] */
				break;
			case 1:
				id = args.args[0];
				id = args->args[0];
				break;
			default:
				/* not supported */
@@ -4801,6 +4795,21 @@ int snd_soc_of_get_dai_name(struct device_node *of_node,
		break;
	}
	mutex_unlock(&client_mutex);
	return ret;
}

int snd_soc_of_get_dai_name(struct device_node *of_node,
			    const char **dai_name)
{
	struct of_phandle_args args;
	int ret;

	ret = of_parse_phandle_with_args(of_node, "sound-dai",
					 "#sound-dai-cells", 0, &args);
	if (ret)
		return ret;

	ret = snd_soc_get_dai_name(&args, dai_name);

	of_node_put(args.np);

@@ -4808,6 +4817,77 @@ int snd_soc_of_get_dai_name(struct device_node *of_node,
}
EXPORT_SYMBOL_GPL(snd_soc_of_get_dai_name);

/*
 * snd_soc_of_get_dai_link_codecs - Parse a list of CODECs in the devicetree
 * @dev: Card device
 * @of_node: Device node
 * @dai_link: DAI link
 *
 * Builds an array of CODEC DAI components from the DAI link property
 * 'sound-dai'.
 * The array is set in the DAI link and the number of DAIs is set accordingly.
 * The device nodes in the array (of_node) must be dereferenced by the caller.
 *
 * Returns 0 for success
 */
int snd_soc_of_get_dai_link_codecs(struct device *dev,
				   struct device_node *of_node,
				   struct snd_soc_dai_link *dai_link)
{
	struct of_phandle_args args;
	struct snd_soc_dai_link_component *component;
	char *name;
	int index, num_codecs, ret;

	/* Count the number of CODECs */
	name = "sound-dai";
	num_codecs = of_count_phandle_with_args(of_node, name,
						"#sound-dai-cells");
	if (num_codecs <= 0) {
		if (num_codecs == -ENOENT)
			dev_err(dev, "No 'sound-dai' property\n");
		else
			dev_err(dev, "Bad phandle in 'sound-dai'\n");
		return num_codecs;
	}
	component = devm_kzalloc(dev,
				 sizeof *component * num_codecs,
				 GFP_KERNEL);
	if (!component)
		return -ENOMEM;
	dai_link->codecs = component;
	dai_link->num_codecs = num_codecs;

	/* Parse the list */
	for (index = 0, component = dai_link->codecs;
	     index < dai_link->num_codecs;
	     index++, component++) {
		ret = of_parse_phandle_with_args(of_node, name,
						 "#sound-dai-cells",
						  index, &args);
		if (ret)
			goto err;
		component->of_node = args.np;
		ret = snd_soc_get_dai_name(&args, &component->dai_name);
		if (ret < 0)
			goto err;
	}
	return 0;
err:
	for (index = 0, component = dai_link->codecs;
	     index < dai_link->num_codecs;
	     index++, component++) {
		if (!component->of_node)
			break;
		of_node_put(component->of_node);
		component->of_node = NULL;
	}
	dai_link->codecs = NULL;
	dai_link->num_codecs = 0;
	return ret;
}
EXPORT_SYMBOL_GPL(snd_soc_of_get_dai_link_codecs);

static int __init snd_soc_init(void)
{
#ifdef CONFIG_DEBUG_FS