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

Commit 566d4eef authored by Mark Brown's avatar Mark Brown
Browse files

Merge remote-tracking branch 'asoc/topic/dt' into asoc-next

parents 8e8fbd8f 6b0a0b3b
Loading
Loading
Loading
Loading
+12 −1
Original line number Original line Diff line number Diff line
@@ -931,7 +931,12 @@ struct snd_soc_dai_link {
};
};


struct snd_soc_codec_conf {
struct snd_soc_codec_conf {
	/*
	 * specify device either by device name, or by
	 * DT/OF node, but not both.
	 */
	const char *dev_name;
	const char *dev_name;
	const struct device_node *of_node;


	/*
	/*
	 * optional map of kcontrol, widget and path name prefixes that are
	 * optional map of kcontrol, widget and path name prefixes that are
@@ -942,7 +947,13 @@ struct snd_soc_codec_conf {


struct snd_soc_aux_dev {
struct snd_soc_aux_dev {
	const char *name;		/* Codec name */
	const char *name;		/* Codec name */
	const char *codec_name;		/* for multi-codec */

	/*
	 * specify multi-codec either by device name, or by
	 * DT/OF node, but not both.
	 */
	const char *codec_name;
	const struct device_node *codec_of_node;


	/* codec/machine specific init - e.g. add machine controls */
	/* codec/machine specific init - e.g. add machine controls */
	int (*init)(struct snd_soc_dapm_context *dapm);
	int (*init)(struct snd_soc_dapm_context *dapm);
+43 −26
Original line number Original line Diff line number Diff line
@@ -1117,12 +1117,14 @@ static void soc_set_name_prefix(struct snd_soc_card *card,


	for (i = 0; i < card->num_configs; i++) {
	for (i = 0; i < card->num_configs; i++) {
		struct snd_soc_codec_conf *map = &card->codec_conf[i];
		struct snd_soc_codec_conf *map = &card->codec_conf[i];
		if (map->dev_name && !strcmp(codec->name, map->dev_name)) {
		if (map->of_node && codec->dev->of_node != map->of_node)
			continue;
		if (map->dev_name && strcmp(codec->name, map->dev_name))
			continue;
		codec->name_prefix = map->name_prefix;
		codec->name_prefix = map->name_prefix;
		break;
		break;
	}
	}
}
}
}


static int soc_probe_codec(struct snd_soc_card *card,
static int soc_probe_codec(struct snd_soc_card *card,
			   struct snd_soc_codec *codec)
			   struct snd_soc_codec *codec)
@@ -1596,52 +1598,67 @@ static void soc_unregister_ac97_dai_link(struct snd_soc_pcm_runtime *rtd)
}
}
#endif
#endif


static int soc_check_aux_dev(struct snd_soc_card *card, int num)
static struct snd_soc_codec *soc_find_matching_codec(struct snd_soc_card *card,
	int num)
{
{
	struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num];
	struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num];
	struct snd_soc_codec *codec;
	struct snd_soc_codec *codec;


	/* find CODEC from registered CODECs */
	/* find CODEC from registered CODECs */
	list_for_each_entry(codec, &codec_list, list) {
	list_for_each_entry(codec, &codec_list, list) {
		if (!strcmp(codec->name, aux_dev->codec_name))
		if (aux_dev->codec_of_node &&
			return 0;
		   (codec->dev->of_node != aux_dev->codec_of_node))
			continue;
		if (aux_dev->codec_name && strcmp(codec->name, aux_dev->codec_name))
			continue;
		return codec;
	}
	}


	dev_err(card->dev, "ASoC: %s not registered\n", aux_dev->codec_name);
	return NULL;
}

static int soc_check_aux_dev(struct snd_soc_card *card, int num)
{
	struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num];
	const char *codecname = aux_dev->codec_name;
	struct snd_soc_codec *codec = soc_find_matching_codec(card, num);

	if (codec)
		return 0;
	if (aux_dev->codec_of_node)
		codecname = of_node_full_name(aux_dev->codec_of_node);


	dev_err(card->dev, "ASoC: %s not registered\n", codecname);
	return -EPROBE_DEFER;
	return -EPROBE_DEFER;
}
}


static int soc_probe_aux_dev(struct snd_soc_card *card, int num)
static int soc_probe_aux_dev(struct snd_soc_card *card, int num)
{
{
	struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num];
	struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num];
	struct snd_soc_codec *codec;
	const char *codecname = aux_dev->codec_name;
	int ret = -ENODEV;
	int ret = -ENODEV;
	struct snd_soc_codec *codec = soc_find_matching_codec(card, num);

	if (!codec) {
		if (aux_dev->codec_of_node)
			codecname = of_node_full_name(aux_dev->codec_of_node);


	/* find CODEC from registered CODECs*/
	list_for_each_entry(codec, &codec_list, list) {
		if (!strcmp(codec->name, aux_dev->codec_name)) {
			if (codec->probed) {
				dev_err(codec->dev,
					"ASoC: codec already probed");
				ret = -EBUSY;
				goto out;
			}
			goto found;
		}
	}
		/* codec not found */
		/* codec not found */
	dev_err(card->dev, "ASoC: codec %s not found", aux_dev->codec_name);
		dev_err(card->dev, "ASoC: codec %s not found", codecname);
		return -EPROBE_DEFER;
		return -EPROBE_DEFER;
	}

	if (codec->probed) {
		dev_err(codec->dev, "ASoC: codec already probed");
		return -EBUSY;
	}


found:
	ret = soc_probe_codec(card, codec);
	ret = soc_probe_codec(card, codec);
	if (ret < 0)
	if (ret < 0)
		return ret;
		return ret;


	ret = soc_post_component_init(card, codec, num, 1);
	ret = soc_post_component_init(card, codec, num, 1);


out:
	return ret;
	return ret;
}
}