diff --git a/sound/soc/stm/stm32_i2s.c b/sound/soc/stm/stm32_i2s.c
index 22152a1..a8e03c5 100644
--- a/sound/soc/stm/stm32_i2s.c
+++ b/sound/soc/stm/stm32_i2s.c
@@ -489,7 +489,6 @@ static int stm32_i2s_configure(struct snd_soc_dai *cpu_dai,
 	struct stm32_i2s_data *i2s = snd_soc_dai_get_drvdata(cpu_dai);
 	int format = params_width(params);
 	u32 cfgr, cfgr_mask, cfg1, cfg1_mask;
-	bool playback_flg = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
 	unsigned int fthlv;
 	int ret;
 
@@ -515,19 +514,13 @@ static int stm32_i2s_configure(struct snd_soc_dai *cpu_dai,
 	}
 
 	if (STM32_I2S_IS_SLAVE(i2s)) {
-		if (playback_flg)
-			cfgr |= I2S_CGFR_I2SCFG_SET(I2S_I2SMOD_TX_SLAVE);
-		else
-			cfgr |= I2S_CGFR_I2SCFG_SET(I2S_I2SMOD_RX_SLAVE);
+		cfgr |= I2S_CGFR_I2SCFG_SET(I2S_I2SMOD_FD_SLAVE);
 
 		/* As data length is either 16 or 32 bits, fixch always set */
 		cfgr |= I2S_CGFR_FIXCH;
 		cfgr_mask |= I2S_CGFR_FIXCH;
 	} else {
-		if (playback_flg)
-			cfgr |= I2S_CGFR_I2SCFG_SET(I2S_I2SMOD_TX_MASTER);
-		else
-			cfgr |= I2S_CGFR_I2SCFG_SET(I2S_I2SMOD_RX_MASTER);
+		cfgr |= I2S_CGFR_I2SCFG_SET(I2S_I2SMOD_FD_MASTER);
 	}
 	cfgr_mask |= I2S_CGFR_I2SCFG_MASK;
 
@@ -536,9 +529,7 @@ static int stm32_i2s_configure(struct snd_soc_dai *cpu_dai,
 	if (ret < 0)
 		return ret;
 
-	cfg1 = I2S_CFG1_RXDMAEN;
-	if (playback_flg)
-		cfg1 = I2S_CFG1_TXDMAEN;
+	cfg1 = I2S_CFG1_RXDMAEN | I2S_CFG1_TXDMAEN;
 	cfg1_mask = cfg1;
 
 	fthlv = STM32_I2S_FIFO_SIZE * I2S_FIFO_TH_ONE_QUARTER / 4;
@@ -553,32 +544,15 @@ static int stm32_i2s_startup(struct snd_pcm_substream *substream,
 			     struct snd_soc_dai *cpu_dai)
 {
 	struct stm32_i2s_data *i2s = snd_soc_dai_get_drvdata(cpu_dai);
-	int ret, ier;
 
 	i2s->substream = substream;
 
 	spin_lock(&i2s->lock_fd);
-	if (i2s->refcount) {
-		dev_err(cpu_dai->dev, "%s stream already started\n",
-			(substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
-			"Capture" : "Playback"));
-		spin_unlock(&i2s->lock_fd);
-		return -EBUSY;
-	}
-	i2s->refcount = 1;
+	i2s->refcount++;
 	spin_unlock(&i2s->lock_fd);
 
-	ret = regmap_update_bits(i2s->regmap, STM32_I2S_IFCR_REG,
-				 I2S_IFCR_MASK, I2S_IFCR_MASK);
-	if (ret < 0)
-		return ret;
-
-	/* Enable ITs */
-	ier = I2S_IER_OVRIE | I2S_IER_UDRIE;
-	if (STM32_I2S_IS_SLAVE(i2s))
-		ier |= I2S_IER_TIFREIE;
-
-	return regmap_update_bits(i2s->regmap, STM32_I2S_IER_REG, ier, ier);
+	return regmap_update_bits(i2s->regmap, STM32_I2S_IFCR_REG,
+				  I2S_IFCR_MASK, I2S_IFCR_MASK);
 }
 
 static int stm32_i2s_hw_params(struct snd_pcm_substream *substream,
@@ -605,9 +579,11 @@ static int stm32_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
 {
 	struct stm32_i2s_data *i2s = snd_soc_dai_get_drvdata(cpu_dai);
 	bool playback_flg = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
-	u32 cfg1_mask;
+	u32 cfg1_mask, ier;
 	int ret;
 
+	spin_lock(&i2s->lock_fd);
+
 	switch (cmd) {
 	case SNDRV_PCM_TRIGGER_START:
 	case SNDRV_PCM_TRIGGER_RESUME:
@@ -628,10 +604,45 @@ static int stm32_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
 			dev_err(cpu_dai->dev, "Error %d starting I2S\n", ret);
 			return ret;
 		}
+
+		regmap_update_bits(i2s->regmap, STM32_I2S_IFCR_REG,
+				   I2S_IFCR_MASK, I2S_IFCR_MASK);
+
+		if (playback_flg) {
+			ier = I2S_IER_UDRIE;
+		} else {
+			ier = I2S_IER_OVRIE;
+
+			if (i2s->refcount == 1) {
+				/* dummy write to trigger capture */
+				ret = regmap_write(i2s->regmap,
+						   STM32_I2S_TXDR_REG, 0);
+				if (ret)
+					return ret;
+			}
+		}
+
+		if (STM32_I2S_IS_SLAVE(i2s))
+			ier |= I2S_IER_TIFREIE;
+
+		regmap_update_bits(i2s->regmap, STM32_I2S_IER_REG, ier, ier);
 		break;
 	case SNDRV_PCM_TRIGGER_STOP:
 	case SNDRV_PCM_TRIGGER_SUSPEND:
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+		if (playback_flg)
+			regmap_update_bits(i2s->regmap, STM32_I2S_IER_REG,
+					   I2S_IER_UDRIE,
+					   (unsigned int)~I2S_IER_UDRIE);
+		else
+			regmap_update_bits(i2s->regmap, STM32_I2S_IER_REG,
+					   I2S_IER_OVRIE,
+					   (unsigned int)~I2S_IER_OVRIE);
+
+		i2s->refcount--;
+		if (i2s->refcount)
+			break;
+
 		dev_dbg(cpu_dai->dev, "stop I2S\n");
 
 		ret = regmap_update_bits(i2s->regmap, STM32_I2S_CR1_REG,
@@ -641,10 +652,7 @@ static int stm32_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
 			return ret;
 		}
 
-		cfg1_mask = I2S_CFG1_RXDMAEN;
-		if (playback_flg)
-			cfg1_mask = I2S_CFG1_TXDMAEN;
-
+		cfg1_mask = I2S_CFG1_RXDMAEN | I2S_CFG1_TXDMAEN;
 		regmap_update_bits(i2s->regmap, STM32_I2S_CFG1_REG,
 				   cfg1_mask, 0);
 		break;
@@ -652,6 +660,8 @@ static int stm32_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
 		return -EINVAL;
 	}
 
+	spin_unlock(&i2s->lock_fd);
+
 	return 0;
 }
 
@@ -662,10 +672,6 @@ static void stm32_i2s_shutdown(struct snd_pcm_substream *substream,
 
 	i2s->substream = NULL;
 
-	spin_lock(&i2s->lock_fd);
-	i2s->refcount = 0;
-	spin_unlock(&i2s->lock_fd);
-
 	regmap_update_bits(i2s->regmap, STM32_I2S_CGFR_REG,
 			   I2S_CGFR_MCKOE, (unsigned int)~I2S_CGFR_MCKOE);
 }
