Merge "Revert "Revert "dsp: voice_mhi: use modified mhi sync/put api""" into audio-drivers.lnx.4.0
diff --git a/asoc/Kbuild b/asoc/Kbuild
index 2b0696b..5ff12c6 100644
--- a/asoc/Kbuild
+++ b/asoc/Kbuild
@@ -31,7 +31,6 @@
 	endif
 	ifeq ($(CONFIG_ARCH_KONA), y)
 		include $(AUDIO_ROOT)/config/konaauto.conf
-		export
 		INCS    +=  -include $(AUDIO_ROOT)/config/konaautoconf.h
 	endif
 	ifeq ($(CONFIG_ARCH_LITO), y)
diff --git a/asoc/codecs/Kbuild b/asoc/codecs/Kbuild
index 1d7142a..df86578 100644
--- a/asoc/codecs/Kbuild
+++ b/asoc/codecs/Kbuild
@@ -31,7 +31,6 @@
 	endif
 	ifeq ($(CONFIG_ARCH_KONA), y)
 		include $(AUDIO_ROOT)/config/konaauto.conf
-		export
 		INCS    +=  -include $(AUDIO_ROOT)/config/konaautoconf.h
 	endif
 	ifeq ($(CONFIG_ARCH_LITO), y)
diff --git a/asoc/codecs/bolero/Kbuild b/asoc/codecs/bolero/Kbuild
index 374b528..06883a3 100644
--- a/asoc/codecs/bolero/Kbuild
+++ b/asoc/codecs/bolero/Kbuild
@@ -28,7 +28,6 @@
 	endif
 	ifeq ($(CONFIG_ARCH_KONA), y)
 		include $(AUDIO_ROOT)/config/konaauto.conf
-		export
 		INCS    +=  -include $(AUDIO_ROOT)/config/konaautoconf.h
 	endif
 	ifeq ($(CONFIG_ARCH_LITO), y)
diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c
index d805126..45e9936 100644
--- a/asoc/codecs/bolero/bolero-cdc.c
+++ b/asoc/codecs/bolero/bolero-cdc.c
@@ -638,15 +638,14 @@
 	struct bolero_priv *priv = data;
 	int macro_idx;
 
-	if (priv->rsc_clk_cb)
-		priv->rsc_clk_cb(priv->clk_dev, BOLERO_MACRO_EVT_SSR_DOWN);
-
 	bolero_cdc_notifier_call(priv, BOLERO_WCD_EVT_PA_OFF_PRE_SSR);
 	regcache_cache_only(priv->regmap, true);
 
 	mutex_lock(&priv->clk_lock);
 	priv->dev_up = false;
 	mutex_unlock(&priv->clk_lock);
+	if (priv->rsc_clk_cb)
+		priv->rsc_clk_cb(priv->clk_dev, BOLERO_MACRO_EVT_SSR_DOWN);
 	/* call ssr event for supported macros */
 	for (macro_idx = START_MACRO; macro_idx < MAX_MACRO; macro_idx++) {
 		if (!priv->macro_params[macro_idx].event_handler)
diff --git a/asoc/codecs/bolero/bolero-clk-rsc.c b/asoc/codecs/bolero/bolero-clk-rsc.c
index 03befde..6742562 100644
--- a/asoc/codecs/bolero/bolero-clk-rsc.c
+++ b/asoc/codecs/bolero/bolero-clk-rsc.c
@@ -326,6 +326,10 @@
 		return;
 	}
 	regmap = dev_get_regmap(priv->dev->parent, NULL);
