Merge "dsp: add audio ion virtualization support"
diff --git a/asoc/codecs/audio-ext-clk-up.c b/asoc/codecs/audio-ext-clk-up.c
index e6e68ad..6bdf00f 100644
--- a/asoc/codecs/audio-ext-clk-up.c
+++ b/asoc/codecs/audio-ext-clk-up.c
@@ -70,7 +70,7 @@
 		clk_priv->clk_cfg.enable = 1;
 		ret = afe_set_lpass_clk_cfg(IDX_RSVD_3, &clk_priv->clk_cfg);
 		if (ret < 0) {
-			pr_err("%s afe_set_digital_codec_core_clock failed\n",
+			pr_err_ratelimited("%s afe_set_digital_codec_core_clock failed\n",
 				__func__);
 			return ret;
 		}
@@ -112,7 +112,7 @@
 		clk_priv->clk_cfg.enable = 0;
 		ret = afe_set_lpass_clk_cfg(IDX_RSVD_3, &clk_priv->clk_cfg);
 		if (ret < 0)
-			pr_err("%s: afe_set_lpass_clk_cfg failed, ret = %d\n",
+			pr_err_ratelimited("%s: afe_set_lpass_clk_cfg failed, ret = %d\n",
 				__func__, ret);
 	}
 
diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c
index 49b7da5..51930ee 100644
--- a/asoc/codecs/bolero/tx-macro.c
+++ b/asoc/codecs/bolero/tx-macro.c
@@ -212,7 +212,7 @@
 							   TX_CORE_CLK,
 							   true);
 			if (ret < 0) {
-				dev_err(tx_priv->dev,
+				dev_err_ratelimited(tx_priv->dev,
 					"%s: request clock enable failed\n",
 					__func__);
 				goto exit;
diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c
index d1ba346..68f1cb9 100644
--- a/asoc/codecs/bolero/wsa-macro.c
+++ b/asoc/codecs/bolero/wsa-macro.c
@@ -815,7 +815,7 @@
 							wsa_priv->default_clk_id,
 							true);
 			if (ret < 0) {
-				dev_err(wsa_priv->dev,
+				dev_err_ratelimited(wsa_priv->dev,
 					"%s: wsa request clock enable failed\n",
 					__func__);
 				goto exit;
@@ -2637,7 +2637,7 @@
 			if (ret < 0) {
 				msm_cdc_pinctrl_select_sleep_state(
 						wsa_priv->wsa_swr_gpio_p);
-				dev_err(wsa_priv->dev,
+				dev_err_ratelimited(wsa_priv->dev,
 					"%s: wsa request clock enable failed\n",
 					__func__);
 				goto exit;
diff --git a/asoc/msm-audio-effects-q6-v2.c b/asoc/msm-audio-effects-q6-v2.c
index 7ab6db4..bdb0059 100644
--- a/asoc/msm-audio-effects-q6-v2.c
+++ b/asoc/msm-audio-effects-q6-v2.c
@@ -1,8 +1,9 @@
 // SPDX-License-Identifier: GPL-2.0-only
-/* Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
  */
 
 #include <linux/slab.h>
+#include <linux/ratelimit.h>
 #include <sound/compress_params.h>
 #include <sound/devdep_params.h>
 #include <dsp/apr_audio-v2.h>
@@ -15,7 +16,8 @@
 #define GET_NEXT(ptr, upper_limit, rc)                                  \
 ({                                                                      \
 	if (((ptr) + 1) > (upper_limit)) {                              \
-		pr_err("%s: param list out of boundary\n", __func__);   \
+		pr_err_ratelimited("%s: param list out of boundary\n",  \
+				   __func__);				\
 		(rc) = -EINVAL;                                         \
 	}                                                               \
 	((rc) == 0) ? *(ptr)++ :  -EINVAL;                              \
@@ -24,7 +26,8 @@
 #define CHECK_PARAM_LEN(len, max_len, tag, rc)                          \
 do {                                                                    \
 	if ((len) > (max_len)) {                                        \
-		pr_err("%s: params length overflows\n", (tag));         \
+		pr_err_ratelimited("%s: params length overflows\n",	\
+				   (tag));				\
 		(rc) = -EINVAL;                                         \
 	}                                                               \
 } while (0)
@@ -244,7 +247,8 @@
 			param_data = (u8 *) &virtualizer->gain_adjust;
 			break;
 		default:
-			pr_err("%s: Invalid command to set config\n", __func__);
+			pr_err_ratelimited("%s: Invalid command to set config\n",
+					   __func__);
 			continue;
 		}
 		if (rc)
@@ -678,7 +682,8 @@
 			param_data = (u8 *) &reverb->density;
 			break;
 		default:
-			pr_err("%s: Invalid command to set config\n", __func__);
+			pr_err_ratelimited("%s: Invalid command to set config\n",
+					   __func__);
 			continue;
 		}
 		if (rc)
@@ -831,7 +836,8 @@
 			param_data = (u8 *) &bass_boost->strength;
 			break;
 		default:
-			pr_err("%s: Invalid command to set config\n", __func__);
+			pr_err_ratelimited("%s: Invalid command to set config\n",
+					   __func__);
 			continue;
 		}
 		if (rc)
@@ -956,7 +962,8 @@
 			param_data = (u8 *) values;
 			break;
 		default:
-			pr_err("%s: Invalid command to set config\n", __func__);
+			pr_err_ratelimited("%s: Invalid command to set config\n",
+					   __func__);
 			continue;
 		}
 		if (rc)
@@ -1214,7 +1221,8 @@
 			param_data = (u8 *) &eq->freq_millihertz;
 			break;
 		default:
-			pr_err("%s: Invalid command to set config\n", __func__);
+			pr_err_ratelimited("%s: Invalid command to set config\n",
+					   __func__);
 			continue;
 		}
 		if (rc)
@@ -1335,7 +1343,7 @@
 					"VOLUME/VOLUME2_GAIN_MASTER", rc);
 			break;
 		default:
-			pr_err("%s: Invalid command id: %d to set config\n",
+			pr_err_ratelimited("%s: Invalid command id: %d to set config\n",
 				__func__, command_id);
 			continue;
 		}
diff --git a/asoc/msm-lsm-client.c b/asoc/msm-lsm-client.c
index 3a5707e..ff77e90 100644
--- a/asoc/msm-lsm-client.c
+++ b/asoc/msm-lsm-client.c
@@ -2425,6 +2425,7 @@
 {
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	struct lsm_priv *prtd;
+	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	int ret = 0;
 
 	pr_debug("%s\n", __func__);
@@ -2488,6 +2489,8 @@
 	prtd->lsm_client->perf_mode = 0;
 	prtd->lsm_client->event_mode = LSM_EVENT_NON_TIME_STAMP_MODE;
 	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;
 
 	return 0;
 }
@@ -2958,13 +2961,81 @@
 	return 0;
 }
 
+static int msm_lsm_afe_data_ctl_put(struct snd_kcontrol *kcontrol,
+				    struct snd_ctl_elem_value *ucontrol)
+{
+	u64 fe_id = kcontrol->private_value;
+	uint16_t afe_data_format = 0;
+	int ret = 0;
+
+	afe_data_format = ucontrol->value.integer.value[0];
+	pr_debug("%s: afe data is %s\n", __func__,
+		 afe_data_format ? "unprocessed" : "processed");
+
+	ret = q6lsm_set_afe_data_format(fe_id, afe_data_format);
+	if (ret)
+		pr_err("%s: q6lsm_set_afe_data_format failed, ret = %d\n",
+			__func__, ret);
+
+	return ret;
+}
+
+static int msm_lsm_afe_data_ctl_get(struct snd_kcontrol *kcontrol,
+				    struct snd_ctl_elem_value *ucontrol)
+{
+	u64 fe_id = kcontrol->private_value;
+	uint16_t afe_data_format = 0;
+	int ret = 0;
+
+	q6lsm_get_afe_data_format(fe_id, &afe_data_format);
+	ucontrol->value.integer.value[0] = afe_data_format;
+	pr_debug("%s: afe data is %s\n", __func__,
+		 afe_data_format ? "unprocessed" : "processed");
+
+	return ret;
+}
+
+static int msm_lsm_add_afe_data_controls(struct snd_soc_pcm_runtime *rtd)
+{
+	struct snd_pcm *pcm = rtd->pcm;
+	struct snd_pcm_usr *afe_data_info;
+	struct snd_kcontrol *kctl;
+	const char *mixer_ctl_name	= "Listen Stream";
+	const char *deviceNo		= "NN";
+	const char *suffix		= "Unprocessed Data";
+	int ctl_len, ret = 0;
+
+	ctl_len = strlen(mixer_ctl_name) + 1 + strlen(deviceNo) + 1 +
+		  strlen(suffix) + 1;
+	pr_debug("%s: Adding Listen afe data cntrls\n", __func__);
+	ret = snd_pcm_add_usr_ctls(pcm, SNDRV_PCM_STREAM_CAPTURE,
+				   NULL, 1, ctl_len, rtd->dai_link->id,
+				   &afe_data_info);
+	if (ret < 0) {
+		pr_err("%s: Adding Listen afe data cntrls failed: %d\n",
+		       __func__, ret);
+		return ret;
+	}
+	kctl = afe_data_info->kctl;
+	snprintf(kctl->id.name, ctl_len, "%s %d %s",
+		 mixer_ctl_name, rtd->pcm->device, suffix);
+	kctl->put = msm_lsm_afe_data_ctl_put;
+	kctl->get = msm_lsm_afe_data_ctl_get;
+
+	return 0;
+}
+
 static int msm_lsm_add_controls(struct snd_soc_pcm_runtime *rtd)
 {
 	int ret = 0;
 
 	ret = msm_lsm_add_app_type_controls(rtd);
 	if (ret)
-		pr_err("%s, add  app type controls failed:%d\n", __func__, ret);
+		pr_err("%s, add app type controls failed:%d\n", __func__, ret);
+
+	ret = msm_lsm_add_afe_data_controls(rtd);
+	if (ret)
+		pr_err("%s, add afe data controls failed:%d\n", __func__, ret);
 
 	return ret;
 }
diff --git a/asoc/qcs405.c b/asoc/qcs405.c
index 0455748..554779d 100644
--- a/asoc/qcs405.c
+++ b/asoc/qcs405.c
@@ -440,6 +440,12 @@
 	[SEN_AUX_PCM]  = {SAMPLING_RATE_8KHZ, SNDRV_PCM_FORMAT_S16_LE, 1},
 };
 
+static struct dev_config afe_lb_tx_cfg = {
+	.sample_rate = SAMPLING_RATE_48KHZ,
+	.bit_format = SNDRV_PCM_FORMAT_S16_LE,
+	.channels = 2,
+};
+
 static int msm_vi_feed_tx_ch = 2;
 static const char *const slim_rx_ch_text[] = {"One", "Two"};
 static const char *const slim_tx_ch_text[] = {"One", "Two", "Three", "Four",
@@ -602,6 +608,10 @@
 static SOC_ENUM_SINGLE_EXT_DECL(spdif_tx_chs, spdif_ch_text);
 static SOC_ENUM_SINGLE_EXT_DECL(spdif_rx_format, spdif_bit_format_text);
 static SOC_ENUM_SINGLE_EXT_DECL(spdif_tx_format, spdif_bit_format_text);
+static SOC_ENUM_SINGLE_EXT_DECL(afe_lb_tx_chs, cdc_dma_tx_ch_text);
+static SOC_ENUM_SINGLE_EXT_DECL(afe_lb_tx_format, bit_format_text);
+static SOC_ENUM_SINGLE_EXT_DECL(afe_lb_tx_sample_rate,
+				cdc_dma_sample_rate_text);
 
 static struct platform_device *spdev;
 
@@ -3444,6 +3454,184 @@
 	return 0;
 }
 
+static int afe_lb_tx_ch_get(struct snd_kcontrol *kcontrol,
+			    struct snd_ctl_elem_value *ucontrol)
+{
+	pr_debug("%s: afe_lb_tx_ch  = %d\n", __func__,
+		 afe_lb_tx_cfg.channels);
+	ucontrol->value.integer.value[0] = afe_lb_tx_cfg.channels - 1;
+	return 0;
+}
+
+static int afe_lb_tx_ch_put(struct snd_kcontrol *kcontrol,
+			    struct snd_ctl_elem_value *ucontrol)
+{
+	afe_lb_tx_cfg.channels = ucontrol->value.integer.value[0] + 1;
+
+	pr_debug("%s: afe_lb_tx_ch = %d\n", __func__, afe_lb_tx_cfg.channels);
+	return 0;
+}
+
+static int afe_lb_tx_sample_rate_get(struct snd_kcontrol *kcontrol,
+				     struct snd_ctl_elem_value *ucontrol)
+{
+	int sample_rate_val;
+
+	switch (afe_lb_tx_cfg.sample_rate) {
+	case SAMPLING_RATE_384KHZ:
+		sample_rate_val = 12;
+		break;
+	case SAMPLING_RATE_352P8KHZ:
+		sample_rate_val = 11;
+		break;
+	case SAMPLING_RATE_192KHZ:
+		sample_rate_val = 10;
+		break;
+	case SAMPLING_RATE_176P4KHZ:
+		sample_rate_val = 9;
+		break;
+	case SAMPLING_RATE_96KHZ:
+		sample_rate_val = 8;
+		break;
+	case SAMPLING_RATE_88P2KHZ:
+		sample_rate_val = 7;
+		break;
+	case SAMPLING_RATE_48KHZ:
+		sample_rate_val = 6;
+		break;
+	case SAMPLING_RATE_44P1KHZ:
+		sample_rate_val = 5;
+		break;
+	case SAMPLING_RATE_32KHZ:
+		sample_rate_val = 4;
+		break;
+	case SAMPLING_RATE_22P05KHZ:
+		sample_rate_val = 3;
+		break;
+	case SAMPLING_RATE_16KHZ:
+		sample_rate_val = 2;
+		break;
+	case SAMPLING_RATE_11P025KHZ:
+		sample_rate_val = 1;
+		break;
+	case SAMPLING_RATE_8KHZ:
+		sample_rate_val = 0;
+		break;
+	default:
+		sample_rate_val = 6;
+		break;
+	}
+
+	ucontrol->value.integer.value[0] = sample_rate_val;
+	pr_debug("%s: afe_lb_tx_sample_rate = %d\n", __func__,
+		 afe_lb_tx_cfg.sample_rate);
+	return 0;
+}
+
+static int afe_lb_tx_sample_rate_put(struct snd_kcontrol *kcontrol,
+				     struct snd_ctl_elem_value *ucontrol)
+{
+	switch (ucontrol->value.integer.value[0]) {
+	case 12:
+		afe_lb_tx_cfg.sample_rate = SAMPLING_RATE_384KHZ;
+		break;
+	case 11:
+		afe_lb_tx_cfg.sample_rate = SAMPLING_RATE_352P8KHZ;
+		break;
+	case 10:
+		afe_lb_tx_cfg.sample_rate = SAMPLING_RATE_192KHZ;
+		break;
+	case 9:
+		afe_lb_tx_cfg.sample_rate = SAMPLING_RATE_176P4KHZ;
+		break;
+	case 8:
+		afe_lb_tx_cfg.sample_rate = SAMPLING_RATE_96KHZ;
+		break;
+	case 7:
+		afe_lb_tx_cfg.sample_rate = SAMPLING_RATE_88P2KHZ;
+		break;
+	case 6:
+		afe_lb_tx_cfg.sample_rate = SAMPLING_RATE_48KHZ;
+		break;
+	case 5:
+		afe_lb_tx_cfg.sample_rate = SAMPLING_RATE_44P1KHZ;
+		break;
+	case 4:
+		afe_lb_tx_cfg.sample_rate = SAMPLING_RATE_32KHZ;
+		break;
+	case 3:
+		afe_lb_tx_cfg.sample_rate = SAMPLING_RATE_22P05KHZ;
+		break;
+	case 2:
+		afe_lb_tx_cfg.sample_rate = SAMPLING_RATE_16KHZ;
+		break;
+	case 1:
+		afe_lb_tx_cfg.sample_rate = SAMPLING_RATE_11P025KHZ;
+		break;
+	case 0:
+		afe_lb_tx_cfg.sample_rate = SAMPLING_RATE_8KHZ;
+		break;
+	default:
+		afe_lb_tx_cfg.sample_rate = SAMPLING_RATE_48KHZ;
+		break;
+	}
+
+	pr_debug("%s: control value = %ld, afe_lb_tx_sample_rate = %d\n",
+		__func__, ucontrol->value.integer.value[0],
+		afe_lb_tx_cfg.sample_rate);
+	return 0;
+}
+
+static int afe_lb_tx_format_get(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	switch (afe_lb_tx_cfg.bit_format) {
+	case SNDRV_PCM_FORMAT_S32_LE:
+		ucontrol->value.integer.value[0] = 3;
+		break;
+	case SNDRV_PCM_FORMAT_S24_3LE:
+		ucontrol->value.integer.value[0] = 2;
+		break;
+	case SNDRV_PCM_FORMAT_S24_LE:
+		ucontrol->value.integer.value[0] = 1;
+		break;
+	case SNDRV_PCM_FORMAT_S16_LE:
+	default:
+		ucontrol->value.integer.value[0] = 0;
+		break;
+	}
+
+	pr_debug("%s: afe_lb_tx_format = %d, ucontrol value = %ld\n",
+		 __func__, afe_lb_tx_cfg.bit_format,
+		 ucontrol->value.integer.value[0]);
+	return 0;
+}
+
+static int afe_lb_tx_format_put(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	switch (ucontrol->value.integer.value[0]) {
+	case 3:
+		afe_lb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S32_LE;
+		break;
+	case 2:
+		afe_lb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_3LE;
+		break;
+	case 1:
+		afe_lb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S24_LE;
+		break;
+	case 0:
+	default:
+		afe_lb_tx_cfg.bit_format = SNDRV_PCM_FORMAT_S16_LE;
+		break;
+	}
+
+	pr_debug("%s: afe_lb_tx_format = %d, ucontrol value = %ld\n",
+		 __func__, afe_lb_tx_cfg.bit_format,
+		 ucontrol->value.integer.value[0]);
+	return 0;
+}
+
 static const struct snd_kcontrol_new msm_snd_sb_controls[] = {
 	SOC_ENUM_EXT("SLIM_0_RX Channels", slim_0_rx_chs,
 			slim_rx_ch_get, slim_rx_ch_put),
@@ -3826,6 +4014,13 @@
 			msm_spdif_rx_format_get, msm_spdif_rx_format_put),
 	SOC_ENUM_EXT("SEC_SPDIF_TX Format", spdif_tx_format,
 			msm_spdif_tx_format_get, msm_spdif_tx_format_put),
