Skip to contentSkip to conversation

ASoC: topology: Remaining kernel patches

PATCH Superseded [email protected] 2 participants 26 messages Aug 19, 2016 – Sep 9, 2016

Subsystems (2)

v1 of 7 Superseded Latest is v7 →

lore
Share & tools
lore
#0 lore raw

cover ASoC: topology: Remaining kernel patches

From: Mengdong Lin <[email protected]>

This series contains all remaining kernel patches of topology, including some ABI update to PCM (FrontEnds) and link (BackEnds) objects. We don't user more series.

User will be able to create BE DAIs and DAI links, configure more for FE links. Code are verified and can cover reqeust of Intel pre-release platforms for next year, so ABI should be stable.

Current kernel topology code does not really touch Codec-Codec links since there is no user requst atm. We can add support for CC links later by reusing code and data structures for BE links, and no need to revise ABI.

Guneshwor Singh (1):
ASoC: topology: Add FE DAIs only if not already added

Mengdong Lin (12):
ASoC: topology: Able to create BE DAIs
ASoC: topology: ABI - Add sig_bits to stream caps
ASoC: topology: ABI - Define DPCM trigger ordering for PCM
ASoC: topology: ABI - Add flags to PCM
ASoC: topology: ABI - Add private data to PCM
ASoC: topology: ABI - Add name & component info to BE/CC links
ASoC: topology: ABI - Define DAI physical PCM data formats
ASoC: topology: ABI - Add HW configurations to BE/CC links
ASoC: topology: ABI - Add flags and private data to BE/CC links
ASoC: Define API to find a dai link by id
ASoC: Probe link components after finding new links
ASoC: topology: Able to create BE DAI links

 include/sound/soc-dai.h      |  15 +-
 include/sound/soc-dpcm.h     |  13 --
 include/sound/soc-topology.h |   1 +
 include/sound/soc.h          |   2 +
 include/uapi/sound/asoc.h    | 106 ++++++++++++-
 sound/soc/soc-core.c         |  36 ++++-
 sound/soc/soc-topology.c     | 359 ++++++++++++++++++++++++++++++++++++++-----
 7 files changed, 466 insertions(+), 66 deletions(-)
Signature · 1 line
2.5.0
#1 lore raw

PATCH 1/13 ASoC: topology: Able to create BE DAIs

From: Mengdong Lin <[email protected]>

Topology will check with ASoC if a BE DAI already exists by checking its name. If the BE DAI doesn't exist, topology will create a new one and the dai_load ops will be called for device specific init.

include/sound/soc-topology.h +1 -0
index d318fe4..9ebb9f2 100644
@@ -39,6 +39,7 @@ enum snd_soc_dobj_type {
 	SND_SOC_DOBJ_ENUM,
 	SND_SOC_DOBJ_BYTES,
 	SND_SOC_DOBJ_PCM,
+	SND_SOC_DOBJ_BE_DAI,
 	SND_SOC_DOBJ_DAI_LINK,
 	SND_SOC_DOBJ_CODEC_LINK,
 	SND_SOC_DOBJ_WIDGET,
sound/soc/soc-core.c +2 -1
index 84e3fa1..f6f5027 100644
@@ -2872,7 +2872,8 @@ int snd_soc_register_dai(struct snd_soc_component *component,
 	struct snd_soc_dai *dai;
 	int ret;
 
-	if (dai_drv->dobj.type != SND_SOC_DOBJ_PCM) {
+	if (!(dai_drv->dobj.type == SND_SOC_DOBJ_PCM ||
+	    dai_drv->dobj.type == SND_SOC_DOBJ_BE_DAI)) {
 		dev_err(component->dev, "Invalid dai type %d\n",
 			dai_drv->dobj.type);
 		return -EINVAL;
sound/soc/soc-topology.c +73 -31

134 lines not on this page · raw message

Signature · 1 line
2.5.0
#7 lore raw

PATCH 2/13 ASoC: topology: ABI - Add sig_bits to stream caps

In reply to [email protected]

From: Mengdong Lin <[email protected]>

Kernel struct snd_soc_pcm_stream, SoC PCM stream information, needs this field. Although current topology users don't configure this, we define it for future extension.

include/uapi/sound/asoc.h +1 -0
index f734bea..33d00a4 100644
@@ -257,6 +257,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));
 
 /*
sound/soc/soc-topology.c +1 -0
index 1e26dc6..b271248 100644
@@ -1556,6 +1556,7 @@ static void set_stream_info(struct snd_soc_pcm_stream *stream,
 	stream->rate_min = caps->rate_min;
 	stream->rate_max = caps->rate_max;
 	stream->formats = caps->formats;
+	stream->sig_bits = caps->sig_bits;
 }
 
 static void set_dai_flags(struct snd_soc_dai_driver *dai_drv,
Signature · 1 line
2.5.0
#9 lore raw

PATCH 3/13 ASoC: topology: ABI - Define DPCM trigger ordering for PCM

In reply to [email protected]

From: Mengdong Lin <[email protected]>

Definition of dynamic PCM trigger ordering is exposed to uapi asoc.h, and topology allows user space to define the trigger ordering for PCM (FE links).

include/sound/soc-dpcm.h +0 -13
index 8060590..428ae95 100644
@@ -52,19 +52,6 @@ enum snd_soc_dpcm_state {
 };
 
 /*
- * Dynamic PCM trigger ordering. Triggering flexibility is required as some
- * DSPs require triggering before/after their CPU platform and DAIs.
- *
- * i.e. some clients may want to manually order this call in their PCM
- * trigger() whilst others will just use the regular core ordering.
- */
-enum snd_soc_dpcm_trigger {
-	SND_SOC_DPCM_TRIGGER_PRE		= 0,
-	SND_SOC_DPCM_TRIGGER_POST,
-	SND_SOC_DPCM_TRIGGER_BESPOKE,
-};
-
-/*
  * Dynamic PCM link
  * This links together a FE and BE DAI at runtime and stores the link
  * state information and the hw_params configuration.
include/uapi/sound/asoc.h +14 -0
index 33d00a4..db0edfb 100644
@@ -131,6 +131,19 @@
 #define SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_SAMPLEBITS    (1 << 2)
 
 /*
+ * Dynamic PCM trigger ordering. Triggering flexibility is required as some
+ * DSPs require triggering before/after their CPU platform and DAIs.
+ *
+ * i.e. some clients may want to manually order this call in their PCM
+ * trigger() whilst others will just use the regular core ordering.
+ */
+enum snd_soc_dpcm_trigger {
+	SND_SOC_DPCM_TRIGGER_PRE		= 0,
+	SND_SOC_DPCM_TRIGGER_POST,
+	SND_SOC_DPCM_TRIGGER_BESPOKE,
+};
+
+/*
  * Block Header.
  * This header precedes all object and object arrays below.
  */
@@ -440,6 +453,7 @@ 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 trigger[2];	/* SND_SOC_DPCM_TRIGGER_ trigger flag for playback & capture */
 } __attribute__((packed));
 
 
sound/soc/soc-topology.c +3 -0
index b271248..6802151 100644
@@ -1645,6 +1645,9 @@ static int soc_tplg_link_create(struct soc_tplg *tplg,
 	link->dpcm_playback = pcm->playback;
 	link->dpcm_capture = pcm->capture;
 
+	link->trigger[0] = pcm->trigger[0];
+	link->trigger[1] = pcm->trigger[1];
+
 	/* pass control to component driver for optional further init */
 	ret = soc_tplg_dai_link_load(tplg, link);
 	if (ret < 0) {
Signature · 1 line
2.5.0
#16 lore raw

PATCH 4/13 ASoC: topology: ABI - Add flags to PCM

In reply to [email protected]

From: Mengdong Lin <[email protected]>

Add flags to PCM. These flags will be applied to FE (Front End) links.

include/uapi/sound/asoc.h +6 -0
index db0edfb..39be708 100644
@@ -130,6 +130,10 @@
 #define SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_CHANNELS      (1 << 1)
 #define SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_SAMPLEBITS    (1 << 2)
 
+/* DAI link flags */
+#define SND_SOC_TPLG_LNK_FLGBIT_IGNORE_SUSPEND          (1 << 0)
+#define SND_SOC_TPLG_LNK_FLGBIT_IGNORE_POWERDOWN_TIME   (1 << 1)
+
 /*
  * Dynamic PCM trigger ordering. Triggering flexibility is required as some
  * DSPs require triggering before/after their CPU platform and DAIs.
@@ -454,6 +458,8 @@ struct snd_soc_tplg_pcm {
 	__le32 num_streams;	/* number of streams */
 	struct snd_soc_tplg_stream_caps caps[2]; /* playback and capture for DAI */
 	__le32 trigger[2];	/* SND_SOC_DPCM_TRIGGER_ trigger flag for playback & capture */
+	__le32 flag_mask;       /* bitmask of flags to configure */
+	__le32 flags;           /* SND_SOC_TPLG_LNK_FLGBIT_* flag value */
 } __attribute__((packed));
 
 
sound/soc/soc-topology.c +14 -0
index 6802151..1f89a2a 100644
@@ -1621,6 +1621,18 @@ static int soc_tplg_dai_create(struct soc_tplg *tplg,
 	return snd_soc_register_dai(tplg->comp, dai_drv);
 }
 
+static void set_link_flags(struct snd_soc_dai_link *link,
+		unsigned int flag_mask, unsigned int flags)
+{
+	if (flag_mask & SND_SOC_TPLG_LNK_FLGBIT_IGNORE_SUSPEND)
+		link->ignore_suspend =
+			flags & SND_SOC_TPLG_LNK_FLGBIT_IGNORE_SUSPEND ? 1 : 0;
+
+	if (flag_mask & SND_SOC_TPLG_LNK_FLGBIT_IGNORE_POWERDOWN_TIME)
+		link->ignore_pmdown_time =
+		flags & SND_SOC_TPLG_LNK_FLGBIT_IGNORE_POWERDOWN_TIME ? 1 : 0;
+}
+
 /* create the FE DAI link */
 static int soc_tplg_link_create(struct soc_tplg *tplg,
 	struct snd_soc_tplg_pcm *pcm)
@@ -1644,6 +1656,8 @@ static int soc_tplg_link_create(struct soc_tplg *tplg,
 	link->dynamic = 1;
 	link->dpcm_playback = pcm->playback;
 	link->dpcm_capture = pcm->capture;
+	if (pcm->flag_mask)
+		set_link_flags(link, pcm->flag_mask, pcm->flags);
 
 	link->trigger[0] = pcm->trigger[0];
 	link->trigger[1] = pcm->trigger[1];
Signature · 1 line
2.5.0
#17 lore raw

PATCH 5/13 ASoC: topology: ABI - Add private data to PCM

In reply to [email protected]

From: Mengdong Lin <[email protected]>

Add private data to PCM (Frontend DAI & DAI link) for future extension. Revise offset update for PCM with private data.

include/uapi/sound/asoc.h +1 -0
index 39be708..c75ed4f 100644
@@ -460,6 +460,7 @@ struct snd_soc_tplg_pcm {
 	__le32 trigger[2];	/* SND_SOC_DPCM_TRIGGER_ trigger flag for playback & capture */
 	__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));
 
 
sound/soc/soc-topology.c +2 -3
index 1f89a2a..b71abad 100644
@@ -1711,19 +1711,18 @@ 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++) {
+		pcm = (struct snd_soc_tplg_pcm *)tplg->pos;
 		if (pcm->size != sizeof(*pcm)) {
 			dev_err(tplg->dev, "ASoC: invalid pcm size\n");
 			return -EINVAL;
 		}
 
 		soc_tplg_pcm_create(tplg, pcm);
-		pcm++;
+		tplg->pos += (sizeof(*pcm) + pcm->priv.size);
 	}
 
 	dev_dbg(tplg->dev, "ASoC: adding %d PCM DAIs\n", count);
-	tplg->pos += sizeof(struct snd_soc_tplg_pcm) * count;
 
 	return 0;
 }