+	if (!regmap) {
+		pr_err("%s: regmap is null\n", __func__);
+		return;
+	}
 	if (enable) {
 		if (priv->reg_seq_en_cnt++ == 0) {
 			for (i = 0; i < (priv->num_fs_reg * 2); i += 2) {
@@ -401,7 +405,7 @@
 	}
 
 	mutex_lock(&priv->rsc_clk_lock);
-	if (!priv->dev_up) {
+	if (!priv->dev_up && enable) {
 		dev_err_ratelimited(priv->dev, "%s: SSR is in progress..\n",
 				__func__);
 		ret = -EINVAL;
@@ -495,6 +499,10 @@
 	}
 	clk_name_array = devm_kzalloc(&pdev->dev, clk_cnt * sizeof(char *),
 					  GFP_KERNEL);
+	if (!clk_name_array) {
+		ret = -ENOMEM;
+		goto err;
+	}
 
 	ret = of_property_read_string_array(pdev->dev.of_node, "clock-names",
 					clk_name_array, clk_cnt);
diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c
index c8a5e1d..d1ba346 100644
--- a/asoc/codecs/bolero/wsa-macro.c
+++ b/asoc/codecs/bolero/wsa-macro.c
@@ -220,6 +220,7 @@
 	struct wsa_macro_bcl_pmic_params bcl_pmic_params;
 	char __iomem *mclk_mode_muxsel;
 	u16 default_clk_id;
+	int wsa_digital_mute_status[WSA_MACRO_RX_MAX];
 };
 
 static int wsa_macro_config_ear_spkr_gain(struct snd_soc_component *component,
@@ -1775,6 +1776,72 @@
 	return 0;
 }
 
+static int wsa_macro_get_rx_mute_status(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
+{
+
+	struct snd_soc_component *component =
+				snd_soc_kcontrol_component(kcontrol);
+	struct device *wsa_dev = NULL;
+	struct wsa_macro_priv *wsa_priv = NULL;
+	int wsa_rx_shift = ((struct soc_multi_mixer_control *)
+		       kcontrol->private_value)->shift;
+
+	if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
+		return -EINVAL;
+
+	ucontrol->value.integer.value[0] =
+		wsa_priv->wsa_digital_mute_status[wsa_rx_shift];
+	return 0;
+}
+
+static int wsa_macro_set_rx_mute_status(struct snd_kcontrol *kcontrol,
+			       struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_component *component =
+				snd_soc_kcontrol_component(kcontrol);
+	struct device *wsa_dev = NULL;
+	struct wsa_macro_priv *wsa_priv = NULL;
+	int value = ucontrol->value.integer.value[0];
+	int wsa_rx_shift = ((struct soc_multi_mixer_control *)
+			kcontrol->private_value)->shift;
+
+	if (!wsa_macro_get_data(component, &wsa_dev, &wsa_priv, __func__))
+		return -EINVAL;
+
+	switch (wsa_rx_shift) {
+	case 0:
+		snd_soc_component_update_bits(component,
+				BOLERO_CDC_WSA_RX0_RX_PATH_CTL,
+				0x10, value << 4);
+		break;
+	case 1:
+		snd_soc_component_update_bits(component,
+				BOLERO_CDC_WSA_RX1_RX_PATH_CTL,
+				0x10, value << 4);
+		break;
+	case 2:
+		snd_soc_component_update_bits(component,
+				BOLERO_CDC_WSA_RX0_RX_PATH_MIX_CTL,
+				0x10, value << 4);
+		break;
+	case 3:
+		snd_soc_component_update_bits(component,
+				BOLERO_CDC_WSA_RX1_RX_PATH_MIX_CTL,
+				0x10, value << 4);
+		break;
+	default:
+		pr_err("%s: invalid argument rx_shift = %d\n", __func__,
+			wsa_rx_shift);
+		return -EINVAL;
+	}
+
+	dev_dbg(component->dev, "%s: WSA Digital Mute RX %d Enable %d\n",
+		__func__, wsa_rx_shift, value);
+	wsa_priv->wsa_digital_mute_status[wsa_rx_shift] = value;
+	return 0;
+}
+
 static int wsa_macro_get_compander(struct snd_kcontrol *kcontrol,
 			       struct snd_ctl_elem_value *ucontrol)
 {
@@ -2102,6 +2169,18 @@
 	SOC_SINGLE_SX_TLV("WSA_RX1 Digital Volume",
 			  BOLERO_CDC_WSA_RX1_RX_VOL_CTL,
 			  0, -84, 40, digital_gain),
+	SOC_SINGLE_EXT("WSA_RX0 Digital Mute", SND_SOC_NOPM, WSA_MACRO_RX0, 1,
+			0, wsa_macro_get_rx_mute_status,
+			wsa_macro_set_rx_mute_status),
+	SOC_SINGLE_EXT("WSA_RX1 Digital Mute", SND_SOC_NOPM, WSA_MACRO_RX1, 1,
+			0, wsa_macro_get_rx_mute_status,
+			wsa_macro_set_rx_mute_status),
+	SOC_SINGLE_EXT("WSA_RX0_MIX Digital Mute", SND_SOC_NOPM,
+			WSA_MACRO_RX_MIX0, 1, 0, wsa_macro_get_rx_mute_status,
+			wsa_macro_set_rx_mute_status),
+	SOC_SINGLE_EXT("WSA_RX1_MIX Digital Mute", SND_SOC_NOPM,
+			WSA_MACRO_RX_MIX1, 1, 0, wsa_macro_get_rx_mute_status,
+			wsa_macro_set_rx_mute_status),
 	SOC_SINGLE_EXT("WSA_COMP1 Switch", SND_SOC_NOPM, WSA_MACRO_COMP1, 1, 0,
 		wsa_macro_get_compander, wsa_macro_set_compander),
 	SOC_SINGLE_EXT("WSA_COMP2 Switch", SND_SOC_NOPM, WSA_MACRO_COMP2, 1, 0,
diff --git a/asoc/codecs/msm-cdc-supply.c b/asoc/codecs/msm-cdc-supply.c
index 04fd2de..220da9d 100644
--- a/asoc/codecs/msm-cdc-supply.c
+++ b/asoc/codecs/msm-cdc-supply.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
  */
 
 #include <linux/kernel.h>
@@ -357,7 +357,7 @@
 
 /*
  * msm_cdc_init_supplies:
- *	Initialize codec static supplies with regulator get
+ *	Initialize codec static supplies
  *
  * @dev: pointer to codec device
  * @supplies: pointer to regulator bulk data
@@ -371,6 +371,29 @@
 			  struct cdc_regulator *cdc_vreg,
 			  int num_supplies)
 {
+	return msm_cdc_init_supplies_v2(dev, supplies, cdc_vreg,
+					num_supplies, false);
+}
+EXPORT_SYMBOL(msm_cdc_init_supplies);
+
+/*
+ * msm_cdc_init_supplies_v2:
+ *	Initialize codec static supplies.
+ *	Initialize codec dynamic supplies based on vote_regulator_on_demand
+ *
+ * @dev: pointer to codec device
+ * @supplies: pointer to regulator bulk data
+ * @cdc_vreg: pointer to platform regulator data
+ * @num_supplies: number of supplies
+ * @vote_regulator_on_demand: initialize codec dynamic supplies at runtime
+ *
+ * Return error code if supply init is failed
+ */
+int msm_cdc_init_supplies_v2(struct device *dev,
+			  struct regulator_bulk_data **supplies,
+			  struct cdc_regulator *cdc_vreg,
+			  int num_supplies, u32 vote_regulator_on_demand)
+{
 	struct regulator_bulk_data *vsup;
 	int rc;
 	int i;
@@ -413,6 +436,9 @@
 		if (regulator_count_voltages(vsup[i].consumer) < 0)
 			continue;
 
+		if (cdc_vreg[i].ondemand && vote_regulator_on_demand)
+			continue;
+
 		rc = regulator_set_voltage(vsup[i].consumer,
 					   cdc_vreg[i].min_uV,
 					   cdc_vreg[i].max_uV);
@@ -437,7 +463,7 @@
 err_supply:
 	return rc;
 }
-EXPORT_SYMBOL(msm_cdc_init_supplies);
+EXPORT_SYMBOL(msm_cdc_init_supplies_v2);
 
 /*
  * msm_cdc_get_power_supplies:
diff --git a/asoc/codecs/wcd-mbhc-adc.c b/asoc/codecs/wcd-mbhc-adc.c
index 4ab510c..4a2c928 100644
--- a/asoc/codecs/wcd-mbhc-adc.c
+++ b/asoc/codecs/wcd-mbhc-adc.c
@@ -343,14 +343,66 @@
 	return (plug_type == MBHC_PLUG_TYPE_GND_MIC_SWAP) ? true : false;
 }
 
+static int wcd_mbhc_adc_get_spl_hs_thres(struct wcd_mbhc *mbhc)
+{
+	int hs_threshold, micbias_mv;
+
+	micbias_mv = wcd_mbhc_get_micbias(mbhc);
+	if (mbhc->hs_thr && mbhc->micb_mv != WCD_MBHC_ADC_MICBIAS_MV) {
+		if (mbhc->micb_mv == micbias_mv)
+			hs_threshold = mbhc->hs_thr;
+		else
+			hs_threshold = (mbhc->hs_thr *
+				micbias_mv) / mbhc->micb_mv;
+	} else {
+		hs_threshold = ((WCD_MBHC_ADC_HS_THRESHOLD_MV *
+			micbias_mv) / WCD_MBHC_ADC_MICBIAS_MV);
+	}
+	return hs_threshold;
+}
+
+static int wcd_mbhc_adc_get_hs_thres(struct wcd_mbhc *mbhc)
+{
+	int hs_threshold, micbias_mv;
+
+	micbias_mv = wcd_mbhc_get_micbias(mbhc);
+	if (mbhc->hs_thr) {
+		if (mbhc->micb_mv == micbias_mv)
+			hs_threshold = mbhc->hs_thr;
+		else
+			hs_threshold = (mbhc->hs_thr *
+				micbias_mv) / mbhc->micb_mv;
+	} else {
+		hs_threshold = ((WCD_MBHC_ADC_HS_THRESHOLD_MV *
+			micbias_mv) / WCD_MBHC_ADC_MICBIAS_MV);
+	}
+	return hs_threshold;
+}
+
+static int wcd_mbhc_adc_get_hph_thres(struct wcd_mbhc *mbhc)
+{
+	int hph_threshold, micbias_mv;
+
+	micbias_mv = wcd_mbhc_get_micbias(mbhc);
+	if (mbhc->hph_thr) {
+		if (mbhc->micb_mv == micbias_mv)
+			hph_threshold = mbhc->hph_thr;
+		else
+			hph_threshold = (mbhc->hph_thr *
+				micbias_mv) / mbhc->micb_mv;
+	} else {
+		hph_threshold = ((WCD_MBHC_ADC_HPH_THRESHOLD_MV *
+			micbias_mv) / WCD_MBHC_ADC_MICBIAS_MV);
+	}
+	return hph_threshold;
+}
+
 static bool wcd_mbhc_adc_check_for_spl_headset(struct wcd_mbhc *mbhc,
 					   int *spl_hs_cnt)
 {
 	bool spl_hs = false;
 	int output_mv = 0;
 	int adc_threshold = 0, adc_hph_threshold = 0;
-	struct snd_soc_component *component = mbhc->component;
-	struct wcd9xxx_pdata *pdata = dev_get_platdata(component->dev->parent);
 
 	pr_debug("%s: enter\n", __func__);
 	if (!mbhc->mbhc_cb->mbhc_micb_ctrl_thr_mic)
@@ -366,20 +418,8 @@
 	 * btn press/relesae for HEADSET type during correct work.
 	 */
 	output_mv = wcd_measure_adc_once(mbhc, MUX_CTL_IN2P);
-
-	if (mbhc->hs_thr &&
-		(pdata->micbias.micb2_mv != WCD_MBHC_ADC_MICBIAS_MV))
-		adc_threshold = mbhc->hs_thr;
-	else
-		adc_threshold = ((WCD_MBHC_ADC_HS_THRESHOLD_MV *
-			  wcd_mbhc_get_micbias(mbhc))/WCD_MBHC_ADC_MICBIAS_MV);
-
-	if (mbhc->hph_thr)
-		adc_hph_threshold = mbhc->hph_thr;
-	else
-		adc_hph_threshold = ((WCD_MBHC_ADC_HPH_THRESHOLD_MV *
-				wcd_mbhc_get_micbias(mbhc))/
-				WCD_MBHC_ADC_MICBIAS_MV);
+	adc_threshold = wcd_mbhc_adc_get_spl_hs_thres(mbhc);
+	adc_hph_threshold = wcd_mbhc_adc_get_hph_thres(mbhc);
 
 	if (output_mv > adc_threshold || output_mv < adc_hph_threshold) {
 		spl_hs = false;
@@ -412,8 +452,6 @@
 	bool is_spl_hs = false;
 	int output_mv = 0;
 	int adc_threshold = 0;
-	struct snd_soc_component *component = mbhc->component;
-	struct wcd9xxx_pdata *pdata = dev_get_platdata(component->dev->parent);
 
 	/*
 	 * Increase micbias to 2.7V to detect headsets with
@@ -433,13 +471,7 @@
 			return false;
 		}
 	}
-	if (mbhc->hs_thr &&
-		(pdata->micbias.micb2_mv != WCD_MBHC_ADC_MICBIAS_MV))
-		adc_threshold = mbhc->hs_thr;
-	else
-		adc_threshold = ((WCD_MBHC_ADC_HS_THRESHOLD_MV *
-			  wcd_mbhc_get_micbias(mbhc)) /
-			  WCD_MBHC_ADC_MICBIAS_MV);
+	adc_threshold = wcd_mbhc_adc_get_spl_hs_thres(mbhc);
 
 	while (!is_spl_hs) {
 		if (mbhc->hs_detect_work_stop) {
@@ -573,15 +605,8 @@
 	enum wcd_mbhc_plug_type plug_type = MBHC_PLUG_TYPE_INVALID;
 	u32 hph_thr = 0, hs_thr = 0;
 
-	if (mbhc->hs_thr)
-		hs_thr = mbhc->hs_thr;
-	else
-		hs_thr = WCD_MBHC_ADC_HS_THRESHOLD_MV;
-
-	if (mbhc->hph_thr)
-		hph_thr = mbhc->hph_thr;
-	else
-		hph_thr = WCD_MBHC_ADC_HPH_THRESHOLD_MV;
+	hs_thr = wcd_mbhc_adc_get_hs_thres(mbhc);
+	hph_thr = wcd_mbhc_adc_get_hph_thres(mbhc);
 
 	if (adc_result < hph_thr)
 		plug_type = MBHC_PLUG_TYPE_HEADPHONE;
@@ -609,12 +634,16 @@
 	int output_mv = 0;
 	int cross_conn;
 	int try = 0;
+	int hs_threshold, micbias_mv;
 
 	pr_debug("%s: enter\n", __func__);
 
 	mbhc = container_of(work, struct wcd_mbhc, correct_plug_swch);
 	component = mbhc->component;
 
+	micbias_mv = wcd_mbhc_get_micbias(mbhc);
+	hs_threshold = wcd_mbhc_adc_get_hs_thres(mbhc);
+
 	WCD_MBHC_RSC_LOCK(mbhc);
 	/* Mask ADC COMPLETE interrupt */
 	wcd_mbhc_hs_elec_irq(mbhc, WCD_MBHC_ELEC_HS_INS, false);
@@ -691,13 +720,15 @@
 		 */
 		plug_type = wcd_mbhc_get_plug_from_adc(mbhc, output_mv);
 
-		if ((output_mv > WCD_MBHC_ADC_HS_THRESHOLD_MV) &&
+		if ((output_mv > hs_threshold) &&
 		    (spl_hs_count < WCD_MBHC_SPL_HS_CNT)) {
 			spl_hs = wcd_mbhc_adc_check_for_spl_headset(mbhc,
 								&spl_hs_count);
+			output_mv = wcd_measure_adc_once(mbhc, MUX_CTL_IN2P);
 
 			if (spl_hs_count == WCD_MBHC_SPL_HS_CNT) {
-				output_mv = WCD_MBHC_ADC_HS_THRESHOLD_MV;
+				hs_threshold = (hs_threshold *
+				     wcd_mbhc_get_micbias(mbhc)) / micbias_mv;
 				spl_hs = true;
 				mbhc->micbias_enable = true;
 			}
@@ -707,7 +738,7 @@
 			is_pa_on = mbhc->mbhc_cb->hph_pa_on_status(
 					mbhc->component);
 
-		if ((output_mv <= WCD_MBHC_ADC_HS_THRESHOLD_MV) &&
+		if ((output_mv <= hs_threshold) &&
 		    (!is_pa_on)) {
 			/* Check for cross connection*/
 			ret = wcd_check_cross_conn(mbhc);
@@ -761,7 +792,7 @@
 			}
 		}
 
-		if (output_mv > WCD_MBHC_ADC_HS_THRESHOLD_MV) {
+		if (output_mv > hs_threshold) {
 			pr_debug("%s: cable is extension cable\n", __func__);
 			plug_type = MBHC_PLUG_TYPE_HIGH_HPH;
 			wrk_complete = true;
@@ -926,9 +957,8 @@
 
 	timeout = jiffies +
 		  msecs_to_jiffies(WCD_FAKE_REMOVAL_MIN_PERIOD_MS);
-	adc_threshold = ((WCD_MBHC_ADC_HS_THRESHOLD_MV *
-			  wcd_mbhc_get_micbias(mbhc)) /
-			  WCD_MBHC_ADC_MICBIAS_MV);
+	adc_threshold = wcd_mbhc_adc_get_hs_thres(mbhc);
+
 	do {
 		retry++;
 		/*
diff --git a/asoc/codecs/wcd9335.c b/asoc/codecs/wcd9335.c
index 22bc0e6..e501a35 100644
--- a/asoc/codecs/wcd9335.c
+++ b/asoc/codecs/wcd9335.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
  */
 #include <linux/module.h>
 #include <linux/init.h>
@@ -22,6 +22,7 @@
 #include <linux/gpio.h>
 #include <linux/mfd/wcd9xxx/wcd9xxx_registers.h>
 #include <soc/swr-wcd.h>
+#include <soc/snd_event.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
@@ -151,6 +152,8 @@
 
 static char on_demand_supply_name[][MAX_ON_DEMAND_SUPPLY_NAME_LENGTH] = {
 	"cdc-vdd-mic-bias",
+	"cdc-vdd-tx-h",
+	"cdc-vdd-rx-h"
 };
 
 enum {
@@ -5634,6 +5637,9 @@
 			snd_soc_dapm_to_component(w->dapm);
 	struct tasha_priv *tasha = snd_soc_component_get_drvdata(component);
 	struct on_demand_supply *supply;
+	struct wcd9xxx *wcd9xxx = tasha->wcd9xxx;
+	struct wcd9xxx_pdata *pdata = dev_get_platdata(component->dev->parent);
+	const char *supply_name;
 
 	if (w->shift >= ON_DEMAND_SUPPLIES_MAX) {
 		dev_err(component->dev, "%s: error index > MAX Demand supplies",
@@ -5646,6 +5652,7 @@
 		__func__, on_demand_supply_name[w->shift], event);
 
 	supply = &tasha->on_demand_list[w->shift];
+	supply_name = on_demand_supply_name[w->shift];
 	WARN_ONCE(!supply->supply, "%s isn't defined\n",
 		on_demand_supply_name[w->shift]);
 	if (!supply->supply) {
@@ -5656,6 +5663,15 @@
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
+		if (pdata->vote_regulator_on_demand) {
+			ret = wcd9xxx_vote_ondemand_regulator(wcd9xxx, pdata,
+							      supply_name,
+							      true);
+			if (ret)
+				dev_err(component->dev, "%s: Failed to vote %s\n",
+					__func__,
+					on_demand_supply_name[w->shift]);
+		}
 		ret = regulator_enable(supply->supply);
 		if (ret)
 			dev_err(component->dev, "%s: Failed to enable %s\n",
@@ -5668,6 +5684,15 @@
 			dev_err(component->dev, "%s: Failed to disable %s\n",
 				__func__,
 				on_demand_supply_name[w->shift]);
+		if (pdata->vote_regulator_on_demand) {
+			ret = wcd9xxx_vote_ondemand_regulator(wcd9xxx, pdata,
+							      supply_name,
+							      false);
+			if (ret)
+				dev_err(component->dev, "%s: Failed to unvote %s\n",
+					__func__,
+					on_demand_supply_name[w->shift]);
+		}
 		break;
 	default:
 		break;
@@ -11130,7 +11155,14 @@
 	SND_SOC_DAPM_SUPPLY(DAPM_LDO_H_STANDALONE, SND_SOC_NOPM, 0, 0,
 			    tasha_codec_force_enable_ldo_h,
 			    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
-
+	SND_SOC_DAPM_SUPPLY("tx regulator", SND_SOC_NOPM,
+			    ON_DEMAND_TX_SUPPLY, 0,
+			    tasha_codec_enable_on_demand_supply,
+			    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+	SND_SOC_DAPM_SUPPLY("rx regulator", SND_SOC_NOPM,
+			    ON_DEMAND_RX_SUPPLY, 0,
+			    tasha_codec_enable_on_demand_supply,
+			    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 	SND_SOC_DAPM_MUX("ANC0 FB MUX", SND_SOC_NOPM, 0, 0, &anc0_fb_mux),
 	SND_SOC_DAPM_MUX("ANC1 FB MUX", SND_SOC_NOPM, 0, 0, &anc1_fb_mux),
 
@@ -13708,11 +13740,23 @@
 
 	component = (struct snd_soc_component *)(wcd9xxx->ssr_priv);
 	priv = snd_soc_component_get_drvdata(component);
+	snd_event_notify(priv->dev->parent, SND_EVENT_DOWN);
 	wcd_cpe_ssr_event(priv->cpe_core, WCD_CPE_BUS_DOWN_EVENT);
-	for (i = 0; i < priv->nr; i++)
+
+	if (!priv->swr_ctrl_data)
+		return -EINVAL;
+
+	for (i = 0; i < priv->nr; i++) {
+		if (is_snd_event_fwk_enabled())
+			swrm_wcd_notify(
+				priv->swr_ctrl_data[i].swr_pdev,
+				SWR_DEVICE_SSR_DOWN, NULL);
 		swrm_wcd_notify(priv->swr_ctrl_data[i].swr_pdev,
 				SWR_DEVICE_DOWN, NULL);
-	snd_soc_card_change_online_state(component->card, 0);
+	}
+
+	if (!is_snd_event_fwk_enabled())
+		snd_soc_card_change_online_state(component->card, 0);
 	for (count = 0; count < NUM_CODEC_DAIS; count++)
 		priv->dai[count].bus_down_in_recovery = true;
 
@@ -13747,7 +13791,8 @@
 	if (tasha->machine_codec_event_cb)
 		tasha->machine_codec_event_cb(component,
 				WCD9335_CODEC_EVENT_CODEC_UP);
-	snd_soc_card_change_online_state(component->card, 1);
+	if (!is_snd_event_fwk_enabled())
+		snd_soc_card_change_online_state(component->card, 1);
 
 	/* Class-H Init*/
 	wcd_clsh_init(&tasha->clsh_d);
@@ -13807,9 +13852,21 @@
 		goto err;
 	}
 
+	if (!tasha->swr_ctrl_data) {
+		ret = -EINVAL;
+		goto err;
+	}
+
+	if (is_snd_event_fwk_enabled()) {
+		for (i = 0; i < tasha->nr; i++)
+			swrm_wcd_notify(
+				tasha->swr_ctrl_data[i].swr_pdev,
+				SWR_DEVICE_SSR_UP, NULL);
+	}
+
 	tasha_set_spkr_mode(component, tasha->spkr_mode);
 	wcd_cpe_ssr_event(tasha->cpe_core, WCD_CPE_BUS_UP_EVENT);
-
+	snd_event_notify(tasha->dev->parent, SND_EVENT_UP);
 err:
 	mutex_unlock(&tasha->codec_mutex);
 	return ret;
@@ -13835,6 +13892,28 @@
 	return NULL;
 }
 
+static void tasha_ssr_disable(struct device *dev, void *data)
+{
+	struct wcd9xxx *wcd9xxx = dev_get_drvdata(dev);
+	struct tasha_priv *tasha;
+	struct snd_soc_component *component;
+	int count = 0;
+
+	if (!wcd9xxx) {
+		dev_dbg(dev, "%s: wcd9xxx pointer NULL.\n", __func__);
+		return;
+	}
+	component = (struct snd_soc_component *)(wcd9xxx->ssr_priv);
+	tasha = snd_soc_component_get_drvdata(component);
+
+	for (count = 0; count < NUM_CODEC_DAIS; count++)
+		tasha->dai[count].bus_down_in_recovery = true;
+}
+
+static const struct snd_event_ops tasha_ssr_ops = {
+	.disable = tasha_ssr_disable,
+};
+
 static int tasha_codec_probe(struct snd_soc_component *component)
 {
 	struct wcd9xxx *control;
@@ -13899,12 +13978,14 @@
 		goto err;
 	}
 
-	supply = tasha_codec_find_ondemand_regulator(component,
-		on_demand_supply_name[ON_DEMAND_MICBIAS]);
-	if (supply) {
-		tasha->on_demand_list[ON_DEMAND_MICBIAS].supply = supply;
-		tasha->on_demand_list[ON_DEMAND_MICBIAS].ondemand_supply_count =
-				0;
+	for (i = ON_DEMAND_MICBIAS; i < ON_DEMAND_SUPPLIES_MAX; i++) {
+		supply = tasha_codec_find_ondemand_regulator(component,
+			on_demand_supply_name[i]);
+		if (supply) {
+			tasha->on_demand_list[i].supply = supply;
+			tasha->on_demand_list[i].ondemand_supply_count =
+					0;
+		}
 	}
 
 	tasha->fw_data = devm_kzalloc(component->dev,
@@ -14654,6 +14735,14 @@
 	tasha_update_reg_defaults(tasha);
 	schedule_work(&tasha->tasha_add_child_devices_work);
 	tasha_get_codec_ver(tasha);
+	ret = snd_event_client_register(pdev->dev.parent, &tasha_ssr_ops, NULL);
+	if (!ret) {
+		snd_event_notify(pdev->dev.parent, SND_EVENT_UP);
+	} else {
+		pr_err("%s: Registration with SND event fwk failed ret = %d\n",
+			   __func__, ret);
+		ret = 0;
+	}
 
 	dev_info(&pdev->dev, "%s: Tasha driver probe done\n", __func__);
 	return ret;
@@ -14682,6 +14771,7 @@
 	if (!tasha)
 		return -EINVAL;
 
+	snd_event_client_deregister(pdev->dev.parent);
 	for (count = 0; count < tasha->child_count &&
 		count < WCD9335_CHILD_DEVICES_MAX; count++)
 		platform_device_unregister(tasha->pdev_child_devices[count]);
diff --git a/asoc/codecs/wcd9335.h b/asoc/codecs/wcd9335.h
index 969ac67..707f2e9 100644
--- a/asoc/codecs/wcd9335.h
+++ b/asoc/codecs/wcd9335.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
  */
 #ifndef WCD9335_H
 #define WCD9335_H
@@ -81,6 +81,8 @@
 
 enum tasha_on_demand_supply {
 	ON_DEMAND_MICBIAS = 0,
+	ON_DEMAND_TX_SUPPLY,
+	ON_DEMAND_RX_SUPPLY,
 	ON_DEMAND_SUPPLIES_MAX,
 };
 
diff --git a/asoc/codecs/wcd934x/wcd934x-mbhc.c b/asoc/codecs/wcd934x/wcd934x-mbhc.c
index f00e4c0..d777d8d 100644
--- a/asoc/codecs/wcd934x/wcd934x-mbhc.c
+++ b/asoc/codecs/wcd934x/wcd934x-mbhc.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
  */
 #include <linux/module.h>
 #include <linux/init.h>
@@ -1102,6 +1102,7 @@
 	struct wcd934x_mbhc *wcd934x_mbhc;
 	struct wcd_mbhc *wcd_mbhc;
 	int ret;
+	struct wcd9xxx_pdata *pdata;
 
 	wcd934x_mbhc = devm_kzalloc(component->dev, sizeof(struct wcd934x_mbhc),
 				    GFP_KERNEL);
@@ -1122,6 +1123,14 @@
 	/* Setting default mbhc detection logic to ADC for Tavil */
 	wcd_mbhc->mbhc_detection_logic = WCD_DETECTION_ADC;
 
+	pdata = dev_get_platdata(component->dev->parent);
+	if (!pdata) {
+		dev_err(component->dev, "%s: pdata pointer is NULL\n", __func__);
+		ret = -EINVAL;
+		goto err;
+	}
+	wcd_mbhc->micb_mv = pdata->micbias.micb2_mv;
+
 	ret = wcd_mbhc_init(wcd_mbhc, component, &mbhc_cb,
 				&intr_ids, wcd_mbhc_registers,
 				TAVIL_ZDET_SUPPORTED);
diff --git a/asoc/codecs/wcd934x/wcd934x.c b/asoc/codecs/wcd934x/wcd934x.c
index 07bbcb3..f1c3536 100644
--- a/asoc/codecs/wcd934x/wcd934x.c
+++ b/asoc/codecs/wcd934x/wcd934x.c
@@ -1,5 +1,5 @@
 // SPDX-License-Identifier: GPL-2.0-only
-/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
  */
 #include <linux/module.h>
 #include <linux/init.h>
@@ -4687,20 +4687,18 @@
 
 		tavil->tx_hpf_work[decimator].hpf_cut_off_freq =
 							hpf_cut_off_freq;
-		if (hpf_cut_off_freq != CF_MIN_3DB_150HZ) {
-			snd_soc_component_update_bits(component, dec_cfg_reg,
-					    TX_HPF_CUT_OFF_FREQ_MASK,
-					    CF_MIN_3DB_150HZ << 5);
-			snd_soc_component_update_bits(component, hpf_gate_reg,
+		snd_soc_component_update_bits(component, dec_cfg_reg,
+					TX_HPF_CUT_OFF_FREQ_MASK,
+					CF_MIN_3DB_150HZ << 5);
+		snd_soc_component_update_bits(component, hpf_gate_reg,
 					0x02, 0x02);
-			/*
-			 * Minimum 1 clk cycle delay is required as per
-			 * HW spec.
-			 */
-			usleep_range(1000, 1010);
-			snd_soc_component_update_bits(component, hpf_gate_reg,
+		/*
+		 * Minimum 1 clk cycle delay is required as per
+		 * HW spec.
+		 */
+		usleep_range(1000, 1010);
+		snd_soc_component_update_bits(component, hpf_gate_reg,
 					0x02, 0x00);
-		}
 		/* schedule work queue to Remove Mute */
 		schedule_delayed_work(&tavil->tx_mute_dwork[decimator].dwork,
 				      msecs_to_jiffies(tx_unmute_delay));
diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c
index fcc4e6f..bde3a7e 100644
--- a/asoc/codecs/wcd937x/wcd937x.c
+++ b/asoc/codecs/wcd937x/wcd937x.c
@@ -134,6 +134,12 @@
 	snd_soc_component_update_bits(component,
 				WCD937X_HPH_SURGE_HPHLR_SURGE_EN,
 				0xFF, 0xD9);
+	snd_soc_component_update_bits(component, WCD937X_MICB1_TEST_CTL_1,
+				0xFF, 0xFA);
+	snd_soc_component_update_bits(component, WCD937X_MICB2_TEST_CTL_1,
+				0xFF, 0xFA);
+	snd_soc_component_update_bits(component, WCD937X_MICB3_TEST_CTL_1,
+				0xFF, 0xFA);
 	return 0;
 }
 
diff --git a/asoc/codecs/wcd938x/Kbuild b/asoc/codecs/wcd938x/Kbuild
index e301bd5..3dfe142 100644
--- a/asoc/codecs/wcd938x/Kbuild
+++ b/asoc/codecs/wcd938x/Kbuild
@@ -16,7 +16,6 @@
 ifeq ($(KERNEL_BUILD), 0)
 	ifeq ($(CONFIG_ARCH_KONA), y)
 		include $(AUDIO_ROOT)/config/konaauto.conf
-		export
 		INCS    +=  -include $(AUDIO_ROOT)/config/konaautoconf.h
 	endif
 	ifeq ($(CONFIG_ARCH_LITO), y)
diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c
index ca20bc4..6241cf2 100644
--- a/asoc/codecs/wcd938x/wcd938x.c
+++ b/asoc/codecs/wcd938x/wcd938x.c
@@ -1655,13 +1655,20 @@
 			snd_soc_dapm_kcontrol_widget(kcontrol);
 	struct snd_soc_component *component =
 			snd_soc_kcontrol_component(kcontrol);
-	struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
-	u32 path = 0;
+	struct wcd938x_priv *wcd938x = NULL;
+	int path = 0;
 
-	if (!widget || !widget->name || !wcd938x || !component)
+	if (!component)
+		return -EINVAL;
+
+	wcd938x = snd_soc_component_get_drvdata(component);
+
+	if (!widget || !widget->name || !wcd938x)
 		return -EINVAL;
 
 	path = wcd938x_tx_path_get(widget->name);
+	if (path < 0 || path >= TX_ADC_MAX)
+		return -EINVAL;
 
 	ucontrol->value.integer.value[0] = wcd938x->tx_mode[path];
 
@@ -1675,14 +1682,22 @@
 			snd_soc_dapm_kcontrol_widget(kcontrol);
 	struct snd_soc_component *component =
 			snd_soc_kcontrol_component(kcontrol);
-	struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
+	struct wcd938x_priv *wcd938x = NULL;
 	u32 mode_val;
-	u32 path = 0;
+	int path = 0;
 
-	if (!widget || !widget->name || !wcd938x || !component)
+	if (!component)
+		return -EINVAL;
+
+	wcd938x  = snd_soc_component_get_drvdata(component);
+
+	if (!widget || !widget->name || !wcd938x)
 		return -EINVAL;
 
 	path = wcd938x_tx_path_get(widget->name);
+	if (path < 0 || path >= TX_ADC_MAX)
+		return -EINVAL;
+
 	mode_val = ucontrol->value.enumerated.item[0];
 
 	dev_dbg(component->dev, "%s: mode: %d\n", __func__, mode_val);
diff --git a/asoc/codecs/wcd9xxx-core.c b/asoc/codecs/wcd9xxx-core.c
index b0cb9c7..fd2e933 100644
--- a/asoc/codecs/wcd9xxx-core.c
+++ b/asoc/codecs/wcd9xxx-core.c
@@ -1,5 +1,5 @@
 // SPDX-License-Identifier: GPL-2.0-only
-/* Copyright (c) 2011-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2019, The Linux Foundation. All rights reserved.
  */
 
 #include <linux/kernel.h>
@@ -98,6 +98,65 @@
 
 struct wcd9xxx_i2c wcd9xxx_modules[MAX_WCD9XXX_DEVICE];
 
+/*
+ * wcd9xxx_vote_ondemand_regulator: Initialize codec dynamic supplies
+ *
+ * @wcd9xxx: Pointer to wcd9xxx structure
+ * @wcd9xxx_pdata: Pointer to wcd9xxx_pdata structure
+ * @supply_name: supply parameter to initialize regulator
+ * @enable: flag to initialize/uninitialize supply
+ *
+ * Return error code if supply init is failed
+ */
+int wcd9xxx_vote_ondemand_regulator(struct wcd9xxx *wcd9xxx,
+				    struct wcd9xxx_pdata *pdata,
+				    const char *supply_name,
+				    bool enable)
+{
+	int i, rc, index = -EINVAL;
+
+	pr_debug("%s: enable %d\n", __func__, enable);
+
+	for (i = 0; i < wcd9xxx->num_of_supplies; ++i) {
+		if (pdata->regulator[i].ondemand &&
+		    wcd9xxx->supplies[i].supply &&
+		    !strcmp(wcd9xxx->supplies[i].supply, supply_name)) {
+			index = i;
+			break;
+		}
+	}
+
+	if (index < 0) {
+		pr_err("%s: no matching regulator found\n", __func__);
+		return -EINVAL;
+	}
+
+	if (enable) {
+		rc = regulator_set_voltage(wcd9xxx->supplies[index].consumer,
+					   pdata->regulator[index].min_uV,
+					   pdata->regulator[index].max_uV);
+		if (rc) {
+			pr_err("%s: set regulator voltage failed for %s, err:%d\n",
+				__func__, supply_name, rc);
+			return rc;
+		}
+		rc = regulator_set_load(wcd9xxx->supplies[index].consumer,
+					pdata->regulator[index].optimum_uA);
+		if (rc < 0) {
+			pr_err("%s: set regulator optimum mode failed for %s, err:%d\n",
+				__func__, supply_name, rc);
+			return rc;
+		}
+	} else {
+		regulator_set_voltage(wcd9xxx->supplies[index].consumer, 0,
+				      pdata->regulator[index].max_uV);
+		regulator_set_load(wcd9xxx->supplies[index].consumer, 0);
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(wcd9xxx_vote_ondemand_regulator);
+
 static int wcd9xxx_slim_multi_reg_write(struct wcd9xxx *wcd9xxx,
 					const void *data, size_t count)
 {
@@ -1069,9 +1128,10 @@
 			wcd9xxx->mclk_rate = pdata->mclk_rate;
 
 		wcd9xxx->num_of_supplies = pdata->num_supplies;
-		ret = msm_cdc_init_supplies(wcd9xxx->dev, &wcd9xxx->supplies,
-					    pdata->regulator,
-					    pdata->num_supplies);
+		ret = msm_cdc_init_supplies_v2(wcd9xxx->dev, &wcd9xxx->supplies,
+					       pdata->regulator,
+					       pdata->num_supplies,
+					       pdata->vote_regulator_on_demand);
 		if (!wcd9xxx->supplies) {
 			dev_err(wcd9xxx->dev, "%s: Cannot init wcd supplies\n",
 				__func__);
@@ -1327,9 +1387,10 @@
 	}
 
 	wcd9xxx->num_of_supplies = pdata->num_supplies;
-	ret = msm_cdc_init_supplies(&slim->dev, &wcd9xxx->supplies,
-				    pdata->regulator,
-				    pdata->num_supplies);
+	ret = msm_cdc_init_supplies_v2(&slim->dev, &wcd9xxx->supplies,
+				       pdata->regulator,
+				       pdata->num_supplies,
+				       pdata->vote_regulator_on_demand);
 	if (!wcd9xxx->supplies) {
 		dev_err(wcd9xxx->dev, "%s: Cannot init wcd supplies\n",
 			__func__);
diff --git a/asoc/codecs/wcd9xxx-utils.c b/asoc/codecs/wcd9xxx-utils.c
index 06968dc..face711 100644
--- a/asoc/codecs/wcd9xxx-utils.c
+++ b/asoc/codecs/wcd9xxx-utils.c
@@ -1,5 +1,5 @@
 // SPDX-License-Identifier: GPL-2.0-only
-/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
  */
 
 #include <linux/kernel.h>
@@ -414,6 +414,14 @@
 
 	pdata->dmic_clk_drv = dmic_clk_drive;
 
+	rc = of_property_read_u32(dev->of_node,
+					"qcom,vote-dynamic-supply-on-demand",
+					&pdata->vote_regulator_on_demand);
+	if (rc)
+		dev_dbg(dev, "%s No entry for %s property in node %s\n",
+				__func__, "qcom,vote-dynamic-supply-on-demand",
+				dev->of_node->full_name);
+
 	return pdata;
 
 err_parse_dt_prop:
diff --git a/asoc/sm8250-port-config.h b/asoc/kona-port-config.h
similarity index 95%
rename from asoc/sm8250-port-config.h
rename to asoc/kona-port-config.h
index 503d514..0f73791 100644
--- a/asoc/sm8250-port-config.h
+++ b/asoc/kona-port-config.h
@@ -3,8 +3,8 @@
  * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
  */
 
-#ifndef _SM8250_PORT_CONFIG
-#define _SM8250_PORT_CONFIG
+#ifndef _KONA_PORT_CONFIG
+#define _KONA_PORT_CONFIG
 
 #include <soc/swr-common.h>
 
@@ -57,4 +57,4 @@
 	{WSA_MACRO, SWR_UC0, wsa_frame_params_default},
 };
 
-#endif /* _SM8250_PORT_CONFIG */
+#endif /* _KONA_PORT_CONFIG */
diff --git a/asoc/kona.c b/asoc/kona.c
index 574c652..50a25b1 100644
--- a/asoc/kona.c
+++ b/asoc/kona.c
@@ -35,7 +35,7 @@
 #include "codecs/bolero/bolero-cdc.h"
 #include <dt-bindings/sound/audio-codec-port-types.h>
 #include "codecs/bolero/wsa-macro.h"
-#include "sm8250-port-config.h"
+#include "kona-port-config.h"
 
 #define DRV_NAME "kona-asoc-snd"
 #define __CHIPSET__ "KONA "
@@ -73,6 +73,7 @@
 #define WSA8810_NAME_2 "wsa881x.20170212"
 #define WCN_CDC_SLIM_RX_CH_MAX 2
 #define WCN_CDC_SLIM_TX_CH_MAX 2
+#define WCN_CDC_SLIM_TX_CH_MAX_LITO 3
 
 enum {
 	TDM_0 = 0,
@@ -137,6 +138,7 @@
 };
 enum {
 	SLIM_TX_7 = 0,
+	SLIM_TX_8,
 	SLIM_TX_MAX,
 };
 
@@ -191,6 +193,7 @@
 
 static struct dev_config slim_tx_cfg[] = {
 	[SLIM_TX_7] = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
+	[SLIM_TX_8] = {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2},
 };
 
 /* Default configuration of external display BE */
@@ -3632,6 +3635,12 @@
 			slim_tx_cfg[SLIM_TX_7].channels;
 		break;
 
+	case MSM_BACKEND_DAI_SLIMBUS_8_TX:
+		rate->min = rate->max = slim_tx_cfg[SLIM_TX_8].sample_rate;
+		channels->min = channels->max =
+			slim_tx_cfg[SLIM_TX_8].channels;
+		break;
+
 	case MSM_BACKEND_DAI_AFE_LOOPBACK_TX:
 		param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
 				afe_loopback_tx_cfg[idx].bit_format);
@@ -3991,6 +4000,41 @@
 	mutex_unlock(&mi2s_intf_conf[index].lock);
 }
 
+static int msm_wcn_hw_params_lito(struct snd_pcm_substream *substream,
+			     struct snd_pcm_hw_params *params)
+{
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct snd_soc_dai *codec_dai = rtd->codec_dai;
+	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+	struct snd_soc_dai_link *dai_link = rtd->dai_link;
+	u32 rx_ch[WCN_CDC_SLIM_RX_CH_MAX], tx_ch[WCN_CDC_SLIM_TX_CH_MAX_LITO];
+	u32 rx_ch_cnt = 0, tx_ch_cnt = 0;
+	int ret = 0;
+
+	dev_dbg(rtd->dev, "%s: %s_tx_dai_id_%d\n", __func__,
+		 codec_dai->name, codec_dai->id);
+	ret = snd_soc_dai_get_channel_map(codec_dai,
+				 &tx_ch_cnt, tx_ch, &rx_ch_cnt, rx_ch);
+	if (ret) {
+		dev_err(rtd->dev,
+			"%s: failed to get BTFM codec chan map\n, err:%d\n",
+			__func__, ret);
+		goto err;
+	}
+
+	dev_dbg(rtd->dev, "%s: tx_ch_cnt(%d) BE id %d\n",
+		__func__, tx_ch_cnt, dai_link->id);
+
+	ret = snd_soc_dai_set_channel_map(cpu_dai,
+					  tx_ch_cnt, tx_ch, rx_ch_cnt, rx_ch);
+	if (ret)
+		dev_err(rtd->dev, "%s: failed to set cpu chan map, err:%d\n",
+			__func__, ret);
+
+err:
+	return ret;
+}
+
 static int msm_wcn_hw_params(struct snd_pcm_substream *substream,
 			     struct snd_pcm_hw_params *params)
 {
@@ -4047,6 +4091,10 @@
 	.hw_params = msm_wcn_hw_params,
 };
 
+static struct snd_soc_ops msm_wcn_ops_lito = {
+	.hw_params = msm_wcn_hw_params_lito,
+};
+
 static int msm_dmic_event(struct snd_soc_dapm_widget *w,
 			  struct snd_kcontrol *kcontrol, int event)
 {
@@ -4155,6 +4203,16 @@
 					   tx_ch, ARRAY_SIZE(rx_ch), rx_ch);
 }
 
+static int msm_wcn_init_lito(struct snd_soc_pcm_runtime *rtd)
+{
+	unsigned int rx_ch[WCN_CDC_SLIM_RX_CH_MAX] = {157, 158};
+	unsigned int tx_ch[WCN_CDC_SLIM_TX_CH_MAX_LITO]  = {159, 160, 161};
+	struct snd_soc_dai *codec_dai = rtd->codec_dai;
+
+	return snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch),
+					   tx_ch, ARRAY_SIZE(rx_ch), rx_ch);
+}
+
 static int msm_int_audrx_init(struct snd_soc_pcm_runtime *rtd)
 {
 	int ret = -EINVAL;
@@ -4897,6 +4955,22 @@
 		.ignore_pmdown_time = 1,
 		.id = MSM_FRONTEND_DAI_MULTIMEDIA17,
 	},
+	{/* hw:x,38 */
+		.name = "SLIMBUS_8 Hostless",
+		.stream_name = "SLIMBUS_8 Hostless",
+		.cpu_dai_name = "SLIMBUS8_HOSTLESS",
+		.platform_name = "msm-pcm-hostless",
+		.dynamic = 1,
+		.dpcm_capture = 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",
+	},
 };
 
 static struct snd_soc_dai_link msm_common_be_dai_links[] = {
@@ -5141,6 +5215,58 @@
 	},
 };
 
+static struct snd_soc_dai_link msm_wcn_btfm_be_dai_links[] = {
+	{
+		.name = LPASS_BE_SLIMBUS_7_RX,
+		.stream_name = "Slimbus7 Playback",
+		.cpu_dai_name = "msm-dai-q6-dev.16398",
+		.platform_name = "msm-pcm-routing",
+		.codec_name = "btfmslim_slave",
+		/* BT codec driver determines capabilities based on
+		 * dai name, bt codecdai name should always contains
+		 * supported usecase information
+		 */
+		.codec_dai_name = "btfm_bt_sco_a2dp_slim_rx",
+		.no_pcm = 1,
+		.dpcm_playback = 1,
+		.id = MSM_BACKEND_DAI_SLIMBUS_7_RX,
+		.be_hw_params_fixup = msm_be_hw_params_fixup,
+		.init = &msm_wcn_init_lito,
+		.ops = &msm_wcn_ops_lito,
+		/* dai link has playback support */
+		.ignore_pmdown_time = 1,
+		.ignore_suspend = 1,
+	},
+	{
+		.name = LPASS_BE_SLIMBUS_7_TX,
+		.stream_name = "Slimbus7 Capture",
+		.cpu_dai_name = "msm-dai-q6-dev.16399",
+		.platform_name = "msm-pcm-routing",
+		.codec_name = "btfmslim_slave",
+		.codec_dai_name = "btfm_bt_sco_slim_tx",
+		.no_pcm = 1,
+		.dpcm_capture = 1,
+		.id = MSM_BACKEND_DAI_SLIMBUS_7_TX,
+		.be_hw_params_fixup = msm_be_hw_params_fixup,
+		.ops = &msm_wcn_ops_lito,
+		.ignore_suspend = 1,
+	},
+	{
+		.name = LPASS_BE_SLIMBUS_8_TX,
+		.stream_name = "Slimbus8 Capture",
+		.cpu_dai_name = "msm-dai-q6-dev.16401",
+		.platform_name = "msm-pcm-routing",
+		.codec_name = "btfmslim_slave",
+		.codec_dai_name = "btfm_fm_slim_tx",
+		.no_pcm = 1,
+		.dpcm_capture = 1,
+		.id = MSM_BACKEND_DAI_SLIMBUS_8_TX,
+		.be_hw_params_fixup = msm_be_hw_params_fixup,
+		.ops = &msm_wcn_ops_lito,
+		.ignore_suspend = 1,
+	},
+};
+
 static struct snd_soc_dai_link ext_disp_be_dai_link[] = {
 	/* DISP PORT BACK END DAI Link */
 	{
@@ -5566,7 +5692,8 @@
 			ARRAY_SIZE(msm_va_cdc_dma_be_dai_links) +
 			ARRAY_SIZE(ext_disp_be_dai_link) +
 			ARRAY_SIZE(msm_wcn_be_dai_links) +
-			ARRAY_SIZE(msm_afe_rxtx_lb_be_dai_link)];
+			ARRAY_SIZE(msm_afe_rxtx_lb_be_dai_link) +
+			ARRAY_SIZE(msm_wcn_btfm_be_dai_links)];
 
 static int msm_populate_dai_link_component_of_node(
 					struct snd_soc_card *card)
@@ -5769,6 +5896,7 @@
 	u32 mi2s_audio_intf = 0;
 	u32 auxpcm_audio_intf = 0;
 	u32 val = 0;
+	u32 wcn_btfm_intf = 0;
 	const struct of_device_id *match;
 
 	match = of_match_node(kona_asoc_machine_of_match, dev->of_node);
@@ -5881,6 +6009,21 @@
 			total_links +=
 				ARRAY_SIZE(msm_afe_rxtx_lb_be_dai_link);
 		}
+
+		rc = of_property_read_u32(dev->of_node, "qcom,wcn-btfm",
+					  &wcn_btfm_intf);
+		if (rc) {
+			dev_dbg(dev, "%s: No DT match wcn btfm interface\n",
+				__func__);
+		} else {
+			if (wcn_btfm_intf) {
+				memcpy(msm_kona_dai_links + total_links,
+					msm_wcn_btfm_be_dai_links,
+					sizeof(msm_wcn_btfm_be_dai_links));
+				total_links +=
+					ARRAY_SIZE(msm_wcn_btfm_be_dai_links);
+			}
+		}
 		dailink = msm_kona_dai_links;
 	} else if(!strcmp(match->data, "stub_codec")) {
 		card = &snd_soc_card_stub_msm;
diff --git a/asoc/msm-compress-q6-v2.c b/asoc/msm-compress-q6-v2.c
index a7b9ff2..f358e45 100644
--- a/asoc/msm-compress-q6-v2.c
+++ b/asoc/msm-compress-q6-v2.c
@@ -76,6 +76,10 @@
 
 #define SND_DEC_DDP_MAX_PARAMS 18
 
+#ifndef COMPRESSED_PERF_MODE_FLAG
+#define COMPRESSED_PERF_MODE_FLAG 0
+#endif
+
 struct msm_compr_gapless_state {
 	bool set_next_stream_id;
 	int32_t stream_opened[MAX_NUMBER_OF_STREAMS];
@@ -2042,6 +2046,11 @@
 		}
 	}
 
+	if (params->codec.flags & COMPRESSED_PERF_MODE_FLAG) {
+		pr_debug("%s: setting perf mode = %d", __func__, LOW_LATENCY_PCM_MODE);
+		prtd->audio_client->perf_mode = LOW_LATENCY_PCM_MODE;
+	}
+
 	switch (params->codec.id) {
 	case SND_AUDIOCODEC_PCM: {
 		pr_debug("SND_AUDIOCODEC_PCM\n");
@@ -3741,7 +3750,7 @@
 
 	pr_debug("%s: fe_id- %llu\n", __func__, fe_id);
 
-	if (fe_id >= MSM_FRONTEND_DAI_MAX) {
+	if (fe_id >= MSM_FRONTEND_DAI_MM_SIZE) {
 		pr_err("%s Received out of bounds fe_id %llu\n",
 			__func__, fe_id);
 		rc = -EINVAL;
@@ -3783,7 +3792,7 @@
 	int rc = 0, i;
 
 	pr_debug("%s: fe_id- %llu\n", __func__, fe_id);
-	if (fe_id >= MSM_FRONTEND_DAI_MAX) {
+	if (fe_id >= MSM_FRONTEND_DAI_MM_SIZE) {
 		pr_err("%s: Received out of bounds fe_id %llu\n",
 			__func__, fe_id);
 		rc = -EINVAL;
@@ -4729,6 +4738,16 @@
 	chmixer_pspd->output_channel = ucontrol->value.integer.value[3];
 	chmixer_pspd->port_idx = ucontrol->value.integer.value[4];
 
+	if (chmixer_pspd->input_channel <= 0 ||
+		chmixer_pspd->input_channel > PCM_FORMAT_MAX_NUM_CHANNEL_V8 ||
+		chmixer_pspd->output_channel <= 0 ||
+		chmixer_pspd->output_channel > PCM_FORMAT_MAX_NUM_CHANNEL_V8) {
+		pr_err("%s: Invalid channels, in %d, out %d\n",
+				__func__, chmixer_pspd->input_channel,
+				chmixer_pspd->output_channel);
+		return -EINVAL;
+	}
+
 	if (chmixer_pspd->enable) {
 		if (session_type == SESSION_TYPE_RX &&
 			!chmixer_pspd->override_in_ch_map) {
@@ -4737,11 +4756,6 @@
 					chmixer_pspd->in_ch_map[i] =
 						pdata->ch_map[fe_id]->channel_map[i];
 			} else {
-				if (chmixer_pspd->input_channel > PCM_FORMAT_MAX_NUM_CHANNEL_V8) {
-					pr_err("%s: Invalid channel count %d\n",
-						__func__, chmixer_pspd->input_channel);
-					return -EINVAL;
-				}
 				q6asm_map_channels(asm_ch_map,
 					chmixer_pspd->input_channel, false);
 				for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++)
@@ -4756,11 +4770,6 @@
 					chmixer_pspd->out_ch_map[i] =
 						pdata->ch_map[fe_id]->channel_map[i];
 			} else {
-				if (chmixer_pspd->output_channel > PCM_FORMAT_MAX_NUM_CHANNEL_V8) {
-					pr_err("%s: Invalid channel count %d\n",
-						__func__, chmixer_pspd->output_channel);
-					return -EINVAL;
-				}
 				q6asm_map_channels(asm_ch_map,
 					chmixer_pspd->output_channel, false);
 				for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++)
@@ -4782,13 +4791,8 @@
 	cstream = pdata->cstream[fe_id];
 	if (chmixer_pspd->enable && cstream && cstream->runtime) {
 		prtd = cstream->runtime->private_data;
-		if (!prtd) {
-			pr_err("%s invalid prtd\n", __func__);
-			ret = -EINVAL;
-			goto done;
-		}
 
-		if (prtd->audio_client) {
+		if (prtd && prtd->audio_client) {
 			stream_id = prtd->audio_client->session;
 			be_id = chmixer_pspd->port_idx;
 			ret = msm_pcm_routing_set_channel_mixer_runtime(be_id,
@@ -4801,7 +4805,6 @@
 	if (reset_override_in_ch_map)
 		chmixer_pspd->override_in_ch_map = false;
 
-done:
 	return ret;
 }
 
diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c
index d4f33c7..1a82d65 100644
--- a/asoc/msm-dai-q6-v2.c
+++ b/asoc/msm-dai-q6-v2.c
@@ -1091,17 +1091,6 @@
 	}
 
 	afe_open(aux_dai_data->rx_pid, &dai_data->port_config, dai_data->rate);
-	if (q6core_get_avcs_api_version_per_service(
-		APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V4) {
-		/*
-		 * send island mode config
-		 * This should be the first configuration
-		 */
-		rc = afe_send_port_island_mode(aux_dai_data->tx_pid);
-		if (rc)
-			dev_err(dai->dev, "%s: afe send island mode failed %d\n",
-				__func__, rc);
-	}
 	afe_open(aux_dai_data->tx_pid, &dai_data->port_config, dai_data->rate);
 	goto exit;
 
@@ -5029,18 +5018,6 @@
 		dai->id, port_id, dai_data->channels, dai_data->rate);
 
 	if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
-		if (q6core_get_avcs_api_version_per_service(
-		APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V4) {
-			/*
-			 * send island mode config.
-			 * This should be the first configuration
-			 */
-			rc = afe_send_port_island_mode(port_id);
-			if (rc)
-				dev_err(dai->dev, "%s: afe send island mode failed %d\n",
-					__func__, rc);
-		}
-
 		/* PORT START should be set if prepare called
 		 * in active state.
 		 */
@@ -8296,17 +8273,6 @@
 	group_ref = &tdm_group_ref[group_idx];
 
 	if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
-		if (q6core_get_avcs_api_version_per_service(
-		APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V4) {
-			/*
-			 * send island mode config.
-			 * This should be the first configuration
-			 */
-			rc = afe_send_port_island_mode(dai->id);
-			if (rc)
-				dev_err(dai->dev, "%s: afe send island mode failed %d\n",
-					__func__, rc);
-		}
 
 		if (msm_dai_q6_get_tdm_clk_ref(group_idx) == 0) {
 			/* TX and RX share the same clk. So enable the clk
@@ -10573,17 +10539,6 @@
 	int rc = 0;
 
 	if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
-		if (q6core_get_avcs_api_version_per_service(
-		APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V4) {
-			/*
-			 * send island mode config.
-			 * This should be the first configuration
-			 */
-			rc = afe_send_port_island_mode(dai->id);
-			if (rc)
-				pr_err("%s: afe send island mode failed %d\n",
-					__func__, rc);
-		}
 		if ((dai->id == AFE_PORT_ID_WSA_CODEC_DMA_TX_0) &&
 			(dai_data->port_config.cdc_dma.data_format == 1))
 			dai_data->port_config.cdc_dma.data_format =
diff --git a/asoc/msm-pcm-q6-v2.c b/asoc/msm-pcm-q6-v2.c
index b010010..322bf66 100644
--- a/asoc/msm-pcm-q6-v2.c
+++ b/asoc/msm-pcm-q6-v2.c
@@ -1934,20 +1934,24 @@
 	chmixer_pspd->output_channel = ucontrol->value.integer.value[3];
 	chmixer_pspd->port_idx = ucontrol->value.integer.value[4];
 
-	if (chmixer_pspd->enable) {
+	if (chmixer_pspd->input_channel <= 0 ||
+		chmixer_pspd->input_channel > PCM_FORMAT_MAX_NUM_CHANNEL_V8 ||
+		chmixer_pspd->output_channel <= 0 ||
+		chmixer_pspd->output_channel > PCM_FORMAT_MAX_NUM_CHANNEL_V8) {
+		pr_err("%s: Invalid channels, in %d, out %d\n",
+				__func__, chmixer_pspd->input_channel,
+				chmixer_pspd->output_channel);
+		return -EINVAL;
+	}
+
+	prtd = substream->runtime ? substream->runtime->private_data : NULL;
+	if (chmixer_pspd->enable && prtd) {
 		if (session_type == SESSION_TYPE_RX &&
 			!chmixer_pspd->override_in_ch_map) {
-			if (pdata->ch_map[fe_id] &&
-				pdata->ch_map[fe_id]->set_ch_map) {
+			if (prtd->set_channel_map) {
 				for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++)
-					chmixer_pspd->in_ch_map[i] =
-						pdata->ch_map[fe_id]->channel_map[i];
+					chmixer_pspd->in_ch_map[i] = prtd->channel_map[i];
 			} else {
-				if (chmixer_pspd->input_channel > PCM_FORMAT_MAX_NUM_CHANNEL_V8) {
-					pr_err("%s: Invalid channel count %d\n",
-						__func__, chmixer_pspd->input_channel);
-					return -EINVAL;
-				}
 				q6asm_map_channels(asm_ch_map,
 					chmixer_pspd->input_channel, false);
 				for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++)
@@ -1957,22 +1961,14 @@
 			reset_override_in_ch_map = true;
 		} else if (session_type == SESSION_TYPE_TX &&
 				!chmixer_pspd->override_out_ch_map) {
-			if (pdata->ch_map[fe_id] &&
-				pdata->ch_map[fe_id]->set_ch_map) {
-				for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++)
-					chmixer_pspd->out_ch_map[i] =
-						pdata->ch_map[fe_id]->channel_map[i];
-			} else {
-				if (chmixer_pspd->output_channel > PCM_FORMAT_MAX_NUM_CHANNEL_V8) {
-					pr_err("%s: Invalid channel count %d\n",
-						__func__, chmixer_pspd->output_channel);
-					return -EINVAL;
-				}
-				q6asm_map_channels(asm_ch_map,
-					chmixer_pspd->output_channel, false);
-				for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++)
-					chmixer_pspd->out_ch_map[i] = asm_ch_map[i];
-			}
+			/*
+			 * Channel map set in prtd is for plyback only,
+			 * hence always use default for capture path.
+			 */
+			q6asm_map_channels(asm_ch_map,
+				chmixer_pspd->output_channel, false);
+			for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++)
+				chmixer_pspd->out_ch_map[i] = asm_ch_map[i];
 			chmixer_pspd->override_out_ch_map = true;
 			reset_override_out_ch_map = true;
 		}
@@ -1986,22 +1982,13 @@
 			session_type,
 			chmixer_pspd);
 
-	if (chmixer_pspd->enable && substream->runtime) {
-		prtd = substream->runtime->private_data;
-		if (!prtd) {
-			pr_err("%s find invalid prtd fail\n", __func__);
-			ret = -EINVAL;
-			goto done;
-		}
-
-		if (prtd->audio_client) {
-			stream_id = prtd->audio_client->session;
-			be_id = chmixer_pspd->port_idx;
-			msm_pcm_routing_set_channel_mixer_runtime(be_id,
-					stream_id,
-					session_type,
-					chmixer_pspd);
-		}
+	if (chmixer_pspd->enable && prtd && prtd->audio_client) {
+		stream_id = prtd->audio_client->session;
+		be_id = chmixer_pspd->port_idx;
+		msm_pcm_routing_set_channel_mixer_runtime(be_id,
+				stream_id,
+				session_type,
+				chmixer_pspd);
 	}
 
 	if (reset_override_out_ch_map)
@@ -2009,7 +1996,6 @@
 	if (reset_override_in_ch_map)
 		chmixer_pspd->override_in_ch_map = false;
 
-done:
 	return ret;
 }
 
diff --git a/asoc/msm-pcm-voice-v2.c b/asoc/msm-pcm-voice-v2.c
index e4d34d1..ea476c1 100644
--- a/asoc/msm-pcm-voice-v2.c
+++ b/asoc/msm-pcm-voice-v2.c
@@ -1,5 +1,5 @@
 // SPDX-License-Identifier: GPL-2.0-only
-/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
  */
 
 #include <linux/init.h>
@@ -24,6 +24,9 @@
 
 #define DRV_NAME "msm-pcm-voice-v2"
 
+#define NUM_CHANNELS_MONO   1
+#define NUM_CHANNELS_STEREO 2
+
 static struct msm_voice voice_info[VOICE_SESSION_INDEX_MAX];
 
 static struct snd_pcm_hardware msm_pcm_hardware = {
@@ -616,6 +619,38 @@
 	return ret;
 }
 
+static int msm_voice_rec_config_put(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_value *ucontrol)
+{
+	int ret = 0;
+	int voc_rec_config_channels = ucontrol->value.integer.value[0];
+
+	if (voc_rec_config_channels < NUM_CHANNELS_MONO ||
+			voc_rec_config_channels > NUM_CHANNELS_STEREO) {
+		pr_err("%s: Invalid channel config (%d)\n", __func__,
+			voc_rec_config_channels);
+		ret = -EINVAL;
+		goto done;
+	}
+	voc_set_incall_capture_channel_config(voc_rec_config_channels);
+
+done:
+	pr_debug("%s: voc_rec_config_channels = %d, ret = %d\n", __func__,
+		voc_rec_config_channels, ret);
+	return ret;
+}
+
+static int msm_voice_rec_config_get(struct snd_kcontrol *kcontrol,
+				  struct snd_ctl_elem_value *ucontrol)
+{
+
+	ucontrol->value.integer.value[0] =
+		voc_get_incall_capture_channel_config();
+	pr_debug("%s: rec_config_channels = %ld\n", __func__,
+		ucontrol->value.integer.value[0]);
+	return 0;
+}
+
 static int msm_voice_cvd_version_info(struct snd_kcontrol *kcontrol,
 				      struct snd_ctl_elem_info *uinfo)
 {
@@ -678,6 +713,12 @@
 				msm_voice_mbd_put),
 };
 
+static struct snd_kcontrol_new msm_voice_rec_config_controls[] = {
+	SOC_SINGLE_MULTI_EXT("Voc Rec Config", SND_SOC_NOPM, 0,
+			     2, 0, 1, msm_voice_rec_config_get,
+			     msm_voice_rec_config_put),
+};
+
 static const struct snd_pcm_ops msm_pcm_ops = {
 	.open			= msm_pcm_open,
 	.hw_params		= msm_pcm_hw_params,
@@ -703,7 +744,8 @@
 {
 	snd_soc_add_component_controls(component, msm_voice_controls,
 					ARRAY_SIZE(msm_voice_controls));
-
+	snd_soc_add_component_controls(component, msm_voice_rec_config_controls,
+				    ARRAY_SIZE(msm_voice_rec_config_controls));
 	return 0;
 }
 
diff --git a/asoc/msm-transcode-loopback-q6-v2.c b/asoc/msm-transcode-loopback-q6-v2.c
index a311cc1..dc41037 100644
--- a/asoc/msm-transcode-loopback-q6-v2.c
+++ b/asoc/msm-transcode-loopback-q6-v2.c
@@ -901,6 +901,67 @@
 	return ret;
 }
 
+static int msm_transcode_capture_app_type_cfg_put(
+			struct snd_kcontrol *kcontrol,
+			struct snd_ctl_elem_value *ucontrol)
+{
+	u64 fe_id = kcontrol->private_value;
+	int session_type = SESSION_TYPE_TX;
+	int be_id = ucontrol->value.integer.value[APP_TYPE_CONFIG_IDX_BE_ID];
+	struct msm_pcm_stream_app_type_cfg cfg_data = {0, 0, 48000};
+	int ret = 0;
+
+	cfg_data.app_type = ucontrol->value.integer.value[
+			    APP_TYPE_CONFIG_IDX_APP_TYPE];
+	cfg_data.acdb_dev_id = ucontrol->value.integer.value[
+			       APP_TYPE_CONFIG_IDX_ACDB_ID];
+	if (ucontrol->value.integer.value[APP_TYPE_CONFIG_IDX_SAMPLE_RATE] != 0)
+		cfg_data.sample_rate = ucontrol->value.integer.value[
+				       APP_TYPE_CONFIG_IDX_SAMPLE_RATE];
+	pr_debug("%s: fe_id %llu session_type %d be_id %d app_type %d acdb_dev_id %d sample_rate- %d\n",
+		__func__, fe_id, session_type, be_id,
+		cfg_data.app_type, cfg_data.acdb_dev_id, cfg_data.sample_rate);
+	ret = msm_pcm_routing_reg_stream_app_type_cfg(fe_id, session_type,
+						      be_id, &cfg_data);
+	if (ret < 0)
+		pr_err("%s: register stream app type cfg failed, returned %d\n",
+			__func__, ret);
+
+	return ret;
+}
+
+static int msm_transcode_capture_app_type_cfg_get(
+			struct snd_kcontrol *kcontrol,
+			struct snd_ctl_elem_value *ucontrol)
+{
+	u64 fe_id = kcontrol->private_value;
+	int session_type = SESSION_TYPE_TX;
+	int be_id = 0;
+	struct msm_pcm_stream_app_type_cfg cfg_data = {0};
+	int ret = 0;
+
+	ret = msm_pcm_routing_get_stream_app_type_cfg(fe_id, session_type,
+						      &be_id, &cfg_data);
+	if (ret < 0) {
+		pr_err("%s: get stream app type cfg failed, returned %d\n",
+			__func__, ret);
+		goto done;
+	}
+
+	ucontrol->value.integer.value[APP_TYPE_CONFIG_IDX_APP_TYPE] =
+					cfg_data.app_type;
+	ucontrol->value.integer.value[APP_TYPE_CONFIG_IDX_ACDB_ID] =
+					cfg_data.acdb_dev_id;
+	ucontrol->value.integer.value[APP_TYPE_CONFIG_IDX_SAMPLE_RATE] =
+					cfg_data.sample_rate;
+	ucontrol->value.integer.value[APP_TYPE_CONFIG_IDX_BE_ID] = be_id;
+	pr_debug("%s: fedai_id %llu, session_type %d, be_id %d, app_type %d, acdb_dev_id %d, sample_rate %d\n",
+		__func__, fe_id, session_type, be_id,
+		cfg_data.app_type, cfg_data.acdb_dev_id, cfg_data.sample_rate);
+done:
+	return ret;
+}
+
 static int msm_transcode_set_volume(struct snd_compr_stream *cstream,
 				uint32_t master_gain)
 {
@@ -1411,14 +1472,12 @@
 			struct snd_soc_pcm_runtime *rtd)
 {
 	struct snd_soc_component *component = NULL;
-	char mixer_str[32];
+	char mixer_str[128];
 	struct snd_kcontrol_new fe_app_type_cfg_control[1] = {
 		{
 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
 		.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
 		.info = msm_transcode_app_type_cfg_info,
-		.put = msm_transcode_playback_app_type_cfg_put,
-		.get = msm_transcode_playback_app_type_cfg_get,
 		.private_value = 0,
 		}
 	};
@@ -1451,10 +1510,28 @@
 		snd_soc_add_component_controls(component,
 					fe_app_type_cfg_control,
 					ARRAY_SIZE(fe_app_type_cfg_control));
+	} else if (rtd->compr->direction == SND_COMPRESS_CAPTURE) {
+		snprintf(mixer_str, sizeof(mixer_str),
+			"Audio Stream Capture %d App Type Cfg",
+			 rtd->pcm->device);
+
+		fe_app_type_cfg_control[0].name = mixer_str;
+		fe_app_type_cfg_control[0].private_value = rtd->dai_link->id;
+
+		fe_app_type_cfg_control[0].put =
+				msm_transcode_capture_app_type_cfg_put;
+		fe_app_type_cfg_control[0].get =
+				msm_transcode_capture_app_type_cfg_get;
+
+		pr_debug("Registering new mixer ctl %s", mixer_str);
+		snd_soc_add_component_controls(component,
+					fe_app_type_cfg_control,
+					ARRAY_SIZE(fe_app_type_cfg_control));
 	}
 
 	return 0;
 }
+
 static int msm_transcode_volume_info(struct snd_kcontrol *kcontrol,
 				 struct snd_ctl_elem_info *uinfo)
 {
diff --git a/asoc/qcs405.c b/asoc/qcs405.c
index 0bbe37b..0455748 100644
--- a/asoc/qcs405.c
+++ b/asoc/qcs405.c
@@ -678,6 +678,60 @@
 
 static struct mi2s_conf mi2s_intf_conf[MI2S_MAX];
 
+static int msm_island_vad_get_portid_from_beid(int32_t be_id, int *port_id)
+{
+	*port_id = 0xFFFF;
+
+	switch (be_id) {
+	case MSM_BACKEND_DAI_VA_CDC_DMA_TX_0:
+		*port_id = AFE_PORT_ID_VA_CODEC_DMA_TX_0;
+		break;
+	case MSM_BACKEND_DAI_QUINARY_MI2S_TX:
+		*port_id = AFE_PORT_ID_QUINARY_MI2S_TX;
+		break;
+	case MSM_BACKEND_DAI_QUIN_TDM_TX_0:
+		*port_id = AFE_PORT_ID_QUINARY_TDM_TX;
+		break;
+	case MSM_BACKEND_DAI_QUIN_AUXPCM_TX:
+		*port_id = AFE_PORT_ID_QUINARY_PCM_TX;
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int qcs405_send_island_vad_config(int32_t be_id)
+{
+	int rc = 0;
+	int port_id = 0xFFFF;
+
+	rc = msm_island_vad_get_portid_from_beid(be_id, &port_id);
+	if (rc) {
+		pr_debug("%s: Invalid island interface\n", __func__);
+	} else {
+		/*
+		 * send island mode config
+		 * This should be the first configuration
+		 */
+		rc = afe_send_port_island_mode(port_id);
+		if (rc) {
+			pr_err("%s: afe send island mode failed %d\n",
+				__func__, rc);
+			return rc;
+		}
+
+		rc = afe_send_port_vad_cfg_params(port_id);
+		if (rc) {
+			pr_err("%s: afe send vad config failed %d\n",
+				__func__, rc);
+			return rc;
+		}
+	}
+
+	return 0;
+}
+
 static int slim_get_sample_rate_val(int sample_rate)
 {
 	int sample_rate_val = 0;
@@ -4048,29 +4102,6 @@
 	return ch_id;
 }
 
-static int msm_vad_get_portid_from_beid(int32_t be_id, int *port_id)
-{
-	*port_id = 0xFFFF;
-
-	switch (be_id) {
-	case MSM_BACKEND_DAI_VA_CDC_DMA_TX_0:
-		*port_id = AFE_PORT_ID_VA_CODEC_DMA_TX_0;
-		break;
-	case MSM_BACKEND_DAI_QUINARY_MI2S_TX:
-		*port_id = AFE_PORT_ID_QUINARY_MI2S_TX;
-		break;
-	case MSM_BACKEND_DAI_QUIN_TDM_TX_0:
-		*port_id = AFE_PORT_ID_QUINARY_TDM_TX;
-		break;
-	case MSM_BACKEND_DAI_QUIN_AUXPCM_TX:
-		*port_id = AFE_PORT_ID_QUINARY_PCM_TX;
-		break;
-	default:
-		return -EINVAL;
-	}
-	return 0;
-}
-
 static int msm_cdc_dma_get_idx_from_beid(int32_t be_id)
 {
 	int idx = 0;
@@ -5073,6 +5104,34 @@
 	return ret;
 }
 
+static int msm_snd_auxpcm_startup(struct snd_pcm_substream *substream)
+{
+	int ret = 0;
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct snd_soc_dai_link *dai_link = rtd->dai_link;
+
+	ret = qcs405_send_island_vad_config(dai_link->id);
+	if (ret) {
+		pr_err("%s: send island/vad cfg failed, err = %d\n",
+		__func__, ret);
+	}
+	return ret;
+}
+
+static int msm_snd_cdc_dma_startup(struct snd_pcm_substream *substream)
+{
+	int ret = 0;
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
+	struct snd_soc_dai_link *dai_link = rtd->dai_link;
+
+	ret = qcs405_send_island_vad_config(dai_link->id);
+	if (ret) {
+		pr_err("%s: send island/vad cfg failed, err = %d\n",
+		__func__, ret);
+	}
+	return ret;
+}
+
 static int msm_snd_cdc_dma_hw_params(struct snd_pcm_substream *substream,
 			     struct snd_pcm_hw_params *params)
 {
@@ -5499,6 +5558,7 @@
 	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
 	struct snd_soc_card *card = rtd->card;
 	struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
+	struct snd_soc_dai_link *dai_link = rtd->dai_link;
 	u32 tdm_mode = msm_get_tdm_mode(cpu_dai->id);
 
 	if (tdm_mode >= TDM_INTERFACE_MAX) {
@@ -5543,6 +5603,13 @@
 		}
 	}
 
+	ret = qcs405_send_island_vad_config(dai_link->id);
+	if (ret) {
+		pr_err("%s: send island/vad cfg failed, err = %d\n",
+		__func__, ret);
+		return ret;
+	}
+
 	return ret;
 }
 
@@ -5612,7 +5679,7 @@
 	int ret = 0;
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
-
+	struct snd_soc_dai_link *dai_link = rtd->dai_link;
 	int index = cpu_dai->id;
 	unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS;
 	struct snd_soc_card *card = rtd->card;
@@ -5660,6 +5727,14 @@
 			msm_cdc_pinctrl_select_active_state(
 					pdata->mi2s_gpio_p[index]);
 	}
+
+	ret = qcs405_send_island_vad_config(dai_link->id);
+	if (ret) {
+		pr_err("%s: send island/vad cfg failed, err = %d\n",
+		__func__, ret);
+		return ret;
+	}
+
 clk_off:
 	if (ret < 0)
 		msm_mi2s_set_sclk(substream, false);
@@ -5835,7 +5910,11 @@
 	.shutdown = msm_mi2s_snd_shutdown,
 };
 
+static struct snd_soc_ops msm_auxpcm_be_ops = {
+	.startup = msm_snd_auxpcm_startup,
+};
 static struct snd_soc_ops msm_cdc_dma_be_ops = {
+	.startup = msm_snd_cdc_dma_startup,
 	.hw_params = msm_snd_cdc_dma_hw_params,
 };
 
@@ -7259,6 +7338,7 @@
 		.dpcm_playback = 1,
 		.id = MSM_BACKEND_DAI_AUXPCM_RX,
 		.be_hw_params_fixup = msm_be_hw_params_fixup,
+		.ops = &msm_auxpcm_be_ops,
 		.ignore_pmdown_time = 1,
 		.ignore_suspend = 1,
 	},
@@ -7273,6 +7353,7 @@
 		.dpcm_capture = 1,
 		.id = MSM_BACKEND_DAI_AUXPCM_TX,
 		.be_hw_params_fixup = msm_be_hw_params_fixup,
+		.ops = &msm_auxpcm_be_ops,
 		.ignore_suspend = 1,
 	},
 	/* Secondary AUX PCM Backend DAI Links */
@@ -7287,6 +7368,7 @@
 		.dpcm_playback = 1,
 		.id = MSM_BACKEND_DAI_SEC_AUXPCM_RX,
 		.be_hw_params_fixup = msm_be_hw_params_fixup,
+		.ops = &msm_auxpcm_be_ops,
 		.ignore_pmdown_time = 1,
 		.ignore_suspend = 1,
 	},
@@ -7301,6 +7383,7 @@
 		.dpcm_capture = 1,
 		.id = MSM_BACKEND_DAI_SEC_AUXPCM_TX,
 		.be_hw_params_fixup = msm_be_hw_params_fixup,
+		.ops = &msm_auxpcm_be_ops,
 		.ignore_suspend = 1,
 	},
 	/* Tertiary AUX PCM Backend DAI Links */
@@ -7315,6 +7398,7 @@
 		.dpcm_playback = 1,
 		.id = MSM_BACKEND_DAI_TERT_AUXPCM_RX,
 		.be_hw_params_fixup = msm_be_hw_params_fixup,
+		.ops = &msm_auxpcm_be_ops,
 		.ignore_suspend = 1,
 	},
 	{
@@ -7328,6 +7412,7 @@
 		.dpcm_capture = 1,
 		.id = MSM_BACKEND_DAI_TERT_AUXPCM_TX,
 		.be_hw_params_fixup = msm_be_hw_params_fixup,
+		.ops = &msm_auxpcm_be_ops,
 		.ignore_suspend = 1,
 	},
 	/* Quaternary AUX PCM Backend DAI Links */
@@ -7342,6 +7427,7 @@
 		.dpcm_playback = 1,
 		.id = MSM_BACKEND_DAI_QUAT_AUXPCM_RX,
 		.be_hw_params_fixup = msm_be_hw_params_fixup,
+		.ops = &msm_auxpcm_be_ops,
 		.ignore_pmdown_time = 1,
 		.ignore_suspend = 1,
 	},
@@ -7356,6 +7442,7 @@
 		.dpcm_capture = 1,
 		.id = MSM_BACKEND_DAI_QUAT_AUXPCM_TX,
 		.be_hw_params_fixup = msm_be_hw_params_fixup,
+		.ops = &msm_auxpcm_be_ops,
 		.ignore_suspend = 1,
 	},
 	/* Quinary AUX PCM Backend DAI Links */
@@ -7370,6 +7457,7 @@
 		.dpcm_playback = 1,
 		.id = MSM_BACKEND_DAI_QUIN_AUXPCM_RX,
 		.be_hw_params_fixup = msm_be_hw_params_fixup,
+		.ops = &msm_auxpcm_be_ops,
 		.ignore_pmdown_time = 1,
 		.ignore_suspend = 1,
 	},
@@ -7384,6 +7472,7 @@
 		.dpcm_capture = 1,
 		.id = MSM_BACKEND_DAI_QUIN_AUXPCM_TX,
 		.be_hw_params_fixup = msm_be_hw_params_fixup,
+		.ops = &msm_auxpcm_be_ops,
 		.ignore_suspend = 1,
 	},
 };
@@ -7594,7 +7683,7 @@
 	pr_debug("%s: vad_enable=%d preroll_config=%d vad_intf=%d\n", __func__,
 		 vad_enable, preroll_config, vad_intf);
 
-	ret = msm_vad_get_portid_from_beid(vad_intf, &port_id);
+	ret = msm_island_vad_get_portid_from_beid(vad_intf, &port_id);
 	if (ret) {
 		pr_err("%s: Invalid vad interface\n", __func__);
 		goto done;
diff --git a/asoc/sa8155.c b/asoc/sa8155.c
index aef8a26..6dba206 100644
--- a/asoc/sa8155.c
+++ b/asoc/sa8155.c
@@ -691,6 +691,7 @@
 static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_tx_format, bit_format_text);
 
 static bool is_initial_boot = true;
+static struct platform_device *spdev;
 
 static struct afe_clk_set mi2s_clk[MI2S_MAX] = {
 	{
@@ -7183,6 +7184,7 @@
 		goto err;
 	}
 	dev_info(&pdev->dev, "Sound card %s registered\n", card->name);
+	spdev = pdev;
 
 	/* Parse pinctrl info from devicetree */
 	ret = msm_get_pinctrl(pdev);
@@ -7223,48 +7225,45 @@
 	.remove = msm_asoc_machine_remove,
 };
 
-static int dummy_asoc_machine_probe(struct platform_device *pdev)
-{
-	return 0;
-}
-
-static int dummy_asoc_machine_remove(struct platform_device *pdev)
-{
-	return 0;
-}
-
-static struct platform_device sa8155_dummy_asoc_machine_device = {
-	.name = "sa8155-asoc-snd-dummy",
-};
-
-static struct platform_driver sa8155_dummy_asoc_machine_driver = {
-	.driver = {
-		.name = "sa8155-asoc-snd-dummy",
-		.owner = THIS_MODULE,
-	},
-	.probe = dummy_asoc_machine_probe,
-	.remove = dummy_asoc_machine_remove,
-};
-
 static int sa8155_notifier_service_cb(struct notifier_block *this,
 					 unsigned long opcode, void *ptr)
 {
+	struct snd_soc_card *card = NULL;
+
 	pr_debug("%s: Service opcode 0x%lx\n", __func__, opcode);
 
 	switch (opcode) {
 	case AUDIO_NOTIFIER_SERVICE_DOWN:
+		if (!spdev)
+			return -EINVAL;
+		card = platform_get_drvdata(spdev);
+		if (card == NULL){
+			pr_err("%s: card is NULL\n",__func__);
+			return -EINVAL;
+		} else {
+			pr_debug("%s: setting snd_card to OFFLINE\n", __func__);
+			snd_soc_card_change_online_state(card, 0);
+		}
 		break;
 	case AUDIO_NOTIFIER_SERVICE_UP:
 		if (is_initial_boot) {
-			platform_driver_register(&sa8155_dummy_asoc_machine_driver);
-			platform_device_register(&sa8155_dummy_asoc_machine_device);
 			is_initial_boot = false;
+			break;
+		}
+		if (!spdev)
+			return -EINVAL;
+		card = platform_get_drvdata(spdev);
+		if (card == NULL){
+			pr_err("%s: card is NULL\n",__func__);
+			return -EINVAL;
+		} else {
+			pr_debug("%s: setting snd_card to ONLINE\n", __func__);
+			snd_soc_card_change_online_state(card, 1);
 		}
 		break;
 	default:
 		break;
 	}
-
 	return NOTIFY_OK;
 }
 
diff --git a/config/konaauto.conf b/config/konaauto.conf
index 7b03dea..03e0541 100644
--- a/config/konaauto.conf
+++ b/config/konaauto.conf
@@ -1,38 +1,38 @@
-CONFIG_PINCTRL_LPI=m
-CONFIG_PINCTRL_WCD=m
-CONFIG_AUDIO_EXT_CLK=m
-CONFIG_SND_SOC_WCD9XXX_V2=m
-CONFIG_SND_SOC_WCD_MBHC=m
-CONFIG_SND_SOC_WSA881X=m
-CONFIG_WCD9XXX_CODEC_CORE_V2=m
-CONFIG_MSM_CDC_PINCTRL=m
-CONFIG_MSM_QDSP6V2_CODECS=m
-CONFIG_MSM_ULTRASOUND=m
-CONFIG_MSM_QDSP6_APRV2_RPMSG=m
-CONFIG_MSM_ADSP_LOADER=m
-CONFIG_REGMAP_SWR=m
-CONFIG_MSM_QDSP6_SSR=m
-CONFIG_MSM_QDSP6_PDR=m
-CONFIG_MSM_QDSP6_NOTIFIER=m
-CONFIG_SND_SOC_MSM_HOSTLESS_PCM=m
-CONFIG_SND_SOC_MSM_QDSP6V2_INTF=m
-CONFIG_SOUNDWIRE=m
-CONFIG_SOUNDWIRE_MSTR_CTRL=m
-CONFIG_SND_SOC_QDSP6V2=m
-CONFIG_SND_SOC_WCD_MBHC_ADC=m
-CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=m
-CONFIG_QTI_PP=m
-CONFIG_SND_HWDEP_ROUTING=m
-CONFIG_SND_SOC_MSM_STUB=m
-CONFIG_MSM_AVTIMER=m
-CONFIG_SND_SOC_BOLERO=m
-CONFIG_WSA_MACRO=m
-CONFIG_VA_MACRO=m
-CONFIG_RX_MACRO=m
-CONFIG_TX_MACRO=m
-CONFIG_SND_SOC_WCD_IRQ=m
-CONFIG_SND_SOC_WCD938X=m
-CONFIG_SND_SOC_WCD938X_SLAVE=m
-CONFIG_SND_SOC_KONA=m
-CONFIG_SND_EVENT=m
-CONFIG_VOICE_MHI=m
+export CONFIG_PINCTRL_LPI=m
+export CONFIG_PINCTRL_WCD=m
+export CONFIG_AUDIO_EXT_CLK=m
+export CONFIG_SND_SOC_WCD9XXX_V2=m
+export CONFIG_SND_SOC_WCD_MBHC=m
+export CONFIG_SND_SOC_WSA881X=m
+export CONFIG_WCD9XXX_CODEC_CORE_V2=m
+export CONFIG_MSM_CDC_PINCTRL=m
+export CONFIG_MSM_QDSP6V2_CODECS=m
+export CONFIG_MSM_ULTRASOUND=m
+export CONFIG_MSM_QDSP6_APRV2_RPMSG=m
+export CONFIG_MSM_ADSP_LOADER=m
+export CONFIG_REGMAP_SWR=m
+export CONFIG_MSM_QDSP6_SSR=m
+export CONFIG_MSM_QDSP6_PDR=m
+export CONFIG_MSM_QDSP6_NOTIFIER=m
+export CONFIG_SND_SOC_MSM_HOSTLESS_PCM=m
+export CONFIG_SND_SOC_MSM_QDSP6V2_INTF=m
+export CONFIG_SOUNDWIRE=m
+export CONFIG_SOUNDWIRE_MSTR_CTRL=m
+export CONFIG_SND_SOC_QDSP6V2=m
+export CONFIG_SND_SOC_WCD_MBHC_ADC=m
+export CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=m
+export CONFIG_QTI_PP=m
+export CONFIG_SND_HWDEP_ROUTING=m
+export CONFIG_SND_SOC_MSM_STUB=m
+export CONFIG_MSM_AVTIMER=m
+export CONFIG_SND_SOC_BOLERO=m
+export CONFIG_WSA_MACRO=m
+export CONFIG_VA_MACRO=m
+export CONFIG_RX_MACRO=m
+export CONFIG_TX_MACRO=m
+export CONFIG_SND_SOC_WCD_IRQ=m
+export CONFIG_SND_SOC_WCD938X=m
+export CONFIG_SND_SOC_WCD938X_SLAVE=m
+export CONFIG_SND_SOC_KONA=m
+export CONFIG_SND_EVENT=m
+export CONFIG_VOICE_MHI=m
diff --git a/dsp/Kbuild b/dsp/Kbuild
index cf9de15..086924f 100644
--- a/dsp/Kbuild
+++ b/dsp/Kbuild
@@ -26,7 +26,6 @@
 	endif
 	ifeq ($(CONFIG_ARCH_KONA), y)
 		include $(AUDIO_ROOT)/config/konaauto.conf
-		export
 		INCS    +=  -include $(AUDIO_ROOT)/config/konaautoconf.h
 	endif
 	ifeq ($(CONFIG_ARCH_LITO), y)
diff --git a/dsp/codecs/Kbuild b/dsp/codecs/Kbuild
index b4be485..d78675f 100644
--- a/dsp/codecs/Kbuild
+++ b/dsp/codecs/Kbuild
@@ -26,7 +26,6 @@
 	endif
 	ifeq ($(CONFIG_ARCH_KONA), y)
 		include $(AUDIO_ROOT)/config/konaauto.conf
-		export
 		INCS    +=  -include $(AUDIO_ROOT)/config/konaautoconf.h
 	endif
 	ifeq ($(CONFIG_ARCH_LITO), y)
diff --git a/dsp/q6adm.c b/dsp/q6adm.c
index 8848b22..345123f 100644
--- a/dsp/q6adm.c
+++ b/dsp/q6adm.c
@@ -128,6 +128,8 @@
 			}
 };
 
+static struct adm_multi_ch_map port_channel_map[AFE_MAX_PORTS];
+
 static int adm_get_parameters[MAX_COPPS_PER_PORT * ADM_GET_PARAMETER_LENGTH];
 static int adm_module_topo_list[MAX_COPPS_PER_PORT *
 				ADM_GET_TOPO_MODULE_INSTANCE_LIST_LENGTH];
@@ -146,7 +148,8 @@
 static int adm_arrange_mch_map_v8(
 		struct adm_device_endpoint_payload *ep_payload,
 		int path,
-		int channel_mode);
+		int channel_mode,
+		int port_idx);
 
 /**
  * adm_validate_and_get_port_index -
@@ -578,7 +581,8 @@
 		index += ch_mixer->output_channel;
 	} else {
 		ep_params.dev_num_channel = ch_mixer->output_channel;
-		adm_arrange_mch_map_v8(&ep_params, path_type, ep_params.dev_num_channel);
+		adm_arrange_mch_map_v8(&ep_params, path_type,
+				       ep_params.dev_num_channel, port_idx);
 		for (i = 0; i < ch_mixer->output_channel; i++)
 			adm_pspd_params[index++] = ep_params.dev_channel_mapping[i];
 	}
@@ -589,7 +593,8 @@
 		index += ch_mixer->input_channel;
 	} else {
 		ep_params.dev_num_channel = ch_mixer->input_channels[channel_index];
-		adm_arrange_mch_map_v8(&ep_params, path_type, ep_params.dev_num_channel);
+		adm_arrange_mch_map_v8(&ep_params, path_type,
+				       ep_params.dev_num_channel, port_idx);
 		for (i = 0; i < ch_mixer->input_channels[channel_index]; i++)
 			adm_pspd_params[index++] = ep_params.dev_channel_mapping[i];
 	}
@@ -1302,6 +1307,31 @@
 }
 EXPORT_SYMBOL(adm_get_multi_ch_map);
 
+/**
+ * adm_set_port_multi_ch_map -
+ *        Update port specific channel map info
+ *
+ * @channel_map: pointer with channel map info
+ * @port_id: port for which chmap is set
+ */
+void adm_set_port_multi_ch_map(char *channel_map, int port_id)
+{
+	int port_idx;
+
+	port_id = q6audio_convert_virtual_to_portid(port_id);
+	port_idx = adm_validate_and_get_port_index(port_id);
+
+	if (port_idx < 0) {
+		pr_err("%s: Invalid port_id 0x%x\n", __func__, port_id);
+		return;
+	}
+
+	memcpy(port_channel_map[port_idx].channel_mapping, channel_map,
+			PCM_FORMAT_MAX_NUM_CHANNEL_V8);
+	port_channel_map[port_idx].set_channel_map = true;
+}
+EXPORT_SYMBOL(adm_set_port_multi_ch_map);
+
 static int adm_process_get_param_response(u32 opcode, u32 idx, u32 *payload,
 					  u32 payload_size)
 {
@@ -2380,7 +2410,7 @@
 EXPORT_SYMBOL(adm_connect_afe_port);
 
 int adm_arrange_mch_map(struct adm_cmd_device_open_v5 *open, int path,
-			 int channel_mode)
+			 int channel_mode, int port_idx)
 {
 	int rc = 0, idx;
 
@@ -2398,10 +2428,18 @@
 	default:
 		goto non_mch_path;
 	};
-	if ((open->dev_num_channel > 2) && multi_ch_maps[idx].set_channel_map) {
-		memcpy(open->dev_channel_mapping,
-			multi_ch_maps[idx].channel_mapping,
-			PCM_FORMAT_MAX_NUM_CHANNEL);
+
+	if ((open->dev_num_channel > 2) &&
+		(port_channel_map[port_idx].set_channel_map ||
+		 multi_ch_maps[idx].set_channel_map)) {
+		if (port_channel_map[port_idx].set_channel_map)
+			memcpy(open->dev_channel_mapping,
+				port_channel_map[port_idx].channel_mapping,
+				PCM_FORMAT_MAX_NUM_CHANNEL);
+		else
+			memcpy(open->dev_channel_mapping,
+				multi_ch_maps[idx].channel_mapping,
+				PCM_FORMAT_MAX_NUM_CHANNEL);
 	} else {
 		if (channel_mode == 1) {
 			open->dev_channel_mapping[0] = PCM_CHANNEL_FC;
@@ -2515,8 +2553,7 @@
 
 static int adm_arrange_mch_map_v8(
 		struct adm_device_endpoint_payload *ep_payload,
-		int path,
-		int channel_mode)
+		int path, int channel_mode, int port_idx)
 {
 	int rc = 0, idx;
 
@@ -2535,10 +2572,16 @@
 	};
 
 	if ((ep_payload->dev_num_channel > 2) &&
-			multi_ch_maps[idx].set_channel_map) {
-		memcpy(ep_payload->dev_channel_mapping,
-			multi_ch_maps[idx].channel_mapping,
-			PCM_FORMAT_MAX_NUM_CHANNEL_V8);
+		(port_channel_map[port_idx].set_channel_map ||
+		 multi_ch_maps[idx].set_channel_map)) {
+		if (port_channel_map[port_idx].set_channel_map)
+			memcpy(ep_payload->dev_channel_mapping,
+				port_channel_map[port_idx].channel_mapping,
+				PCM_FORMAT_MAX_NUM_CHANNEL_V8);
+		else
+			memcpy(ep_payload->dev_channel_mapping,
+				multi_ch_maps[idx].channel_mapping,
+				PCM_FORMAT_MAX_NUM_CHANNEL_V8);
 	} else {
 		if (channel_mode == 1) {
 			ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FC;
@@ -2754,6 +2797,11 @@
 			__func__, port_id, copp_idx, sample_rate,
 			bps, in_channels, out_channels);
 
+	if (out_channels <= 0 || out_channels > AUDPROC_MFC_OUT_CHANNELS_MAX) {
+		pr_err("%s: unsupported out channels=%d\n", __func__, out_channels);
+		return -EINVAL;
+	}
+
 	/* 1. Update Media Format */
 	param_hdr.param_id = AUDPROC_PARAM_ID_MFC_OUTPUT_MEDIA_FORMAT;
 	param_hdr.param_size = sizeof(mfc_cfg);
@@ -3052,7 +3100,7 @@
 			ep1_payload.bit_width = bit_width;
 			ep1_payload.sample_rate  = rate;
 			ret = adm_arrange_mch_map_v8(&ep1_payload, path,
-					channel_mode);
+					channel_mode, port_idx);
 			if (ret)
 				return ret;
 
@@ -3165,8 +3213,8 @@
 				(rate != ULL_SUPPORTED_SAMPLE_RATE));
 			open.sample_rate  = rate;
 
-			ret = adm_arrange_mch_map(&open, path, channel_mode);
-
+			ret = adm_arrange_mch_map(&open, path, channel_mode,
+						  port_idx);
 			if (ret)
 				return ret;
 
@@ -3314,7 +3362,7 @@
 		atomic_read(&this_adm.copp.channels[port_idx][copp_idx]);
 
 	rc = adm_arrange_mch_map(&open, ADM_PATH_PLAYBACK,
-		mfc_cfg.num_channels);
+		mfc_cfg.num_channels, port_idx);
 	if (rc < 0) {
 		pr_err("%s: unable to get channal map\n", __func__);
 		goto fail_cmd;
@@ -3671,6 +3719,7 @@
 		return -EINVAL;
 	}
 
+	port_channel_map[port_idx].set_channel_map = false;
 	if (this_adm.copp.adm_delay[port_idx][copp_idx] && perf_mode
 		== LEGACY_PCM_MODE) {
 		atomic_set(&this_adm.copp.adm_delay_stat[port_idx][copp_idx],
diff --git a/dsp/q6afe.c b/dsp/q6afe.c
index 6c188d7..7a510be 100644
--- a/dsp/q6afe.c
+++ b/dsp/q6afe.c
@@ -1466,7 +1466,8 @@
 }
 
 static int q6afe_svc_set_params(int index, struct mem_mapping_hdr *mem_hdr,
-				u8 *packed_param_data, u32 packed_data_size)
+				u8 *packed_param_data, u32 packed_data_size,
+				bool is_iid_supported)
 {
 	int ret;
 
@@ -1476,7 +1477,7 @@
 		return ret;
 	}
 
-	if (q6common_is_instance_id_supported())
+	if (is_iid_supported)
 		return q6afe_svc_set_params_v2(index, mem_hdr,
 					       packed_param_data,
 					       packed_data_size);
@@ -1494,13 +1495,15 @@
 	u32 packed_data_size =
 		sizeof(struct param_hdr_v3) + param_hdr.param_size;
 	int ret = 0;
+	bool is_iid_supported = q6common_is_instance_id_supported();
 
 	packed_param_data = kzalloc(packed_data_size, GFP_KERNEL);
 	if (!packed_param_data)
 		return -ENOMEM;
 
-	ret = q6common_pack_pp_params(packed_param_data, &param_hdr, param_data,
-				      &packed_data_size);
+	ret = q6common_pack_pp_params_v2(packed_param_data, &param_hdr,
+					param_data, &packed_data_size,
+					is_iid_supported);
 	if (ret) {
 		pr_err("%s: Failed to pack parameter header and data, error %d\n",
 		       __func__, ret);
@@ -1508,7 +1511,7 @@
 	}
 
 	ret = q6afe_svc_set_params(index, NULL, packed_param_data,
-				   packed_data_size);
+				   packed_data_size, is_iid_supported);
 
 done:
 	kfree(packed_param_data);
@@ -2255,6 +2258,13 @@
 	u32 island_mode = 0;
 	int ret = 0;
 
+	if (!(q6core_get_avcs_api_version_per_service(
+		APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V4)) {
+		pr_debug("%s: AFE port[%d] API version is invalid!\n",
+				__func__, port_id);
+		return 0;
+	}
+
 	memset(&island_cfg, 0, sizeof(island_cfg));
 	memset(&param_info, 0, sizeof(param_info));
 
@@ -2303,66 +2313,105 @@
 	return ret;
 }
 
-static int afe_send_port_vad_cfg_params(u16 port_id)
+int afe_send_port_vad_cfg_params(u16 port_id)
 {
 	struct afe_param_id_vad_cfg_t vad_cfg;
+	struct afe_mod_enable_param vad_enable;
 	struct param_hdr_v3 param_info;
 	u32 pre_roll_cfg = 0;
 	struct firmware_cal *hwdep_cal = NULL;
 	int ret = 0;
+	uint16_t port_index = 0;
 
-	memset(&vad_cfg, 0, sizeof(vad_cfg));
-	memset(&param_info, 0, sizeof(param_info));
-
-	ret = afe_get_vad_preroll_cfg(port_id, &pre_roll_cfg);
-	if (ret) {
-		pr_err("%s: AFE port[%d] get preroll cfg is invalid!\n",
-				__func__, port_id);
-		return ret;
-	}
-	param_info.module_id = AFE_MODULE_VAD;
-	param_info.instance_id = INSTANCE_ID_0;
-	param_info.param_id = AFE_PARAM_ID_VAD_CFG;
-	param_info.param_size = sizeof(vad_cfg);
-
-	vad_cfg.vad_cfg_minor_version = AFE_API_VERSION_VAD_CFG;
-	vad_cfg.pre_roll_in_ms = pre_roll_cfg;
-
-	ret = q6afe_pack_and_set_param_in_band(port_id,
-					       q6audio_get_port_index(port_id),
-					       param_info, (u8 *) &vad_cfg);
-	if (ret) {
-		pr_err("%s: AFE set vad cfg for port 0x%x failed %d\n",
-			__func__, port_id, ret);
-		return ret;
+	if (!(q6core_get_avcs_api_version_per_service(
+	APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V4)) {
+		pr_err("%s: AFE port[%d]: AFE API version doesn't support VAD config\n",
+		__func__, port_id);
+		return 0;
 	}
 
-	memset(&param_info, 0, sizeof(param_info));
+	port_index = afe_get_port_index(port_id);
 
-	hwdep_cal = q6afecal_get_fw_cal(this_afe.fw_data, Q6AFE_VAD_CORE_CAL);
-	if (!hwdep_cal) {
-		pr_err("%s: error in retrieving vad core calibration",
-			__func__);
-		return -EINVAL;
+	if (this_afe.vad_cfg[port_index].is_enable) {
+		memset(&vad_cfg, 0, sizeof(vad_cfg));
+		memset(&param_info, 0, sizeof(param_info));
+
+		ret = afe_get_vad_preroll_cfg(port_id, &pre_roll_cfg);
+		if (ret) {
+			pr_err("%s: AFE port[%d] get preroll cfg is invalid!\n",
+					__func__, port_id);
+			return ret;
+		}
+		param_info.module_id = AFE_MODULE_VAD;
+		param_info.instance_id = INSTANCE_ID_0;
+		param_info.param_id = AFE_PARAM_ID_VAD_CFG;
+		param_info.param_size = sizeof(vad_cfg);
+
+		vad_cfg.vad_cfg_minor_version = AFE_API_VERSION_VAD_CFG;
+		vad_cfg.pre_roll_in_ms = pre_roll_cfg;
+
+		ret = q6afe_pack_and_set_param_in_band(port_id,
+						q6audio_get_port_index(port_id),
+						param_info, (u8 *) &vad_cfg);
+		if (ret) {
+			pr_err("%s: AFE set vad cfg for port 0x%x failed %d\n",
+				__func__, port_id, ret);
+			return ret;
+		}
+
+		memset(&param_info, 0, sizeof(param_info));
+
+		hwdep_cal = q6afecal_get_fw_cal(this_afe.fw_data,
+						Q6AFE_VAD_CORE_CAL);
+		if (!hwdep_cal) {
+			pr_err("%s: error in retrieving vad core calibration",
+				__func__);
+			return -EINVAL;
+		}
+
+		param_info.module_id = AFE_MODULE_VAD;
+		param_info.instance_id = INSTANCE_ID_0;
+		param_info.param_id = AFE_PARAM_ID_VAD_CORE_CFG;
+		param_info.param_size = hwdep_cal->size;
+
+		ret = q6afe_pack_and_set_param_in_band(port_id,
+						q6audio_get_port_index(port_id),
+						param_info,
+						(u8 *) hwdep_cal->data);
+		if (ret) {
+			pr_err("%s: AFE set vad cfg for port 0x%x failed %d\n",
+				__func__, port_id, ret);
+			return ret;
+		}
 	}
 
-	param_info.module_id = AFE_MODULE_VAD;
-	param_info.instance_id = INSTANCE_ID_0;
-	param_info.param_id = AFE_PARAM_ID_VAD_CORE_CFG;
-	param_info.param_size = hwdep_cal->size;
+	if (q6core_get_avcs_api_version_per_service(
+		APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V6) {
+		memset(&vad_enable, 0, sizeof(vad_enable));
+		memset(&param_info, 0, sizeof(param_info));
+		param_info.module_id = AFE_MODULE_VAD;
+		param_info.instance_id = INSTANCE_ID_0;
+		param_info.param_id = AFE_PARAM_ID_ENABLE;
+		param_info.param_size = sizeof(vad_enable);
 
-	ret = q6afe_pack_and_set_param_in_band(port_id,
-					q6audio_get_port_index(port_id),
-					param_info, (u8 *) hwdep_cal->data);
-	if (ret) {
-		pr_err("%s: AFE set vad cfg for port 0x%x failed %d\n",
-			__func__, port_id, ret);
-		return ret;
+		port_index = afe_get_port_index(port_id);
+		vad_enable.enable = this_afe.vad_cfg[port_index].is_enable;
+
+		ret = q6afe_pack_and_set_param_in_band(port_id,
+						q6audio_get_port_index(port_id),
+						param_info, (u8 *) &vad_enable);
+		if (ret) {
+			pr_err("%s: AFE set vad enable for port 0x%x failed %d\n",
+				__func__, port_id, ret);
+			return ret;
+		}
 	}
+
 	pr_debug("%s: AFE set preroll cfg %d vad core cfg  port 0x%x ret %d\n",
 			__func__, pre_roll_cfg, port_id, ret);
 	return ret;
 }
+EXPORT_SYMBOL(afe_send_port_vad_cfg_params);
 
 static int remap_cal_data(struct cal_block_data *cal_block, int cal_index)
 {
@@ -2595,6 +2644,7 @@
 	struct param_hdr_v3 param_hdr;
 	int idx = 0;
 	int ret = -EINVAL;
+	bool is_iid_supported = q6common_is_instance_id_supported();
 
 	memset(&param_hdr, 0, sizeof(param_hdr));
 	max_single_param = sizeof(struct param_hdr_v3) +
@@ -2617,10 +2667,10 @@
 
 		while (packed_data_size + max_single_param < max_data_size &&
 		       idx < cdc_reg_cfg->num_registers) {
-			ret = q6common_pack_pp_params(
+			ret = q6common_pack_pp_params_v2(
 				packed_param_data + packed_data_size,
 				&param_hdr, (u8 *) &cdc_reg_cfg->reg_data[idx],
-				&single_param_size);
+				&single_param_size, is_iid_supported);
 			if (ret) {
 				pr_err("%s: Failed to pack parameters with error %d\n",
 				       __func__, ret);
@@ -2631,7 +2681,8 @@
 		}
 
 		ret = q6afe_svc_set_params(IDX_GLOBAL_CFG, NULL,
-					   packed_param_data, packed_data_size);
+					   packed_param_data, packed_data_size,
+					   is_iid_supported);
 		if (ret) {
 			pr_err("%s: AFE_PARAM_ID_CDC_REG_CFG failed %d\n",
 				__func__, ret);
@@ -3397,19 +3448,6 @@
 
 	port_index = afe_get_port_index(port_id);
 
-	if (q6core_get_avcs_api_version_per_service(
-		APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V4) {
-		/* send VAD configuration if enabled */
-		if (this_afe.vad_cfg[port_index].is_enable) {
-			ret = afe_send_port_vad_cfg_params(port_id);
-			if (ret) {
-				pr_err("%s: afe send VAD config failed %d\n",
-					__func__, ret);
-				goto fail_cmd;
-			}
-		}
-	}
-
 	/* Also send the topology id here: */
 	if (!(this_afe.afe_cal_mode[port_index] == AFE_CAL_MODE_NONE)) {
 		/* One time call: only for first time */
@@ -4360,19 +4398,6 @@
 	mutex_lock(&this_afe.afe_cmd_lock);
 	port_index = afe_get_port_index(port_id);
 
-	if (q6core_get_avcs_api_version_per_service(
-		APRV2_IDS_SERVICE_ID_ADSP_AFE_V) >= AFE_API_VERSION_V4) {
-		/* send VAD configuration if is enabled */
-		if (this_afe.vad_cfg[port_index].is_enable) {
-			ret = afe_send_port_vad_cfg_params(port_id);
-			if (ret) {
-				pr_err("%s: afe send VAD config failed %d\n",
-					__func__, ret);
-				goto fail_cmd;
-			}
-		}
-	}
-
 	/* Also send the topology id here: */
 	if (!(this_afe.afe_cal_mode[port_index] == AFE_CAL_MODE_NONE)) {
 		/* One time call: only for first time */
diff --git a/dsp/q6common.c b/dsp/q6common.c
index 8270054..b5444b1 100644
--- a/dsp/q6common.c
+++ b/dsp/q6common.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
  */
 
 #include <dsp/q6common.h>
@@ -104,3 +104,74 @@
 	return 0;
 }
 EXPORT_SYMBOL(q6common_pack_pp_params);
+
+/**
+ * q6common_pack_pp_params_v2
+ *
+ * Populate params header based on instance ID support and pack
+ * it with payload.
+ * Instance ID support -
+ *     yes - param_hdr_v3 + payload
+ *     no  - param_hdr_v1 + payload
+ *
+ * @dest: destination data pointer to be packed into
+ * @v3_hdr: param header v3
+ * @param_data: param payload
+ * @total_size: total size of packed data (hdr + payload)
+ * @iid_supported: Instance ID supported or not
+ *
+ * Returns 0 on success or error on failure
+ */
+int q6common_pack_pp_params_v2(u8 *dest, struct param_hdr_v3 *v3_hdr,
+			    u8 *param_data, u32 *total_size,
+			    bool iid_supported)
+{
+	struct param_hdr_v1 *v1_hdr = NULL;
+	u32 packed_size = 0;
+	u32 param_size = 0;
+
+	if (dest == NULL) {
+		pr_err("%s: Received NULL pointer for destination\n", __func__);
+		return -EINVAL;
+	} else if (v3_hdr == NULL) {
+		pr_err("%s: Received NULL pointer for header\n", __func__);
+		return -EINVAL;
+	} else if (total_size == NULL) {
+		pr_err("%s: Received NULL pointer for total size\n", __func__);
+		return -EINVAL;
+	}
+
+	param_size = v3_hdr->param_size;
+	packed_size = iid_supported ? sizeof(struct param_hdr_v3) :
+				      sizeof(struct param_hdr_v1);
+
+	if (iid_supported) {
+		memcpy(dest, v3_hdr, packed_size);
+	} else {
+		v1_hdr = (struct param_hdr_v1 *) dest;
+		v1_hdr->module_id = v3_hdr->module_id;
+		v1_hdr->param_id = v3_hdr->param_id;
+
+		if (param_size > U16_MAX) {
+			pr_err("%s: Invalid param size for V1 %d\n", __func__,
+			       param_size);
+			return -EINVAL;
+		}
+		v1_hdr->param_size = param_size;
+		v1_hdr->reserved = 0;
+	}
+
+	/*
+	 * Make param_data optional for cases when there is no data
+	 * present as in some set cases and all get cases.
+	 */
+	if (param_data != NULL) {
+		memcpy(dest + packed_size, param_data, param_size);
+		packed_size += param_size;
+	}
+
+	*total_size = packed_size;
+
+	return 0;
+}
+EXPORT_SYMBOL(q6common_pack_pp_params_v2);
diff --git a/dsp/q6voice.c b/dsp/q6voice.c
index e36e18b..131da55 100644
--- a/dsp/q6voice.c
+++ b/dsp/q6voice.c
@@ -98,7 +98,8 @@
 
 static int voice_cvs_stop_playback(struct voice_data *v);
 static int voice_cvs_start_playback(struct voice_data *v);
-static int voice_cvs_start_record(struct voice_data *v, uint32_t rec_mode);
+static int voice_cvs_start_record(struct voice_data *v, uint32_t rec_mode,
+					uint32_t port_id);
 static int voice_cvs_stop_record(struct voice_data *v);
 
 static int32_t qdsp_mvm_callback(struct apr_client_data *data, void *priv);
@@ -4411,7 +4412,8 @@
 
 	/* Start in-call recording if this feature is enabled */
 	if (v->rec_info.rec_enable)
-		voice_cvs_start_record(v, v->rec_info.rec_mode);
+		voice_cvs_start_record(v, v->rec_info.rec_mode,
+					v->rec_info.port_id);
 
 	if (v->dtmf_rx_detect_en)
 		voice_send_dtmf_rx_detection_cmd(v, v->dtmf_rx_detect_en);
@@ -5056,7 +5058,8 @@
 		if (v->rec_info.rec_enable) {
 			voice_cvs_start_record(
 				&common.voice[VOC_PATH_PASSIVE],
-				v->rec_info.rec_mode);
+				v->rec_info.rec_mode,
+				v->rec_info.port_id);
 			common.srvcc_rec_flag = true;
 
 			pr_debug("%s: switch recording, srvcc_rec_flag %d\n",
@@ -5565,7 +5568,8 @@
 	return 0;
 }
 
-static int voice_cvs_start_record(struct voice_data *v, uint32_t rec_mode)
+static int voice_cvs_start_record(struct voice_data *v, uint32_t rec_mode,
+					uint32_t port_id)
 {
 	int ret = 0;
 	void *apr_cvs;
@@ -5616,6 +5620,18 @@
 					VSS_IRECORD_TAP_POINT_STREAM_END;
 			cvs_start_record.rec_mode.tx_tap_point =
 					VSS_IRECORD_TAP_POINT_STREAM_END;
+			if (common.rec_channel_count ==
+					NUM_CHANNELS_STEREO) {
+			/*
+			 * if channel count is not stereo,
+			 * then default port_id and mode
+			 * (mono) will be used
+			 */
+				cvs_start_record.rec_mode.mode =
+					VSS_IRECORD_MODE_TX_RX_STEREO;
+				cvs_start_record.rec_mode.port_id =
+					port_id;
+			}
 		} else {
 			pr_err("%s: Invalid in-call rec_mode %d\n", __func__,
 				rec_mode);
@@ -5774,6 +5790,7 @@
 
 		mutex_lock(&v->lock);
 		rec_mode = v->rec_info.rec_mode;
+		v->rec_info.port_id = port_id;
 		rec_set = set;
 		if (set) {
 			if ((v->rec_route_state.ul_flag != 0) &&
@@ -5850,7 +5867,8 @@
 
 		if (cvs_handle != 0) {
 			if (rec_set)
-				ret = voice_cvs_start_record(v, rec_mode);
+				ret = voice_cvs_start_record(v, rec_mode,
+						port_id);
 			else
 				ret = voice_cvs_stop_record(v);
 		}
@@ -6148,6 +6166,31 @@
 }
 EXPORT_SYMBOL(voc_disable_topology);
 
+/**
+ * voc_set_incall_capture_channel_config -
+ *		command to set channel count for record
+ *
+ * @channel_count: number of channels
+ *
+ */
+void voc_set_incall_capture_channel_config(int channel_count)
+{
+	common.rec_channel_count = channel_count;
+}
+EXPORT_SYMBOL(voc_set_incall_capture_channel_config);
+
+/**
+ * voc_get_incall_capture_channel_config -
+ *		command to get channel count for record
+ *
+ * Returns number of channels configured for record
+ */
+int voc_get_incall_capture_channel_config(void)
+{
+	return common.rec_channel_count;
+}
+EXPORT_SYMBOL(voc_get_incall_capture_channel_config);
+
 static int voice_set_packet_exchange_mode_and_config(uint32_t session_id,
 						 uint32_t mode)
 {
@@ -9907,6 +9950,12 @@
 	/* Initialize Per-Vocoder Calibration flag */
 	common.is_per_vocoder_cal_enabled = false;
 
+	/*
+	 * Initialize in call record channel config
+	 * to mono
+	 */
+	common.rec_channel_count = NUM_CHANNELS_MONO;
+
 	mutex_init(&common.common_lock);
 
 	common.uevent_data = kzalloc(sizeof(*(common.uevent_data)), GFP_KERNEL);
diff --git a/include/asoc/core.h b/include/asoc/core.h
index e4f0413..c6e544e 100644
--- a/include/asoc/core.h
+++ b/include/asoc/core.h
@@ -10,6 +10,7 @@
 #include <linux/of_irq.h>
 #include <linux/interrupt.h>
 #include <linux/pm_qos.h>
+#include "pdata.h"
 
 #define WCD9XXX_MAX_IRQ_REGS 4
 #define WCD9XXX_MAX_NUM_IRQS (WCD9XXX_MAX_IRQ_REGS * 8)
@@ -394,6 +395,11 @@
 			    struct wcd9xxx_reg_val *bulk_reg,
 			    unsigned int size, bool interface);
 
+int wcd9xxx_vote_ondemand_regulator(struct wcd9xxx *wcd9xxx,
+				    struct wcd9xxx_pdata *pdata,
+				    const char *supply_name,
+				    bool enable);
+
 extern int wcd9xxx_core_res_init(
 	struct wcd9xxx_core_resource *wcd9xxx_core_res,
 	int num_irqs, int num_irq_regs, struct regmap *wcd_regmap);
diff --git a/include/asoc/msm-cdc-supply.h b/include/asoc/msm-cdc-supply.h
index 9801115..c6aacf6 100644
--- a/include/asoc/msm-cdc-supply.h
+++ b/include/asoc/msm-cdc-supply.h
@@ -1,5 +1,5 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
-/* Copyright (c) 2016, 2018 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016, 2018-2019 The Linux Foundation. All rights reserved.
  */
 
 #ifndef __CODEC_POWER_SUPPLY_H__
@@ -45,4 +45,9 @@
 				 struct regulator_bulk_data **supplies,
 				 struct cdc_regulator *cdc_vreg,
 				 int num_supplies);
+extern int msm_cdc_init_supplies_v2(struct device *dev,
+				 struct regulator_bulk_data **supplies,
+				 struct cdc_regulator *cdc_vreg,
+				 int num_supplies,
+				 u32 vote_regulator_on_demand);
 #endif
diff --git a/include/asoc/pdata.h b/include/asoc/pdata.h
index d24d56a..41862d4 100644
--- a/include/asoc/pdata.h
+++ b/include/asoc/pdata.h
@@ -1,5 +1,5 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
-/* Copyright (c) 2011-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2019, The Linux Foundation. All rights reserved.
  */
 
 #ifndef __MFD_WCD9XXX_PDATA_H__
@@ -193,6 +193,7 @@
 	u32 ecpp_dmic_sample_rate;
 	u32 dmic_clk_drv;
 	u16 use_pinctrl;
+	u32 vote_regulator_on_demand;
 };
 
 #endif
diff --git a/include/asoc/wcd-mbhc-v2.h b/include/asoc/wcd-mbhc-v2.h
index c98cdda..9341e3d 100644
--- a/include/asoc/wcd-mbhc-v2.h
+++ b/include/asoc/wcd-mbhc-v2.h
@@ -1,5 +1,5 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
-/* Copyright (c) 2014-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2019, The Linux Foundation. All rights reserved.
  */
 #ifndef __WCD_MBHC_V2_H__
 #define __WCD_MBHC_V2_H__
@@ -540,6 +540,7 @@
 	bool gnd_swh; /*track GND switch NC / NO */
 	u32 hs_thr;
 	u32 hph_thr;
+	u32 micb_mv;
 	u32 swap_thr;
 	u32 moist_vref;
 	u32 moist_iref;
diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h
index e7c132a..8bff499 100644
--- a/include/dsp/apr_audio-v2.h
+++ b/include/dsp/apr_audio-v2.h
@@ -874,11 +874,14 @@
 	 */
 } __packed;
 
+/* Maximum number of channels supported by MFC media fmt params */
+#define AUDPROC_MFC_OUT_CHANNELS_MAX 8
+
 struct audproc_mfc_param_media_fmt {
 	uint32_t sampling_rate;
 	uint16_t bits_per_sample;
 	uint16_t num_channels;
-	uint16_t channel_type[8];
+	uint16_t channel_type[AUDPROC_MFC_OUT_CHANNELS_MAX];
 } __packed;
 
 struct audproc_volume_ctrl_master_gain {
diff --git a/include/dsp/q6adm-v2.h b/include/dsp/q6adm-v2.h
index 70dc2d0..a48082b 100644
--- a/include/dsp/q6adm-v2.h
+++ b/include/dsp/q6adm-v2.h
@@ -145,6 +145,8 @@
 
 int adm_get_multi_ch_map(char *channel_map, int path);
 
+void adm_set_port_multi_ch_map(char *channel_map, int port_id);
+
 int adm_validate_and_get_port_index(int port_id);
 
 int adm_get_default_copp_idx(int port_id);
diff --git a/include/dsp/q6afe-v2.h b/include/dsp/q6afe-v2.h
index 1efcb50..4a5f39a 100644
--- a/include/dsp/q6afe-v2.h
+++ b/include/dsp/q6afe-v2.h
@@ -43,6 +43,9 @@
 #define AFE_API_VERSION_V3		3
 /* for VAD and Island mode */
 #define AFE_API_VERSION_V4		4
+/* for VAD enable */
+#define AFE_API_VERSION_V6		6
+
 
 typedef int (*routing_cb)(int port);
 
@@ -452,6 +455,7 @@
 		u16 port_id);
 int afe_cal_init_hwdep(void *card);
 int afe_send_port_island_mode(u16 port_id);
+int afe_send_port_vad_cfg_params(u16 port_id);
 int afe_send_cmd_wakeup_register(void *handle, bool enable);
 void afe_register_wakeup_irq_callback(
 	void (*afe_cb_wakeup_irq)(void *handle));
diff --git a/include/dsp/q6common.h b/include/dsp/q6common.h
index c21ac5c..7250a13 100644
--- a/include/dsp/q6common.h
+++ b/include/dsp/q6common.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
  */
 
 #ifndef __Q6COMMON_H__
@@ -12,5 +12,7 @@
 bool q6common_is_instance_id_supported(void);
 int q6common_pack_pp_params(u8 *dest, struct param_hdr_v3 *v3_hdr,
 			    u8 *param_data, u32 *total_size);
-
+int q6common_pack_pp_params_v2(u8 *dest, struct param_hdr_v3 *v3_hdr,
+			    u8 *param_data, u32 *total_size,
+			    bool iid_supported);
 #endif /* __Q6COMMON_H__ */
diff --git a/include/dsp/q6voice.h b/include/dsp/q6voice.h
index 1e62124..06f4dfe 100644
--- a/include/dsp/q6voice.h
+++ b/include/dsp/q6voice.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
  */
 #ifndef __QDSP6VOICE_H__
 #define __QDSP6VOICE_H__
@@ -1768,6 +1768,7 @@
 	uint32_t rec_enable;
 	uint32_t rec_mode;
 	uint32_t recording;
+	uint32_t port_id;
 };
 
 struct incall_music_info {
@@ -1946,6 +1947,7 @@
 	bool sidetone_enable;
 	bool mic_break_enable;
 	struct audio_uevent_data *uevent_data;
+	int32_t rec_channel_count;
 };
 
 struct voice_session_itr {
@@ -2079,6 +2081,8 @@
 int voc_set_device_config(uint32_t session_id, uint8_t path_dir,
 			  struct media_format_info *finfo);
 uint32_t voice_get_topology(uint32_t topology_idx);
+void voc_set_incall_capture_channel_config(int channel_count);
+int voc_get_incall_capture_channel_config(void);
 int voice_set_topology_specific_info(struct voice_data *v,
 				     uint32_t topology_idx);
 int voc_set_sound_focus(struct sound_focus_param sound_focus_param);
diff --git a/ipc/Kbuild b/ipc/Kbuild
index 2da5fbd..fb0974e 100644
--- a/ipc/Kbuild
+++ b/ipc/Kbuild
@@ -27,7 +27,6 @@
         endif
 	ifeq ($(CONFIG_ARCH_KONA), y)
 		include $(AUDIO_ROOT)/config/konaauto.conf
-		export
 		INCS    +=  -include $(AUDIO_ROOT)/config/konaautoconf.h
 	endif
 	ifeq ($(CONFIG_ARCH_LITO), y)
diff --git a/soc/Android.mk b/soc/Android.mk
index 0698221..0bd7403 100644
--- a/soc/Android.mk
+++ b/soc/Android.mk
@@ -58,6 +58,7 @@
 include $(DLKM_DIR)/AndroidKernelModule.mk
 endif
 ###########################################################
+ifeq ($(call is-board-platform-in-list,$(MSMSTEPPE) $(TRINKET) kona), true)
 include $(CLEAR_VARS)
 LOCAL_MODULE              := $(AUDIO_CHIPSET)_pinctrl_wcd.ko
 LOCAL_MODULE_KBUILD_NAME  := pinctrl_wcd_dlkm.ko
@@ -65,6 +66,7 @@
 LOCAL_MODULE_DEBUG_ENABLE := true
 LOCAL_MODULE_PATH         := $(KERNEL_MODULES_OUT)
 include $(DLKM_DIR)/AndroidKernelModule.mk
+endif
 ###########################################################
 include $(CLEAR_VARS)
 LOCAL_MODULE              := $(AUDIO_CHIPSET)_swr.ko
diff --git a/soc/Kbuild b/soc/Kbuild
index f5f5c8b..a1944a1 100644
--- a/soc/Kbuild
+++ b/soc/Kbuild
@@ -21,7 +21,6 @@
 	endif
 	ifeq ($(CONFIG_ARCH_KONA), y)
 		include $(AUDIO_ROOT)/config/konaauto.conf
-		export
 		INCS    +=  -include $(AUDIO_ROOT)/config/konaautoconf.h
 	endif
 	ifeq ($(CONFIG_ARCH_LITO), y)
diff --git a/soc/pinctrl-lpi.c b/soc/pinctrl-lpi.c
index 3db2210..4eee086 100644
--- a/soc/pinctrl-lpi.c
+++ b/soc/pinctrl-lpi.c
@@ -110,6 +110,7 @@
 	char __iomem        *base;
 	struct clk          *lpass_core_hw_vote;
 	struct mutex         slew_access_lock;
+	bool core_hw_vote_status;
 };
 
 static const char *const lpi_gpio_groups[] = {
@@ -710,6 +711,7 @@
 	}
 	state->lpass_core_hw_vote = lpass_core_hw_vote;
 
+	state->core_hw_vote_status = false;
 	pm_runtime_set_autosuspend_delay(&pdev->dev, LPI_AUTO_SUSPEND_DELAY);
 	pm_runtime_use_autosuspend(&pdev->dev);
 	pm_runtime_set_suspended(&pdev->dev);
@@ -760,10 +762,12 @@
 	}
 
 	ret = clk_prepare_enable(state->lpass_core_hw_vote);
-	if (ret < 0) {
+	if (ret < 0)
 		dev_err(dev, "%s:lpass core hw island enable failed\n",
 			__func__);
-	}
+	else
+		state->core_hw_vote_status = true;
+
 	pm_runtime_set_autosuspend_delay(dev, LPI_AUTO_SUSPEND_DELAY);
 	return 0;
 }
@@ -776,7 +780,11 @@
 		dev_dbg(dev, "%s: Invalid core hw node\n", __func__);
 		return 0;
 	}
-	clk_disable_unprepare(state->lpass_core_hw_vote);
+
+	if (state->core_hw_vote_status) {
+		clk_disable_unprepare(state->lpass_core_hw_vote);
+		state->core_hw_vote_status = false;
+	}
 	return 0;
 }
 
diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c
index bddf30a..c9cccf6 100644
--- a/soc/swr-mstr-ctrl.c
+++ b/soc/swr-mstr-ctrl.c
@@ -241,8 +241,10 @@
 
 	mutex_lock(&swrm->clklock);
 	if (enable) {
-		if (!swrm->dev_up)
+		if (!swrm->dev_up) {
+			ret = -ENODEV;
 			goto exit;
+		}
 		swrm->clk_ref_count++;
 		if (swrm->clk_ref_count == 1) {
 			ret = swrm->clk(swrm->handle, true);
@@ -1274,7 +1276,10 @@
 	}
 
 	mutex_lock(&swrm->reslock);
-	swrm_clk_request(swrm, true);
+	if (swrm_clk_request(swrm, true)) {
+		mutex_unlock(&swrm->reslock);
+		goto exit;
+	}
 	mutex_unlock(&swrm->reslock);
 
 	intr_sts = swr_master_read(swrm, SWRM_INTERRUPT_STATUS);
@@ -1420,6 +1425,7 @@
 	mutex_lock(&swrm->reslock);
 	swrm_clk_request(swrm, false);
 	mutex_unlock(&swrm->reslock);
+exit:
 	swrm_unlock_sleep(swrm);
 	return ret;
 }
@@ -2293,7 +2299,12 @@
 			enable_bank_switch(swrm, 0, SWR_ROW_50, SWR_MIN_COL);
 			list_for_each_entry(swr_dev, &mstr->devices, dev_list) {
 				ret = swr_device_up(swr_dev);
-				if (ret) {
+				if (ret == -ENODEV) {
+					dev_dbg(dev,
+						"%s slave device up not implemented\n",
+						__func__);
+					ret = 0;
+				} else if (ret) {
 					dev_err(dev,
 						"%s: failed to wakeup swr dev %d\n",
 						__func__, swr_dev->dev_num);
@@ -2358,7 +2369,12 @@
 			swr_master_write(swrm, SWRM_COMP_CFG_ADDR, 0x00);
 			list_for_each_entry(swr_dev, &mstr->devices, dev_list) {
 				ret = swr_device_down(swr_dev);
-				if (ret) {
+				if (ret == -ENODEV) {
+					dev_dbg_ratelimited(dev,
+						"%s slave device down not implemented\n",
+						__func__);
+					ret = 0;
+				} else if (ret) {
 					dev_err(dev,
 						"%s: failed to shutdown swr dev %d\n",
 						__func__, swr_dev->dev_num);