Merge "asoc: codecs: Add default case for switch."
diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c
index 417b34d..fea1686 100644
--- a/asoc/codecs/bolero/bolero-cdc.c
+++ b/asoc/codecs/bolero/bolero-cdc.c
@@ -1078,7 +1078,7 @@
  * Returns 0 on success or -EINVAL on error.
  */
 int bolero_register_event_listener(struct snd_soc_component *component,
-				   bool enable)
+				   bool enable, bool is_dmic_sva)
 {
 	struct bolero_priv *priv = NULL;
 	int ret = 0;
@@ -1097,7 +1097,8 @@
 
 	if (priv->macro_params[TX_MACRO].reg_evt_listener)
 		ret = priv->macro_params[TX_MACRO].reg_evt_listener(component,
-								    enable);
+								    enable,
+								    is_dmic_sva);
 
 	return ret;
 }
diff --git a/asoc/codecs/bolero/bolero-cdc.h b/asoc/codecs/bolero/bolero-cdc.h
index b37eeae..7528eae 100644
--- a/asoc/codecs/bolero/bolero-cdc.h
+++ b/asoc/codecs/bolero/bolero-cdc.h
@@ -88,7 +88,8 @@
 			    u32 size, void *data);
 	int (*clk_div_get)(struct snd_soc_component *component);
 	int (*clk_switch)(struct snd_soc_component *component, int clk_src);
-	int (*reg_evt_listener)(struct snd_soc_component *component, bool en);
+	int (*reg_evt_listener)(struct snd_soc_component *component,
+			bool en, bool is_dmic_sva);
 	int (*clk_enable)(struct snd_soc_component *c, bool en);
 	char __iomem *io_base;
 	u16 clk_id_req;
@@ -115,7 +116,7 @@
 int bolero_set_port_map(struct snd_soc_component *component, u32 size, void *data);
 int bolero_tx_clk_switch(struct snd_soc_component *component, int clk_src);
 int bolero_register_event_listener(struct snd_soc_component *component,
-				   bool enable);
+				   bool enable, bool is_dmic_sva);
 void bolero_wsa_pa_on(struct device *dev);
 bool bolero_check_core_votes(struct device *dev);
 int bolero_tx_mclk_enable(struct snd_soc_component *c, bool enable);
@@ -189,7 +190,7 @@
 
 static inline int bolero_register_event_listener(
 					struct snd_soc_component *component,
-					bool enable)
+					bool enable, bool is_dmic_sva)
 {
 	return 0;
 }
diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c
index 121f56d..ff94198 100644
--- a/asoc/codecs/bolero/tx-macro.c
+++ b/asoc/codecs/bolero/tx-macro.c
@@ -2385,7 +2385,7 @@
 };
 
 static int tx_macro_register_event_listener(struct snd_soc_component *component,
-					    bool enable)
+					    bool enable, bool is_dmic_sva)
 {
 	struct device *tx_dev = NULL;
 	struct tx_macro_priv *tx_priv = NULL;
@@ -2412,10 +2412,12 @@
 			ret = swrm_wcd_notify(
 				tx_priv->swr_ctrl_data[0].tx_swr_pdev,
 				SWR_REGISTER_WAKEUP, NULL);
-			msm_cdc_pinctrl_set_wakeup_capable(
+			if (!is_dmic_sva)
+				msm_cdc_pinctrl_set_wakeup_capable(
 					tx_priv->tx_swr_gpio_p, false);
 		} else {
-			msm_cdc_pinctrl_set_wakeup_capable(
+			if (!is_dmic_sva)
+				msm_cdc_pinctrl_set_wakeup_capable(
 					tx_priv->tx_swr_gpio_p, true);
 			ret = swrm_wcd_notify(
 				tx_priv->swr_ctrl_data[0].tx_swr_pdev,
diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c
index a947a28..de834ad 100644
--- a/asoc/codecs/bolero/va-macro.c
+++ b/asoc/codecs/bolero/va-macro.c
@@ -457,14 +457,14 @@
 				dev_dbg(va_dev, "%s: clock switch failed\n",
 					__func__);
 		if (va_priv->lpi_enable) {
-			bolero_register_event_listener(component, true);
+			bolero_register_event_listener(component, true, false);
 			va_priv->register_event_listener = true;
 		}
 		break;
 	case SND_SOC_DAPM_POST_PMD:
 		if (va_priv->register_event_listener) {
 			va_priv->register_event_listener = false;
-			bolero_register_event_listener(component, false);
+			bolero_register_event_listener(component, false, false);
 		}
 		if (bolero_tx_clk_switch(component, CLK_SRC_TX_RCG))
 			dev_dbg(va_dev, "%s: clock switch failed\n",__func__);
@@ -480,6 +480,45 @@
 	return ret;
 }
 
+static int va_macro_swr_intr_event(struct snd_soc_dapm_widget *w,
+			       struct snd_kcontrol *kcontrol, int event)
+{
+	struct snd_soc_component *component =
+			snd_soc_dapm_to_component(w->dapm);
+	int ret = 0;
+	struct device *va_dev = NULL;
+	struct va_macro_priv *va_priv = NULL;
+
+	if (!va_macro_get_data(component, &va_dev, &va_priv, __func__))
+		return -EINVAL;
+
+	dev_dbg(va_dev, "%s: event = %d, lpi_enable = %d\n",
+		__func__, event, va_priv->lpi_enable);
+
+	if (!va_priv->lpi_enable)
+		return ret;
+
+	switch (event) {
+	case SND_SOC_DAPM_PRE_PMU:
+		if (va_priv->lpi_enable) {
+			bolero_register_event_listener(component, true, true);
+			va_priv->register_event_listener = true;
+		}
+		break;
+	case SND_SOC_DAPM_POST_PMD:
+		if (va_priv->register_event_listener) {
+			va_priv->register_event_listener = false;
+			bolero_register_event_listener(component, false, true);
+		}
+		break;
+	default:
+		dev_err(va_priv->dev,
+			"%s: invalid DAPM event %d\n", __func__, event);
+		ret = -EINVAL;
+	}
+	return ret;
+}
+
 static int va_macro_tx_swr_clk_event_v2(struct snd_soc_dapm_widget *w,
 			       struct snd_kcontrol *kcontrol, int event)
 {
@@ -1962,6 +2001,10 @@
 	SND_SOC_DAPM_SUPPLY_S("VA_SWR_PWR", -1, SND_SOC_NOPM, 0, 0,
 			      va_macro_swr_pwr_event,
 			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_SUPPLY_S("VA_SWR_INTR", 0, SND_SOC_NOPM, 0, 0,
+			      va_macro_swr_intr_event,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 };
 
 static const struct snd_soc_dapm_widget va_macro_dapm_widgets[] = {
@@ -2106,6 +2149,10 @@
 	SND_SOC_DAPM_SUPPLY_S("VA_MCLK", -1, SND_SOC_NOPM, 0, 0,
 			      va_macro_mclk_event,
 			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+	SND_SOC_DAPM_SUPPLY_S("VA_SWR_INTR", 0, SND_SOC_NOPM, 0, 0,
+			      va_macro_swr_intr_event,
+			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 };
 
 static const struct snd_soc_dapm_widget va_macro_wod_dapm_widgets[] = {
@@ -2252,6 +2299,15 @@
 	{"VA SMIC MUX3", "SWR_MIC9", "VA SWR_MIC9"},
 	{"VA SMIC MUX3", "SWR_MIC10", "VA SWR_MIC10"},
 	{"VA SMIC MUX3", "SWR_MIC11", "VA SWR_MIC11"},
+
+	{"VA DMIC0", NULL, "VA_SWR_INTR"},
+	{"VA DMIC1", NULL, "VA_SWR_INTR"},
+	{"VA DMIC2", NULL, "VA_SWR_INTR"},
+	{"VA DMIC3", NULL, "VA_SWR_INTR"},
+	{"VA DMIC4", NULL, "VA_SWR_INTR"},
+	{"VA DMIC5", NULL, "VA_SWR_INTR"},
+	{"VA DMIC6", NULL, "VA_SWR_INTR"},
+	{"VA DMIC7", NULL, "VA_SWR_INTR"},
 };
 
 static const struct snd_soc_dapm_route va_audio_map_v2[] = {
@@ -2488,6 +2544,15 @@
 	{"VA SMIC MUX7", "SWR_DMIC6", "VA SWR_MIC6"},
 	{"VA SMIC MUX7", "SWR_DMIC7", "VA SWR_MIC7"},
 
+	{"VA DMIC0", NULL, "VA_SWR_INTR"},
+	{"VA DMIC1", NULL, "VA_SWR_INTR"},
+	{"VA DMIC2", NULL, "VA_SWR_INTR"},
+	{"VA DMIC3", NULL, "VA_SWR_INTR"},
+	{"VA DMIC4", NULL, "VA_SWR_INTR"},
+	{"VA DMIC5", NULL, "VA_SWR_INTR"},
+	{"VA DMIC6", NULL, "VA_SWR_INTR"},
+	{"VA DMIC7", NULL, "VA_SWR_INTR"},
+
 	{"VA SWR_ADC0", NULL, "VA_SWR_PWR"},
 	{"VA SWR_ADC1", NULL, "VA_SWR_PWR"},
 	{"VA SWR_ADC2", NULL, "VA_SWR_PWR"},
diff --git a/asoc/codecs/rouleur/internal.h b/asoc/codecs/rouleur/internal.h
index df8541e..233ca51 100644
--- a/asoc/codecs/rouleur/internal.h
+++ b/asoc/codecs/rouleur/internal.h
@@ -170,4 +170,6 @@
 extern int rouleur_get_micb_vout_ctl_val(u32 micb_mv);
 extern int rouleur_micbias_control(struct snd_soc_component *component,
 			int micb_num, int req, bool is_dapm);
+extern int rouleur_global_mbias_enable(struct snd_soc_component *component);
+extern int rouleur_global_mbias_disable(struct snd_soc_component *component);
 #endif
diff --git a/asoc/codecs/rouleur/rouleur-mbhc.c b/asoc/codecs/rouleur/rouleur-mbhc.c
index 2f8e954..f0eea09 100644
--- a/asoc/codecs/rouleur/rouleur-mbhc.c
+++ b/asoc/codecs/rouleur/rouleur-mbhc.c
@@ -22,20 +22,15 @@
 
 #define ROULEUR_ZDET_SUPPORTED          true
 /* Z value defined in milliohm */
-#define ROULEUR_ZDET_VAL_32             32000
-#define ROULEUR_ZDET_VAL_400            400000
-#define ROULEUR_ZDET_VAL_1200           1200000
 #define ROULEUR_ZDET_VAL_100K           100000000
 /* Z floating defined in ohms */
 #define ROULEUR_ZDET_FLOATING_IMPEDANCE 0x0FFFFFFE
 
-#define ROULEUR_ZDET_NUM_MEASUREMENTS   900
-#define ROULEUR_MBHC_GET_C1(c)          ((c & 0xC000) >> 14)
-#define ROULEUR_MBHC_GET_X1(x)          (x & 0x3FFF)
-/* Z value compared in milliOhm */
-#define ROULEUR_MBHC_IS_SECOND_RAMP_REQUIRED(z) ((z > 400000) || (z < 32000))
-#define ROULEUR_MBHC_ZDET_CONST         (86 * 16384)
-#define ROULEUR_MBHC_MOISTURE_RREF      R_24_KOHM
+#define ROULEUR_ZDET_NUM_MEASUREMENTS   100
+#define ROULEUR_ZDET_RMAX               1280000
+#define ROULEUR_ZDET_C1                 7500000
+#define ROULEUR_ZDET_C2                 187
+#define ROULEUR_ZDET_C3                 4500
 
 /* Cross connection thresholds in mV */
 #define ROULEUR_HPHL_CROSS_CONN_THRESHOLD 200
@@ -157,9 +152,6 @@
 	u16 ldo_ctl;
 	u16 noff;
 	u16 nshift;
-	u16 btn5;
-	u16 btn6;
-	u16 btn7;
 };
 
 static int rouleur_mbhc_request_irq(struct snd_soc_component *component,
@@ -380,174 +372,180 @@
 	return rc;
 }
 
-static inline void rouleur_mbhc_get_result_params(struct rouleur_priv *rouleur,
-						s16 *d1_a, u16 noff,
-						int32_t *zdet)
+static void rouleur_mbhc_get_result_params(struct rouleur_priv *rouleur,
+					   struct snd_soc_component *component,
+					   int32_t *zdet)
 {
 	int i;
-	int val = 0, val1 = 0;
-	s16 c1 = 0;
-	s32 x1 = 0, d1 = 0;
-	int32_t denom;
-	int minCode_param[] = {
-			3277, 1639, 820, 410, 205, 103, 52, 26
-	};
+	int zcode = 0, zcode1 = 0, zdet_cal_result = 0, zdet_est_range = 0;
+	int noff = 0, ndac = 14;
+	int zdet_cal_coeff = 0, div_ratio = 0;
+	int num = 0, denom = 0;
 
+	/* Charge enable and wait for zcode to be updated */
 	regmap_update_bits(rouleur->regmap, ROULEUR_ANA_MBHC_ZDET, 0x20, 0x20);
 	for (i = 0; i < ROULEUR_ZDET_NUM_MEASUREMENTS; i++) {
-		regmap_read(rouleur->regmap, ROULEUR_ANA_MBHC_RESULT_2, &val);
-		if (val & 0x80)
+		regmap_read(rouleur->regmap, ROULEUR_ANA_MBHC_RESULT_2, &zcode);
+		if (zcode & 0x80)
 			break;
+		usleep_range(200, 210);
 	}
-	val = val << 0x8;
-	regmap_read(rouleur->regmap, ROULEUR_ANA_MBHC_RESULT_1, &val1);
-	val |= val1;
-	regmap_update_bits(rouleur->regmap, ROULEUR_ANA_MBHC_ZDET, 0x20, 0x00);
-	x1 = ROULEUR_MBHC_GET_X1(val);
-	c1 = ROULEUR_MBHC_GET_C1(val);
-	/* If ramp is not complete, give additional 5ms */
-	if ((c1 < 2) && x1)
-		usleep_range(5000, 5050);
 
-	if (!c1 || !x1) {
+	/* If zcode updation is not complete, give additional 10ms */
+	if (!(zcode & 0x80))
+		usleep_range(10000, 10100);
+
+	regmap_read(rouleur->regmap, ROULEUR_ANA_MBHC_RESULT_2, &zcode);
+	if (!(zcode & 0x80)) {
 		dev_dbg(rouleur->dev,
-			"%s: Impedance detect ramp error, c1=%d, x1=0x%x\n",
-			__func__, c1, x1);
-		goto ramp_down;
+			"%s: Impedance detect calculation error, zcode=0x%x\n",
+			__func__, zcode);
+		regmap_update_bits(rouleur->regmap, ROULEUR_ANA_MBHC_ZDET,
+				   0x20, 0x00);
+		return;
 	}
-	d1 = d1_a[c1];
-	denom = (x1 * d1) - (1 << (14 - noff));
+	zcode = zcode << 0x8;
+	zcode = zcode & 0x3FFF;
+	regmap_read(rouleur->regmap, ROULEUR_ANA_MBHC_RESULT_1, &zcode1);
+	zcode |= zcode1;
+
+	dev_dbg(rouleur->dev,
+		"%s: zcode: %d, zcode1: %d\n", __func__, zcode, zcode1);
+
+	/* Calculate calibration coefficient */
+	zdet_cal_result = (snd_soc_component_read32(component,
+				ROULEUR_ANA_MBHC_ZDET_CALIB_RESULT)) & 0x1F;
+	zdet_cal_coeff = ROULEUR_ZDET_C1 /
+			((ROULEUR_ZDET_C2 * zdet_cal_result) + ROULEUR_ZDET_C3);
+	/* Rload calculation */
+	zdet_est_range = (snd_soc_component_read32(component,
+			  ROULEUR_ANA_MBHC_ZDET_CALIB_RESULT) & 0x60) >> 5;
+
+	dev_dbg(rouleur->dev,
+		"%s: zdet_cal_result: %d, zdet_cal_coeff: %d, zdet_est_range: %d\n",
+		__func__, zdet_cal_result, zdet_cal_coeff, zdet_est_range);
+	switch (zdet_est_range) {
+	case 0:
+	default:
+		noff = 0;
+		div_ratio = 320;
+		break;
+	case 1:
+		noff = 0;
+		div_ratio = 64;
+		break;
+	case 2:
+		noff = 4;
+		div_ratio = 64;
+		break;
+	case 3:
+		noff = 5;
+		div_ratio = 40;
+		break;
+	}
+
+	num = zdet_cal_coeff * ROULEUR_ZDET_RMAX;
+	denom = ((zcode * div_ratio * 100) - (1 << (ndac - noff)) * 1000);
+	dev_dbg(rouleur->dev,
+		"%s: num: %d, denom: %d\n", __func__, num, denom);
 	if (denom > 0)
-		*zdet = (ROULEUR_MBHC_ZDET_CONST * 1000) / denom;
-	else if (x1 < minCode_param[noff])
+		*zdet = (int32_t) ((num / denom) * 1000);
+	else
 		*zdet = ROULEUR_ZDET_FLOATING_IMPEDANCE;
 
-	dev_dbg(rouleur->dev, "%s: d1=%d, c1=%d, x1=0x%x, z_val=%d(milliOhm)\n",
-		__func__, d1, c1, x1, *zdet);
-ramp_down:
-	i = 0;
-	while (x1) {
-		regmap_read(rouleur->regmap, ROULEUR_ANA_MBHC_RESULT_1, &val);
-		regmap_read(rouleur->regmap, ROULEUR_ANA_MBHC_RESULT_2, &val1);
-		val = val << 0x8;
-		val |= val1;
-		x1 = ROULEUR_MBHC_GET_X1(val);
-		i++;
-		if (i == ROULEUR_ZDET_NUM_MEASUREMENTS)
-			break;
-	}
+	dev_dbg(rouleur->dev, "%s: z_val=%d(milliOhm)\n",
+		__func__, *zdet);
+	/* Start discharge */
+	regmap_update_bits(rouleur->regmap, ROULEUR_ANA_MBHC_ZDET, 0x20, 0x00);
 }
 
-#if 0
-static void rouleur_mbhc_zdet_ramp(struct snd_soc_component *component,
-				 struct rouleur_mbhc_zdet_param *zdet_param,
-				 int32_t *zl, int32_t *zr, s16 *d1_a)
+static void rouleur_mbhc_zdet_start(struct snd_soc_component *component,
+				 int32_t *zl, int32_t *zr)
 {
 	struct rouleur_priv *rouleur = dev_get_drvdata(component->dev);
 	int32_t zdet = 0;
 
-	snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_ZDET_ANA_CTL,
-				0x70, zdet_param->ldo_ctl << 4);
-	snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_BTN5, 0xFC,
-				zdet_param->btn5);
-	snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_BTN6, 0xFC,
-				zdet_param->btn6);
-	snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_BTN7, 0xFC,
-				zdet_param->btn7);
-	snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_ZDET_ANA_CTL,
-				0x0F, zdet_param->noff);
-	snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_ZDET_RAMP_CTL,
-				0x0F, zdet_param->nshift);
-
 	if (!zl)
 		goto z_right;
-	/* Start impedance measurement for HPH_L */
+
+	/* HPHL pull down switch to force OFF */
+	regmap_update_bits(rouleur->regmap,
+			  ROULEUR_ANA_HPHPA_CNP_CTL_2, 0x30, 0x00);
+	/* Averaging enable for reliable results */
+	regmap_update_bits(rouleur->regmap,
+			   ROULEUR_ANA_MBHC_ZDET_ANA_CTL, 0x80, 0x80);
+	/* ZDET left measurement enable */
 	regmap_update_bits(rouleur->regmap,
 			   ROULEUR_ANA_MBHC_ZDET, 0x80, 0x80);
-	dev_dbg(rouleur->dev, "%s: ramp for HPH_L, noff = %d\n",
-		__func__, zdet_param->noff);
-	rouleur_mbhc_get_result_params(rouleur, d1_a, zdet_param->noff, &zdet);
+	/* Calculate the left Rload result */
+	rouleur_mbhc_get_result_params(rouleur, component, &zdet);
+
 	regmap_update_bits(rouleur->regmap,
 			   ROULEUR_ANA_MBHC_ZDET, 0x80, 0x00);
+	regmap_update_bits(rouleur->regmap,
+			   ROULEUR_ANA_MBHC_ZDET_ANA_CTL, 0x80, 0x00);
+	regmap_update_bits(rouleur->regmap,
+			  ROULEUR_ANA_HPHPA_CNP_CTL_2, 0x30, 0x20);
 
 	*zl = zdet;
 
 z_right:
 	if (!zr)
 		return;
-	/* Start impedance measurement for HPH_R */
+	/* HPHR pull down switch to force OFF */
+	regmap_update_bits(rouleur->regmap,
+			  ROULEUR_ANA_HPHPA_CNP_CTL_2, 0x0C, 0x00);
+	/* Averaging enable for reliable results */
+	regmap_update_bits(rouleur->regmap,
+			   ROULEUR_ANA_MBHC_ZDET_ANA_CTL, 0x80, 0x80);
+	/* ZDET right measurement enable */
 	regmap_update_bits(rouleur->regmap,
 			   ROULEUR_ANA_MBHC_ZDET, 0x40, 0x40);
-	dev_dbg(rouleur->dev, "%s: ramp for HPH_R, noff = %d\n",
-		__func__, zdet_param->noff);
-	rouleur_mbhc_get_result_params(rouleur, d1_a, zdet_param->noff, &zdet);
+
+	/* Calculate the right Rload result */
+	rouleur_mbhc_get_result_params(rouleur, component, &zdet);
+
 	regmap_update_bits(rouleur->regmap,
 			   ROULEUR_ANA_MBHC_ZDET, 0x40, 0x00);
+	regmap_update_bits(rouleur->regmap,
+			   ROULEUR_ANA_MBHC_ZDET_ANA_CTL, 0x80, 0x00);
+	regmap_update_bits(rouleur->regmap,
+			  ROULEUR_ANA_HPHPA_CNP_CTL_2, 0x0C, 0x08);
 
 	*zr = zdet;
 }
 
-static inline void rouleur_wcd_mbhc_qfuse_cal(
-					struct snd_soc_component *component,
-					int32_t *z_val, int flag_l_r)
-{
-	s16 q1;
-	int q1_cal;
-
-	if (*z_val < (ROULEUR_ZDET_VAL_400/1000))
-		q1 = snd_soc_component_read32(component,
-			ROULEUR_DIGITAL_EFUSE_REG_23 + (2 * flag_l_r));
-	else
-		q1 = snd_soc_component_read32(component,
-			ROULEUR_DIGITAL_EFUSE_REG_24 + (2 * flag_l_r));
-	if (q1 & 0x80)
-		q1_cal = (10000 - ((q1 & 0x7F) * 25));
-	else
-		q1_cal = (10000 + (q1 * 25));
-	if (q1_cal > 0)
-		*z_val = ((*z_val) * 10000) / q1_cal;
-}
-
 static void rouleur_wcd_mbhc_calc_impedance(struct wcd_mbhc *mbhc, uint32_t *zl,
 					  uint32_t *zr)
 {
 	struct snd_soc_component *component = mbhc->component;
 	struct rouleur_priv *rouleur = dev_get_drvdata(component->dev);
-	s16 reg0, reg1, reg2, reg3, reg4;
+	s16 reg0;
 	int32_t z1L, z1R, z1Ls;
 	int zMono, z_diff1, z_diff2;
 	bool is_fsm_disable = false;
-	struct rouleur_mbhc_zdet_param zdet_param[] = {
-		{4, 0, 4, 0x08, 0x14, 0x18}, /* < 32ohm */
-		{2, 0, 3, 0x18, 0x7C, 0x90}, /* 32ohm < Z < 400ohm */
-		{1, 4, 5, 0x18, 0x7C, 0x90}, /* 400ohm < Z < 1200ohm */
-		{1, 6, 7, 0x18, 0x7C, 0x90}, /* >1200ohm */
-	};
-	struct rouleur_mbhc_zdet_param *zdet_param_ptr = NULL;
-	s16 d1_a[][4] = {
-		{0, 30, 90, 30},
-		{0, 30, 30, 5},
-		{0, 30, 30, 5},
-		{0, 30, 30, 5},
-	};
-	s16 *d1 = NULL;
 
 	WCD_MBHC_RSC_ASSERT_LOCKED(mbhc);
 
-	reg0 = snd_soc_component_read32(component, ROULEUR_ANA_MBHC_BTN5);
-	reg1 = snd_soc_component_read32(component, ROULEUR_ANA_MBHC_BTN6);
-	reg2 = snd_soc_component_read32(component, ROULEUR_ANA_MBHC_BTN7);
-	reg3 = snd_soc_component_read32(component, ROULEUR_MBHC_CTL_CLK);
-	reg4 = snd_soc_component_read32(component,
-			ROULEUR_ANA_MBHC_ZDET_ANA_CTL);
+	reg0 = snd_soc_component_read32(component, ROULEUR_ANA_MBHC_ELECT);
 
-	if (snd_soc_component_read32(component, ROULEUR_ANA_MBHC_ELECT) &
-			0x80) {
+	if (reg0 & 0x80) {
 		is_fsm_disable = true;
 		regmap_update_bits(rouleur->regmap,
 				   ROULEUR_ANA_MBHC_ELECT, 0x80, 0x00);
 	}
 
+	/* Enable electrical bias */
+	snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_ELECT,
+				      0x01, 0x01);
+
+	/* Enable codec main bias */
+	rouleur_global_mbias_enable(component);
+
+	/* Enable RCO clock */
+	snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_CTL_1,
+				      0x80, 0x80);
+
 	/* For NO-jack, disable L_DET_EN before Z-det measurements */
 	if (mbhc->hphl_swh)
 		regmap_update_bits(rouleur->regmap,
@@ -557,79 +555,34 @@
 	regmap_update_bits(rouleur->regmap,
 			   ROULEUR_ANA_MBHC_MECH, 0x01, 0x00);
 
-	/* Disable surge protection before impedance detection.
+	/*
+	 * Disable surge protection before impedance detection.
 	 * This is done to give correct value for high impedance.
 	 */
-	regmap_update_bits(rouleur->regmap,
-			   ROULEUR_HPH_SURGE_HPHLR_SURGE_EN, 0xC0, 0x00);
+	snd_soc_component_update_bits(component, ROULEUR_ANA_SURGE_EN,
+					0xC0, 0x00);
 	/* 1ms delay needed after disable surge protection */
 	usleep_range(1000, 1010);
 
-	/* First get impedance on Left */
-	d1 = d1_a[1];
-	zdet_param_ptr = &zdet_param[1];
-	rouleur_mbhc_zdet_ramp(component, zdet_param_ptr, &z1L, NULL, d1);
-
-	if (!ROULEUR_MBHC_IS_SECOND_RAMP_REQUIRED(z1L))
-		goto left_ch_impedance;
-
-	/* Second ramp for left ch */
-	if (z1L < ROULEUR_ZDET_VAL_32) {
-		zdet_param_ptr = &zdet_param[0];
-		d1 = d1_a[0];
-	} else if ((z1L > ROULEUR_ZDET_VAL_400) &&
-		  (z1L <= ROULEUR_ZDET_VAL_1200)) {
-		zdet_param_ptr = &zdet_param[2];
-		d1 = d1_a[2];
-	} else if (z1L > ROULEUR_ZDET_VAL_1200) {
-		zdet_param_ptr = &zdet_param[3];
-		d1 = d1_a[3];
-	}
-	rouleur_mbhc_zdet_ramp(component, zdet_param_ptr, &z1L, NULL, d1);
-
-left_ch_impedance:
+	/* Start of left ch impedance calculation */
+	rouleur_mbhc_zdet_start(component, &z1L, NULL);
 	if ((z1L == ROULEUR_ZDET_FLOATING_IMPEDANCE) ||
-		(z1L > ROULEUR_ZDET_VAL_100K)) {
+		(z1L > ROULEUR_ZDET_VAL_100K))
 		*zl = ROULEUR_ZDET_FLOATING_IMPEDANCE;
-		zdet_param_ptr = &zdet_param[1];
-		d1 = d1_a[1];
-	} else {
+	else
 		*zl = z1L/1000;
-		rouleur_wcd_mbhc_qfuse_cal(component, zl, 0);
-	}
+
 	dev_dbg(component->dev, "%s: impedance on HPH_L = %d(ohms)\n",
 		__func__, *zl);
 
-	/* Start of right impedance ramp and calculation */
-	rouleur_mbhc_zdet_ramp(component, zdet_param_ptr, NULL, &z1R, d1);
-	if (ROULEUR_MBHC_IS_SECOND_RAMP_REQUIRED(z1R)) {
-		if (((z1R > ROULEUR_ZDET_VAL_1200) &&
-			(zdet_param_ptr->noff == 0x6)) ||
-			((*zl) != ROULEUR_ZDET_FLOATING_IMPEDANCE))
-			goto right_ch_impedance;
-		/* Second ramp for right ch */
-		if (z1R < ROULEUR_ZDET_VAL_32) {
-			zdet_param_ptr = &zdet_param[0];
-			d1 = d1_a[0];
-		} else if ((z1R > ROULEUR_ZDET_VAL_400) &&
-			(z1R <= ROULEUR_ZDET_VAL_1200)) {
-			zdet_param_ptr = &zdet_param[2];
-			d1 = d1_a[2];
-		} else if (z1R > ROULEUR_ZDET_VAL_1200) {
-			zdet_param_ptr = &zdet_param[3];
-			d1 = d1_a[3];
-		}
-		rouleur_mbhc_zdet_ramp(component, zdet_param_ptr, NULL,
-				&z1R, d1);
-	}
-right_ch_impedance:
+	/* Start of right ch impedance calculation */
+	rouleur_mbhc_zdet_start(component, NULL, &z1R);
 	if ((z1R == ROULEUR_ZDET_FLOATING_IMPEDANCE) ||
-		(z1R > ROULEUR_ZDET_VAL_100K)) {
+		(z1R > ROULEUR_ZDET_VAL_100K))
 		*zr = ROULEUR_ZDET_FLOATING_IMPEDANCE;
-	} else {
+	else
 		*zr = z1R/1000;
-		rouleur_wcd_mbhc_qfuse_cal(component, zr, 1);
-	}
+
 	dev_dbg(component->dev, "%s: impedance on HPH_R = %d(ohms)\n",
 		__func__, *zr);
 
@@ -651,24 +604,10 @@
 		mbhc->hph_type = WCD_MBHC_HPH_MONO;
 		goto zdet_complete;
 	}
-	snd_soc_component_update_bits(component, ROULEUR_HPH_R_ATEST,
-				0x02, 0x02);
-	snd_soc_component_update_bits(component, ROULEUR_HPH_PA_CTL2,
-				0x40, 0x01);
-	if (*zl < (ROULEUR_ZDET_VAL_32/1000))
-		rouleur_mbhc_zdet_ramp(component, &zdet_param[0], &z1Ls,
-				NULL, d1);
-	else
-		rouleur_mbhc_zdet_ramp(component, &zdet_param[1], &z1Ls,
-				NULL, d1);
-	snd_soc_component_update_bits(component, ROULEUR_HPH_PA_CTL2,
-				0x40, 0x00);
-	snd_soc_component_update_bits(component, ROULEUR_HPH_R_ATEST,
-				0x02, 0x00);
-	z1Ls /= 1000;
-	rouleur_wcd_mbhc_qfuse_cal(component, &z1Ls, 0);
-	/* Parallel of left Z and 9 ohm pull down resistor */
-	zMono = ((*zl) * 9) / ((*zl) + 9);
+
+	z1Ls = z1L/1000;
+	/* Parallel of left Z and 20 ohm pull down resistor */
+	zMono = ((*zl) * 20) / ((*zl) + 20);
 	z_diff1 = (z1Ls > zMono) ? (z1Ls - zMono) : (zMono - z1Ls);
 	z_diff2 = ((*zl) > z1Ls) ? ((*zl) - z1Ls) : (z1Ls - (*zl));
 	if ((z_diff1 * (*zl + z1Ls)) > (z_diff2 * (z1Ls + zMono))) {
@@ -681,13 +620,10 @@
 		mbhc->hph_type = WCD_MBHC_HPH_MONO;
 	}
 
+zdet_complete:
 	/* Enable surge protection again after impedance detection */
 	regmap_update_bits(rouleur->regmap,
-			   ROULEUR_HPH_SURGE_HPHLR_SURGE_EN, 0xC0, 0xC0);
-zdet_complete:
-	snd_soc_component_write(component, ROULEUR_ANA_MBHC_BTN5, reg0);
-	snd_soc_component_write(component, ROULEUR_ANA_MBHC_BTN6, reg1);
-	snd_soc_component_write(component, ROULEUR_ANA_MBHC_BTN7, reg2);
+			   ROULEUR_ANA_SURGE_EN, 0xC0, 0xC0);
 	/* Turn on 100k pull down on HPHL */
 	regmap_update_bits(rouleur->regmap,
 			   ROULEUR_ANA_MBHC_MECH, 0x01, 0x01);
@@ -697,13 +633,14 @@
 		regmap_update_bits(rouleur->regmap,
 				   ROULEUR_ANA_MBHC_MECH, 0x80, 0x80);
 
-	snd_soc_component_write(component, ROULEUR_ANA_MBHC_ZDET_ANA_CTL, reg4);
-	snd_soc_component_write(component, ROULEUR_MBHC_CTL_CLK, reg3);
+	/* Restore electrical bias state */
+	snd_soc_component_update_bits(component, ROULEUR_ANA_MBHC_ELECT, 0x01,
+				      reg0 >> 7);
 	if (is_fsm_disable)
 		regmap_update_bits(rouleur->regmap,
 				   ROULEUR_ANA_MBHC_ELECT, 0x80, 0x80);
+	rouleur_global_mbias_disable(component);
 }
-#endif
 
 static void rouleur_mbhc_gnd_det_ctrl(struct snd_soc_component *component,
 			bool enable)
@@ -727,10 +664,10 @@
 	if (enable) {
 		snd_soc_component_update_bits(component,
 				    ROULEUR_ANA_HPHPA_CNP_CTL_2,
-				    0x30, 0x10);
+				    0x30, 0x20);
 		snd_soc_component_update_bits(component,
 				    ROULEUR_ANA_HPHPA_CNP_CTL_2,
-				    0x0C, 0x04);
+				    0x0C, 0x08);
 	} else {
 		snd_soc_component_update_bits(component,
 				    ROULEUR_ANA_HPHPA_CNP_CTL_2,
@@ -843,10 +780,10 @@
 {
 	if (az_enable)
 		snd_soc_component_update_bits(mbhc->component,
-				ROULEUR_ANA_MBHC_MCLK, 0x08, 0x08);
+				ROULEUR_ANA_MBHC_CTL_CLK, 0x08, 0x08);
 	else
 		snd_soc_component_update_bits(mbhc->component,
-				ROULEUR_ANA_MBHC_MCLK, 0x08, 0x00);
+				ROULEUR_ANA_MBHC_CTL_CLK, 0x08, 0x00);
 
 }
 
@@ -889,7 +826,7 @@
 	.mbhc_micb_ramp_control = rouleur_mbhc_micb_ramp_control,
 	.get_hwdep_fw_cal = rouleur_get_hwdep_fw_cal,
 	.mbhc_micb_ctrl_thr_mic = rouleur_mbhc_micb_ctrl_threshold_mic,
-	//.compute_impedance = rouleur_wcd_mbhc_calc_impedance,
+	.compute_impedance = rouleur_wcd_mbhc_calc_impedance,
 	.mbhc_gnd_det_ctrl = rouleur_mbhc_gnd_det_ctrl,
 	.hph_pull_down_ctrl = rouleur_mbhc_hph_pull_down_ctrl,
 	.mbhc_moisture_config = rouleur_mbhc_moisture_config,
diff --git a/asoc/codecs/rouleur/rouleur-registers.h b/asoc/codecs/rouleur/rouleur-registers.h
index 816e492..8cc0ae4 100644
--- a/asoc/codecs/rouleur/rouleur-registers.h
+++ b/asoc/codecs/rouleur/rouleur-registers.h
@@ -45,7 +45,7 @@
 #define ROULEUR_ANA_MBHC_ZDET_RAMP_CTL        (ROULEUR_ANA_BASE_ADDR+0x06A)
 #define ROULEUR_ANA_MBHC_FSM_STATUS           (ROULEUR_ANA_BASE_ADDR+0x06B)
 #define ROULEUR_ANA_MBHC_ADC_RESULT           (ROULEUR_ANA_BASE_ADDR+0x06C)
-#define ROULEUR_ANA_MBHC_MCLK                 (ROULEUR_ANA_BASE_ADDR+0x06D)
+#define ROULEUR_ANA_MBHC_CTL_CLK              (ROULEUR_ANA_BASE_ADDR+0x06D)
 #define ROULEUR_ANA_MBHC_ZDET_CALIB_RESULT    (ROULEUR_ANA_BASE_ADDR+0x072)
 #define ROULEUR_ANA_NCP_EN                    (ROULEUR_ANA_BASE_ADDR+0x077)
 #define ROULEUR_ANA_HPHPA_CNP_CTL_1           (ROULEUR_ANA_BASE_ADDR+0x083)