Signature · 1 line
2.5.0
#18 lore raw

PATCH 6/13 ASoC: topology: Add FE DAIs only if not already added

In reply to [email protected]

From: Guneshwor Singh <[email protected]>

Topology will check with ASoC if the FE DAI already exists by checking its name. If not, topology will create a new one.

sound/soc/soc-topology.c +16 -4
index b71abad..6a1a9c2 100644
@@ -1683,13 +1683,25 @@ static int soc_tplg_link_create(struct soc_tplg *tplg,
 static int soc_tplg_pcm_create(struct soc_tplg *tplg,
 	struct snd_soc_tplg_pcm *pcm)
 {
+	struct snd_soc_dai_link_component dai_component = {0};
+	struct snd_soc_dai *dai;
 	int ret;
 
-	ret = soc_tplg_dai_create(tplg, pcm);
-	if (ret < 0)
-		return ret;
+	if (!strlen(pcm->dai_name)) {
+		dev_err(tplg->dev, "ASoC: Invalid FE DAI name %s\n",
+			pcm->dai_name);
+		return -EINVAL;
+	}
+
+	dai_component.dai_name = pcm->dai_name;
+	dai = snd_soc_find_dai(&dai_component);
+	if (!dai) { /* FE DAI doesn't exist, create it */
+		ret = soc_tplg_dai_create(tplg, pcm);
+		if (ret < 0)
+			return ret;
+	}
 
-	return  soc_tplg_link_create(tplg, pcm);
+	return soc_tplg_link_create(tplg, pcm);
 }
 
 static int soc_tplg_pcm_elems_load(struct soc_tplg *tplg,
Signature · 1 line
2.5.0
#19 lore raw

PATCH 7/13 ASoC: topology: ABI - Add name & component info to BE/CC links

In reply to [email protected]

From: Mengdong Lin <[email protected]>

Add link name, stream name, CPU and codec components info, for topology to create new backend or codec-codec links in the future.

include/uapi/sound/asoc.h +20 -1
index c75ed4f..812a70b 100644
@@ -39,6 +39,9 @@
  */
 #define SND_SOC_TPLG_STREAM_CONFIG_MAX  8
 
+/* maximum number of codecs for a BE/CC link */
+#define SND_SOC_TPLG_LINK_CODECS_MAX    4
+
 /* individual kcontrol info types - can be mixed with other types */
 #define SND_SOC_TPLG_CTL_VOLSW		1
 #define SND_SOC_TPLG_CTL_VOLSW_SX	2
@@ -465,6 +468,15 @@ struct snd_soc_tplg_pcm {
 
 
 /*
+ * Component for backend links.
+ */
+struct snd_soc_tplg_link_cmpnt {
+	__le32 size;		/* in bytes of this structure */
+	char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; /* component name, optional */
+	char dai_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
+} __attribute__((packed));
+
+/*
  * Describes the BE or CC link runtime supported configs or params
  *
  * File block representation for BE/CC link config :-
@@ -476,9 +488,16 @@ struct snd_soc_tplg_pcm {
  */
 struct snd_soc_tplg_link_config {
 	__le32 size;            /* in bytes of this structure */
-	__le32 id;              /* unique ID - used to match */
+	__le32 id;              /* unique ID - used to match with DAI link */
 	struct snd_soc_tplg_stream stream[SND_SOC_TPLG_STREAM_CONFIG_MAX]; /* supported configs playback and captrure */
 	__le32 num_streams;     /* number of streams */
+
+	char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];        /* link name */
+	char stream_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; /* stream name */
+
+	struct snd_soc_tplg_link_cmpnt cpu;              /* cpu component */
+	struct snd_soc_tplg_link_cmpnt codecs[SND_SOC_TPLG_LINK_CODECS_MAX]; /* codec components */
+	__le32 num_codecs;      /* number of codecs */
 } __attribute__((packed));
 
 /*
Signature · 1 line
2.5.0
#20 lore raw

PATCH 8/13 ASoC: topology: ABI - Define DAI physical PCM data formats

In reply to [email protected]

From: Mengdong Lin <[email protected]>

Define DAI physical PCM data formats for user space, so users can specify the formats of backends by topology (e.g. the DAI format to set on backend link init).

The kernel will also refer to these formats.

include/sound/soc-dai.h +8 -7
index 964b7de..534aae2 100644
@@ -15,6 +15,7 @@
 
 
 #include <linux/list.h>
+#include <sound/asoc.h>
 
 struct snd_pcm_substream;
 struct snd_soc_dapm_widget;
@@ -26,13 +27,13 @@ struct snd_compr_stream;
  * Describes the physical PCM data formating and clocking. Add new formats
  * to the end.
  */
-#define SND_SOC_DAIFMT_I2S		1 /* I2S mode */
-#define SND_SOC_DAIFMT_RIGHT_J		2 /* Right Justified mode */
-#define SND_SOC_DAIFMT_LEFT_J		3 /* Left Justified mode */
-#define SND_SOC_DAIFMT_DSP_A		4 /* L data MSB after FRM LRC */
-#define SND_SOC_DAIFMT_DSP_B		5 /* L data MSB during FRM LRC */
-#define SND_SOC_DAIFMT_AC97		6 /* AC97 */
-#define SND_SOC_DAIFMT_PDM		7 /* Pulse density modulation */
+#define SND_SOC_DAIFMT_I2S		SND_SOC_DAI_FORMAT_I2S
+#define SND_SOC_DAIFMT_RIGHT_J		SND_SOC_DAI_FORMAT_RIGHT_J
+#define SND_SOC_DAIFMT_LEFT_J		SND_SOC_DAI_FORMAT_LEFT_J
+#define SND_SOC_DAIFMT_DSP_A		SND_SOC_DAI_FORMAT_DSP_A
+#define SND_SOC_DAIFMT_DSP_B		SND_SOC_DAI_FORMAT_DSP_B
+#define SND_SOC_DAIFMT_AC97		SND_SOC_DAI_FORMAT_AC97
+#define SND_SOC_DAIFMT_PDM		SND_SOC_DAI_FORMAT_PDM
 
 /* left and right justified also known as MSB and LSB respectively */
 #define SND_SOC_DAIFMT_MSB		SND_SOC_DAIFMT_LEFT_J
include/uapi/sound/asoc.h +16 -0
index 812a70b..4802410 100644
@@ -138,6 +138,22 @@
 #define SND_SOC_TPLG_LNK_FLGBIT_IGNORE_POWERDOWN_TIME   (1 << 1)
 
 /*
+ * DAI physical PCM data formats.
+ * Add new formats to the end of the list.
+ */
+#define SND_SOC_DAI_FORMAT_I2S          1 /* I2S mode */
+#define SND_SOC_DAI_FORMAT_RIGHT_J      2 /* Right Justified mode */
+#define SND_SOC_DAI_FORMAT_LEFT_J       3 /* Left Justified mode */
+#define SND_SOC_DAI_FORMAT_DSP_A        4 /* L data MSB after FRM LRC */
+#define SND_SOC_DAI_FORMAT_DSP_B        5 /* L data MSB during FRM LRC */
+#define SND_SOC_DAI_FORMAT_AC97         6 /* AC97 */
+#define SND_SOC_DAI_FORMAT_PDM          7 /* Pulse density modulation */
+
+/* left and right justified also known as MSB and LSB respectively */
+#define SND_SOC_DAI_FORMAT_MSB          SND_SOC_DAI_FORMAT_LEFT_J
+#define SND_SOC_DAI_FORMAT_LSB          SND_SOC_DAI_FORMAT_RIGHT_J
+
+/*
  * Dynamic PCM trigger ordering. Triggering flexibility is required as some
  * DSPs require triggering before/after their CPU platform and DAIs.
  *
Signature · 1 line
2.5.0
#21 lore raw

PATCH 9/13 ASoC: topology: ABI - Add HW configurations to BE/CC links

In reply to [email protected]

From: Mengdong Lin <[email protected]>

Define the types and ABI struct for a single Backend or Codec<->Codec link runtime supported hardware config, e.g. audio hardware formats.

The default HW config ID will help topology to find the DAI format to set on init.

Topology provides this as a fallback if such HW settings are not available in ACPI or device tree, to avoid hard code in drivers.

It's only for config items that can be programmed by SW or FW, not for physical things like link connections or GPIO used for HP etc.

include/uapi/sound/asoc.h +38 -0
index 4802410..21ebb97 100644
@@ -42,6 +42,11 @@
 /* maximum number of codecs for a BE/CC link */
 #define SND_SOC_TPLG_LINK_CODECS_MAX    4
 
+/*
+ * Maximum number of BE/CC link HW configs
+ */
+#define SND_SOC_TPLG_HW_CONFIG_MAX	8
+
 /* individual kcontrol info types - can be mixed with other types */
 #define SND_SOC_TPLG_CTL_VOLSW		1
 #define SND_SOC_TPLG_CTL_VOLSW_SX	2
@@ -309,6 +314,35 @@ struct snd_soc_tplg_stream {
 	__le32 channels;	/* channels */
 } __attribute__((packed));
 
+
+/*
+ * Describes a single BE or CC link runtime supported hardware config,
+ * i.e. hardware audio formats.
+ */
+struct snd_soc_tplg_hw_config {
+	__le32 size;            /* in bytes of this structure */
+	__le32 id;		/* unique ID - - used to match */
+	__le32 fmt;		/* SND_SOC_DAI_FORMAT_ format value */
+	__u8 clock_gated;	/* 1 if clock can be gated to save power */
+	__u8 invert_bclk;	/* 1 for inverted BCLK, 0 for normal */
+	__u8 invert_fsync;	/* 1 for inverted frame clock, 0 for normal */
+	__u8 bclk_master;	/* 1 for master of BCLK, 0 for slave */
+	__u8 fsync_master;	/* 1 for master of FSYNC, 0 for slave */
+	__u8 mclk_direction;    /* 0 for input, 1 for output */
+	__le16 reserved;	/* for 32bit alignment */
+	__le32 mclk_rate;	/* MCLK or SYSCLK freqency in Hz */
+	__le32 bclk_rate;	/* BCLK freqency in Hz */
+	__le32 fsync_rate;	/* frame clock in Hz */
+	__le32 tdm_slots;	/* number of TDM slots in use */
+	__le32 tdm_slot_width;	/* width in bits for each slot */
+	__le32 tx_slots;	/* bit mask for active Tx slots */
+	__le32 rx_slots;	/* bit mask for active Rx slots */
+	__le32 tx_channels;	/* number of Tx channels */
+	__le32 tx_chanmap[SND_SOC_TPLG_MAX_CHAN]; /* array of slot number */
+	__le32 rx_channels;	/* number of Rx channels */
+	__le32 rx_chanmap[SND_SOC_TPLG_MAX_CHAN]; /* array of slot number */
+} __attribute__((packed));
+
 /*
  * Manifest. List totals for each payload type. Not used in parsing, but will
  * be passed to the component driver before any other objects in order for any
@@ -514,6 +548,10 @@ struct snd_soc_tplg_link_config {
 	struct snd_soc_tplg_link_cmpnt cpu;              /* cpu component */
 	struct snd_soc_tplg_link_cmpnt codecs[SND_SOC_TPLG_LINK_CODECS_MAX]; /* codec components */
 	__le32 num_codecs;      /* number of codecs */
+
+	struct snd_soc_tplg_hw_config hw_config[SND_SOC_TPLG_HW_CONFIG_MAX]; /* hw configs */
+	__le32 num_hw_configs;         /* number of hw configs */
+	__le32 default_hw_config_id;   /* default hw config ID for init */
 } __attribute__((packed));
 
 /*
Signature · 1 line
2.5.0
#22 lore raw

PATCH 10/13 ASoC: topology: ABI - Add flags and private data to BE/CC links

In reply to [email protected]

From: Mengdong Lin <[email protected]>

The flags will be used to configure an existing Backend and Codec<->Codec link or create a new links.

The private data is reserved for future extension.

include/uapi/sound/asoc.h +9 -0
index 21ebb97..4f1427a 100644
@@ -141,6 +141,11 @@
 /* DAI link flags */
 #define SND_SOC_TPLG_LNK_FLGBIT_IGNORE_SUSPEND          (1 << 0)
 #define SND_SOC_TPLG_LNK_FLGBIT_IGNORE_POWERDOWN_TIME   (1 << 1)
+#define SND_SOC_TPLG_LNK_FLGBIT_SYMMETRIC_RATES         (1 << 2)
+#define SND_SOC_TPLG_LNK_FLGBIT_SYMMETRIC_CHANNELS      (1 << 3)
+#define SND_SOC_TPLG_LNK_FLGBIT_SYMMETRIC_SAMPLEBITS    (1 << 4)
+#define SND_SOC_TPLG_LNK_FLGBIT_DPCM_PLAYBACK           (1 << 5)
+#define SND_SOC_TPLG_LNK_FLGBIT_DPCM_CAPTURE            (1 << 6)
 
 /*
  * DAI physical PCM data formats.
@@ -552,6 +557,10 @@ struct snd_soc_tplg_link_config {
 	struct snd_soc_tplg_hw_config hw_config[SND_SOC_TPLG_HW_CONFIG_MAX]; /* hw configs */
 	__le32 num_hw_configs;         /* number of hw configs */
 	__le32 default_hw_config_id;   /* default hw config ID for init */
+
+	__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.5.0
#23 lore raw

PATCH 11/13 ASoC: Define API to find a dai link by id

In reply to [email protected]

From: Mengdong Lin <[email protected]>

Topology can use this to check if a BE link already exists, and create a new link if not found.

include/sound/soc.h +2 -0
index 4f1c784..d52601a 100644
@@ -1671,6 +1671,8 @@ int snd_soc_add_dai_link(struct snd_soc_card *card,
 				struct snd_soc_dai_link *dai_link);
 void snd_soc_remove_dai_link(struct snd_soc_card *card,
 			     struct snd_soc_dai_link *dai_link);
+struct snd_soc_dai_link *snd_soc_find_dai_link(struct snd_soc_card *card,
+					       int id);
 
 int snd_soc_register_dai(struct snd_soc_component *component,
 	struct snd_soc_dai_driver *dai_drv);
sound/soc/soc-core.c +16 -0
index f6f5027..6b1d198 100644
@@ -972,6 +972,22 @@ struct snd_soc_dai *snd_soc_find_dai(
 }
 EXPORT_SYMBOL_GPL(snd_soc_find_dai);
 
+struct snd_soc_dai_link *snd_soc_find_dai_link(
+	struct snd_soc_card *card, int id)
+{
+	struct snd_soc_dai_link *link, *_link;
+
+	lockdep_assert_held(&client_mutex);
+
+	list_for_each_entry_safe(link, _link, &card->dai_link_list, list) {
+		if (link->id == id)
+			return link;
+	}
+
+	return NULL;
+}
+EXPORT_SYMBOL_GPL(snd_soc_find_dai_link);
+
 static bool soc_is_dai_link_bound(struct snd_soc_card *card,
 		struct snd_soc_dai_link *dai_link)
 {
Signature · 1 line
2.5.0
#24 lore raw

PATCH 12/13 ASoC: Probe link components after finding new links

In reply to [email protected]

From: Mengdong Lin <[email protected]>

Probing link components may bring new links from topolgy and these new links may need new components. So there will be multiple rounds of components probing until there is no new links found during the process.

Probing of aux_dev is moved earlier to simply the code. There is no need to probe aux_devices multiple times.

sound/soc/soc-core.c +12 -5
index 6b1d198..dbd2169 100644
@@ -1862,6 +1862,7 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
 	struct snd_soc_pcm_runtime *rtd;
 	struct snd_soc_dai_link *dai_link;
 	int ret, i, order;
+	bool find_new_link; /* topolgy may create new links */
 
 	mutex_lock(&client_mutex);
 	mutex_lock_nested(&card->mutex, SND_SOC_CARD_CLASS_INIT);
@@ -1934,7 +1935,13 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
 			goto card_probe_error;
 	}
 
+	/* probe auxiliary components */
+	ret = soc_probe_aux_devices(card);
+	if (ret < 0)
+		goto probe_dai_err;
+
 	/* probe all components used by DAI links on this card */
+probe_link_cmpnt:
 	for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST;
 			order++) {
 		list_for_each_entry(rtd, &card->rtd_list, list) {
@@ -1948,18 +1955,15 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
 		}
 	}
 
