asoc: sdm660: TDM device grouping changes for capture path

Add support for multi port in primary TDM capture interface.
Add front end functionality to support TDM group device capture.

Change-Id: Ic1d551beab0cd947d3bb0c378217ccae43e62086
Signed-off-by: Gangadhar S <gangadha@codeaurora.org>
diff --git a/asoc/sdm660-common.c b/asoc/sdm660-common.c
index abd85df..1cceb7a 100644
--- a/asoc/sdm660-common.c
+++ b/asoc/sdm660-common.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -43,6 +43,29 @@
 	EXT_DISP_RX_IDX_MAX,
 };
 
+enum {
+	PRIMARY_TDM_RX_0,
+	PRIMARY_TDM_RX_1,
+	PRIMARY_TDM_RX_2,
+	PRIMARY_TDM_RX_3,
+	PRIMARY_TDM_RX_4,
+	PRIMARY_TDM_RX_5,
+	PRIMARY_TDM_RX_6,
+	PRIMARY_TDM_RX_7,
+	TDM_MAX_RX,
+};
+enum {
+	PRIMARY_TDM_TX_0,
+	PRIMARY_TDM_TX_1,
+	PRIMARY_TDM_TX_2,
+	PRIMARY_TDM_TX_3,
+	PRIMARY_TDM_TX_4,
+	PRIMARY_TDM_TX_5,
+	PRIMARY_TDM_TX_6,
+	PRIMARY_TDM_TX_7,
+	TDM_MAX_TX,
+};
+
 bool codec_reg_done;
 
 struct tdm_dai_data {
@@ -605,18 +628,62 @@
 		{0xFFFF}, /* not used */
 	}
 };