diff --git a/asoc/codecs/rouleur/rouleur-regmap.c b/asoc/codecs/rouleur/rouleur-regmap.c
index 08b490d..23b8ddc 100644
--- a/asoc/codecs/rouleur/rouleur-regmap.c
+++ b/asoc/codecs/rouleur/rouleur-regmap.c
@@ -38,7 +38,7 @@
 	{ ROULEUR_ANA_MBHC_ZDET_RAMP_CTL,         0x00 },
 	{ ROULEUR_ANA_MBHC_FSM_STATUS,            0x00 },
 	{ ROULEUR_ANA_MBHC_ADC_RESULT,            0x00 },
-	{ ROULEUR_ANA_MBHC_MCLK,                  0x30 },
+	{ ROULEUR_ANA_MBHC_CTL_CLK,               0x30 },
 	{ ROULEUR_ANA_MBHC_ZDET_CALIB_RESULT,     0x00 },
 	{ ROULEUR_ANA_NCP_EN,                     0x00 },
 	{ ROULEUR_ANA_HPHPA_CNP_CTL_1,            0x54 },
diff --git a/asoc/codecs/rouleur/rouleur-tables.c b/asoc/codecs/rouleur/rouleur-tables.c
index 59b7cf2..7912267 100644
--- a/asoc/codecs/rouleur/rouleur-tables.c
+++ b/asoc/codecs/rouleur/rouleur-tables.c
@@ -33,7 +33,7 @@
 	[ROULEUR_REG(ROULEUR_ANA_MBHC_ZDET_RAMP_CTL)] = RD_WR_REG,
 	[ROULEUR_REG(ROULEUR_ANA_MBHC_FSM_STATUS)] = RD_REG,
 	[ROULEUR_REG(ROULEUR_ANA_MBHC_ADC_RESULT)] = RD_REG,
-	[ROULEUR_REG(ROULEUR_ANA_MBHC_MCLK)] = RD_WR_REG,
+	[ROULEUR_REG(ROULEUR_ANA_MBHC_CTL_CLK)] = RD_WR_REG,
 	[ROULEUR_REG(ROULEUR_ANA_MBHC_ZDET_CALIB_RESULT)] = RD_REG,
 	[ROULEUR_REG(ROULEUR_ANA_NCP_EN)] = RD_WR_REG,
 	[ROULEUR_REG(ROULEUR_ANA_HPHPA_CNP_CTL_1)] = RD_WR_REG,
diff --git a/asoc/codecs/rouleur/rouleur.c b/asoc/codecs/rouleur/rouleur.c
index e1ecdba..480e0ce 100644
--- a/asoc/codecs/rouleur/rouleur.c
+++ b/asoc/codecs/rouleur/rouleur.c
@@ -304,7 +304,7 @@
 	return ret;
 }
 
-static int rouleur_global_mbias_enable(struct snd_soc_component *component)
+int rouleur_global_mbias_enable(struct snd_soc_component *component)
 {
 	struct rouleur_priv *rouleur = snd_soc_component_get_drvdata(component);
 
@@ -322,7 +322,7 @@
 	return 0;
 }
 
-static int rouleur_global_mbias_disable(struct snd_soc_component *component)
+int rouleur_global_mbias_disable(struct snd_soc_component *component)
 {
 	struct rouleur_priv *rouleur = snd_soc_component_get_drvdata(component);
 
@@ -472,7 +472,7 @@
 		}
 		snd_soc_component_update_bits(component,
 				ROULEUR_DIG_SWR_CDC_RX0_CTL,
-				0x7C, 0x7C);
+				0x80, 0x00);
 		snd_soc_component_update_bits(component,
 				ROULEUR_DIG_SWR_CDC_RX_GAIN_CTL,
 				0x04, 0x04);
@@ -486,6 +486,9 @@
 		snd_soc_component_update_bits(component,
 				ROULEUR_DIG_SWR_CDC_RX_GAIN_CTL,
 				0x04, 0x00);
+		snd_soc_component_update_bits(component,
+				ROULEUR_DIG_SWR_CDC_RX0_CTL,
+				0x80, 0x80);
 		if (rouleur->comp1_enable)
 			snd_soc_component_update_bits(component,
 					ROULEUR_DIG_SWR_CDC_COMP_CTL_0,
@@ -544,7 +547,7 @@
 		}
 		snd_soc_component_update_bits(component,
 				ROULEUR_DIG_SWR_CDC_RX1_CTL,
-				0x7C, 0x7C);
+				0x80, 0x00);
 		snd_soc_component_update_bits(component,
 				ROULEUR_DIG_SWR_CDC_RX_GAIN_CTL,
 				0x08, 0x08);
@@ -557,6 +560,9 @@
 		snd_soc_component_update_bits(component,
 				ROULEUR_DIG_SWR_CDC_RX_GAIN_CTL,
 				0x08, 0x00);
+		snd_soc_component_update_bits(component,
+				ROULEUR_DIG_SWR_CDC_RX1_CTL,
+				0x80, 0x80);
 		if (rouleur->comp2_enable)
 			snd_soc_component_update_bits(component,
 					ROULEUR_DIG_SWR_CDC_COMP_CTL_0,
@@ -583,7 +589,7 @@
 		rouleur_rx_clk_enable(component);
 		snd_soc_component_update_bits(component,
 				ROULEUR_DIG_SWR_CDC_RX0_CTL,
-				0x7C, 0x7C);
+				0x80, 0x00);
 		snd_soc_component_update_bits(component,
 				ROULEUR_DIG_SWR_CDC_RX_GAIN_CTL,
 				0x04, 0x04);
@@ -599,6 +605,9 @@
 		snd_soc_component_update_bits(component,
 				ROULEUR_DIG_SWR_CDC_RX_GAIN_CTL,
 				0x04, 0x00);
+		snd_soc_component_update_bits(component,
+				ROULEUR_DIG_SWR_CDC_RX0_CTL,
+				0x80, 0x80);
 
 		break;
 	};
diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c
index abd3106..26174dc 100644
--- a/asoc/codecs/wcd938x/wcd938x.c
+++ b/asoc/codecs/wcd938x/wcd938x.c
@@ -1377,8 +1377,7 @@
 		/* enable clock scaling */
 		snd_soc_component_update_bits(component,
 				WCD938X_DIGITAL_CDC_DMIC_CTL, 0x06, 0x06);
-		wcd938x_tx_connect_port(component, DMIC0 + (w->shift),
-					SWR_CLK_RATE_2P4MHZ, true);
+		wcd938x_tx_connect_port(component, DMIC0 + (w->shift), 0, true);
 		break;
 	case SND_SOC_DAPM_POST_PMD:
 		wcd938x_tx_connect_port(component, DMIC0 + (w->shift), 0,
diff --git a/asoc/codecs/wsa883x/internal.h b/asoc/codecs/wsa883x/internal.h
index 1863aac..83cef64 100644
--- a/asoc/codecs/wsa883x/internal.h
+++ b/asoc/codecs/wsa883x/internal.h
@@ -125,7 +125,6 @@
 	void *handle;
 	int (*register_notifier)(void *handle,
 				struct notifier_block *nblock, bool enable);
-	struct delayed_work vbat_work;
 	struct cdc_regulator *regulator;
 	int num_supplies;
 	struct regulator_bulk_data *supplies;
diff --git a/asoc/codecs/wsa883x/wsa883x.c b/asoc/codecs/wsa883x/wsa883x.c
index 9e25e53..8433185 100644
--- a/asoc/codecs/wsa883x/wsa883x.c
+++ b/asoc/codecs/wsa883x/wsa883x.c
@@ -36,11 +36,7 @@
 #define HIGH_TEMP_THRESHOLD 45
 #define TEMP_INVALID	0xFFFF
 #define WSA883X_TEMP_RETRY 3
-#define WSA883X_VBAT_TIMER_SEC    2
 
-static int wsa883x_vbat_timer_sec = WSA883X_VBAT_TIMER_SEC;
-module_param(wsa883x_vbat_timer_sec, int, 0664);
-MODULE_PARM_DESC(wsa883x_vbat_timer_sec, "timer for VBAT monitor polling");
 
 #define DRV_NAME "wsa-codec"
 
@@ -92,9 +88,10 @@
 	{WSA883X_DRE_CTL_0, 0xF0, 0x90},
 	{WSA883X_DRE_IDLE_DET_CTL, 0x10, 0x00},
 	{WSA883X_PDM_WD_CTL, 0x01, 0x01},
-	{WSA883X_CURRENT_LIMIT, 0x78, 0x40},
+	{WSA883X_CURRENT_LIMIT, 0x78, 0x20},
 	{WSA883X_DRE_CTL_0, 0x07, 0x02},
-	{WSA883X_VAGC_TIME, 0x03, 0x02},
+	{WSA883X_VAGC_TIME, 0x0F, 0x0F},
+	{WSA883X_VAGC_ATTN_LVL_3, 0x07, 0x02},
 	{WSA883X_VAGC_CTL, 0x01, 0x01},
 	{WSA883X_TAGC_CTL, 0x0E, 0x0A},
 	{WSA883X_TAGC_TIME, 0x0C, 0x0C},
@@ -985,24 +982,9 @@
 		/* Force remove group */
 		swr_remove_from_group(wsa883x->swr_slave,
 				      wsa883x->swr_slave->dev_num);
-		snd_soc_component_update_bits(component,
-				WSA883X_VBAT_ADC_FLT_CTL,
-				0x0E, 0x06);
-		snd_soc_component_update_bits(component,
-				WSA883X_VBAT_ADC_FLT_CTL,
-				0x01, 0x01);
-		schedule_delayed_work(&wsa883x->vbat_work,
-			msecs_to_jiffies(wsa883x_vbat_timer_sec * 1000));
 		set_bit(SPKR_STATUS, &wsa883x->status_mask);
 		break;
 	case SND_SOC_DAPM_PRE_PMD:
-		cancel_delayed_work_sync(&wsa883x->vbat_work);
-		snd_soc_component_update_bits(component,
-				WSA883X_VBAT_ADC_FLT_CTL,
-				0x01, 0x00);
-		snd_soc_component_update_bits(component,
-				WSA883X_VBAT_ADC_FLT_CTL,
-				0x0E, 0x00);
 		snd_soc_component_update_bits(component, WSA883X_PA_FSM_CTL,
 				0x01, 0x00);
 		wcd_disable_irq(&wsa883x->irq_info, WSA883X_IRQ_INT_PDM_WD);
@@ -1172,37 +1154,6 @@
 	return ret;
 }
 
-static void wsa883x_vbat_monitor_work(struct work_struct *work)
-{
-	struct wsa883x_priv *wsa883x;
-	struct delayed_work *dwork;
-	struct snd_soc_component *component;
-	u16 val = 0, vbat_code = 0;
-	int vbat_val = 0;
-
-	dwork = to_delayed_work(work);
-	wsa883x = container_of(dwork, struct wsa883x_priv, vbat_work);
-	component = wsa883x->component;
-
-	val = snd_soc_component_read32(component, WSA883X_VBAT_DIN_MSB);
-	vbat_code = (val << 2);
-	val = (snd_soc_component_read32(component, WSA883X_VBAT_DIN_LSB)
-		& 0xC0);
-	vbat_code |= (val >> 6);
-	vbat_val = ((vbat_code * 5) / 1023);
-	dev_dbg(component->dev, "%s: instant vbat code = %d val = %d\n",
-		__func__, vbat_code, vbat_val);
-
-	val = snd_soc_component_read32(component, WSA883X_VBAT_DOUT);
-	vbat_val = ((val * 5) / 255);
-
-	dev_dbg(component->dev, "%s: low pass vbat code = %d val = %d\n",
-		__func__, val, vbat_val);
-
-	schedule_delayed_work(&wsa883x->vbat_work,
-			msecs_to_jiffies(wsa883x_vbat_timer_sec * 1000));
-}
-
 static int wsa883x_codec_probe(struct snd_soc_component *component)
 {
 	struct wsa883x_priv *wsa883x = snd_soc_component_get_drvdata(component);
@@ -1226,7 +1177,6 @@
 
 	wsa883x_codec_init(component);
 	wsa883x->global_pa_cnt = 0;
-	INIT_DELAYED_WORK(&wsa883x->vbat_work, wsa883x_vbat_monitor_work);
 
 	return 0;
 }
