ASoC: sdm845: update TDM configurations for TX and RX

Update TDM configurations for primary, secondary, and
tertiary TDM interfaces.

Change-Id: I1729ad4d8563063802dfae9128e290d58ad43497
Signed-off-by: Xiaoyu Ye <benyxy@codeaurora.org>
diff --git a/asoc/sdm845.c b/asoc/sdm845.c
index 5721c32..7294882 100644
--- a/asoc/sdm845.c
+++ b/asoc/sdm845.c
@@ -70,7 +70,6 @@
 #define WCN_CDC_SLIM_TX_CH_MAX 3
 
 #define TDM_CHANNEL_MAX 8
-#define TDM_SLOT_OFFSET_MAX 8
 
 #define MSM_HIFI_ON 1
 
@@ -311,17 +310,6 @@
 	}
 };
 
-/*TDM default offset currently only supporting TDM_RX_0 and TDM_TX_0 */
-static unsigned int tdm_slot_offset[TDM_PORT_MAX][TDM_SLOT_OFFSET_MAX] = {
-	{0, 4, 8, 12, 16, 20, 24, 28},/* TX_0 | RX_0 */
-	{AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_1 | RX_1 */
-	{AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_2 | RX_2 */
-	{AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_3 | RX_3 */
-	{AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_4 | RX_4 */
-	{AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_5 | RX_5 */
-	{AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_6 | RX_6 */
-	{AFE_SLOT_MAPPING_OFFSET_INVALID},/* TX_7 | RX_7 */
-};
 
 /* Default configuration of slimbus channels */
 static struct dev_config slim_rx_cfg[] = {
@@ -431,8 +419,8 @@
 				    "Five", "Six", "Seven", "Eight"};
 static char const *tdm_bit_format_text[] = {"S16_LE", "S24_LE", "S32_LE"};
 static char const *tdm_sample_rate_text[] = {"KHZ_8", "KHZ_16", "KHZ_32",
-					     "KHZ_44P1", "KHZ_48", "KHZ_96",
-					     "KHZ_192", "KHZ_352P8", "KHZ_384"};
+					     "KHZ_48", "KHZ_176P4",
+					     "KHZ_352P8"};
 static const char *const auxpcm_rate_text[] = {"KHZ_8", "KHZ_16"};
 static char const *mi2s_rate_text[] = {"KHZ_8", "KHZ_16",
 				      "KHZ_32", "KHZ_44P1", "KHZ_48",
@@ -1614,23 +1602,14 @@
 		sample_rate = SAMPLING_RATE_32KHZ;
 		break;
 	case 3:
-		sample_rate = SAMPLING_RATE_44P1KHZ;
-		break;
-	case 4:
 		sample_rate = SAMPLING_RATE_48KHZ;
 		break;
+	case 4:
+		sample_rate = SAMPLING_RATE_176P4KHZ;
+		break;
 	case 5:
-		sample_rate = SAMPLING_RATE_96KHZ;
-		break;
-	case 6:
-		sample_rate = SAMPLING_RATE_192KHZ;
-		break;
-	case 7:
 		sample_rate = SAMPLING_RATE_352P8KHZ;
 		break;
-	case 8:
-		sample_rate = SAMPLING_RATE_384KHZ;
-		break;
 	default:
 		sample_rate = SAMPLING_RATE_48KHZ;
 		break;
@@ -1668,26 +1647,17 @@
 	case SAMPLING_RATE_32KHZ:
 		sample_rate_val = 2;
 		break;
-	case SAMPLING_RATE_44P1KHZ:
+	case SAMPLING_RATE_48KHZ:
 		sample_rate_val = 3;
 		break;
-	case SAMPLING_RATE_48KHZ:
+	case SAMPLING_RATE_176P4KHZ:
 		sample_rate_val = 4;
 		break;
-	case SAMPLING_RATE_96KHZ:
-		sample_rate_val = 5;
-		break;
-	case SAMPLING_RATE_192KHZ:
-		sample_rate_val = 6;
-		break;
 	case SAMPLING_RATE_352P8KHZ:
-		sample_rate_val = 7;
-		break;
-	case SAMPLING_RATE_384KHZ:
-		sample_rate_val = 8;
+		sample_rate_val = 5;
 		break;
 	default:
-		sample_rate_val = 4;
+		sample_rate_val = 3;
 		break;
 	}
 	return sample_rate_val;
@@ -4491,15 +4461,46 @@
 	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;
+	int slot_width = 32;
+	int channels, slots;
 	unsigned int slot_mask, rate, clk_freq;
 	unsigned int slot_offset[8] = {0, 4, 8, 12, 16, 20, 24, 28};
 
-	slot_width = 32;
 	pr_debug("%s: dai id = 0x%x\n", __func__, cpu_dai->id);
 
-	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+	/* currently only supporting TDM_RX_0 and TDM_TX_0 */
+	switch (cpu_dai->id) {
+	case AFE_PORT_ID_PRIMARY_TDM_RX:
+		slots = tdm_rx_cfg[TDM_PRI][TDM_0].channels;
+		break;
+	case AFE_PORT_ID_SECONDARY_TDM_RX:
+		slots = tdm_rx_cfg[TDM_SEC][TDM_0].channels;
+		break;
+	case AFE_PORT_ID_TERTIARY_TDM_RX:
+		slots = tdm_rx_cfg[TDM_TERT][TDM_0].channels;
+		break;
+	case AFE_PORT_ID_QUATERNARY_TDM_RX:
 		slots = tdm_rx_cfg[TDM_QUAT][TDM_0].channels;
+		break;
+	case AFE_PORT_ID_PRIMARY_TDM_TX:
+		slots = tdm_tx_cfg[TDM_PRI][TDM_0].channels;
+		break;
+	case AFE_PORT_ID_SECONDARY_TDM_TX:
+		slots = tdm_tx_cfg[TDM_SEC][TDM_0].channels;
+		break;
+	case AFE_PORT_ID_TERTIARY_TDM_TX:
+		slots = tdm_tx_cfg[TDM_TERT][TDM_0].channels;
+		break;
+	case AFE_PORT_ID_QUATERNARY_TDM_TX:
+		slots = tdm_tx_cfg[TDM_QUAT][TDM_0].channels;
+		break;
+	default:
+		pr_err("%s: dai id 0x%x not supported\n",
+			__func__, cpu_dai->id);
+		return -EINVAL;
+	}
+
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 		/*2 slot config - bits 0 and 1 set for the first two slots */
 		slot_mask = 0x0000FFFF >> (16-slots);
 		channels = slots;
@@ -4523,7 +4524,6 @@
 			goto end;
 		}
 	} else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
-		slots = tdm_tx_cfg[TDM_QUAT][TDM_0].channels;
 		/*2 slot config - bits 0 and 1 set for the first two slots */
 		slot_mask = 0x0000FFFF >> (16-slots);
 		channels = slots;
@@ -4568,14 +4568,19 @@
 {
 	int ret = 0;
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
 	struct snd_soc_card *card = rtd->card;
 	struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
 	struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info;
 
-	ret = msm_set_pinctrl(pinctrl_info, STATE_TDM_ACTIVE);
-	if (ret)
-		pr_err("%s: TDM TLMM pinctrl set failed with %d\n",
-			__func__, ret);
+	/* currently only supporting TDM_RX_0 and TDM_TX_0 */
+	if ((cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_RX) ||
+		(cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_TX)) {
+		ret = msm_set_pinctrl(pinctrl_info, STATE_TDM_ACTIVE);
+		if (ret)
+			pr_err("%s: TDM TLMM pinctrl set failed with %d\n",
+				__func__, ret);
+	}
 
 	return ret;
 }
@@ -4584,15 +4589,19 @@
 {
 	int ret = 0;
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
 	struct snd_soc_card *card = rtd->card;
 	struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
 	struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info;
 
-	ret = msm_set_pinctrl(pinctrl_info, STATE_DISABLE);
-	if (ret)
-		pr_err("%s: TDM TLMM pinctrl set failed with %d\n",
-			__func__, ret);
-
+	/* currently only supporting TDM_RX_0 and TDM_TX_0 */
+	if ((cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_RX) ||
+		(cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_TX)) {
+		ret = msm_set_pinctrl(pinctrl_info, STATE_DISABLE);
+		if (ret)
+			pr_err("%s: TDM TLMM pinctrl set failed with %d\n",
+				__func__, ret);
+	}
 }
 
 static struct snd_soc_ops sdm845_tdm_be_ops = {
@@ -4726,157 +4735,6 @@
 	.shutdown = msm_aux_pcm_snd_shutdown,
 };
 
-static unsigned int tdm_param_set_slot_mask(u16 port_id, int slot_width,
-					    int slots)
-{
-	unsigned int slot_mask = 0;
-	int i, j;
-	unsigned int *slot_offset;
-
-	for (i = TDM_0; i < TDM_PORT_MAX; i++) {
-		slot_offset = tdm_slot_offset[i];
-
-		for (j = 0; j < TDM_SLOT_OFFSET_MAX; j++) {
-			if (slot_offset[j] != AFE_SLOT_MAPPING_OFFSET_INVALID)
-				slot_mask |=
-				(1 << ((slot_offset[j] * 8) / slot_width));
-			else
-				break;
-		}
-	}
-
-	return slot_mask;
-}
-
-static int msm_tdm_snd_hw_params(struct snd_pcm_substream *substream,
-				     struct snd_pcm_hw_params *params)
-{
-	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;
-	unsigned int slot_mask;
-	unsigned int *slot_offset;
-	int offset_channels = 0;
-	int i;
-
-	pr_debug("%s: dai id = 0x%x\n", __func__, cpu_dai->id);
-
-	channels = params_channels(params);
-	switch (channels) {
-	case 1:
-	case 2:
-	case 3:
-	case 4:
-	case 5:
-	case 6:
-	case 7:
-	case 8:
-		switch (params_format(params)) {
-		case SNDRV_PCM_FORMAT_S32_LE:
-		case SNDRV_PCM_FORMAT_S24_LE:
-		case SNDRV_PCM_FORMAT_S16_LE:
-		/*
-		 * Up to 8 channels HW config should
-		 * use 32 bit slot width for max support of
-		 * stream bit width. (slot_width > bit_width)
-		 */
-			slot_width = 32;
-			break;
-		default:
-			pr_err("%s: invalid param format 0x%x\n",
-				__func__, params_format(params));
-			return -EINVAL;
-		}
-		slots = 8;
-		slot_mask = tdm_param_set_slot_mask(cpu_dai->id,
-						    slot_width,
-						    slots);
-		if (!slot_mask) {
-			pr_err("%s: invalid slot_mask 0x%x\n",
-				__func__, slot_mask);
-			return -EINVAL;
-		}
-		break;
-	default:
-		pr_err("%s: invalid param channels %d\n",
-			__func__, channels);
-		return -EINVAL;
-	}
-	/* currently only supporting TDM_RX_0 and TDM_TX_0 */
-	switch (cpu_dai->id) {
-	case AFE_PORT_ID_PRIMARY_TDM_RX:
-	case AFE_PORT_ID_SECONDARY_TDM_RX:
-	case AFE_PORT_ID_TERTIARY_TDM_RX:
-	case AFE_PORT_ID_QUATERNARY_TDM_RX:
-	case AFE_PORT_ID_PRIMARY_TDM_TX:
-	case AFE_PORT_ID_SECONDARY_TDM_TX:
-	case AFE_PORT_ID_TERTIARY_TDM_TX:
-	case AFE_PORT_ID_QUATERNARY_TDM_TX:
-		slot_offset = tdm_slot_offset[TDM_0];
-		break;
-	default:
-		pr_err("%s: dai id 0x%x not supported\n",
-			__func__, cpu_dai->id);
-		return -EINVAL;
-	}
-
-	for (i = 0; i < TDM_SLOT_OFFSET_MAX; i++) {
-		if (slot_offset[i] != AFE_SLOT_MAPPING_OFFSET_INVALID)
-			offset_channels++;
-		else
-			break;
-	}
-
-	if (offset_channels == 0) {
-		pr_err("%s: slot offset not supported, offset_channels %d\n",
-			__func__, offset_channels);
-		return -EINVAL;
-	}
-
-	if (channels > offset_channels) {
-		pr_err("%s: channels %d exceed offset_channels %d\n",
-			__func__, channels, offset_channels);
-		return -EINVAL;
-	}
-
-	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-		ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, slot_mask,
-					       slots, slot_width);
-		if (ret < 0) {
-			pr_err("%s: failed to set tdm slot, err:%d\n",
-				__func__, ret);
-			goto err;
-		}
-
-		ret = snd_soc_dai_set_channel_map(cpu_dai, 0, NULL,
-						  channels, slot_offset);
-		if (ret < 0) {
-			pr_err("%s: failed to set channel map, err:%d\n",
-				__func__, ret);
-			goto err;
-		}
-	} else {
-		ret = snd_soc_dai_set_tdm_slot(cpu_dai, slot_mask, 0,
-					       slots, slot_width);
-		if (ret < 0) {
-			pr_err("%s: failed to set tdm slot, err:%d\n",
-				__func__, ret);
-			goto err;
-		}
-
-		ret = snd_soc_dai_set_channel_map(cpu_dai, channels,
-						  slot_offset, 0, NULL);
-		if (ret < 0) {
-			pr_err("%s: failed to set channel map, err:%d\n",
-				__func__, ret);
-			goto err;
-		}
-	}
-err:
-	return ret;
-}
-
 static struct snd_soc_ops msm_be_ops = {
 	.hw_params = msm_snd_hw_params,
 };
@@ -4889,9 +4747,6 @@
 	.hw_params = msm_wcn_hw_params,
 };
 