-static unsigned int tdm_param_set_slot_mask(int slots)
+
+static unsigned int tdm_param_set_slot_mask(u16 port_id, int slot_width,
+		int slots, int tdm_interface)
 {
 	unsigned int slot_mask = 0;
-	int i = 0;
+	int upper, lower, i, j, rx_path = 0;
+	unsigned int *slot_offset;
 
-	if ((slots <= 0) || (slots > 32)) {
-		pr_err("%s: invalid slot number %d\n", __func__, slots);
-		return -EINVAL;
+	switch (port_id) {
+		pr_err("port_id %x", port_id );
+	case AFE_PORT_ID_PRIMARY_TDM_RX:
+	case AFE_PORT_ID_PRIMARY_TDM_RX_1:
+	case AFE_PORT_ID_PRIMARY_TDM_RX_2:
+	case AFE_PORT_ID_PRIMARY_TDM_RX_3:
+	case AFE_PORT_ID_PRIMARY_TDM_RX_4:
+	case AFE_PORT_ID_PRIMARY_TDM_RX_5:
+	case AFE_PORT_ID_PRIMARY_TDM_RX_6:
+	case AFE_PORT_ID_PRIMARY_TDM_RX_7:
+		lower = PRIMARY_TDM_RX_0;
+		upper = PRIMARY_TDM_RX_7;
+		rx_path = 1;
+		break;
+	case AFE_PORT_ID_PRIMARY_TDM_TX:
+	case AFE_PORT_ID_PRIMARY_TDM_TX_1:
+	case AFE_PORT_ID_PRIMARY_TDM_TX_2:
+	case AFE_PORT_ID_PRIMARY_TDM_TX_3:
+	case AFE_PORT_ID_PRIMARY_TDM_TX_4:
+	case AFE_PORT_ID_PRIMARY_TDM_TX_5:
+	case AFE_PORT_ID_PRIMARY_TDM_TX_6:
+	case AFE_PORT_ID_PRIMARY_TDM_TX_7:
+		lower = PRIMARY_TDM_TX_0;
+		upper = PRIMARY_TDM_TX_7;
+		break;
+	default:
+		return slot_mask;
 	}
 
-	for (i = 0; i < slots ; i++)
-		slot_mask |= 1 << i;
+	for (i = lower; i <= upper; i++) {
+		if (rx_path)
+			slot_offset = tdm_rx_slot_offset[tdm_interface][i];
+		else
+			slot_offset = tdm_tx_slot_offset[tdm_interface][i];
+
+		for (j = 0; j < TDM_SLOT_OFFSET_MAX; j++) {
+			if (slot_offset[j] != AFE_SLOT_MAPPING_OFFSET_INVALID) {
+				/*
+				 * set the mask of active slot according to
+				 * the offset table for the group of devices
+				 */
+				slot_mask |=
+				(1 << ((slot_offset[j] * 8) / slot_width));
+			} else {
+				break;
+			}
+		}
+	}
 
 	return slot_mask;
 }
@@ -627,7 +694,7 @@
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
 	int ret = 0;
-	int channels, slot_width, slots, rate, format;
+	int channels, slot_width, slots, rate, format, tdm_interface;
 	unsigned int slot_mask;
 	unsigned int *slot_offset;
 	int offset_channels = 0;
@@ -662,401 +729,481 @@
 		slots = tdm_slot[TDM_PRI].num;
 		slot_width = tdm_slot[TDM_PRI].width;
 		slot_offset = tdm_rx_slot_offset[TDM_PRI][TDM_0];
+		tdm_interface = TDM_PRI;
 		break;
 	case AFE_PORT_ID_PRIMARY_TDM_RX_1:
 		slots = tdm_slot[TDM_PRI].num;
 		slot_width = tdm_slot[TDM_PRI].width;
 		slot_offset = tdm_rx_slot_offset[TDM_PRI][TDM_1];
+		tdm_interface = TDM_PRI;
 		break;
 	case AFE_PORT_ID_PRIMARY_TDM_RX_2:
 		slots = tdm_slot[TDM_PRI].num;
 		slot_width = tdm_slot[TDM_PRI].width;
 		slot_offset = tdm_rx_slot_offset[TDM_PRI][TDM_2];
+		tdm_interface = TDM_PRI;
 		break;
 	case AFE_PORT_ID_PRIMARY_TDM_RX_3:
 		slots = tdm_slot[TDM_PRI].num;
 		slot_width = tdm_slot[TDM_PRI].width;
 		slot_offset = tdm_rx_slot_offset[TDM_PRI][TDM_3];
+		tdm_interface = TDM_PRI;
 		break;
 	case AFE_PORT_ID_PRIMARY_TDM_RX_4:
 		slots = tdm_slot[TDM_PRI].num;
 		slot_width = tdm_slot[TDM_PRI].width;
 		slot_offset = tdm_rx_slot_offset[TDM_PRI][TDM_4];
+		tdm_interface = TDM_PRI;
 		break;
 	case AFE_PORT_ID_PRIMARY_TDM_RX_5:
 		slots = tdm_slot[TDM_PRI].num;
 		slot_width = tdm_slot[TDM_PRI].width;
 		slot_offset = tdm_rx_slot_offset[TDM_PRI][TDM_5];
+		tdm_interface = TDM_PRI;
 		break;
 	case AFE_PORT_ID_PRIMARY_TDM_RX_6:
 		slots = tdm_slot[TDM_PRI].num;
 		slot_width = tdm_slot[TDM_PRI].width;
 		slot_offset = tdm_rx_slot_offset[TDM_PRI][TDM_6];
+		tdm_interface = TDM_PRI;
 		break;
 	case AFE_PORT_ID_PRIMARY_TDM_RX_7:
 		slots = tdm_slot[TDM_PRI].num;
 		slot_width = tdm_slot[TDM_PRI].width;
 		slot_offset = tdm_rx_slot_offset[TDM_PRI][TDM_7];
+		tdm_interface = TDM_PRI;
 		break;
 	case AFE_PORT_ID_PRIMARY_TDM_TX:
 		slots = tdm_slot[TDM_PRI].num;
 		slot_width = tdm_slot[TDM_PRI].width;
 		slot_offset = tdm_tx_slot_offset[TDM_PRI][TDM_0];
+		tdm_interface = TDM_PRI;
 		break;
 	case AFE_PORT_ID_PRIMARY_TDM_TX_1:
 		slots = tdm_slot[TDM_PRI].num;
 		slot_width = tdm_slot[TDM_PRI].width;
 		slot_offset = tdm_tx_slot_offset[TDM_PRI][TDM_1];
+		tdm_interface = TDM_PRI;
 		break;
 	case AFE_PORT_ID_PRIMARY_TDM_TX_2:
 		slots = tdm_slot[TDM_PRI].num;
 		slot_width = tdm_slot[TDM_PRI].width;
 		slot_offset = tdm_tx_slot_offset[TDM_PRI][TDM_2];
+		tdm_interface = TDM_PRI;
 		break;
 	case AFE_PORT_ID_PRIMARY_TDM_TX_3:
 		slots = tdm_slot[TDM_PRI].num;
 		slot_width = tdm_slot[TDM_PRI].width;
 		slot_offset = tdm_tx_slot_offset[TDM_PRI][TDM_3];
+		tdm_interface = TDM_PRI;
 		break;
 	case AFE_PORT_ID_PRIMARY_TDM_TX_4:
 		slots = tdm_slot[TDM_PRI].num;
 		slot_width = tdm_slot[TDM_PRI].width;
 		slot_offset = tdm_tx_slot_offset[TDM_PRI][TDM_4];
+		tdm_interface = TDM_PRI;
 		break;
 	case AFE_PORT_ID_PRIMARY_TDM_TX_5:
 		slots = tdm_slot[TDM_PRI].num;
 		slot_width = tdm_slot[TDM_PRI].width;
 		slot_offset = tdm_tx_slot_offset[TDM_PRI][TDM_5];
+		tdm_interface = TDM_PRI;
 		break;
 	case AFE_PORT_ID_PRIMARY_TDM_TX_6:
 		slots = tdm_slot[TDM_PRI].num;
 		slot_width = tdm_slot[TDM_PRI].width;
 		slot_offset = tdm_tx_slot_offset[TDM_PRI][TDM_6];
+		tdm_interface = TDM_PRI;
 		break;
 	case AFE_PORT_ID_PRIMARY_TDM_TX_7:
 		slots = tdm_slot[TDM_PRI].num;
 		slot_width = tdm_slot[TDM_PRI].width;
 		slot_offset = tdm_tx_slot_offset[TDM_PRI][TDM_7];
+		tdm_interface = TDM_PRI;
 		break;
 	case AFE_PORT_ID_SECONDARY_TDM_RX:
 		slots = tdm_slot[TDM_SEC].num;
 		slot_width = tdm_slot[TDM_SEC].width;
 		slot_offset = tdm_rx_slot_offset[TDM_SEC][TDM_0];
+		tdm_interface = TDM_SEC;
 		break;
 	case AFE_PORT_ID_SECONDARY_TDM_RX_1:
 		slots = tdm_slot[TDM_SEC].num;
 		slot_width = tdm_slot[TDM_SEC].width;
 		slot_offset = tdm_rx_slot_offset[TDM_SEC][TDM_1];
+		tdm_interface = TDM_SEC;
 		break;
 	case AFE_PORT_ID_SECONDARY_TDM_RX_2:
 		slots = tdm_slot[TDM_SEC].num;
 		slot_width = tdm_slot[TDM_SEC].width;
 		slot_offset = tdm_rx_slot_offset[TDM_SEC][TDM_2];
+		tdm_interface = TDM_SEC;
 		break;
 	case AFE_PORT_ID_SECONDARY_TDM_RX_3:
 		slots = tdm_slot[TDM_SEC].num;
 		slot_width = tdm_slot[TDM_SEC].width;
 		slot_offset = tdm_rx_slot_offset[TDM_SEC][TDM_3];
+		tdm_interface = TDM_SEC;
 		break;
 	case AFE_PORT_ID_SECONDARY_TDM_RX_4:
 		slots = tdm_slot[TDM_SEC].num;
 		slot_width = tdm_slot[TDM_SEC].width;
 		slot_offset = tdm_rx_slot_offset[TDM_SEC][TDM_4];
+		tdm_interface = TDM_SEC;
 		break;
 	case AFE_PORT_ID_SECONDARY_TDM_RX_5:
 		slots = tdm_slot[TDM_SEC].num;
 		slot_width = tdm_slot[TDM_SEC].width;
 		slot_offset = tdm_rx_slot_offset[TDM_SEC][TDM_5];
+		tdm_interface = TDM_SEC;
 		break;
 	case AFE_PORT_ID_SECONDARY_TDM_RX_6:
 		slots = tdm_slot[TDM_SEC].num;
 		slot_width = tdm_slot[TDM_SEC].width;
 		slot_offset = tdm_rx_slot_offset[TDM_SEC][TDM_6];
+		tdm_interface = TDM_SEC;
 		break;
 	case AFE_PORT_ID_SECONDARY_TDM_RX_7:
 		slots = tdm_slot[TDM_SEC].num;
 		slot_width = tdm_slot[TDM_SEC].width;
 		slot_offset = tdm_rx_slot_offset[TDM_SEC][TDM_7];
+		tdm_interface = TDM_SEC;
 		break;
 	case AFE_PORT_ID_SECONDARY_TDM_TX:
 		slots = tdm_slot[TDM_SEC].num;
 		slot_width = tdm_slot[TDM_SEC].width;
 		slot_offset = tdm_tx_slot_offset[TDM_SEC][TDM_0];
+		tdm_interface = TDM_SEC;
 		break;
 	case AFE_PORT_ID_SECONDARY_TDM_TX_1:
 		slots = tdm_slot[TDM_SEC].num;
 		slot_width = tdm_slot[TDM_SEC].width;
 		slot_offset = tdm_tx_slot_offset[TDM_SEC][TDM_1];
+		tdm_interface = TDM_SEC;
 		break;
 	case AFE_PORT_ID_SECONDARY_TDM_TX_2:
 		slots = tdm_slot[TDM_SEC].num;
 		slot_width = tdm_slot[TDM_SEC].width;
 		slot_offset = tdm_tx_slot_offset[TDM_SEC][TDM_2];
+		tdm_interface = TDM_SEC;
 		break;
 	case AFE_PORT_ID_SECONDARY_TDM_TX_3:
 		slots = tdm_slot[TDM_SEC].num;
 		slot_width = tdm_slot[TDM_SEC].width;
 		slot_offset = tdm_tx_slot_offset[TDM_SEC][TDM_3];
+		tdm_interface = TDM_SEC;
 		break;
 	case AFE_PORT_ID_SECONDARY_TDM_TX_4:
 		slots = tdm_slot[TDM_SEC].num;
 		slot_width = tdm_slot[TDM_SEC].width;
 		slot_offset = tdm_tx_slot_offset[TDM_SEC][TDM_4];
+		tdm_interface = TDM_SEC;
 		break;
 	case AFE_PORT_ID_SECONDARY_TDM_TX_5:
 		slots = tdm_slot[TDM_SEC].num;
 		slot_width = tdm_slot[TDM_SEC].width;
 		slot_offset = tdm_tx_slot_offset[TDM_SEC][TDM_5];
+		tdm_interface = TDM_SEC;
 		break;
 	case AFE_PORT_ID_SECONDARY_TDM_TX_6:
 		slots = tdm_slot[TDM_SEC].num;
 		slot_width = tdm_slot[TDM_SEC].width;
 		slot_offset = tdm_tx_slot_offset[TDM_SEC][TDM_6];
+		tdm_interface = TDM_SEC;
 		break;
 	case AFE_PORT_ID_SECONDARY_TDM_TX_7:
 		slots = tdm_slot[TDM_SEC].num;
 		slot_width = tdm_slot[TDM_SEC].width;
 		slot_offset = tdm_tx_slot_offset[TDM_SEC][TDM_7];
+		tdm_interface = TDM_SEC;
 		break;
 	case AFE_PORT_ID_TERTIARY_TDM_RX:
 		slots = tdm_slot[TDM_TERT].num;
 		slot_width = tdm_slot[TDM_TERT].width;
 		slot_offset = tdm_rx_slot_offset[TDM_TERT][TDM_0];
+		tdm_interface = TDM_TERT;
 		break;
 	case AFE_PORT_ID_TERTIARY_TDM_RX_1:
 		slots = tdm_slot[TDM_TERT].num;
 		slot_width = tdm_slot[TDM_TERT].width;
 		slot_offset = tdm_rx_slot_offset[TDM_TERT][TDM_1];
+		tdm_interface = TDM_TERT;
 		break;
 	case AFE_PORT_ID_TERTIARY_TDM_RX_2:
 		slots = tdm_slot[TDM_TERT].num;
 		slot_width = tdm_slot[TDM_TERT].width;
 		slot_offset = tdm_rx_slot_offset[TDM_TERT][TDM_2];
+		tdm_interface = TDM_TERT;
 		break;
 	case AFE_PORT_ID_TERTIARY_TDM_RX_3:
 		slots = tdm_slot[TDM_TERT].num;
 		slot_width = tdm_slot[TDM_TERT].width;
 		slot_offset = tdm_rx_slot_offset[TDM_TERT][TDM_3];
+		tdm_interface = TDM_TERT;
 		break;
 	case AFE_PORT_ID_TERTIARY_TDM_RX_4:
 		slots = tdm_slot[TDM_TERT].num;
 		slot_width = tdm_slot[TDM_TERT].width;
 		slot_offset = tdm_rx_slot_offset[TDM_TERT][TDM_4];
+		tdm_interface = TDM_TERT;
 		break;
 	case AFE_PORT_ID_TERTIARY_TDM_RX_5:
 		slots = tdm_slot[TDM_TERT].num;
 		slot_width = tdm_slot[TDM_TERT].width;
 		slot_offset = tdm_rx_slot_offset[TDM_TERT][TDM_5];
+		tdm_interface = TDM_TERT;
 		break;
 	case AFE_PORT_ID_TERTIARY_TDM_RX_6:
 		slots = tdm_slot[TDM_TERT].num;
 		slot_width = tdm_slot[TDM_TERT].width;
 		slot_offset = tdm_rx_slot_offset[TDM_TERT][TDM_6];
+		tdm_interface = TDM_TERT;
 		break;
 	case AFE_PORT_ID_TERTIARY_TDM_RX_7:
 		slots = tdm_slot[TDM_TERT].num;
 		slot_width = tdm_slot[TDM_TERT].width;
 		slot_offset = tdm_rx_slot_offset[TDM_TERT][TDM_7];
+		tdm_interface = TDM_TERT;
 		break;
 	case AFE_PORT_ID_TERTIARY_TDM_TX:
 		slots = tdm_slot[TDM_TERT].num;
 		slot_width = tdm_slot[TDM_TERT].width;
 		slot_offset = tdm_tx_slot_offset[TDM_TERT][TDM_0];
+		tdm_interface = TDM_TERT;
 		break;
 	case AFE_PORT_ID_TERTIARY_TDM_TX_1:
 		slots = tdm_slot[TDM_TERT].num;
 		slot_width = tdm_slot[TDM_TERT].width;
 		slot_offset = tdm_tx_slot_offset[TDM_TERT][TDM_1];
+		tdm_interface = TDM_TERT;
 		break;
 	case AFE_PORT_ID_TERTIARY_TDM_TX_2:
 		slots = tdm_slot[TDM_TERT].num;
 		slot_width = tdm_slot[TDM_TERT].width;
 		slot_offset = tdm_tx_slot_offset[TDM_TERT][TDM_2];
+		tdm_interface = TDM_TERT;
 		break;
 	case AFE_PORT_ID_TERTIARY_TDM_TX_3:
 		slots = tdm_slot[TDM_TERT].num;
 		slot_width = tdm_slot[TDM_TERT].width;
 		slot_offset = tdm_tx_slot_offset[TDM_TERT][TDM_3];
+		tdm_interface = TDM_TERT;
 		break;
 	case AFE_PORT_ID_TERTIARY_TDM_TX_4:
 		slots = tdm_slot[TDM_TERT].num;
 		slot_width = tdm_slot[TDM_TERT].width;
 		slot_offset = tdm_tx_slot_offset[TDM_TERT][TDM_4];
+		tdm_interface = TDM_TERT;
 		break;
 	case AFE_PORT_ID_TERTIARY_TDM_TX_5:
 		slots = tdm_slot[TDM_TERT].num;
 		slot_width = tdm_slot[TDM_TERT].width;
 		slot_offset = tdm_tx_slot_offset[TDM_TERT][TDM_5];
+		tdm_interface = TDM_TERT;
 		break;
 	case AFE_PORT_ID_TERTIARY_TDM_TX_6:
 		slots = tdm_slot[TDM_TERT].num;
 		slot_width = tdm_slot[TDM_TERT].width;
 		slot_offset = tdm_tx_slot_offset[TDM_TERT][TDM_6];
+		tdm_interface = TDM_TERT;
 		break;
 	case AFE_PORT_ID_TERTIARY_TDM_TX_7:
 		slots = tdm_slot[TDM_TERT].num;
 		slot_width = tdm_slot[TDM_TERT].width;
 		slot_offset = tdm_tx_slot_offset[TDM_TERT][TDM_7];
+		tdm_interface = TDM_TERT;
 		break;
 	case AFE_PORT_ID_QUATERNARY_TDM_RX:
 		slots = tdm_slot[TDM_QUAT].num;
 		slot_width = tdm_slot[TDM_QUAT].width;
 		slot_offset = tdm_rx_slot_offset[TDM_QUAT][TDM_0];
+		tdm_interface = TDM_QUAT;
 		break;
 	case AFE_PORT_ID_QUATERNARY_TDM_RX_1:
 		slots = tdm_slot[TDM_QUAT].num;
 		slot_width = tdm_slot[TDM_QUAT].width;
 		slot_offset = tdm_rx_slot_offset[TDM_QUAT][TDM_1];
+		tdm_interface = TDM_QUAT;
 		break;
 	case AFE_PORT_ID_QUATERNARY_TDM_RX_2:
 		slots = tdm_slot[TDM_QUAT].num;
 		slot_width = tdm_slot[TDM_QUAT].width;
 		slot_offset = tdm_rx_slot_offset[TDM_QUAT][TDM_2];
+		tdm_interface = TDM_QUAT;
 		break;
 	case AFE_PORT_ID_QUATERNARY_TDM_RX_3:
 		slots = tdm_slot[TDM_QUAT].num;
 		slot_width = tdm_slot[TDM_QUAT].width;
 		slot_offset = tdm_rx_slot_offset[TDM_QUAT][TDM_3];
+		tdm_interface = TDM_QUAT;
 		break;
 	case AFE_PORT_ID_QUATERNARY_TDM_RX_4:
 		slots = tdm_slot[TDM_QUAT].num;
 		slot_width = tdm_slot[TDM_QUAT].width;
 		slot_offset = tdm_rx_slot_offset[TDM_QUAT][TDM_4];
+		tdm_interface = TDM_QUAT;
 		break;
 	case AFE_PORT_ID_QUATERNARY_TDM_RX_5:
 		slots = tdm_slot[TDM_QUAT].num;
 		slot_width = tdm_slot[TDM_QUAT].width;
 		slot_offset = tdm_rx_slot_offset[TDM_QUAT][TDM_5];
+		tdm_interface = TDM_QUAT;
 		break;
 	case AFE_PORT_ID_QUATERNARY_TDM_RX_6:
 		slots = tdm_slot[TDM_QUAT].num;
 		slot_width = tdm_slot[TDM_QUAT].width;
 		slot_offset = tdm_rx_slot_offset[TDM_QUAT][TDM_6];
+		tdm_interface = TDM_QUAT;
 		break;
 	case AFE_PORT_ID_QUATERNARY_TDM_RX_7:
 		slots = tdm_slot[TDM_QUAT].num;
 		slot_width = tdm_slot[TDM_QUAT].width;
 		slot_offset = tdm_rx_slot_offset[TDM_QUAT][TDM_7];
+		tdm_interface = TDM_QUAT;
 		break;
 	case AFE_PORT_ID_QUATERNARY_TDM_TX:
 		slots = tdm_slot[TDM_QUAT].num;
 		slot_width = tdm_slot[TDM_QUAT].width;
 		slot_offset = tdm_tx_slot_offset[TDM_QUAT][TDM_0];
+		tdm_interface = TDM_QUAT;
 		break;
 	case AFE_PORT_ID_QUATERNARY_TDM_TX_1:
 		slots = tdm_slot[TDM_QUAT].num;
 		slot_width = tdm_slot[TDM_QUAT].width;
 		slot_offset = tdm_tx_slot_offset[TDM_QUAT][TDM_1];
+		tdm_interface = TDM_QUAT;
 		break;
 	case AFE_PORT_ID_QUATERNARY_TDM_TX_2:
 		slots = tdm_slot[TDM_QUAT].num;
 		slot_width = tdm_slot[TDM_QUAT].width;
 		slot_offset = tdm_tx_slot_offset[TDM_QUAT][TDM_2];
+		tdm_interface = TDM_QUAT;
 		break;
 	case AFE_PORT_ID_QUATERNARY_TDM_TX_3:
 		slots = tdm_slot[TDM_QUAT].num;
 		slot_width = tdm_slot[TDM_QUAT].width;
 		slot_offset = tdm_tx_slot_offset[TDM_QUAT][TDM_3];
+		tdm_interface = TDM_QUAT;
 		break;
 	case AFE_PORT_ID_QUATERNARY_TDM_TX_4:
 		slots = tdm_slot[TDM_QUAT].num;
 		slot_width = tdm_slot[TDM_QUAT].width;
 		slot_offset = tdm_tx_slot_offset[TDM_QUAT][TDM_4];
+		tdm_interface = TDM_QUAT;
 		break;
 	case AFE_PORT_ID_QUATERNARY_TDM_TX_5:
 		slots = tdm_slot[TDM_QUAT].num;
 		slot_width = tdm_slot[TDM_QUAT].width;
 		slot_offset = tdm_tx_slot_offset[TDM_QUAT][TDM_5];
+		tdm_interface = TDM_QUAT;
 		break;
 	case AFE_PORT_ID_QUATERNARY_TDM_TX_6:
 		slots = tdm_slot[TDM_QUAT].num;
 		slot_width = tdm_slot[TDM_QUAT].width;
 		slot_offset = tdm_tx_slot_offset[TDM_QUAT][TDM_6];
+		tdm_interface = TDM_QUAT;
 		break;
 	case AFE_PORT_ID_QUATERNARY_TDM_TX_7:
 		slots = tdm_slot[TDM_QUAT].num;
 		slot_width = tdm_slot[TDM_QUAT].width;
 		slot_offset = tdm_tx_slot_offset[TDM_QUAT][TDM_7];
+		tdm_interface = TDM_QUAT;
 		break;
 	case AFE_PORT_ID_QUINARY_TDM_RX:
 		slots = tdm_slot[TDM_QUIN].num;
 		slot_width = tdm_slot[TDM_QUIN].width;
 		slot_offset = tdm_rx_slot_offset[TDM_QUIN][TDM_0];
+		tdm_interface = TDM_QUIN;
 		break;
 	case AFE_PORT_ID_QUINARY_TDM_RX_1:
 		slots = tdm_slot[TDM_QUIN].num;
 		slot_width = tdm_slot[TDM_QUIN].width;
 		slot_offset = tdm_rx_slot_offset[TDM_QUIN][TDM_1];
+		tdm_interface = TDM_QUIN;
 		break;
 	case AFE_PORT_ID_QUINARY_TDM_RX_2:
 		slots = tdm_slot[TDM_QUIN].num;
 		slot_width = tdm_slot[TDM_QUIN].width;
 		slot_offset = tdm_rx_slot_offset[TDM_QUIN][TDM_2];
+		tdm_interface = TDM_QUIN;
 		break;
 	case AFE_PORT_ID_QUINARY_TDM_RX_3:
 		slots = tdm_slot[TDM_QUIN].num;
 		slot_width = tdm_slot[TDM_QUIN].width;
 		slot_offset = tdm_rx_slot_offset[TDM_QUIN][TDM_3];
+		tdm_interface = TDM_QUIN;
 		break;
 	case AFE_PORT_ID_QUINARY_TDM_RX_4:
 		slots = tdm_slot[TDM_QUIN].num;
 		slot_width = tdm_slot[TDM_QUIN].width;
 		slot_offset = tdm_rx_slot_offset[TDM_QUIN][TDM_4];
+		tdm_interface = TDM_QUIN;
 		break;
 	case AFE_PORT_ID_QUINARY_TDM_RX_5:
 		slots = tdm_slot[TDM_QUIN].num;
 		slot_width = tdm_slot[TDM_QUIN].width;
 		slot_offset = tdm_rx_slot_offset[TDM_QUIN][TDM_5];
+		tdm_interface = TDM_QUIN;
 		break;
 	case AFE_PORT_ID_QUINARY_TDM_RX_6:
 		slots = tdm_slot[TDM_QUIN].num;
 		slot_width = tdm_slot[TDM_QUIN].width;
 		slot_offset = tdm_rx_slot_offset[TDM_QUIN][TDM_6];
+		tdm_interface = TDM_QUIN;
 		break;
 	case AFE_PORT_ID_QUINARY_TDM_RX_7:
 		slots = tdm_slot[TDM_QUIN].num;
 		slot_width = tdm_slot[TDM_QUIN].width;
 		slot_offset = tdm_rx_slot_offset[TDM_QUIN][TDM_7];
+		tdm_interface = TDM_QUIN;
 		break;
 	case AFE_PORT_ID_QUINARY_TDM_TX:
 		slots = tdm_slot[TDM_QUIN].num;
 		slot_width = tdm_slot[TDM_QUIN].width;
 		slot_offset = tdm_tx_slot_offset[TDM_QUIN][TDM_0];
+		tdm_interface = TDM_QUIN;
 		break;
 	case AFE_PORT_ID_QUINARY_TDM_TX_1:
 		slots = tdm_slot[TDM_QUIN].num;
 		slot_width = tdm_slot[TDM_QUIN].width;
 		slot_offset = tdm_tx_slot_offset[TDM_QUIN][TDM_1];
+		tdm_interface = TDM_QUIN;
 		break;
 	case AFE_PORT_ID_QUINARY_TDM_TX_2:
 		slots = tdm_slot[TDM_QUIN].num;
 		slot_width = tdm_slot[TDM_QUIN].width;
 		slot_offset = tdm_tx_slot_offset[TDM_QUIN][TDM_2];
+		tdm_interface = TDM_QUIN;
 		break;
 	case AFE_PORT_ID_QUINARY_TDM_TX_3:
 		slots = tdm_slot[TDM_QUIN].num;
 		slot_width = tdm_slot[TDM_QUIN].width;
 		slot_offset = tdm_tx_slot_offset[TDM_QUIN][TDM_3];
+		tdm_interface = TDM_QUIN;
 		break;
 	case AFE_PORT_ID_QUINARY_TDM_TX_4:
 		slots = tdm_slot[TDM_QUIN].num;
 		slot_width = tdm_slot[TDM_QUIN].width;
 		slot_offset = tdm_tx_slot_offset[TDM_QUIN][TDM_4];
+		tdm_interface = TDM_QUIN;
 		break;
 	case AFE_PORT_ID_QUINARY_TDM_TX_5:
 		slots = tdm_slot[TDM_QUIN].num;
 		slot_width = tdm_slot[TDM_QUIN].width;
 		slot_offset = tdm_tx_slot_offset[TDM_QUIN][TDM_5];
+		tdm_interface = TDM_QUIN;
 		break;
 	case AFE_PORT_ID_QUINARY_TDM_TX_6:
 		slots = tdm_slot[TDM_QUIN].num;
 		slot_width = tdm_slot[TDM_QUIN].width;
 		slot_offset = tdm_tx_slot_offset[TDM_QUIN][TDM_6];
+		tdm_interface = TDM_QUIN;
 		break;
 	case AFE_PORT_ID_QUINARY_TDM_TX_7:
 		slots = tdm_slot[TDM_QUIN].num;
 		slot_width = tdm_slot[TDM_QUIN].width;
 		slot_offset = tdm_tx_slot_offset[TDM_QUIN][TDM_7];
+		tdm_interface = TDM_QUIN;
 		break;
 	default:
 		pr_err("%s: dai id 0x%x not supported\n",
@@ -1083,7 +1230,10 @@
 		return -EINVAL;
 	}
 
-	slot_mask = tdm_param_set_slot_mask(slots);
+	slot_mask = tdm_param_set_slot_mask(cpu_dai->id,
+				slot_width, slots, tdm_interface);
+	pr_debug("%s: slot_mask :%x\n", __func__, slot_mask);
+
 	if (!slot_mask) {
 		pr_err("%s: invalid slot_mask 0x%x\n",
 			__func__, slot_mask);
@@ -1108,6 +1258,7 @@
 			goto end;
 		}
 	} else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
