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

Commit 4c1c16d9 authored by Mark Brown's avatar Mark Brown
Browse files

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

parents 463f7e50 8ea41674
Loading
Loading
Loading
Loading
+42 −2
Original line number Diff line number Diff line
@@ -116,6 +116,14 @@
#define SND_SOC_TPLG_STREAM_PLAYBACK	0
#define SND_SOC_TPLG_STREAM_CAPTURE	1

/* vendor tuple types */
#define SND_SOC_TPLG_TUPLE_TYPE_UUID	0
#define SND_SOC_TPLG_TUPLE_TYPE_STRING	1
#define SND_SOC_TPLG_TUPLE_TYPE_BOOL	2
#define SND_SOC_TPLG_TUPLE_TYPE_BYTE	3
#define SND_SOC_TPLG_TUPLE_TYPE_WORD	4
#define SND_SOC_TPLG_TUPLE_TYPE_SHORT	5

/*
 * Block Header.
 * This header precedes all object and object arrays below.
@@ -132,6 +140,35 @@ struct snd_soc_tplg_hdr {
	__le32 count;		/* number of elements in block */
} __attribute__((packed));

/* vendor tuple for uuid */
struct snd_soc_tplg_vendor_uuid_elem {
	__le32 token;
	char uuid[16];
} __attribute__((packed));

/* vendor tuple for a bool/byte/short/word value */
struct snd_soc_tplg_vendor_value_elem {
	__le32 token;
	__le32 value;
} __attribute__((packed));

