[Sound-open-firmware] [PATCH] apl-ssp: fix padding bit issues in I2S/LEFT_J mode

Pierre-Louis Bossart pierre-louis.bossart at linux.intel.com
Fri Apr 13 00:27:16 CEST 2018


The current code doesn't work for I2S/LEFT_J when the slot width and
number of valid bits don't match (e.g. 24 bit data in 32-bit slot).

In I2S/LEFT_J mode, the padding is not at the end of the frame but
at the end of each slot, and is evenly distributed between the two
left and right phases.

Fix by using DMYSTOP for I2S/LEFT_J, and only program SSPSP2 for DSP_A
and DSP_B modes

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>
---
 src/drivers/apl-ssp.c | 79 ++++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 63 insertions(+), 16 deletions(-)

diff --git a/src/drivers/apl-ssp.c b/src/drivers/apl-ssp.c
index a02d934..3a97cb8 100644
--- a/src/drivers/apl-ssp.c
+++ b/src/drivers/apl-ssp.c
@@ -107,6 +107,7 @@ static inline int ssp_set_config(struct dai *dai,
 	uint32_t data_size;
 	uint32_t start_delay;
 	uint32_t frame_end_padding;
+	uint32_t slot_end_padding;
 	uint32_t frame_len = 0;
 	uint32_t bdiv_min;
 	uint32_t tft;
@@ -299,6 +300,20 @@ static inline int ssp_set_config(struct dai *dai,
 		goto out;
 	}
 
+	bdiv_min = config->ssp.tdm_slots * config->ssp.sample_valid_bits;
+	if (bdiv < bdiv_min) {
+		trace_ssp_error("ecc");
+		ret = -EINVAL;
+		goto out;
+	}
+
+	frame_end_padding = bdiv - bdiv_min;
+	if (frame_end_padding > SSPSP2_FEP_MASK) {
+		trace_ssp_error("ecd");
+		ret = -EINVAL;
+		goto out;
+	}
+
 	/* format */
 	switch (config->format & SOF_DAI_FMT_FORMAT_MASK) {
 	case SOF_DAI_FMT_I2S:
@@ -325,6 +340,28 @@ static inline int ssp_set_config(struct dai *dai,
 		sspsp |= SSPSP_SFRMP(inverted_frame);
 		sspsp |= SSPSP_FSRT;
 
+		/*
+		 *  for I2S/LEFT_J, the padding has to happen at the end
+		 * of each slot
+		 */
+		if (frame_end_padding % 2) {
+			trace_ssp_error("ece");
+			ret = -EINVAL;
+			goto out;
+		}
+
+		slot_end_padding = frame_end_padding / 2;
+
+		if (slot_end_padding > 15) {
+			/* can't handle padding over 15 bits */
+			trace_ssp_error("ecf");
+			ret = -EINVAL;
+			goto out;
+		}
+
+		sspsp |= SSPSP_EDMYSTOP((slot_end_padding >> 2) & 0x3);
+		sspsp |= SSPSP_DMYSTOP(slot_end_padding & 0x3);
+
 		break;
 
 	case SOF_DAI_FMT_LEFT_J:
@@ -353,6 +390,28 @@ static inline int ssp_set_config(struct dai *dai,
 		 */
 		sspsp |= SSPSP_SFRMP(!inverted_frame);
 
+		/*
+		 *  for I2S/LEFT_J, the padding has to happen at the end
+		 * of each slot
+		 */
+		if (frame_end_padding % 2) {
+			trace_ssp_error("ecg");
+			ret = -EINVAL;
+			goto out;
+		}
+
+		slot_end_padding = frame_end_padding / 2;
+
+		if (slot_end_padding > 15) {
+			/* can't handle padding over 15 bits */
+			trace_ssp_error("ech");
+			ret = -EINVAL;
+			goto out;
+		}
+
+		sspsp |= SSPSP_EDMYSTOP((slot_end_padding >> 2) & 0x3);
+		sspsp |= SSPSP_DMYSTOP(slot_end_padding & 0x3);
+
 		break;
 	case SOF_DAI_FMT_DSP_A:
 
@@ -375,6 +434,8 @@ static inline int ssp_set_config(struct dai *dai,
 		active_tx_slots = hweight_32(config->ssp.tx_slots);
 		active_rx_slots = hweight_32(config->ssp.rx_slots);
 
+		sspsp2 |= (frame_end_padding & SSPSP2_FEP_MASK);
+
 		break;
 	case SOF_DAI_FMT_DSP_B:
 
@@ -396,6 +457,8 @@ static inline int ssp_set_config(struct dai *dai,
 		active_tx_slots = hweight_32(config->ssp.tx_slots);
 		active_rx_slots = hweight_32(config->ssp.rx_slots);
 
+		sspsp2 |= (frame_end_padding & SSPSP2_FEP_MASK);
+
 		break;
 	default:
 		trace_ssp_error("eca");
@@ -406,22 +469,6 @@ static inline int ssp_set_config(struct dai *dai,
 	sspsp |= SSPSP_STRTDLY(start_delay);
 	sspsp |= SSPSP_SFRMWDTH(frame_len);
 
-	bdiv_min = config->ssp.tdm_slots * config->ssp.sample_valid_bits;
-	if (bdiv < bdiv_min) {
-		trace_ssp_error("ecc");
-		ret = -EINVAL;
-		goto out;
-	}
-
-	frame_end_padding = bdiv - bdiv_min;
-	if (frame_end_padding > SSPSP2_FEP_MASK) {
-		trace_ssp_error("ecd");
-		ret = -EINVAL;
-		goto out;
-	}
-
-	sspsp2 |= (frame_end_padding & SSPSP2_FEP_MASK);
-
 	data_size = config->ssp.sample_valid_bits;
 
 	if (data_size > 16)
-- 
2.14.1



More information about the Sound-open-firmware mailing list