+
 		ret = snd_soc_dai_set_tdm_slot(cpu_dai, slot_mask, 0,
 					       slots, slot_width);
 		if (ret < 0) {
@@ -3094,18 +3245,45 @@
 	SOC_ENUM_EXT("PRI_TDM_TX_0 SampleRate", tdm_tx_sample_rate,
 			tdm_tx_sample_rate_get,
 			tdm_tx_sample_rate_put),
+	SOC_ENUM_EXT("PRI_TDM_TX_1 SampleRate", tdm_tx_sample_rate,
+			tdm_tx_sample_rate_get,
+			tdm_tx_sample_rate_put),
+	SOC_ENUM_EXT("PRI_TDM_TX_2 SampleRate", tdm_tx_sample_rate,
+			tdm_tx_sample_rate_get,
+			tdm_tx_sample_rate_put),
+	SOC_ENUM_EXT("PRI_TDM_TX_3 SampleRate", tdm_tx_sample_rate,
+			tdm_tx_sample_rate_get,
+			tdm_tx_sample_rate_put),
 	SOC_ENUM_EXT("PRI_TDM_RX_0 Format", tdm_rx_format,
 			tdm_rx_format_get,
 			tdm_rx_format_put),
 	SOC_ENUM_EXT("PRI_TDM_TX_0 Format", tdm_tx_format,
 			tdm_tx_format_get,
 			tdm_tx_format_put),
+	SOC_ENUM_EXT("PRI_TDM_TX_1 Format", tdm_tx_format,
+			tdm_tx_format_get,
+			tdm_tx_format_put),
+	SOC_ENUM_EXT("PRI_TDM_TX_2 Format", tdm_tx_format,
+			tdm_tx_format_get,
+			tdm_tx_format_put),
+	SOC_ENUM_EXT("PRI_TDM_TX_3 Format", tdm_tx_format,
+			tdm_tx_format_get,
+			tdm_tx_format_put),
 	SOC_ENUM_EXT("PRI_TDM_RX_0 Channels", tdm_rx_chs,
 			tdm_rx_ch_get,
 			tdm_rx_ch_put),
 	SOC_ENUM_EXT("PRI_TDM_TX_0 Channels", tdm_tx_chs,
 			tdm_tx_ch_get,
 			tdm_tx_ch_put),
+	SOC_ENUM_EXT("PRI_TDM_TX_1 Channels", tdm_tx_chs,
+			tdm_tx_ch_get,
+			tdm_tx_ch_put),
+	SOC_ENUM_EXT("PRI_TDM_TX_2 Channels", tdm_tx_chs,
+			tdm_tx_ch_get,
+			tdm_tx_ch_put),
+	SOC_ENUM_EXT("PRI_TDM_TX_3 Channels", tdm_tx_chs,
+			tdm_tx_ch_get,
+			tdm_tx_ch_put),
 	SOC_ENUM_EXT("SEC_TDM_RX_0 SampleRate", tdm_rx_sample_rate,
 			tdm_rx_sample_rate_get,
 			tdm_rx_sample_rate_put),
@@ -4751,7 +4929,21 @@
 
 	switch (port_id) {
 	case AFE_PORT_ID_PRIMARY_TDM_RX:
+	case AFE_PORT_ID_PRIMARY_TDM_RX_1:
+	case AFE_PORT_ID_PRIMARY_TDM_RX_2:
+	case AFE_PORT_ID_PRIMARY_TDM_RX_3:
+	case AFE_PORT_ID_PRIMARY_TDM_RX_4:
+	case AFE_PORT_ID_PRIMARY_TDM_RX_5:
+	case AFE_PORT_ID_PRIMARY_TDM_RX_6:
+	case AFE_PORT_ID_PRIMARY_TDM_RX_7:
 	case AFE_PORT_ID_PRIMARY_TDM_TX:
+	case AFE_PORT_ID_PRIMARY_TDM_TX_1:
+	case AFE_PORT_ID_PRIMARY_TDM_TX_2:
+	case AFE_PORT_ID_PRIMARY_TDM_TX_3:
+	case AFE_PORT_ID_PRIMARY_TDM_TX_4:
+	case AFE_PORT_ID_PRIMARY_TDM_TX_5:
+	case AFE_PORT_ID_PRIMARY_TDM_TX_6:
+	case AFE_PORT_ID_PRIMARY_TDM_TX_7:
 		tdm_mode = TDM_PRI;
 		break;
 	case AFE_PORT_ID_SECONDARY_TDM_RX: