Merge "dsp: q6adm: add ADM_LSM_AUDPROC_PERSISTENT cal type"
diff --git a/asoc/codecs/wcd934x/wcd934x.c b/asoc/codecs/wcd934x/wcd934x.c
index 8a70ea3..aa4afdc 100644
--- a/asoc/codecs/wcd934x/wcd934x.c
+++ b/asoc/codecs/wcd934x/wcd934x.c
@@ -3149,8 +3149,6 @@
 		/* Undo reset for MAD */
 		snd_soc_update_bits(codec, WCD934X_CPE_SS_MAD_CTL,
 				    0x02, 0x00);
-		snd_soc_update_bits(codec, WCD934X_CODEC_RPM_CLK_MCLK_CFG,
-					0x04, 0x04);
 	} else {
 		snd_soc_update_bits(codec, WCD934X_SOC_MAD_AUDIO_CTL_2,
 				    0x03, 0x00);
@@ -3160,8 +3158,6 @@
 		/* Turn off MAD clk */
 		snd_soc_update_bits(codec, WCD934X_CPE_SS_MAD_CTL,
 				    0x01, 0x00);
-		snd_soc_update_bits(codec, WCD934X_CODEC_RPM_CLK_MCLK_CFG,
-					0x04, 0x00);
 	}
 done:
 	return rc;
@@ -9386,6 +9382,7 @@
 	{WCD934X_HPH_R_TEST, 0x01, 0x01},
 	{WCD934X_CPE_FLL_CONFIG_CTL_2, 0xFF, 0x20},
 	{WCD934X_MBHC_NEW_CTL_2, 0x0C, 0x00},
+	{WCD934X_CODEC_RPM_CLK_MCLK_CFG, 0x04, 0x04},
 };
 
 static const struct tavil_reg_mask_val tavil_codec_reg_init_1_1_val[] = {
diff --git a/asoc/codecs/wsa881x.c b/asoc/codecs/wsa881x.c
index 2ef9e0a..d2a3938 100644
--- a/asoc/codecs/wsa881x.c
+++ b/asoc/codecs/wsa881x.c
@@ -1,5 +1,5 @@
 /*
- * 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
@@ -76,6 +76,7 @@
 enum {
 	WSA881X_DEV_DOWN,
 	WSA881X_DEV_UP,
+	WSA881X_DEV_READY,
 };
 
 /*
@@ -99,6 +100,7 @@
 	int version;
 	struct mutex bg_lock;
 	struct mutex res_lock;
+	struct mutex temp_lock;
 	struct snd_info_entry *entry;
 	struct snd_info_entry *version_entry;
 	int state;
@@ -491,6 +493,17 @@
 	.read = codec_debug_read,
 };
 
+static void wsa881x_regcache_sync(struct wsa881x_priv *wsa881x)
+{
+	mutex_lock(&wsa881x->res_lock);
+	if (wsa881x->state != WSA881X_DEV_READY) {
+		regcache_mark_dirty(wsa881x->regmap);
+		regcache_sync(wsa881x->regmap);
+		wsa881x->state = WSA881X_DEV_READY;
+	}
+	mutex_unlock(&wsa881x->res_lock);
+}
+
 static const struct reg_sequence wsa881x_pre_pmu_pa[] = {
 	{WSA881X_SPKR_DRV_GAIN, 0x41, 0},
 	{WSA881X_SPKR_MISC_CTL1, 0x01, 0},
@@ -850,7 +863,9 @@
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
+		mutex_lock(&wsa881x->temp_lock);
 		wsa881x_resource_acquire(codec, ENABLE);
+		mutex_unlock(&wsa881x->temp_lock);
 		wsa881x_boost_ctrl(codec, ENABLE);
 		break;
 	case SND_SOC_DAPM_POST_PMD:
@@ -858,7 +873,9 @@
 					    wsa881x->swr_slave->dev_num,
 					    false);
 		wsa881x_boost_ctrl(codec, DISABLE);
+		mutex_lock(&wsa881x->temp_lock);
 		wsa881x_resource_acquire(codec, DISABLE);
+		mutex_unlock(&wsa881x->temp_lock);
 		break;
 	}
 	return 0;
@@ -1103,13 +1120,8 @@
 			return -EINVAL;
 		}
 	}
-	mutex_lock(&wsa881x->res_lock);
-	if (!wsa881x->clk_cnt) {
-		regcache_mark_dirty(wsa881x->regmap);
-		regcache_sync(wsa881x->regmap);
-	}
-	mutex_unlock(&wsa881x->res_lock);
-
+	wsa881x_regcache_sync(wsa881x);
+	mutex_lock(&wsa881x->temp_lock);
 	wsa881x_resource_acquire(codec, ENABLE);
 
 	snd_soc_update_bits(codec, WSA881X_TADC_VALUE_CTL, 0x01, 0x00);
@@ -1122,6 +1134,7 @@
 	wsa_temp_reg->d2_lsb = snd_soc_read(codec, WSA881X_OTP_REG_4);
 
 	wsa881x_resource_acquire(codec, DISABLE);
+	mutex_unlock(&wsa881x->temp_lock);
 
 	return 0;
 }
@@ -1137,7 +1150,6 @@
 	dev = wsa881x->swr_slave;
 	wsa881x->codec = codec;
 	mutex_init(&wsa881x->bg_lock);
-	mutex_init(&wsa881x->res_lock);
 	wsa881x_init(codec);
 	snprintf(wsa881x->tz_pdata.name, sizeof(wsa881x->tz_pdata.name),
 		"%s.%x", "wsatz", (u8)dev->addr);
@@ -1159,7 +1171,6 @@
 	if (wsa881x->tz_pdata.tz_dev)
 		wsa881x_deinit_thermal(wsa881x->tz_pdata.tz_dev);
 	mutex_destroy(&wsa881x->bg_lock);
-	mutex_destroy(&wsa881x->res_lock);
 
 	return 0;
 }
@@ -1342,6 +1353,8 @@
 			__func__);
 		goto dev_err;
 	}
+	mutex_init(&wsa881x->res_lock);
+	mutex_init(&wsa881x->temp_lock);
 
 	return 0;
 
@@ -1364,6 +1377,8 @@
 	}
 	debugfs_remove_recursive(debugfs_wsa881x_dent);
 	debugfs_wsa881x_dent = NULL;
+	mutex_destroy(&wsa881x->res_lock);
+	mutex_destroy(&wsa881x->temp_lock);
 	snd_soc_unregister_codec(&pdev->dev);
 	if (wsa881x->pd_gpio)
 		gpio_free(wsa881x->pd_gpio);
@@ -1422,6 +1437,11 @@
 		dev_err(&pdev->dev, "%s: wsa881x is NULL\n", __func__);
 		return -EINVAL;
 	}
+	if (wsa881x->state == WSA881X_DEV_READY) {
+		dev_dbg(&pdev->dev, "%s: device already active\n", __func__);
+		return 0;
+	}
+
 	wsa881x->bg_cnt = 0;
 	wsa881x->clk_cnt = 0;
 	while (swr_get_logical_dev_num(pdev, pdev->addr, &devnum) && retry--) {
@@ -1429,8 +1449,8 @@
 		usleep_range(1000, 1100);
 	}
 	pdev->dev_num = devnum;
-	regcache_mark_dirty(wsa881x->regmap);
-	regcache_sync(wsa881x->regmap);
+	wsa881x_regcache_sync(wsa881x);
+
 	return 0;
 }
 
diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c
index e821717..0426679 100644
--- a/asoc/msm-pcm-routing-v2.c
+++ b/asoc/msm-pcm-routing-v2.c
@@ -3693,6 +3693,10 @@
 		msm_route_ec_ref_rx = 23;
 		ec_ref_port_id = AFE_PORT_ID_HDMI_OVER_DP_RX;
 		break;
+	case 24:
+		msm_route_ec_ref_rx = 24;
+		ec_ref_port_id = AFE_PORT_ID_PRIMARY_TDM_RX_1;
+		break;
 	default:
 		msm_route_ec_ref_rx = 0; /* NONE */
 		pr_err("%s EC ref rx %ld not valid\n",
@@ -3716,7 +3720,8 @@
 	"SLIM_5_RX", "SLIM_1_TX", "QUAT_TDM_TX_1",
 	"QUAT_TDM_RX_0", "QUAT_TDM_RX_1", "QUAT_TDM_RX_2", "SLIM_6_RX",
 	"TERT_MI2S_RX", "QUAT_MI2S_RX", "TERT_TDM_TX_0", "USB_AUDIO_RX",
-	"INT0_MI2S_RX", "INT4_MI2S_RX", "INT3_MI2S_TX", "DISPLAY_PORT"};
+	"INT0_MI2S_RX", "INT4_MI2S_RX", "INT3_MI2S_TX", "DISPLAY_PORT",
+	"PRI_TDM_RX_1"};
 
 static const struct soc_enum msm_route_ec_ref_rx_enum[] = {
 	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(ec_ref_rx), ec_ref_rx),
@@ -15670,6 +15675,7 @@
 	{"AUDIO_REF_EC_UL1 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"},
 	{"AUDIO_REF_EC_UL1 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"},
 	{"AUDIO_REF_EC_UL1 MUX", "SLIM_1_TX", "SLIMBUS_1_TX"},
+	{"AUDIO_REF_EC_UL1 MUX", "PRI_TDM_TX_3", "PRI_TDM_TX_3"},
 	{"AUDIO_REF_EC_UL1 MUX", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"},
 	{"AUDIO_REF_EC_UL1 MUX", "QUAT_TDM_RX_0", "QUAT_TDM_RX_0"},
 	{"AUDIO_REF_EC_UL1 MUX", "QUAT_TDM_RX_1", "QUAT_TDM_RX_1"},
@@ -15705,6 +15711,7 @@
 	{"AUDIO_REF_EC_UL8 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"},
 	{"AUDIO_REF_EC_UL8 MUX", "TERT_MI2S_TX", "TERT_MI2S_TX"},
 	{"AUDIO_REF_EC_UL8 MUX", "QUAT_MI2S_TX", "QUAT_MI2S_TX"},
+	{"AUDIO_REF_EC_UL8 MUX", "PRI_TDM_TX_3", "PRI_TDM_TX_3"},
 
 	{"AUDIO_REF_EC_UL9 MUX", "PRI_MI2S_TX", "PRI_MI2S_TX"},
 	{"AUDIO_REF_EC_UL9 MUX", "SEC_MI2S_TX", "SEC_MI2S_TX"},
diff --git a/dsp/q6adm.c b/dsp/q6adm.c
index 3a61224..ce297e1 100644
--- a/dsp/q6adm.c
+++ b/dsp/q6adm.c
@@ -2633,6 +2633,7 @@
 	}
 
 	if ((topology == VPM_TX_SM_ECNS_V2_COPP_TOPOLOGY) ||
+	    (topology == VPM_TX_SM_ECNS_COPP_TOPOLOGY) ||
 	    (topology == VPM_TX_DM_FLUENCE_COPP_TOPOLOGY) ||
 	    (topology == VPM_TX_DM_RFECNS_COPP_TOPOLOGY))
 		rate = 16000;
diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h
index a608a66..d313d64 100644
--- a/include/dsp/apr_audio-v2.h
+++ b/include/dsp/apr_audio-v2.h
@@ -4015,6 +4015,7 @@
 #define DEFAULT_POPP_TOPOLOGY				0x00010BE4
 #define COMPRESSED_PASSTHROUGH_DEFAULT_TOPOLOGY         0x0001076B
 #define COMPRESSED_PASSTHROUGH_NONE_TOPOLOGY            0x00010774
+#define VPM_TX_SM_ECNS_COPP_TOPOLOGY			0x00010F71
 #define VPM_TX_SM_ECNS_V2_COPP_TOPOLOGY			0x00010F89
 #define VPM_TX_DM_FLUENCE_COPP_TOPOLOGY			0x00010F72
 #define VPM_TX_QMIC_FLUENCE_COPP_TOPOLOGY		0x00010F75
diff --git a/include/uapi/linux/msm_audio_calibration.h b/include/uapi/linux/msm_audio_calibration.h
index 3b97ab2..c5811d0 100644
--- a/include/uapi/linux/msm_audio_calibration.h
+++ b/include/uapi/linux/msm_audio_calibration.h
@@ -103,6 +103,7 @@
 	AFE_LSM_TX_CAL_TYPE,
 	ADM_LSM_TOPOLOGY_CAL_TYPE,
 	ADM_LSM_AUDPROC_CAL_TYPE,
+	ADM_LSM_AUDPROC_PERSISTENT_CAL_TYPE,
 	MAX_CAL_TYPES,
 };
 
@@ -115,6 +116,7 @@
 #define AFE_LSM_TX_CAL_TYPE AFE_LSM_TX_CAL_TYPE
 #define ADM_LSM_TOPOLOGY_CAL_TYPE ADM_LSM_TOPOLOGY_CAL_TYPE
 #define ADM_LSM_AUDPROC_CAL_TYPE ADM_LSM_AUDPROC_CAL_TYPE
+#define ADM_LSM_AUDPROC_PERSISTENT_CAL_TYPE ADM_LSM_AUDPROC_PERSISTENT_CAL_TYPE
 #define LSM_CAL_TYPES
 
 #define TOPOLOGY_SPECIFIC_CHANNEL_INFO
diff --git a/soc/soundwire.c b/soc/soundwire.c
index cda4789..69a9ed4 100644
--- a/soc/soundwire.c
+++ b/soc/soundwire.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
@@ -245,7 +245,7 @@
 	if (!dev->group_id)
 		return 0;
 
-	if (master->gr_sid == dev_num)
+	if (master->gr_sid != dev_num)
 		return 0;
 
 	if (master->remove_from_group && master->remove_from_group(master))
diff --git a/soc/swr-wcd-ctrl.c b/soc/swr-wcd-ctrl.c
index c5ba37b..455e03b 100644
--- a/soc/swr-wcd-ctrl.c
+++ b/soc/swr-wcd-ctrl.c
@@ -1756,6 +1756,8 @@
 		    (swrm->state == SWR_MSTR_UP)) {
 			dev_dbg(swrm->dev, "%s: SWR master is already UP: %d\n",
 				__func__, swrm->state);
+			list_for_each_entry(swr_dev, &mstr->devices, dev_list)
+				swr_reset_device(swr_dev);
 		} else {
 			pm_runtime_mark_last_busy(&pdev->dev);
 			mutex_unlock(&swrm->reslock);