Merge branch 'sm7225_r_fp4' into Bitra2
diff --git a/asoc/bengal.c b/asoc/bengal.c
index 15c2104..0ecc191 100644
--- a/asoc/bengal.c
+++ b/asoc/bengal.c
@@ -161,6 +161,9 @@
 	bool is_afe_config_done;
 	struct device_node *fsa_handle;
 	bool va_disable;
+#ifdef CONFIG_T2M_SND_FP4
+    struct device_node *hac_pa_gpio_p;
+#endif
 };
 
 struct tdm_port {
@@ -586,6 +589,35 @@
 	.moisture_duty_cycle_en = true,
 };
 
+#ifdef CONFIG_T2M_SND_FP4
+static int msm_enable_hac_pa(struct snd_soc_dapm_widget *w,
+                       struct snd_kcontrol *kcontrol,
+                       int event);
+
+static const struct snd_kcontrol_new hac_pa_switch[] = {
+    SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
+};
+
+static const struct snd_soc_dapm_widget msm_hac_dapm_widgets[] = {
+    SND_SOC_DAPM_MIXER("HAC_PA", SND_SOC_NOPM, 0, 0,
+               hac_pa_switch, ARRAY_SIZE(hac_pa_switch)),
+    SND_SOC_DAPM_PGA_E("HAC PGA", SND_SOC_NOPM, 0, 0, NULL, 0,
+                msm_enable_hac_pa,
+                SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+                SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+
+    SND_SOC_DAPM_INPUT("HAC_RX"),
+    SND_SOC_DAPM_OUTPUT("HAC"),
+};
+
+static const struct snd_soc_dapm_route msm_hac_audio_map[] = {
+    {"HAC_PA", "Switch", "HAC_RX"},
+    {"HAC PGA", NULL, "HAC_PA"},
+    {"HAC", NULL, "HAC PGA"},
+};
+#endif
+
 static inline int param_is_mask(int p)
 {
 	return (p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) &&
@@ -4199,6 +4231,43 @@
 	return 0;
 }
 
+#ifdef CONFIG_T2M_SND_FP4
+static int msm_enable_hac_pa(struct snd_soc_dapm_widget *w,
+                       struct snd_kcontrol *kcontrol,
+                       int event)
+{
+    struct snd_soc_component *component =
+                    snd_soc_dapm_to_component(w->dapm);
+    struct msm_asoc_mach_data *pdata = NULL;
+    int ret = 0;
+
+    dev_dbg(component->dev, "%s wname: %s event: %d\n", __func__,
+        w->name, event);
+
+    pdata = snd_soc_card_get_drvdata(component->card);
+
+    switch (event) {
+    case SND_SOC_DAPM_POST_PMU:
+        ret = msm_cdc_pinctrl_select_active_state(
+                    pdata->hac_pa_gpio_p);
+        if (ret) {
+            pr_err("%s: gpio set cannot be de-activated %s\n",
+                    __func__, "hac_pa");
+        }
+        break;
+    case SND_SOC_DAPM_PRE_PMD:
+        ret = msm_cdc_pinctrl_select_sleep_state(
+                    pdata->hac_pa_gpio_p);
+        if (ret) {
+            pr_err("%s: gpio set cannot be de-activated %s\n",
+                    __func__, "hac_pa");
+        }
+        break;
+    };
+    return ret;
+}
+#endif
+
 static const struct snd_soc_dapm_widget msm_int_dapm_widgets[] = {
 	SND_SOC_DAPM_MIC("Analog Mic1", NULL),
 	SND_SOC_DAPM_MIC("Analog Mic2", NULL),
@@ -4303,6 +4372,16 @@
 	snd_soc_dapm_new_controls(dapm, msm_int_dapm_widgets,
 				ARRAY_SIZE(msm_int_dapm_widgets));
 
+#ifdef CONFIG_T2M_SND_FP4
+    snd_soc_dapm_new_controls(dapm, msm_hac_dapm_widgets,
+                ARRAY_SIZE(msm_hac_dapm_widgets));
+
+    snd_soc_dapm_add_routes(dapm, msm_hac_audio_map,
+                    ARRAY_SIZE(msm_hac_audio_map));
+
+    snd_soc_dapm_ignore_suspend(dapm, "HAC");
+#endif
+
 	snd_soc_dapm_ignore_suspend(dapm, "Digital Mic0");
 	snd_soc_dapm_ignore_suspend(dapm, "Digital Mic1");
 	snd_soc_dapm_ignore_suspend(dapm, "Digital Mic2");
@@ -4423,7 +4502,20 @@
 
 	return wcd_mbhc_cal;
 }
-
+#ifdef CONFIG_T2M_SND_FP4
+struct snd_soc_dai_link_component awinic_codecs[] = {
+	{
+		.of_node = NULL,
+		.dai_name = "aw881xx-aif-0-34",
+		.name = "aw881xx_smartpa.0-0034",
+	},
+	{
+		.of_node = NULL,
+		.dai_name = "aw881xx-aif-0-36",
+		.name = "aw881xx_smartpa.0-0036",
+	},
+};
+#endif
 /* Digital audio interface glue - connects codec <---> CPU */
 static struct snd_soc_dai_link msm_common_dai_links[] = {
 	/* FrontEnd DAI Links */
@@ -5053,6 +5145,38 @@
 		.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
 		.ops = &msm_cdc_dma_be_ops,
 	},
+/*#if defined(CONFIG_T2M_SND_FP4)
+	{
+		.name = "Quinary MI2S RX_Hostless",
+		.stream_name = "Quinary MI2S_RX Hostless Playback",
+		.cpu_dai_name = "QUIN_MI2S_RX_HOSTLESS",
+		.platform_name = "msm-pcm-hostless",
+		.dynamic = 1,
+		.dpcm_playback = 1,
+		.trigger = {SND_SOC_DPCM_TRIGGER_POST,
+			SND_SOC_DPCM_TRIGGER_POST},
+		.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+		.ignore_suspend = 1,
+		.ignore_pmdown_time = 1,
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.codec_name = "snd-soc-dummy",
+	},
+	{
+		.name = "Quinary MI2S TX_Hostless",
+		.stream_name = "Quinary MI2S_TX Hostless Capture",
+		.cpu_dai_name = "QUIN_MI2S_RX_HOSTLESS",
+		.platform_name = "msm-pcm-hostless",
+		.dynamic = 1,
+		.dpcm_capture = 1,
+		.trigger = {SND_SOC_DPCM_TRIGGER_POST,
+			SND_SOC_DPCM_TRIGGER_POST},
+		.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+		.ignore_suspend = 1,
+		.ignore_pmdown_time = 1,
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.codec_name = "snd-soc-dummy",
+	},
+#endif*/
 };
 
 static struct snd_soc_dai_link msm_common_be_dai_links[] = {
@@ -5370,7 +5494,20 @@
 		.ignore_suspend = 1,
 	},
 };
-
+#if defined(CONFIG_T2M_SND_FP4)
+struct snd_soc_dai_link_component awinic_codecs[] = {
+    {
+        .of_node = NULL,
+        .dai_name = "aw882xx-aif-l",
+        .name = "aw882xx_smartpa_l",
+    },
+    {
+        .of_node = NULL,
+        .dai_name = "aw882xx-aif-r",
+        .name = "aw882xx_smartpa_r",
+    },
+};
+#endif
 static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = {
 	{
 		.name = LPASS_BE_PRI_MI2S_RX,
@@ -6676,6 +6813,37 @@
 	return ret;
 }
 
+#ifdef CONFIG_T2M_SND_FP4
+int is_hac_pa_gpio_support(struct platform_device *pdev,
+            struct msm_asoc_mach_data *pdata)
+{
+    const char *hac_pa_gpio = "qcom,msm-hac-pa-gpios";
+    int ret = 0;
+
+    pr_debug("%s:Enter\n", __func__);
+
+    pdata->hac_pa_gpio_p= of_parse_phandle(pdev->dev.of_node,
+                    hac_pa_gpio, 0);
+    if (!pdata->hac_pa_gpio_p) {
+        dev_dbg(&pdev->dev, "property %s not detected in node %s",
+            hac_pa_gpio, pdev->dev.of_node->full_name);
+    } else {
+        dev_dbg(&pdev->dev, "%s detected",
+            hac_pa_gpio);
+        if (pdata->hac_pa_gpio_p) {
+            ret = msm_cdc_pinctrl_select_sleep_state(
+                        pdata->hac_pa_gpio_p);
+            if (ret) {
+                pr_err("%s: gpio set cannot be de-activated %s\n",
+                        __func__, "hac_pa");
+            }
+        }
+    }
+
+    return 0;
+}
+#endif
+
 static int msm_asoc_machine_probe(struct platform_device *pdev)
 {
 	struct snd_soc_card *card = NULL;
@@ -6801,7 +6969,12 @@
 			"qcom,us-euro-gpios");
 		wcd_mbhc_cfg.swap_gnd_mic = msm_swap_gnd_mic;
 	}
-
+#ifdef CONFIG_T2M_SND_FP4
+    ret = is_hac_pa_gpio_support(pdev, pdata);
+    if (ret < 0)
+        pr_err("%s:  doesn't support hac pa gpio\n",
+                __func__);
+#endif
 	if (wcd_mbhc_cfg.enable_usbc_analog)
 		wcd_mbhc_cfg.swap_gnd_mic = msm_usbc_swap_gnd_mic;
 
diff --git a/asoc/codecs/wcd-mbhc-v2.c b/asoc/codecs/wcd-mbhc-v2.c
index ee24ea6..12074d1 100644
--- a/asoc/codecs/wcd-mbhc-v2.c
+++ b/asoc/codecs/wcd-mbhc-v2.c
@@ -1755,6 +1755,13 @@
 		goto err;
 	}
 
+#ifdef CONFIG_T2M_SND_FP4
+    hph_swh = 1;
+	gnd_swh = 0;
+    dev_dbg(card->dev,"%s:set msm-mbhc-hphl-swh %d in dt node\n", __func__, hph_swh);
+    dev_dbg(card->dev,"%s:set msm-mbhc-gnd-swh %d in dt node\n", __func__, gnd_swh);
+#endif
+
 	ret = of_property_read_u32(card->dev->of_node, hs_thre,
 				&(mbhc->hs_thr));
 	if (ret)
diff --git a/asoc/kona.c b/asoc/kona.c
index c8874a6..7565ef1 100644
--- a/asoc/kona.c
+++ b/asoc/kona.c
@@ -201,6 +201,9 @@
 	u32 tdm_max_slots; /* Max TDM slots used */
 	int (*get_wsa_dev_num)(struct snd_soc_component*);
 	struct afe_cps_hw_intf_cfg cps_config;
+#ifdef CONFIG_T2M_SND_FP4
+    struct device_node *hac_pa_gpio_p;
+#endif
 };
 
 struct tdm_port {
@@ -494,7 +497,7 @@
 	[SEC_MI2S]  = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
 	[TERT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
 	[QUAT_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
-	[QUIN_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+	[QUIN_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2},
 	[SEN_MI2S] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
 };
 
@@ -935,6 +938,35 @@
 	.moisture_duty_cycle_en = true,
 };
 
+#ifdef CONFIG_T2M_SND_FP4
+static int msm_enable_hac_pa(struct snd_soc_dapm_widget *w,
+                       struct snd_kcontrol *kcontrol,
+                       int event);
+
+static const struct snd_kcontrol_new hac_pa_switch[] = {
+    SOC_DAPM_SINGLE("Switch", SND_SOC_NOPM, 0, 1, 0)
+};
+
+static const struct snd_soc_dapm_widget msm_hac_dapm_widgets[] = {
+    SND_SOC_DAPM_MIXER("HAC_PA", SND_SOC_NOPM, 0, 0,
+               hac_pa_switch, ARRAY_SIZE(hac_pa_switch)),
+    SND_SOC_DAPM_PGA_E("HAC PGA", SND_SOC_NOPM, 0, 0, NULL, 0,
+                msm_enable_hac_pa,
+                SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+                SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+
+    SND_SOC_DAPM_INPUT("HAC_RX"),
+    SND_SOC_DAPM_OUTPUT("HAC"),
+};
+
+static const struct snd_soc_dapm_route msm_hac_audio_map[] = {
+    {"HAC_PA", "Switch", "HAC_RX"},
+    {"HAC PGA", NULL, "HAC_PA"},
+    {"HAC", NULL, "HAC PGA"},
+};
+#endif
+
 static inline int param_is_mask(int p)
 {
 	return (p >= SNDRV_PCM_HW_PARAM_FIRST_MASK) &&
@@ -5503,6 +5535,43 @@
 	return 0;
 }
 
+#ifdef CONFIG_T2M_SND_FP4
+static int msm_enable_hac_pa(struct snd_soc_dapm_widget *w,
+                       struct snd_kcontrol *kcontrol,
+                       int event)
+{
+    struct snd_soc_component *component =
+                    snd_soc_dapm_to_component(w->dapm);
+    struct msm_asoc_mach_data *pdata = NULL;
+    int ret = 0;
+
+    dev_dbg(component->dev, "HAC %s wname: %s event: %d\n", __func__,
+        w->name, event);
+
+    pdata = snd_soc_card_get_drvdata(component->card);
+
+    switch (event) {
+    case SND_SOC_DAPM_POST_PMU:
+        ret = msm_cdc_pinctrl_select_active_state(
+                    pdata->hac_pa_gpio_p);
+        if (ret) {
+            pr_err("%s:HAC gpio set cannot be de-activated %s\n",
+                    __func__, "hac_pa");
+        }
+        break;
+    case SND_SOC_DAPM_PRE_PMD:
+        ret = msm_cdc_pinctrl_select_sleep_state(
+                    pdata->hac_pa_gpio_p);
+        if (ret) {
+            pr_err("%s:HAC gpio set cannot be de-activated %s\n",
+                    __func__, "hac_pa");
+        }
+        break;
+    };
+    return ret;
+}
+#endif
+
 static const struct snd_soc_dapm_widget msm_int_dapm_widgets[] = {
 	SND_SOC_DAPM_MIC("Analog Mic1", NULL),
 	SND_SOC_DAPM_MIC("Analog Mic2", NULL),
@@ -5624,6 +5693,16 @@
 	snd_soc_dapm_new_controls(dapm, msm_int_dapm_widgets,
 				ARRAY_SIZE(msm_int_dapm_widgets));
 
+#ifdef CONFIG_T2M_SND_FP4
+    snd_soc_dapm_new_controls(dapm, msm_hac_dapm_widgets,
+                ARRAY_SIZE(msm_hac_dapm_widgets));
+
+    snd_soc_dapm_add_routes(dapm, msm_hac_audio_map,
+                    ARRAY_SIZE(msm_hac_audio_map));
+
+    snd_soc_dapm_ignore_suspend(dapm, "HAC");
+#endif
+
 	snd_soc_dapm_ignore_suspend(dapm, "Digital Mic0");
 	snd_soc_dapm_ignore_suspend(dapm, "Digital Mic1");
 	snd_soc_dapm_ignore_suspend(dapm, "Digital Mic2");
@@ -6407,6 +6486,38 @@
 		.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
 		.ops = &msm_cdc_dma_be_ops,
 	},
+#if defined(CONFIG_SND_SMARTPA_AW882XX)
+	{
+		.name = "Quinary MI2S RX_Hostless",
+		.stream_name = "Quinary MI2S_RX Hostless Playback",
+		.cpu_dai_name = "QUIN_MI2S_RX_HOSTLESS",
+		.platform_name = "msm-pcm-hostless",
+		.dynamic = 1,
+		.dpcm_playback = 1,
+		.trigger = {SND_SOC_DPCM_TRIGGER_POST,
+			SND_SOC_DPCM_TRIGGER_POST},
+		.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+		.ignore_suspend = 1,
+		.ignore_pmdown_time = 1,
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.codec_name = "snd-soc-dummy",
+	},
+	{
+		.name = "Quinary MI2S TX_Hostless",
+		.stream_name = "Quinary MI2S_TX Hostless Capture",
+		.cpu_dai_name = "QUIN_MI2S_TX_HOSTLESS",
+		.platform_name = "msm-pcm-hostless",
+		.dynamic = 1,
+		.dpcm_capture = 1,
+		.trigger = {SND_SOC_DPCM_TRIGGER_POST,
+			SND_SOC_DPCM_TRIGGER_POST},
+		.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+		.ignore_suspend = 1,
+		.ignore_pmdown_time = 1,
+		.codec_dai_name = "snd-soc-dummy-dai",
+		.codec_name = "snd-soc-dummy",
+	},
+#endif
 };
 
 static struct snd_soc_dai_link msm_common_be_dai_links[] = {
@@ -6855,6 +6966,21 @@
 	},
 };
 
+#if defined(CONFIG_SND_SMARTPA_AW882XX)
+struct snd_soc_dai_link_component awinic_codecs[] = {
+    {
+        .of_node = NULL,
+        .dai_name = "aw882xx-aif-l",
+        .name = "aw882xx_smartpa_l",
+    },
+    {
+        .of_node = NULL,
+        .dai_name = "aw882xx-aif-r",
+        .name = "aw882xx_smartpa_r",
+    },
+};
+#endif
+
 static struct snd_soc_dai_link msm_mi2s_be_dai_links[] = {
 	{
 		.name = LPASS_BE_PRI_MI2S_RX,
@@ -6977,9 +7103,9 @@
 		.stream_name = "Quinary MI2S Playback",
 		.cpu_dai_name = "msm-dai-q6-mi2s.4",
 		.platform_name = "msm-pcm-routing",
-#ifdef CONFIG_SND_SMARTPA_AW881XX
-		.codec_name = "aw881xx_smartpa",
-		.codec_dai_name = "aw881xx-aif",
+#ifdef CONFIG_SND_SMARTPA_AW882XX
+		.num_codecs = ARRAY_SIZE(awinic_codecs),
+        .codecs = awinic_codecs,
 #else
 		.codec_name = "msm-stub-codec.1",
 		.codec_dai_name = "msm-stub-rx",
@@ -6997,8 +7123,13 @@
 		.stream_name = "Quinary MI2S Capture",
 		.cpu_dai_name = "msm-dai-q6-mi2s.4",
 		.platform_name = "msm-pcm-routing",
+#ifdef CONFIG_SND_SMARTPA_AW882XX
+		.num_codecs = ARRAY_SIZE(awinic_codecs),
+        .codecs = awinic_codecs,
+#else
 		.codec_name = "msm-stub-codec.1",
 		.codec_dai_name = "msm-stub-tx",
+#endif
 		.no_pcm = 1,
 		.dpcm_capture = 1,
 		.id = MSM_BACKEND_DAI_QUINARY_MI2S_TX,
@@ -8372,6 +8503,35 @@
 	return ret;
 }
 
+#ifdef CONFIG_T2M_SND_FP4
+int is_hac_pa_gpio_support(struct platform_device *pdev,
+            struct msm_asoc_mach_data *pdata)
+{
+    const char *hac_pa_gpio = "qcom,msm-hac-pa-gpios";//plt defined in dtsi &lagoon_snd "lito-lagoon-fp4-snd-card"
+    int ret = 0;
+
+    pr_debug("%s:HAC Enter\n", __func__);
+
+    pdata->hac_pa_gpio_p= of_parse_phandle(pdev->dev.of_node, hac_pa_gpio, 0);
+    if (!pdata->hac_pa_gpio_p) {
+        dev_dbg(&pdev->dev, "HAC property %s not detected in node %s",
+            hac_pa_gpio, pdev->dev.of_node->full_name);
+    } else {
+        dev_dbg(&pdev->dev, "%s detected", hac_pa_gpio);
+        if (pdata->hac_pa_gpio_p) {
+            ret = msm_cdc_pinctrl_select_sleep_state(
+                        pdata->hac_pa_gpio_p);
+            if (ret) {
+                pr_err("%s:HAC gpio set cannot be de-activated %s\n",
+                        __func__, "hac_pa");
+            }
+        }
+    }
+
+    return 0;
+}
+#endif
+
 static void parse_cps_configuration(struct platform_device *pdev,
 			struct msm_asoc_mach_data *pdata)
 {
@@ -8628,7 +8788,12 @@
 			"qcom,us-euro-gpios");
 		wcd_mbhc_cfg.swap_gnd_mic = msm_swap_gnd_mic;
 	}
-
+#ifdef CONFIG_T2M_SND_FP4
+    ret = is_hac_pa_gpio_support(pdev, pdata);
+    if (ret < 0)
+        pr_err("%s:HAC doesn't support hac pa gpio\n",
+                __func__);
+#endif
 	if (wcd_mbhc_cfg.enable_usbc_analog)
 		wcd_mbhc_cfg.swap_gnd_mic = msm_usbc_swap_gnd_mic;
 
diff --git a/asoc/msm-dai-fe.c b/asoc/msm-dai-fe.c
index 29e15dd..e7838ff 100644
--- a/asoc/msm-dai-fe.c
+++ b/asoc/msm-dai-fe.c
@@ -978,6 +978,38 @@
 		.probe = fe_dai_probe,
 	},
 	{
+		.capture = {
+			.stream_name = "Quinary MI2S_TX Hostless Capture",
+			.aif_name = "QUIN_MI2S_UL_HL",
+			.rates = SNDRV_PCM_RATE_8000_48000,
+			.formats = (SNDRV_PCM_FMTBIT_S16_LE |
+				    SNDRV_PCM_FMTBIT_S24_LE),
+			.channels_min = 1,
+			.channels_max = 2,
+			.rate_min = 8000,
+			.rate_max = 48000,
+		},
+		.ops = &msm_fe_dai_ops,
+		.name = "QUIN_MI2S_TX_HOSTLESS",
+		.probe = fe_dai_probe,
+	},
+	{
+		.playback = {
+			.stream_name = "Quinary MI2S_RX Hostless Playback",
+			.aif_name = "QUIN_MI2S_DL_HL",
+			.rates = SNDRV_PCM_RATE_8000_384000,
+			.formats = SNDRV_PCM_FMTBIT_S16_LE |
+				    SNDRV_PCM_FMTBIT_S24_LE,
+			.channels_min = 1,
+			.channels_max = 8,
+			.rate_min = 8000,
+			.rate_max = 384000,
+		},
+		.ops = &msm_fe_dai_ops,
+		.name = "QUIN_MI2S_RX_HOSTLESS",
+		.probe = fe_dai_probe,
+	},
+	{
 		.playback = {
 			.stream_name = "INT0 MI2S_RX Hostless Playback",
 			.aif_name = "INT0_MI2S_DL_HL",
diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c
index 7aafe2b..d619dbd 100644
--- a/asoc/msm-pcm-routing-v2.c
+++ b/asoc/msm-pcm-routing-v2.c
@@ -23843,6 +23843,10 @@
 	"ZERO", "SENARY_TX"
 };
 
+static const char * const quin_mi2s_rx_vi_fb_tx_mux_text[] = {
+    "ZERO", "QUIN_MI2S_TX"
+};
+
 static const char * const int4_mi2s_rx_vi_fb_tx_mono_mux_text[] = {
 	"ZERO", "INT5_MI2S_TX"
 };
@@ -23880,6 +23884,10 @@
 	MSM_BACKEND_DAI_MAX, MSM_BACKEND_DAI_INT5_MI2S_TX
 };
 