-	/* probe auxiliary components */
-	ret = soc_probe_aux_devices(card);
-	if (ret < 0)
-		goto probe_dai_err;
-
 	/* Find new DAI links added during probing components and bind them.
 	 * Components with topology may bring new DAIs and DAI links.
 	 */
+	find_new_link = false;
 	list_for_each_entry(dai_link, &card->dai_link_list, list) {
 		if (soc_is_dai_link_bound(card, dai_link))
 			continue;
 
+		find_new_link = true;
 		ret = soc_init_dai_link(card, dai_link);
 		if (ret)
 			goto probe_dai_err;
@@ -1968,6 +1972,9 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
 			goto probe_dai_err;
 	}
 
+	if (find_new_link) /* new link may have unprobed components */
+		goto probe_link_cmpnt;
+
 	/* probe all DAI links on this card */
 	for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST;
 			order++) {
Signature · 1 line
2.5.0
#25 lore raw

PATCH 13/13 ASoC: topology: Able to create BE DAI links

In reply to [email protected]

From: Mengdong Lin <[email protected]>

Topology will check with ASoC if a BE (Backend) link already exists by checking its ID. If the BE link doesn't exist, topology will create it and the link_load ops and card's add_dai_link will be called for machine specific init.

sound/soc/soc-topology.c +211 -1
index 6a1a9c2..fd2c36b 100644
@@ -49,9 +49,10 @@
 #define SOC_TPLG_PASS_GRAPH		5
 #define SOC_TPLG_PASS_PINS		6
 #define SOC_TPLG_PASS_BE_DAI		7
+#define SOC_TPLG_PASS_LINK		8
 
 #define SOC_TPLG_PASS_START	SOC_TPLG_PASS_MANIFEST
-#define SOC_TPLG_PASS_END	SOC_TPLG_PASS_BE_DAI
+#define SOC_TPLG_PASS_END	SOC_TPLG_PASS_LINK
 
 struct soc_tplg {
 	const struct firmware *fw;
@@ -493,6 +494,7 @@ static void remove_link(struct snd_soc_component *comp,
 
 	list_del(&dobj->list);
 	snd_soc_remove_dai_link(comp->card, link);
+	kfree(link->codecs);
 	kfree(link);
 }
 
@@ -1631,6 +1633,29 @@ static void set_link_flags(struct snd_soc_dai_link *link,
 	if (flag_mask & SND_SOC_TPLG_LNK_FLGBIT_IGNORE_POWERDOWN_TIME)
 		link->ignore_pmdown_time =
 		flags & SND_SOC_TPLG_LNK_FLGBIT_IGNORE_POWERDOWN_TIME ? 1 : 0;
+
+	if (flag_mask & SND_SOC_TPLG_LNK_FLGBIT_SYMMETRIC_RATES)
+		link->symmetric_rates =
+			flags & SND_SOC_TPLG_LNK_FLGBIT_SYMMETRIC_RATES ? 1 : 0;
+
+	if (flag_mask & SND_SOC_TPLG_LNK_FLGBIT_SYMMETRIC_CHANNELS)
+		link->symmetric_channels =
+			flags & SND_SOC_TPLG_LNK_FLGBIT_SYMMETRIC_CHANNELS ?
+			1 : 0;
+
+	if (flag_mask & SND_SOC_TPLG_LNK_FLGBIT_SYMMETRIC_SAMPLEBITS)
+		link->symmetric_samplebits =
+			flags & SND_SOC_TPLG_LNK_FLGBIT_SYMMETRIC_SAMPLEBITS ?
+			1 : 0;
+
+	if (flag_mask & SND_SOC_TPLG_LNK_FLGBIT_DPCM_PLAYBACK)
+		link->dpcm_playback =
+			flags & SND_SOC_TPLG_LNK_FLGBIT_DPCM_PLAYBACK ? 1 : 0;
+
+	if (flag_mask & SND_SOC_TPLG_LNK_FLGBIT_DPCM_CAPTURE)
+		link->dpcm_capture =
+			flags & SND_SOC_TPLG_LNK_FLGBIT_DPCM_CAPTURE ? 1 : 0;
+
 }
 
 /* create the FE DAI link */
@@ -1865,6 +1890,189 @@ static int soc_tplg_be_dai_elems_load(struct soc_tplg *tplg,
 	return 0;
 }
 
+/* *
+ * set_be_link_hw_format - Set the HW audio format of the BE DAI link.
+ * @tplg: topology context
+ * @cfg: topology BE DAI link configs.
+ *
+ * Topology context contains a list of supported HW formats (configs) and
+ * a default format ID for the BE link. This function will use this default ID
+ * to choose the HW format to set the link's DAI format for init.
+ */
+static void set_be_link_hw_format(struct snd_soc_dai_link *link,
+			struct snd_soc_tplg_link_config *cfg)
+{
+	struct snd_soc_tplg_hw_config *hw_config;
+	unsigned char bclk_master, fsync_master;
+	unsigned char invert_bclk, invert_fsync;
+	int i;
+
+	for (i = 0; i < cfg->num_hw_configs; i++) {
+		hw_config = &cfg->hw_config[i];
+		if (hw_config->id != cfg->default_hw_config_id)
+			continue;
+
+		link->dai_fmt = hw_config->fmt & SND_SOC_DAIFMT_FORMAT_MASK;
+
+		/* clock signal polarity */
+		invert_bclk = hw_config->invert_bclk;
+		invert_fsync = hw_config->invert_fsync;
+		if (!invert_bclk && !invert_fsync)
+			link->dai_fmt |= SND_SOC_DAIFMT_NB_NF;
+		else if (!invert_bclk && invert_fsync)
+			link->dai_fmt |= SND_SOC_DAIFMT_NB_IF;
+		else if (invert_bclk && !invert_fsync)
+			link->dai_fmt |= SND_SOC_DAIFMT_IB_NF;
+		else
+			link->dai_fmt |= SND_SOC_DAIFMT_IB_IF;
+
+		/* clock masters */
+		bclk_master = hw_config->bclk_master;
+		fsync_master = hw_config->fsync_master;
+		if (!bclk_master && !fsync_master)
+			link->dai_fmt |= SND_SOC_DAIFMT_CBM_CFM;
+		else if (bclk_master && !fsync_master)
+			link->dai_fmt |= SND_SOC_DAIFMT_CBS_CFM;
+		else if (!bclk_master && fsync_master)
+			link->dai_fmt |= SND_SOC_DAIFMT_CBM_CFS;
+		else
+			link->dai_fmt |= SND_SOC_DAIFMT_CBS_CFS;
+
+		return;
+	}
+}
+
+/* create a BE DAI link */
+static int soc_tplg_be_link_create(struct soc_tplg *tplg,
+	struct snd_soc_tplg_link_config *cfg)
+{
+	struct snd_soc_dai_link *link;
+	int i, ret = 0;
+
+	dev_dbg(tplg->dev,
+		"Adding BE link %s, stream name %s\n",
+		cfg->name, cfg->stream_name);
+
+	link = kzalloc(sizeof(struct snd_soc_dai_link), GFP_KERNEL);
+	if (link == NULL)
+		return -ENOMEM;
+
+	/* id and names */
+	if (strlen(cfg->name))
+		link->name = cfg->name;
+	if (strlen(cfg->stream_name))
+		link->stream_name = cfg->stream_name;
+	link->id = cfg->id;
+
+	/* components */
+	if (strlen(cfg->cpu.name))
+		link->cpu_name = cfg->cpu.name;
+	link->cpu_dai_name = cfg->cpu.dai_name;
+
+	if (!cfg->num_codecs || !cfg->codecs) {
+		ret = -EINVAL;
+		goto err;
+	}
+
+	link->num_codecs = cfg->num_codecs;
+	link->codecs = kcalloc(link->num_codecs,
+			       sizeof(struct snd_soc_dai_link_component),
+			       GFP_KERNEL);
+	if (!link->codecs) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	for (i = 0; i < link->num_codecs ; i++) {
+		if (strlen(cfg->codecs[i].name))
+			link->codecs[i].name = cfg->codecs[i].name;
+		link->codecs[i].dai_name = cfg->codecs[i].dai_name;
+	}
+
+	/* hw format */
+	if (cfg->num_hw_configs)
+		set_be_link_hw_format(link, cfg);
+
+	/* flags */
+	link->no_pcm = 1;
+	if (cfg->flag_mask)
+		set_link_flags(link, cfg->flag_mask, cfg->flags);
+
+	/* pass control to component driver for optional further init */
+	ret = soc_tplg_dai_link_load(tplg, link);
+	if (ret < 0) {
+		dev_err(tplg->dev, "ASoC: BE link loading failed\n");
+		goto err;
+	}
+
+	link->dobj.index = tplg->index;
+	link->dobj.ops = tplg->ops;
+	link->dobj.type = SND_SOC_DOBJ_DAI_LINK;
+	list_add(&link->dobj.list, &tplg->comp->dobj_list);
+
+	snd_soc_add_dai_link(tplg->comp->card, link);
+	return 0;
+
+err:
+	if (link) {
+		kfree(link->codecs);
+		kfree(link->params);
+		kfree(link);
+	}
+
+	return ret;
+}
+
+/* Config an existing or create a new BE DAI link */
+static int soc_tplg_be_link_config(struct soc_tplg *tplg,
+	struct snd_soc_tplg_link_config *cfg)
+{
+	struct snd_soc_dai_link *link;
+
+	link = snd_soc_find_dai_link(tplg->comp->card, cfg->id);
+	if (!link)
+		return soc_tplg_be_link_create(tplg, cfg);
+
+	/* TODO: configure existing BE links. No user request atm. */
+	return 0;
+}
+
+
+/* Load BE link elements from the topology context */
+static int soc_tplg_be_link_elems_load(struct soc_tplg *tplg,
+	struct snd_soc_tplg_hdr *hdr)
+{
+	struct snd_soc_tplg_link_config *link;
+	int count = hdr->count;
+	int i;
+
+	if (tplg->pass != SOC_TPLG_PASS_LINK) {
+		tplg->pos += hdr->size + hdr->payload_size;
+		return 0;
+	};
+
+	if (soc_tplg_check_elem_count(tplg,
+		sizeof(struct snd_soc_tplg_link_config), count,
+		hdr->payload_size, "BE DAI link")) {
+		dev_err(tplg->dev, "ASoC: invalid count %d for BE DAI link elems\n",
+			count);
+		return -EINVAL;
+	}
+
+	/* config or create the BE DAI links */
+	for (i = 0; i < count; i++) {
+		link = (struct snd_soc_tplg_link_config *)tplg->pos;
+		if (link->size != sizeof(*link)) {
+			dev_err(tplg->dev, "ASoC: invalid link config size\n");
+			return -EINVAL;
+		}
+
+		soc_tplg_be_link_config(tplg, link);
+		tplg->pos += (sizeof(*link) + link->priv.size);
+	}
+
+	return 0;
+}
 
 static int soc_tplg_manifest_load(struct soc_tplg *tplg,
 				  struct snd_soc_tplg_hdr *hdr)
@@ -1971,6 +2179,8 @@ static int soc_tplg_load_header(struct soc_tplg *tplg,
 		return soc_tplg_pcm_elems_load(tplg, hdr);
 	case SND_SOC_TPLG_TYPE_BE_DAI:
 		return soc_tplg_be_dai_elems_load(tplg, hdr);
+	case SND_SOC_TPLG_TYPE_BACKEND_LINK:
+		return soc_tplg_be_link_elems_load(tplg, hdr);
 	case SND_SOC_TPLG_TYPE_MANIFEST:
 		return soc_tplg_manifest_load(tplg, hdr);
 	default:
Signature · 1 line
2.5.0
maintainer
#8 lore raw

Applied "ASoC: topology: ABI - Add sig_bits to stream caps" to the asoc tree

In reply to [email protected]

The patch

ASoC: topology: ABI - Add sig_bits to stream caps

has been applied to the asoc tree at

git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git

All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying to this mail.

Thanks,
Mark

Quoted 1 line

From f918e1697b1a8f2f26a4813db053cfbcafc48046 Mon Sep 17 00:00:00 2001

From: Mengdong Lin <[email protected]>
Date: Fri, 19 Aug 2016 18:12:46 +0800
Subject: [PATCH] ASoC: topology: ABI - Add sig_bits to stream caps

Kernel struct snd_soc_pcm_stream, SoC PCM stream information, needs this field. Although current topology users don't configure this, we define it for future extension.

---
 include/uapi/sound/asoc.h | 1 +
 sound/soc/soc-topology.c  | 1 +
 2 files changed, 2 insertions(+)
include/uapi/sound/asoc.h +1 -0
index f734bea9a032..33d00a4ce656 100644
@@ -257,6 +257,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));
 
 /*
sound/soc/soc-topology.c +1 -0
index a9e83a2dd91c..6b05047a4134 100644
@@ -1556,6 +1556,7 @@ static void set_stream_info(struct snd_soc_pcm_stream *stream,
 	stream->rate_min = caps->rate_min;
 	stream->rate_max = caps->rate_max;
 	stream->formats = caps->formats;
+	stream->sig_bits = caps->sig_bits;
 }
 
 static void set_dai_flags(struct snd_soc_dai_driver *dai_drv,
Signature · 1 line
2.8.1
maintainer
#2 lore raw

Re: [PATCH 01/13] ASoC: topology: Able to create BE DAIs

In reply to [email protected]
Quoted 3 lines · On Fri, Aug 19, 2016 at 06:12:35PM +0800, [email protected] wrote:

Topology will check with ASoC if a BE DAI already exists by checking its name. If the BE DAI doesn't exist, topology will create a new one and the dai_load ops will be called for device specific init.

This doesn't explain in what situation we'd want to dynamically create a back end, or why we're representing DPCM so directly in the topology - we really need more words about what the use case is and why this makes sense. The expectation would be that back ends refer to physical objects that exist in the system so it's not clear why we'd be loading them from topologies (and that even where this makes sense there wouldn't be any misuse by other users). This is a bit of a theme here, the series is adding a bunch of stuff but not explaining why.

maintainer
#10 lore raw

Re: [PATCH 03/13] ASoC: topology: ABI - Define DPCM trigger ordering for PCM

In reply to [email protected]
Quoted 3 lines · On Fri, Aug 19, 2016 at 06:12:55PM +0800, [email protected] wrote:

Definition of dynamic PCM trigger ordering is exposed to uapi asoc.h, and topology allows user space to define the trigger ordering for PCM (FE links).

This seems *incredibly* implementation specific. Why wouldn't the driver for the thing implementing the topology be able to figure out the ordering here? What's the use case? What happens when we change away from DPCM?

#3 lore raw

Re: [PATCH 01/13] ASoC: topology: Able to create BE DAIs

In reply to Mark Brown
Quoted 6 lines · Mark Brown
Quoted 3 lines · On Fri, Aug 19, 2016 at 06:12:35PM +0800, [email protected] wrote:

Topology will check with ASoC if a BE DAI already exists by checking its name. If the BE DAI doesn't exist, topology will create a new one and the dai_load ops will be called for device specific init.

Quoted 9 lines

This doesn't explain in what situation we'd want to dynamically create a back end, or why we're representing DPCM so directly in the topology - we really need more words about what the use case is and why this makes sense. The expectation would be that back ends refer to physical objects that exist in the system so it's not clear why we'd be loading them from topologies (and that even where this makes sense there wouldn't be any misuse by other users). This is a bit of a theme here, the series is adding a bunch of stuff but not explaining why.

Thanks for the review! Sorry for not giving enough background info.

In previous design, we had thought that BE DAI and BE DAI links should be created based on ACPI info in BIOS. But unfortunately, the BIOS doesn't have enough physical information, so BE DAI & DAI links are hard coded in platform and machine driver. But when new platforms are coming out with different physical connections, this BIOS gap blocks us from sharing a generic driver across platforms. Now the gap in BIOS ACPI info still exists, the implementations also vary for different generations of platforms, BIOS for public shipped machines cannot change ... So finally we fall back to topology to overcome the BIOS gap and make driver sharing possible. We have tried creating BE DAI & DAI links to new platforms and plan to back port this to upstream drivers for existing platforms like SKL.

I'll add this to the commit messages of next version.

Thanks
Mengdong

#11 lore raw

Re: [PATCH 03/13] ASoC: topology: ABI - Define DPCM trigger ordering for PCM

In reply to Mark Brown
Quoted 11 lines · Mark Brown
Quoted 3 lines · On Fri, Aug 19, 2016 at 06:12:55PM +0800, [email protected] wrote:

Definition of dynamic PCM trigger ordering is exposed to uapi asoc.h, and topology allows user space to define the trigger ordering for PCM (FE links).

This seems *incredibly* implementation specific. Why wouldn't the driver for the thing implementing the topology be able to figure out the ordering here? What's the use case? What happens when we change away from DPCM?

I'll check if we can let driver figure out this ordering or use some more generic name.

We add this trigger ordering as driver developer request and we think it's decided by the firmware behavior. We hope firmware properties can be covered by topology.

Thanks
Mengdong

maintainer
#4 lore raw

Re: [PATCH 01/13] ASoC: topology: Able to create BE DAIs

In reply to Mengdong Lin
Quoted 11 lines · Mengdong Lin

In previous design, we had thought that BE DAI and BE DAI links should be created based on ACPI info in BIOS. But unfortunately, the BIOS doesn't have enough physical information, so BE DAI & DAI links are hard coded in platform and machine driver. But when new platforms are coming out with different physical connections, this BIOS gap blocks us from sharing a generic driver across platforms. Now the gap in BIOS ACPI info still exists, the implementations also vary for different generations of platforms, BIOS for public shipped machines cannot change ... So finally we fall back to topology to overcome the BIOS gap and make driver sharing possible. We have tried creating BE DAI & DAI links to new platforms and plan to back port this to upstream drivers for existing platforms like SKL.

I don't understand why we're not able to just enumerate all the possible back ends in the driver and then select the required one at runtime
- even if we do this there's going to be some fairly strict limits on the set of back ends that can be added. Do we have any concrete examples here?

#5 lore raw

Re: [PATCH 01/13] ASoC: topology: Able to create BE DAIs

Hi Mark,

Here is the info from our audio platform enabling team that answers why we need this feature. Please review.

Intel platform supports too many different types of DAIs based on the platform variant e.g. I2S, HDA, DMIC and in future there are few more like soundwire in the pipelines.

Using this framework our attempt is to create DAI based on what is supported on the platform. If the platform does not support HDA then we would like not to create the HDA DAIs. e.g. SKL Chrome topology does not use HDA Codec and so there is only I2S and DMIC DAIs.

Based on the SoC pin count limitation not all the interface pins are taken out of the SoC to connect various peripherals. So even though technically hardware supports many physical interfaces but the platform may have limited what can be connected on the platform.

Surely we can create worst case number of DAIs but that would be too much.

Here is the example of SKL/BXT:
6 SSP Ports Rx and Tx, 2 DMIC Ports, 7 Playback DMA channels, 6 Capture DMA channels.We are creating topology diagram in text to explain different configuration for different use case,like Android, Linux, Chrome and Automotive.

Thanks
Mengdong

Quoted 20 lines · Mark Brown
Quoted 11 lines · Mengdong Lin

In previous design, we had thought that BE DAI and BE DAI links should be created based on ACPI info in BIOS. But unfortunately, the BIOS doesn't have enough physical information, so BE DAI & DAI links are hard coded in platform and machine driver. But when new platforms are coming out with different physical connections, this BIOS gap blocks us from sharing a generic driver across platforms. Now the gap in BIOS ACPI info still exists, the implementations also vary for different generations of platforms, BIOS for public shipped machines cannot change ... So finally we fall back to topology to overcome the BIOS gap and make driver sharing possible. We have tried creating BE DAI & DAI links to new platforms and plan to back port this to upstream drivers for existing platforms like SKL.

I don't understand why we're not able to just enumerate all the possible back ends in the driver and then select the required one at runtime
- even if we do this there's going to be some fairly strict limits on the set of back ends that can be added. Do we have any concrete examples here?

#12 lore raw

Re: [PATCH 03/13] ASoC: topology: ABI - Define DPCM trigger ordering for PCM

In reply to Mark Brown
Quoted 11 lines · Mark Brown
Quoted 3 lines · On Fri, Aug 19, 2016 at 06:12:55PM +0800, [email protected] wrote:

Definition of dynamic PCM trigger ordering is exposed to uapi asoc.h, and topology allows user space to define the trigger ordering for PCM (FE links).

This seems *incredibly* implementation specific. Why wouldn't the driver for the thing implementing the topology be able to figure out the ordering here? What's the use case? What happens when we change away from DPCM?

There is another patch (04/13) to add generic flags and flag mask to PCM objects. So we'll allow users to set DPCM trigger ordering as flags as below, to avoid using trigger[] in ABI. The topology kernel driver will check the flag bits and set the proper trigger ordering to FE DAI links. If we change away from DPCM in the future, user can stop using these flags. And the 32-bit flags seems enough for future extension.

include/uapi/sound/asoc.h +10 -0
index f734bea..30da32f 100644
@@ -130,6 +130,16 @@
 #define SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_CHANNELS      (1 << 1)
 #define SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_SAMPLEBITS    (1 << 2)
 
+/* DAI link flags */
+#define SND_SOC_TPLG_LNK_FLGBIT_IGNORE_SUSPEND          (1 << 0)
+#define SND_SOC_TPLG_LNK_FLGBIT_IGNORE_POWERDOWN_TIME   (1 << 1)
+#define SND_SOC_TPLG_LNK_FLGBIT_PLAYBACK_DPCM_TRIGGER_PRE       (1<<2)
+#define SND_SOC_TPLG_LNK_FLGBIT_PLAYBACK_DPCM_TRIGGER_POST      (1<<3)
+#define SND_SOC_TPLG_LNK_FLGBIT_PLAYBACK_DPCM_TRIGGER_BESPOKE   (1<<4)
+#define SND_SOC_TPLG_LNK_FLGBIT_CAPTURE_DPCM_TRIGGER_PRE        (1<<2)
+#define SND_SOC_TPLG_LNK_FLGBIT_CAPTURE_DPCM_TRIGGER_POST       (1<<3)
+#define SND_SOC_TPLG_LNK_FLGBIT_CAPTURE_DPCM_TRIGGER_BESPOKE    (1<<4)
+
 /*
  * Block Header.
  * This header precedes all object and object arrays below.
@@ -439,6 +449,8 @@ 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 */

} __attribute__((packed));