+	SOC_ENUM_EXT("AFE_LOOPBACK_TX Channels", afe_lb_tx_chs,
+			afe_lb_tx_ch_get, afe_lb_tx_ch_put),
+	SOC_ENUM_EXT("AFE_LOOPBACK_TX Format", afe_lb_tx_format,
+			afe_lb_tx_format_get, afe_lb_tx_format_put),
+	SOC_ENUM_EXT("AFE_LOOPBACK_TX SampleRate", afe_lb_tx_sample_rate,
+			afe_lb_tx_sample_rate_get,
+			afe_lb_tx_sample_rate_put),
 };
 
 static int msm_snd_enable_codec_ext_clk(struct snd_soc_component *component,
@@ -4610,6 +4805,13 @@
 			spdif_tx_cfg[SEC_SPDIF_TX].channels;
 	break;
 
+	case MSM_BACKEND_DAI_AFE_LOOPBACK_TX:
+		param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+				afe_lb_tx_cfg.bit_format);
+		rate->min = rate->max = afe_lb_tx_cfg.sample_rate;
+		channels->min = channels->max = afe_lb_tx_cfg.channels;
+		break;
+
 	default:
 		rate->min = rate->max = SAMPLING_RATE_48KHZ;
 		break;
@@ -7630,6 +7832,7 @@
 		.no_pcm = 1,
 		.dpcm_capture = 1,
 		.id = MSM_BACKEND_DAI_AFE_LOOPBACK_TX,