/* vendor tuple for string */
struct snd_soc_tplg_vendor_string_elem {
	__le32 token;
	char string[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
} __attribute__((packed));

struct snd_soc_tplg_vendor_array {
	__le32 size;	/* size in bytes of the array, including all elements */
	__le32 type;	/* SND_SOC_TPLG_TUPLE_TYPE_ */
	__le32 num_elems;	/* number of elements in array */
	union {
		struct snd_soc_tplg_vendor_uuid_elem uuid[0];
		struct snd_soc_tplg_vendor_value_elem value[0];
		struct snd_soc_tplg_vendor_string_elem string[0];
	};
} __attribute__((packed));

/*
 * Private data.
 * All topology objects may have private data that can be used by the driver or
@@ -139,7 +176,10 @@ struct snd_soc_tplg_hdr {
 */
struct snd_soc_tplg_private {
	__le32 size;	/* in bytes of private data */
	union {
		char data[0];
		struct snd_soc_tplg_vendor_array array[0];
	};
} __attribute__((packed));

/*
@@ -383,7 +423,7 @@ struct snd_soc_tplg_pcm {
	__le32 size;		/* in bytes of this structure */
	char pcm_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
	char dai_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
	__le32 pcm_id;		/* unique ID - used to match */
	__le32 pcm_id;		/* unique ID - used to match with DAI link */
	__le32 dai_id;		/* unique ID - used to match */
	__le32 playback;	/* supports playback mode */
	__le32 capture;		/* supports capture mode */
+45 −3
Original line number Diff line number Diff line
@@ -1023,6 +1023,11 @@ static int soc_tplg_kcontrol_elems_load(struct soc_tplg *tplg,

		control_hdr = (struct snd_soc_tplg_ctl_hdr *)tplg->pos;

		if (control_hdr->size != sizeof(*control_hdr)) {
			dev_err(tplg->dev, "ASoC: invalid control size\n");
			return -EINVAL;
		}

		switch (control_hdr->ops.info) {
		case SND_SOC_TPLG_CTL_VOLSW:
		case SND_SOC_TPLG_CTL_STROBE:
@@ -1476,6 +1481,8 @@ static int soc_tplg_dapm_widget_create(struct soc_tplg *tplg,
	widget->dobj.type = SND_SOC_DOBJ_WIDGET;
	widget->dobj.ops = tplg->ops;
	widget->dobj.index = tplg->index;
	kfree(template.sname);
	kfree(template.name);
	list_add(&widget->dobj.list, &tplg->comp->dobj_list);
	return 0;

@@ -1499,10 +1506,17 @@ static int soc_tplg_dapm_widget_elems_load(struct soc_tplg *tplg,

	for (i = 0; i < count; i++) {
		widget = (struct snd_soc_tplg_dapm_widget *) tplg->pos;
		if (widget->size != sizeof(*widget)) {
			dev_err(tplg->dev, "ASoC: invalid widget size\n");
			return -EINVAL;
		}

		ret = soc_tplg_dapm_widget_create(tplg, widget);
		if (ret < 0)
		if (ret < 0) {
			dev_err(tplg->dev, "ASoC: failed to load widget %s\n",
				widget->name);
			return ret;
		}
	}

	return 0;
@@ -1586,6 +1600,7 @@ static int soc_tplg_dai_create(struct soc_tplg *tplg,
	return snd_soc_register_dai(tplg->comp, dai_drv);
}

/* create the FE DAI link */
static int soc_tplg_link_create(struct soc_tplg *tplg,
	struct snd_soc_tplg_pcm *pcm)
{
@@ -1598,6 +1613,16 @@ static int soc_tplg_link_create(struct soc_tplg *tplg,

	link->name = pcm->pcm_name;
	link->stream_name = pcm->pcm_name;
	link->id = pcm->pcm_id;

	link->cpu_dai_name = pcm->dai_name;
	link->codec_name = "snd-soc-dummy";
	link->codec_dai_name = "snd-soc-dummy-dai";

	/* enable DPCM */
	link->dynamic = 1;
	link->dpcm_playback = pcm->playback;
	link->dpcm_capture = pcm->capture;

	/* pass control to component driver for optional further init */
	ret = soc_tplg_dai_link_load(tplg, link);
@@ -1639,8 +1664,6 @@ static int soc_tplg_pcm_elems_load(struct soc_tplg *tplg,
	if (tplg->pass != SOC_TPLG_PASS_PCM_DAI)
		return 0;

	pcm = (struct snd_soc_tplg_pcm *)tplg->pos;

	if (soc_tplg_check_elem_count(tplg,
		sizeof(struct snd_soc_tplg_pcm), count,
		hdr->payload_size, "PCM DAI")) {
@@ -1650,7 +1673,13 @@ static int soc_tplg_pcm_elems_load(struct soc_tplg *tplg,
	}

	/* create the FE DAIs and DAI links */
	pcm = (struct snd_soc_tplg_pcm *)tplg->pos;
	for (i = 0; i < count; i++) {
		if (pcm->size != sizeof(*pcm)) {
			dev_err(tplg->dev, "ASoC: invalid pcm size\n");
			return -EINVAL;
		}

		soc_tplg_pcm_create(tplg, pcm);
		pcm++;
	}
@@ -1670,6 +1699,11 @@ static int soc_tplg_manifest_load(struct soc_tplg *tplg,
		return 0;

	manifest = (struct snd_soc_tplg_manifest *)tplg->pos;
	if (manifest->size != sizeof(*manifest)) {
		dev_err(tplg->dev, "ASoC: invalid manifest size\n");
		return -EINVAL;
	}

	tplg->pos += sizeof(struct snd_soc_tplg_manifest);

	if (tplg->comp && tplg->ops && tplg->ops->manifest)
@@ -1686,6 +1720,14 @@ static int soc_valid_header(struct soc_tplg *tplg,
	if (soc_tplg_get_hdr_offset(tplg) >= tplg->fw->size)
		return 0;

	if (hdr->size != sizeof(*hdr)) {
		dev_err(tplg->dev,
			"ASoC: invalid header size for type %d at offset 0x%lx size 0x%zx.\n",
			hdr->type, soc_tplg_get_hdr_offset(tplg),
			tplg->fw->size);
		return -EINVAL;
	}

	/* big endian firmware objects not supported atm */
	if (hdr->magic == cpu_to_be32(SND_SOC_TPLG_MAGIC)) {
		dev_err(tplg->dev,