Thanks
Mengdong

maintainer
#13 lore raw

Re: [PATCH 03/13] ASoC: topology: ABI - Define DPCM trigger ordering for PCM

Quoted 7 lines · Mengdong Lin
Quoted 4 lines · Mark Brown

This seems *incredibly* implementation specific. Why wouldn't the driver for the thing implementing the topology be able to figure out the ordering here? What's the use case? What happens when we change away from DPCM?

Quoted 6 lines

There is another patch (04/13) to add generic flags and flag mask to PCM objects. So we'll allow users to set DPCM trigger ordering as flags as below, to avoid using trigger[] in ABI. The topology kernel driver will check the flag bits and set the proper trigger ordering to FE DAI links. If we change away from DPCM in the future, user can stop using these flags. And the 32-bit flags seems enough for future extension.

This doesn't seem much better to be honest, it's just shuffling the problem around. Why do these things need to be triggered in this particular order and why is that invisible to the system?

maintainer
#6 lore raw

Re: [PATCH 01/13] ASoC: topology: Able to create BE DAIs

In reply to Mengdong Lin
Quoted 7 lines · Mengdong Lin

Surely we can create worst case number of DAIs but that would be too much.

Here is the example of SKL/BXT:
6 SSP Ports Rx and Tx, 2 DMIC Ports, 7 Playback DMA channels, 6 Capture DMA channels.We are creating topology diagram in text to explain different configuration for different use case,like Android, Linux, Chrome and Automotive.

