[ALM:10872983][FP4-99][Audio]code update
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/kona.c b/asoc/kona.c
index c8874a6..fa514b0 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 {
@@ -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",
@@ -8372,6 +8498,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 +8783,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/dsp/q6afe.c b/dsp/q6afe.c
index 88124df..e55978c 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;
@@ -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;
@@ -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();