+static const int const quin_mi2s_rx_vi_fb_tx_value[] = {
+    MSM_BACKEND_DAI_MAX, MSM_BACKEND_DAI_QUINARY_MI2S_TX
+};
+
 static const struct soc_enum slim0_rx_vi_fb_lch_mux_enum =
 	SOC_VALUE_ENUM_DOUBLE(0, MSM_BACKEND_DAI_SLIMBUS_0_RX, 0, 0,
 	ARRAY_SIZE(slim0_rx_vi_fb_tx_lch_mux_text),
@@ -23917,6 +23925,12 @@
 	int4_mi2s_rx_vi_fb_tx_stereo_mux_text,
 	int4_mi2s_rx_vi_fb_tx_stereo_ch_value);
 
+static const struct soc_enum quin_mi2s_rx_vi_fb_mux_enum =
+    SOC_VALUE_ENUM_DOUBLE(0, MSM_BACKEND_DAI_QUINARY_MI2S_RX, 0, 0,
+    ARRAY_SIZE(quin_mi2s_rx_vi_fb_tx_mux_text),
+    quin_mi2s_rx_vi_fb_tx_mux_text,
+    quin_mi2s_rx_vi_fb_tx_value);
+
 static const struct snd_kcontrol_new slim0_rx_vi_fb_lch_mux =
 	SOC_DAPM_ENUM_EXT("SLIM0_RX_VI_FB_LCH_MUX",
 	slim0_rx_vi_fb_lch_mux_enum, spkr_prot_get_vi_lch_port,
@@ -23952,6 +23966,11 @@
 	int4_mi2s_rx_vi_fb_stereo_ch_mux_enum, spkr_prot_get_vi_rch_port,
 	spkr_prot_put_vi_rch_port);
 
