From b73287f0b0745961b14e5ebcce92cc8ed24d4d52 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Mon, 8 Jun 2020 14:44:12 -0500 Subject: ASoC: soc-pcm: dpcm: fix playback/capture checks Recent changes in the ASoC core prevent multi-cpu BE dailinks from being used. DPCM does support multi-cpu DAIs for BE Dailinks, but not for FE. Handle the FE checks first, and make sure all DAIs support the same capabilities within the same dailink. Fixes: 9b5db059366ae2 ("ASoC: soc-pcm: dpcm: Only allow playback/capture if supported") Signed-off-by: Pierre-Louis Bossart Reviewed-by: Bard Liao Reviewed-by: Guennadi Liakhovetski Reviewed-by: Ranjani Sridharan Reviewed-by: Daniel Baluta BugLink: https://github.com/thesofproject/linux/issues/2031 Link: https://lore.kernel.org/r/20200608194415.4663-2-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/soc-pcm.c | 44 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 10 deletions(-) (limited to 'sound') diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c index 276505fb9d50..2c114b4542ce 100644 --- a/sound/soc/soc-pcm.c +++ b/sound/soc/soc-pcm.c @@ -2789,20 +2789,44 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num) struct snd_pcm *pcm; char new_name[64]; int ret = 0, playback = 0, capture = 0; + int stream; int i; + if (rtd->dai_link->dynamic && rtd->num_cpus > 1) { + dev_err(rtd->dev, + "DPCM doesn't support Multi CPU for Front-Ends yet\n"); + return -EINVAL; + } + if (rtd->dai_link->dynamic || rtd->dai_link->no_pcm) { - cpu_dai = asoc_rtd_to_cpu(rtd, 0); - if (rtd->num_cpus > 1) { - dev_err(rtd->dev, - "DPCM doesn't support Multi CPU yet\n"); - return -EINVAL; + if (rtd->dai_link->dpcm_playback) { + stream = SNDRV_PCM_STREAM_PLAYBACK; + + for_each_rtd_cpu_dais(rtd, i, cpu_dai) + if (!snd_soc_dai_stream_valid(cpu_dai, + stream)) { + dev_err(rtd->card->dev, + "CPU DAI %s for rtd %s does not support playback\n", + cpu_dai->name, + rtd->dai_link->stream_name); + return -EINVAL; + } + playback = 1; + } + if (rtd->dai_link->dpcm_capture) { + stream = SNDRV_PCM_STREAM_CAPTURE; + + for_each_rtd_cpu_dais(rtd, i, cpu_dai) + if (!snd_soc_dai_stream_valid(cpu_dai, + stream)) { + dev_err(rtd->card->dev, + "CPU DAI %s for rtd %s does not support capture\n", + cpu_dai->name, + rtd->dai_link->stream_name); + return -EINVAL; + } + capture = 1; } - - playback = rtd->dai_link->dpcm_playback && - snd_soc_dai_stream_valid(cpu_dai, SNDRV_PCM_STREAM_PLAYBACK); - capture = rtd->dai_link->dpcm_capture && - snd_soc_dai_stream_valid(cpu_dai, SNDRV_PCM_STREAM_CAPTURE); } else { /* Adapt stream for codec2codec links */ int cpu_capture = rtd->dai_link->params ? -- cgit v1.2.3-70-g09d2 From 607fa205a7e4dfad28b8a67ab1c985756ddbccb0 Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Mon, 8 Jun 2020 14:44:13 -0500 Subject: ASoC: core: only convert non DPCM link to DPCM link Additional checks for valid DAIs expose a corner case, where existing BE dailinks get modified, e.g. HDMI links are tagged with dpcm_capture=1 even if the DAIs are for playback. This patch makes those changes conditional and flags configuration issues when a BE dailink is has no_pcm=0 but dpcm_playback or dpcm_capture=1 (which makes no sense). As discussed on the alsa-devel mailing list, there are redundant flags for dpcm_playback, dpcm_capture, playback_only, capture_only. This will have to be cleaned-up in a future update. For now only correct and flag problematic configurations. Fixes: 218fe9b7ec7f3 ("ASoC: soc-core: Set dpcm_playback / dpcm_capture") Suggested-by: Daniel Baluta Signed-off-by: Bard Liao Signed-off-by: Pierre-Louis Bossart Reviewed-by: Guennadi Liakhovetski Reviewed-by: Daniel Baluta Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20200608194415.4663-3-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) (limited to 'sound') diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index b07eca2c6ccc..7b387202c5db 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1648,9 +1648,25 @@ match: dai_link->platforms->name = component->name; /* convert non BE into BE */ - dai_link->no_pcm = 1; - dai_link->dpcm_playback = 1; - dai_link->dpcm_capture = 1; + if (!dai_link->no_pcm) { + dai_link->no_pcm = 1; + + if (dai_link->dpcm_playback) + dev_warn(card->dev, + "invalid configuration, dailink %s has flags no_pcm=0 and dpcm_playback=1\n", + dai_link->name); + if (dai_link->dpcm_capture) + dev_warn(card->dev, + "invalid configuration, dailink %s has flags no_pcm=0 and dpcm_capture=1\n", + dai_link->name); + + /* convert normal link into DPCM one */ + if (!(dai_link->dpcm_playback || + dai_link->dpcm_capture)) { + dai_link->dpcm_playback = !dai_link->capture_only; + dai_link->dpcm_capture = !dai_link->playback_only; + } + } /* * override any BE fixups -- cgit v1.2.3-70-g09d2 From dc261875865539ca91bff9bc44d3e62f811dec1d Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Mon, 8 Jun 2020 14:44:14 -0500 Subject: ASoC: Intel: boards: replace capture_only by dpcm_capture It's not clear why specific FE dailinks use capture_only flags, likely blind copy/paste from Chromebook driver to the other. Replace by dpcm_capture, this will make future alignment and removal of flags easier. Signed-off-by: Pierre-Louis Bossart Reviewed-by: Guennadi Liakhovetski Reviewed-by: Daniel Baluta Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20200608194415.4663-4-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/intel/boards/glk_rt5682_max98357a.c | 2 +- sound/soc/intel/boards/kbl_da7219_max98927.c | 4 ++-- sound/soc/intel/boards/kbl_rt5663_max98927.c | 2 +- sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) (limited to 'sound') diff --git a/sound/soc/intel/boards/glk_rt5682_max98357a.c b/sound/soc/intel/boards/glk_rt5682_max98357a.c index 48eda1a8aa6c..954ab01f695b 100644 --- a/sound/soc/intel/boards/glk_rt5682_max98357a.c +++ b/sound/soc/intel/boards/glk_rt5682_max98357a.c @@ -407,7 +407,7 @@ static struct snd_soc_dai_link geminilake_dais[] = { .name = "Glk Audio Echo Reference cap", .stream_name = "Echoreference Capture", .init = NULL, - .capture_only = 1, + .dpcm_capture = 1, .nonatomic = 1, .dynamic = 1, SND_SOC_DAILINK_REG(echoref, dummy, platform), diff --git a/sound/soc/intel/boards/kbl_da7219_max98927.c b/sound/soc/intel/boards/kbl_da7219_max98927.c index cc9b5eab8b4a..e29c31ffd241 100644 --- a/sound/soc/intel/boards/kbl_da7219_max98927.c +++ b/sound/soc/intel/boards/kbl_da7219_max98927.c @@ -692,7 +692,7 @@ static struct snd_soc_dai_link kabylake_dais[] = { .name = "Kbl Audio Echo Reference cap", .stream_name = "Echoreference Capture", .init = NULL, - .capture_only = 1, + .dpcm_capture = 1, .nonatomic = 1, SND_SOC_DAILINK_REG(echoref, dummy, platform), }, @@ -858,7 +858,7 @@ static struct snd_soc_dai_link kabylake_max98_927_373_dais[] = { .name = "Kbl Audio Echo Reference cap", .stream_name = "Echoreference Capture", .init = NULL, - .capture_only = 1, + .dpcm_capture = 1, .nonatomic = 1, SND_SOC_DAILINK_REG(echoref, dummy, platform), }, diff --git a/sound/soc/intel/boards/kbl_rt5663_max98927.c b/sound/soc/intel/boards/kbl_rt5663_max98927.c index 658a9da3a40f..09ba55fc36d5 100644 --- a/sound/soc/intel/boards/kbl_rt5663_max98927.c +++ b/sound/soc/intel/boards/kbl_rt5663_max98927.c @@ -672,7 +672,7 @@ static struct snd_soc_dai_link kabylake_dais[] = { .name = "Kbl Audio Echo Reference cap", .stream_name = "Echoreference Capture", .init = NULL, - .capture_only = 1, + .dpcm_capture = 1, .nonatomic = 1, SND_SOC_DAILINK_REG(echoref, dummy, platform), }, diff --git a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c index 1b1f8d7a4ea3..b34cf6cf1139 100644 --- a/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c +++ b/sound/soc/intel/boards/kbl_rt5663_rt5514_max98927.c @@ -566,7 +566,7 @@ static struct snd_soc_dai_link kabylake_dais[] = { .name = "Kbl Audio Echo Reference cap", .stream_name = "Echoreference Capture", .init = NULL, - .capture_only = 1, + .dpcm_capture = 1, .nonatomic = 1, SND_SOC_DAILINK_REG(echoref, dummy, platform), }, -- cgit v1.2.3-70-g09d2 From ba4e5abc6c4e173af7c941c03c067263b686665d Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bossart Date: Mon, 8 Jun 2020 14:44:15 -0500 Subject: ASoC: SOF: nocodec: conditionally set dpcm_capture/dpcm_playback flags With additional checks on dailinks, we see errors such as [ 3.000418] sof-nocodec sof-nocodec: CPU DAI DMIC01 Pin for rtd NoCodec-6 does not support playback It's not clear why we set the dpcm_playback and dpcm_capture flags unconditionally, add a check on number of channels for each direction to avoid invalid configurations. Fixes: 8017b8fd37bf5e ('ASoC: SOF: Add Nocodec machine driver support') Signed-off-by: Pierre-Louis Bossart Reviewed-by: Guennadi Liakhovetski Reviewed-by: Daniel Baluta Reviewed-by: Bard Liao Link: https://lore.kernel.org/r/20200608194415.4663-5-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown --- sound/soc/sof/nocodec.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'sound') diff --git a/sound/soc/sof/nocodec.c b/sound/soc/sof/nocodec.c index ce053ba8f2e8..d03b5be31255 100644 --- a/sound/soc/sof/nocodec.c +++ b/sound/soc/sof/nocodec.c @@ -52,8 +52,10 @@ static int sof_nocodec_bes_setup(struct device *dev, links[i].platforms->name = dev_name(dev); links[i].codecs->dai_name = "snd-soc-dummy-dai"; links[i].codecs->name = "snd-soc-dummy"; - links[i].dpcm_playback = 1; - links[i].dpcm_capture = 1; + if (ops->drv[i].playback.channels_min) + links[i].dpcm_playback = 1; + if (ops->drv[i].capture.channels_min) + links[i].dpcm_capture = 1; } card->dai_link = links; -- cgit v1.2.3-70-g09d2