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));