ASoC: topology: Add support for PCM, BE & CC links
Subsystems (10)
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
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.csound/soc/fsl/imx-wm8962.csound/soc/pxa/mioa701_wm9713.csound/soc/samsung/bells.csound/soc/samsung/littlemill.csound/soc/samsung/odroidx2_max98090.csound/soc/samsung/snow.csound/soc/samsung/speyside.csound/soc/samsung/tobermory.csound/soc/tegra/tegra_wm8903
sound/soc/fsl/fsl-asoc-card.c +4 -1
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
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
@@ -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
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
@@ -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
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
@@ -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
@@ -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
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
@@ -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
@@ -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
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
@@ -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
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
@@ -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
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
@@ -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
@@ -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
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
@@ -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
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
@@ -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
@@ -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
@@ -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
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
@@ -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
@@ -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
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
@@ -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
@@ -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
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 bysnd_soc_get_pcm_runtime()
ASoC: Change the PCM runtime array to a list
ASoC: Definesoc_init_dai_link()to wrap link intialization.
ASoC: Change 2nd argument ofsoc_bind_dai_link()to DAI link pointer
ASoC: Implement DAI links in a list & define API to add a link
ASoC: Addadd_dai_linkops 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 linksVedang Patel (1):
ASoC: topology: Add support for BE and CC DAI Linksinclude/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(-)
Mark Brown
maintainerApplied "ASoC: Change 2nd argument of soc_bind_dai_link() to DAI link pointer" to the asoc tree
In reply to [email protected]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
6f2f1ff0de83ad69f5a823ae77d1e0f77cc75d45Mon 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
@@ -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
Re: [PATCH v2 09/13] ASoC: The soc card can have auxiliary components
In reply to [email protected]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?
Mark Brown
maintainerApplied "ASoC: Bind new DAI links after probing components" to the asoc tree
In reply to [email protected]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
61b0088b6a5b98608ce00c18a057b1f5bcb5f8b3Mon 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
@@ -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
Mark Brown
maintainerApplied "ASoC: soc_bind_dai_link() directly returns success for a bound DAI link" to the asoc tree
In reply to [email protected]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
49a5ba1cd9da4fb04e7ce1e0d94f6a5a9b7be48eMon 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
@@ -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