aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRicard Wanderlof <ricard.wanderlof@axis.com>2015-08-24 08:16:51 -0400
committerMark Brown <broonie@kernel.org>2015-09-19 13:58:04 -0400
commitcde79035c6cf578dd33dfea3e39666efc27cbcf2 (patch)
tree3c8ee2baf3fbfc589300f132acfdc0ada17b431e
parent6ff33f3902c3b1c5d0db6b1e2c70b6d76fba357f (diff)
ASoC: Handle multiple codecs with split playback / capture
Add the capability to use multiple codecs on the same DAI linke where one codec is used for playback and another one is used for capture. Tested on a setup using an SSM2518 for playback and an ICS43432 I2S MEMS microphone for capture. No verification is made that the playback and capture codec setups are compatible in terms of number of TDM slots (where applicable). Signed-off-by: Ricard Wanderlof <ricardw@axis.com> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--sound/soc/soc-pcm.c49
1 files changed, 49 insertions, 0 deletions
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index 70e4b9d8bdcd..317395824cd7 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -34,6 +34,24 @@
34 34
35#define DPCM_MAX_BE_USERS 8 35#define DPCM_MAX_BE_USERS 8
36 36
37/*
38 * snd_soc_dai_stream_valid() - check if a DAI supports the given stream
39 *
40 * Returns true if the DAI supports the indicated stream type.
41 */
42static bool snd_soc_dai_stream_valid(struct snd_soc_dai *dai, int stream)
43{
44 struct snd_soc_pcm_stream *codec_stream;
45
46 if (stream == SNDRV_PCM_STREAM_PLAYBACK)
47 codec_stream = &dai->driver->playback;
48 else
49 codec_stream = &dai->driver->capture;
50
51 /* If the codec specifies any rate at all, it supports the stream. */
52 return codec_stream->rates;
53}
54
37/** 55/**
38 * snd_soc_runtime_activate() - Increment active count for PCM runtime components 56 * snd_soc_runtime_activate() - Increment active count for PCM runtime components
39 * @rtd: ASoC PCM runtime that is activated 57 * @rtd: ASoC PCM runtime that is activated
@@ -371,6 +389,20 @@ static void soc_pcm_init_runtime_hw(struct snd_pcm_substream *substream)
371 389
372 /* first calculate min/max only for CODECs in the DAI link */ 390 /* first calculate min/max only for CODECs in the DAI link */
373 for (i = 0; i < rtd->num_codecs; i++) { 391 for (i = 0; i < rtd->num_codecs; i++) {
392
393 /*
394 * Skip CODECs which don't support the current stream type.
395 * Otherwise, since the rate, channel, and format values will
396 * zero in that case, we would have no usable settings left,
397 * causing the resulting setup to fail.
398 * At least one CODEC should match, otherwise we should have
399 * bailed out on a higher level, since there would be no
400 * CODEC to support the transfer direction in that case.
401 */
402 if (!snd_soc_dai_stream_valid(rtd->codec_dais[i],
403 substream->stream))
404 continue;
405
374 codec_dai_drv = rtd->codec_dais[i]->driver; 406 codec_dai_drv = rtd->codec_dais[i]->driver;
375 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 407 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
376 codec_stream = &codec_dai_drv->playback; 408 codec_stream = &codec_dai_drv->playback;
@@ -827,6 +859,23 @@ static int soc_pcm_hw_params(struct snd_pcm_substream *substream,
827 struct snd_soc_dai *codec_dai = rtd->codec_dais[i]; 859 struct snd_soc_dai *codec_dai = rtd->codec_dais[i];
828 struct snd_pcm_hw_params codec_params; 860 struct snd_pcm_hw_params codec_params;
829 861
862 /*
863 * Skip CODECs which don't support the current stream type,
864 * the idea being that if a CODEC is not used for the currently
865 * set up transfer direction, it should not need to be
866 * configured, especially since the configuration used might
867 * not even be supported by that CODEC. There may be cases
868 * however where a CODEC needs to be set up although it is
869 * actually not being used for the transfer, e.g. if a
870 * capture-only CODEC is acting as an LRCLK and/or BCLK master
871 * for the DAI link including a playback-only CODEC.
872 * If this becomes necessary, we will have to augment the
873 * machine driver setup with information on how to act, so
874 * we can do the right thing here.
875 */
876 if (!snd_soc_dai_stream_valid(codec_dai, substream->stream))
877 continue;
878
830 /* copy params for each codec */ 879 /* copy params for each codec */
831 codec_params = *params; 880 codec_params = *params;
832 881