That's just 14 back ends by my count (the SSP and DMIC ports) which seems totally managable? Even if you include the DMA it's still not an absurdly large number especially if you compare it to something like the number of widgets we actively manage in a running CODEC.

#14 lore raw

Re: [PATCH 03/13] ASoC: topology: ABI - Define DPCM trigger ordering for PCM

In reply to Mengdong Lin

+ Rakesh

Hi Hardik/Vinod/Rakesh,

Would you please share more info about DPCM trigger ordering used in current ADSP firmware? And why we hope to configure this by topology?

Here is Mark's question "Why do these things need to be triggered in this particular order and why is that invisible to the system?".

Please see link http://mailman.alsa-project.org/pipermail/alsa-devel/2016-September/112539.html

My mail client lost Mark's mail so I paste the link here.

Thanks
Mengdong

Quoted 57 lines · Mengdong Lin
Quoted 12 lines · Mark Brown
Quoted 3 lines · On Fri, Aug 19, 2016 at 06:12:55PM +0800, [email protected] wrote:

Definition of dynamic PCM trigger ordering is exposed to uapi asoc.h, and topology allows user space to define the trigger ordering for PCM (FE links).

This seems *incredibly* implementation specific. Why wouldn't the driver for the thing implementing the topology be able to figure out the ordering here? What's the use case? What happens when we change away from DPCM?