@@ -1324,8 +1274,6 @@
 
 	switch (event) {
 	case BOLERO_WSA_EVT_PA_OFF_PRE_SSR:
-		if (delayed_work_pending(&wsa883x->vbat_work))
-			cancel_delayed_work_sync(&wsa883x->vbat_work);
 		snd_soc_component_update_bits(wsa883x->component,
 					WSA883X_PA_FSM_CTL,
 					0x01, 0x00);
diff --git a/asoc/msm-compress-q6-v2.c b/asoc/msm-compress-q6-v2.c
index fdf61cf..b34202c 100644
--- a/asoc/msm-compress-q6-v2.c
+++ b/asoc/msm-compress-q6-v2.c
@@ -225,7 +225,7 @@
 				     int stream_id);
 
 static int msm_compr_set_render_mode(struct msm_compr_audio *prtd,
-				     uint32_t render_mode) {
+				     uint32_t render_mode, int dir) {
 	int ret = -EINVAL;
 	struct audio_client *ac = prtd->audio_client;
 
@@ -250,7 +250,7 @@
 		goto exit;
 	}
 
-	ret = q6asm_send_mtmx_strtr_render_mode(ac, render_mode);
+	ret = q6asm_send_mtmx_strtr_render_mode(ac, render_mode, dir);
 	if (ret) {
 		pr_err("%s, Render mode can't be set error %d\n", __func__,
 			ret);
@@ -324,6 +324,29 @@
 	return ret;
 }
 
+static int msm_compr_set_ttp_offset(struct audio_client *ac,
+		uint32_t offset_lsw, uint32_t offset_msw, int dir)
+{
+	int ret = -EINVAL;
+	struct asm_session_mtmx_strtr_param_ttp_offset_t ttp_offset;
+	uint32_t param_id;
+
+	pr_debug("%s, ttp offset lsw 0x%x  ttp offset msw 0x%x\n",
+		 __func__, offset_lsw, offset_msw);
+
+	memset(&ttp_offset, 0,
+	       sizeof(struct asm_session_mtmx_strtr_param_ttp_offset_t));
+	ttp_offset.ttp_offset_lsw = offset_lsw;
+	ttp_offset.ttp_offset_msw = offset_msw;
+	param_id = ASM_SESSION_MTMX_STRTR_PARAM_TTP_OFFSET;
+	ret = q6asm_send_mtmx_strtr_ttp_offset(ac, &ttp_offset, param_id, dir);
+	if (ret)
+		pr_err("%s, ttp offset can't be set error %d\n", __func__,
+			ret);
+
+	return ret;
+}
+
 static int msm_compr_enable_adjust_session_clock(struct audio_client *ac,
 		bool enable)
 {
@@ -3221,7 +3244,8 @@
 			 __func__, metadata->value[0]);
 		prtd->gapless_state.initial_samples_drop = metadata->value[0];
 	} else if (metadata->key == SNDRV_COMPRESS_RENDER_MODE) {
-		return msm_compr_set_render_mode(prtd, metadata->value[0]);
+		return msm_compr_set_render_mode(prtd, metadata->value[0],
+				cstream->direction);
 	} else if (metadata->key == SNDRV_COMPRESS_CLK_REC_MODE) {
 		return msm_compr_set_clk_rec_mode(ac, metadata->value[0]);
 	} else if (metadata->key == SNDRV_COMPRESS_RENDER_WINDOW) {
@@ -3242,6 +3266,9 @@
 		return msm_compr_adjust_session_clock(ac,
 				metadata->value[0],
 				metadata->value[1]);
+	} else if (metadata->key == SNDRV_COMPRESS_IN_TTP_OFFSET) {
+		return msm_compr_set_ttp_offset(ac, metadata->value[0],
+				metadata->value[1], cstream->direction);
 	}
 
 	return 0;
diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c
index a0d9895..883d8d8 100644
--- a/asoc/msm-dai-q6-v2.c
+++ b/asoc/msm-dai-q6-v2.c
@@ -232,6 +232,7 @@
 	u16 afe_tx_out_bitformat;
 	struct afe_enc_config enc_config;
 	struct afe_dec_config dec_config;
+	struct afe_ttp_config ttp_config;
 	union afe_port_config port_config;
 	u16 vi_feed_mono;
 	u32 xt_logging_disable;
@@ -2230,6 +2231,7 @@
 {
 	struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev);
 	int rc = 0;
+	uint16_t ttp_gen_enable = dai_data->ttp_config.ttp_gen_enable.enable;
 
 	if (!test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
 		if (dai_data->enc_config.format != ENC_FMT_NONE) {
@@ -2279,13 +2281,27 @@
 				bitwidth = 0;
 				break;
 			}
-			pr_debug("%s: calling AFE_PORT_START_V2 with dec format: %d\n",
-				 __func__, dai_data->dec_config.format);
-			rc = afe_port_start_v2(dai->id, &dai_data->port_config,
-					       dai_data->rate,
-					       dai_data->afe_tx_out_channels,
-					       bitwidth,
-					       NULL, &dai_data->dec_config);
+
+			if (ttp_gen_enable == true) {
+				pr_debug("%s: calling AFE_PORT_START_V3 with dec format: %d\n",
+					 __func__, dai_data->dec_config.format);
+				rc = afe_port_start_v3(dai->id,
+						&dai_data->port_config,
+						dai_data->rate,
+						dai_data->afe_tx_out_channels,
+						bitwidth,
+						NULL, &dai_data->dec_config,
+						&dai_data->ttp_config);
+			} else {
+				pr_debug("%s: calling AFE_PORT_START_V2 with dec format: %d\n",
+					 __func__, dai_data->dec_config.format);
+				rc = afe_port_start_v2(dai->id,
+						&dai_data->port_config,
+						dai_data->rate,
+						dai_data->afe_tx_out_channels,
+						bitwidth,
+						NULL, &dai_data->dec_config);
+			}
 			if (rc < 0) {
 				pr_err("%s: fail to open AFE port 0x%x\n",
 					__func__, dai->id);
@@ -2795,7 +2811,6 @@
 	return rc;
 }
 
-/* all ports with excursion logging requirement can use this digital_mute api */
 static int msm_dai_q6_spk_digital_mute(struct snd_soc_dai *dai,
 				       int mute)
 {
@@ -3669,6 +3684,91 @@
 	return ret;
 }
 
+static int  msm_dai_q6_afe_enable_ttp_info(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_info *uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
+	uinfo->count = sizeof(struct afe_ttp_gen_enable_t);
+
+	return 0;
+}
+
+static int msm_dai_q6_afe_enable_ttp_get(struct snd_kcontrol *kcontrol,
+				      struct snd_ctl_elem_value *ucontrol)
+{
+	struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data;
+
+	pr_debug("%s:\n", __func__);
+	if (!dai_data) {
+		pr_err("%s: Invalid dai data\n", __func__);
+		return -EINVAL;
+	}
+
+	memcpy(ucontrol->value.bytes.data,
+	       &dai_data->ttp_config.ttp_gen_enable,
+	       sizeof(struct afe_ttp_gen_enable_t));
+	return 0;
+}
+
+static int msm_dai_q6_afe_enable_ttp_put(struct snd_kcontrol *kcontrol,
+				      struct snd_ctl_elem_value *ucontrol)
+{
+	struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data;
+
+	pr_debug("%s:\n", __func__);
+	if (!dai_data) {
+		pr_err("%s: Invalid dai data\n", __func__);
+		return -EINVAL;
+	}
+
+	memcpy(&dai_data->ttp_config.ttp_gen_enable,
+		ucontrol->value.bytes.data,
+		sizeof(struct afe_ttp_gen_enable_t));
+	return 0;
+}
+
+static int  msm_dai_q6_afe_ttp_cfg_info(struct snd_kcontrol *kcontrol,
+					struct snd_ctl_elem_info *uinfo)
+{
+	uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
+	uinfo->count = sizeof(struct afe_ttp_gen_cfg_t);
+
+	return 0;
+}
+
+static int msm_dai_q6_afe_ttp_cfg_get(struct snd_kcontrol *kcontrol,
+				      struct snd_ctl_elem_value *ucontrol)
+{
+	struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data;
+
+	pr_debug("%s:\n", __func__);
+	if (!dai_data) {
+		pr_err("%s: Invalid dai data\n", __func__);
+		return -EINVAL;
+	}
+
+	memcpy(ucontrol->value.bytes.data,
+	       &dai_data->ttp_config.ttp_gen_cfg,
+	       sizeof(struct afe_ttp_gen_cfg_t));
+	return 0;
+}
+
+static int msm_dai_q6_afe_ttp_cfg_put(struct snd_kcontrol *kcontrol,
+				      struct snd_ctl_elem_value *ucontrol)
+{
+	struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data;
+
+	pr_debug("%s: Received ttp config\n", __func__);
+	if (!dai_data) {
+		pr_err("%s: Invalid dai data\n", __func__);
+		return -EINVAL;
+	}
+
+	memcpy(&dai_data->ttp_config.ttp_gen_cfg,
+		ucontrol->value.bytes.data, sizeof(struct afe_ttp_gen_cfg_t));
+	return 0;
+}
+
 static const struct snd_kcontrol_new afe_dec_config_controls[] = {
 	{
 		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
@@ -3696,6 +3796,27 @@
 		     msm_dai_q6_afe_output_bit_format_put),
 };
 
+static const struct snd_kcontrol_new afe_ttp_config_controls[] = {
+	{
+		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
+			   SNDRV_CTL_ELEM_ACCESS_INACTIVE),
+		.iface = SNDRV_CTL_ELEM_IFACE_PCM,
+		.name = "TTP Enable",
+		.info = msm_dai_q6_afe_enable_ttp_info,
+		.get = msm_dai_q6_afe_enable_ttp_get,
+		.put = msm_dai_q6_afe_enable_ttp_put,
+	},
+	{
+		.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
+			   SNDRV_CTL_ELEM_ACCESS_INACTIVE),
+		.iface = SNDRV_CTL_ELEM_IFACE_PCM,
+		.name = "AFE TTP config",
+		.info = msm_dai_q6_afe_ttp_cfg_info,
+		.get = msm_dai_q6_afe_ttp_cfg_get,
+		.put = msm_dai_q6_afe_ttp_cfg_put,
+	},
+};
+
 static int msm_dai_q6_slim_rx_drift_info(struct snd_kcontrol *kcontrol,
 				    struct snd_ctl_elem_info *uinfo)
 {
@@ -3919,6 +4040,12 @@
 		rc = snd_ctl_add(dai->component->card->snd_card,
 				 snd_ctl_new1(&afe_dec_config_controls[3],
 				 dai_data));
+		rc = snd_ctl_add(dai->component->card->snd_card,
+				 snd_ctl_new1(&afe_ttp_config_controls[0],
+				 dai_data));
+		rc = snd_ctl_add(dai->component->card->snd_card,
+				 snd_ctl_new1(&afe_ttp_config_controls[1],
+				 dai_data));
 		break;
 	case RT_PROXY_DAI_001_RX:
 		rc = snd_ctl_add(dai->component->card->snd_card,
@@ -12337,7 +12464,8 @@
 static void msm_dai_q6_cdc_dma_shutdown(struct snd_pcm_substream *substream,
 				     struct snd_soc_dai *dai)
 {
-	struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev);
+	struct msm_dai_q6_cdc_dma_dai_data *dai_data =
+					dev_get_drvdata(dai->dev);
 	int rc = 0;
 
 	if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
@@ -12356,6 +12484,19 @@
 		clear_bit(STATUS_PORT_STARTED, dai_data->hwfree_status);
 }
 
+static int msm_dai_q6_cdc_dma_digital_mute(struct snd_soc_dai *dai,
+				       int mute)
+{
+	int port_id = dai->id;
+	struct msm_dai_q6_cdc_dma_dai_data *dai_data =
+					dev_get_drvdata(dai->dev);
+
+	if (mute && !dai_data->xt_logging_disable)
+		afe_get_sp_xt_logging_data(port_id);
+
+	return 0;
+}
+
 static struct snd_soc_dai_ops msm_dai_q6_cdc_dma_ops = {
 	.prepare          = msm_dai_q6_cdc_dma_prepare,
 	.hw_params        = msm_dai_q6_cdc_dma_hw_params,
@@ -12368,7 +12509,7 @@
 	.hw_params        = msm_dai_q6_cdc_dma_hw_params,
 	.shutdown         = msm_dai_q6_cdc_dma_shutdown,
 	.set_channel_map = msm_dai_q6_cdc_dma_set_channel_map,
-	.digital_mute = msm_dai_q6_spk_digital_mute,
+	.digital_mute = msm_dai_q6_cdc_dma_digital_mute,
 };
 
 static struct snd_soc_dai_driver msm_dai_q6_cdc_dma_dai[] = {
diff --git a/asoc/msm-lsm-client.c b/asoc/msm-lsm-client.c
index b6624f0..8a179fd 100644
--- a/asoc/msm-lsm-client.c
+++ b/asoc/msm-lsm-client.c
@@ -12,6 +12,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/of.h>
 #include <linux/freezer.h>
+#include <linux/version.h>
 #include <sound/core.h>
 #include <sound/soc.h>
 #include <sound/soc-dapm.h>
@@ -92,7 +93,7 @@
 	int xrun_count;
 	int xrun_index;
 	spinlock_t xrun_lock;
-	struct wakeup_source ws;
+	struct wakeup_source *ws;
 };
 
 enum { /* lsm session states */
@@ -220,7 +221,7 @@
 	}
 	rtd = substream->private_data;
 
-	pm_wakeup_ws_event(&prtd->ws, WAKELOCK_TIMEOUT, true);
+	pm_wakeup_ws_event(prtd->ws, WAKELOCK_TIMEOUT, true);
 	dev_dbg(rtd->dev, "%s: opcode %x\n", __func__, opcode);
 	switch (opcode) {
 	case LSM_DATA_EVENT_READ_DONE: {
@@ -235,13 +236,13 @@
 				"%s: EVENT_READ_DONE invalid callback, session %d callback %d payload %pK",
 				__func__, prtd->lsm_client->session,
 				token, read_done);
-			__pm_relax(&prtd->ws);
+			__pm_relax(prtd->ws);
 			return;
 		}
 		if (atomic_read(&prtd->read_abort)) {
 			dev_dbg(rtd->dev,
 				"%s: read abort set skip data\n", __func__);
-			__pm_relax(&prtd->ws);
+			__pm_relax(prtd->ws);
 			return;
 		}
 		if (!lsm_lab_buffer_sanity(prtd, read_done, &buf_index)) {
@@ -254,7 +255,7 @@
 					"%s: Invalid index %d buf_index max cnt %d\n",
 					__func__, buf_index,
 				prtd->lsm_client->out_hw_params.period_count);
-				__pm_relax(&prtd->ws);
+				__pm_relax(prtd->ws);
 				return;
 			}
 			spin_lock_irqsave(&prtd->xrun_lock, flags);