+static const struct snd_kcontrol_new quin_mi2s_rx_vi_fb_mux =
+    SOC_DAPM_ENUM_EXT("QUIN_MI2S_RX_VI_FB_MUX",
+    quin_mi2s_rx_vi_fb_mux_enum, spkr_prot_get_vi_lch_port,
+    spkr_prot_put_vi_lch_port);
+
 static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = {
 	/* Frontend AIF */
 	/* Widget name equals to Front-End DAI name<Need confirmation>,
@@ -24912,6 +24931,8 @@
 	ARRAY_SIZE(int4_mi2s_rx_port_mixer_controls)),
 	/* lsm mixer definitions */
 	/* Virtual Pins to force backends ON atm */
+	SND_SOC_DAPM_MUX("QUIN_MI2S_RX_VI_FB_MUX", SND_SOC_NOPM, 0, 0,
+				&quin_mi2s_rx_vi_fb_mux),
 	SND_SOC_DAPM_MUX("PRI_MI2S_RX_VI_FB_MUX", SND_SOC_NOPM, 0, 0,
 				&mi2s_rx_vi_fb_mux),
 	SND_SOC_DAPM_MUX("INT4_MI2S_RX_VI_FB_MONO_CH_MUX", SND_SOC_NOPM, 0, 0,
@@ -27049,8 +27070,10 @@
 	{"SLIM0_RX_VI_FB_RCH_MUX", "SLIM4_TX", "SLIMBUS_4_TX"},
 	{"WSA_RX_0_VI_FB_LCH_MUX", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"},
 	{"WSA_RX_0_VI_FB_RCH_MUX", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_TX_0"},
+	{"QUIN_MI2S_RX_VI_FB_MUX", "QUIN_MI2S_TX", "QUIN_MI2S_TX"},
 	{"SLIMBUS_0_RX", NULL, "SLIM0_RX_VI_FB_LCH_MUX"},
 	{"SLIMBUS_0_RX", NULL, "SLIM0_RX_VI_FB_RCH_MUX"},
+	{"QUIN_MI2S_RX", NULL, "QUIN_MI2S_RX_VI_FB_MUX"},
 	{"WSA_CDC_DMA_RX_0", NULL, "WSA_RX_0_VI_FB_LCH_MUX"},
 	{"WSA_CDC_DMA_RX_0", NULL, "WSA_RX_0_VI_FB_RCH_MUX"},
 	{"WSA_CDC_DMA_TX_0", NULL, "BE_IN"},
@@ -29929,7 +29952,8 @@
 	{"PRI_MI2S_RX", NULL, "PRI_MI2S_DL_HL"},
 	{"TERT_MI2S_RX", NULL, "TERT_MI2S_DL_HL"},
 	{"QUAT_MI2S_UL_HL", NULL, "QUAT_MI2S_TX"},
-
+	{"QUIN_MI2S_UL_HL", NULL, "QUIN_MI2S_TX"},
+	{"QUIN_MI2S_RX", NULL, "QUIN_MI2S_DL_HL"},
 	{"INT0_MI2S_RX Port Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"},
 	{"INT0_MI2S_RX Port Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"},
 	{"INT0_MI2S_RX Port Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"},
@@ -30083,8 +30107,10 @@
 	{"SENARY_MI2S_TX", NULL, "BE_IN"},
 
 	{"PRI_MI2S_RX_VI_FB_MUX", "SENARY_TX", "SENARY_TX"},
+	{"QUIN_MI2S_RX_VI_FB_MUX", "QUIN_MI2S_TX", "QUIN_MI2S_TX"},
 	{"INT4_MI2S_RX_VI_FB_MONO_CH_MUX", "INT5_MI2S_TX", "INT5_MI2S_TX"},
 	{"INT4_MI2S_RX_VI_FB_STEREO_CH_MUX", "INT5_MI2S_TX", "INT5_MI2S_TX"},
+	{"QUIN_MI2S_RX", NULL, "QUIN_MI2S_RX_VI_FB_MUX"},
 	{"PRI_MI2S_RX", NULL, "PRI_MI2S_RX_VI_FB_MUX"},
 	{"INT4_MI2S_RX", NULL, "INT4_MI2S_RX_VI_FB_MONO_CH_MUX"},
 	{"INT4_MI2S_RX", NULL, "INT4_MI2S_RX_VI_FB_STEREO_CH_MUX"},
diff --git a/dsp/q6afe.c b/dsp/q6afe.c
index 88124df..e2dbfa4 100644
--- a/dsp/q6afe.c
+++ b/dsp/q6afe.c
@@ -43,6 +43,16 @@
 
 static struct afe_avcs_payload_port_mapping *pm[MAX_ALLOWED_USE_CASES];
 
+#ifdef CONFIG_SND_SMARTPA_AW882XX
+#include <sound/aw882xx_afe.h>
+#define AFE_MODULE_ID_AWDSP_TX			(0x10013D00)
+#define AFE_MODULE_ID_AWDSP_RX			(0x10013D01)
+#define AFE_PARAM_ID_AWDSP_RX_SET_ENABLE	(0x10013D11)
+#define AFE_PARAM_ID_AWDSP_TX_SET_ENABLE	(0x10013D13)
+#define AFE_PARAM_ID_AWDSP_RX_PARAMS            (0x10013D12)
+#define AFE_PORT_ID_AWDSP_RX			(AFE_PORT_ID_QUINARY_MI2S_RX)
+#define AFE_PORT_ID_AWDSP_TX			(AFE_PORT_ID_QUINARY_MI2S_TX)
+#endif /* #ifdef CONFIG_SND_SMARTPA_AW882XX */
 enum {
 	AFE_COMMON_RX_CAL = 0,
 	AFE_COMMON_TX_CAL,
@@ -251,6 +261,12 @@
 	uint32_t cps_ch_mask;
 	struct afe_cps_hw_intf_cfg *cps_config;
 	int lsm_afe_ports[MAX_LSM_SESSIONS];
+
+#ifdef CONFIG_SND_SMARTPA_AW882XX
+	struct rtac_cal_block_data aw_cal;
+	atomic_t aw_state;
+#endif /*CONFIG_SND_SMARTPA_AW882XX*/
+
 };
 
 struct afe_clkinfo_per_port {
@@ -920,7 +936,19 @@
 				payload, data->token);
 			return -EINVAL;
 		}
-
+#ifdef CONFIG_SND_SMARTPA_AW882XX
+        if (atomic_read(&this_afe.aw_state) == 1) {
+            if (!payload[0]) {
+                atomic_set(&this_afe.state, 0);
+            } else {
+                pr_debug("%s: status: %d", __func__, payload[0]);
+                atomic_set(&this_afe.state, -1);
+            }
+            atomic_set(&this_afe.aw_state, 0);
+            wake_up(&this_afe.wait[data->token]);
+        return 0;
+        }
+#endif /*CONFIG_SND_SMARTPA_AW882XX*/
 		if (rtac_make_afe_callback(data->payload,
 					   data->payload_size))
 			return 0;
@@ -2302,6 +2330,15 @@
 	case AFE_PARAM_ID_SP_V4_EX_VI_FTM_CFG:
 		param_info.module_id = AFE_MODULE_SPEAKER_PROTECTION_V4_VI;
 		break;
+#ifdef CONFIG_SND_SMARTPA_AW882XX
+    case AFE_PARAM_ID_AWDSP_RX_SET_ENABLE:
+    case AFE_PARAM_ID_AWDSP_RX_PARAMS:
+        param_info.module_id = AFE_MODULE_ID_AWDSP_RX;
+        break;
+    case AFE_PARAM_ID_AWDSP_TX_SET_ENABLE:
+        param_info.module_id = AFE_MODULE_ID_AWDSP_TX;
+        break;
+#endif	/*CONFIG_SND_SMARTPA_AW882XX*/
 	default:
 		pr_err("%s: default case 0x%x\n", __func__, param_id);
 		goto fail_cmd;
@@ -2390,11 +2427,11 @@
 	if (this_afe.vi_tx_port == port_id) {
 		memcpy(&afe_spk_config.v4_ch_map_cfg, &this_afe.v4_ch_map_cfg,
 			sizeof(struct afe_sp_v4_param_vi_channel_map_cfg));
-		if (afe_spk_prot_prepare(port_id, this_afe.vi_rx_port,
+		/*if (afe_spk_prot_prepare(port_id, this_afe.vi_rx_port,
 			AFE_PARAM_ID_SP_V4_VI_CHANNEL_MAP_CFG, &afe_spk_config,
 			sizeof(struct afe_sp_v4_param_vi_channel_map_cfg)))
 			pr_info("%s: SPKR_CALIB_CHANNEL_MAP_CFG failed\n",
-				 __func__);
+				 __func__);*/
 	}
 
 	if (this_afe.cal_data[AFE_FB_SPKR_PROT_CAL] == NULL ||
@@ -3530,6 +3567,177 @@
 	return ret;
 }
 
+#ifdef CONFIG_SND_SMARTPA_AW882XX
+int aw_send_afe_rx_module_enable(void *buf, int size)
+{
+    union afe_spkr_prot_config config;
+    int32_t port_id = AFE_PORT_ID_AWDSP_RX;
+
+    if (size > sizeof(config))
+        return -EINVAL;
+
+    memcpy(&config, buf, size);
+
+    if (afe_spk_prot_prepare(port_id, 0,
+        AFE_PARAM_ID_AWDSP_RX_SET_ENABLE, &config,sizeof(union afe_spkr_prot_config))) {
+        pr_err("%s: set bypass failed \n", __func__);
+        return -EINVAL;
+    }
+    return 0;
+}
+EXPORT_SYMBOL(aw_send_afe_rx_module_enable);
+int aw_send_afe_tx_module_enable(void *buf, int size)
+{
+    union afe_spkr_prot_config config;
+    int32_t port_id = AFE_PORT_ID_AWDSP_TX;
+
+    if (size > sizeof(config))
+        return -EINVAL;
+
+    memcpy(&config, buf, size);
+
+    if (afe_spk_prot_prepare(port_id, 0,
+        AFE_PARAM_ID_AWDSP_TX_SET_ENABLE, &config,sizeof(union afe_spkr_prot_config))) {
+        pr_err("%s: set bypass failed \n", __func__);
+        return -EINVAL;
+    }
+    return 0;
+}
+EXPORT_SYMBOL(aw_send_afe_tx_module_enable);
+
+int aw_send_afe_cal_apr(uint32_t param_id, void *buf, int cmd_size, bool write)
+{
+    int32_t result = 0, port_id = AFE_PORT_ID_AWDSP_RX;
+    int32_t  module_id = AFE_MODULE_ID_AWDSP_RX;
+    uint32_t port_index = 0;
+    uint32_t payload_size = 0;
+    size_t len;
+    struct rtac_cal_block_data *aw_cal = &(this_afe.aw_cal);
+    struct mem_mapping_hdr mem_hdr;
+    struct param_hdr_v3  param_hdr;
+
+    pr_debug("%s: enter\n", __func__);
+
+    if (param_id == AFE_PARAM_ID_AWDSP_TX_SET_ENABLE) {
+        port_id = AFE_PORT_ID_AWDSP_TX;
+        module_id = AFE_MODULE_ID_AWDSP_TX;
+    }
+
+    if (aw_cal->map_data.dma_buf == 0) {
+        /*Minimal chunk size is 4K*/
+        aw_cal->map_data.map_size = SZ_4K;
+        result = msm_audio_ion_alloc(&(aw_cal->map_data.dma_buf),
+                aw_cal->map_data.map_size,
+                &(aw_cal->cal_data.paddr),&len,
+                &(aw_cal->cal_data.kvaddr));
+        if (result < 0) {
+            pr_err("%s: allocate buffer failed! ret = %d\n",
+                __func__, result);
+            goto err;
+        }
+    }
+
+    if (aw_cal->map_data.map_handle == 0) {
+        result = afe_map_rtac_block(aw_cal);
+        if (result < 0) {
+            pr_err("%s: map buffer failed! ret = %d\n",
+                __func__, result);
+            goto err;
+        }
+    }
+
+    port_index = q6audio_get_port_index(port_id);
+    if (port_index >= AFE_MAX_PORTS) {
+        pr_err("%s: Invalid AFE port = 0x%x\n", __func__, port_id);
+        goto err;
+    }
+
+    if (cmd_size > (SZ_4K - sizeof(struct param_hdr_v3))) {
+        pr_err("%s: Invalid payload size = %d\n", __func__, cmd_size);
+        result = -EINVAL;
+        goto err;
+    }
+
+    /* Pack message header with data */
+    param_hdr.module_id = module_id;
+    param_hdr.instance_id = INSTANCE_ID_0;
+    param_hdr.param_size = cmd_size;
+
+    if (write) {
+        param_hdr.param_id = param_id;
+        q6common_pack_pp_params(aw_cal->cal_data.kvaddr,
+                            &param_hdr,
+                            buf,
+                            &payload_size);
+        aw_cal->cal_data.size = payload_size;
+    } else {
+        param_hdr.param_id = param_id;
+        aw_cal->cal_data.size = cmd_size + sizeof(struct param_hdr_v3);
+    }
+
+    /*Send/Get package to/from ADSP*/
+    mem_hdr.data_payload_addr_lsw =
+        lower_32_bits(aw_cal->cal_data.paddr);
+    mem_hdr.data_payload_addr_msw =
+        msm_audio_populate_upper_32_bits(aw_cal->cal_data.paddr);
+    mem_hdr.mem_map_handle =
+        aw_cal->map_data.map_handle;
+
+    pr_debug("%s: Sending aw_cal port = 0x%x, cal size = %zd, cal addr = 0x%pK\n",
+        __func__, port_id, aw_cal->cal_data.size, &aw_cal->cal_data.paddr);
+
+    result = afe_q6_interface_prepare();
+    if (result != 0) {
+        pr_err("%s: Q6 interface prepare failed %d\n", __func__, result);
+        goto err;
+    }
+
+    if (write) {
+        if (q6common_is_instance_id_supported())
+            result = q6afe_set_params_v3(port_id, port_index, &mem_hdr, NULL, payload_size);
+        else
+            result = q6afe_set_params_v2(port_id, port_index, &mem_hdr, NULL, payload_size);
+    } else {
+        int8_t *resp = (int8_t *)aw_cal->cal_data.kvaddr;
+
+        atomic_set(&this_afe.aw_state, 1);
+        if (q6common_is_instance_id_supported()) {
+            result = q6afe_get_params_v3(port_id, port_index, &mem_hdr, &param_hdr);
+            resp += sizeof(struct param_hdr_v3);
+        } else {
+            result = q6afe_get_params_v2(port_id, port_index, &mem_hdr, &param_hdr);
+            resp += sizeof(struct param_hdr_v1);
+        }
+
+        if (result) {
+            pr_err("%s: get response from port 0x%x failed %d\n",
+                __func__, port_id, result);
+            goto err;
+        }
+        else {
+            /*Copy response data to command buffer*/
+            memcpy(buf,  resp,  cmd_size);
+        }
+    }
+err:
+    return result;
+}
+EXPORT_SYMBOL(aw_send_afe_cal_apr);
+void aw_cal_unmap_memory(void)
+{
+    int result = 0;
+
+    if (this_afe.aw_cal.map_data.map_handle) {
+        result = afe_unmap_rtac_block(&this_afe.aw_cal.map_data.map_handle);
+
+        /*Force to remap after unmap failed*/
+        if (result)
+            this_afe.aw_cal.map_data.map_handle = 0;
+    }
+}
+EXPORT_SYMBOL(aw_cal_unmap_memory);
+#endif
+
 static int afe_init_cdc_reg_config(void)
 {
 	struct param_hdr_v3 param_hdr;
@@ -9632,7 +9840,7 @@
 	}
 	pr_debug("%s: src_port 0x%x  dst_port 0x%x l_ch %d r_ch %d\n",
 		 __func__, src_port, dst_port, l_ch, r_ch);
-	if (q6core_get_avcs_api_version_per_service(
+	/*if (q6core_get_avcs_api_version_per_service(
 		APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V9) {
 		if (l_ch) {
 			this_afe.v4_ch_map_cfg.chan_info[index++] = 1;
@@ -9648,7 +9856,7 @@
 		this_afe.vi_tx_port = src_port;
 		this_afe.vi_rx_port = dst_port;
 		ret = 0;
-	} else {
+	} else {*/
 		memset(&prot_config, 0, sizeof(prot_config));
 		prot_config.feedback_path_cfg.dst_portid =
 		q6audio_get_port_id(dst_port);
@@ -9666,7 +9874,7 @@
 		ret = afe_spk_prot_prepare(src_port, dst_port,
 				AFE_PARAM_ID_FEEDBACK_PATH_CFG, &prot_config,
 				 sizeof(union afe_spkr_prot_config));
-	}
+//	}
 
 fail_cmd:
 	return ret;
@@ -10644,7 +10852,15 @@
 
 	kfree(data);
 }
-
+#ifdef CONFIG_SND_SMARTPA_AW882XX
+struct aw_afe_func aw_func= {
+    .afe_get_topology = afe_get_topology,
+    .aw_send_afe_cal_apr = aw_send_afe_cal_apr,
+    .aw_send_afe_rx_module_enable = aw_send_afe_rx_module_enable,
+    .aw_send_afe_tx_module_enable = aw_send_afe_tx_module_enable,
+//	.aw_adm_param_enable = aw_adm_param_enable;	
+};
+#endif
 int __init afe_init(void)
 {
 	int i = 0, ret;
@@ -10686,7 +10902,9 @@
 		pr_err("%s: could not init cal data! %d\n", __func__, ret);
 
 	config_debug_fs_init();
-
+#ifdef CONFIG_SND_SMARTPA_AW882XX
+    aw_reg_fae_func(&aw_func);
+#endif
 	this_afe.uevent_data = kzalloc(sizeof(*(this_afe.uevent_data)), GFP_KERNEL);
 	if (!this_afe.uevent_data)
 		return -ENOMEM;
@@ -10723,6 +10941,10 @@
 
 	q6core_destroy_uevent_data(this_afe.uevent_data);
 
+#ifdef CONFIG_SND_SMARTPA_AW882XX
+    aw_cal_unmap_memory();
+#endif
+
 	afe_delete_cal_data();
 
 	config_debug_fs_exit();