Skip to contentSkip to conversation

topology: Updates for PCM object in ABI v5

PATCH In review [email protected] 3 participants 11 messages Nov 3, 2016 – Nov 5, 2016 Sound

lore
Share & tools
lore
#0 lore raw

cover topology: Updates for PCM object in ABI v5

From: Mengdong Lin <[email protected]>

These ABI updates for PCM have just been applied to ASoC kernel. And kernel can handle the PCM ABI updates in a backward compatible way.

So we update the user space code for PCM now.

The updates for physical DAI link and DAIs will come later after their kernel updates be applied at first.

Mengdong Lin (6):
topology: ABI - Update stream caps and PCM objects to ABI v5
topology: Parse sig_bits of stream caps
topology: Parse flags for PCM
topology: Define a function to build a single PCM element
topology: Parse and build private data for PCM
topology: tplg_elem_lookup() checks parameter before searching

 include/sound/asoc.h      |   9 ++++
 include/topology.h        |  11 +++++
 src/topology/elem.c       |   3 ++
 src/topology/parser.c     |   2 +-
 src/topology/pcm.c        | 120 ++++++++++++++++++++++++++++++++++++++++++++--
 src/topology/tplg_local.h |   2 +-
 6 files changed, 140 insertions(+), 7 deletions(-)
Signature · 1 line
2.7.4
#1 lore raw

PATCH 1/6 topology: ABI - Update stream caps and PCM objects to ABI v5

From: Mengdong Lin <[email protected]>

Here are the ABI updates for PCM (Front DAI & DAI link) objects:

- add sig_bits to stream caps.
- add flags and private data to PCM.

The kernel can handle the ABI update in a backward compatible way with the patch "ASoC: topology: Make PCM backward compatible from ABI v4".

include/sound/asoc.h +9 -0
index abe49c5..1f2c230 100644
@@ -115,6 +115,11 @@
 #define SND_SOC_TPLG_TUPLE_TYPE_WORD	4
 #define SND_SOC_TPLG_TUPLE_TYPE_SHORT	5
 
+/* DAI link flags */
+#define SND_SOC_TPLG_LNK_FLGBIT_SYMMETRIC_RATES         (1 << 0)
+#define SND_SOC_TPLG_LNK_FLGBIT_SYMMETRIC_CHANNELS      (1 << 1)
+#define SND_SOC_TPLG_LNK_FLGBIT_SYMMETRIC_SAMPLEBITS    (1 << 2)
+
 /*
  * Block Header.
  * This header precedes all object and object arrays below.
@@ -242,6 +247,7 @@ struct snd_soc_tplg_stream_caps {
 	__le32 period_size_max;	/* max period size bytes */
 	__le32 buffer_size_min;	/* min buffer size bytes */
 	__le32 buffer_size_max;	/* max buffer size bytes */
+	__le32 sig_bits;        /* number of bits of content */
 } __attribute__((packed));
 
 /*
@@ -422,6 +428,9 @@ struct snd_soc_tplg_pcm {
 	struct snd_soc_tplg_stream stream[SND_SOC_TPLG_STREAM_CONFIG_MAX]; /* for DAI link */
 	__le32 num_streams;	/* number of streams */
 	struct snd_soc_tplg_stream_caps caps[2]; /* playback and capture for DAI */
+	__le32 flag_mask;       /* bitmask of flags to configure */
+	__le32 flags;           /* SND_SOC_TPLG_LNK_FLGBIT_* flag value */
+	struct snd_soc_tplg_private priv;
 } __attribute__((packed));
 
 
Signature · 1 line
2.7.4
#2 lore raw

PATCH 2/6 topology: Parse sig_bits of stream caps

In reply to [email protected]

From: Mengdong Lin <[email protected]>

Add sig_bits to stream caps template of C API and parse it.