@@ -292,7 +293,7 @@
 			dev_err(rtd->dev,
 					"%s: client_size has invalid size[%d]\n",
 					__func__, client_size);
-			__pm_relax(&prtd->ws);
+			__pm_relax(prtd->ws);
 			return;
 		}
 		status = (uint16_t)((uint8_t *)payload)[0];
@@ -308,7 +309,7 @@
 			dev_err(rtd->dev,
 					"%s: client_size has invalid size[%d]\n",
 					__func__, client_size);
-			__pm_relax(&prtd->ws);
+			__pm_relax(prtd->ws);
 			return;
 		}
 		status = (uint16_t)((uint8_t *)payload)[0];
@@ -324,7 +325,7 @@
 			dev_err(rtd->dev,
 					"%s: client_size has invalid size[%d]\n",
 					__func__, client_size);
-			__pm_relax(&prtd->ws);
+			__pm_relax(prtd->ws);
 			return;
 		}
 		event_ts_lsw = ((uint32_t *)payload)[0];
@@ -344,7 +345,7 @@
 			dev_err(rtd->dev,
 					"%s: client_size has invalid size[%d]\n",
 					__func__, client_size);
-			__pm_relax(&prtd->ws);
+			__pm_relax(prtd->ws);
 			return;
 		}
 
@@ -364,7 +365,7 @@
 				"LSM_SESSION_DETECTION_ENGINE_GENERIC_EVENT",
 				sizeof(struct snd_lsm_event_status) +
 				payload_size);
-			__pm_relax(&prtd->ws);
+			__pm_relax(prtd->ws);
 			return;
 		}
 
@@ -379,7 +380,7 @@
 			dev_err(rtd->dev,
 				"%s: Failed to copy memory with invalid size = %d\n",
 				__func__, payload_size);
-			__pm_relax(&prtd->ws);
+			__pm_relax(prtd->ws);
 			return;
 		}
 		prtd->event_avail = 1;
