Skip to contentSkip to conversation

ASoC: topology: Add support for PCM, BE & CC links

PATCH In review [email protected] 3 participants 19 messages Nov 5, 2015 – Dec 8, 2015

Subsystems (10)
lore
Share & tools
lore
#0 lore raw

v2 cover ASoC: topology: Add support for PCM, BE & CC links

From: Mengdong Lin <[email protected]>

This series allows the topology core to create PCM devices dynamically, as well as configure BE and CC DAI links.

Mengdong Lin (12):
ASoC: Vendor drivers get a link's runtime by snd_soc_get_pcm_runtime()
ASoC: Change the PCM runtime array to a list
ASoC: Define soc_init_dai_link() to wrap link intialization.
ASoC: Change 2nd argument of soc_bind_dai_link() to DAI link pointer
ASoC: Implement DAI links in a list & define API to add a link
ASoC: Add add_dai_link ops for a soc card
ASoC: soc_bind_dai_link() directly returns success for a bound DAI
link
ASoC: Bind new DAI links after probing components
ASoC: The soc card can have auxiliary components
ASoC: Support adding a DAI dynamically
ASoC: topology: Add PCM DAIs dynamically when loading them
ASoC: topology: Add support for FE DAI links

Vedang Patel (1):
ASoC: topology: Add support for BE and CC DAI Links

 include/sound/soc-dai.h                      |   1 +
 include/sound/soc-topology.h                 |  22 +-
 include/sound/soc.h                          |  38 +-
 sound/soc/fsl/fsl-asoc-card.c                |   5 +-
 sound/soc/fsl/imx-wm8962.c                   |  10 +-
 sound/soc/generic/simple-card.c              |  12 +-
 sound/soc/intel/atom/sst-mfld-platform-pcm.c |  12 +-
 sound/soc/intel/boards/cht_bsw_max98090_ti.c |   7 +-
 sound/soc/intel/boards/cht_bsw_rt5645.c      |   7 +-
 sound/soc/intel/boards/cht_bsw_rt5672.c      |   7 +-
 sound/soc/pxa/mioa701_wm9713.c               |   6 +-
 sound/soc/samsung/bells.c                    |  40 +-
 sound/soc/samsung/littlemill.c               |  32 +-
 sound/soc/samsung/odroidx2_max98090.c        |   9 +-
 sound/soc/samsung/snow.c                     |   9 +-
 sound/soc/samsung/speyside.c                 |  12 +-
 sound/soc/samsung/tobermory.c                |  21 +-
 sound/soc/sh/rcar/core.c                     |   2 +-
 sound/soc/sh/rcar/rsrc-card.c                |   6 +-
 sound/soc/soc-core.c                         | 629 ++++++++++++++++++---------
 sound/soc/soc-dapm.c                         |   7 +-
 sound/soc/soc-pcm.c                          |  22 +-
 sound/soc/soc-topology.c                     | 284 ++++++++++--
 sound/soc/tegra/tegra_wm8903.c               |   3 +-
 24 files changed, 879 insertions(+), 324 deletions(-)
Signature · 1 line
1.9.1
#1 lore raw

PATCH v2 1/13 ASoC: Vendor drivers get a link's runtime by snd_soc_get_pcm_runtime()

From: Mengdong Lin <[email protected]>

Vendor drivers no longer access a DAI link's runtime by the link index but by matching the link name via snd_soc_get_pcm_runtime(). We assume each DAI link has a unique name.

This is preparation for changing runtimes from an array to a list later.

Vendor drivers changed:
sound/soc/fsl/fsl-asoc-card.c
sound/soc/fsl/imx-wm8962.c
sound/soc/pxa/mioa701_wm9713.c
sound/soc/samsung/bells.c
sound/soc/samsung/littlemill.c
sound/soc/samsung/odroidx2_max98090.c
sound/soc/samsung/snow.c
sound/soc/samsung/speyside.c
sound/soc/samsung/tobermory.c
sound/soc/tegra/tegra_wm8903