-static struct snd_soc_ops msm_tdm_be_ops = {
-	.hw_params = msm_tdm_snd_hw_params
-};
 
 /* Digital audio interface glue - connects codec <---> CPU */
 static struct snd_soc_dai_link msm_common_dai_links[] = {
@@ -5670,7 +5525,7 @@
 		.dpcm_playback = 1,
 		.id = MSM_BACKEND_DAI_PRI_TDM_RX_0,
 		.be_hw_params_fixup = msm_be_hw_params_fixup,
-		.ops = &msm_tdm_be_ops,
+		.ops = &sdm845_tdm_be_ops,
 		.ignore_suspend = 1,
 	},
 	{
@@ -5684,7 +5539,7 @@
 		.dpcm_capture = 1,
 		.id = MSM_BACKEND_DAI_PRI_TDM_TX_0,
 		.be_hw_params_fixup = msm_be_hw_params_fixup,
-		.ops = &msm_tdm_be_ops,
+		.ops = &sdm845_tdm_be_ops,
 		.ignore_suspend = 1,
 	},
 	{
@@ -5698,7 +5553,7 @@
 		.dpcm_playback = 1,
 		.id = MSM_BACKEND_DAI_SEC_TDM_RX_0,
 		.be_hw_params_fixup = msm_be_hw_params_fixup,
-		.ops = &msm_tdm_be_ops,
+		.ops = &sdm845_tdm_be_ops,
 		.ignore_suspend = 1,
 	},
 	{
@@ -5712,7 +5567,7 @@
 		.dpcm_capture = 1,
 		.id = MSM_BACKEND_DAI_SEC_TDM_TX_0,
 		.be_hw_params_fixup = msm_be_hw_params_fixup,
-		.ops = &msm_tdm_be_ops,
+		.ops = &sdm845_tdm_be_ops,
 		.ignore_suspend = 1,
 	},
 	{
@@ -5726,7 +5581,7 @@
 		.dpcm_playback = 1,
 		.id = MSM_BACKEND_DAI_TERT_TDM_RX_0,
 		.be_hw_params_fixup = msm_be_hw_params_fixup,
-		.ops = &msm_tdm_be_ops,
+		.ops = &sdm845_tdm_be_ops,
 		.ignore_suspend = 1,
 	},
 	{
@@ -5740,7 +5595,7 @@
 		.dpcm_capture = 1,
 		.id = MSM_BACKEND_DAI_TERT_TDM_TX_0,
 		.be_hw_params_fixup = msm_be_hw_params_fixup,
-		.ops = &msm_tdm_be_ops,
+		.ops = &sdm845_tdm_be_ops,
 		.ignore_suspend = 1,
 	},
 	{