@@ -411,7 +412,7 @@
 		if (!temp) {
 			dev_err(rtd->dev, "%s: no memory for event status\n",
 				__func__);
-			__pm_relax(&prtd->ws);
+			__pm_relax(prtd->ws);
 			return;
 		}
 		/*
@@ -438,7 +439,7 @@
 				dev_err(rtd->dev,
 						"%s: Failed to copy memory with invalid size = %d\n",
 						__func__, payload_size);
-				__pm_relax(&prtd->ws);
+				__pm_relax(prtd->ws);
 				return;
 			}
 		} else {
@@ -1156,7 +1157,7 @@
 			dev_err(rtd->dev,
 				"%s: lsm open failed, %d\n",
 				__func__, ret);
-			__pm_relax(&prtd->ws);
+			__pm_relax(prtd->ws);
 			return ret;
 		}
 		prtd->lsm_client->opened = true;
@@ -1504,14 +1505,14 @@
 		if (prtd->lsm_client->num_stages > 1) {
 			dev_err(rtd->dev, "%s: %s: not supported for multi stage session\n",
 				__func__, "LSM_LAB_CONTROL");
-			__pm_relax(&prtd->ws);
+			__pm_relax(prtd->ws);
 			return -EINVAL;
 		}
 
 		if (copy_from_user(&enable, arg, sizeof(enable))) {
 			dev_err(rtd->dev, "%s: %s: copy_frm_user failed\n",
 				__func__, "LSM_LAB_CONTROL");
-			__pm_relax(&prtd->ws);
+			__pm_relax(prtd->ws);
 			return -EFAULT;
 		}
 
@@ -1566,7 +1567,7 @@
 		if (copy_from_user(&mode, arg, sizeof(mode))) {
 			dev_err(rtd->dev, "%s: %s: copy_frm_user failed\n",
 				__func__, "LSM_SET_FWK_MODE_CONFIG");
-			__pm_relax(&prtd->ws);
+			__pm_relax(prtd->ws);
 			return -EFAULT;
 		}
 
@@ -1597,7 +1598,7 @@
 		if (copy_from_user(&params, arg, sizeof(params))) {
 			dev_err(rtd->dev, "%s: %s: copy_from_user failed\n",
 				__func__, "LSM_SET_INPUT_HW_PARAMS");
-			__pm_relax(&prtd->ws);
+			__pm_relax(prtd->ws);
 			return -EFAULT;
 		}
 
@@ -1624,7 +1625,7 @@
 		dev_err(rtd->dev, "%s: cmd 0x%x failed %d\n",
 			__func__, cmd, rc);
 
-	__pm_relax(&prtd->ws);
+	__pm_relax(prtd->ws);
 	return rc;
 }
 
@@ -2528,8 +2529,11 @@
 	prtd->lsm_client->event_type = LSM_DET_EVENT_TYPE_LEGACY;
 	prtd->lsm_client->fe_id = rtd->dai_link->id;
 	prtd->lsm_client->unprocessed_data = 0;
-
-	wakeup_source_init(&prtd->ws, "lsm-client");
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 110))
+	prtd->ws = wakeup_source_register(rtd->dev, "lsm-client");
+#else
+	prtd->ws = wakeup_source_register("lsm-client");
+#endif
 	return 0;
 }
 
@@ -2774,7 +2778,7 @@
 
 	q6lsm_client_free(prtd->lsm_client);
 
-	wakeup_source_trash(&prtd->ws);
+	wakeup_source_unregister(prtd->ws);
 	spin_lock_irqsave(&prtd->event_lock, flags);
 	kfree(prtd->event_status);
 	prtd->event_status = NULL;
diff --git a/asoc/msm-transcode-loopback-q6-v2.c b/asoc/msm-transcode-loopback-q6-v2.c
index e20f0df..bba4ad7 100644
--- a/asoc/msm-transcode-loopback-q6-v2.c
+++ b/asoc/msm-transcode-loopback-q6-v2.c
@@ -613,7 +613,7 @@
 }
 
 static int msm_transcode_set_render_mode(struct msm_transcode_loopback *prtd,
-					 uint32_t render_mode)
+					 uint32_t render_mode, int dir)
 {
 	int ret = -EINVAL;
 	struct audio_client *ac = prtd->audio_client;
@@ -639,7 +639,7 @@
 		goto exit;
 	}
 
-	ret = q6asm_send_mtmx_strtr_render_mode(ac, render_mode);
+	ret = q6asm_send_mtmx_strtr_render_mode(ac, render_mode, dir);
 	if (ret) {
 		pr_err("%s: Render mode can't be set error %d\n", __func__,
 			ret);
@@ -705,7 +705,8 @@
 	}
 	case SNDRV_COMPRESS_RENDER_MODE:
 	{
-		rc = msm_transcode_set_render_mode(prtd, metadata->value[0]);
+		rc = msm_transcode_set_render_mode(prtd, metadata->value[0],
+						   cstream->direction);
 		if (rc)
 			pr_err("%s: error setting render mode %d\n", __func__,
 				rc);
diff --git a/config/litoauto.conf b/config/litoauto.conf
index d0030bb..ecf848c 100644
--- a/config/litoauto.conf
+++ b/config/litoauto.conf
@@ -38,3 +38,6 @@
 CONFIG_SND_SOC_WCD937X_SLAVE=m
 CONFIG_SND_SOC_LITO=m
 CONFIG_SND_EVENT=m
+CONFIG_MI2S_DISABLE=m
+CONFIG_TDM_DISABLE=m
+CONFIG_AUXPCM_DISABLE=m
diff --git a/config/litoautoconf.h b/config/litoautoconf.h
index 322ac73..3c979cc 100644
--- a/config/litoautoconf.h
+++ b/config/litoautoconf.h
@@ -42,3 +42,6 @@
 #define CONFIG_SND_SOC_WCD937X_SLAVE 1
 #define CONFIG_SND_SOC_LITO 1
 #define CONFIG_SND_EVENT 1
+#define CONFIG_MI2S_DISABLE 1
+#define CONFIG_TDM_DISABLE 1
+#define CONFIG_AUXPCM_DISABLE 1
diff --git a/dsp/codecs/audio_utils.c b/dsp/codecs/audio_utils.c
index ac93413..33495b2 100644
--- a/dsp/codecs/audio_utils.c
+++ b/dsp/codecs/audio_utils.c
@@ -936,6 +936,7 @@
 
 int audio_in_release(struct inode *inode, struct file *file)
 {
+	unsigned long flags = 0;
 	struct q6audio_in  *audio = file->private_data;
 
 	pr_info("%s: session id %d\n", __func__, audio->ac->session);
@@ -943,11 +944,11 @@
 	audio_in_disable(audio);
 	q6asm_audio_client_free(audio->ac);
 	mutex_unlock(&audio->lock);
-	spin_lock(&enc_dec_lock);
+	spin_lock_irqsave(&enc_dec_lock, flags);
 	kfree(audio->enc_cfg);
 	kfree(audio->codec_cfg);
 	kfree(audio);
 	file->private_data = NULL;
-	spin_unlock(&enc_dec_lock);
+	spin_unlock_irqrestore(&enc_dec_lock, flags);
 	return 0;
 }
diff --git a/dsp/codecs/audio_utils_aio.c b/dsp/codecs/audio_utils_aio.c
index 93095e3..94be57d 100644
--- a/dsp/codecs/audio_utils_aio.c
+++ b/dsp/codecs/audio_utils_aio.c
@@ -588,6 +588,7 @@
 
 int audio_aio_release(struct inode *inode, struct file *file)
 {
+	unsigned long flags = 0;
 	struct q6audio_aio *audio = file->private_data;
 
 	pr_debug("%s[%pK]\n", __func__, audio);
@@ -631,11 +632,11 @@
 #ifdef CONFIG_DEBUG_FS
 	debugfs_remove(audio->dentry);
 #endif
-	spin_lock(&enc_dec_lock);
+	spin_lock_irqsave(&enc_dec_lock, flags);
 	kfree(audio->codec_cfg);
 	kfree(audio);
 	file->private_data = NULL;
-	spin_unlock(&enc_dec_lock);
+	spin_unlock_irqrestore(&enc_dec_lock, flags);
 	mutex_unlock(&lock);
 	return 0;
 }
diff --git a/dsp/codecs/q6audio_v2.c b/dsp/codecs/q6audio_v2.c
index 6a402f5..51ff850 100644
--- a/dsp/codecs/q6audio_v2.c
+++ b/dsp/codecs/q6audio_v2.c
@@ -20,8 +20,9 @@
 {
 	struct q6audio_in *audio = (struct q6audio_in *)priv;
 	unsigned long flags;
+	unsigned long en_de_flags;
 
-	spin_lock(&enc_dec_lock);
+	spin_lock_irqsave(&enc_dec_lock, en_de_flags);
 	if (audio == NULL) {
 		pr_err("%s: failed to get q6audio value\n", __func__);
 		goto error;
@@ -64,7 +65,7 @@
 	}
 	spin_unlock_irqrestore(&audio->dsp_lock, flags);
 error:
-	spin_unlock(&enc_dec_lock);
+	spin_unlock_irqrestore(&enc_dec_lock, en_de_flags);
 }
 
 void  audio_in_get_dsp_frames(void *priv,
diff --git a/dsp/codecs/q6audio_v2_aio.c b/dsp/codecs/q6audio_v2_aio.c
index ecd14da..d9dd29b 100644
--- a/dsp/codecs/q6audio_v2_aio.c
+++ b/dsp/codecs/q6audio_v2_aio.c
@@ -42,8 +42,9 @@
 {
 	struct q6audio_aio *audio = (struct q6audio_aio *)priv;
 	union msm_audio_event_payload e_payload;
+	unsigned long flags = 0;
 
-	spin_lock(&enc_dec_lock);
+	spin_lock_irqsave(&enc_dec_lock, flags);
 	if (audio == NULL) {
 		pr_err("%s: failed to get q6audio value\n", __func__);
 		goto error;
@@ -113,7 +114,7 @@
 		break;
 	}
 error:
-	spin_unlock(&enc_dec_lock);
+	spin_unlock_irqrestore(&enc_dec_lock, flags);
 }
 
 int extract_meta_out_info(struct q6audio_aio *audio,
diff --git a/dsp/q6afe.c b/dsp/q6afe.c
index 2586bd5..9d5908d 100644
--- a/dsp/q6afe.c
+++ b/dsp/q6afe.c
@@ -10,6 +10,7 @@
 #include <linux/jiffies.h>
 #include <linux/sched.h>
 #include <linux/delay.h>
+#include <linux/version.h>
 #include <dsp/msm_audio_ion.h>
 #include <dsp/apr_audio-v2.h>
 #include <dsp/audio_cal_utils.h>
@@ -98,7 +99,7 @@
 };
 
 struct wlock {
-	struct wakeup_source ws;
+	struct wakeup_source *ws;
 };
 
 static struct wlock wl;
@@ -3924,6 +3925,51 @@
 	return ret;
 }
 
+static int q6afe_send_ttp_config(u16 port_id,
+			union afe_port_config afe_config,
+			struct afe_ttp_config *ttp_cfg)
+{
+	struct afe_ttp_gen_enable_t ttp_gen_enable;
+	struct afe_ttp_gen_cfg_t ttp_gen_cfg;
+	struct param_hdr_v3 param_hdr;
+	int ret;
+
+	memset(&ttp_gen_enable, 0, sizeof(ttp_gen_enable));
+	memset(&ttp_gen_cfg, 0, sizeof(ttp_gen_cfg));
+	memset(&param_hdr, 0, sizeof(param_hdr));
+
+	param_hdr.module_id = AFE_MODULE_ID_DECODER;
+	param_hdr.instance_id = INSTANCE_ID_0;
+
+	pr_debug("%s: Enable TTP generator\n", __func__);
+	ttp_gen_enable = ttp_cfg->ttp_gen_enable;
+	param_hdr.param_id = AVS_DEPACKETIZER_PARAM_ID_TTP_GEN_STATE;
+	param_hdr.param_size = sizeof(struct afe_ttp_gen_enable_t);
+	ret = q6afe_pack_and_set_param_in_band(port_id,
+					       q6audio_get_port_index(port_id),
+					       param_hdr,
+					       (u8 *) &ttp_gen_enable);
+	if (ret) {
+		pr_err("%s: AVS_DEPACKETIZER_PARAM_ID_TTP_GEN_STATE for port 0x%x failed %d\n",
+			__func__, port_id, ret);
+		goto exit;
+	}
+
+	pr_debug("%s: sending TTP generator config\n", __func__);
+	ttp_gen_cfg = ttp_cfg->ttp_gen_cfg;
+	param_hdr.param_id = AVS_DEPACKETIZER_PARAM_ID_TTP_GEN_CFG;
+	param_hdr.param_size = sizeof(struct afe_ttp_gen_cfg_t);
+	ret = q6afe_pack_and_set_param_in_band(port_id,
+					       q6audio_get_port_index(port_id),
+					       param_hdr,
+					       (u8 *) &ttp_gen_cfg);
+	if (ret)
+		pr_err("%s: AVS_DEPACKETIZER_PARAM_ID_TTP_GEN_CFG for port 0x%x failed %d\n",
+			__func__, port_id, ret);
+exit:
+	return ret;
+}
+
 static int q6afe_send_dec_config(u16 port_id,
 			union afe_port_config afe_config,
 			struct afe_dec_config *cfg,
@@ -4594,7 +4640,8 @@
 			    u32 rate, u16 afe_in_channels, u16 afe_in_bit_width,
 			    union afe_enc_config_data *enc_cfg,
 			    u32 codec_format, u32 scrambler_mode, u32 mono_mode,
-			    struct afe_dec_config *dec_cfg)
+			    struct afe_dec_config *dec_cfg,
+			    struct afe_ttp_config *ttp_cfg)
 {
 	union afe_port_config port_cfg;
 	struct param_hdr_v3 param_hdr;
@@ -4912,6 +4959,15 @@
 				goto fail_cmd;
 			}
 		}
+		if (ttp_cfg != NULL) {
+			ret = q6afe_send_ttp_config(port_id, *afe_config,
+						    ttp_cfg);
+			if (ret) {
+				pr_err("%s: AFE TTP config for port 0x%x failed %d\n",
+					 __func__, port_id, ret);
+				goto fail_cmd;
+			}
+		}
 	}
 
 	port_index = afe_get_port_index(port_id);
@@ -4958,8 +5014,8 @@
 int afe_port_start(u16 port_id, union afe_port_config *afe_config,
 		   u32 rate)
 {
-	return __afe_port_start(port_id, afe_config, rate,
-				0, 0, NULL, ASM_MEDIA_FMT_NONE, 0, 0, NULL);
+	return __afe_port_start(port_id, afe_config, rate, 0, 0, NULL,
+				ASM_MEDIA_FMT_NONE, 0, 0, NULL, NULL);
 }
 EXPORT_SYMBOL(afe_port_start);
 
@@ -4989,16 +5045,50 @@
 					afe_in_channels, afe_in_bit_width,
 					&enc_cfg->data, enc_cfg->format,
 					enc_cfg->scrambler_mode,
-					enc_cfg->mono_mode, dec_cfg);
+					enc_cfg->mono_mode, dec_cfg, NULL);
 	else if (dec_cfg != NULL)
 		ret = __afe_port_start(port_id, afe_config, rate,
 					afe_in_channels, afe_in_bit_width,
-					NULL, dec_cfg->format, 0, 0, dec_cfg);
+					NULL, dec_cfg->format, 0, 0,
+					dec_cfg, NULL);
 
 	return ret;
 }
 EXPORT_SYMBOL(afe_port_start_v2);
 
+/**
+ * afe_port_start_v3 - to configure AFE session with
+ * specified port configuration and encoder /decoder params
+ *
+ * @port_id: AFE port id number
+ * @afe_config: port configuration
+ * @rate: sampling rate of port
+ * @enc_cfg: AFE enc configuration information to setup encoder
+ * @afe_in_channels: AFE input channel configuration, this needs
+ *  update only if input channel is differ from AFE output
+ * @dec_cfg: AFE dec configuration information to set up decoder
+ * @ttp_cfg: TTP generator configuration to enable TTP in AFE
+ *
+ * Returns 0 on success or error value on port start failure.
+ */
+int afe_port_start_v3(u16 port_id, union afe_port_config *afe_config,
+		      u32 rate, u16 afe_in_channels, u16 afe_in_bit_width,
+		      struct afe_enc_config *enc_cfg,
+		      struct afe_dec_config *dec_cfg,
+		      struct afe_ttp_config *ttp_cfg)
+{
+	int ret = 0;
+
+	if (dec_cfg != NULL && ttp_cfg != NULL)
+		ret = __afe_port_start(port_id, afe_config, rate,
+				       afe_in_channels, afe_in_bit_width,
+				       NULL, dec_cfg->format, 0, 0,
+				       dec_cfg, ttp_cfg);
+
+	return ret;
+}
+EXPORT_SYMBOL(afe_port_start_v3);
+
 int afe_get_port_index(u16 port_id)
 {
 	switch (port_id) {
@@ -8960,7 +9050,7 @@
 		goto done;
 
 	if (cal_data->cal_info.mode == MSM_SPKR_PROT_CALIBRATION_IN_PROGRESS)
-		__pm_wakeup_event(&wl.ws, jiffies_to_msecs(WAKELOCK_TIMEOUT));
+		__pm_wakeup_event(wl.ws, jiffies_to_msecs(WAKELOCK_TIMEOUT));
 	mutex_lock(&this_afe.cal_data[AFE_FB_SPKR_PROT_CAL]->lock);
 	memcpy(&this_afe.prot_cfg, &cal_data->cal_info,
 		sizeof(this_afe.prot_cfg));
@@ -9166,7 +9256,7 @@
 	}
 	this_afe.initial_cal = 0;
 	mutex_unlock(&this_afe.cal_data[AFE_FB_SPKR_PROT_CAL]->lock);
-	__pm_relax(&wl.ws);
+	__pm_relax(wl.ws);
 done:
 	return ret;
 }
@@ -9464,7 +9554,6 @@
 	init_waitqueue_head(&this_afe.wait_wakeup);
 	init_waitqueue_head(&this_afe.lpass_core_hw_wait);
 	init_waitqueue_head(&this_afe.clk_wait);
-	wakeup_source_init(&wl.ws, "spkr-prot");
 	ret = afe_init_cal_data();
 	if (ret)
 		pr_err("%s: could not init cal data! %d\n", __func__, ret);
@@ -9474,8 +9563,12 @@
 	this_afe.uevent_data = kzalloc(sizeof(*(this_afe.uevent_data)), GFP_KERNEL);
 	if (!this_afe.uevent_data)
 		return -ENOMEM;
-
-	/*
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 110))
+	wl.ws = wakeup_source_register(NULL, "spkr-prot");
+#else
+	wl.ws = wakeup_source_register("spkr-prot");
+#endif
+/*
 	 * Set release function to cleanup memory related to kobject
 	 * before initializing the kobject.
 	 */
@@ -9509,7 +9602,7 @@
 	mutex_destroy(&this_afe.afe_cmd_lock);
 	mutex_destroy(&this_afe.afe_apr_lock);
 	mutex_destroy(&this_afe.afe_clk_lock);
