[PATCH 2/2] ASoC: TWL4030: Add constrains for second stream

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



In case of duplex mode (capture and playback at the same time), the second
stream has to have the same parameters (rate, sample size) as the already
running stream.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@xxxxxxxxx>
---
 sound/soc/codecs/twl4030.c |   54 ++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 54 insertions(+), 0 deletions(-)

diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index b07d8d6..4199498 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -122,6 +122,9 @@ struct twl4030_priv {
 	unsigned int bypass_state;
 	unsigned int codec_powered;
 	unsigned int codec_muted;
+
+	struct snd_pcm_substream *master_substream;
+	struct snd_pcm_substream *slave_substream;
 };
 
 /*
@@ -1217,6 +1220,50 @@ static int twl4030_set_bias_level(struct snd_soc_codec *codec,
 	return 0;
 }
 
+static int twl4030_startup(struct snd_pcm_substream *substream)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct snd_soc_device *socdev = rtd->socdev;
+	struct snd_soc_codec *codec = socdev->codec;
+	struct twl4030_priv *twl4030 = codec->private_data;
+
+	/* If we already have a playback or capture going then constrain
+	 * this substream to match it.
+	 */
+	if (twl4030->master_substream) {
+		struct snd_pcm_runtime *master_runtime;
+		master_runtime = twl4030->master_substream->runtime;
+
+		snd_pcm_hw_constraint_minmax(substream->runtime,
+					     SNDRV_PCM_HW_PARAM_RATE,
+					     master_runtime->rate,
+					     master_runtime->rate);
+
+		snd_pcm_hw_constraint_minmax(substream->runtime,
+					     SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
+					     master_runtime->sample_bits,
+					     master_runtime->sample_bits);
+
+		twl4030->slave_substream = substream;
+	} else
+		twl4030->master_substream = substream;
+
+	return 0;
+}
+
+static void twl4030_shutdown(struct snd_pcm_substream *substream)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct snd_soc_device *socdev = rtd->socdev;
+	struct snd_soc_codec *codec = socdev->codec;
+	struct twl4030_priv *twl4030 = codec->private_data;
+
+	if (twl4030->master_substream == substream)
+		twl4030->master_substream = twl4030->slave_substream;
+
+	twl4030->slave_substream = NULL;
+}
+
 static int twl4030_hw_params(struct snd_pcm_substream *substream,
 			   struct snd_pcm_hw_params *params,
 			   struct snd_soc_dai *dai)
@@ -1224,8 +1271,13 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream,
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct snd_soc_device *socdev = rtd->socdev;
 	struct snd_soc_codec *codec = socdev->card->codec;
+	struct twl4030_priv *twl4030 = codec->private_data;
 	u8 mode, old_mode, format, old_format;
 
+	if (substream == twl4030->slave_substream)
+		/* Ignoring hw_params for slave substream */
+		return 0;
+
 	/* bit rate */
 	old_mode = twl4030_read_reg_cache(codec,
 			TWL4030_REG_CODEC_MODE) & ~TWL4030_CODECPDZ;
@@ -1384,6 +1436,8 @@ static int twl4030_set_dai_fmt(struct snd_soc_dai *codec_dai,
 #define TWL4030_FORMATS	 (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FORMAT_S24_LE)
 
 static struct snd_soc_dai_ops twl4030_dai_ops = {
+	.startup	= twl4030_startup,
+	.shutdown	= twl4030_shutdown,
 	.hw_params	= twl4030_hw_params,
 	.set_sysclk	= twl4030_set_dai_sysclk,
 	.set_fmt	= twl4030_set_dai_fmt,
-- 
1.6.2

_______________________________________________
Alsa-devel mailing list
Alsa-devel@xxxxxxxxxxxxxxxx
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

[Index of Archives]     [ALSA User]     [Linux Audio Users]     [Kernel Archive]     [Asterisk PBX]     [Photo Sharing]     [Linux Sound]     [Video 4 Linux]     [Gimp]     [Yosemite News]

  Powered by Linux