There is another patch (04/13) to add generic flags and flag mask to PCM objects. So we'll allow users to set DPCM trigger ordering as flags as below, to avoid using trigger[] in ABI. The topology kernel driver will check the flag bits and set the proper trigger ordering to FE DAI links. If we change away from DPCM in the future, user can stop using these flags. And the 32-bit flags seems enough for future extension.

include/uapi/sound/asoc.h +10 -0
index f734bea..30da32f 100644
@@ -130,6 +130,16 @@
  #define SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_CHANNELS      (1 << 1)
  #define SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_SAMPLEBITS    (1 << 2)
 
+/* DAI link flags */
+#define SND_SOC_TPLG_LNK_FLGBIT_IGNORE_SUSPEND          (1 << 0)
+#define SND_SOC_TPLG_LNK_FLGBIT_IGNORE_POWERDOWN_TIME   (1 << 1)
+#define SND_SOC_TPLG_LNK_FLGBIT_PLAYBACK_DPCM_TRIGGER_PRE       (1<<2)
+#define SND_SOC_TPLG_LNK_FLGBIT_PLAYBACK_DPCM_TRIGGER_POST      (1<<3)
+#define SND_SOC_TPLG_LNK_FLGBIT_PLAYBACK_DPCM_TRIGGER_BESPOKE   (1<<4)
+#define SND_SOC_TPLG_LNK_FLGBIT_CAPTURE_DPCM_TRIGGER_PRE        (1<<2)
+#define SND_SOC_TPLG_LNK_FLGBIT_CAPTURE_DPCM_TRIGGER_POST       (1<<3)
+#define SND_SOC_TPLG_LNK_FLGBIT_CAPTURE_DPCM_TRIGGER_BESPOKE    (1<<4)
+
  /*
   * Block Header.
   * This header precedes all object and object arrays below.
@@ -439,6 +449,8 @@ 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 */