include/topology.h +1 -0
index 0675b52..ccd8401 100644
@@ -848,6 +848,7 @@ struct snd_tplg_stream_caps_template {
 	unsigned int period_size_max;	/*!< max period size bytes */
 	unsigned int buffer_size_min;	/*!< min buffer size bytes */
 	unsigned int buffer_size_max;	/*!< max buffer size bytes */
+	unsigned int sig_bits;		/*!< number of bits of content */
 };
 
 /** \struct snd_tplg_pcm_template
src/topology/pcm.c +1 -0
index 0a90cb9..6fdf047 100644
@@ -572,6 +572,7 @@ static void tplg_add_stream_caps(struct snd_soc_tplg_stream_caps *caps,
 	caps->period_size_max = caps_tpl->period_size_max;
 	caps->buffer_size_min = caps_tpl->buffer_size_min;
 	caps->buffer_size_max = caps_tpl->buffer_size_max;
+	caps->sig_bits = caps_tpl->sig_bits;
 }
 
 int tplg_add_pcm_object(snd_tplg_t *tplg, snd_tplg_obj_template_t *t)
Signature · 1 line
2.7.4
#3 lore raw

PATCH 3/6 topology: Parse flags for PCM

In reply to [email protected]

From: Mengdong Lin <[email protected]>

Users can define flags by both text conf file and C API. Add flags and flag_mask to C API template of PCM object.

include/topology.h +7 -0
index ccd8401..b6a6f19 100644
@@ -606,6 +606,11 @@ extern "C" {
  *			"config3"
  *		]
  *	}
+ *
+ *	# Optional boolean flags
+ *	symmetric_rates			"true"
+ *	symmetric_channels		"true"
+ *	symmetric_sample_bits		"false"
  * }
  * </pre>
  *
@@ -863,6 +868,8 @@ struct snd_tplg_pcm_template {
 	unsigned int capture;	/*!< supports capture mode */
 	unsigned int compress;	/*!< 1 = compressed; 0 = PCM */
 	struct snd_tplg_stream_caps_template *caps[2]; /*!< playback & capture for DAI */
+	unsigned int flag_mask; /*!< bitmask of flags to configure */
+	unsigned int flags;     /*!< flag value SND_SOC_TPLG_LNK_FLGBIT_* */
 	int num_streams;	/*!< number of supported configs */
 	struct snd_tplg_stream_template stream[0]; /*!< supported configs */
 };
src/topology/pcm.c +49 -0

67 lines not on this page · raw message

Signature · 1 line
2.7.4
#6 lore raw

PATCH 4/6 topology: Define a function to build a single PCM element

In reply to [email protected]

From: Mengdong Lin <[email protected]>

Code refactoring. Rename tplg_build_pcm() to tplg_build_pcms() to build all PCM (FE DAI & DAI link) elements. It will call a new function build_pcm() to build a single PCM elemement.

build_pcm() will be extended to handle more properties of a PCM.

src/topology/parser.c +1 -1
index 3ab64f4..7b2c879 100644
@@ -267,7 +267,7 @@ static int tplg_build_integ(snd_tplg_t *tplg)
 	if (err <  0)
 		return err;
 
-	err = tplg_build_pcm(tplg, SND_TPLG_TYPE_PCM);
+	err = tplg_build_pcms(tplg, SND_TPLG_TYPE_PCM);
 	if (err <  0)
 		return err;
 
src/topology/pcm.c +15 -3
index bd70dc9..77b7605 100644
@@ -70,8 +70,20 @@ static int tplg_build_stream_caps(snd_tplg_t *tplg,
 	return 0;
 }
 
-/* build FE DAI/PCM configurations */
-int tplg_build_pcm(snd_tplg_t *tplg, unsigned int type)
+/* build a PCM (FE DAI & DAI link) element */
+static int build_pcm(snd_tplg_t *tplg, struct tplg_elem *elem)
+{
+	int err;
+
+	err = tplg_build_stream_caps(tplg, elem->id, elem->pcm->caps);
+		if (err < 0)
+			return err;
+
+	return 0;
+}
+
+/* build all PCM (FE DAI & DAI link) elements */
+int tplg_build_pcms(snd_tplg_t *tplg, unsigned int type)
 {
 	struct list_head *base, *pos;
 	struct tplg_elem *elem;
@@ -86,7 +98,7 @@ int tplg_build_pcm(snd_tplg_t *tplg, unsigned int type)
 			return -EINVAL;
 		}
 
-		err = tplg_build_stream_caps(tplg, elem->id, elem->pcm->caps);
+		err = build_pcm(tplg, elem);
 		if (err < 0)
 			return err;
 