sound/soc/fsl/fsl-asoc-card.c +4 -1
index 1b05d1c..f4b6c53 100644
@@ -222,12 +222,15 @@ static int fsl_asoc_card_set_bias_level(struct snd_soc_card *card,
 					enum snd_soc_bias_level level)
 {
 	struct fsl_asoc_card_priv *priv = snd_soc_card_get_drvdata(card);
-	struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
+	struct snd_soc_pcm_runtime *rtd;
+	struct snd_soc_dai *codec_dai;
 	struct codec_priv *codec_priv = &priv->codec_priv;
 	struct device *dev = card->dev;
 	unsigned int pll_out;
 	int ret;
 
+	rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
+	codec_dai = rtd->codec_dai;
 	if (dapm->dev != codec_dai->dev)
 		return 0;
 
sound/soc/fsl/imx-wm8962.c +8 -2
index b38b98c..201a70d 100644
@@ -69,13 +69,16 @@ static int imx_wm8962_set_bias_level(struct snd_soc_card *card,
 					struct snd_soc_dapm_context *dapm,
 					enum snd_soc_bias_level level)
 {
-	struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
+	struct snd_soc_pcm_runtime *rtd;
+	struct snd_soc_dai *codec_dai;
 	struct imx_priv *priv = &card_priv;
 	struct imx_wm8962_data *data = snd_soc_card_get_drvdata(card);
 	struct device *dev = &priv->pdev->dev;
 	unsigned int pll_out;
 	int ret;
 
+	rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
+	codec_dai = rtd->codec_dai;
 	if (dapm->dev != codec_dai->dev)
 		return 0;
 
@@ -135,12 +138,15 @@ static int imx_wm8962_set_bias_level(struct snd_soc_card *card,
 
 static int imx_wm8962_late_probe(struct snd_soc_card *card)
 {
-	struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
+	struct snd_soc_pcm_runtime *rtd;
+	struct snd_soc_dai *codec_dai;
 	struct imx_priv *priv = &card_priv;
 	struct imx_wm8962_data *data = snd_soc_card_get_drvdata(card);
 	struct device *dev = &priv->pdev->dev;
 	int ret;
 
+	rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
+	codec_dai = rtd->codec_dai;
 	ret = snd_soc_dai_set_sysclk(codec_dai, WM8962_SYSCLK_MCLK,
 			data->clk_frequency, SND_SOC_CLOCK_IN);
 	if (ret < 0)
sound/soc/pxa/mioa701_wm9713.c +5 -1
index 29bc60e8..5c8f9db 100644
@@ -81,8 +81,12 @@ static int rear_amp_power(struct snd_soc_codec *codec, int power)
 static int rear_amp_event(struct snd_soc_dapm_widget *widget,
 			  struct snd_kcontrol *kctl, int event)
 {
-	struct snd_soc_codec *codec = widget->dapm->card->rtd[0].codec;
+	struct snd_soc_card *card = widget->dapm->card;
+	struct snd_soc_pcm_runtime *rtd;
+	struct snd_soc_codec *codec;
 
+	rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
+	codec = rtd->codec;
 	return rear_amp_power(codec, SND_SOC_DAPM_EVENT_ON(event));
 }
 
sound/soc/samsung/bells.c +30 -10
index e5f05e6..3dd246f 100644
@@ -58,11 +58,16 @@ static int bells_set_bias_level(struct snd_soc_card *card,
 				struct snd_soc_dapm_context *dapm,
 				enum snd_soc_bias_level level)
 {
-	struct snd_soc_dai *codec_dai = card->rtd[DAI_DSP_CODEC].codec_dai;
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_pcm_runtime *rtd;
+	struct snd_soc_dai *codec_dai;
+	struct snd_soc_codec *codec;
 	struct bells_drvdata *bells = card->drvdata;
 	int ret;
 
+	rtd = snd_soc_get_pcm_runtime(card, card->dai_link[DAI_DSP_CODEC].name);
+	codec_dai = rtd->codec_dai;
+	codec = codec_dai->codec;
+
 	if (dapm->dev != codec_dai->dev)
 		return 0;
 
@@ -99,11 +104,16 @@ static int bells_set_bias_level_post(struct snd_soc_card *card,
 				     struct snd_soc_dapm_context *dapm,
 				     enum snd_soc_bias_level level)
 {
-	struct snd_soc_dai *codec_dai = card->rtd[DAI_DSP_CODEC].codec_dai;
-	struct snd_soc_codec *codec = codec_dai->codec;
+	struct snd_soc_pcm_runtime *rtd;
+	struct snd_soc_dai *codec_dai;
+	struct snd_soc_codec *codec;
 	struct bells_drvdata *bells = card->drvdata;
 	int ret;
 
+	rtd = snd_soc_get_pcm_runtime(card, card->dai_link[DAI_DSP_CODEC].name);
+	codec_dai = rtd->codec_dai;
+	codec = codec_dai->codec;
+
 	if (dapm->dev != codec_dai->dev)
 		return 0;
 
@@ -137,14 +147,22 @@ static int bells_set_bias_level_post(struct snd_soc_card *card,
 static int bells_late_probe(struct snd_soc_card *card)
 {
 	struct bells_drvdata *bells = card->drvdata;
-	struct snd_soc_codec *wm0010 = card->rtd[DAI_AP_DSP].codec;
-	struct snd_soc_codec *codec = card->rtd[DAI_DSP_CODEC].codec;
-	struct snd_soc_dai *aif1_dai = card->rtd[DAI_DSP_CODEC].codec_dai;
+	struct snd_soc_pcm_runtime *rtd;
+	struct snd_soc_codec *wm0010;
+	struct snd_soc_codec *codec;
+	struct snd_soc_dai *aif1_dai;
 	struct snd_soc_dai *aif2_dai;
 	struct snd_soc_dai *aif3_dai;
 	struct snd_soc_dai *wm9081_dai;
 	int ret;
 
+	rtd = snd_soc_get_pcm_runtime(card, card->dai_link[DAI_AP_DSP].name);
+	wm0010 = rtd->codec;
+
+	rtd = snd_soc_get_pcm_runtime(card, card->dai_link[DAI_DSP_CODEC].name);
+	codec = rtd->codec;
+	aif1_dai = rtd->codec_dai;
+
 	ret = snd_soc_codec_set_sysclk(codec, ARIZONA_CLK_SYSCLK,
 				       ARIZONA_CLK_SRC_FLL1,
 				       bells->sysclk_rate,
@@ -181,7 +199,8 @@ static int bells_late_probe(struct snd_soc_card *card)
 		return ret;
 	}
 
-	aif2_dai = card->rtd[DAI_CODEC_CP].cpu_dai;
+	rtd = snd_soc_get_pcm_runtime(card, card->dai_link[DAI_CODEC_CP].name);
+	aif2_dai = rtd->cpu_dai;
 
 	ret = snd_soc_dai_set_sysclk(aif2_dai, ARIZONA_CLK_ASYNCCLK, 0, 0);
 	if (ret != 0) {
@@ -192,8 +211,9 @@ static int bells_late_probe(struct snd_soc_card *card)
 	if (card->num_rtd == DAI_CODEC_SUB)
 		return 0;
 
-	aif3_dai = card->rtd[DAI_CODEC_SUB].cpu_dai;
-	wm9081_dai = card->rtd[DAI_CODEC_SUB].codec_dai;
+	rtd = snd_soc_get_pcm_runtime(card, card->dai_link[DAI_CODEC_SUB].name);
+	aif3_dai = rtd->cpu_dai;
+	wm9081_dai = rtd->codec_dai;
 
 	ret = snd_soc_dai_set_sysclk(aif3_dai, ARIZONA_CLK_SYSCLK, 0, 0);
 	if (ret != 0) {
sound/soc/samsung/littlemill.c +26 -6
index 31a820e..7cb204e 100644
@@ -23,9 +23,13 @@ static int littlemill_set_bias_level(struct snd_soc_card *card,
 					  struct snd_soc_dapm_context *dapm,
 					  enum snd_soc_bias_level level)
 {
-	struct snd_soc_dai *aif1_dai = card->rtd[0].codec_dai;
+	struct snd_soc_pcm_runtime *rtd;
+	struct snd_soc_dai *aif1_dai;
 	int ret;
 
+	rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
+	aif1_dai = rtd->codec_dai;
+
 	if (dapm->dev != aif1_dai->dev)
 		return 0;
 
@@ -66,9 +70,13 @@ static int littlemill_set_bias_level_post(struct snd_soc_card *card,
 					       struct snd_soc_dapm_context *dapm,
 					       enum snd_soc_bias_level level)
 {
-	struct snd_soc_dai *aif1_dai = card->rtd[0].codec_dai;
+	struct snd_soc_pcm_runtime *rtd;
+	struct snd_soc_dai *aif1_dai;
 	int ret;
 
+	rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
+	aif1_dai = rtd->codec_dai;
+
 	if (dapm->dev != aif1_dai->dev)
 		return 0;
 
@@ -168,9 +176,13 @@ static int bbclk_ev(struct snd_soc_dapm_widget *w,
 		    struct snd_kcontrol *kcontrol, int event)
 {
 	struct snd_soc_card *card = w->dapm->card;
-	struct snd_soc_dai *aif2_dai = card->rtd[1].cpu_dai;
+	struct snd_soc_pcm_runtime *rtd;
+	struct snd_soc_dai *aif2_dai;
 	int ret;
 
+	rtd = snd_soc_get_pcm_runtime(card, card->dai_link[1].name);
+	aif2_dai = rtd->cpu_dai;
+
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
 		ret = snd_soc_dai_set_pll(aif2_dai, WM8994_FLL2,
@@ -245,11 +257,19 @@ static struct snd_soc_jack littlemill_headset;
 
 static int littlemill_late_probe(struct snd_soc_card *card)
 {
-	struct snd_soc_codec *codec = card->rtd[0].codec;
-	struct snd_soc_dai *aif1_dai = card->rtd[0].codec_dai;
-	struct snd_soc_dai *aif2_dai = card->rtd[1].cpu_dai;
+	struct snd_soc_pcm_runtime *rtd;
+	struct snd_soc_codec *codec;
+	struct snd_soc_dai *aif1_dai;
+	struct snd_soc_dai *aif2_dai;
 	int ret;
 
+	rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
+	codec = rtd->codec;
+	aif1_dai = rtd->codec_dai;
+
+	rtd = snd_soc_get_pcm_runtime(card, card->dai_link[1].name);
+	aif2_dai = rtd->cpu_dai;
+
 	ret = snd_soc_dai_set_sysclk(aif1_dai, WM8994_SYSCLK_MCLK2,
 				     32768, SND_SOC_CLOCK_IN);
 	if (ret < 0)
sound/soc/samsung/odroidx2_max98090.c +7 -2
index 596f118..0421727 100644
@@ -25,10 +25,15 @@ static struct snd_soc_dai_link odroidx2_dai[];
 
 static int odroidx2_late_probe(struct snd_soc_card *card)
 {
-	struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
-	struct snd_soc_dai *cpu_dai = card->rtd[0].cpu_dai;
+	struct snd_soc_pcm_runtime *rtd;
+	struct snd_soc_dai *codec_dai;
+	struct snd_soc_dai *cpu_dai;
 	int ret;
 
+	rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
+	codec_dai = rtd->codec_dai;
+	cpu_dai = rtd->cpu_dai;
+
 	ret = snd_soc_dai_set_sysclk(codec_dai, 0, MAX98090_MCLK,
 						SND_SOC_CLOCK_IN);
 
sound/soc/samsung/snow.c +7 -2
index 07ce2cf..d8ac907 100644
@@ -35,10 +35,15 @@ static struct snd_soc_dai_link snow_dai[] = {
 
 static int snow_late_probe(struct snd_soc_card *card)
 {
-	struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
-	struct snd_soc_dai *cpu_dai = card->rtd[0].cpu_dai;
+	struct snd_soc_pcm_runtime *rtd;
+	struct snd_soc_dai *codec_dai;
+	struct snd_soc_dai *cpu_dai;
 	int ret;
 
+	rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
+	codec_dai = rtd->codec_dai;
+	cpu_dai = rtd->cpu_dai;
+
 	/* Set the MCLK rate for the codec */
 	ret = snd_soc_dai_set_sysclk(codec_dai, 0,
 					FIN_PLL_RATE, SND_SOC_CLOCK_IN);
sound/soc/samsung/speyside.c +10 -2
index d1ae21c..083ef5e 100644
@@ -25,9 +25,13 @@ static int speyside_set_bias_level(struct snd_soc_card *card,
 				   struct snd_soc_dapm_context *dapm,
 				   enum snd_soc_bias_level level)
 {
-	struct snd_soc_dai *codec_dai = card->rtd[1].codec_dai;
+	struct snd_soc_pcm_runtime *rtd;
+	struct snd_soc_dai *codec_dai;
 	int ret;
 
+	rtd = snd_soc_get_pcm_runtime(card, card->dai_link[1].name);
+	codec_dai = rtd->codec_dai;
+
 	if (dapm->dev != codec_dai->dev)
 		return 0;
 
@@ -57,9 +61,13 @@ static int speyside_set_bias_level_post(struct snd_soc_card *card,
 					struct snd_soc_dapm_context *dapm,
 					enum snd_soc_bias_level level)
 {
-	struct snd_soc_dai *codec_dai = card->rtd[1].codec_dai;
+	struct snd_soc_pcm_runtime *rtd;
+	struct snd_soc_dai *codec_dai;
 	int ret;
 
+	rtd = snd_soc_get_pcm_runtime(card, card->dai_link[1].name);
+	codec_dai = rtd->codec_dai;
+
 	if (dapm->dev != codec_dai->dev)
 		return 0;
 
sound/soc/samsung/tobermory.c +17 -4
index 85ccfb7..3310eda 100644
@@ -23,9 +23,13 @@ static int tobermory_set_bias_level(struct snd_soc_card *card,
 					  struct snd_soc_dapm_context *dapm,
 					  enum snd_soc_bias_level level)
 {
-	struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
+	struct snd_soc_pcm_runtime *rtd;
+	struct snd_soc_dai *codec_dai;
 	int ret;
 
+	rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
+	codec_dai = rtd->codec_dai;
+
 	if (dapm->dev != codec_dai->dev)
 		return 0;
 
@@ -62,9 +66,13 @@ static int tobermory_set_bias_level_post(struct snd_soc_card *card,
 					       struct snd_soc_dapm_context *dapm,
 					       enum snd_soc_bias_level level)
 {
-	struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
+	struct snd_soc_pcm_runtime *rtd;
+	struct snd_soc_dai *codec_dai;
 	int ret;
 
+	rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
+	codec_dai = rtd->codec_dai;
+
 	if (dapm->dev != codec_dai->dev)
 		return 0;
 
@@ -170,10 +178,15 @@ static struct snd_soc_jack_pin tobermory_headset_pins[] = {
 
 static int tobermory_late_probe(struct snd_soc_card *card)
 {
-	struct snd_soc_codec *codec = card->rtd[0].codec;
-	struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
+	struct snd_soc_pcm_runtime *rtd;
+	struct snd_soc_codec *codec;
+	struct snd_soc_dai *codec_dai;
 	int ret;
 
+	rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
+	codec = rtd->codec;
+	codec_dai = rtd->codec_dai;
+
 	ret = snd_soc_dai_set_sysclk(codec_dai, WM8962_SYSCLK_MCLK,
 				     32768, SND_SOC_CLOCK_IN);
 	if (ret < 0)
sound/soc/tegra/tegra_wm8903.c +2 -1
index 2160400..e485278 100644
@@ -199,7 +199,8 @@ static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd)
 
 static int tegra_wm8903_remove(struct snd_soc_card *card)
 {
-	struct snd_soc_pcm_runtime *rtd = &(card->rtd[0]);
+	struct snd_soc_pcm_runtime *rtd =
+		snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
 	struct snd_soc_dai *codec_dai = rtd->codec_dai;
 	struct snd_soc_codec *codec = codec_dai->codec;
 	struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card);
Signature · 1 line
1.9.1
#2 lore raw

PATCH v2 2/13 ASoC: Change the PCM runtime array to a list

In reply to [email protected]

From: Mengdong Lin <[email protected]>

Currently the number of DAI links is statically defined by the machine driver at build time using an array. This makes it difficult to shrink/ grow the number of DAI links at runtime in order to reflect any changes in topology.

We can change the DAI link array in the core to a list so that PCMs and FE DAI links can be added and deleted at runtime to reflect changes in use case and DSP topology. The machine driver can still register DAI links as an array.

As the 1st step, this patch change the PCM runtime array to a list. A new PCM runtime is added to the list when a DAI link is bound successfully.

Later patches will further implement the DAI link list.

More:
- define snd_soc_new/free_pcm_runtime() to create/free a runtime.
- define soc_add_pcm_runtime() to add a runtime to the rtd list.
- define soc_remove_pcm_runtimes() to clean up the runtime list.

- traverse the rtd list to probe the link components and dais.

- Add a field "num" to PCM runtime struct, used to specify the device number when creating the pcm device, and for a soc card to access its dai_props array.

- The following 3rd party machine/platform drivers iterate the rtd list to check the runtimes:
sound/soc/intel/atom/sst-mfld-platform-pcm.c sound/soc/intel/boards/cht_bsw_rt5645.c sound/soc/intel/boards/cht_bsw_rt5672.c sound/soc/intel/boards/cht_bsw_max98090_ti.c

include/sound/soc.h +4 -1
index a8b4b9c..232b30d 100644
@@ -1106,7 +1106,7 @@ struct snd_soc_card {
 	/* CPU <--> Codec DAI links  */
 	struct snd_soc_dai_link *dai_link;
 	int num_links;
-	struct snd_soc_pcm_runtime *rtd;
+	struct list_head rtd_list;
 	int num_rtd;
 
 	/* optional codec specific configuration */
@@ -1201,6 +1201,9 @@ struct snd_soc_pcm_runtime {
 	struct dentry *debugfs_dpcm_root;
 	struct dentry *debugfs_dpcm_state;
 #endif
+
+	unsigned int num; /* 0-based and monotonic increasing */
+	struct list_head list; /* rtd list of the soc card */
 };
 
 /* mixer control */
sound/soc/generic/simple-card.c +5 -7
index 54c3320..1ded881 100644
@@ -45,7 +45,7 @@ static int asoc_simple_card_startup(struct snd_pcm_substream *substream)
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct simple_card_data *priv =	snd_soc_card_get_drvdata(rtd->card);
 	struct simple_dai_props *dai_props =
-		&priv->dai_props[rtd - rtd->card->rtd];
+		&priv->dai_props[rtd->num];
 	int ret;
 
 	ret = clk_prepare_enable(dai_props->cpu_dai.clk);
@@ -64,7 +64,7 @@ static void asoc_simple_card_shutdown(struct snd_pcm_substream *substream)
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct simple_card_data *priv =	snd_soc_card_get_drvdata(rtd->card);
 	struct simple_dai_props *dai_props =
-		&priv->dai_props[rtd - rtd->card->rtd];
+		&priv->dai_props[rtd->num];
 
 	clk_disable_unprepare(dai_props->cpu_dai.clk);
 
@@ -78,8 +78,7 @@ static int asoc_simple_card_hw_params(struct snd_pcm_substream *substream,
 	struct snd_soc_dai *codec_dai = rtd->codec_dai;
 	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
 	struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
-	struct simple_dai_props *dai_props =
-		&priv->dai_props[rtd - rtd->card->rtd];
+	struct simple_dai_props *dai_props = &priv->dai_props[rtd->num];
 	unsigned int mclk, mclk_fs = 0;
 	int ret = 0;
 
@@ -174,10 +173,9 @@ static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd)
 	struct snd_soc_dai *codec = rtd->codec_dai;
 	struct snd_soc_dai *cpu = rtd->cpu_dai;
 	struct simple_dai_props *dai_props;
-	int num, ret;
+	int ret;
 
-	num = rtd - rtd->card->rtd;
-	dai_props = &priv->dai_props[num];
+	dai_props = &priv->dai_props[rtd->num];
 	ret = __asoc_simple_card_dai_init(codec, &dai_props->codec_dai);
 	if (ret < 0)
 		return ret;
sound/soc/intel/atom/sst-mfld-platform-pcm.c +6 -6
index 0487cfa..8e475e8 100644
@@ -760,15 +760,15 @@ static int sst_platform_remove(struct platform_device *pdev)
 static int sst_soc_prepare(struct device *dev)
 {
 	struct sst_data *drv = dev_get_drvdata(dev);
-	int i;
+	struct snd_soc_pcm_runtime *rtd;
 
 	/* suspend all pcms first */
 	snd_soc_suspend(drv->soc_card->dev);
 	snd_soc_poweroff(drv->soc_card->dev);
 
 	/* set the SSPs to idle */
-	for (i = 0; i < drv->soc_card->num_rtd; i++) {
-		struct snd_soc_dai *dai = drv->soc_card->rtd[i].cpu_dai;
+	list_for_each_entry(rtd, &drv->soc_card->rtd_list, list) {
+		struct snd_soc_dai *dai = rtd->cpu_dai;
 
 		if (dai->active) {
 			send_ssp_cmd(dai, dai->name, 0);
@@ -782,11 +782,11 @@ static int sst_soc_prepare(struct device *dev)
 static void sst_soc_complete(struct device *dev)
 {
 	struct sst_data *drv = dev_get_drvdata(dev);
-	int i;
+	struct snd_soc_pcm_runtime *rtd;
 
 	/* restart SSPs */
-	for (i = 0; i < drv->soc_card->num_rtd; i++) {
-		struct snd_soc_dai *dai = drv->soc_card->rtd[i].cpu_dai;
+	list_for_each_entry(rtd, &drv->soc_card->rtd_list, list) {
+		struct snd_soc_dai *dai = rtd->cpu_dai;
 
 		if (dai->active) {
 			sst_handle_vb_timer(dai, true);
sound/soc/intel/boards/cht_bsw_max98090_ti.c +2 -5
index 49f4869..21ae614 100644
@@ -41,12 +41,9 @@ struct cht_mc_private {
 
 static inline struct snd_soc_dai *cht_get_codec_dai(struct snd_soc_card *card)
 {
-	int i;
+	struct snd_soc_pcm_runtime *rtd;
 
-	for (i = 0; i < card->num_rtd; i++) {
-		struct snd_soc_pcm_runtime *rtd;
-
-		rtd = card->rtd + i;
+	list_for_each_entry(rtd, &card->rtd_list, list) {
 		if (!strncmp(rtd->codec_dai->name, CHT_CODEC_DAI,
 			     strlen(CHT_CODEC_DAI)))
 			return rtd->codec_dai;
sound/soc/intel/boards/cht_bsw_rt5645.c +2 -5
index 7be8461..5184e94 100644
@@ -47,12 +47,9 @@ struct cht_mc_private {
 
 static inline struct snd_soc_dai *cht_get_codec_dai(struct snd_soc_card *card)
 {
-	int i;
-
-	for (i = 0; i < card->num_rtd; i++) {
-		struct snd_soc_pcm_runtime *rtd;
+	struct snd_soc_pcm_runtime *rtd;
 
-		rtd = card->rtd + i;
+	list_for_each_entry(rtd, &card->rtd_list, list) {
 		if (!strncmp(rtd->codec_dai->name, CHT_CODEC_DAI,
 			     strlen(CHT_CODEC_DAI)))
 			return rtd->codec_dai;
sound/soc/intel/boards/cht_bsw_rt5672.c +2 -5
index 23fe040..b0154b8 100644
@@ -46,12 +46,9 @@ static struct snd_soc_jack_pin cht_bsw_headset_pins[] = {
 
 static inline struct snd_soc_dai *cht_get_codec_dai(struct snd_soc_card *card)
 {
-	int i;
+	struct snd_soc_pcm_runtime *rtd;
 
-	for (i = 0; i < card->num_rtd; i++) {
-		struct snd_soc_pcm_runtime *rtd;
-
-		rtd = card->rtd + i;
+	list_for_each_entry(rtd, &card->rtd_list, list) {
 		if (!strncmp(rtd->codec_dai->name, CHT_CODEC_DAI,
 			     strlen(CHT_CODEC_DAI)))
 			return rtd->codec_dai;
sound/soc/sh/rcar/core.c +1 -1
index deed48e..8c4f54b 100644
@@ -1040,7 +1040,7 @@ static int __rsnd_kctrl_new(struct rsnd_mod *mod,
 		.iface		= SNDRV_CTL_ELEM_IFACE_MIXER,
 		.name		= name,
 		.info		= rsnd_kctrl_info,
-		.index		= rtd - soc_card->rtd,
+		.index		= rtd->num,
 		.get		= rsnd_kctrl_get,
 		.put		= rsnd_kctrl_put,
 		.private_value	= (unsigned long)cfg,
sound/soc/sh/rcar/rsrc-card.c +3 -3
index d61db9c..94d23d8 100644
@@ -75,7 +75,7 @@ static int rsrc_card_startup(struct snd_pcm_substream *substream)
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct rsrc_card_priv *priv =	snd_soc_card_get_drvdata(rtd->card);
 	struct rsrc_card_dai *dai_props =
-		rsrc_priv_to_props(priv, rtd - rtd->card->rtd);
+		rsrc_priv_to_props(priv, rtd->num);
 
 	return clk_prepare_enable(dai_props->clk);
 }
@@ -85,7 +85,7 @@ static void rsrc_card_shutdown(struct snd_pcm_substream *substream)
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct rsrc_card_priv *priv =	snd_soc_card_get_drvdata(rtd->card);
 	struct rsrc_card_dai *dai_props =
-		rsrc_priv_to_props(priv, rtd - rtd->card->rtd);
+		rsrc_priv_to_props(priv, rtd->num);
 
 	clk_disable_unprepare(dai_props->clk);
 }
@@ -101,7 +101,7 @@ static int rsrc_card_dai_init(struct snd_soc_pcm_runtime *rtd)
 	struct snd_soc_dai *dai;
 	struct snd_soc_dai_link *dai_link;
 	struct rsrc_card_dai *dai_props;
-	int num = rtd - rtd->card->rtd;
+	int num = rtd->num;
 	int ret;
 
 	dai_link	= rsrc_priv_to_link(priv, num);
sound/soc/soc-core.c +154 -109

565 lines not on this page · raw message

sound/soc/soc-dapm.c +2 -5
index 016eba1..3eba72c 100644
@@ -3893,13 +3893,10 @@ static void soc_dapm_dai_stream_event(struct snd_soc_dai *dai, int stream,
 
 void snd_soc_dapm_connect_dai_link_widgets(struct snd_soc_card *card)
 {
-	struct snd_soc_pcm_runtime *rtd = card->rtd;
-	int i;
+	struct snd_soc_pcm_runtime *rtd;
 
 	/* for each BE DAI link... */
-	for (i = 0; i < card->num_rtd; i++) {
-		rtd = &card->rtd[i];
-
+	list_for_each_entry(rtd, &card->rtd_list, list)  {
 		/*
 		 * dynamic FE links have no fixed DAI mapping.
 		 * CODEC<->CODEC links have no direct connection.
sound/soc/soc-pcm.c +10 -12
index 3173958..bfef69b 100644
@@ -1215,11 +1215,10 @@ static struct snd_soc_pcm_runtime *dpcm_get_be(struct snd_soc_card *card,
 		struct snd_soc_dapm_widget *widget, int stream)
 {
 	struct snd_soc_pcm_runtime *be;
-	int i, j;
+	int i;
 
 	if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
-		for (i = 0; i < card->num_links; i++) {
-			be = &card->rtd[i];
+		list_for_each_entry(be, &card->rtd_list, list) {
 
 			if (!be->dai_link->no_pcm)
 				continue;
@@ -1227,16 +1226,15 @@ static struct snd_soc_pcm_runtime *dpcm_get_be(struct snd_soc_card *card,
 			if (be->cpu_dai->playback_widget == widget)
 				return be;
 
-			for (j = 0; j < be->num_codecs; j++) {
-				struct snd_soc_dai *dai = be->codec_dais[j];
+			for (i = 0; i < be->num_codecs; i++) {
+				struct snd_soc_dai *dai = be->codec_dais[i];
 				if (dai->playback_widget == widget)
 					return be;
 			}
 		}
 	} else {
 
-		for (i = 0; i < card->num_links; i++) {
-			be = &card->rtd[i];
+		list_for_each_entry(be, &card->rtd_list, list) {
 
 			if (!be->dai_link->no_pcm)
 				continue;
@@ -1244,8 +1242,8 @@ static struct snd_soc_pcm_runtime *dpcm_get_be(struct snd_soc_card *card,
 			if (be->cpu_dai->capture_widget == widget)
 				return be;
 
-			for (j = 0; j < be->num_codecs; j++) {
-				struct snd_soc_dai *dai = be->codec_dais[j];
+			for (i = 0; i < be->num_codecs; i++) {
+				struct snd_soc_dai *dai = be->codec_dais[i];
 				if (dai->capture_widget == widget)
 					return be;
 			}
@@ -2345,12 +2343,12 @@ static int dpcm_run_old_update(struct snd_soc_pcm_runtime *fe, int stream)
  */
 int soc_dpcm_runtime_update(struct snd_soc_card *card)
 {
-	int i, old, new, paths;
+	struct snd_soc_pcm_runtime *fe;
+	int old, new, paths;
 
 	mutex_lock_nested(&card->mutex, SND_SOC_CARD_CLASS_RUNTIME);
-	for (i = 0; i < card->num_rtd; i++) {
+	list_for_each_entry(fe, &card->rtd_list, list) {
 		struct snd_soc_dapm_widget_list *list;
-		struct snd_soc_pcm_runtime *fe = &card->rtd[i];
 
 		/* make sure link is FE */
 		if (!fe->dai_link->dynamic)
Signature · 1 line
1.9.1
#3 lore raw

PATCH v2 3/13 ASoC: Define soc_init_dai_link() to wrap link intialization.

In reply to [email protected]

From: Mengdong Lin <[email protected]>

Define soc_init_dai_link() to wrap link initialization, to reuse it later by snd_soc_instantiate_card() when adding new DAI links from topology in component probing phase.

Move static func snd_soc_init_multicodec(), so that it can be reused by soc_init_dai_link(). This saves adding a function declaration for snd_soc_init_multicodec().

sound/soc/soc-core.c +98 -83
index 2c95de7..2ecd094 100644
@@ -1134,6 +1134,100 @@ static void soc_remove_dai_links(struct snd_soc_card *card)
 	}
 }
 
+static int snd_soc_init_multicodec(struct snd_soc_card *card,
+				   struct snd_soc_dai_link *dai_link)
+{
+	/* Legacy codec/codec_dai link is a single entry in multicodec */
+	if (dai_link->codec_name || dai_link->codec_of_node ||
+	    dai_link->codec_dai_name) {
+		dai_link->num_codecs = 1;
+
+		dai_link->codecs = devm_kzalloc(card->dev,
+				sizeof(struct snd_soc_dai_link_component),
+				GFP_KERNEL);
+		if (!dai_link->codecs)
+			return -ENOMEM;
+
+		dai_link->codecs[0].name = dai_link->codec_name;
+		dai_link->codecs[0].of_node = dai_link->codec_of_node;
+		dai_link->codecs[0].dai_name = dai_link->codec_dai_name;
+	}
+
+	if (!dai_link->codecs) {
+		dev_err(card->dev, "ASoC: DAI link has no CODECs\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static int soc_init_dai_link(struct snd_soc_card *card,
+				   struct snd_soc_dai_link *link)
+{
+	int i, ret;
+
+	ret = snd_soc_init_multicodec(card, link);
+	if (ret) {
+		dev_err(card->dev, "ASoC: failed to init multicodec\n");
+		return ret;
+	}
+
+	for (i = 0; i < link->num_codecs; i++) {
+		/*
+		 * Codec must be specified by 1 of name or OF node,
+		 * not both or neither.
+		 */
+		if (!!link->codecs[i].name ==
+		    !!link->codecs[i].of_node) {
+			dev_err(card->dev, "ASoC: Neither/both codec name/of_node are set for %s\n",
+				link->name);
+			return -EINVAL;
+		}
+		/* Codec DAI name must be specified */
+		if (!link->codecs[i].dai_name) {
+			dev_err(card->dev, "ASoC: codec_dai_name not set for %s\n",
+				link->name);
+			return -EINVAL;
+		}
+	}
+
+	/*
+	 * Platform may be specified by either name or OF node, but
+	 * can be left unspecified, and a dummy platform will be used.
+	 */
+	if (link->platform_name && link->platform_of_node) {
+		dev_err(card->dev,
+			"ASoC: Both platform name/of_node are set for %s\n",
+			link->name);
+		return -EINVAL;
+	}
+
+	/*
+	 * CPU device may be specified by either name or OF node, but
+	 * can be left unspecified, and will be matched based on DAI
+	 * name alone..
+	 */
+	if (link->cpu_name && link->cpu_of_node) {
+		dev_err(card->dev,
+			"ASoC: Neither/both cpu name/of_node are set for %s\n",
+			link->name);
+		return -EINVAL;
+	}
+	/*
+	 * At least one of CPU DAI name or CPU device name/node must be
+	 * specified
+	 */
+	if (!link->cpu_dai_name &&
+	    !(link->cpu_name || link->cpu_of_node)) {
+		dev_err(card->dev,
+			"ASoC: Neither cpu_dai_name nor cpu_name/of_node are set for %s\n",
+			link->name);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 static void soc_set_name_prefix(struct snd_soc_card *card,
 				struct snd_soc_component *component)
 {
@@ -2356,33 +2450,6 @@ int snd_soc_dai_digital_mute(struct snd_soc_dai *dai, int mute,
 }
 EXPORT_SYMBOL_GPL(snd_soc_dai_digital_mute);
 
-static int snd_soc_init_multicodec(struct snd_soc_card *card,
-				   struct snd_soc_dai_link *dai_link)
-{
-	/* Legacy codec/codec_dai link is a single entry in multicodec */
-	if (dai_link->codec_name || dai_link->codec_of_node ||
-	    dai_link->codec_dai_name) {
-		dai_link->num_codecs = 1;
-
-		dai_link->codecs = devm_kzalloc(card->dev,
-				sizeof(struct snd_soc_dai_link_component),
-				GFP_KERNEL);
-		if (!dai_link->codecs)
-			return -ENOMEM;
-
-		dai_link->codecs[0].name = dai_link->codec_name;
-		dai_link->codecs[0].of_node = dai_link->codec_of_node;
-		dai_link->codecs[0].dai_name = dai_link->codec_dai_name;
-	}
-
-	if (!dai_link->codecs) {
-		dev_err(card->dev, "ASoC: DAI link has no CODECs\n");
-		return -EINVAL;
-	}
-
-	return 0;
-}
-
 /**
  * snd_soc_register_card - Register a card with the ASoC core
  *
@@ -2391,7 +2458,7 @@ static int snd_soc_init_multicodec(struct snd_soc_card *card,
  */
 int snd_soc_register_card(struct snd_soc_card *card)
 {
-	int i, j, ret;
+	int i, ret;
 	struct snd_soc_pcm_runtime *rtd;
 
 	if (!card->name || !card->dev)
@@ -2400,63 +2467,11 @@ int snd_soc_register_card(struct snd_soc_card *card)
 	for (i = 0; i < card->num_links; i++) {
 		struct snd_soc_dai_link *link = &card->dai_link[i];
 
-		ret = snd_soc_init_multicodec(card, link);
+		ret = soc_init_dai_link(card, link);
 		if (ret) {
-			dev_err(card->dev, "ASoC: failed to init multicodec\n");
-			return ret;
-		}
-
-		for (j = 0; j < link->num_codecs; j++) {
-			/*
-			 * Codec must be specified by 1 of name or OF node,
-			 * not both or neither.
-			 */
-			if (!!link->codecs[j].name ==
-			    !!link->codecs[j].of_node) {
-				dev_err(card->dev, "ASoC: Neither/both codec name/of_node are set for %s\n",
-					link->name);
-				return -EINVAL;
-			}
-			/* Codec DAI name must be specified */
-			if (!link->codecs[j].dai_name) {
-				dev_err(card->dev, "ASoC: codec_dai_name not set for %s\n",
-					link->name);
-				return -EINVAL;
-			}
-		}
-
-		/*
-		 * Platform may be specified by either name or OF node, but
-		 * can be left unspecified, and a dummy platform will be used.
-		 */
-		if (link->platform_name && link->platform_of_node) {
-			dev_err(card->dev,
-				"ASoC: Both platform name/of_node are set for %s\n",
+			dev_err(card->dev, "ASoC: failed to init link %s\n",
 				link->name);
-			return -EINVAL;
-		}
-
-		/*
-		 * CPU device may be specified by either name or OF node, but
-		 * can be left unspecified, and will be matched based on DAI
-		 * name alone..
-		 */
-		if (link->cpu_name && link->cpu_of_node) {
-			dev_err(card->dev,
-				"ASoC: Neither/both cpu name/of_node are set for %s\n",
-				link->name);
-			return -EINVAL;
-		}
-		/*
-		 * At least one of CPU DAI name or CPU device name/node must be
-		 * specified
-		 */
-		if (!link->cpu_dai_name &&
-		    !(link->cpu_name || link->cpu_of_node)) {
-			dev_err(card->dev,
-				"ASoC: Neither cpu_dai_name nor cpu_name/of_node are set for %s\n",
-				link->name);
-			return -EINVAL;
+			return ret;
 		}
 	}
 
Signature · 1 line
1.9.1
#4 lore raw

PATCH v2 4/13 ASoC: Change 2nd argument of soc_bind_dai_link() to DAI link pointer

In reply to [email protected]

From: Mengdong Lin <[email protected]>

Just code refactoring, to reuse it if new DAI Links are added later based on topology in component probing phase.

sound/soc/soc-core.c +4 -4
index 2ecd094..878a9fe 100644
@@ -960,9 +960,9 @@ static struct snd_soc_dai *snd_soc_find_dai(
 	return NULL;
 }
 
-static int soc_bind_dai_link(struct snd_soc_card *card, int num)
+static int soc_bind_dai_link(struct snd_soc_card *card,
+	struct snd_soc_dai_link *dai_link)
 {
-	struct snd_soc_dai_link *dai_link = &card->dai_link[num];
 	struct snd_soc_pcm_runtime *rtd;
 	struct snd_soc_dai_link_component *codecs = dai_link->codecs;
 	struct snd_soc_dai_link_component cpu_dai_component;
@@ -971,7 +971,7 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num)
 	const char *platform_name;
 	int i;
 
-	dev_dbg(card->dev, "ASoC: binding %s at idx %d\n", dai_link->name, num);
+	dev_dbg(card->dev, "ASoC: binding %s\n", dai_link->name);
 
 	rtd = soc_new_pcm_runtime(card, dai_link);
 	if (!rtd)
@@ -1710,7 +1710,7 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
 
 	/* bind DAIs */
 	for (i = 0; i < card->num_links; i++) {
-		ret = soc_bind_dai_link(card, i);
+		ret = soc_bind_dai_link(card, &card->dai_link[i]);
 		if (ret != 0)
 			goto base_error;
 	}
Signature · 1 line
1.9.1
maintainer
#5 lore raw

Applied "ASoC: Change 2nd argument of soc_bind_dai_link() to DAI link pointer" to the asoc tree

The patch

ASoC: Change 2nd argument of soc_bind_dai_link() to DAI link pointer

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 6f2f1ff0de83ad69f5a823ae77d1e0f77cc75d45 Mon Sep 17 00:00:00 2001

From: Mengdong Lin <[email protected]>
Date: Mon, 23 Nov 2015 11:03:52 -0500
Subject: [PATCH] ASoC: Change 2nd argument of soc_bind_dai_link() to DAI link
pointer

Just code refactoring, to reuse it if new DAI Links are added later based on topology in component probing phase.

---
 sound/soc/soc-core.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
sound/soc/soc-core.c +4 -4
index 2ecd09475d88..878a9fe92686 100644
@@ -960,9 +960,9 @@ static struct snd_soc_dai *snd_soc_find_dai(
 	return NULL;
 }
 
-static int soc_bind_dai_link(struct snd_soc_card *card, int num)
+static int soc_bind_dai_link(struct snd_soc_card *card,
+	struct snd_soc_dai_link *dai_link)
 {
-	struct snd_soc_dai_link *dai_link = &card->dai_link[num];
 	struct snd_soc_pcm_runtime *rtd;
 	struct snd_soc_dai_link_component *codecs = dai_link->codecs;
 	struct snd_soc_dai_link_component cpu_dai_component;
@@ -971,7 +971,7 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num)
 	const char *platform_name;
 	int i;
 
-	dev_dbg(card->dev, "ASoC: binding %s at idx %d\n", dai_link->name, num);
+	dev_dbg(card->dev, "ASoC: binding %s\n", dai_link->name);
 
 	rtd = soc_new_pcm_runtime(card, dai_link);
 	if (!rtd)
@@ -1710,7 +1710,7 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
 
 	/* bind DAIs */
 	for (i = 0; i < card->num_links; i++) {
-		ret = soc_bind_dai_link(card, i);
+		ret = soc_bind_dai_link(card, &card->dai_link[i]);
 		if (ret != 0)
 			goto base_error;
 	}
Signature · 1 line
2.6.2
#6 lore raw

PATCH v2 5/13 ASoC: Implement DAI links in a list & define API to add a link

In reply to [email protected]

From: Mengdong Lin <[email protected]>

Implement a dai link list for the soc card.

Add API snd_soc_add_dai_link() to add an DAI links dynamically, e.g. based on topology.

The predefined DAI links are reserved to keep backward compatibility, and they will also be added to the list.

Open:
No API to remove a DAI link from the list, because there is no request from topology atm. When machine driver is removed, the dynamically added links need to be removed and freed. Need a clear working flow.

include/sound/soc.h +10 -2
index 232b30d..60e5fda 100644
@@ -1037,6 +1037,8 @@ struct snd_soc_dai_link {
 
 	/* pmdown_time is ignored at stop */
 	unsigned int ignore_pmdown_time:1;
+
+	struct list_head list; /* dai link list of the soc card */
 };
 
 struct snd_soc_codec_conf {
@@ -1104,8 +1106,11 @@ struct snd_soc_card {
 	long pmdown_time;
 
 	/* CPU <--> Codec DAI links  */
-	struct snd_soc_dai_link *dai_link;
-	int num_links;
+	struct snd_soc_dai_link *dai_link;  /* predefined links only */
+	int num_links;  /* predefined links only */
+	struct list_head dai_link_list; /* all links */
+	int num_dai_links;
+
 	struct list_head rtd_list;
 	int num_rtd;
 
@@ -1647,6 +1652,9 @@ int snd_soc_of_get_dai_link_codecs(struct device *dev,
 				   struct device_node *of_node,
 				   struct snd_soc_dai_link *dai_link);
 
+void snd_soc_add_dai_link(struct snd_soc_card *card,
+				struct snd_soc_dai_link *dai_link);
+
 #include <sound/soc-dai.h>
 
 #ifdef CONFIG_DEBUG_FS
sound/soc/soc-core.c +28 -0
index 878a9fe..c855e30 100644
@@ -1228,6 +1228,27 @@ static int soc_init_dai_link(struct snd_soc_card *card,
 	return 0;
 }
 
+/**
+ * snd_soc_add_dai_link - Add a DAI link dynamically
+ * @card: The ASoC card to which the DAI link is added
+ * @dai_link: The new DAI link to add
+ *
+ * This function adds a DAI link to the ASoC card, and creates a ASoC
+ * runtime for the link.
+ *
+ * Note: For adding DAI links dynamically by machine drivers based on
+ * the topology info when probing the platform component. And machine
+ * drivers can still define static DAI links in dai_link array.
+ */
+void snd_soc_add_dai_link(struct snd_soc_card *card,
+		struct snd_soc_dai_link *dai_link)
+{
+	lockdep_assert_held(&client_mutex);
+	list_add_tail(&dai_link->list, &card->dai_link_list);
+	card->num_dai_links++;
+}
+EXPORT_SYMBOL_GPL(snd_soc_add_dai_link);
+
 static void soc_set_name_prefix(struct snd_soc_card *card,
 				struct snd_soc_component *component)
 {
@@ -1722,6 +1743,10 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
 			goto base_error;
 	}
 
+	/* add predefined DAI links to the list */
+	for (i = 0; i < card->num_links; i++)
+		snd_soc_add_dai_link(card, card->dai_link+i);
+
 	/* initialize the register cache for each available codec */
 	list_for_each_entry(codec, &codec_list, list) {
 		if (codec->cache_init)
@@ -2479,6 +2504,9 @@ int snd_soc_register_card(struct snd_soc_card *card)
 
 	snd_soc_initialize_card_lists(card);
 
+	INIT_LIST_HEAD(&card->dai_link_list);
+	card->num_dai_links = 0;
+
 	INIT_LIST_HEAD(&card->rtd_list);
 	card->num_rtd = 0;
 
Signature · 1 line
1.9.1
#7 lore raw

PATCH v2 6/13 ASoC: Add add_dai_link ops for a soc card

In reply to [email protected]

From: Mengdong Lin <[email protected]>

When a new DAI link is added, the ASoC core will call this ops to notify a machine driver for extra intialization.

include/sound/soc.h +3 -0
index 60e5fda..9a0e0e8 100644
@@ -1103,6 +1103,9 @@ struct snd_soc_card {
 				   struct snd_soc_dapm_context *dapm,
 				   enum snd_soc_bias_level level);
 
+	int (*add_dai_link)(struct snd_soc_card *,
+			    struct snd_soc_dai_link *link);
+
 	long pmdown_time;
 
 	/* CPU <--> Codec DAI links  */
sound/soc/soc-core.c +4 -0
index c855e30..24e0c50 100644
@@ -1243,6 +1243,10 @@ static int soc_init_dai_link(struct snd_soc_card *card,
 void snd_soc_add_dai_link(struct snd_soc_card *card,
 		struct snd_soc_dai_link *dai_link)
 {
+	/* Notify the machine driver for extra initialization. */
+	if (card && card->add_dai_link)
+		card->add_dai_link(card, dai_link);
+
 	lockdep_assert_held(&client_mutex);
 	list_add_tail(&dai_link->list, &card->dai_link_list);
 	card->num_dai_links++;
Signature · 1 line
1.9.1
#8 lore raw

PATCH v2 7/13 ASoC: soc_bind_dai_link() directly returns success for a bound DAI link

In reply to [email protected]

From: Mengdong Lin <[email protected]>

This function will return success immediately for a bound DAI link. No need to look for the cpu/codec DAIs again.

sound/soc/soc-core.c +19 -0
index 24e0c50..86c3219 100644
@@ -960,6 +960,19 @@ static struct snd_soc_dai *snd_soc_find_dai(
 	return NULL;
 }
 
+static bool soc_is_dai_link_bound(struct snd_soc_card *card,
+		struct snd_soc_dai_link *dai_link)
+{
+	struct snd_soc_pcm_runtime *rtd;
+
+	list_for_each_entry(rtd, &card->rtd_list, list) {
+		if (rtd->dai_link == dai_link)
+			return true;
+	}
+
+	return false;
+}
+
 static int soc_bind_dai_link(struct snd_soc_card *card,
 	struct snd_soc_dai_link *dai_link)
 {
@@ -977,6 +990,12 @@ static int soc_bind_dai_link(struct snd_soc_card *card,
 	if (!rtd)
 		return -ENOMEM;
 
+	if (soc_is_dai_link_bound(card, dai_link)) {
+		dev_dbg(card->dev, "ASoC: dai link %s already bound\n",
+			dai_link->name);
+		return 0;
+	}
+
 	cpu_dai_component.name = dai_link->cpu_name;
 	cpu_dai_component.of_node = dai_link->cpu_of_node;
 	cpu_dai_component.dai_name = dai_link->cpu_dai_name;
Signature · 1 line
1.9.1
maintainer
#9 lore raw

Applied "ASoC: soc_bind_dai_link() directly returns success for a bound DAI link" to the asoc tree

The patch

ASoC: soc_bind_dai_link() directly returns success for a bound DAI link

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 49a5ba1cd9da4fb04e7ce1e0d94f6a5a9b7be48e Mon Sep 17 00:00:00 2001

From: Mengdong Lin <[email protected]>
Date: Wed, 2 Dec 2015 14:11:40 +0800
Subject: [PATCH] ASoC: soc_bind_dai_link() directly returns success for a
bound DAI link

This function will return success immediately for a bound DAI link. No need to look for the cpu/codec DAIs again.

---
 sound/soc/soc-core.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)
sound/soc/soc-core.c +19 -0
index 094856fa8cec..11d073b6ce33 100644
@@ -960,6 +960,19 @@ static struct snd_soc_dai *snd_soc_find_dai(
 	return NULL;
 }
 
+static bool soc_is_dai_link_bound(struct snd_soc_card *card,
+		struct snd_soc_dai_link *dai_link)
+{
+	struct snd_soc_pcm_runtime *rtd;
+
+	list_for_each_entry(rtd, &card->rtd_list, list) {
+		if (rtd->dai_link == dai_link)
+			return true;
+	}
+
+	return false;
+}
+
 static int soc_bind_dai_link(struct snd_soc_card *card,
 	struct snd_soc_dai_link *dai_link)
 {
@@ -977,6 +990,12 @@ static int soc_bind_dai_link(struct snd_soc_card *card,
 	if (!rtd)
 		return -ENOMEM;
 
+	if (soc_is_dai_link_bound(card, dai_link)) {
+		dev_dbg(card->dev, "ASoC: dai link %s already bound\n",
+			dai_link->name);
+		return 0;
+	}
+
 	cpu_dai_component.name = dai_link->cpu_name;
 	cpu_dai_component.of_node = dai_link->cpu_of_node;
 	cpu_dai_component.dai_name = dai_link->cpu_dai_name;
Signature · 1 line
2.6.2
#10 lore raw

PATCH v2 8/13 ASoC: Bind new DAI links after probing components

In reply to [email protected]

From: Mengdong Lin <[email protected]>

Probing components can bring new DAI or DAI links based on the topology info. This patch finds the unbound DAI links and bind them.

sound/soc/soc-core.c +16 -0
index 86c3219..cb49a31 100644
@@ -1747,6 +1747,7 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
 {
 	struct snd_soc_codec *codec;
 	struct snd_soc_pcm_runtime *rtd;
+	struct snd_soc_dai_link *dai_link;
 	int ret, i, order;
 
 	mutex_lock(&client_mutex);
@@ -1834,6 +1835,21 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
 		}
 	}
 
+	/* Find new DAI links added during probing components and bind them.
+	 * Components with topology may bring new DAIs and DAI links.
+	 */
+	list_for_each_entry(dai_link, &card->dai_link_list, list) {
+		if (soc_is_dai_link_bound(card, dai_link))
+			continue;
+
+		ret = soc_init_dai_link(card, dai_link);
+		if (ret)
+			goto probe_dai_err;
+		ret = soc_bind_dai_link(card, dai_link);
+		if (ret)
+			goto probe_dai_err;
+	}
+
 	/* probe all DAI links on this card */
 	for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST;
 			order++) {
Signature · 1 line
1.9.1
maintainer
#11 lore raw

Applied "ASoC: Bind new DAI links after probing components" to the asoc tree

The patch

ASoC: Bind new DAI links after probing components

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 61b0088b6a5b98608ce00c18a057b1f5bcb5f8b3 Mon Sep 17 00:00:00 2001

From: Mengdong Lin <[email protected]>
Date: Wed, 2 Dec 2015 14:11:48 +0800
Subject: [PATCH] ASoC: Bind new DAI links after probing components

Probing components can bring new DAI or DAI links based on the topology info. This patch finds the unbound DAI links and bind them.

---
 sound/soc/soc-core.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)
sound/soc/soc-core.c +16 -0
index 11d073b6ce33..6b1982dcedf1 100644
@@ -1806,6 +1806,7 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
 {
 	struct snd_soc_codec *codec;
 	struct snd_soc_pcm_runtime *rtd;
+	struct snd_soc_dai_link *dai_link;
 	int ret, i, order;
 
 	mutex_lock(&client_mutex);
@@ -1893,6 +1894,21 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
 		}
 	}
 
+	/* Find new DAI links added during probing components and bind them.
+	 * Components with topology may bring new DAIs and DAI links.
+	 */
+	list_for_each_entry(dai_link, &card->dai_link_list, list) {
+		if (soc_is_dai_link_bound(card, dai_link))
+			continue;
+
+		ret = soc_init_dai_link(card, dai_link);
+		if (ret)
+			goto probe_dai_err;
+		ret = soc_bind_dai_link(card, dai_link);
+		if (ret)
+			goto probe_dai_err;
+	}
+
 	/* 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.6.2
#12 lore raw

PATCH v2 9/13 ASoC: The soc card can have auxiliary components

In reply to [email protected]

From: Mengdong Lin <[email protected]>

Machine drivers can set the name of one or more auxiliary components. And the ASoC core will find and probe the auxiliary components.

Machine drivers can use this to specify the components with topology. Then when the components are probed, topology info will be loaded to the core.

include/sound/soc.h +9 -0
index 9a0e0e8..13e1409 100644
@@ -1070,6 +1070,11 @@ struct snd_soc_aux_dev {
 	int (*init)(struct snd_soc_component *component);
 };
 
+struct snd_soc_aux_component {
+	const char *name;
+	struct snd_soc_component *comp;
+};
+
 /* SoC card */
 struct snd_soc_card {
 	const char *name;
@@ -1114,6 +1119,10 @@ struct snd_soc_card {
 	struct list_head dai_link_list; /* all links */
 	int num_dai_links;
 
+	/* auxiliary components, e.g. topology */
+	struct snd_soc_aux_component *aux_components;
+	int num_aux_components;
+
 	struct list_head rtd_list;
 	int num_rtd;
 
sound/soc/soc-core.c +27 -0
index cb49a31..23d067ae 100644
@@ -1767,6 +1767,18 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
 			goto base_error;
 	}
 
+	/* find auxiliary components */
+	for (i = 0; i < card->num_aux_components; i++) {
+		card->aux_components[i].comp =
+			soc_find_component(NULL, card->aux_components[i].name);
+		if (!card->aux_components[i].comp) {
+			dev_err(card->dev, "ASoC: Aux component %s not registered\n",
+				card->aux_components[i].name);
+			ret = -EPROBE_DEFER;
+			goto base_error;
+		}
+	}
+
 	/* add predefined DAI links to the list */
 	for (i = 0; i < card->num_links; i++)
 		snd_soc_add_dai_link(card, card->dai_link+i);
@@ -1821,6 +1833,21 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
 			goto card_probe_error;
 	}
 
+	/* probe auxiliary components */
+	for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST;
+			order++) {
+		for (i = 0; i < card->num_aux_components; i++) {
+			ret = soc_probe_component(card,
+					card->aux_components[i].comp);
+			if (ret < 0) {
+				dev_err(card->dev,
+					"ASoC: failed to probe aux component %s %d\n",
+					card->aux_components[i].name, ret);
+				goto probe_dai_err;
+			}
+		}
+	}
+
 	/* probe all components used by DAI links on this card */
 	for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST;
 			order++) {
Signature · 1 line
1.9.1
#13 lore raw

Re: [PATCH v2 09/13] ASoC: The soc card can have auxiliary components

Quoted 8 lines · On 11/05/2015 10:59 AM, [email protected] wrote:

From: Mengdong Lin <[email protected]>

Machine drivers can set the name of one or more auxiliary components. And the ASoC core will find and probe the auxiliary components.

Machine drivers can use this to specify the components with topology. Then when the components are probed, topology info will be loaded to the core.

How is this different from the existing aux_devs?

#14 lore raw

PATCH v2 10/13 ASoC: Support adding a DAI dynamically

In reply to [email protected]

From: Mengdong Lin <[email protected]>

API snd_soc_add_dai() is defined to register a DAI dynamically and create its DAI widget. This API can be used by the topology core to add DAIs.

include/sound/soc.h +3 -0
index 13e1409..a6e6a1b 100644
@@ -1667,6 +1667,9 @@ int snd_soc_of_get_dai_link_codecs(struct device *dev,
 void snd_soc_add_dai_link(struct snd_soc_card *card,
 				struct snd_soc_dai_link *dai_link);
 
+int snd_soc_add_dai(struct snd_soc_component *component,
+	struct snd_soc_dai_driver *dai_drv);
+
 #include <sound/soc-dai.h>
 
 #ifdef CONFIG_DEBUG_FS
sound/soc/soc-core.c +85 -0

91 lines not on this page · raw message

Signature · 1 line
1.9.1
#15 lore raw

PATCH v2 11/13 ASoC: topology: Add PCM DAIs dynamically when loading them

In reply to [email protected]

From: Mengdong Lin <[email protected]>

Add PCM DAIs to ASoC core when loading them from topology.

More:
1. Embed dobj in the DAI to free it when unloading.
2. Change tplg load ops for DAI:
- only process a DAI
- pass the dai driver pointer to device driver for extra initialization. The device driver can just work on the dai driver object.

include/sound/soc-dai.h +1 -0
index 212eaaf..964b7de 100644
@@ -222,6 +222,7 @@ struct snd_soc_dai_driver {
 	const char *name;
 	unsigned int id;
 	unsigned int base;
+	struct snd_soc_dobj dobj;
 
 	/* DAI driver callbacks */
 	int (*probe)(struct snd_soc_dai *dai);
include/sound/soc-topology.h +4 -11
index ea387ed..b51c207 100644
@@ -56,12 +56,6 @@ struct snd_soc_dobj_widget {
 	unsigned int kcontrol_enum:1;	/* this widget is an enum kcontrol */
 };
 
-/* dynamic PCM DAI object */
-struct snd_soc_dobj_pcm_dai {
-	struct snd_soc_tplg_pcm_dai *pd;
-	unsigned int count;
-};
-
 /* generic dynamic object - all dynamic objects belong to this struct */
 struct snd_soc_dobj {
 	enum snd_soc_dobj_type type;
@@ -71,7 +65,6 @@ struct snd_soc_dobj {
 	union {
 		struct snd_soc_dobj_control control;
 		struct snd_soc_dobj_widget widget;
-		struct snd_soc_dobj_pcm_dai pcm_dai;
 	};
 	void *private; /* core does not touch this */
 };
@@ -124,10 +117,10 @@ struct snd_soc_tplg_ops {
 	int (*widget_unload)(struct snd_soc_component *,
 		struct snd_soc_dobj *);
 
-	/* FE - used for any driver specific init */
-	int (*pcm_dai_load)(struct snd_soc_component *,
-		struct snd_soc_tplg_pcm_dai *pcm_dai, int num_fe);
-	int (*pcm_dai_unload)(struct snd_soc_component *,
+	/* FE DAI - used for any driver specific init */
+	int (*dai_load)(struct snd_soc_component *,
+		struct snd_soc_dai_driver *dai);
+	int (*dai_unload)(struct snd_soc_component *,
 		struct snd_soc_dobj *);
 
 	/* callback to handle vendor bespoke data */
include/sound/soc.h +1 -1
index a6e6a1b..4d07a9e 100644
@@ -27,7 +27,6 @@
 #include <sound/compress_driver.h>
 #include <sound/control.h>
 #include <sound/ac97_codec.h>
-#include <sound/soc-topology.h>
 
 /*
  * Convenience kcontrol builders
@@ -393,6 +392,7 @@ struct snd_soc_jack_zone;
 struct snd_soc_jack_pin;
 #include <sound/soc-dapm.h>
 #include <sound/soc-dpcm.h>
+#include <sound/soc-topology.h>
 
 struct snd_soc_jack_gpio;
 
sound/soc/soc-topology.c +98 -35

180 lines not on this page · raw message

Signature · 1 line
1.9.1
#16 lore raw

PATCH v2 12/13 ASoC: topology: Add support for FE DAI links

In reply to [email protected]

From: Mengdong Lin <[email protected]>

FE DAI links can be created from topology.

And a machine driver can register add_dai_link ops to the soc card, to get notified when a new DAI link is created and bind machine-specific info to the link.

include/sound/soc-topology.h +6 -0
index b51c207..6324537 100644
@@ -123,6 +123,12 @@ struct snd_soc_tplg_ops {
 	int (*dai_unload)(struct snd_soc_component *,
 		struct snd_soc_dobj *);
 
+	/* DAI link - used for any driver specific init */
+	int (*link_load)(struct snd_soc_component *,
+		struct snd_soc_dai_link *link);
+	int (*link_unload)(struct snd_soc_component *,
+		struct snd_soc_dobj *);
+
 	/* callback to handle vendor bespoke data */
 	int (*vendor_load)(struct snd_soc_component *,
 		struct snd_soc_tplg_hdr *);
include/sound/soc.h +1 -0
index 4d07a9e..31fe60a 100644
@@ -1039,6 +1039,7 @@ struct snd_soc_dai_link {
 	unsigned int ignore_pmdown_time:1;
 
 	struct list_head list; /* dai link list of the soc card */
+	struct snd_soc_dobj dobj;
 };
 
 struct snd_soc_codec_conf {
sound/soc/soc-topology.c +47 -1

63 lines not on this page · raw message

Signature · 1 line
1.9.1
#17 lore raw

PATCH v2 13/13 ASoC: topology: Add support for BE and CC DAI Links

In reply to [email protected]

From: Vedang Patel <[email protected]>

Adding support to modify already existing BE and CC DAI Links. The links are matches using unique id (be_id) of the links.

Now, the params member in the snd_soc_dai_link struct will be populated with stream related information.

include/sound/soc-topology.h +1 -0
index 6324537..f37f5d8 100644
@@ -40,6 +40,7 @@ enum snd_soc_dobj_type {
 	SND_SOC_DOBJ_BYTES,
 	SND_SOC_DOBJ_PCM,
 	SND_SOC_DOBJ_DAI_LINK,
+	SND_SOC_DOBJ_BACKEND_LINK,
 	SND_SOC_DOBJ_CODEC_LINK,
 	SND_SOC_DOBJ_WIDGET,
 };
include/sound/soc.h +3 -0
index 31fe60a..875c361 100644
@@ -992,6 +992,9 @@ struct snd_soc_dai_link {
 	const struct snd_soc_pcm_stream *params;
 	unsigned int num_params;
 
+	/* Stores HW params. Used by topology core. */
+	const struct snd_pcm_hardware *hw_params;
+
 	unsigned int dai_fmt;           /* format to set on init */
 
 	enum snd_soc_dpcm_trigger trigger[2]; /* trigger type for DPCM */
sound/soc/soc-topology.c +110 -3

154 lines not on this page · raw message

Signature · 1 line
1.9.1
#18 lore raw
In reply to [email protected]

Hi Mark,

Sorry, please over look this thread now.

I should wait for your comments on the other thread "[PATCH v2 0/2] ASoC: Change the PCM runtime array to a list" at first. The 2 patches are preparation to support dynamic PCM in topology.

Thanks
Mengdong

Quoted 49 lines · On 11/05/2015 05:58 PM, [email protected] wrote:

From: Mengdong Lin <[email protected]>

This series allows the topology core to create PCM devices dynamically, as well as configure BE and CC DAI links.

Mengdong Lin (12):
ASoC: Vendor drivers get a link's runtime by snd_soc_get_pcm_runtime()
ASoC: Change the PCM runtime array to a list
ASoC: Define soc_init_dai_link() to wrap link intialization.
ASoC: Change 2nd argument of soc_bind_dai_link() to DAI link pointer
ASoC: Implement DAI links in a list & define API to add a link
ASoC: Add add_dai_link ops for a soc card
ASoC: soc_bind_dai_link() directly returns success for a bound DAI
link
ASoC: Bind new DAI links after probing components
ASoC: The soc card can have auxiliary components
ASoC: Support adding a DAI dynamically
ASoC: topology: Add PCM DAIs dynamically when loading them
ASoC: topology: Add support for FE DAI links

Vedang Patel (1):
ASoC: topology: Add support for BE and CC DAI Links

  include/sound/soc-dai.h                      |   1 +
  include/sound/soc-topology.h                 |  22 +-
  include/sound/soc.h                          |  38 +-
  sound/soc/fsl/fsl-asoc-card.c                |   5 +-
  sound/soc/fsl/imx-wm8962.c                   |  10 +-
  sound/soc/generic/simple-card.c              |  12 +-
  sound/soc/intel/atom/sst-mfld-platform-pcm.c |  12 +-
  sound/soc/intel/boards/cht_bsw_max98090_ti.c |   7 +-
  sound/soc/intel/boards/cht_bsw_rt5645.c      |   7 +-
  sound/soc/intel/boards/cht_bsw_rt5672.c      |   7 +-
  sound/soc/pxa/mioa701_wm9713.c               |   6 +-
  sound/soc/samsung/bells.c                    |  40 +-
  sound/soc/samsung/littlemill.c               |  32 +-
  sound/soc/samsung/odroidx2_max98090.c        |   9 +-
  sound/soc/samsung/snow.c                     |   9 +-
  sound/soc/samsung/speyside.c                 |  12 +-
  sound/soc/samsung/tobermory.c                |  21 +-
  sound/soc/sh/rcar/core.c                     |   2 +-
  sound/soc/sh/rcar/rsrc-card.c                |   6 +-
  sound/soc/soc-core.c                         | 629 ++++++++++++++++++---------
  sound/soc/soc-dapm.c                         |   7 +-
  sound/soc/soc-pcm.c                          |  22 +-
  sound/soc/soc-topology.c                     | 284 ++++++++++--
  sound/soc/tegra/tegra_wm8903.c               |   3 +-
  24 files changed, 879 insertions(+), 324 deletions(-)