-	wakeup_source_trash(&wl.ws);
+	wakeup_source_unregister(wl.ws);
 }
 
 /*
diff --git a/dsp/q6asm.c b/dsp/q6asm.c
index fef09c5..e56c7c5 100644
--- a/dsp/q6asm.c
+++ b/dsp/q6asm.c
@@ -10048,16 +10048,105 @@
 EXPORT_SYMBOL(q6asm_send_mtmx_strtr_window);
 
 /**
+ * q6asm_send_mtmx_strtr_ttp_offset -
+ *       command to send matrix for ttp offset
+ *
+ * @ac: Audio client handle
+ * @ttp_offset: ttp offset params
+ * @param_id: param id for ttp offset
+ * @dir: RX or TX direction
+ *
+ * Returns 0 on success or error on failure
+ */
+int q6asm_send_mtmx_strtr_ttp_offset(struct audio_client *ac,
+		struct asm_session_mtmx_strtr_param_ttp_offset_t *ttp_offset,
+		uint32_t param_id, int dir)
+{
+	struct asm_mtmx_strtr_params matrix;
+	int sz = 0;
+	int rc  = 0;
+
+	pr_debug("%s: ttp offset lsw is %d, ttp offset msw is %d\n", __func__,
+		  ttp_offset->ttp_offset_lsw, ttp_offset->ttp_offset_msw);
+
+	if (!ac) {
+		pr_err("%s: audio client handle is NULL\n", __func__);
+		rc = -EINVAL;
+		goto fail_cmd;
+	}
+
+	if (ac->apr == NULL) {
+		pr_err("%s: ac->apr is NULL", __func__);
+		rc = -EINVAL;
+		goto fail_cmd;
+	}
+
+	memset(&matrix, 0, sizeof(struct asm_mtmx_strtr_params));
+	sz = sizeof(struct asm_mtmx_strtr_params);
+	q6asm_add_hdr(ac, &matrix.hdr, sz, TRUE);
+	atomic_set(&ac->cmd_state, -1);
+	matrix.hdr.opcode = ASM_SESSION_CMD_SET_MTMX_STRTR_PARAMS_V2;
+
+	matrix.param.data_payload_addr_lsw = 0;
+	matrix.param.data_payload_addr_msw = 0;
+	matrix.param.mem_map_handle = 0;
+	matrix.param.data_payload_size =
+		sizeof(struct param_hdr_v1) +
+		sizeof(struct asm_session_mtmx_strtr_param_ttp_offset_t);
+	matrix.param.direction = dir;
+	matrix.data.module_id = ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC;
+	matrix.data.param_id = param_id;
+	matrix.data.param_size =
+		sizeof(struct asm_session_mtmx_strtr_param_ttp_offset_t);
+	matrix.data.reserved = 0;
+	memcpy(&(matrix.config.ttp_offset),
+	       ttp_offset,
+	       sizeof(struct asm_session_mtmx_strtr_param_ttp_offset_t));
+
+	rc = apr_send_pkt(ac->apr, (uint32_t *) &matrix);
+	if (rc < 0) {
+		pr_err("%s: ttp offset send failed paramid [0x%x]\n",
+			__func__, matrix.data.param_id);
+		rc = -EINVAL;
+		goto fail_cmd;
+	}
+
+	rc = wait_event_timeout(ac->cmd_wait,
+			(atomic_read(&ac->cmd_state) >= 0),
+			msecs_to_jiffies(TIMEOUT_MS));
+	if (!rc) {
+		pr_err("%s: timeout, ttp offset paramid[0x%x]\n",
+			__func__, matrix.data.param_id);
+		rc = -ETIMEDOUT;
+		goto fail_cmd;
+	}
+
+	if (atomic_read(&ac->cmd_state) > 0) {
+		pr_err("%s: DSP returned error[%s]\n",
+				__func__, adsp_err_get_err_str(
+				atomic_read(&ac->cmd_state)));
+		rc = adsp_err_get_lnx_err_code(
+				atomic_read(&ac->cmd_state));
+		goto fail_cmd;
+	}
+	rc = 0;
+fail_cmd:
+	return rc;
+}
+EXPORT_SYMBOL(q6asm_send_mtmx_strtr_ttp_offset);
+
+/**
  * q6asm_send_mtmx_strtr_render_mode -
  *       command to send matrix for render mode
  *
  * @ac: Audio client handle
  * @render_mode: rendering mode
+ * @dir: RX or TX direction
  *
  * Returns 0 on success or error on failure
  */
 int q6asm_send_mtmx_strtr_render_mode(struct audio_client *ac,
-		uint32_t render_mode)
+		uint32_t render_mode, int dir)
 {
 	struct asm_mtmx_strtr_params matrix;
 	struct asm_session_mtmx_strtr_param_render_mode_t render_param;
@@ -10101,7 +10190,7 @@
 	matrix.param.data_payload_size =
 		sizeof(struct param_hdr_v1) +
 		sizeof(struct asm_session_mtmx_strtr_param_render_mode_t);
-	matrix.param.direction = 0; /* RX */
+	matrix.param.direction = dir;
 	matrix.data.module_id = ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC;
 	matrix.data.param_id = ASM_SESSION_MTMX_STRTR_PARAM_RENDER_MODE_CMD;
 	matrix.data.param_size =
diff --git a/dsp/usf.c b/dsp/usf.c
index e408c7d..d0f6ed3 100644
--- a/dsp/usf.c
+++ b/dsp/usf.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2017, 2020, The Linux Foundation. All rights reserved.
  */
 
 #include <linux/compat.h>
@@ -15,6 +15,7 @@
 #include <linux/time.h>
 #include <linux/kmemleak.h>
 #include <linux/mutex.h>
+#include <linux/version.h>
 #include <dsp/apr_audio-v2.h>
 #include "q6usm.h"
 #include "usf.h"
@@ -173,7 +174,7 @@
 /* The opened devices container */
 static atomic_t s_opened_devs[MAX_DEVS_NUMBER];
 
-static struct wakeup_source usf_wakeup_source;
+static struct wakeup_source *usf_wakeup_source;
 
 #define USF_NAME_PREFIX "usf_"
 #define USF_NAME_PREFIX_SIZE 4
@@ -442,7 +443,7 @@
 	case Q6USM_EVENT_READ_DONE:
 		pr_debug("%s: acquiring %d msec wake lock\n", __func__,
 				STAY_AWAKE_AFTER_READ_MSECS);
-		__pm_wakeup_event(&usf_wakeup_source,
+		__pm_wakeup_event(usf_wakeup_source,
 				  STAY_AWAKE_AFTER_READ_MSECS);
 		if (token == USM_WRONG_TOKEN)
 			usf_xx->usf_state = USF_ERROR_STATE;
@@ -2369,8 +2370,11 @@
 	usf = kzalloc(sizeof(struct usf_type), GFP_KERNEL);
 	if (usf == NULL)
 		return -ENOMEM;
-
-	wakeup_source_init(&usf_wakeup_source, "usf");
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 110))
+	usf_wakeup_source = wakeup_source_register(NULL, "usf");
+#else
+	usf_wakeup_source = wakeup_source_register("usf");
+#endif
 
 	file->private_data = usf;
 	usf->dev_ind = dev_ind;
@@ -2401,7 +2405,7 @@
 
 	atomic_set(&s_opened_devs[usf->dev_ind], 0);
 
-	wakeup_source_trash(&usf_wakeup_source);
+	wakeup_source_unregister(usf_wakeup_source);
 	mutex_unlock(&usf->mutex);
 	mutex_destroy(&usf->mutex);
 	kfree(usf);
diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h
index 311c892..6814646 100644
--- a/include/dsp/apr_audio-v2.h
+++ b/include/dsp/apr_audio-v2.h
@@ -4732,6 +4732,56 @@
 	union afe_enc_config_data data;
 };
 
+/*
+ * Enable TTP generator in AFE.
+ */
+#define AVS_DEPACKETIZER_PARAM_ID_TTP_GEN_STATE         0x000132EF
+/*
+ * Configure TTP generator params in AFE.
+ */
+#define AVS_DEPACKETIZER_PARAM_ID_TTP_GEN_CFG           0x000132F0
+#define MAX_TTP_OFFSET_PAIRS  4
+struct afe_ttp_gen_enable_t {
+	uint16_t enable;
+	uint16_t reserved;
+} __packed;
+
+struct afe_ttp_ssrc_offset_pair_t {
+	uint32_t ssrc;
+	uint32_t offset;
+} __packed;
+
+struct afe_ttp_gen_cfg_t {
+	uint32_t ttp_offset_default;
+	/*
+	 * TTP offset uses for all other cases
+	 * where no valid SSRC is received.
+	 */
+	uint32_t settling_time;
+	/*
+	 * If settling_mode==0x00: time in [us]
+	 * after first received packet until
+	 * packets are no longer dropped.
+	 */
+	uint16_t settling_mode;
+	/*
+	 * 0x00(Drop), 0x01(Settle)
+	 */
+	uint16_t num_ssrc_offsets;
+	/*
+	 * Number of SSRC/TTPOFFSET pairs to follow
+	 */
+	struct afe_ttp_ssrc_offset_pair_t ssrc_ttp_offset[MAX_TTP_OFFSET_PAIRS];
+	/*
+	 * Array of ssrc/offset pairs
+	 */
+} __packed;
+
+struct afe_ttp_config {
+	struct afe_ttp_gen_enable_t ttp_gen_enable;
+	struct afe_ttp_gen_cfg_t ttp_gen_cfg;
+};
+
 union afe_dec_config_data {
 	struct asm_sbc_dec_cfg_t sbc_config;
 	struct asm_aac_dec_cfg_v2_t aac_config;
@@ -12348,6 +12398,12 @@
  */
 #define ASM_SESSION_MTMX_STRTR_PARAM_RENDER_WINDOW_END_V2   0x00010DD2
 
+/* Parameter used by #ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC to specify the
+ * ttp offset value. This parameter is supported only for a Set
+ * command (not a Get command) in the Tx direction
+ */
+#define ASM_SESSION_MTMX_STRTR_PARAM_TTP_OFFSET 0x00013228
+
 /* Generic payload of the window parameters in the
  * #ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC module.
  * This payload is supported only for a Set command
@@ -12456,6 +12512,26 @@
 	u32                  flags;
 } __packed;
 
+struct asm_session_mtmx_strtr_param_ttp_offset_t {
+	uint32_t                  ttp_offset_lsw;
+	/* Lower 32 bits of the ttp_offset in microseconds. */
+
+	uint32_t                  ttp_offset_msw;
+	/* Upper 32 bits of the ttp_offset in microseconds.
+	 *
+	 * Internal default value is 0 for both values. The 64-bit number
+	 * formed by ttp_offset_lsw and ttp_offset_lsw is treated as unsigned.
+	 * In case of local DSP loopback when using start flag
+	 * ASM_SESSION_CMD_RUN_START_TIME_RUN_WITH_TTP the max. ttp_offset
+	 * value is limited by internal buffer constraints. Currently the
+	 * limit is 200ms.
+
+	 * This parameter can be set before or while an ASM stream is running,
+	 * allowing “at-run-time” changes of the overall latency.
+	 */
+
+} __packed;
+
 /* Parameter used by #ASM_SESSION_MTMX_STRTR_MODULE_ID_AVSYNC which allows the
  * audio client to specify the clock recovery mechanism that the audio DSP
  * should use.
@@ -12527,6 +12603,7 @@
 	struct asm_session_mtmx_strtr_param_render_mode_t render_param;
 	struct asm_session_mtmx_strtr_param_clk_rec_t clk_rec_param;
 	struct asm_session_mtmx_param_adjust_session_time_ctl_t adj_time_param;
+	struct asm_session_mtmx_strtr_param_ttp_offset_t ttp_offset;
 } __packed;
 
 struct asm_mtmx_strtr_params {
diff --git a/include/dsp/q6afe-v2.h b/include/dsp/q6afe-v2.h
index 3ff3028..55ae6be 100644
--- a/include/dsp/q6afe-v2.h
+++ b/include/dsp/q6afe-v2.h
@@ -402,6 +402,11 @@
 		      u32 rate, u16 afe_in_channels, u16 afe_in_bit_width,
 		      struct afe_enc_config *enc_config,
 		      struct afe_dec_config *dec_config);
+int afe_port_start_v3(u16 port_id, union afe_port_config *afe_config,
+		      u32 rate, u16 afe_in_channels, u16 afe_in_bit_width,
+		      struct afe_enc_config *enc_config,
+		      struct afe_dec_config *dec_config,
+		      struct afe_ttp_config *ttp_config);
 int afe_spk_prot_feed_back_cfg(int src_port, int dst_port,
 	int l_ch, int r_ch, u32 enable);
 int afe_spk_prot_get_calib_data(struct afe_spkr_prot_get_vi_calib *calib);
diff --git a/include/dsp/q6asm-v2.h b/include/dsp/q6asm-v2.h
index 5ad8fb0..1a34161 100644
--- a/include/dsp/q6asm-v2.h
+++ b/include/dsp/q6asm-v2.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
  */
 #ifndef __Q6_ASM_V2_H__
 #define __Q6_ASM_V2_H__
@@ -726,9 +726,13 @@
 		struct asm_session_mtmx_strtr_param_window_v2_t *window_param,
 		uint32_t param_id);
 
+int q6asm_send_mtmx_strtr_ttp_offset(struct audio_client *ac,
+		struct asm_session_mtmx_strtr_param_ttp_offset_t *ttp_offset,
+		uint32_t param_id, int dir);
+
 /* Configure DSP render mode */
 int q6asm_send_mtmx_strtr_render_mode(struct audio_client *ac,
-		uint32_t render_mode);
+		uint32_t render_mode, int dir);
 
 /* Configure DSP clock recovery mode */
 int q6asm_send_mtmx_strtr_clk_rec_mode(struct audio_client *ac,