include/uapi/sound/asoc.h +2 -0
+       __le32 flag_mask;       /* bitmask of flags to configure */
+       __le32 flags;           /* SND_SOC_TPLG_LNK_FLGBIT_* flag value */
  } __attribute__((packed));

Thanks
Mengdong

#15 lore raw

Re: [PATCH 03/13] ASoC: topology: ABI - Define DPCM trigger ordering for PCM

Hi Mark,

We'll drop support for configuring DPCM trigger ordering in topology, and the driver will set this in kernel.

I'll submit the v2 series. Please review.

Thanks
Mengdong

Quoted 79 lines · Mengdong Lin

+ Rakesh

Hi Hardik/Vinod/Rakesh,

Would you please share more info about DPCM trigger ordering used in current ADSP firmware? And why we hope to configure this by topology?

Here is Mark's question "Why do these things need to be triggered in this particular order and why is that invisible to the system?".

Please see link
http://mailman.alsa-project.org/pipermail/alsa-devel/2016-September/112539.html

My mail client lost Mark's mail so I paste the link here.

Thanks
Mengdong

Quoted 58 lines · Mengdong Lin
Quoted 12 lines · Mark Brown
Quoted 3 lines · On Fri, Aug 19, 2016 at 06:12:55PM +0800, [email protected] wrote:

Definition of dynamic PCM trigger ordering is exposed to uapi asoc.h, and topology allows user space to define the trigger ordering for PCM (FE links).

This seems *incredibly* implementation specific. Why wouldn't the driver for the thing implementing the topology be able to figure out the ordering here? What's the use case? What happens when we change away from DPCM?

There is another patch (04/13) to add generic flags and flag mask to PCM objects. So we'll allow users to set DPCM trigger ordering as flags as below, to avoid using trigger[] in ABI. The topology kernel driver will check the flag bits and set the proper trigger ordering to FE DAI links. If we change away from DPCM in the future, user can stop using these flags. And the 32-bit flags seems enough for future extension.

include/uapi/sound/asoc.h +10 -0
index f734bea..30da32f 100644
@@ -130,6 +130,16 @@
  #define SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_CHANNELS      (1 << 1)
  #define SND_SOC_TPLG_DAI_FLGBIT_SYMMETRIC_SAMPLEBITS    (1 << 2)
 
+/* DAI link flags */
+#define SND_SOC_TPLG_LNK_FLGBIT_IGNORE_SUSPEND          (1 << 0)
+#define SND_SOC_TPLG_LNK_FLGBIT_IGNORE_POWERDOWN_TIME   (1 << 1)
+#define SND_SOC_TPLG_LNK_FLGBIT_PLAYBACK_DPCM_TRIGGER_PRE       (1<<2)
+#define SND_SOC_TPLG_LNK_FLGBIT_PLAYBACK_DPCM_TRIGGER_POST      (1<<3)
+#define SND_SOC_TPLG_LNK_FLGBIT_PLAYBACK_DPCM_TRIGGER_BESPOKE   (1<<4)
+#define SND_SOC_TPLG_LNK_FLGBIT_CAPTURE_DPCM_TRIGGER_PRE        (1<<2)
+#define SND_SOC_TPLG_LNK_FLGBIT_CAPTURE_DPCM_TRIGGER_POST       (1<<3)
+#define SND_SOC_TPLG_LNK_FLGBIT_CAPTURE_DPCM_TRIGGER_BESPOKE    (1<<4)
+
  /*
   * Block Header.
   * This header precedes all object and object arrays below.
@@ -439,6 +449,8 @@ 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 */

include/uapi/sound/asoc.h +2 -0
+       __le32 flag_mask;       /* bitmask of flags to configure */
+       __le32 flags;           /* SND_SOC_TPLG_LNK_FLGBIT_* flag

value */
} __attribute__((packed));

Thanks
Mengdong