Browse Source

asoc: Add support to handle SPDIF input and output interfaces

Support two SPDIF input and two SPDIF output interfaces in AFE.

Change-Id: Ie2eb97e85c3b21cb112282dbdf0049a271e7cc93
Signed-off-by: Ralf Herz <[email protected]>
Ralf Herz 6 years ago
parent
commit
c8701f776a
3 changed files with 721 additions and 89 deletions
  1. 364 33
      asoc/msm-dai-q6-v2.c
  2. 349 54
      asoc/msm-pcm-routing-v2.c
  3. 8 2
      asoc/msm-pcm-routing-v2.h

+ 364 - 33
asoc/msm-dai-q6-v2.c

@@ -216,7 +216,14 @@ struct msm_dai_q6_spdif_dai_data {
 	u32 rate;
 	u32 channels;
 	u32 bitwidth;
+	u16 port_id;
 	struct afe_spdif_port_config spdif_port;
+	struct afe_event_fmt_update fmt_event;
+};
+
+struct msm_dai_q6_spdif_event_msg {
+	struct afe_port_mod_evt_rsp_hdr  evt_hdr;
+	struct afe_event_fmt_update      fmt_event;
 };
 
 struct msm_dai_q6_mi2s_dai_config {
@@ -1398,15 +1405,89 @@ static int msm_dai_q6_spdif_format_get(struct snd_kcontrol *kcontrol,
 	return 0;
 }
 
+static int msm_dai_q6_spdif_source_put(struct snd_kcontrol *kcontrol,
+		struct snd_ctl_elem_value *ucontrol)
+{
+
+	struct msm_dai_q6_spdif_dai_data *dai_data = kcontrol->private_data;
+	int value = ucontrol->value.integer.value[0];
+
+	dai_data->spdif_port.cfg.src_sel = value;
+	pr_debug("%s: value = %d\n", __func__, value);
+	return 0;
+}
+
+static int msm_dai_q6_spdif_source_get(struct snd_kcontrol *kcontrol,
+		struct snd_ctl_elem_value *ucontrol)
+{
+
+	struct msm_dai_q6_spdif_dai_data *dai_data = kcontrol->private_data;
+
+	ucontrol->value.integer.value[0] =
+		dai_data->spdif_port.cfg.src_sel;
+	return 0;
+}
+
+static int msm_dai_q6_spdif_ext_state_get(struct snd_kcontrol *kcontrol,
+		struct snd_ctl_elem_value *ucontrol)
+{
+
+	struct msm_dai_q6_spdif_dai_data *dai_data = kcontrol->private_data;
+
+	ucontrol->value.integer.value[0] =
+		dai_data->fmt_event.status & 0x3;
+	return 0;
+}
+
+static int msm_dai_q6_spdif_ext_format_get(struct snd_kcontrol *kcontrol,
+		struct snd_ctl_elem_value *ucontrol)
+{
+
+	struct msm_dai_q6_spdif_dai_data *dai_data = kcontrol->private_data;
+
+	ucontrol->value.integer.value[0] =
+		dai_data->fmt_event.data_format & 0x1;
+	return 0;
+}
+
+static int msm_dai_q6_spdif_ext_rate_get(struct snd_kcontrol *kcontrol,
+		struct snd_ctl_elem_value *ucontrol)
+{
+
+	struct msm_dai_q6_spdif_dai_data *dai_data = kcontrol->private_data;
+
+	ucontrol->value.integer.value[0] =
+		dai_data->fmt_event.sample_rate;
+	return 0;
+}
+
 static const char * const spdif_format[] = {
 	"LPCM",
 	"Compr"
 };
 
-static const struct soc_enum spdif_config_enum[] = {
-	SOC_ENUM_SINGLE_EXT(2, spdif_format),
+static const char * const spdif_source[] = {
+	"Optical", "EXT-ARC", "Coaxial", "VT-ARC"
+};
+
+static const char * const spdif_state[] = {
+	"Inactive", "Active", "EOS"
+};
+
+static const struct soc_enum spdif_rx_config_enum[] = {
+	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spdif_format), spdif_format),
+};
+
+static const struct soc_enum spdif_tx_config_enum[] = {
+	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spdif_source), spdif_source),
+	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spdif_format), spdif_format),
 };
 
+static const struct soc_enum spdif_tx_status_enum[] = {
+	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spdif_state), spdif_state),
+	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(spdif_format), spdif_format),
+ };
+
 static int msm_dai_q6_spdif_chstatus_put(struct snd_kcontrol *kcontrol,
 		struct snd_ctl_elem_value *ucontrol)
 {
@@ -1428,7 +1509,7 @@ static int msm_dai_q6_spdif_chstatus_put(struct snd_kcontrol *kcontrol,
 				__func__);
 		ret = afe_send_spdif_ch_status_cfg(
 				&dai_data->spdif_port.ch_status,
-				AFE_PORT_ID_SPDIF_RX);
+				dai_data->port_id);
 	}
 	return ret;
 }
@@ -1453,7 +1534,8 @@ static int msm_dai_q6_spdif_chstatus_info(struct snd_kcontrol *kcontrol,
 	return 0;
 }
 
