Merge "asoc: codecs: msm_sdw: Fix serv_reg ack timeout in PDR"
diff --git a/Android.mk b/Android.mk
index abfd1de..a287fd7 100644
--- a/Android.mk
+++ b/Android.mk
@@ -14,6 +14,7 @@
 $(shell rm -rf $(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/Module.symvers)
 $(shell rm -rf $(OUT)/obj/vendor/qcom/opensource/audio-kernel/asoc/codecs/wcd934x/Module.symvers)
 
+include $(MY_LOCAL_PATH)/include/uapi/Android.mk
 include $(MY_LOCAL_PATH)/ipc/Android.mk
 include $(MY_LOCAL_PATH)/dsp/Android.mk
 include $(MY_LOCAL_PATH)/dsp/codecs/Android.mk
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..5955ae7
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,48 @@
+KBUILD_OPTIONS := AUDIO_ROOT=$(PWD)
+KBUILD_OPTIONS += MODNAME=audio
+KBUILD_OPTIONS += HEADER_INSTALL_DIR=$(KERNEL_SRC)/scripts
+KBUILD_OPTIONS += UAPI_OUT=$(PWD)
+
+ifeq ($(TARGET_SUPPORT), $(filter $(TARGET_SUPPORT), sdm670 qcs605))
+KBUILD_OPTIONS += CONFIG_ARCH_SDM670=y
+endif
+ifeq ($(TARGET_SUPPORT),sdm845)
+KBUILD_OPTIONS += CONFIG_ARCH_SDM845=y
+endif
+ifeq ($(TARGET_SUPPORT),apq8053)
+KBUILD_OPTIONS += CONFIG_ARCH_SDM450=y
+endif
+
+obj-m := ipc/
+obj-m += dsp/
+obj-m += dsp/codecs/
+obj-m += soc/
+obj-m += asoc/
+obj-m += asoc/codecs/
+ifeq ($(TARGET_SUPPORT), $(filter $(TARGET_SUPPORT), sdm670 qcs605))
+obj-m += asoc/codecs/wcd934x/
+endif
+ifeq ($(TARGET_SUPPORT), $(filter $(TARGET_SUPPORT), apq8053 sdm670 qcs605))
+obj-m += asoc/codecs/sdm660_cdc/
+endif
+ifeq ($(TARGET_SUPPORT), $(filter $(TARGET_SUPPORT), sdm670 qcs605))
+obj-m += asoc/codecs/msm_sdw/
+endif
+
+all:
+	$(shell rm -fr $(shell pwd)/soc/core.h)
+	$(shell ln -s $(KERNEL_SRC)/drivers/pinctrl/core.h $(shell pwd)/soc/core.h)
+	$(shell rm -fr $(shell pwd)/include/soc/internal.h)
+	$(shell ln -s $(KERNEL_SRC)/drivers/base/regmap/internal.h $(shell pwd)/include/soc/internal.h)
+	$(shell rm -fr $(shell pwd)/soc/pinctrl-utils.h)
+	$(shell ln -s $(KERNEL_SRC)/drivers/pinctrl/pinctrl-utils.h $(shell pwd)/soc/pinctrl-utils.h)
+	$(shell mkdir $(shell pwd)/linux)
+	$(shell mkdir $(shell pwd)/sound)
+	$(MAKE) -C $(KERNEL_SRC) M=$(shell pwd) modules $(KBUILD_OPTIONS)
+
+modules_install:
+	$(MAKE) INSTALL_MOD_STRIP=1 -C $(KERNEL_SRC) M=$(shell pwd) modules_install
+
+clean:
+	rm -f *.o *.ko *.mod.c *.mod.o *~ .*.cmd Module.symvers
+	rm -rf .tmp_versions
diff --git a/asoc/Android.mk b/asoc/Android.mk
index b2e3fa8..867379b 100644
--- a/asoc/Android.mk
+++ b/asoc/Android.mk
@@ -56,7 +56,7 @@
 LOCAL_MODULE_PATH         := $(KERNEL_MODULES_OUT)
 include $(DLKM_DIR)/AndroidKernelModule.mk
 ###########################################################
-ifeq ($(call is-board-platform-in-list,sdm670 qcs605),true)
+ifeq ($(call is-board-platform-in-list,msm8953 msm8937 sdm670 qcs605),true)
 include $(CLEAR_VARS)
 LOCAL_MODULE              := $(AUDIO_CHIPSET)_cpe_lsm.ko
 LOCAL_MODULE_KBUILD_NAME  := cpe_lsm_dlkm.ko
@@ -74,7 +74,7 @@
 LOCAL_MODULE_PATH         := $(KERNEL_MODULES_OUT)
 include $(DLKM_DIR)/AndroidKernelModule.mk
 ###########################################################
-ifeq ($(call is-board-platform-in-list,msm8953),true)
+ifeq ($(call is-board-platform-in-list,msm8953 msm8937),true)
 include $(CLEAR_VARS)
 LOCAL_MODULE              := $(AUDIO_CHIPSET)_machine_ext_$(TARGET).ko
 LOCAL_MODULE_KBUILD_NAME  := machine_ext_dlkm.ko
diff --git a/asoc/codecs/msm_sdw/msm_sdw_cdc.c b/asoc/codecs/msm_sdw/msm_sdw_cdc.c
index 3cde1ed..21c03ae 100644
--- a/asoc/codecs/msm_sdw/msm_sdw_cdc.c
+++ b/asoc/codecs/msm_sdw/msm_sdw_cdc.c
@@ -1961,7 +1961,8 @@
 	int adsp_state;
 
 	adsp_state = apr_get_subsys_state();
-	if (adsp_state != APR_SUBSYS_LOADED) {
+	if (adsp_state != APR_SUBSYS_LOADED ||
+		!q6core_is_adsp_ready()) {
 		dev_err(&pdev->dev, "Adsp is not loaded yet %d\n",
 				adsp_state);
 		return -EPROBE_DEFER;
diff --git a/asoc/codecs/sdm660_cdc/msm-analog-cdc.c b/asoc/codecs/sdm660_cdc/msm-analog-cdc.c
index 7487348..86f9db7 100644
--- a/asoc/codecs/sdm660_cdc/msm-analog-cdc.c
+++ b/asoc/codecs/sdm660_cdc/msm-analog-cdc.c
@@ -31,7 +31,6 @@
 #include "msm-cdc-common.h"
 #include "sdm660-cdc-irq.h"
 #include "msm-analog-cdc-regmap.h"
-#include "../../sdm660-common.h"
 #include "../wcd-mbhc-v2-api.h"
 
 #define DRV_NAME "pmic_analog_codec"
@@ -1464,9 +1463,6 @@
 static int msm_anlg_cdc_codec_enable_clock_block(struct snd_soc_codec *codec,
 						 int enable)
 {
-	struct msm_asoc_mach_data *pdata = NULL;
-
-	pdata = snd_soc_card_get_drvdata(codec->component.card);
 	if (enable) {
 		snd_soc_update_bits(codec,
 			MSM89XX_PMIC_ANALOG_MASTER_BIAS_CTL, 0x30, 0x30);
@@ -2348,9 +2344,6 @@
 	struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
 	struct sdm660_cdc_priv *sdm660_cdc =
 					snd_soc_codec_get_drvdata(codec);
-	struct msm_asoc_mach_data *pdata = NULL;
-
-	pdata = snd_soc_card_get_drvdata(codec->component.card);
 
 	dev_dbg(codec->dev, "%s event %d w->name %s\n", __func__,
 			event, w->name);
@@ -3705,13 +3698,11 @@
 
 static int msm_anlg_cdc_device_down(struct snd_soc_codec *codec)
 {
-	struct msm_asoc_mach_data *pdata = NULL;
 	struct sdm660_cdc_priv *sdm660_cdc_priv =
 		snd_soc_codec_get_drvdata(codec);
 	unsigned int tx_1_en;
 	unsigned int tx_2_en;
 
-	pdata = snd_soc_card_get_drvdata(codec->component.card);
 	dev_dbg(codec->dev, "%s: device down!\n", __func__);
 
 	tx_1_en = snd_soc_read(codec, MSM89XX_PMIC_ANALOG_TX_1_EN);
@@ -3779,7 +3770,6 @@
 		MSM89XX_PMIC_ANALOG_SPKR_DAC_CTL, 0x93);
 
 	msm_anlg_cdc_dig_notifier_call(codec, DIG_CDC_EVENT_SSR_DOWN);
-	atomic_set(&pdata->int_mclk0_enabled, false);
 	set_bit(BUS_DOWN, &sdm660_cdc_priv->status_mask);
 	snd_soc_card_change_online_state(codec->component.card, 0);
 
@@ -3931,17 +3921,18 @@
 static void msm_anlg_cdc_configure_cap(struct snd_soc_codec *codec,
 				       bool micbias1, bool micbias2)
 {
+	struct sdm660_cdc_priv *sdm660_cdc = snd_soc_codec_get_drvdata(codec);
+	struct msm_cap_mode *cap_mode = &sdm660_cdc->cap_mode;
 
-	struct msm_asoc_mach_data *pdata = NULL;
-
-	pdata = snd_soc_card_get_drvdata(codec->component.card);
+	blocking_notifier_call_chain(&sdm660_cdc->notifier,
+		 DIG_CDC_EVENT_CAP_CONFIGURE, cap_mode);
 
 	pr_debug("\n %s: micbias1 %x micbias2 = %d\n", __func__, micbias1,
 			micbias2);
 	if (micbias1 && micbias2) {
-		if ((pdata->micbias1_cap_mode
+		if ((cap_mode->micbias1_cap_mode
 		     == MICBIAS_EXT_BYP_CAP) ||
-		    (pdata->micbias2_cap_mode
+		    (cap_mode->micbias2_cap_mode
 		     == MICBIAS_EXT_BYP_CAP))
 			snd_soc_update_bits(codec,
 				MSM89XX_PMIC_ANALOG_MICB_1_EN,
@@ -3952,10 +3943,10 @@
 				0x40, (MICBIAS_NO_EXT_BYP_CAP << 6));
 	} else if (micbias2) {
 		snd_soc_update_bits(codec, MSM89XX_PMIC_ANALOG_MICB_1_EN,
-				0x40, (pdata->micbias2_cap_mode << 6));
+				0x40, (cap_mode->micbias2_cap_mode << 6));
 	} else if (micbias1) {
 		snd_soc_update_bits(codec, MSM89XX_PMIC_ANALOG_MICB_1_EN,
-				0x40, (pdata->micbias1_cap_mode << 6));
+				0x40, (cap_mode->micbias1_cap_mode << 6));
 	} else {
 		snd_soc_update_bits(codec, MSM89XX_PMIC_ANALOG_MICB_1_EN,
 				0x40, 0x00);
@@ -4275,12 +4266,10 @@
 
 static int msm_anlg_cdc_resume(struct snd_soc_codec *codec)
 {
-	struct msm_asoc_mach_data *pdata = NULL;
 	struct sdm660_cdc_priv *sdm660_cdc = snd_soc_codec_get_drvdata(codec);
 	struct sdm660_cdc_pdata *sdm660_cdc_pdata =
 					sdm660_cdc->dev->platform_data;
 
-	pdata = snd_soc_card_get_drvdata(codec->component.card);
 	msm_anlg_cdc_enable_static_supplies_to_optimum(sdm660_cdc,
 						       sdm660_cdc_pdata);
 	return 0;
@@ -4549,7 +4538,8 @@
 	int adsp_state;
 
 	adsp_state = apr_get_subsys_state();
-	if (adsp_state != APR_SUBSYS_LOADED) {
+	if (adsp_state != APR_SUBSYS_LOADED ||
+		!q6core_is_adsp_ready()) {
 		dev_err(&pdev->dev, "Adsp is not loaded yet %d\n",
 			adsp_state);
 		return -EPROBE_DEFER;
diff --git a/asoc/codecs/sdm660_cdc/msm-analog-cdc.h b/asoc/codecs/sdm660_cdc/msm-analog-cdc.h
index fe0de89..bf69cd0 100644
--- a/asoc/codecs/sdm660_cdc/msm-analog-cdc.h
+++ b/asoc/codecs/sdm660_cdc/msm-analog-cdc.h
@@ -18,6 +18,7 @@
 #include "../wcd-mbhc-v2.h"
 #include "../wcdcal-hwdep.h"
 #include "sdm660-cdc-registers.h"
+#include "msm-digital-cdc.h"
 
 #define MICBIAS_EXT_BYP_CAP 0x00
 #define MICBIAS_NO_EXT_BYP_CAP 0x01
@@ -219,6 +220,7 @@
 	struct platform_device *pdev_child_devices
 		[ANLG_CDC_CHILD_DEVICES_MAX];
 	int child_count;
+	struct msm_cap_mode cap_mode;
 };
 
 struct sdm660_cdc_pdata {
diff --git a/asoc/codecs/sdm660_cdc/msm-cdc-common.h b/asoc/codecs/sdm660_cdc/msm-cdc-common.h
index 1a490a4..8773387 100644
--- a/asoc/codecs/sdm660_cdc/msm-cdc-common.h
+++ b/asoc/codecs/sdm660_cdc/msm-cdc-common.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -63,5 +63,6 @@
 	DIG_CDC_EVENT_POST_RX2_INT_OFF,
 	DIG_CDC_EVENT_SSR_DOWN,
 	DIG_CDC_EVENT_SSR_UP,
+	DIG_CDC_EVENT_CAP_CONFIGURE,
 	DIG_CDC_EVENT_LAST,
 };
diff --git a/asoc/codecs/sdm660_cdc/msm-digital-cdc-legacy.c b/asoc/codecs/sdm660_cdc/msm-digital-cdc-legacy.c
index a83be92..b4353ab 100644
--- a/asoc/codecs/sdm660_cdc/msm-digital-cdc-legacy.c
+++ b/asoc/codecs/sdm660_cdc/msm-digital-cdc-legacy.c
@@ -1022,6 +1022,7 @@
 	struct msm_dig_priv *msm_dig_cdc = snd_soc_codec_get_drvdata(codec);
 	struct msm_asoc_mach_data *pdata = NULL;
 	int ret = -EINVAL;
+	struct msm_cap_mode *capmode = NULL;
 
 	pdata = snd_soc_card_get_drvdata(codec->component.card);
 
@@ -1105,6 +1106,9 @@
 		break;
 	case DIG_CDC_EVENT_SSR_DOWN:
 		regcache_cache_only(msm_dig_cdc->regmap, true);
+		mutex_lock(&pdata->cdc_int_mclk0_mutex);
+		atomic_set(&pdata->int_mclk0_enabled, false);
+		mutex_unlock(&pdata->cdc_int_mclk0_mutex);
 		break;
 	case DIG_CDC_EVENT_SSR_UP:
 		regcache_cache_only(msm_dig_cdc->regmap, false);
@@ -1132,6 +1136,11 @@
 				&pdata->digital_cdc_core_clk);
 		mutex_unlock(&pdata->cdc_int_mclk0_mutex);
 		break;
+	case DIG_CDC_EVENT_CAP_CONFIGURE:
+		capmode = (struct msm_cap_mode *)data;
+		capmode->micbias1_cap_mode = pdata->micbias1_cap_mode;
+		capmode->micbias2_cap_mode = pdata->micbias2_cap_mode;
+		break;
 	case DIG_CDC_EVENT_INVALID:
 	default:
 		break;
diff --git a/asoc/codecs/sdm660_cdc/msm-digital-cdc.c b/asoc/codecs/sdm660_cdc/msm-digital-cdc.c
index 2c3d0d6..af6ca81 100644
--- a/asoc/codecs/sdm660_cdc/msm-digital-cdc.c
+++ b/asoc/codecs/sdm660_cdc/msm-digital-cdc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -1019,6 +1019,7 @@
 	struct snd_soc_codec *codec = registered_digcodec;
 	struct msm_dig_priv *msm_dig_cdc = snd_soc_codec_get_drvdata(codec);
 	struct msm_asoc_mach_data *pdata = NULL;
+	struct msm_cap_mode *capmode;
 	int ret = -EINVAL;
 
 	pdata = snd_soc_card_get_drvdata(codec->component.card);
@@ -1107,6 +1108,9 @@
 		break;
 	case DIG_CDC_EVENT_SSR_DOWN:
 		regcache_cache_only(msm_dig_cdc->regmap, true);
+		mutex_lock(&pdata->cdc_int_mclk0_mutex);
+		atomic_set(&pdata->int_mclk0_enabled, false);
+		mutex_unlock(&pdata->cdc_int_mclk0_mutex);
 		break;
 	case DIG_CDC_EVENT_SSR_UP:
 		regcache_cache_only(msm_dig_cdc->regmap, false);
@@ -1134,6 +1138,11 @@
 				&pdata->digital_cdc_core_clk);
 		mutex_unlock(&pdata->cdc_int_mclk0_mutex);
 		break;
+	case DIG_CDC_EVENT_CAP_CONFIGURE:
+		capmode = (struct msm_cap_mode *)data;
+		capmode->micbias1_cap_mode = pdata->micbias1_cap_mode;
+		capmode->micbias2_cap_mode = pdata->micbias2_cap_mode;
+		break;
 	case DIG_CDC_EVENT_INVALID:
 	default:
 		break;
diff --git a/asoc/codecs/sdm660_cdc/msm-digital-cdc.h b/asoc/codecs/sdm660_cdc/msm-digital-cdc.h
index 15f7fe5..ae69a5c 100644
--- a/asoc/codecs/sdm660_cdc/msm-digital-cdc.h
+++ b/asoc/codecs/sdm660_cdc/msm-digital-cdc.h
@@ -38,6 +38,11 @@
 	struct delayed_work dwork;
 };
 
+struct msm_cap_mode {
+	u8 micbias1_cap_mode;
+	u8 micbias2_cap_mode;
+};
+
 struct msm_dig_priv {
 	struct snd_soc_codec *codec;
 	u32 comp_enabled[MSM89XX_RX_MAX];
diff --git a/asoc/codecs/wsa881x-analog.c b/asoc/codecs/wsa881x-analog.c
index 5175181..d4575d0 100644
--- a/asoc/codecs/wsa881x-analog.c
+++ b/asoc/codecs/wsa881x-analog.c
@@ -818,7 +818,7 @@
 	else
 		snd_soc_update_bits(codec, WSA881X_SPKR_OCP_CTL, 0xC0, 0xC0);
 
-		schedule_delayed_work(&wsa881x->ocp_ctl_work,
+	schedule_delayed_work(&wsa881x->ocp_ctl_work,
 			msecs_to_jiffies(wsa881x_ocp_poll_timer_sec * 1000));
 }
 
diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c
index 5543cab..cf4b5c0 100644
--- a/asoc/msm-pcm-routing-v2.c
+++ b/asoc/msm-pcm-routing-v2.c
@@ -938,7 +938,7 @@
 	}
 	pr_debug("%s: Can't find topology for path %d, app %d, acdb_id %d defaulting to search by path\n",
 		__func__, path, app_type, acdb_id);
-	return msm_routing_find_topology_by_path(cal_index, path);
+	return msm_routing_find_topology_by_path(path, cal_index);
 }
 
 static int msm_routing_get_adm_topology(int fedai_id, int session_type,
@@ -1622,7 +1622,7 @@
 			path_type = ADM_PATH_PLAYBACK;
 	} else {
 		session_type = SESSION_TYPE_TX;
-		if (passthr_mode != LEGACY_PCM)
+		if ((passthr_mode != LEGACY_PCM) && (passthr_mode != LISTEN))
 			path_type = ADM_PATH_COMPRESSED_TX;
 		else
 			path_type = ADM_PATH_LIVE_REC;
diff --git a/asoc/msm8952-dai-links.c b/asoc/msm8952-dai-links.c
index a19190c..1fa9ac6 100644
--- a/asoc/msm8952-dai-links.c
+++ b/asoc/msm8952-dai-links.c
@@ -119,7 +119,7 @@
 		.name = "CPE Listen service",
 		.stream_name = "CPE Listen Audio Service",
 		.cpu_dai_name = "msm-dai-slim",
-		.platform_name = "msm-pcm-hostless",
+		.platform_name = "msm-cpe-lsm",
 		.trigger = {SND_SOC_DPCM_TRIGGER_POST,
 			SND_SOC_DPCM_TRIGGER_POST},
 		.no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
diff --git a/asoc/msm8952.c b/asoc/msm8952.c
index 651087f..44db613 100644
--- a/asoc/msm8952.c
+++ b/asoc/msm8952.c
@@ -242,12 +242,13 @@
 				__func__);
 			return ret;
 		}
-		if (atomic_dec_return(&supply->ref) == 0)
+		if (atomic_dec_return(&supply->ref) == 0) {
 			ret = regulator_disable(supply->supply);
 			if (ret)
 				dev_err(codec->component.card->dev,
 					"%s: Failed to disable wsa switch supply\n",
 					__func__);
+		}
 		break;
 	default:
 		break;
diff --git a/config/sdm450auto.conf b/config/sdm450auto.conf
index 6d1734f..0d367ae 100644
--- a/config/sdm450auto.conf
+++ b/config/sdm450auto.conf
@@ -5,6 +5,7 @@
 CONFIG_SND_SOC_WSA881X=m
 CONFIG_SND_SOC_WSA881X_ANALOG=m
 CONFIG_SND_SOC_WCD_CPE=m
+CONFIG_SND_SOC_CPE=m
 CONFIG_SND_SOC_WCD9335=m
 CONFIG_MSM_QDSP6V2_CODECS=m
 CONFIG_MSM_ULTRASOUND=m
@@ -32,6 +33,7 @@
 CONFIG_DTS_SRS_TM=m
 CONFIG_SND_SOC_MSM_STUB=m
 CONFIG_MSM_AVTIMER=m
+CONFIG_AVTIMER_LEGACY=m
 CONFIG_SND_SOC_SDM660_CDC=m
 CONFIG_SND_SOC_ANALOG_CDC=m
 CONFIG_SND_SOC_DIGITAL_CDC_LEGACY=m
diff --git a/config/sdm450autoconf.h b/config/sdm450autoconf.h
index 59a96f0..1aca114 100644
--- a/config/sdm450autoconf.h
+++ b/config/sdm450autoconf.h
@@ -15,6 +15,7 @@
 #define CONFIG_AUDIO_EXT_CLK 1
 #define CONFIG_SND_SOC_WCD9XXX_V2 1
 #define CONFIG_SND_SOC_WCD_CPE 1
+#define CONFIG_SND_SOC_CPE 1
 #define CONFIG_SND_SOC_WCD_MBHC 1
 #define CONFIG_SND_SOC_WSA881X 1
 #define CONFIG_SND_SOC_WSA881X_ANALOG 1
@@ -45,6 +46,7 @@
 #define CONFIG_MSM_CDC_PINCTRL 1
 #define CONFIG_SND_SOC_MSM_STUB 1
 #define CONFIG_MSM_AVTIMER 1
+#define CONFIG_AVTIMER_LEGACY 1
 #define CONFIG_SND_SOC_EXT_CODEC 1
 #define CONFIG_SND_SOC_INT_CODEC 1
 #define CONFIG_SND_SOC_SDM660_CDC 1
diff --git a/dsp/avtimer.c b/dsp/avtimer.c
index b6833ed..db9eb9a 100644
--- a/dsp/avtimer.c
+++ b/dsp/avtimer.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2015, 2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2015, 2017-2018 The Linux Foundation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -25,6 +25,9 @@
 #include <linux/of.h>
 #include <linux/wait.h>
 #include <linux/sched.h>
+#if IS_ENABLED(CONFIG_AVTIMER_LEGACY)
+#include <media/msmb_isp.h>
+#endif
 #include <ipc/apr.h>
 #include <dsp/q6core.h>
 
@@ -70,6 +73,7 @@
 };
 
 static struct avtimer_t avtimer;
+static void avcs_set_isp_fptr(bool enable);
 
 static int32_t aprv2_core_fn_q(struct apr_client_data *data, void *priv)
 {
@@ -313,6 +317,29 @@
 }
 EXPORT_SYMBOL(avcs_core_query_timer);
 
+#if IS_ENABLED(CONFIG_AVTIMER_LEGACY)
+static void avcs_set_isp_fptr(bool enable)
+{
+	struct avtimer_fptr_t av_fptr;
+
+	if (enable) {
+		av_fptr.fptr_avtimer_open = avcs_core_open;
+		av_fptr.fptr_avtimer_enable = avcs_core_disable_power_collapse;
+		av_fptr.fptr_avtimer_get_time = avcs_core_query_timer;
+		msm_isp_set_avtimer_fptr(av_fptr);
+	} else {
+		av_fptr.fptr_avtimer_open = NULL;
+		av_fptr.fptr_avtimer_enable = NULL;
+		av_fptr.fptr_avtimer_get_time = NULL;
+		msm_isp_set_avtimer_fptr(av_fptr);
+	}
+}
+#else
+static void avcs_set_isp_fptr(bool enable)
+{
+}
+#endif
+
 static int avtimer_open(struct inode *inode, struct file *file)
 {
 	return avcs_core_disable_power_collapse(1);
@@ -469,6 +496,8 @@
 	else
 		avtimer.clk_mult = clk_mult_val;
 
+	avcs_set_isp_fptr(true);
+
 	pr_debug("%s: avtimer.clk_div = %d, avtimer.clk_mult = %d\n",
 		 __func__, avtimer.clk_div, avtimer.clk_mult);
 	return 0;
@@ -500,6 +529,7 @@
 	cdev_del(&avtimer.myc);
 	class_destroy(avtimer.avtimer_class);
 	unregister_chrdev_region(MKDEV(major, 0), 1);
+	avcs_set_isp_fptr(false);
 
 	return 0;
 }
diff --git a/dsp/q6asm.c b/dsp/q6asm.c
index 911a2dd..9fb5d6b 100644
--- a/dsp/q6asm.c
+++ b/dsp/q6asm.c
@@ -284,6 +284,11 @@
 		pr_err("%s: out_buffer is null\n", __func__);
 		return 0;
 	}
+	if (count < OUT_BUFFER_SIZE) {
+		pr_err("%s: read size %d exceeds buf size %zd\n", __func__,
+						OUT_BUFFER_SIZE, count);
+		return 0;
+	}
 	snprintf(out_buffer, OUT_BUFFER_SIZE, "%ld,%ld,%ld,%ld,%ld,%ld,",
 		out_cold_tv.tv_sec, out_cold_tv.tv_usec, out_warm_tv.tv_sec,
 		out_warm_tv.tv_usec, out_cont_tv.tv_sec, out_cont_tv.tv_usec);
@@ -336,6 +341,11 @@
 		pr_err("%s: in_buffer is null\n", __func__);
 		return 0;
 	}
+	if (count < IN_BUFFER_SIZE) {
+		pr_err("%s: read size %d exceeds buf size %zd\n", __func__,
+						IN_BUFFER_SIZE, count);
+		return 0;
+	}
 	snprintf(in_buffer, IN_BUFFER_SIZE, "%ld,%ld,",
 				in_cont_tv.tv_sec, in_cont_tv.tv_usec);
 	return  simple_read_from_buffer(buf, IN_BUFFER_SIZE, ppos,
@@ -8300,8 +8310,10 @@
 		list_for_each_safe(ptr, next, &ac->port[OUT].mem_map_handle) {
 			buf_node = list_entry(ptr, struct asm_buffer_node,
 					list);
-			if (buf_node->buf_phys_addr == ab->phys)
+			if (buf_node->buf_phys_addr == ab->phys) {
 				read.mem_map_handle = buf_node->mmap_hdl;
+				break;
+			}
 		}
 		dev_vdbg(ac->dev, "memory_map handle in q6asm_read: [%0x]:",
 				read.mem_map_handle);
diff --git a/include/uapi/Android.mk b/include/uapi/Android.mk
new file mode 100644
index 0000000..36bcfde
--- /dev/null
+++ b/include/uapi/Android.mk
@@ -0,0 +1,28 @@
+# Use this by setting
+#   LOCAL_HEADER_LIBRARIES := audio_kernel_headers
+
+LOCAL_PATH := $(call my-dir)
+MYLOCAL_PATH := $(LOCAL_PATH)
+
+UAPI_OUT := $(PRODUCT_OUT)/obj/vendor/qcom/opensource/audio-kernel/include
+
+AUDIO_KERNEL_HEADERS := $(call all-named-files-under,*.h,linux) $(call all-named-files-under,*.h,sound)
+
+HEADER_INSTALL_DIR := kernel/msm-$(TARGET_KERNEL_VERSION)/scripts
+
+BUILD_ROOT_RELATIVE := ../../../../../../../
+
+include $(CLEAR_VARS)
+LOCAL_MODULE                  := audio_kernel_headers
+LOCAL_ADDITIONAL_DEPENDENCIES := $(TARGET_PREBUILT_INT_KERNEL)
+
+GEN := $(addprefix $(UAPI_OUT)/,$(AUDIO_KERNEL_HEADERS))
+$(GEN): PRIVATE_PATH := $(MYLOCAL_PATH)
+$(GEN): PRIVATE_CUSTOM_TOOL = $(shell cd $(PRODUCT_OUT)/obj/KERNEL_OBJ; $(BUILD_ROOT_RELATIVE)$(HEADER_INSTALL_DIR)/headers_install.sh $(BUILD_ROOT_RELATIVE)$(dir $@) $(BUILD_ROOT_RELATIVE)$(subst $(UAPI_OUT),$(MYLOCAL_PATH),$(dir $@)) $(notdir $@))
+$(GEN): $(addprefix $(MYLOCAL_PATH)/,$(AUDIO_KERNEL_HEADERS))
+	$(transform-generated-source)
+
+LOCAL_GENERATED_SOURCES := $(GEN)
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(UAPI_OUT)
+
+include $(BUILD_HEADER_LIBRARY)