+		.be_hw_params_fixup = msm_be_hw_params_fixup,
 		.ignore_pmdown_time = 1,
 		.ignore_suspend = 1,
 	},
diff --git a/dsp/codecs/audio_alac.c b/dsp/codecs/audio_alac.c
index f7e0932..a3e473f 100644
--- a/dsp/codecs/audio_alac.c
+++ b/dsp/codecs/audio_alac.c
@@ -1,15 +1,5 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /* Copyright (c) 2015-2019, 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
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
  */
 
 #include <linux/types.h>
diff --git a/dsp/codecs/audio_ape.c b/dsp/codecs/audio_ape.c
index 1e12981..319828b 100644
--- a/dsp/codecs/audio_ape.c
+++ b/dsp/codecs/audio_ape.c
@@ -1,15 +1,5 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /* Copyright (c) 2015-2019, 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
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
  */
 
 #include <linux/types.h>
diff --git a/dsp/codecs/audio_g711alaw.c b/dsp/codecs/audio_g711alaw.c
index b4a1d7e..27d7fe0 100644
--- a/dsp/codecs/audio_g711alaw.c
+++ b/dsp/codecs/audio_g711alaw.c
@@ -1,15 +1,5 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /* Copyright (c) 2016-2017, 2019 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
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
  */
 
 #include <linux/types.h>
diff --git a/dsp/codecs/audio_g711mlaw.c b/dsp/codecs/audio_g711mlaw.c
index 1cf8a97..57c7f1a 100644
--- a/dsp/codecs/audio_g711mlaw.c
+++ b/dsp/codecs/audio_g711mlaw.c
@@ -1,15 +1,5 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /* Copyright (c) 2016-2017, 2019 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
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
  */
 
 #include <linux/types.h>
diff --git a/dsp/q6afe.c b/dsp/q6afe.c
index 7a510be..23d30bc 100644
--- a/dsp/q6afe.c
+++ b/dsp/q6afe.c
@@ -7578,7 +7578,7 @@
 
 	ret = afe_q6_interface_prepare();
 	if (ret != 0) {
-		pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
+		pr_err_ratelimited("%s: Q6 interface prepare failed %d\n", __func__, ret);
 		return ret;
 	}
 
@@ -7599,7 +7599,7 @@
 	ret = q6afe_svc_pack_and_set_param_in_band(index, param_hdr,
 						   (u8 *) cfg);
 	if (ret < 0)