-static const struct snd_kcontrol_new spdif_config_controls[] = {
+static const struct snd_kcontrol_new spdif_rx_config_controls[] = {
+	/* Primary SPDIF output */
 	{
 		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
 				SNDRV_CTL_ELEM_ACCESS_INACTIVE),
@@ -1463,11 +1545,76 @@ static const struct snd_kcontrol_new spdif_config_controls[] = {
 		.get    =   msm_dai_q6_spdif_chstatus_get,
 		.put    =   msm_dai_q6_spdif_chstatus_put,
 	},
-	SOC_ENUM_EXT("SPDIF RX Format", spdif_config_enum[0],
+	SOC_ENUM_EXT("PRI SPDIF RX Format", spdif_rx_config_enum[0],
+			msm_dai_q6_spdif_format_get,
+			msm_dai_q6_spdif_format_put),
+	/* Secondary SPDIF output */
+	{
+		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
+				SNDRV_CTL_ELEM_ACCESS_INACTIVE),
+		.iface  =   SNDRV_CTL_ELEM_IFACE_PCM,
+		.name   =   SNDRV_CTL_NAME_IEC958("SEC", PLAYBACK, PCM_STREAM),
+		.info   =   msm_dai_q6_spdif_chstatus_info,
+		.get    =   msm_dai_q6_spdif_chstatus_get,
+		.put    =   msm_dai_q6_spdif_chstatus_put,
+	},
+	SOC_ENUM_EXT("SEC SPDIF RX Format", spdif_rx_config_enum[0],
 			msm_dai_q6_spdif_format_get,
 			msm_dai_q6_spdif_format_put)
 };
 
+static const struct snd_kcontrol_new spdif_tx_config_controls[] = {
+	SOC_ENUM_EXT("PRI SPDIF TX Source", spdif_tx_config_enum[0],
+			msm_dai_q6_spdif_source_get,
+			msm_dai_q6_spdif_source_put),
+	SOC_ENUM_EXT("PRI SPDIF TX Format", spdif_tx_config_enum[1],
+			msm_dai_q6_spdif_format_get,
+			msm_dai_q6_spdif_format_put),
+	SOC_ENUM_EXT("SEC SPDIF TX Source", spdif_tx_config_enum[0],
+			msm_dai_q6_spdif_source_get,
+			msm_dai_q6_spdif_source_put),
+	SOC_ENUM_EXT("SEC SPDIF TX Format", spdif_tx_config_enum[1],
+			msm_dai_q6_spdif_format_get,
+			msm_dai_q6_spdif_format_put)
+};
+
+static const struct snd_kcontrol_new spdif_tx_status_controls[] = {
+	SOC_ENUM_EXT("PRI SPDIF TX EXT State", spdif_tx_status_enum[0],
+			msm_dai_q6_spdif_ext_state_get, NULL),
+	SOC_ENUM_EXT("PRI SPDIF TX EXT Format", spdif_tx_status_enum[1],
+			msm_dai_q6_spdif_ext_format_get, NULL),
+	SOC_SINGLE_EXT("PRI SPDIF TX EXT Rate", 0, 0, 192000, 0,
+			msm_dai_q6_spdif_ext_rate_get, NULL),
+	SOC_ENUM_EXT("SEC SPDIF TX EXT State", spdif_tx_status_enum[0],
+			msm_dai_q6_spdif_ext_state_get, NULL),
+	SOC_ENUM_EXT("SEC SPDIF TX EXT Format", spdif_tx_status_enum[1],
+			msm_dai_q6_spdif_ext_format_get, NULL),
+	SOC_SINGLE_EXT("SEC SPDIF TX EXT Rate", 0, 0, 192000, 0,
+			msm_dai_q6_spdif_ext_rate_get, NULL)
+};
+
+static void msm_dai_q6_spdif_process_event(uint32_t opcode, uint32_t token,
+		uint32_t *payload, void *private_data)
+{
+	struct msm_dai_q6_spdif_event_msg *evt;
+	struct msm_dai_q6_spdif_dai_data *dai_data;
+
+	evt = (struct msm_dai_q6_spdif_event_msg *)payload;
+	dai_data = (struct msm_dai_q6_spdif_dai_data *)private_data;
+
+	pr_debug("%s: old state %d, fmt %d, rate %d\n",
+			__func__, dai_data->fmt_event.status,
+			dai_data->fmt_event.data_format,
+			dai_data->fmt_event.sample_rate);
+	pr_debug("%s: new state %d, fmt %d, rate %d\n",
+			__func__, evt->fmt_event.status,
+			evt->fmt_event.data_format,
+			evt->fmt_event.sample_rate);
+
+	dai_data->fmt_event.status = evt->fmt_event.status;
+	dai_data->fmt_event.data_format = evt->fmt_event.data_format;
+	dai_data->fmt_event.sample_rate = evt->fmt_event.sample_rate;
+}
 
 static int msm_dai_q6_spdif_hw_params(struct snd_pcm_substream *substream,
 		struct snd_pcm_hw_params *params,
@@ -1475,7 +1622,6 @@ static int msm_dai_q6_spdif_hw_params(struct snd_pcm_substream *substream,
 {
 	struct msm_dai_q6_spdif_dai_data *dai_data = dev_get_drvdata(dai->dev);
 
-	dai->id = AFE_PORT_ID_SPDIF_RX;
 	dai_data->channels = params_channels(params);
 	dai_data->spdif_port.cfg.num_channels = dai_data->channels;
 	switch (params_format(params)) {
@@ -1496,7 +1642,7 @@ static int msm_dai_q6_spdif_hw_params(struct snd_pcm_substream *substream,
 	dai_data->bitwidth = dai_data->spdif_port.cfg.bit_width;
 	dai_data->spdif_port.cfg.sample_rate = dai_data->rate;
 	dai_data->spdif_port.cfg.spdif_cfg_minor_version =
-		AFE_API_VERSION_SPDIF_CONFIG;
+		AFE_API_VERSION_SPDIF_CONFIG_V2;
 	dev_dbg(dai->dev, " channel %d sample rate %d bit width %d\n",
 			dai_data->channels, dai_data->rate,
 			dai_data->spdif_port.cfg.bit_width);
@@ -1520,13 +1666,14 @@ static void msm_dai_q6_spdif_shutdown(struct snd_pcm_substream *substream,
 	if (rc < 0)
 		dev_err(dai->dev, "fail to close AFE port\n");
 
+	dai_data->fmt_event.status = 0; /* report invalid line state */
+
 	pr_debug("%s: dai_data->status_mask = %ld\n", __func__,
 			*dai_data->status_mask);
 
 	clear_bit(STATUS_PORT_STARTED, dai_data->status_mask);
 }
 
-
 static int msm_dai_q6_spdif_prepare(struct snd_pcm_substream *substream,
 		struct snd_soc_dai *dai)
 {
@@ -1534,6 +1681,15 @@ static int msm_dai_q6_spdif_prepare(struct snd_pcm_substream *substream,
 	int rc = 0;
 
 	if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
+		rc = afe_spdif_reg_event_cfg(dai->id,
+				AFE_MODULE_REGISTER_EVENT_FLAG,
+				msm_dai_q6_spdif_process_event,
+				dai_data);
+		if (rc < 0)
+			dev_err(dai->dev,
+				"fail to register event for port 0x%x\n",
+				dai->id);
+
 		rc = afe_spdif_port_start(dai->id, &dai_data->spdif_port,
 				dai_data->rate);
 		if (rc < 0)
@@ -1550,7 +1706,6 @@ static int msm_dai_q6_spdif_prepare(struct snd_pcm_substream *substream,
 static int msm_dai_q6_spdif_dai_probe(struct snd_soc_dai *dai)
 {
 	struct msm_dai_q6_spdif_dai_data *dai_data;
-	const struct snd_kcontrol_new *kcontrol;
 	int rc = 0;
 	struct snd_soc_dapm_route intercon;
 	struct snd_soc_dapm_context *dapm;
@@ -1563,17 +1718,67 @@ static int msm_dai_q6_spdif_dai_probe(struct snd_soc_dai *dai)
 			GFP_KERNEL);
 
 	if (!dai_data) {
-		dev_err(dai->dev, "DAI-%d: fail to allocate dai data\n",
-				AFE_PORT_ID_SPDIF_RX);
 		rc = -ENOMEM;
 	} else
 		dev_set_drvdata(dai->dev, dai_data);
 
-	kcontrol = &spdif_config_controls[1];
-	dapm = snd_soc_component_get_dapm(dai->component);
+	dai->id = dai->driver->id;
+	dai_data->port_id = dai->id;
+
+	switch (dai->id) {
+	case AFE_PORT_ID_PRIMARY_SPDIF_RX:
+		rc = snd_ctl_add(dai->component->card->snd_card,
+				 snd_ctl_new1(&spdif_rx_config_controls[1],
+				 dai_data));
+		break;
+	case AFE_PORT_ID_SECONDARY_SPDIF_RX:
+		rc = snd_ctl_add(dai->component->card->snd_card,
+				 snd_ctl_new1(&spdif_rx_config_controls[3],
+				 dai_data));
+		break;
+	case AFE_PORT_ID_PRIMARY_SPDIF_TX:
+		rc = snd_ctl_add(dai->component->card->snd_card,
+				snd_ctl_new1(&spdif_tx_config_controls[0],
+				dai_data));
+		rc = snd_ctl_add(dai->component->card->snd_card,
+				snd_ctl_new1(&spdif_tx_config_controls[1],
+				dai_data));
+
+		rc = snd_ctl_add(dai->component->card->snd_card,
+				snd_ctl_new1(&spdif_tx_status_controls[0],
+				dai_data));
+		rc = snd_ctl_add(dai->component->card->snd_card,
+				snd_ctl_new1(&spdif_tx_status_controls[1],
+				dai_data));
+		rc = snd_ctl_add(dai->component->card->snd_card,
+				snd_ctl_new1(&spdif_tx_status_controls[2],
+				dai_data));
+		break;
+	case AFE_PORT_ID_SECONDARY_SPDIF_TX:
+		rc = snd_ctl_add(dai->component->card->snd_card,
+				snd_ctl_new1(&spdif_tx_config_controls[2],
+				dai_data));
+		rc = snd_ctl_add(dai->component->card->snd_card,
+				snd_ctl_new1(&spdif_tx_config_controls[3],
+				dai_data));
+
+		rc = snd_ctl_add(dai->component->card->snd_card,
+				snd_ctl_new1(&spdif_tx_status_controls[3],
+				dai_data));
+		rc = snd_ctl_add(dai->component->card->snd_card,
+				snd_ctl_new1(&spdif_tx_status_controls[4],
+				dai_data));
+		rc = snd_ctl_add(dai->component->card->snd_card,
+				snd_ctl_new1(&spdif_tx_status_controls[5],
+				dai_data));
+		break;
+	}
+	if (rc < 0)
+		dev_err(dai->dev,
+			"%s: err add config ctl, DAI = %s\n",
+			__func__, dai->name);
 
-	rc = snd_ctl_add(dai->component->card->snd_card,
-			snd_ctl_new1(kcontrol, dai_data));
+	dapm = snd_soc_component_get_dapm(dai->component);
 
 	memset(&intercon, 0, sizeof(intercon));
 	if (!rc && dai && dai->driver) {
@@ -1610,6 +1815,15 @@ static int msm_dai_q6_spdif_dai_remove(struct snd_soc_dai *dai)
 
 	/* If AFE port is still up, close it */
 	if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
+		rc = afe_spdif_reg_event_cfg(dai->id,
+				AFE_MODULE_DEREGISTER_EVENT_FLAG,
+				NULL,
+				dai_data);
+		if (rc < 0)
+			dev_err(dai->dev,
+				"fail to deregister event for port 0x%x\n",
+				dai->id);
+
 		rc = afe_close(dai->id); /* can block */
 		if (rc < 0)
 			dev_err(dai->dev, "fail to close AFE port\n");
@@ -1628,21 +1842,106 @@ static struct snd_soc_dai_ops msm_dai_q6_spdif_ops = {
 	.shutdown	= msm_dai_q6_spdif_shutdown,
 };
 
-static struct snd_soc_dai_driver msm_dai_q6_spdif_spdif_rx_dai = {
-	.playback = {
-		.stream_name = "SPDIF Playback",
-		.aif_name = "SPDIF_RX",
-		.rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
-			SNDRV_PCM_RATE_16000,
-		.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
-		.channels_min = 1,
-		.channels_max = 4,
-		.rate_min = 8000,
-		.rate_max = 48000,
+static struct snd_soc_dai_driver msm_dai_q6_spdif_spdif_rx_dai[] = {
+	{
+		.playback = {
+			.stream_name = "Primary SPDIF Playback",
+			.aif_name = "PRI_SPDIF_RX",
+			.rates = SNDRV_PCM_RATE_32000 |
+				 SNDRV_PCM_RATE_44100 |
+				 SNDRV_PCM_RATE_48000 |
+				 SNDRV_PCM_RATE_88200 |
+				 SNDRV_PCM_RATE_96000 |
+				 SNDRV_PCM_RATE_176400 |
+				 SNDRV_PCM_RATE_192000,
+			.formats = SNDRV_PCM_FMTBIT_S16_LE |
+				   SNDRV_PCM_FMTBIT_S24_LE,
+			.channels_min = 1,
+			.channels_max = 2,
+			.rate_min = 32000,
+			.rate_max = 192000,
+		},
+		.name = "PRI_SPDIF_RX",
+		.ops = &msm_dai_q6_spdif_ops,
+		.id = AFE_PORT_ID_PRIMARY_SPDIF_RX,
+		.probe = msm_dai_q6_spdif_dai_probe,
+		.remove = msm_dai_q6_spdif_dai_remove,
+	},
+	{
+		.playback = {
+			.stream_name = "Secondary SPDIF Playback",
+			.aif_name = "SEC_SPDIF_RX",
+			.rates = SNDRV_PCM_RATE_32000 |
+				 SNDRV_PCM_RATE_44100 |
+				 SNDRV_PCM_RATE_48000 |
+				 SNDRV_PCM_RATE_88200 |
+				 SNDRV_PCM_RATE_96000 |
+				 SNDRV_PCM_RATE_176400 |
+				 SNDRV_PCM_RATE_192000,
+			.formats = SNDRV_PCM_FMTBIT_S16_LE |
+				   SNDRV_PCM_FMTBIT_S24_LE,
+			.channels_min = 1,
+			.channels_max = 2,
+			.rate_min = 32000,
+			.rate_max = 192000,
+		},
+		.name = "SEC_SPDIF_RX",
+		.ops = &msm_dai_q6_spdif_ops,
+		.id = AFE_PORT_ID_SECONDARY_SPDIF_RX,
+		.probe = msm_dai_q6_spdif_dai_probe,
+		.remove = msm_dai_q6_spdif_dai_remove,
+	},
+};
+
+static struct snd_soc_dai_driver msm_dai_q6_spdif_spdif_tx_dai[] = {
+	{
+		.capture = {
+			.stream_name = "Primary SPDIF Capture",
+			.aif_name = "PRI_SPDIF_TX",
+			.rates = SNDRV_PCM_RATE_32000 |
+				 SNDRV_PCM_RATE_44100 |
+				 SNDRV_PCM_RATE_48000 |
+				 SNDRV_PCM_RATE_88200 |
+				 SNDRV_PCM_RATE_96000 |
+				 SNDRV_PCM_RATE_176400 |
+				 SNDRV_PCM_RATE_192000,
+			.formats = SNDRV_PCM_FMTBIT_S16_LE |
+				   SNDRV_PCM_FMTBIT_S24_LE,
+			.channels_min = 1,
+			.channels_max = 2,
+			.rate_min = 32000,
+			.rate_max = 192000,
+		},
+		.name = "PRI_SPDIF_TX",
+		.ops = &msm_dai_q6_spdif_ops,
+		.id = AFE_PORT_ID_PRIMARY_SPDIF_TX,
+		.probe = msm_dai_q6_spdif_dai_probe,
+		.remove = msm_dai_q6_spdif_dai_remove,
+	},
+	{
+		.capture = {
+			.stream_name = "Secondary SPDIF Capture",
+			.aif_name = "SEC_SPDIF_TX",
+			.rates = SNDRV_PCM_RATE_32000 |
+				 SNDRV_PCM_RATE_44100 |
+				 SNDRV_PCM_RATE_48000 |
+				 SNDRV_PCM_RATE_88200 |
+				 SNDRV_PCM_RATE_96000 |
+				 SNDRV_PCM_RATE_176400 |
+				 SNDRV_PCM_RATE_192000,
+			.formats = SNDRV_PCM_FMTBIT_S16_LE |
+				   SNDRV_PCM_FMTBIT_S24_LE,
+			.channels_min = 1,
+			.channels_max = 2,
+			.rate_min = 32000,
+			.rate_max = 192000,
+		},
+		.name = "SEC_SPDIF_TX",
+		.ops = &msm_dai_q6_spdif_ops,
+		.id = AFE_PORT_ID_SECONDARY_SPDIF_TX,
+		.probe = msm_dai_q6_spdif_dai_probe,
+		.remove = msm_dai_q6_spdif_dai_remove,
 	},
-	.ops = &msm_dai_q6_spdif_ops,
-	.probe = msm_dai_q6_spdif_dai_probe,
-	.remove = msm_dai_q6_spdif_dai_remove,
 };
 
 static const struct snd_soc_component_driver msm_dai_spdif_q6_component = {
@@ -5471,16 +5770,48 @@ static struct platform_driver msm_dai_q6_mi2s_driver = {
 
 static int msm_dai_q6_spdif_dev_probe(struct platform_device *pdev)
 {
-	int rc;
+	int rc, id;
+	const char *q6_dev_id = "qcom,msm-dai-q6-dev-id";
+
+	rc = of_property_read_u32(pdev->dev.of_node, q6_dev_id, &id);
+	if (rc) {
+		dev_err(&pdev->dev,
+			"%s: missing %s in dt node\n", __func__, q6_dev_id);
+		return rc;
+	}
 
-	pdev->id = AFE_PORT_ID_SPDIF_RX;
+	pdev->id = id;
 
 	pr_debug("%s: dev name %s, id:%d\n", __func__,
 			dev_name(&pdev->dev), pdev->id);
 
-	rc = snd_soc_register_component(&pdev->dev,
+	switch (pdev->id) {
+	case AFE_PORT_ID_PRIMARY_SPDIF_RX:
+		rc = snd_soc_register_component(&pdev->dev,
+			&msm_dai_spdif_q6_component,
+			&msm_dai_q6_spdif_spdif_rx_dai[0], 1);
+		break;
+	case AFE_PORT_ID_SECONDARY_SPDIF_RX:
+		rc = snd_soc_register_component(&pdev->dev,
 			&msm_dai_spdif_q6_component,
-			&msm_dai_q6_spdif_spdif_rx_dai, 1);
+			&msm_dai_q6_spdif_spdif_rx_dai[1], 1);
+		break;
+	case AFE_PORT_ID_PRIMARY_SPDIF_TX:
+		rc = snd_soc_register_component(&pdev->dev,
+			&msm_dai_spdif_q6_component,
+			&msm_dai_q6_spdif_spdif_tx_dai[0], 1);
+		break;
+	case AFE_PORT_ID_SECONDARY_SPDIF_TX:
+		rc = snd_soc_register_component(&pdev->dev,
+			&msm_dai_spdif_q6_component,
+			&msm_dai_q6_spdif_spdif_tx_dai[1], 1);
+		break;
+	default:
+		dev_err(&pdev->dev, "invalid device ID %d\n", pdev->id);
+		rc = -ENODEV;
+		break;
+	}
+
 	return rc;
 }
 

+ 349 - 54
asoc/msm-pcm-routing-v2.c

@@ -368,8 +368,8 @@ struct msm_pcm_routing_bdai_data msm_bedais[MSM_BACKEND_DAI_MAX] = {
 	  LPASS_BE_SEC_AUXPCM_RX},
 	{ AFE_PORT_ID_SECONDARY_PCM_TX,   0, {0}, {0}, 0, 0, 0, 0, {0},
 	  LPASS_BE_SEC_AUXPCM_TX},
-	{ AFE_PORT_ID_SPDIF_RX, 0, {0}, {0}, 0, 0, 0, 0, {0},
-	  LPASS_BE_SPDIF_RX},
+	{ AFE_PORT_ID_PRIMARY_SPDIF_RX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+	  LPASS_BE_PRI_SPDIF_RX},
 	{ AFE_PORT_ID_SECONDARY_MI2S_RX_SD1, 0, {0}, {0}, 0, 0, 0, 0, {0},
 	  LPASS_BE_SEC_MI2S_RX_SD1},
 	{ AFE_PORT_ID_QUINARY_MI2S_RX, 0, {0}, {0}, 0, 0, 0, 0, {0},
@@ -602,6 +602,12 @@ struct msm_pcm_routing_bdai_data msm_bedais[MSM_BACKEND_DAI_MAX] = {
 	  LPASS_BE_VA_CDC_DMA_TX_0},
 	{ AFE_PORT_ID_VA_CODEC_DMA_TX_1, 0, {0}, {0}, 0, 0, 0, 0, {0},
 	  LPASS_BE_VA_CDC_DMA_TX_1},
+	{ AFE_PORT_ID_PRIMARY_SPDIF_TX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+	  LPASS_BE_PRI_SPDIF_TX},
+	{ AFE_PORT_ID_SECONDARY_SPDIF_RX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+	  LPASS_BE_SEC_SPDIF_RX},
+	{ AFE_PORT_ID_SECONDARY_SPDIF_TX, 0, {0}, {0}, 0, 0, 0, 0, {0},
+	  LPASS_BE_SEC_SPDIF_TX},
 };
 
 /* Track ASM playback & capture sessions of DAI
@@ -1337,7 +1343,9 @@ int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode,
 								i);
 			if ((passthr_mode == COMPRESSED_PASSTHROUGH_DSD)
 			     || (passthr_mode ==
-			     COMPRESSED_PASSTHROUGH_GEN))
+				COMPRESSED_PASSTHROUGH_GEN)
+			     || (passthr_mode ==
+				COMPRESSED_PASSTHROUGH_IEC61937))
 				topology = COMPRESSED_PASSTHROUGH_NONE_TOPOLOGY;
 			pr_debug("%s: Before adm open topology %d\n", __func__,
 				topology);
@@ -1389,12 +1397,12 @@ int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode,
 				}
 			}
 			if (passthr_mode != COMPRESSED_PASSTHROUGH_DSD
+			    && passthr_mode != COMPRESSED_PASSTHROUGH_GEN
 			    && passthr_mode !=
-			    COMPRESSED_PASSTHROUGH_GEN) {
+					    COMPRESSED_PASSTHROUGH_IEC61937)
 				msm_routing_send_device_pp_params(
-				msm_bedais[i].port_id,
-				copp_idx, fe_id);
-			}
+						msm_bedais[i].port_id,
+						copp_idx, fe_id);
 		}
 	}
 	if (num_copps) {
@@ -1758,7 +1766,7 @@ static void msm_pcm_routing_process_audio(u16 reg, u16 val, int set)
 			path_type = ADM_PATH_PLAYBACK;
 	} else {
 		session_type = SESSION_TYPE_TX;
-		if (passthr_mode != LEGACY_PCM)
+		if ((passthr_mode != LEGACY_PCM) && (passthr_mode != LISTEN))
 			path_type = ADM_PATH_COMPRESSED_TX;
 		else
 			path_type = ADM_PATH_LIVE_REC;
@@ -2999,7 +3007,7 @@ static const char *const be_name[] = {
 "SLIM_8_TX", "EXTPROC_RX", "EXTPROC_TX", "EXPROC_EC_TX",
 "QUAT_MI2S_RX", "QUAT_MI2S_TX", "SECOND_MI2S_RX", "SECOND_MI2S_TX",
 "PRI_MI2S_RX", "PRI_MI2S_TX", "TERT_MI2S_RX", "TERT_MI2S_TX",
-"AUDIO_I2S_RX", "SEC_AUXPCM_RX", "SEC_AUXPCM_TX", "SPDIF_RX",
+"AUDIO_I2S_RX", "SEC_AUXPCM_RX", "SEC_AUXPCM_TX", "PRI_SPDIF_RX",
 "SECOND_MI2S_RX_SD1", "QUIN_MI2S_RX", "QUIN_MI2S_TX", "SENARY_MI2S_TX",
 "PRI_TDM_RX_0", "PRI_TDM_TX_0", "PRI_TDM_RX_1", "PRI_TDM_TX_1",
 "PRI_TDM_RX_2", "PRI_TDM_TX_2", "PRI_TDM_RX_3", "PRI_TDM_TX_3",
@@ -3029,7 +3037,8 @@ static const char *const be_name[] = {
 "INT4_MI2S_RX", "INT4_MI2S_TX", "INT5_MI2S_RX", "INT5_MI2S_TX",
 "INT6_MI2S_RX", "INT6_MI2S_TX", "WSA_CDC_DMA_RX_0",
 "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_RX_1", "WSA_CDC_DMA_TX_1",
-"WSA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_1"
+"WSA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_1",
+"PRI_SPDIF_TX", "SEC_SPDIF_RX", "SEC_SPDIF_TX"
 };
 
 static SOC_ENUM_SINGLE_DECL(mm1_channel_mux,
@@ -4206,89 +4215,176 @@ static const struct snd_kcontrol_new sec_i2s_rx_mixer_controls[] = {
 	msm_routing_put_audio_mixer),
 };
 
-static const struct snd_kcontrol_new spdif_rx_mixer_controls[] = {
+static const struct snd_kcontrol_new pri_spdif_rx_mixer_controls[] = {
+	SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM,
+	MSM_BACKEND_DAI_PRI_SPDIF_RX,
+	MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM,
+	MSM_BACKEND_DAI_PRI_SPDIF_RX,
+	MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM,
+	MSM_BACKEND_DAI_PRI_SPDIF_RX,
+	MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM,
+	MSM_BACKEND_DAI_PRI_SPDIF_RX,
+	MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM,
+	MSM_BACKEND_DAI_PRI_SPDIF_RX,
+	MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM,
+	MSM_BACKEND_DAI_PRI_SPDIF_RX,
+	MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM,
+	MSM_BACKEND_DAI_PRI_SPDIF_RX,
+	MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM,
+	MSM_BACKEND_DAI_PRI_SPDIF_RX,
+	MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM,
+	MSM_BACKEND_DAI_PRI_SPDIF_RX,
+	MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM,
+	MSM_BACKEND_DAI_PRI_SPDIF_RX,
+	MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM,
+	MSM_BACKEND_DAI_PRI_SPDIF_RX,
+	MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM,
+	MSM_BACKEND_DAI_PRI_SPDIF_RX,
+	MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM,
+	MSM_BACKEND_DAI_PRI_SPDIF_RX,
+	MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM,
+	MSM_BACKEND_DAI_PRI_SPDIF_RX,
+	MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM,
+	MSM_BACKEND_DAI_PRI_SPDIF_RX,
+	MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM,
+	MSM_BACKEND_DAI_PRI_SPDIF_RX,
+	MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM,
+	MSM_BACKEND_DAI_PRI_SPDIF_RX,
+	MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM,
+	MSM_BACKEND_DAI_PRI_SPDIF_RX,
+	MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM,
+	MSM_BACKEND_DAI_PRI_SPDIF_RX,
+	MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM,
+	MSM_BACKEND_DAI_PRI_SPDIF_RX,
+	MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM,
+	MSM_BACKEND_DAI_PRI_SPDIF_RX,
+	MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+};
+
+static const struct snd_kcontrol_new sec_spdif_rx_mixer_controls[] = {
 	SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM,
-	MSM_BACKEND_DAI_SPDIF_RX,
+	MSM_BACKEND_DAI_SEC_SPDIF_RX,
 	MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
 	SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM,
-	MSM_BACKEND_DAI_SPDIF_RX,
+	MSM_BACKEND_DAI_SEC_SPDIF_RX,
 	MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
 	SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM,
-	MSM_BACKEND_DAI_SPDIF_RX,
+	MSM_BACKEND_DAI_SEC_SPDIF_RX,
 	MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
 	SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM,
-	MSM_BACKEND_DAI_SPDIF_RX,
+	MSM_BACKEND_DAI_SEC_SPDIF_RX,
 	MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
 	SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM,
-	MSM_BACKEND_DAI_SPDIF_RX,
+	MSM_BACKEND_DAI_SEC_SPDIF_RX,
 	MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
 	SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM,
-	MSM_BACKEND_DAI_SPDIF_RX,
+	MSM_BACKEND_DAI_SEC_SPDIF_RX,
 	MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
 	SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM,
-	MSM_BACKEND_DAI_SPDIF_RX,
+	MSM_BACKEND_DAI_SEC_SPDIF_RX,
 	MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
 	SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM,
-	MSM_BACKEND_DAI_SPDIF_RX,
+	MSM_BACKEND_DAI_SEC_SPDIF_RX,
 	MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
 	SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM,
-	MSM_BACKEND_DAI_SPDIF_RX,
+	MSM_BACKEND_DAI_SEC_SPDIF_RX,
 	MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
 	SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM,
-	MSM_BACKEND_DAI_SPDIF_RX,
+	MSM_BACKEND_DAI_SEC_SPDIF_RX,
 	MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
 	SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM,
-	MSM_BACKEND_DAI_SPDIF_RX,
+	MSM_BACKEND_DAI_SEC_SPDIF_RX,
 	MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
 	SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM,
-	MSM_BACKEND_DAI_SPDIF_RX,
+	MSM_BACKEND_DAI_SEC_SPDIF_RX,
 	MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
 	SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM,
-	MSM_BACKEND_DAI_SPDIF_RX,
+	MSM_BACKEND_DAI_SEC_SPDIF_RX,
 	MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
 	SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM,
-	MSM_BACKEND_DAI_SPDIF_RX,
+	MSM_BACKEND_DAI_SEC_SPDIF_RX,
 	MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
 	SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM,
-	MSM_BACKEND_DAI_SPDIF_RX,
+	MSM_BACKEND_DAI_SEC_SPDIF_RX,
 	MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
 	SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM,
-	MSM_BACKEND_DAI_SPDIF_RX,
+	MSM_BACKEND_DAI_SEC_SPDIF_RX,
 	MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
 	SOC_DOUBLE_EXT("MultiMedia17", SND_SOC_NOPM,
-	MSM_BACKEND_DAI_SPDIF_RX,
+	MSM_BACKEND_DAI_SEC_SPDIF_RX,
 	MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
 	SOC_DOUBLE_EXT("MultiMedia18", SND_SOC_NOPM,
-	MSM_BACKEND_DAI_SPDIF_RX,
+	MSM_BACKEND_DAI_SEC_SPDIF_RX,
 	MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
 	SOC_DOUBLE_EXT("MultiMedia19", SND_SOC_NOPM,
-	MSM_BACKEND_DAI_SPDIF_RX,
+	MSM_BACKEND_DAI_SEC_SPDIF_RX,
 	MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
 	SOC_DOUBLE_EXT("MultiMedia28", SND_SOC_NOPM,
-	MSM_BACKEND_DAI_SPDIF_RX,
+	MSM_BACKEND_DAI_SEC_SPDIF_RX,
 	MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
 	SOC_DOUBLE_EXT("MultiMedia29", SND_SOC_NOPM,
-	MSM_BACKEND_DAI_SPDIF_RX,
+	MSM_BACKEND_DAI_SEC_SPDIF_RX,
 	MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
 };
@@ -8482,6 +8578,14 @@ static const struct snd_kcontrol_new mmul1_mixer_controls[] = {
 			MSM_BACKEND_DAI_VA_CDC_DMA_TX_1,
 		MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
 		msm_routing_put_audio_mixer),
+	SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM,
+		MSM_BACKEND_DAI_PRI_SPDIF_TX,
+		MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+		msm_routing_put_audio_mixer),
+	SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM,
+		MSM_BACKEND_DAI_SEC_SPDIF_TX,
+		MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+		msm_routing_put_audio_mixer),
 };
 
 static const struct snd_kcontrol_new mmul2_mixer_controls[] = {
@@ -8641,6 +8745,14 @@ static const struct snd_kcontrol_new mmul2_mixer_controls[] = {
 			MSM_BACKEND_DAI_VA_CDC_DMA_TX_1,
 	MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
+	SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM,
+	MSM_BACKEND_DAI_PRI_SPDIF_TX,
+	MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM,
+	MSM_BACKEND_DAI_SEC_SPDIF_TX,
+	MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
 };
 
 static const struct snd_kcontrol_new mmul3_mixer_controls[] = {
@@ -8800,6 +8912,14 @@ static const struct snd_kcontrol_new mmul3_mixer_controls[] = {
 			MSM_BACKEND_DAI_VA_CDC_DMA_TX_1,
 	MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
+	SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM,
+	MSM_BACKEND_DAI_PRI_SPDIF_TX,
+	MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM,
+	MSM_BACKEND_DAI_SEC_SPDIF_TX,
+	MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
 };
 
 static const struct snd_kcontrol_new mmul4_mixer_controls[] = {
@@ -8955,6 +9075,14 @@ static const struct snd_kcontrol_new mmul4_mixer_controls[] = {
 			MSM_BACKEND_DAI_VA_CDC_DMA_TX_1,
 	MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
+	SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM,
+	MSM_BACKEND_DAI_PRI_SPDIF_TX,
+	MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM,
+	MSM_BACKEND_DAI_SEC_SPDIF_TX,
+	MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
 };
 
 static const struct snd_kcontrol_new mmul5_mixer_controls[] = {
@@ -9134,6 +9262,14 @@ static const struct snd_kcontrol_new mmul5_mixer_controls[] = {
 			MSM_BACKEND_DAI_VA_CDC_DMA_TX_1,
 	MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
+	SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM,
+	MSM_BACKEND_DAI_PRI_SPDIF_TX,
+	MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM,
+	MSM_BACKEND_DAI_SEC_SPDIF_TX,
+	MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
 };
 
 static const struct snd_kcontrol_new mmul6_mixer_controls[] = {
@@ -9293,6 +9429,14 @@ static const struct snd_kcontrol_new mmul6_mixer_controls[] = {
 			MSM_BACKEND_DAI_VA_CDC_DMA_TX_1,
 	MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
+	SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM,
+	MSM_BACKEND_DAI_PRI_SPDIF_TX,
+	MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM,
+	MSM_BACKEND_DAI_SEC_SPDIF_TX,
+	MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
 };
 
 static const struct snd_kcontrol_new mmul8_mixer_controls[] = {
@@ -9456,6 +9600,14 @@ static const struct snd_kcontrol_new mmul8_mixer_controls[] = {
 			MSM_BACKEND_DAI_VA_CDC_DMA_TX_1,
 	MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
+	SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM,
+	MSM_BACKEND_DAI_PRI_SPDIF_TX,
+	MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM,
+	MSM_BACKEND_DAI_SEC_SPDIF_TX,
+	MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
 };
 
 static const struct snd_kcontrol_new mmul16_mixer_controls[] = {
@@ -9619,6 +9771,14 @@ static const struct snd_kcontrol_new mmul16_mixer_controls[] = {
 			MSM_BACKEND_DAI_VA_CDC_DMA_TX_1,
 	MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
+	SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM,
+	MSM_BACKEND_DAI_PRI_SPDIF_TX,
+	MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM,
+	MSM_BACKEND_DAI_SEC_SPDIF_TX,
+	MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
 };
 
 static const struct snd_kcontrol_new mmul9_mixer_controls[] = {
@@ -9722,6 +9882,14 @@ static const struct snd_kcontrol_new mmul9_mixer_controls[] = {
 			MSM_BACKEND_DAI_VA_CDC_DMA_TX_1,
 	MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
+	SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM,
+	MSM_BACKEND_DAI_PRI_SPDIF_TX,
+	MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM,
+	MSM_BACKEND_DAI_SEC_SPDIF_TX,
+	MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
 };
 
 static const struct snd_kcontrol_new mmul10_mixer_controls[] = {
@@ -9849,6 +10017,14 @@ static const struct snd_kcontrol_new mmul10_mixer_controls[] = {
 			MSM_BACKEND_DAI_VA_CDC_DMA_TX_1,
 	MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
+	SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM,
+	MSM_BACKEND_DAI_PRI_SPDIF_TX,
+	MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM,
+	MSM_BACKEND_DAI_SEC_SPDIF_TX,
+	MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
 };
 static const struct snd_kcontrol_new mmul17_mixer_controls[] = {
 	SOC_DOUBLE_EXT("SLIM_0_TX", SND_SOC_NOPM,
@@ -9911,6 +10087,14 @@ static const struct snd_kcontrol_new mmul17_mixer_controls[] = {
 			MSM_BACKEND_DAI_VA_CDC_DMA_TX_1,
 	MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
+	SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM,
+	MSM_BACKEND_DAI_PRI_SPDIF_TX,
+	MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM,
+	MSM_BACKEND_DAI_SEC_SPDIF_TX,
+	MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
 };
 
 static const struct snd_kcontrol_new mmul18_mixer_controls[] = {
@@ -9926,6 +10110,10 @@ static const struct snd_kcontrol_new mmul18_mixer_controls[] = {
 	MSM_BACKEND_DAI_INT3_MI2S_TX,
 	MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
+	SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM,
+	MSM_BACKEND_DAI_SECONDARY_MI2S_TX,
+	MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
 	SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM,
 	MSM_BACKEND_DAI_TERTIARY_MI2S_TX,
 	MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer,
@@ -9974,6 +10162,14 @@ static const struct snd_kcontrol_new mmul18_mixer_controls[] = {
 			MSM_BACKEND_DAI_VA_CDC_DMA_TX_1,
 	MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
+	SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM,
+	MSM_BACKEND_DAI_PRI_SPDIF_TX,
+	MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM,
+	MSM_BACKEND_DAI_SEC_SPDIF_TX,
+	MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
 };
 
 static const struct snd_kcontrol_new mmul19_mixer_controls[] = {
@@ -10037,6 +10233,14 @@ static const struct snd_kcontrol_new mmul19_mixer_controls[] = {
 			MSM_BACKEND_DAI_VA_CDC_DMA_TX_1,
 	MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
+	SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM,
+	MSM_BACKEND_DAI_PRI_SPDIF_TX,
+	MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM,
+	MSM_BACKEND_DAI_SEC_SPDIF_TX,
+	MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
 };
 
 static const struct snd_kcontrol_new mmul20_mixer_controls[] = {
@@ -10160,6 +10364,14 @@ static const struct snd_kcontrol_new mmul20_mixer_controls[] = {
 			MSM_BACKEND_DAI_VA_CDC_DMA_TX_1,
 	MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
+	SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM,
+	MSM_BACKEND_DAI_PRI_SPDIF_TX,
+	MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM,
+	MSM_BACKEND_DAI_SEC_SPDIF_TX,
+	MSM_FRONTEND_DAI_MULTIMEDIA20, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
 };
 
 static const struct snd_kcontrol_new mmul28_mixer_controls[] = {
@@ -10223,6 +10435,14 @@ static const struct snd_kcontrol_new mmul28_mixer_controls[] = {
 			MSM_BACKEND_DAI_VA_CDC_DMA_TX_1,
 	MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
+	SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM,
+	MSM_BACKEND_DAI_PRI_SPDIF_TX,
+	MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM,
+	MSM_BACKEND_DAI_SEC_SPDIF_TX,
+	MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
 };
 
 static const struct snd_kcontrol_new mmul29_mixer_controls[] = {
@@ -10286,6 +10506,14 @@ static const struct snd_kcontrol_new mmul29_mixer_controls[] = {
 			MSM_BACKEND_DAI_VA_CDC_DMA_TX_1,
 	MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer,
 	msm_routing_put_audio_mixer),
+	SOC_DOUBLE_EXT("PRI_SPDIF_TX", SND_SOC_NOPM,
+	MSM_BACKEND_DAI_PRI_SPDIF_TX,
+	MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
+	SOC_DOUBLE_EXT("SEC_SPDIF_TX", SND_SOC_NOPM,
+	MSM_BACKEND_DAI_SEC_SPDIF_TX,
+	MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer,
+	msm_routing_put_audio_mixer),
 };
 
 static const struct snd_kcontrol_new pri_rx_voice_mixer_controls[] = {
@@ -16125,7 +16353,14 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = {
 	SND_SOC_DAPM_AIF_OUT("PRI_I2S_RX", "Primary I2S Playback", 0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_OUT("SEC_I2S_RX", "Secondary I2S Playback",
 				0, 0, 0, 0),
-	SND_SOC_DAPM_AIF_OUT("SPDIF_RX", "SPDIF Playback", 0, 0, 0, 0),
+	SND_SOC_DAPM_AIF_OUT("PRI_SPDIF_RX", "Primary SPDIF Playback",
+			0, 0, 0, 0),
+	SND_SOC_DAPM_AIF_IN("PRI_SPDIF_TX", "Primary SPDIF Capture",
+			0, 0, 0, 0),
+	SND_SOC_DAPM_AIF_OUT("SEC_SPDIF_RX", "Secondary SPDIF Playback",
+			0, 0, 0, 0),
+	SND_SOC_DAPM_AIF_IN("SEC_SPDIF_TX", "Secondary SPDIF Capture",
+			0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_OUT("SLIMBUS_0_RX", "Slimbus Playback", 0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_OUT("SLIMBUS_2_RX", "Slimbus2 Playback", 0, 0, 0, 0),
 	SND_SOC_DAPM_AIF_OUT("SLIMBUS_5_RX", "Slimbus5 Playback", 0, 0, 0, 0),
@@ -16495,8 +16730,10 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = {
 	display_port_mixer_controls, ARRAY_SIZE(display_port_mixer_controls)),
 	SND_SOC_DAPM_MIXER("DISPLAY_PORT1 Mixer", SND_SOC_NOPM, 0, 0,
 	display_port1_mixer_controls, ARRAY_SIZE(display_port1_mixer_controls)),
-	SND_SOC_DAPM_MIXER("SPDIF_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
-	spdif_rx_mixer_controls, ARRAY_SIZE(spdif_rx_mixer_controls)),
+	SND_SOC_DAPM_MIXER("PRI_SPDIF_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
+	pri_spdif_rx_mixer_controls, ARRAY_SIZE(pri_spdif_rx_mixer_controls)),
+	SND_SOC_DAPM_MIXER("SEC_SPDIF_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
+	sec_spdif_rx_mixer_controls, ARRAY_SIZE(sec_spdif_rx_mixer_controls)),
 	SND_SOC_DAPM_MIXER("MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
 	mi2s_rx_mixer_controls, ARRAY_SIZE(mi2s_rx_mixer_controls)),
 	SND_SOC_DAPM_MIXER("QUAT_MI2S_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
@@ -17184,23 +17421,41 @@ static const struct snd_soc_dapm_route intercon[] = {
 	{"DISPLAY_PORT1 Mixer", "MultiMedia16", "MM_DL16"},
 	{"DISPLAY_PORT1", NULL, "DISPLAY_PORT1 Mixer"},
 
-	{"SPDIF_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
-	{"SPDIF_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
-	{"SPDIF_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
-	{"SPDIF_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
-	{"SPDIF_RX Audio Mixer", "MultiMedia5", "MM_DL5"},
-	{"SPDIF_RX Audio Mixer", "MultiMedia6", "MM_DL6"},
-	{"SPDIF_RX Audio Mixer", "MultiMedia7", "MM_DL7"},
-	{"SPDIF_RX Audio Mixer", "MultiMedia8", "MM_DL8"},
-	{"SPDIF_RX Audio Mixer", "MultiMedia9", "MM_DL9"},
-	{"SPDIF_RX Audio Mixer", "MultiMedia10", "MM_DL10"},
-	{"SPDIF_RX Audio Mixer", "MultiMedia11", "MM_DL11"},
-	{"SPDIF_RX Audio Mixer", "MultiMedia12", "MM_DL12"},
-	{"SPDIF_RX Audio Mixer", "MultiMedia13", "MM_DL13"},
-	{"SPDIF_RX Audio Mixer", "MultiMedia14", "MM_DL14"},
-	{"SPDIF_RX Audio Mixer", "MultiMedia15", "MM_DL15"},
-	{"SPDIF_RX Audio Mixer", "MultiMedia16", "MM_DL16"},
-	{"SPDIF_RX", NULL, "SPDIF_RX Audio Mixer"},
+	{"PRI_SPDIF_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
+	{"PRI_SPDIF_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
+	{"PRI_SPDIF_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
+	{"PRI_SPDIF_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
+	{"PRI_SPDIF_RX Audio Mixer", "MultiMedia5", "MM_DL5"},
+	{"PRI_SPDIF_RX Audio Mixer", "MultiMedia6", "MM_DL6"},
+	{"PRI_SPDIF_RX Audio Mixer", "MultiMedia7", "MM_DL7"},
+	{"PRI_SPDIF_RX Audio Mixer", "MultiMedia8", "MM_DL8"},
+	{"PRI_SPDIF_RX Audio Mixer", "MultiMedia9", "MM_DL9"},
+	{"PRI_SPDIF_RX Audio Mixer", "MultiMedia10", "MM_DL10"},
+	{"PRI_SPDIF_RX Audio Mixer", "MultiMedia11", "MM_DL11"},
+	{"PRI_SPDIF_RX Audio Mixer", "MultiMedia12", "MM_DL12"},
+	{"PRI_SPDIF_RX Audio Mixer", "MultiMedia13", "MM_DL13"},
+	{"PRI_SPDIF_RX Audio Mixer", "MultiMedia14", "MM_DL14"},
+	{"PRI_SPDIF_RX Audio Mixer", "MultiMedia15", "MM_DL15"},
+	{"PRI_SPDIF_RX Audio Mixer", "MultiMedia16", "MM_DL16"},
+	{"PRI_SPDIF_RX", NULL, "PRI_SPDIF_RX Audio Mixer"},
+
+	{"SEC_SPDIF_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
+	{"SEC_SPDIF_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
+	{"SEC_SPDIF_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
+	{"SEC_SPDIF_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
+	{"SEC_SPDIF_RX Audio Mixer", "MultiMedia5", "MM_DL5"},
+	{"SEC_SPDIF_RX Audio Mixer", "MultiMedia6", "MM_DL6"},
+	{"SEC_SPDIF_RX Audio Mixer", "MultiMedia7", "MM_DL7"},
+	{"SEC_SPDIF_RX Audio Mixer", "MultiMedia8", "MM_DL8"},
+	{"SEC_SPDIF_RX Audio Mixer", "MultiMedia9", "MM_DL9"},
+	{"SEC_SPDIF_RX Audio Mixer", "MultiMedia10", "MM_DL10"},
+	{"SEC_SPDIF_RX Audio Mixer", "MultiMedia11", "MM_DL11"},
+	{"SEC_SPDIF_RX Audio Mixer", "MultiMedia12", "MM_DL12"},
+	{"SEC_SPDIF_RX Audio Mixer", "MultiMedia13", "MM_DL13"},
+	{"SEC_SPDIF_RX Audio Mixer", "MultiMedia14", "MM_DL14"},
+	{"SEC_SPDIF_RX Audio Mixer", "MultiMedia15", "MM_DL15"},
+	{"SEC_SPDIF_RX Audio Mixer", "MultiMedia16", "MM_DL16"},
+	{"SEC_SPDIF_RX", NULL, "SEC_SPDIF_RX Audio Mixer"},
 
 	/* incall */
 	{"Incall_Music Audio Mixer", "MultiMedia1", "MM_DL1"},
@@ -17300,6 +17555,7 @@ static const struct snd_soc_dapm_route intercon[] = {
 	{"MultiMedia28 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"},
 	{"MultiMedia29 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"},
 	{"MultiMedia8 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"},
+	{"MultiMedia18 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"},
 	{"MultiMedia17 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"},
 	{"MultiMedia18 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"},
 	{"MultiMedia19 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"},
@@ -17318,6 +17574,9 @@ static const struct snd_soc_dapm_route intercon[] = {
 	{"MultiMedia5 Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"},
 	{"MultiMedia5 Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"},
 	{"MultiMedia10 Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"},
+	{"MultiMedia18 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"},
+	{"MultiMedia18 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"},
+
 	{"MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
 	{"MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
 	{"MI2S_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
@@ -18036,6 +18295,8 @@ static const struct snd_soc_dapm_route intercon[] = {
 	{"MultiMedia1 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"},
 	{"MultiMedia1 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"},
 	{"MultiMedia1 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"},
+	{"MultiMedia1 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"},
+	{"MultiMedia1 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"},
 
 	{"MultiMedia2 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"},
 	{"MultiMedia2 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"},
@@ -18062,6 +18323,8 @@ static const struct snd_soc_dapm_route intercon[] = {
 	{"MultiMedia2 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"},
 	{"MultiMedia2 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"},
 	{"MultiMedia2 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"},
+	{"MultiMedia2 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"},
+	{"MultiMedia2 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"},
 
 	{"MultiMedia3 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"},
 	{"MultiMedia3 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"},
@@ -18088,6 +18351,8 @@ static const struct snd_soc_dapm_route intercon[] = {
 	{"MultiMedia3 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"},
 	{"MultiMedia3 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"},
 	{"MultiMedia3 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"},
+	{"MultiMedia3 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"},
+	{"MultiMedia3 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"},
 
 	{"MultiMedia4 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"},
 	{"MultiMedia4 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"},
@@ -18114,6 +18379,8 @@ static const struct snd_soc_dapm_route intercon[] = {
 	{"MultiMedia4 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"},
 	{"MultiMedia4 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"},
 	{"MultiMedia4 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"},
+	{"MultiMedia4 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"},
+	{"MultiMedia4 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"},
 
 	{"MultiMedia5 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"},
 	{"MultiMedia5 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"},
@@ -18140,6 +18407,8 @@ static const struct snd_soc_dapm_route intercon[] = {
 	{"MultiMedia5 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"},
 	{"MultiMedia5 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"},
 	{"MultiMedia5 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"},
+	{"MultiMedia5 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"},
+	{"MultiMedia5 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"},
 
 	{"MultiMedia6 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"},
 	{"MultiMedia6 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"},
@@ -18166,6 +18435,8 @@ static const struct snd_soc_dapm_route intercon[] = {
 	{"MultiMedia6 Mixer", "WSA_CDC_DMA_TX_2", "WSA_CDC_DMA_TX_2"},
 	{"MultiMedia6 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"},
 	{"MultiMedia6 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"},
+	{"MultiMedia6 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"},
+	{"MultiMedia6 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"},
 
 	{"MultiMedia8 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"},
 	{"MultiMedia8 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"},
@@ -18193,6 +18464,8 @@ static const struct snd_soc_dapm_route intercon[] = {
 	{"MultiMedia8 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"},
 	{"MultiMedia8 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"},
 	{"MultiMedia8 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"},
+	{"MultiMedia8 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"},
+	{"MultiMedia8 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"},
 
 	{"MultiMedia9 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"},
 	{"MultiMedia9 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"},
@@ -18212,6 +18485,8 @@ static const struct snd_soc_dapm_route intercon[] = {
 	{"MultiMedia9 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"},
 	{"MultiMedia9 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"},
 	{"MultiMedia9 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"},
+	{"MultiMedia9 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"},
+	{"MultiMedia9 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"},
 
 	{"MultiMedia10 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"},
 	{"MultiMedia10 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"},
@@ -18252,6 +18527,8 @@ static const struct snd_soc_dapm_route intercon[] = {
 	{"MultiMedia20 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"},
 	{"MultiMedia20 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"},
 	{"MultiMedia20 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"},
+	{"MultiMedia20 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"},
+	{"MultiMedia20 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"},
 
 	{"MultiMedia1 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"},
 	{"MultiMedia2 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"},
@@ -18284,6 +18561,8 @@ static const struct snd_soc_dapm_route intercon[] = {
 	{"MultiMedia16 Mixer", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_0"},
 	{"MultiMedia16 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"},
 	{"MultiMedia16 Mixer", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_1"},
+	{"MultiMedia16 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"},
+	{"MultiMedia16 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"},
 
 	{"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
 	{"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
@@ -19768,7 +20047,8 @@ static const struct snd_soc_dapm_route intercon[] = {
 	{"BE_OUT", NULL, "HDMI"},
 	{"BE_OUT", NULL, "DISPLAY_PORT"},
 	{"BE_OUT", NULL, "DISPLAY_PORT1"},
-	{"BE_OUT", NULL, "SPDIF_RX"},
+	{"BE_OUT", NULL, "PRI_SPDIF_RX"},
+	{"BE_OUT", NULL, "SEC_SPDIF_RX"},
 	{"BE_OUT", NULL, "MI2S_RX"},
 	{"BE_OUT", NULL, "QUAT_MI2S_RX"},
 	{"BE_OUT", NULL, "QUIN_MI2S_RX"},
@@ -19897,6 +20177,8 @@ static const struct snd_soc_dapm_route intercon[] = {
 	{"WSA_CDC_DMA_TX_2", NULL, "BE_IN"},
 	{"VA_CDC_DMA_TX_0", NULL, "BE_IN"},
 	{"VA_CDC_DMA_TX_1", NULL, "BE_IN"},
+	{"PRI_SPDIF_TX", NULL, "BE_IN"},
+	{"SEC_SPDIF_TX", NULL, "BE_IN"},
 
 };
 
@@ -20036,7 +20318,11 @@ static int msm_pcm_routing_prepare(struct snd_pcm_substream *substream)
 				path_type = ADM_PATH_PLAYBACK;
 			session_type = SESSION_TYPE_RX;
 		} else {
-			path_type = ADM_PATH_LIVE_REC;
+			if ((bedai->passthr_mode[i] != LEGACY_PCM) &&
+			    (bedai->passthr_mode[i] != LISTEN))
+				path_type = ADM_PATH_COMPRESSED_TX;
+			else
+				path_type = ADM_PATH_LIVE_REC;
 			session_type = SESSION_TYPE_TX;
 		}
 
@@ -20094,6 +20380,15 @@ static int msm_pcm_routing_prepare(struct snd_pcm_substream *substream)
 			fe_dai_app_type_cfg[i][session_type][be_id].acdb_dev_id;
 			topology = msm_routing_get_adm_topology(i, session_type,
 								be_id);
+
+			if ((bedai->passthr_mode[i] ==
+					COMPRESSED_PASSTHROUGH_DSD)
+				|| (bedai->passthr_mode[i] ==
+					COMPRESSED_PASSTHROUGH_GEN)
+				|| (bedai->passthr_mode[i] ==
+					COMPRESSED_PASSTHROUGH_IEC61937))
+				topology = COMPRESSED_PASSTHROUGH_NONE_TOPOLOGY;
+
 			copp_idx = adm_open(bedai->port_id, path_type,
 					    sample_rate, channels, topology,
 					    fdai->perf_mode, bits_per_sample,

+ 8 - 2
asoc/msm-pcm-routing-v2.h

@@ -48,7 +48,10 @@
 #define LPASS_BE_INCALL_RECORD_RX "INCALL_RECORD_RX"
 #define LPASS_BE_INCALL_RECORD_TX "INCALL_RECORD_TX"
 #define LPASS_BE_SEC_I2S_RX "SECONDARY_I2S_RX"
-#define LPASS_BE_SPDIF_RX "SPDIF_RX"
+#define LPASS_BE_PRI_SPDIF_RX "PRI_SPDIF_RX"
+#define LPASS_BE_PRI_SPDIF_TX "PRI_SPDIF_TX"
+#define LPASS_BE_SEC_SPDIF_RX "SEC_SPDIF_RX"
+#define LPASS_BE_SEC_SPDIF_TX "SEC_SPDIF_TX"
 
 #define LPASS_BE_MI2S_RX "MI2S_RX"
 #define LPASS_BE_MI2S_TX "MI2S_TX"
@@ -299,7 +302,7 @@ enum {
 	MSM_BACKEND_DAI_AUDIO_I2S_RX,
 	MSM_BACKEND_DAI_SEC_AUXPCM_RX,
 	MSM_BACKEND_DAI_SEC_AUXPCM_TX,
-	MSM_BACKEND_DAI_SPDIF_RX,
+	MSM_BACKEND_DAI_PRI_SPDIF_RX,
 	MSM_BACKEND_DAI_SECONDARY_MI2S_RX_SD1,
 	MSM_BACKEND_DAI_QUINARY_MI2S_RX,
 	MSM_BACKEND_DAI_QUINARY_MI2S_TX,
@@ -416,6 +419,9 @@ enum {
 	MSM_BACKEND_DAI_WSA_CDC_DMA_TX_2,
 	MSM_BACKEND_DAI_VA_CDC_DMA_TX_0,
 	MSM_BACKEND_DAI_VA_CDC_DMA_TX_1,
+	MSM_BACKEND_DAI_PRI_SPDIF_TX,
+	MSM_BACKEND_DAI_SEC_SPDIF_RX,
+	MSM_BACKEND_DAI_SEC_SPDIF_TX,
 	MSM_BACKEND_DAI_MAX,
 };