src/topology/tplg_local.h +1 -1
index cfde4cc..7b30b84 100644
@@ -284,7 +284,7 @@ int tplg_add_enum(snd_tplg_t *tplg, struct snd_tplg_enum_template *enum_ctl,
 int tplg_add_bytes(snd_tplg_t *tplg, struct snd_tplg_bytes_template *bytes_ctl,
 		   struct tplg_elem **e);
 
-int tplg_build_pcm(snd_tplg_t *tplg, unsigned int type);
+int tplg_build_pcms(snd_tplg_t *tplg, unsigned int type);
 int tplg_build_link_cfg(snd_tplg_t *tplg, unsigned int type);
 int tplg_add_link_object(snd_tplg_t *tplg, snd_tplg_obj_template_t *t);
 int tplg_add_pcm_object(snd_tplg_t *tplg, snd_tplg_obj_template_t *t);
Signature · 1 line
2.7.4
#7 lore raw

PATCH 5/6 topology: Parse and build private data for PCM

In reply to [email protected]

From: Mengdong Lin <[email protected]>

Users can define private for PCM (FE DAI & DAI links) elements by both text conf file and C API:

- Text conf file may define multiple data blocks for a PCM and they will be merged in building phase;

- Add private data to C API template of PCM object.

include/topology.h +3 -0
index b6a6f19..481b408 100644
@@ -611,6 +611,8 @@ extern "C" {
  *	symmetric_rates			"true"
  *	symmetric_channels		"true"
  *	symmetric_sample_bits		"false"
+ *
+ *	data "name"			# optional private data
  * }
  * </pre>
  *
@@ -870,6 +872,7 @@ struct snd_tplg_pcm_template {
 	struct snd_tplg_stream_caps_template *caps[2]; /*!< playback & capture for DAI */
 	unsigned int flag_mask; /*!< bitmask of flags to configure */
 	unsigned int flags;     /*!< flag value SND_SOC_TPLG_LNK_FLGBIT_* */
+	struct snd_soc_tplg_private *priv;	/*!< private data */
 	int num_streams;	/*!< number of supported configs */
 	struct snd_tplg_stream_template stream[0]; /*!< supported configs */
 };
src/topology/pcm.c +50 -2

97 lines not on this page · raw message

Signature · 1 line
2.7.4
#8 lore raw

PATCH 6/6 topology: tplg_elem_lookup() checks parameter before searching

In reply to [email protected]

From: Mengdong Lin <[email protected]>

Check the parameters at first in case of misuse.

src/topology/elem.c +3 -0
index 029c9ab..724bf26 100644
@@ -111,6 +111,9 @@ struct tplg_elem *tplg_elem_lookup(struct list_head *base, const char* id,
 	struct list_head *pos;
 	struct tplg_elem *elem;
 
+	if (!base || !id)
+		return NULL;
+
 	list_for_each(pos, base) {
 
 		elem = list_entry(pos, struct tplg_elem, list);
Signature · 1 line
2.7.4
#9 lore raw
In reply to [email protected]

I'm so sorry, please overlook the duplicated cover letters. I sent them out by mistake.

Thanks
Mengdong

Quoted 40 lines

-----Original Message-----
From: [email protected] [mailto:[email protected]]
Sent: Friday, November 4, 2016 7:00 AM
To: [email protected]
Cc: [email protected]; [email protected]; [email protected]; [email protected]; Shah, Hardik T <[email protected]>; Singh, Guneshwor O <[email protected]>; Koul, Vinod <[email protected]>; Lin, Mengdong <[email protected]>; Mengdong Lin <[email protected]>
Subject: [PATCH 0/6] topology: Updates for PCM object in ABI v5

From: Mengdong Lin <[email protected]>

These ABI updates for PCM have just been applied to ASoC kernel. And kernel can handle the PCM ABI updates in a backward compatible way.

So we update the user space code for PCM now.

The updates for physical DAI link and DAIs will come later after their kernel updates be applied at first.

Mengdong Lin (6):
topology: ABI - Update stream caps and PCM objects to ABI v5
topology: Parse sig_bits of stream caps
topology: Parse flags for PCM
topology: Define a function to build a single PCM element
topology: Parse and build private data for PCM
topology: tplg_elem_lookup() checks parameter before searching

 include/sound/asoc.h      |   9 ++++
 include/topology.h        |  11 +++++
 src/topology/elem.c       |   3 ++
 src/topology/parser.c     |   2 +-
 src/topology/pcm.c        | 120
++++++++++++++++++++++++++++++++++++++++++++--
 src/topology/tplg_local.h |   2 +-
 6 files changed, 140 insertions(+), 7 deletions(-)

--
2.7.4

#10 lore raw
In reply to [email protected]
Quoted 11 lines · On Fri, 04 Nov 2016 00:00:19 +0100, [email protected] wrote:

From: Mengdong Lin <[email protected]>

These ABI updates for PCM have just been applied to ASoC kernel. And kernel can handle the PCM ABI updates in a backward compatible way.

So we update the user space code for PCM now.

The updates for physical DAI link and DAIs will come later after their kernel updates be applied at first.

Quoted 7 lines

Mengdong Lin (6):
topology: ABI - Update stream caps and PCM objects to ABI v5
topology: Parse sig_bits of stream caps
topology: Parse flags for PCM
topology: Define a function to build a single PCM element
topology: Parse and build private data for PCM
topology: tplg_elem_lookup() checks parameter before searching

Applied all patches now.
There was a minor issue, but we can address it later.

thanks,

Takashi

#4 lore raw

Re: [PATCH 3/6] topology: Parse flags for PCM

In reply to [email protected]
Quoted 45 lines · On Fri, 04 Nov 2016 00:07:06 +0100, [email protected] wrote:

From: Mengdong Lin <[email protected]>

Users can define flags by both text conf file and C API. Add flags and flag_mask to C API template of PCM object.

include/topology.h +7 -0
index ccd8401..b6a6f19 100644
@@ -606,6 +606,11 @@ extern "C" {
  *			"config3"
  *		]
  *	}
+ *
+ *	# Optional boolean flags
+ *	symmetric_rates			"true"
+ *	symmetric_channels		"true"
+ *	symmetric_sample_bits		"false"
  * }
  * </pre>
  *
@@ -863,6 +868,8 @@ struct snd_tplg_pcm_template {
 	unsigned int capture;	/*!< supports capture mode */
 	unsigned int compress;	/*!< 1 = compressed; 0 = PCM */
 	struct snd_tplg_stream_caps_template *caps[2]; /*!< playback & capture for DAI */
+	unsigned int flag_mask; /*!< bitmask of flags to configure */
+	unsigned int flags;     /*!< flag value SND_SOC_TPLG_LNK_FLGBIT_* */
 	int num_streams;	/*!< number of supported configs */
 	struct snd_tplg_stream_template stream[0]; /*!< supported configs */
 };
src/topology/pcm.c +4 -0
index 6fdf047..bd70dc9 100644
@@ -364,6 +364,24 @@ static int tplg_parse_fe_dai(snd_tplg_t *tplg ATTRIBUTE_UNUSED,
 	return 0;
 }
 
+/* parse a flag bit of the given mask */
+static int parse_flag(snd_config_t *n, unsigned int mask_in,
+		      unsigned int *mask, unsigned int *flags)
+{

src/topology/pcm.c static int tplg_parse_fe_dai(snd_tplg_t *tplg ATTRIBUTE_UNUSED, · line 380

Quoted 10 lines
src/topology/pcm.c +10 -0
+	const char *val = NULL;
+
+	if (snd_config_get_string(n, &val) < 0)
+		return -EINVAL;
+
+	*mask |= mask_in;
+	if (strcmp(val, "true") == 0)
+		*flags |= mask_in;
+	else
+		*flags &= ~mask_in;

This can be simplified with snd_config_get_bool().

thanks,

Takashi

Quoted 55 lines
src/topology/pcm.c +35 -0
+
+	return 0;
+}
+
 /* Parse pcm (for front end DAI & DAI link) */
 int tplg_parse_pcm(snd_tplg_t *tplg,
 	snd_config_t *cfg, void *private ATTRIBUTE_UNUSED)
@@ -430,6 +448,34 @@ int tplg_parse_pcm(snd_tplg_t *tplg,
 				return err;
 			continue;
 		}
+
+		/* flags */
+		if (strcmp(id, "symmetric_rates") == 0) {
+			err = parse_flag(n,
+				SND_SOC_TPLG_LNK_FLGBIT_SYMMETRIC_RATES,
+				&pcm->flag_mask, &pcm->flags);
+			if (err < 0)
+				return err;
+			continue;
+		}
+
+		if (strcmp(id, "symmetric_channels") == 0) {
+			err = parse_flag(n,
+				SND_SOC_TPLG_LNK_FLGBIT_SYMMETRIC_CHANNELS,
+				&pcm->flag_mask, &pcm->flags);
+			if (err < 0)
+				return err;
+			continue;
+		}
+
+		if (strcmp(id, "symmetric_sample_bits") == 0) {
+			err = parse_flag(n,
+				SND_SOC_TPLG_LNK_FLGBIT_SYMMETRIC_SAMPLEBITS,
+				&pcm->flag_mask, &pcm->flags);
+			if (err < 0)
+				return err;
+			continue;
+		}
 	}
 
 	return 0;
@@ -610,6 +656,9 @@ int tplg_add_pcm_object(snd_tplg_t *tplg, snd_tplg_obj_template_t *t)
 			tplg_add_stream_caps(&pcm->caps[i], pcm_tpl->caps[i]);
 	}
 