-		pr_err("%s: AFE clk cfg failed with ret %d\n",
+		pr_err_ratelimited("%s: AFE clk cfg failed with ret %d\n",
 		       __func__, ret);
 
 	mutex_unlock(&this_afe.afe_cmd_lock);
diff --git a/dsp/q6lsm.c b/dsp/q6lsm.c
index 96671ec..d55dfc3 100644
--- a/dsp/q6lsm.c
+++ b/dsp/q6lsm.c
@@ -89,6 +89,13 @@
 static int q6lsm_memory_unmap_regions(struct lsm_client *client,
 				      uint32_t handle);
 
+struct lsm_client_afe_data {
+	uint64_t fe_id;
+	uint16_t unprocessed_data;
+};
+
+static struct lsm_client_afe_data lsm_client_afe_data[LSM_MAX_SESSION_ID + 1];
+
 static int q6lsm_get_session_id_from_lsm_client(struct lsm_client *client)
 {
 	int n;
@@ -255,6 +262,8 @@
 	pr_debug("%s: Freeing session ID %d\n", __func__, client->session);
 	spin_lock_irqsave(&lsm_session_lock, flags);
 	lsm_session[client->session] = NULL;
+	lsm_client_afe_data[client->session].fe_id = 0;
+	lsm_client_afe_data[client->session].unprocessed_data = 0;
 	spin_unlock_irqrestore(&lsm_session_lock, flags);
 	client->session = LSM_INVALID_SESSION_ID;
 }
@@ -1063,6 +1072,72 @@
 }
 
 /**
+ * q6lsm_set_afe_data_format -
+ * command to set afe data format
+ *
+ * @fe_id: FrontEnd DAI link ID
+ * @afe_data_format: afe data format
+ *
+ * Returns 0 on success or -EINVAL on failure
+ */
+int q6lsm_set_afe_data_format(uint64_t fe_id, uint16_t afe_data_format)
+{
+	int n = 0;
+
+	if (0 != afe_data_format && 1 != afe_data_format)
+		goto done;
+
+	pr_debug("%s: afe data is %s\n", __func__,
+		 afe_data_format ? "unprocessed" : "processed");
+
+	for (n = LSM_MIN_SESSION_ID; n <= LSM_MAX_SESSION_ID; n++) {
+		if (0 == lsm_client_afe_data[n].fe_id) {
+			lsm_client_afe_data[n].fe_id = fe_id;
+			lsm_client_afe_data[n].unprocessed_data =
+							afe_data_format;
+			pr_debug("%s: session ID is %d, fe_id is %d\n",
+				 __func__, n, fe_id);
+			return 0;
+		}
+	}
+
+	pr_err("%s: all lsm sessions are taken\n", __func__);
+done:
+	return -EINVAL;
+}
+EXPORT_SYMBOL(q6lsm_set_afe_data_format);
+
+/**
+ * q6lsm_get_afe_data_format -
+ * command to get afe data format
+ *
+ * @fe_id: FrontEnd DAI link ID
+ * @afe_data_format: afe data format
+ *
+ */
+void q6lsm_get_afe_data_format(uint64_t fe_id, uint16_t *afe_data_format)
+{
+	int n = 0;
+
+	if (NULL == afe_data_format) {
+		pr_err("%s: Pointer afe_data_format is NULL\n", __func__);
+		return;
+	}
+
+	for (n = LSM_MIN_SESSION_ID; n <= LSM_MAX_SESSION_ID; n++) {
+		if (fe_id == lsm_client_afe_data[n].fe_id) {
+			*afe_data_format =
+				lsm_client_afe_data[n].unprocessed_data;
+			pr_debug("%s: session: %d, fe_id: %d, afe data: %s\n",
+				__func__, n, fe_id,
+				*afe_data_format ? "unprocessed" : "processed");
+			return;
+		}
+	}
+}
+EXPORT_SYMBOL(q6lsm_get_afe_data_format);
+
+/**
  * q6lsm_set_port_connected -
  *       command to set LSM port connected
  *
@@ -1092,14 +1167,19 @@
 	connectport_hdr.param_size = sizeof(connect_port);
 
 	client->connect_to_port = get_lsm_port();
+	if (ADM_LSM_PORT_ID != client->connect_to_port)
+		q6lsm_get_afe_data_format(client->fe_id,
+					  &client->unprocessed_data);
 	connect_port.minor_version = QLSM_PARAM_ID_MINOR_VERSION;
 	connect_port.port_id = client->connect_to_port;
+	connect_port.unprocessed_data = client->unprocessed_data;
 
 	rc = q6lsm_pack_and_set_params(client, &connectport_hdr,
 				       (uint8_t *) &connect_port,
 				       set_param_opcode);
 	if (rc)
 		pr_err("%s: Failed set_params, rc %d\n", __func__, rc);
+
 	return rc;
 }
 EXPORT_SYMBOL(q6lsm_set_port_connected);
diff --git a/include/dsp/q6lsm.h b/include/dsp/q6lsm.h
index e4a007f..af43cdd 100644
--- a/include/dsp/q6lsm.h
+++ b/include/dsp/q6lsm.h
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
  */
 #ifndef __Q6LSM_H__
 #define __Q6LSM_H__
@@ -102,6 +102,8 @@
 	uint32_t	event_type;
 	uint32_t	num_stages;
 	struct lsm_stage_config	stage_cfg[LSM_MAX_STAGES_PER_SESSION];
