drivers: apl-ssp: handle tdm mode in ssp

I've added tdm support in ssp. Tdm mode has
padding at the end of each slot. Tdm mode is
enabled by tdm_per_slot_padding flag in
sof_ipc_dai_ssp_params struct.

Signed-off-by: Bartosz Kokoszko <bartoszx.kokoszko@linux.intel.com>
diff --git a/src/drivers/apl-ssp.c b/src/drivers/apl-ssp.c
index f8742a4..c77ef18 100644
--- a/src/drivers/apl-ssp.c
+++ b/src/drivers/apl-ssp.c
@@ -574,6 +574,32 @@
 		active_tx_slots = hweight_32(config->ssp.tx_slots);
 		active_rx_slots = hweight_32(config->ssp.rx_slots);
 
+		/*
+		 * handle TDM mode, TDM mode has padding at the end of
+		 * each slot. The amount of padding is equal to result of
+		 * subtracting slot width and valid bits per slot.
+		 */
+		if (ssp->params.tdm_per_slot_padding_flag) {
+			frame_end_padding = bdiv - config->ssp.tdm_slots *
+				config->ssp.tdm_slot_width;
+
+			slot_end_padding = config->ssp.tdm_slot_width -
+				config->ssp.sample_valid_bits;
+
+			if (slot_end_padding >
+				SOF_DAI_INTEL_SSP_SLOT_PADDING_MAX) {
+				trace_ssp_error("esb");
+				ret = -EINVAL;
+				goto out;
+			}
+
+			sspsp |= SSPSP_DMYSTOP(slot_end_padding &
+				SSPSP_DMYSTOP_MASK);
+			slot_end_padding >>= SSPSP_DMYSTOP_BITS;
+			sspsp |= SSPSP_EDMYSTOP(slot_end_padding &
+				SSPSP_EDMYSTOP_MASK);
+		}
+
 		sspsp2 |= (frame_end_padding & SSPSP2_FEP_MASK);
 
 		break;
diff --git a/src/include/uapi/ipc.h b/src/include/uapi/ipc.h
index c5174b9..68f638e 100644
--- a/src/include/uapi/ipc.h
+++ b/src/include/uapi/ipc.h
@@ -241,6 +241,7 @@
  /* here is the possibility to define others aux macros */
 
 #define SOF_DAI_INTEL_SSP_FRAME_PULSE_WIDTH_MAX		38
+#define SOF_DAI_INTEL_SSP_SLOT_PADDING_MAX		31
 
 /** \brief Types of DAI */
 enum sof_ipc_dai_type {
@@ -278,7 +279,7 @@
 	uint16_t frame_pulse_width;
 	uint32_t quirks; // FIXME: is 32 bits enough ?
 
-	uint16_t padding;
+	uint16_t tdm_per_slot_padding_flag;
 	/* private data, e.g. for quirks */
 	//uint32_t pdata[10]; // FIXME: would really need ~16 u32
 } __attribute__((packed));