+	pcm->flag_mask = pcm_tpl->flag_mask;
+	pcm->flags = pcm_tpl->flags;
+
 	pcm->num_streams = pcm_tpl->num_streams;
 	for (i = 0; i < pcm_tpl->num_streams; i++)
 		tplg_add_stream_object(&pcm->stream[i], &pcm_tpl->stream[i]);
Signature · 1 line
2.7.4
#5 lore raw

Re: [PATCH 3/6] topology: Parse flags for PCM

Quoted 4 lines

-----Original Message-----
From: Takashi Iwai [mailto:[email protected]]
Sent: Saturday, November 5, 2016 11:46 PM

Quoted 1 line
Quoted 15 lines

src/topology/pcm.c static int tplg_parse_fe_dai(snd_tplg_t *tplg ATTRIBUTE_UNUSED, · line 380

Quoted 13 lines
src/topology/pcm.c +13 -0
+/* parse a flag bit of the given mask */ static int
+parse_flag(snd_config_t *n, unsigned int mask_in,
+		      unsigned int *mask, unsigned int *flags) {
+	const char *val = NULL;
+
+	if (snd_config_get_string(n, &val) < 0)
+		return -EINVAL;
+
+	*mask |= mask_in;
+	if (strcmp(val, "true") == 0)
+		*flags |= mask_in;
+	else
+		*flags &= ~mask_in;

This can be simplified with snd_config_get_bool().

Okay, I'll fix it in my later patches. Thank you so much for the review!

There will be ~15 patches left for topology user space. I'll split into 2 series.

Regards
Mengdong

Quoted 68 lines

thanks,

Takashi

Quoted 7 lines
src/topology/pcm.c +4 -0
+
+	return 0;
+}
+
 /* Parse pcm (for front end DAI & DAI link) */  int

tplg_parse_pcm(snd_tplg_t *tplg,
snd_config_t *cfg, void *private ATTRIBUTE_UNUSED) @@ -430,6

+448,34

src/topology/pcm.c int tplg_parse_pcm(snd_tplg_t *tplg, · line 461

Quoted 9 lines

@@ int tplg_parse_pcm(snd_tplg_t *tplg,

src/topology/pcm.c +5 -0
 				return err;
 			continue;
 		}
+
+		/* flags */
+		if (strcmp(id, "symmetric_rates") == 0) {
+			err = parse_flag(n,
+

SND_SOC_TPLG_LNK_FLGBIT_SYMMETRIC_RATES,

src/topology/pcm.c int tplg_parse_pcm(snd_tplg_t *tplg, · line 470

Quoted 9 lines
src/topology/pcm.c +9 -0
+				&pcm->flag_mask, &pcm->flags);
+			if (err < 0)
+				return err;
+			continue;
+		}
+
+		if (strcmp(id, "symmetric_channels") == 0) {
+			err = parse_flag(n,
+

SND_SOC_TPLG_LNK_FLGBIT_SYMMETRIC_CHANNELS,

src/topology/pcm.c int tplg_parse_pcm(snd_tplg_t *tplg,

Quoted 9 lines
src/topology/pcm.c +9 -0
+				&pcm->flag_mask, &pcm->flags);
+			if (err < 0)
+				return err;
+			continue;
+		}
+
+		if (strcmp(id, "symmetric_sample_bits") == 0) {
+			err = parse_flag(n,
+

SND_SOC_TPLG_LNK_FLGBIT_SYMMETRIC_SAMPLEBITS,

src/topology/pcm.c int tplg_add_pcm_object(snd_tplg_t *tplg,

Quoted 9 lines
src/topology/pcm.c +5 -0
+				&pcm->flag_mask, &pcm->flags);
+			if (err < 0)
+				return err;
+			continue;
+		}
 	}
 
 	return 0;
@@ -610,6 +656,9 @@ int tplg_add_pcm_object(snd_tplg_t *tplg,

snd_tplg_obj_template_t *t)

Quoted 14 lines
src/topology/pcm.c +3 -0
 			tplg_add_stream_caps(&pcm->caps[i], pcm_tpl-
 caps[i]);
 	}
 
+	pcm->flag_mask = pcm_tpl->flag_mask;
+	pcm->flags = pcm_tpl->flags;
+
 	pcm->num_streams = pcm_tpl->num_streams;
 	for (i = 0; i < pcm_tpl->num_streams; i++)

tplg_add_stream_object(&pcm->stream[i], &pcm_tpl-
stream[i]);
--
2.7.4