+	uint64_t	fe_id;
+	uint16_t	unprocessed_data;
 };
 
 struct lsm_stream_cmd_open_tx {
@@ -159,7 +161,7 @@
 	uint32_t	minor_version;
 	/* AFE port id that receives voice wake up data */
 	uint16_t	port_id;
-	uint16_t	reserved;
+	uint16_t	unprocessed_data;
 } __packed;
 
 struct lsm_param_poll_enable {
@@ -295,4 +297,6 @@
 int q6lsm_lab_out_ch_cfg(struct lsm_client *client, u8 *ch_map,
 		struct lsm_params_info_v2 *p_info);
 bool q6lsm_adsp_supports_multi_stage_detection(void);
+int q6lsm_set_afe_data_format(uint64_t fe_id, uint16_t afe_data_format);
+void q6lsm_get_afe_data_format(uint64_t fe_id, uint16_t *afe_data_format);
 #endif /* __Q6LSM_H__ */
diff --git a/include/soc/wcd-spi-ac.h b/include/soc/wcd-spi-ac.h
index 5131c49..e07d235 100644
--- a/include/soc/wcd-spi-ac.h
+++ b/include/soc/wcd-spi-ac.h
@@ -1,13 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
 /* Copyright (c) 2018-2019, 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
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
  */
 
 #ifndef __WCD_SPI_AC_H__
diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c
index c9cccf6..461e82f 100644
--- a/soc/swr-mstr-ctrl.c
+++ b/soc/swr-mstr-ctrl.c
@@ -249,7 +249,7 @@
 		if (swrm->clk_ref_count == 1) {
 			ret = swrm->clk(swrm->handle, true);
 			if (ret) {
-				dev_err(swrm->dev,
+				dev_err_ratelimited(swrm->dev,
 					"%s: clock enable req failed",
 					__func__);
 				--swrm->clk_ref_count;
@@ -1277,6 +1277,8 @@
 
 	mutex_lock(&swrm->reslock);
 	if (swrm_clk_request(swrm, true)) {
+		dev_err_ratelimited(swrm->dev, "%s:clk request failed\n",
+				__func__);
 		mutex_unlock(&swrm->reslock);
 		goto exit;
 	}
@@ -1447,8 +1449,15 @@
 	}
 
 	mutex_lock(&swrm->reslock);
-	if (swrm->lpass_core_hw_vote)
-		clk_prepare_enable(swrm->lpass_core_hw_vote);
+	if (swrm->lpass_core_hw_vote) {
+		ret = clk_prepare_enable(swrm->lpass_core_hw_vote);
+		if (ret < 0) {
+			dev_err(dev, "%s:lpass core hw enable failed\n",
+				__func__);
+			ret = IRQ_NONE;
+			goto exit;
+		}
+	}
 	swrm_clk_request(swrm, true);
 	mutex_unlock(&swrm->reslock);
 
@@ -1618,6 +1627,7 @@
 	swrm_clk_request(swrm, false);
 	if (swrm->lpass_core_hw_vote)
 		clk_disable_unprepare(swrm->lpass_core_hw_vote);
+exit:
 	mutex_unlock(&swrm->reslock);
 	swrm_unlock_sleep(swrm);
 	return ret;
diff --git a/soc/wcd-spi-ac.c b/soc/wcd-spi-ac.c
index ee7a7a9..87bdbb2 100644
--- a/soc/wcd-spi-ac.c
+++ b/soc/wcd-spi-ac.c
@@ -1,13 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-only
 /* Copyright (c) 2018-2019, 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
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
  */
 
 #include <linux/init.h>
diff --git a/soc/wcd_spi_ctl_v01.c b/soc/wcd_spi_ctl_v01.c
index 0e59ca3..a803fd0 100644
--- a/soc/wcd_spi_ctl_v01.c
+++ b/soc/wcd_spi_ctl_v01.c
@@ -1,14 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-only
 /* Copyright (c) 2018-2019, 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
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
  */
 #include <linux/qmi_encdec.h>
 #include <soc/qcom/msm_qmi_interface.h>
diff --git a/soc/wcd_spi_ctl_v01.h b/soc/wcd_spi_ctl_v01.h
index dd9b1c3..683caa4 100644
--- a/soc/wcd_spi_ctl_v01.h
+++ b/soc/wcd_spi_ctl_v01.h
@@ -1,14 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
 /* Copyright (c) 2018-2019, 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
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
  */
 #ifndef WCD_SPI_CTL_V01_H
 #define WCD_SPI_CTL_V01_H