Prechádzať zdrojové kódy

Merge ab02a0d9c1a39e051abdefbc29d121838792769b on remote branch

Change-Id: Iead80efbe86dda699575a57d054f157faf996eeb
Linux Build Service Account 4 rokov pred
rodič
commit
51e80f180a

+ 8 - 1
Makefile

@@ -25,8 +25,11 @@ endif
 ifeq ($(CONFIG_ARCH_HOLI), y)
 include $(srctree)/techpack/audio/config/holiauto.conf
 endif
+ifeq ($(CONFIG_ARCH_SA8155), y)
+include $(srctree)/techpack/audio/config/sa8155auto.conf
+export
+endif
 endif
-
 # Use USERINCLUDE when you must reference the UAPI directories only.
 USERINCLUDE     += \
                 -I$(srctree)/techpack/audio/include/uapi/audio
@@ -66,6 +69,10 @@ ifeq ($(CONFIG_ARCH_HOLI), y)
 LINUXINCLUDE    += \
                 -include $(srctree)/techpack/audio/config/holiautoconf.h
 endif
+ifeq ($(CONFIG_ARCH_SA8155), y)
+LINUXINCLUDE    += \
+                -include $(srctree)/techpack/audio/config/sa8155autoconf.h
+endif
 
 obj-y += soc/
 obj-y += dsp/

+ 2 - 0
asoc/codecs/Kbuild

@@ -164,8 +164,10 @@ ifdef CONFIG_SND_SOC_WSA881X_ANALOG
 	WSA881X_ANALOG_OBJS += wsa881x-analog.o
 	WSA881X_ANALOG_OBJS += wsa881x-tables-analog.o
 	WSA881X_ANALOG_OBJS += wsa881x-regmap-analog.o
+ifndef CONFIG_WSA881X_TEMP_SENSOR_DISABLE
 	WSA881X_ANALOG_OBJS += wsa881x-temp-sensor.o
 endif
+endif
 ifdef CONFIG_SND_SOC_MSM_STUB
 	STUB_OBJS += msm_stub.o
 endif

+ 36 - 0
asoc/codecs/bolero/bolero-cdc.c

@@ -688,6 +688,7 @@ int bolero_register_macro(struct device *dev, u16 macro_id,
 				bolero_mclk_mux_tbl[macro_id][MCLK_MUX0];
 	if (macro_id == TX_MACRO) {
 		priv->macro_params[macro_id].reg_wake_irq = ops->reg_wake_irq;
+		priv->macro_params[macro_id].clk_switch = ops->clk_switch;
 		priv->macro_params[macro_id].reg_evt_listener =
 							ops->reg_evt_listener;
 		priv->macro_params[macro_id].clk_enable = ops->clk_enable;
@@ -762,6 +763,7 @@ void bolero_unregister_macro(struct device *dev, u16 macro_id)
 	priv->macro_params[macro_id].dev = NULL;
 	if (macro_id == TX_MACRO) {
 		priv->macro_params[macro_id].reg_wake_irq = NULL;
+		priv->macro_params[macro_id].clk_switch = NULL;
 		priv->macro_params[macro_id].reg_evt_listener = NULL;
 		priv->macro_params[macro_id].clk_enable = NULL;
 	}
@@ -1065,6 +1067,40 @@ int bolero_register_wake_irq(struct snd_soc_component *component,
 }
 EXPORT_SYMBOL(bolero_register_wake_irq);
 
+/**
+ * bolero_tx_clk_switch - Switch tx macro clock
+ *
+ * @component: pointer to codec component instance.
+ *
+ * @clk_src: clk source
+ *
+ * Returns 0 on success or -EINVAL on error.
+ */
+int bolero_tx_clk_switch(struct snd_soc_component *component, int clk_src)
+{
+	struct bolero_priv *priv = NULL;
+	int ret = 0;
+
+	if (!component)
+		return -EINVAL;
+
+	priv = snd_soc_component_get_drvdata(component);
+	if (!priv)
+		return -EINVAL;
+
+	if (!bolero_is_valid_codec_dev(priv->dev)) {
+		dev_err(component->dev, "%s: invalid codec\n", __func__);
+		return -EINVAL;
+	}
+
+	if (priv->macro_params[TX_MACRO].clk_switch)
+		ret = priv->macro_params[TX_MACRO].clk_switch(component,
+							      clk_src);
+
+	return ret;
+}
+EXPORT_SYMBOL(bolero_tx_clk_switch);
+
 /**
  * bolero_tx_mclk_enable - Enable/Disable TX Macro mclk
  *

+ 13 - 0
asoc/codecs/bolero/bolero-cdc.h

@@ -37,6 +37,11 @@ enum {
 	BOLERO_ADC_MAX
 };
 
+enum {
+	CLK_SRC_TX_RCG = 0,
+	CLK_SRC_VA_RCG,
+};
+
 enum {
 	BOLERO_MACRO_EVT_RX_MUTE = 1, /* for RX mute/unmute */
 	BOLERO_MACRO_EVT_IMPED_TRUE, /* for imped true */
@@ -74,6 +79,7 @@ struct macro_ops {
 	int (*set_port_map)(struct snd_soc_component *component, u32 uc,
 			    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 (*clk_enable)(struct snd_soc_component *c, bool en);
 	char __iomem *io_base;
@@ -100,6 +106,7 @@ void bolero_clear_amic_tx_hold(struct device *dev, u16 adc_n);
 int bolero_runtime_resume(struct device *dev);
 int bolero_runtime_suspend(struct device *dev);
 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);
 void bolero_wsa_pa_on(struct device *dev, bool adie_lb);
@@ -172,6 +179,12 @@ static inline int bolero_set_port_map(struct snd_soc_component *component,
 	return 0;
 }
 
+static inline int bolero_tx_clk_switch(struct snd_soc_component *component,
+					int clk_src)
+{
+	return 0;
+}
+
 static inline int bolero_register_event_listener(
 					struct snd_soc_component *component,
 					bool enable)

+ 94 - 8
asoc/codecs/bolero/tx-macro.c

@@ -179,6 +179,8 @@ struct tx_macro_priv {
 	int amic_sample_rate;
 	bool lpi_enable;
 	bool register_event_listener;
+	u16 current_clk_id;
+	int disable_afe_wakeup_event_listener;
 };
 
 static bool tx_macro_get_data(struct snd_soc_component *component,
@@ -1817,11 +1819,11 @@ static const struct snd_soc_dapm_widget tx_macro_dapm_widgets_v3[] = {
 			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
 			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
 
-	SND_SOC_DAPM_SUPPLY_S("TX_SWR_CLK", 0, SND_SOC_NOPM, 0, 0,
+	SND_SOC_DAPM_SUPPLY_S("TX_SWR_CLK", -1, SND_SOC_NOPM, 0, 0,
 			tx_macro_tx_swr_clk_event,
 			SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 
-	SND_SOC_DAPM_SUPPLY_S("VA_SWR_CLK", 0, SND_SOC_NOPM, 0, 0,
+	SND_SOC_DAPM_SUPPLY_S("VA_SWR_CLK", -1, SND_SOC_NOPM, 0, 0,
 			tx_macro_va_swr_clk_event,
 			SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 };
@@ -2644,17 +2646,19 @@ static int tx_macro_register_event_listener(struct snd_soc_component *component,
 	if (tx_priv->swr_ctrl_data &&
 		(!tx_priv->tx_swr_clk_cnt || !tx_priv->va_swr_clk_cnt)) {
 		if (enable) {
-			ret = swrm_wcd_notify(
-				tx_priv->swr_ctrl_data[0].tx_swr_pdev,
-				SWR_REGISTER_WAKEUP, NULL);
+			if (!tx_priv->disable_afe_wakeup_event_listener)
+				ret = swrm_wcd_notify(
+					tx_priv->swr_ctrl_data[0].tx_swr_pdev,
+					SWR_REGISTER_WAKEUP, NULL);
 			msm_cdc_pinctrl_set_wakeup_capable(
 					tx_priv->tx_swr_gpio_p, false);
 		} else {
 			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,
-				SWR_DEREGISTER_WAKEUP, NULL);
+			if (!tx_priv->disable_afe_wakeup_event_listener)
+				ret = swrm_wcd_notify(
+					tx_priv->swr_ctrl_data[0].tx_swr_pdev,
+					SWR_DEREGISTER_WAKEUP, NULL);
 		}
 	}
 
@@ -2848,6 +2852,70 @@ static int tx_macro_clk_div_get(struct snd_soc_component *component)
 	return tx_priv->dmic_clk_div;
 }
 
+static int tx_macro_clk_switch(struct snd_soc_component *component, int clk_src)
+{
+	struct device *tx_dev = NULL;
+	struct tx_macro_priv *tx_priv = NULL;
+	int ret = 0;
+
+	if (!component)
+		return -EINVAL;
+
+	tx_dev = bolero_get_device_ptr(component->dev, TX_MACRO);
+	if (!tx_dev) {
+		dev_err(component->dev,
+			"%s: null device for macro!\n", __func__);
+		return -EINVAL;
+	}
+	tx_priv = dev_get_drvdata(tx_dev);
+	if (!tx_priv) {
+		dev_err(component->dev,
+			"%s: priv is null for macro!\n", __func__);
+		return -EINVAL;
+	}
+	dev_dbg(component->dev,
+		"%s: va_swr_clk_cnt %d, tx_swr_clk_cnt %d, tx_clk_status %d\n",
+		__func__, tx_priv->va_swr_clk_cnt,
+		tx_priv->tx_swr_clk_cnt, tx_priv->tx_clk_status);
+	if (tx_priv->current_clk_id == clk_src) {
+		dev_dbg(component->dev,
+			"%s: requested clk %d is same as current\n",
+			__func__, clk_src);
+		return 0;
+	} else if (tx_priv->va_swr_clk_cnt != 0 && tx_priv->tx_clk_status) {
+		ret = bolero_clk_rsc_request_clock(tx_priv->dev,
+				TX_CORE_CLK,
+				clk_src,
+				true);
+		if (ret) {
+			dev_dbg(component->dev,
+				"%s: request clock %d enable failed\n",
+				__func__, clk_src);
+			goto ret;
+		}
+		ret = bolero_clk_rsc_request_clock(tx_priv->dev,
+				TX_CORE_CLK,
+				tx_priv->current_clk_id,
+				false);
+		if (ret) {
+			dev_dbg(component->dev,
+				"%s: request clock  disable failed\n",
+				__func__);
+			bolero_clk_rsc_request_clock(tx_priv->dev,
+				TX_CORE_CLK,
+				clk_src,
+				false);
+			goto ret;
+		}
+		tx_priv->current_clk_id = clk_src;
+	} else {
+		ret = -EBUSY;
+	}
+
+ret:
+	return ret;
+}
+
 static int tx_macro_core_vote(void *handle, bool enable)
 {
 	struct tx_macro_priv *tx_priv = (struct tx_macro_priv *) handle;
@@ -3331,6 +3399,7 @@ static void tx_macro_init_ops(struct macro_ops *ops,
 	ops->reg_wake_irq = tx_macro_reg_wake_irq;
 	ops->set_port_map = tx_macro_set_port_map;
 	ops->clk_div_get = tx_macro_clk_div_get;
+	ops->clk_switch = tx_macro_clk_switch;
 	ops->reg_evt_listener = tx_macro_register_event_listener;
 	ops->clk_enable = __tx_macro_mclk_enable;
 }
@@ -3345,6 +3414,9 @@ static int tx_macro_probe(struct platform_device *pdev)
 	const char *dmic_sample_rate = "qcom,tx-dmic-sample-rate";
 	u32 is_used_tx_swr_gpio = 1;
 	const char *is_used_tx_swr_gpio_dt = "qcom,is-used-swr-gpio";
+	u32 disable_afe_wakeup_event_listener = 0;
+	const char *disable_afe_wakeup_event_listener_dt =
+			"qcom,disable-afe-wakeup-event-listener";
 
 	if (!bolero_is_va_macro_registered(&pdev->dev)) {
 		dev_err(&pdev->dev,
@@ -3411,6 +3483,19 @@ static int tx_macro_probe(struct platform_device *pdev)
 		sample_rate, tx_priv) == TX_MACRO_DMIC_SAMPLE_RATE_UNDEFINED)
 			return -EINVAL;
 	}
+
+	if (of_find_property(pdev->dev.of_node,
+			     disable_afe_wakeup_event_listener_dt, NULL)) {
+		ret = of_property_read_u32(pdev->dev.of_node,
+					   disable_afe_wakeup_event_listener_dt,
+					   &disable_afe_wakeup_event_listener);
+		if (ret)
+			dev_dbg(&pdev->dev, "%s: error reading %s in dt\n",
+				__func__, disable_afe_wakeup_event_listener_dt);
+	}
+	tx_priv->disable_afe_wakeup_event_listener =
+			disable_afe_wakeup_event_listener;
+
 	if (is_used_tx_swr_gpio) {
 		tx_priv->reset_swr = true;
 		INIT_WORK(&tx_priv->tx_macro_add_child_devices_work,
@@ -3429,6 +3514,7 @@ static int tx_macro_probe(struct platform_device *pdev)
 	tx_macro_init_ops(&ops, tx_io_base);
 	ops.clk_id_req = TX_CORE_CLK;
 	ops.default_clk_id = TX_CORE_CLK;
+	tx_priv->current_clk_id = TX_CORE_CLK;
 	ret = bolero_register_macro(&pdev->dev, TX_MACRO, &ops);
 	if (ret) {
 		dev_err(&pdev->dev,

+ 67 - 24
asoc/codecs/bolero/va-macro.c

@@ -173,7 +173,6 @@ struct va_macro_priv {
 	bool lpi_enable;
 	bool register_event_listener;
 	int dec_mode[VA_MACRO_NUM_DECIMATORS];
-	int disable_afe_wakeup_event_listener;
 };
 
 static bool va_macro_get_data(struct snd_soc_component *component,
@@ -393,12 +392,64 @@ static int va_macro_swr_pwr_event_v2(struct snd_soc_dapm_widget *w,
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
+		if (va_priv->default_clk_id != VA_CORE_CLK) {
+			ret = bolero_clk_rsc_request_clock(va_priv->dev,
+					va_priv->default_clk_id,
+					VA_CORE_CLK,
+					true);
+			if (ret) {
+				dev_dbg(component->dev,
+					"%s: request clock VA_CLK enable failed\n",
+					__func__);
+				break;
+			}
+			ret = bolero_clk_rsc_request_clock(va_priv->dev,
+					va_priv->default_clk_id,
+					TX_CORE_CLK,
+					false);
+			if (ret) {
+				dev_dbg(component->dev,
+					"%s: request clock TX_CLK enable failed\n",
+					__func__);
+				bolero_clk_rsc_request_clock(va_priv->dev,
+					va_priv->default_clk_id,
+					VA_CORE_CLK,
+					false);
+				break;
+			}
+		}
 		msm_cdc_pinctrl_set_wakeup_capable(
 				va_priv->va_swr_gpio_p, false);
 		break;
 	case SND_SOC_DAPM_POST_PMD:
 		msm_cdc_pinctrl_set_wakeup_capable(
 				va_priv->va_swr_gpio_p, true);
+		if (va_priv->default_clk_id == TX_CORE_CLK) {
+			ret = bolero_clk_rsc_request_clock(va_priv->dev,
+					va_priv->default_clk_id,
+					TX_CORE_CLK,
+					true);
+			if (ret) {
+				dev_dbg(component->dev,
+					"%s: request clock TX_CLK disable failed\n",
+					__func__);
+				break;
+			}
+			ret = bolero_clk_rsc_request_clock(va_priv->dev,
+					va_priv->default_clk_id,
+					VA_CORE_CLK,
+					false);
+			if (ret) {
+				dev_dbg(component->dev,
+					"%s: request clock VA_CLK disable failed\n",
+					__func__);
+				bolero_clk_rsc_request_clock(va_priv->dev,
+					TX_CORE_CLK,
+					TX_CORE_CLK,
+					false);
+				break;
+			}
+		}
 		break;
 	default:
 		dev_err(va_priv->dev,
@@ -436,8 +487,12 @@ static int va_macro_swr_pwr_event(struct snd_soc_dapm_widget *w,
 					"%s: lpass audio hw enable failed\n",
 					__func__);
 		}
-		if (va_priv->lpi_enable &&
-		    !va_priv->disable_afe_wakeup_event_listener) {
+		if (!ret) {
+			if (bolero_tx_clk_switch(component, VA_CORE_CLK))
+				dev_dbg(va_dev, "%s: clock switch failed\n",
+					__func__);
+		}
+		if (va_priv->lpi_enable) {
 			bolero_register_event_listener(component, true);
 			va_priv->register_event_listener = true;
 		}
@@ -447,6 +502,8 @@ static int va_macro_swr_pwr_event(struct snd_soc_dapm_widget *w,
 			va_priv->register_event_listener = false;
 			bolero_register_event_listener(component, false);
 		}
+		if (bolero_tx_clk_switch(component, TX_CORE_CLK))
+			dev_dbg(va_dev, "%s: clock switch failed\n",__func__);
 		if (va_priv->lpass_audio_hw_vote)
 			digital_cdc_rsc_mgr_hw_vote_disable(
 				va_priv->lpass_audio_hw_vote);
@@ -506,10 +563,11 @@ static int va_macro_mclk_event(struct snd_soc_dapm_widget *w,
 			ret = bolero_tx_mclk_enable(component, 1);
 		break;
 	case SND_SOC_DAPM_POST_PMD:
-		if (va_priv->lpi_enable)
+		if (va_priv->lpi_enable) {
 			va_macro_mclk_enable(va_priv, 0, true);
-		else
+		} else {
 			bolero_tx_mclk_enable(component, 0);
+		}
 
 		if (va_priv->tx_clk_status > 0) {
 			bolero_clk_rsc_request_clock(va_priv->dev,
@@ -1903,15 +1961,15 @@ static const struct snd_soc_dapm_widget va_macro_dapm_widgets_v2[] = {
 		VA_MACRO_AIF3_CAP, 0,
 		va_aif3_cap_mixer_v2, ARRAY_SIZE(va_aif3_cap_mixer_v2)),
 
-	SND_SOC_DAPM_SUPPLY_S("VA_SWR_PWR", -1, SND_SOC_NOPM, 0, 0,
+	SND_SOC_DAPM_SUPPLY_S("VA_SWR_PWR", 0, SND_SOC_NOPM, 0, 0,
 			      va_macro_swr_pwr_event_v2,
 			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 
-	SND_SOC_DAPM_SUPPLY_S("VA_TX_SWR_CLK", 0, SND_SOC_NOPM, 0, 0,
+	SND_SOC_DAPM_SUPPLY_S("VA_TX_SWR_CLK", -1, SND_SOC_NOPM, 0, 0,
 			      va_macro_tx_swr_clk_event_v2,
 			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 
-	SND_SOC_DAPM_SUPPLY_S("VA_SWR_CLK", 0, SND_SOC_NOPM, 0, 0,
+	SND_SOC_DAPM_SUPPLY_S("VA_SWR_CLK", -1, SND_SOC_NOPM, 0, 0,
 			      va_macro_swr_clk_event_v2,
 			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 };
@@ -1945,7 +2003,7 @@ static const struct snd_soc_dapm_widget va_macro_dapm_widgets_v3[] = {
 			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
 			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
 
-	SND_SOC_DAPM_SUPPLY_S("VA_SWR_PWR", -1, SND_SOC_NOPM, 0, 0,
+	SND_SOC_DAPM_SUPPLY_S("VA_SWR_PWR", 0, SND_SOC_NOPM, 0, 0,
 			      va_macro_swr_pwr_event,
 			      SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
 };
@@ -2997,10 +3055,7 @@ static int va_macro_probe(struct platform_device *pdev)
 	u32 default_clk_id = 0;
 	struct clk *lpass_audio_hw_vote = NULL;
 	u32 is_used_va_swr_gpio = 0;
-	u32 disable_afe_wakeup_event_listener = 0;
 	const char *is_used_va_swr_gpio_dt = "qcom,is-used-swr-gpio";
-	const char *disable_afe_wakeup_event_listener_dt =
-			"qcom,disable-afe-wakeup-event-listener";
 
 	va_priv = devm_kzalloc(&pdev->dev, sizeof(struct va_macro_priv),
 			    GFP_KERNEL);
@@ -3043,18 +3098,6 @@ static int va_macro_probe(struct platform_device *pdev)
 		}
 	}
 
-	if (of_find_property(pdev->dev.of_node,
-			     disable_afe_wakeup_event_listener_dt, NULL)) {
-		ret = of_property_read_u32(pdev->dev.of_node,
-					   disable_afe_wakeup_event_listener_dt,
-					   &disable_afe_wakeup_event_listener);
-		if (ret)
-			dev_dbg(&pdev->dev, "%s: error reading %s in dt\n",
-				__func__, disable_afe_wakeup_event_listener_dt);
-	}
-	va_priv->disable_afe_wakeup_event_listener =
-			disable_afe_wakeup_event_listener;
-
 	va_priv->va_swr_gpio_p = of_parse_phandle(pdev->dev.of_node,
 					"qcom,va-swr-gpios", 0);
 	if (!va_priv->va_swr_gpio_p && is_used_va_swr_gpio) {

+ 8 - 1
asoc/codecs/swr-dmic.c

@@ -220,11 +220,18 @@ static int dmic_swr_ctrl(struct snd_soc_dapm_widget *w,
 	u8 port_type = 0;
 	u8 port_id = w->shift;
 
+	if (port_id >= SWR_DMIC_MAX_PORTS)
+	{
+		dev_err(component->dev, "%s: invalid port id: %d\n",
+			__func__, port_id);
+		return -EINVAL;
+	}
+
 	/*
 	 * Port 1 is high quality / 2.4 or 3.072 Mbps
 	 * Port 2 is listen low power / 0.6 or 0.768 Mbps
 	 */
-	if(port_id == SWR_DMIC_HIFI_PORT)
+	if (port_id == SWR_DMIC_HIFI_PORT)
 		ch_rate = SWR_CLK_RATE_2P4MHZ;
 	else
 		ch_rate = SWR_CLK_RATE_0P6MHZ;

+ 0 - 28
asoc/codecs/wcd-mbhc-v2.c

@@ -515,15 +515,6 @@ static void wcd_mbhc_set_and_turnoff_hph_padac(struct wcd_mbhc *mbhc)
 int wcd_mbhc_get_impedance(struct wcd_mbhc *mbhc, uint32_t *zl,
 			uint32_t *zr)
 {
-	int detection_type = -EINVAL;
-
-	WCD_MBHC_REG_READ(WCD_MBHC_MECH_DETECTION_TYPE, detection_type);
-	/* Call compute impedance only when accessory is inserted */
-	if (!detection_type) {
-		if (mbhc->mbhc_cb->compute_impedance)
-			mbhc->mbhc_cb->compute_impedance(mbhc,
-						&mbhc->zl, &mbhc->zr);
-	}
 	*zl = mbhc->zl;
 	*zr = mbhc->zr;
 
@@ -1630,8 +1621,6 @@ static int wcd_mbhc_set_keycode(struct wcd_mbhc *mbhc)
 static int wcd_mbhc_usbc_ana_event_handler(struct notifier_block *nb,
 					   unsigned long mode, void *ptr)
 {
-	unsigned int l_det_en = 0;
-	unsigned int detection_type = 0;
 	struct wcd_mbhc *mbhc = container_of(nb, struct wcd_mbhc, fsa_nb);
 
 	if (!mbhc)
@@ -1644,23 +1633,6 @@ static int wcd_mbhc_usbc_ana_event_handler(struct notifier_block *nb,
 			mbhc->mbhc_cb->clk_setup(mbhc->component, true);
 		/* insertion detected, enable L_DET_EN */
 		WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_L_DET_EN, 1);
-	} else {
-		WCD_MBHC_REG_READ(WCD_MBHC_MECH_DETECTION_TYPE, detection_type);
-		WCD_MBHC_REG_READ(WCD_MBHC_L_DET_EN, l_det_en);
-		/* If both l_det_en and detection type are set, it means device was
-		 * unplugged during SSR and detection interrupt was not handled.
-		 * So trigger device disconnect */
-		if (detection_type && l_det_en) {
-			/* Set the detection type appropriately */
-			WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_MECH_DETECTION_TYPE,
-						 !detection_type);
-			/* Set current plug type to the state before SSR */
-			mbhc->current_plug = mbhc->plug_before_ssr;
-
-			wcd_mbhc_swch_irq_handler(mbhc);
-			mbhc->mbhc_cb->lock_sleep(mbhc, false);
-			mbhc->plug_before_ssr = MBHC_PLUG_TYPE_NONE;
-		}
 	}
 	return 0;
 }

+ 33 - 17
asoc/codecs/wcd938x/wcd938x.c

@@ -1883,9 +1883,12 @@ static int wcd938x_enable_req(struct snd_soc_dapm_widget *w,
 		default:
 			break;
 		}
-		if (wcd938x->adc_count == 0)
+		if (wcd938x->adc_count == 0) {
 			snd_soc_component_update_bits(component,
 					WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x10, 0x00);
+			snd_soc_component_update_bits(component,
+					WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x08, 0x00);
+		}
 		break;
 	};
 	return ret;
@@ -2156,8 +2159,6 @@ static int wcd938x_event_notify(struct notifier_block *block,
 						     WCD938X_EVT_SSR_DOWN,
 						     NULL);
 		wcd938x->mbhc->wcd_mbhc.deinit_in_progress = true;
-		wcd938x->mbhc->wcd_mbhc.plug_before_ssr =
-					wcd938x->mbhc->wcd_mbhc.current_plug;
 		mbhc = &wcd938x->mbhc->wcd_mbhc;
 		wcd938x->usbc_hs_status = get_usbc_hs_status(component,
 						mbhc->mbhc_cfg);
@@ -2183,8 +2184,6 @@ static int wcd938x_event_notify(struct notifier_block *block,
 				__func__);
 		} else {
 			wcd938x_mbhc_hs_detect(component, mbhc->mbhc_cfg);
-			if (wcd938x->usbc_hs_status)
-				mdelay(500);
 		}
 		wcd938x->mbhc->wcd_mbhc.deinit_in_progress = false;
 		wcd938x->dev_up = true;
@@ -2192,6 +2191,8 @@ static int wcd938x_event_notify(struct notifier_block *block,
 			blocking_notifier_call_chain(&wcd938x->notifier,
 						     WCD938X_EVT_SSR_UP,
 						     NULL);
+		if (wcd938x->usbc_hs_status)
+			mdelay(500);
 		break;
 	case BOLERO_SLV_EVT_CLK_NOTIFY:
 		snd_soc_component_update_bits(component,
@@ -2842,15 +2843,22 @@ static int wcd938x_tx_master_ch_get(struct snd_kcontrol *kcontrol,
 {
 	struct snd_soc_component *component =
 				snd_soc_kcontrol_component(kcontrol);
-	struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
-	int slave_ch_idx;
+	struct wcd938x_priv *wcd938x = NULL;
+	int slave_ch_idx = -EINVAL;
+
+	if (component == NULL)
+		return -EINVAL;
+
+	wcd938x = snd_soc_component_get_drvdata(component);
+	if (wcd938x == NULL)
+		return -EINVAL;
 
 	wcd938x_tx_get_slave_ch_type_idx(kcontrol->id.name, &slave_ch_idx);
+	if (slave_ch_idx < 0 || slave_ch_idx >= WCD938X_MAX_SLAVE_CH_TYPES)
+		return -EINVAL;
 
-	if (slave_ch_idx != -EINVAL)
-		ucontrol->value.integer.value[0] =
-				wcd938x_slave_get_master_ch_val(
-				wcd938x->tx_master_ch_map[slave_ch_idx]);
+	ucontrol->value.integer.value[0] = wcd938x_slave_get_master_ch_val(
+			wcd938x->tx_master_ch_map[slave_ch_idx]);
 
 	return 0;
 }
@@ -2860,19 +2868,27 @@ static int wcd938x_tx_master_ch_put(struct snd_kcontrol *kcontrol,
 {
 	struct snd_soc_component *component =
 				snd_soc_kcontrol_component(kcontrol);
-	struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
-	int slave_ch_idx;
+	struct wcd938x_priv *wcd938x = NULL;
+	int slave_ch_idx = -EINVAL;
+
+	if (component == NULL)
+		return -EINVAL;
+
+	wcd938x = snd_soc_component_get_drvdata(component);
+	if (wcd938x == NULL)
+		return -EINVAL;
 
 	wcd938x_tx_get_slave_ch_type_idx(kcontrol->id.name, &slave_ch_idx);
 
+	if (slave_ch_idx < 0 || slave_ch_idx >= WCD938X_MAX_SLAVE_CH_TYPES)
+		return -EINVAL;
+
 	dev_dbg(component->dev, "%s: slave_ch_idx: %d", __func__, slave_ch_idx);
 	dev_dbg(component->dev, "%s: ucontrol->value.enumerated.item[0] = %ld\n",
 			__func__, ucontrol->value.enumerated.item[0]);
 
-	if (slave_ch_idx != -EINVAL)
-		wcd938x->tx_master_ch_map[slave_ch_idx] =
-				wcd938x_slave_get_master_ch(
-					ucontrol->value.enumerated.item[0]);
+	wcd938x->tx_master_ch_map[slave_ch_idx] = wcd938x_slave_get_master_ch(
+				ucontrol->value.enumerated.item[0]);
 	return 0;
 }
 

+ 19 - 5
asoc/codecs/wsa881x-analog.c

@@ -34,6 +34,7 @@
 
 #define SPK_GAIN_12DB 4
 #define WIDGET_NAME_MAX_SIZE 80
+#define REGMAP_REGISTER_CHECK_RETRY 30
 
 #define MAX_NAME_LEN 30
 #define WSA881X_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
@@ -102,7 +103,7 @@ static int32_t wsa881x_resource_acquire(struct snd_soc_component *component,
 
 const char *wsa_tz_names[] = {"wsa881x.0e", "wsa881x.0f"};
 
-struct wsa881x_pdata wsa_pdata[MAX_WSA881X_DEVICE];
+static struct wsa881x_pdata wsa_pdata[MAX_WSA881X_DEVICE];
 
 static bool pinctrl_init;
 
@@ -1142,6 +1143,7 @@ static int wsa881x_probe(struct snd_soc_component *component)
 {
 	struct i2c_client *client;
 	int ret = 0;
+	int retry = REGMAP_REGISTER_CHECK_RETRY;
 	int wsa881x_index = 0;
 	struct snd_soc_dapm_context *dapm =
 					snd_soc_component_get_dapm(component);
@@ -1165,6 +1167,16 @@ static int wsa881x_probe(struct snd_soc_component *component)
 	wsa_pdata[wsa881x_index].tz_pdata.wsa_temp_reg_read =
 						wsa881x_temp_reg_read;
 	snd_soc_component_set_drvdata(component, &wsa_pdata[wsa881x_index]);
+	while (retry) {
+		if (wsa_pdata[wsa881x_index].regmap[WSA881X_ANALOG_SLAVE]
+							!= NULL)
+			break;
+		msleep(100);
+		retry--;
+	}
+	if (!retry)
+		dev_err(&client->dev, "%s: max retry expired and regmap of\n"
+				"analog slave not initilized\n", __func__);
 	wsa881x_init_thermal(&wsa_pdata[wsa881x_index].tz_pdata);
 	INIT_DELAYED_WORK(&wsa_pdata[wsa881x_index].ocp_ctl_work,
 				wsa881x_ocp_ctl_work);
@@ -1382,9 +1394,9 @@ static int wsa881x_i2c_probe(struct i2c_client *client,
 	}
 
 	if (pdata->status == WSA881X_STATUS_I2C) {
-		dev_dbg(&client->dev, "%s:probe for other slaves\n"
-			"devices of codec I2C slave Addr = %x\n",
-			__func__, client->addr);
+		dev_info(&client->dev, "%s:probe for other slaves\n"
+			"devices of codec I2C slave Addr = %x wsa_idx = %d\n",
+			__func__, client->addr, wsa881x_index);
 		dev_dbg(&client->dev, "%s:wsa_idx = %d SLAVE = %d\n",
 				__func__, wsa881x_index, WSA881X_ANALOG_SLAVE);
 		pdata->regmap[WSA881X_ANALOG_SLAVE] =
@@ -1402,6 +1414,7 @@ static int wsa881x_i2c_probe(struct i2c_client *client,
 		client->dev.platform_data = pdata;
 		i2c_set_clientdata(client, pdata);
 		pdata->client[WSA881X_ANALOG_SLAVE] = client;
+		pdata->regmap_flag = true;
 		if (pdata->version == WSA881X_2_0)
 			wsa881x_update_regmap_2_0(
 					pdata->regmap[WSA881X_ANALOG_SLAVE],
@@ -1467,7 +1480,6 @@ static int wsa881x_i2c_probe(struct i2c_client *client,
 			goto err;
 		}
 		pdata->client[WSA881X_DIGITAL_SLAVE] = client;
-		pdata->regmap_flag = true;
 		ret = check_wsa881x_presence(client);
 		if (ret < 0) {
 			dev_err(&client->dev,
@@ -1551,6 +1563,8 @@ static int wsa881x_i2c_probe(struct i2c_client *client,
 		component->name_prefix = pdata->wsa881x_name_prefix;
 
 		pdata->status = WSA881X_STATUS_I2C;
+		dev_info(&client->dev, "%s:pdata status changed to I2C\n",
+			__func__);
 		goto err1;
 	}
 err_mem:

+ 8 - 2
asoc/codecs/wsa881x-temp-sensor.h

@@ -1,5 +1,5 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
-/* Copyright (c) 2015, 2018 The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015, 2018, 2020 The Linux Foundation. All rights reserved.
  */
 #ifndef WSA881X_TEMP_SENSOR_H
 #define WSA881X_TEMP_SENSOR_H
@@ -29,7 +29,13 @@ struct wsa881x_tz_priv {
 	int curr_temp;
 };
 
-int wsa881x_get_temp(struct thermal_zone_device *tz_dev, int *temp);
+#ifndef CONFIG_WSA881X_TEMP_SENSOR_DISABLE
 int wsa881x_init_thermal(struct wsa881x_tz_priv *tz_pdata);
 void wsa881x_deinit_thermal(struct thermal_zone_device *tz_dev);
+int wsa881x_get_temp(struct thermal_zone_device *tz_dev, int *temp);
+#else
+int wsa881x_init_thermal(struct wsa881x_tz_priv *tz_pdata){ return 0; }
+void wsa881x_deinit_thermal(struct thermal_zone_device *tz_dev){}
+int wsa881x_get_temp(struct thermal_zone_device *tz_dev, int *temp){ return 0; }
+#endif
 #endif

+ 15 - 3
asoc/holi-port-config.h

@@ -33,9 +33,19 @@ static struct port_params rx_frame_params_default[SWR_MSTR_PORT_LEN] = {
 	{0x18F, 0, 0, 0x8, 0x8, 0x0F,  0x00, 0,    0, 0x00, 0x01}, /* PCM_OUT */
 };
 
+/* Headset(44.1K) + PCM Haptics */
+static struct port_params rx_frame_params_44p1KHz[SWR_MSTR_PORT_LEN] = {
+	{3,  0,  0,  0xFF, 0xFF, 1,    0xFF, 0xFF, 1, 0x00, 0x00}, /* HPH/EAR */
+	{63, 0,  0,  3,    6,    7,    0,    0xFF, 0, 0x00, 0x00}, /* HPH_CLH */
+	{31, 11, 11, 0xFF, 0xFF, 4,    1,    0xFF, 0, 0x00, 0x00}, /* HPH_CMP */
+	{3,  1,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0, 0x00, 0x00}, /* LO/AUX */
+	{0,  0,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0,    0, 0x00, 0x00}, /* DSD */
+	{0x1FF, 0, 0, 0x8, 0x8, 0x0F, 0, 0,    0, 0x00, 0x01}, /* PCM_OUT */
+};
+
 /* TX UC1: TX1: 1ch, TX2: 2chs, TX3: 1ch(MBHC) */
-static struct port_params tx_frame_params_default[SWR_MSTR_PORT_LEN] = {
-	{3,  1,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX1 */
+static struct port_params tx_frame_params_4p8MHz[SWR_MSTR_PORT_LEN] = {
+	{3,  0,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 1, 0x00, 0x00}, /* TX1 */
 	{3,  2,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX2 */
 	{7,  1,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX3 */
 };
@@ -47,15 +57,17 @@ static struct port_params tx_frame_params_wcd937x[SWR_MSTR_PORT_LEN] = {
 };
 
 static struct swr_mstr_port_map sm_port_map[] = {
-	{VA_MACRO, SWR_UC0, tx_frame_params_default},
+	{VA_MACRO, SWR_UC0, tx_frame_params_4p8MHz},
 	{RX_MACRO, SWR_UC0, rx_frame_params_default},
 	{RX_MACRO, SWR_UC1, rx_frame_params_dsd},
+	{RX_MACRO, SWR_UC2, rx_frame_params_44p1KHz},
 };
 
 static struct swr_mstr_port_map sm_port_map_wcd937x[] = {
 	{VA_MACRO, SWR_UC0, tx_frame_params_wcd937x},
 	{RX_MACRO, SWR_UC0, rx_frame_params_default},
 	{RX_MACRO, SWR_UC1, rx_frame_params_dsd},
+	{RX_MACRO, SWR_UC2, rx_frame_params_44p1KHz},
 };
 
 #endif /* _HOLI_PORT_CONFIG */

+ 12 - 0
asoc/lahaina-port-config.h

@@ -44,6 +44,16 @@ static struct port_params rx_frame_params_default[SWR_MSTR_PORT_LEN] = {
 	{0x18F, 0, 0, 0x8, 0x8, 0x0F,  0x00, 0,    0, 0x00, 0x01}, /* PCM_OUT */
 };
 
+/* Headset(44.1K) + PCM Haptics */
+static struct port_params rx_frame_params_44p1KHz[SWR_MSTR_PORT_LEN] = {
+	{3,  0,  0,  0xFF, 0xFF, 1,    0xFF, 0xFF, 1, 0x00, 0x00}, /* HPH/EAR */
+	{63, 0,  0,  3,    6,    7,    0,    0xFF, 0, 0x00, 0x00}, /* HPH_CLH */
+	{31, 11, 11, 0xFF, 0xFF, 4,    1,    0xFF, 0, 0x00, 0x00}, /* HPH_CMP */
+	{3,  1,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0, 0x00, 0x00}, /* LO/AUX */
+	{0,  0,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0,    0, 0x00, 0x00}, /* DSD */
+	{0x1FF, 0, 0, 0x8, 0x8, 0x0F, 0, 0,    0, 0x00, 0x01}, /* PCM_OUT */
+};
+
 /* TX UC1: TX1: 1ch, TX2: 2chs, TX3: 1ch(MBHC) */
 static struct port_params tx_frame_params_default[SWR_MSTR_PORT_LEN] = {
 	{7,  1,  0,  0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0x00, 0x00}, /* TX1 */
@@ -92,6 +102,7 @@ static struct swr_mstr_port_map sm_port_map[] = {
 	{TX_MACRO, SWR_UC2, tx_frame_params_0p6MHz},
 	{RX_MACRO, SWR_UC0, rx_frame_params_default},
 	{RX_MACRO, SWR_UC1, rx_frame_params_dsd},
+	{RX_MACRO, SWR_UC2, rx_frame_params_44p1KHz},
 	{WSA_MACRO, SWR_UC0, wsa_frame_params_default},
 };
 
@@ -101,6 +112,7 @@ static struct swr_mstr_port_map sm_port_map_shima[] = {
 	{TX_MACRO, SWR_UC2, tx_frame_params_shima_0p6MHz},
 	{RX_MACRO, SWR_UC0, rx_frame_params_default},
 	{RX_MACRO, SWR_UC1, rx_frame_params_dsd},
+	{RX_MACRO, SWR_UC2, rx_frame_params_44p1KHz},
 	{WSA_MACRO, SWR_UC0, wsa_frame_params_default},
 };
 

+ 7 - 1
asoc/lahaina.c

@@ -310,6 +310,7 @@ struct mi2s_conf {
 	struct mutex lock;
 	u32 ref_cnt;
 	u32 msm_is_mi2s_master;
+	bool audio_core_vote;
 };
 
 static u32 mi2s_ebit_clk[MI2S_MAX] = {
@@ -5242,7 +5243,8 @@ void mi2s_disable_audio_vote(struct snd_pcm_substream *substream)
 		return;
 	}
 
-	if (IS_MSM_INTERFACE_MI2S(index) && IS_FRACTIONAL(sample_rate)) {
+	if ((IS_MSM_INTERFACE_MI2S(index) && IS_FRACTIONAL(sample_rate)) ||
+	    mi2s_intf_conf[index].audio_core_vote) {
 		if (pdata->lpass_audio_hw_vote != NULL) {
 			if (--pdata->core_audio_vote_count == 0) {
 				clk_disable_unprepare(
@@ -5251,6 +5253,7 @@ void mi2s_disable_audio_vote(struct snd_pcm_substream *substream)
 				pr_err("%s: audio vote mismatch\n", __func__);
 				pdata->core_audio_vote_count = 0;
 			}
+			mi2s_intf_conf[index].audio_core_vote = false;
 		} else {
 			pr_err("%s: Invalid lpass audio hw node\n", __func__);
 		}
@@ -5312,6 +5315,7 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream)
 			}
 		}
 		pdata->core_audio_vote_count++;
+		mi2s_intf_conf[index].audio_core_vote = true;
 	}
 
 	if (++mi2s_intf_conf[index].ref_cnt == 1) {
@@ -7808,6 +7812,7 @@ static void msm_i2s_auxpcm_init(struct platform_device *pdev)
 	for (count = 0; count < MI2S_MAX; count++) {
 		mutex_init(&mi2s_intf_conf[count].lock);
 		mi2s_intf_conf[count].ref_cnt = 0;
+		mi2s_intf_conf[count].audio_core_vote = false;
 	}
 
 	ret = of_property_read_u32_array(pdev->dev.of_node,
@@ -7832,6 +7837,7 @@ static void msm_i2s_auxpcm_deinit(void)
 		mutex_destroy(&mi2s_intf_conf[count].lock);
 		mi2s_intf_conf[count].ref_cnt = 0;
 		mi2s_intf_conf[count].msm_is_mi2s_master = 0;
+		mi2s_intf_conf[count].audio_core_vote = false;
 	}
 }
 

+ 6 - 6
asoc/msm-compress-q6-v2.c

@@ -3083,18 +3083,18 @@ static int msm_compr_pointer(struct snd_compr_stream *cstream,
 	spin_lock_irqsave(&prtd->lock, flags);
 	tstamp.sampling_rate = prtd->sample_rate;
 	tstamp.byte_offset = prtd->byte_offset;
-	if (cstream->direction == SND_COMPRESS_PLAYBACK)
+	if (cstream->direction == SND_COMPRESS_PLAYBACK) {
+		runtime->total_bytes_transferred = prtd->copied_total;
 		tstamp.copied_total = prtd->copied_total;
-	else if (cstream->direction == SND_COMPRESS_CAPTURE)
+	}
+	else if (cstream->direction == SND_COMPRESS_CAPTURE) {
+		runtime->total_bytes_available = prtd->received_total;
 		tstamp.copied_total = prtd->received_total;
+	}
 	first_buffer = prtd->first_buffer;
 	if (atomic_read(&prtd->error)) {
 		pr_err_ratelimited("%s Got RESET EVENTS notification, return error\n",
 				   __func__);
-		if (cstream->direction == SND_COMPRESS_PLAYBACK)
-			runtime->total_bytes_transferred = prtd->copied_total;
-		else
-			runtime->total_bytes_available = prtd->received_total;
 		tstamp.pcm_io_frames = 0;
 		memcpy(arg, &tstamp, sizeof(struct snd_compr_tstamp));
 		spin_unlock_irqrestore(&prtd->lock, flags);

+ 0 - 29
asoc/msm-dai-fe.c

@@ -685,35 +685,6 @@ static struct snd_soc_dai_driver msm_fe_dais[] = {
 		.name = "USBAUDIO_HOSTLESS",
 		.probe = fe_dai_probe,
 	},
-	{
-		.playback = {
-			.stream_name = "AFE Playback",
-			.aif_name = "PCM_RX",
-			.rates = (SNDRV_PCM_RATE_8000 |
-				SNDRV_PCM_RATE_16000 |
-				SNDRV_PCM_RATE_48000),
-			.formats = SNDRV_PCM_FMTBIT_S16_LE,
-			.channels_min = 1,
-			.channels_max = 2,
-			.rate_min =     8000,
-			.rate_max =     48000,
-		},
-		.capture = {
-			.stream_name = "AFE Capture",
-			.aif_name = "PCM_TX",
-			.rates = (SNDRV_PCM_RATE_8000 |
-				SNDRV_PCM_RATE_16000 |
-				SNDRV_PCM_RATE_48000),
-			.formats = SNDRV_PCM_FMTBIT_S16_LE,
-			.channels_min = 1,
-			.channels_max = 2,
-			.rate_min =     8000,
-			.rate_max =     48000,
-		},
-		.ops = &msm_fe_dai_ops,
-		.name = "AFE-PROXY",
-		.probe = fe_dai_probe,
-	},
 	{
 		.playback = {
 			.stream_name = "HDMI_HOSTLESS Playback",

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 193 - 815
asoc/msm-pcm-routing-v2.c


+ 1 - 1
asoc/msm_dailink.h

@@ -318,7 +318,7 @@ SND_SOC_DAILINK_DEFS(quin_tdm_rx_7_hostless,
 	DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-hostless")));
 
 SND_SOC_DAILINK_DEFS(quin_tdm_tx_7_hostless,
-	DAILINK_COMP_ARRAY(COMP_CPU("QUIN_TDM_RX_7_HOSTLESS")),
+	DAILINK_COMP_ARRAY(COMP_CPU("QUIN_TDM_TX_7_HOSTLESS")),
 	DAILINK_COMP_ARRAY(COMP_CODEC("snd-soc-dummy", "snd-soc-dummy-dai")),
 	DAILINK_COMP_ARRAY(COMP_PLATFORM("msm-pcm-hostless")));
 

+ 186 - 4
asoc/qcs405.c

@@ -21,6 +21,7 @@
 #include <sound/pcm_params.h>
 #include <sound/info.h>
 #include <dsp/audio_notifier.h>
+#include <dsp/apr_audio-v2.h>
 #include <dsp/q6afe-v2.h>
 #include <dsp/q6core.h>
 #include <dsp/msm_mdf.h>
@@ -178,6 +179,7 @@ struct dev_config {
 	u32 sample_rate;
 	u32 bit_format;
 	u32 channels;
+	u32 data_format;
 };
 
 struct msm_wsa881x_dev_info {
@@ -206,6 +208,7 @@ struct msm_asoc_mach_data {
 	u32 tdm_micb_voltage;
 	u32 tdm_micb_current;
 	bool codec_is_csra;
+	void __iomem *mi2s_dsd_mode[MI2S_MAX];
 };
 
 struct msm_asoc_wcd93xx_codec {
@@ -478,6 +481,19 @@ static const char *const slim_tx_ch_text[] = {"One", "Two", "Three", "Four",
 static const char *const vi_feed_ch_text[] = {"One", "Two"};
 static char const *bit_format_text[] = {"S16_LE", "S24_LE", "S24_3LE",
 					  "S32_LE"};
+static const char *const data_format_text[] = {
+	"LPCM",
+	"Compr",
+	"LPCM-60958",
+	"Compr-60958",
+	"NA4",
+	"NA5",
+	"NA6",
+	"NA7",
+	"NA8",
+	"DSD_DOP_W_MARKER",
+	"NATIVE_DSD_DATA"
+};
 static char const *slim_sample_rate_text[] = {"KHZ_8", "KHZ_16",
 					"KHZ_32", "KHZ_44P1", "KHZ_48",
 					"KHZ_88P2", "KHZ_96", "KHZ_176P4",
@@ -616,6 +632,8 @@ static SOC_ENUM_SINGLE_EXT_DECL(sen_mi2s_rx_chs, mi2s_ch_text);
 static SOC_ENUM_SINGLE_EXT_DECL(sen_mi2s_tx_chs, mi2s_ch_text);
 static SOC_ENUM_SINGLE_EXT_DECL(mi2s_rx_format, bit_format_text);
 static SOC_ENUM_SINGLE_EXT_DECL(mi2s_tx_format, bit_format_text);
+static SOC_ENUM_SINGLE_EXT_DECL(mi2s_rx_data_format, data_format_text);
+static SOC_ENUM_SINGLE_EXT_DECL(mi2s_tx_data_format, data_format_text);
 static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_rx_format, bit_format_text);
 static SOC_ENUM_SINGLE_EXT_DECL(aux_pcm_tx_format, bit_format_text);
 static SOC_ENUM_SINGLE_EXT_DECL(prim_meta_mi2s_rx_sample_rate, mi2s_rate_text);
@@ -3251,7 +3269,8 @@ static int msm_mi2s_rx_format_put(struct snd_kcontrol *kcontrol,
 		return idx;
 
 	/* check for PRIM_MI2S and CSRAx config to allow 24bit BE config only */
-	if ((PRIM_MI2S == idx) && (true==pdata->codec_is_csra))
+	if ((idx == PRIM_MI2S) && (pdata->codec_is_csra == true)
+			&& mi2s_rx_cfg[idx].data_format != AFE_DSD_DATA)
 	{
 		mi2s_rx_cfg[idx].bit_format = SNDRV_PCM_FORMAT_S24_LE;
 		pr_debug("%s: Keeping default format idx[%d]_rx_format = %d, item = %d\n",
@@ -3305,6 +3324,74 @@ static int msm_mi2s_tx_format_put(struct snd_kcontrol *kcontrol,
 	return 0;
 }
 
+static int msm_mi2s_tx_data_format_put(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	int idx = mi2s_get_port_idx(kcontrol);
+
+	if (idx < 0)
+		return idx;
+
+	mi2s_tx_cfg[idx].data_format = ucontrol->value.enumerated.item[0];
+
+	pr_debug("%s: idx[%d]_data_format = %d, item = %d\n", __func__,
+		  idx, mi2s_tx_cfg[idx].data_format,
+		  ucontrol->value.enumerated.item[0]);
+
+	return 0;
+}
+
+static int msm_mi2s_rx_data_format_put(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	int idx = mi2s_get_port_idx(kcontrol);
+
+	if (idx < 0)
+		return idx;
+
+	mi2s_rx_cfg[idx].data_format = ucontrol->value.enumerated.item[0];
+
+	pr_debug("%s: idx[%d]_data_format = %d, item = %d\n", __func__,
+		  idx, mi2s_rx_cfg[idx].data_format,
+		  ucontrol->value.enumerated.item[0]);
+
+	return 0;
+}
+
+static int msm_mi2s_tx_data_format_get(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	int idx = mi2s_get_port_idx(kcontrol);
+
+	if (idx < 0)
+		return idx;
+
+	ucontrol->value.enumerated.item[0] = mi2s_tx_cfg[idx].data_format;
+
+	pr_debug("%s: idx[%d]_tx_format = %d, item = %d\n", __func__,
+		idx, mi2s_tx_cfg[idx].data_format,
+		ucontrol->value.enumerated.item[0]);
+
+	return 0;
+}
+
+static int msm_mi2s_rx_data_format_get(struct snd_kcontrol *kcontrol,
+				struct snd_ctl_elem_value *ucontrol)
+{
+	int idx = mi2s_get_port_idx(kcontrol);
+
+	if (idx < 0)
+		return idx;
+
+	ucontrol->value.enumerated.item[0] = mi2s_rx_cfg[idx].data_format;
+
+	pr_debug("%s: idx[%d]_rx_format = %d, item = %d\n", __func__,
+		idx, mi2s_rx_cfg[idx].data_format,
+		ucontrol->value.enumerated.item[0]);
+
+	return 0;
+}
+
 static int msm_meta_mi2s_get_port_idx(struct snd_kcontrol *kcontrol)
 {
 	int idx = 0;
@@ -4335,6 +4422,18 @@ static const struct snd_kcontrol_new msm_snd_controls[] = {
 			msm_mi2s_rx_ch_get, msm_mi2s_rx_ch_put),
 	SOC_ENUM_EXT("SEN_MI2S_TX Channels", sen_mi2s_tx_chs,
 			msm_mi2s_tx_ch_get, msm_mi2s_tx_ch_put),
+	SOC_ENUM_EXT("PRIM_MI2S_TX DataFormat", mi2s_tx_data_format,
+			msm_mi2s_tx_data_format_get,
+				msm_mi2s_tx_data_format_put),
+	SOC_ENUM_EXT("QUAT_MI2S_TX DataFormat", mi2s_tx_data_format,
+			msm_mi2s_tx_data_format_get,
+				msm_mi2s_tx_data_format_put),
+	SOC_ENUM_EXT("PRIM_MI2S_RX DataFormat", mi2s_rx_data_format,
+			msm_mi2s_rx_data_format_get,
+				msm_mi2s_rx_data_format_put),
+	SOC_ENUM_EXT("QUAT_MI2S_RX DataFormat", mi2s_rx_data_format,
+			msm_mi2s_rx_data_format_get,
+				msm_mi2s_rx_data_format_put),
 	SOC_ENUM_EXT("PRIM_MI2S_RX Format", mi2s_rx_format,
 			msm_mi2s_rx_format_get, msm_mi2s_rx_format_put),
 	SOC_ENUM_EXT("PRIM_MI2S_TX Format", mi2s_tx_format,
@@ -6349,7 +6448,7 @@ static struct snd_soc_ops msm_fe_qos_ops = {
 
 static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream)
 {
-	int ret = 0;
+	int ret = 0, val = 0;
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
 	struct snd_soc_dai_link *dai_link = rtd->dai_link;
@@ -6357,6 +6456,12 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream)
 	unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS;
 	struct snd_soc_card *card = rtd->card;
 	struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
+	int data_format;
+
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+		data_format = mi2s_rx_cfg[index].data_format;
+	else
+		data_format = mi2s_tx_cfg[index].data_format;
 
 	dev_dbg(rtd->card->dev,
 		"%s: substream = %s  stream = %d, dai name %s, dai ID %d\n",
@@ -6382,6 +6487,9 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream)
 			mi2s_clk[index].clk_id = mi2s_ebit_clk[index];
 			fmt = SND_SOC_DAIFMT_CBM_CFM;
 		}
+
+		if (data_format == AFE_DSD_DATA)
+			fmt = SND_SOC_DAIFMT_CBM_CFS;
 		ret = msm_mi2s_set_sclk(substream, true);
 		if (ret < 0) {
 			dev_err(rtd->card->dev,
@@ -6396,9 +6504,34 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream)
 				__func__, index, ret);
 			goto clk_off;
 		}
-		if (pdata->mi2s_gpio_p[index])
-			msm_cdc_pinctrl_select_active_state(
+
+		if (pdata->mi2s_gpio_p[index]) {
+			if ((data_format == AFE_DSD_DATA) &&
+					((index == QUAT_MI2S) ||
+						(index == PRIM_MI2S))) {
+				msm_cdc_pinctrl_select_alt_active_state(
+						pdata->mi2s_gpio_p[index]);
+			} else {
+				msm_cdc_pinctrl_select_active_state(
 					pdata->mi2s_gpio_p[index]);
+			}
+		}
+
+		if (index == QUAT_MI2S || index == PRIM_MI2S) {
+			switch (data_format) {
+			case AFE_DSD_DATA:
+				if (pdata->mi2s_dsd_mode[index]) {
+					val = ioread32(
+						pdata->mi2s_dsd_mode[index]);
+					val = val | 0x1;
+					iowrite32(val,
+						pdata->mi2s_dsd_mode[index]);
+				}
+				break;
+			default:
+				break;
+			}
+		}
 	}
 
 	ret = qcs405_send_island_vad_config(dai_link->id);
@@ -6452,11 +6585,18 @@ static int msm_mi2s_snd_hw_free(struct snd_pcm_substream *substream)
 static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream)
 {
 	int ret;
+	int val;
+	int data_format;
 	struct snd_soc_pcm_runtime *rtd = substream->private_data;
 	int index = rtd->cpu_dai->id;
 	struct snd_soc_card *card = rtd->card;
 	struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
 
+	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+		data_format = mi2s_rx_cfg[index].data_format;
+	else
+		data_format = mi2s_tx_cfg[index].data_format;
+
 	pr_debug("%s(): substream = %s  stream = %d\n", __func__,
 		 substream->name, substream->stream);
 	if (index < PRIM_MI2S || index >= MI2S_MAX) {
@@ -6470,6 +6610,22 @@ static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream)
 			msm_cdc_pinctrl_select_sleep_state(
 					pdata->mi2s_gpio_p[index]);
 
+		if (index == QUAT_MI2S || index == PRIM_MI2S) {
+			switch (data_format) {
+			case AFE_DSD_DATA:
+				if (pdata->mi2s_dsd_mode[index]) {
+					val = ioread32(
+						pdata->mi2s_dsd_mode[index]);
+					val = val & ~1;
+					iowrite32(val,
+						pdata->mi2s_dsd_mode[index]);
+				}
+				break;
+			default:
+				break;
+			}
+		}
+
 		ret = msm_mi2s_set_sclk(substream, false);
 		if (ret < 0)
 			pr_err("%s:clock disable failed for MI2S (%d); ret=%d\n",
@@ -9750,6 +9906,7 @@ static int msm_asoc_machine_probe(struct platform_device *pdev)
 	const char *micb_supply_str1 = "tdm-vdd-micb";
 	const char *micb_voltage_str = "qcom,tdm-vdd-micb-voltage";
 	const char *micb_current_str = "qcom,tdm-vdd-micb-current";
+	u32 v_base_addr;
 
 	if (!pdev->dev.of_node) {
 		dev_err(&pdev->dev, "No platform supplied from device tree\n");
@@ -9761,6 +9918,31 @@ static int msm_asoc_machine_probe(struct platform_device *pdev)
 	if (!pdata)
 		return -ENOMEM;
 
+	ret = of_property_read_u32(
+		pdev->dev.of_node, "tcsr_i2s_dsd_prim", &v_base_addr);
+	if (ret) {
+		dev_err(&pdev->dev, "MUX addr invalid for MI2S dsd prim\n");
+	} else {
+		pdata->mi2s_dsd_mode[PRIM_MI2S] =
+			devm_ioremap(&pdev->dev, v_base_addr, 4);
+		if (pdata->mi2s_dsd_mode[PRIM_MI2S] == NULL) {
+			pr_err("%s ioremap failure for muxsel virt addr dsd prim\n",
+				__func__);
+		}
+	}
+	ret = of_property_read_u32(
+		pdev->dev.of_node, "tcsr_i2s_dsd_quat", &v_base_addr);
+	if (ret) {
+		dev_err(&pdev->dev, "MUX addr invalid for MI2S dsd quat\n");
+	} else {
+		pdata->mi2s_dsd_mode[QUAT_MI2S] =
+			devm_ioremap(&pdev->dev, v_base_addr, 4);
+		if (pdata->mi2s_dsd_mode[QUAT_MI2S] == NULL) {
+			pr_err("%s ioremap failure for muxsel virt addr dsd quat\n",
+				__func__);
+		}
+	}
+
 	/* test for ep92 HDMI bridge and update dai links accordingly */
 	ret = msm_detect_ep92_dev(pdev, card);
 	if (ret)

+ 7 - 7
asoc/sa6155.c

@@ -267,9 +267,9 @@ static struct dev_config tdm_tx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = {
 		{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */
 	},
 	{ /* QUIN TDM */
-		{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 4}, /* TX_0 */
-		{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* TX_1 */
-		{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* TX_2 */
+		{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 6}, /* TX_0 */
+		{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */
+		{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */
 		{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */
 		{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */
 		{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */
@@ -471,14 +471,14 @@ static unsigned int tdm_tx_slot_offset
 		{60,0xFFFF},
 	},
 	{/* QUIN TDM */
-		{0, 4, 8, 12, 0xFFFF},
-		{16, 20, 0xFFFF},
-		{24, 28, 0xFFFF},
+		{0, 4, 8, 12, 16, 20, 0xFFFF},
+		{24, 0xFFFF},
+		{28, 0xFFFF},
+		{0xFFFF}, /* not used */
 		{0xFFFF}, /* not used */
 		{0xFFFF}, /* not used */
 		{0xFFFF}, /* not used */
 		{0xFFFF}, /* not used */
-		{28, 0xFFFF},
 	}
 };
 

+ 1 - 0
config/holiauto.conf

@@ -29,6 +29,7 @@ export CONFIG_SND_SOC_WCD938X_SLAVE=m
 export CONFIG_SND_SOC_WCD937X=m
 export CONFIG_SND_SOC_WCD937X_SLAVE=m
 export CONFIG_SND_SOC_WSA881X_ANALOG=m
+export CONFIG_WSA881X_TEMP_SENSOR_DISABLE=m
 export CONFIG_SND_SOC_HOLI=m
 export CONFIG_SND_EVENT=m
 export CONFIG_TDM_DISABLE=m

+ 1 - 0
config/holiautoconf.h

@@ -33,6 +33,7 @@
 #define CONFIG_SND_SOC_WCD937X 1
 #define CONFIG_SND_SOC_WCD937X_SLAVE 1
 #define CONFIG_SND_SOC_WSA881X_ANALOG 1
+#define CONFIG_WSA881X_TEMP_SENSOR_DISABLE 1
 #define CONFIG_SND_SOC_HOLI 1
 #define CONFIG_SND_EVENT 1
 #define CONFIG_TDM_DISABLE 1

+ 1 - 0
config/lahainaauto.conf

@@ -36,3 +36,4 @@ export CONFIG_SND_SOC_LAHAINA=m
 export CONFIG_SND_EVENT=m
 export CONFIG_SND_SWR_HAPTICS=m
 export CONFIG_DIGITAL_CDC_RSC_MGR=m
+export CONFIG_AUXPCM_DISABLE=m

+ 1 - 0
config/lahainaautoconf.h

@@ -40,3 +40,4 @@
 #define CONFIG_SND_EVENT 1
 #define CONFIG_SND_SWR_HAPTICS 1
 #define CONFIG_DIGITAL_CDC_RSC_MGR 1
+#define CONFIG_AUXPCM_DISABLE 1

+ 1 - 0
config/sa8155auto.conf

@@ -13,3 +13,4 @@ CONFIG_SND_SOC_MSM_STUB=m
 CONFIG_SND_SOC_MSM_HDMI_CODEC_RX=m
 CONFIG_MSM_QDSP6V2_CODECS=m
 CONFIG_SND_EVENT=m
+CONFIG_SND_SOC_SA8155=m

+ 1 - 0
config/sa8155autoconf.h

@@ -17,3 +17,4 @@
 #define CONFIG_SND_SOC_MSM_HDMI_CODEC_RX 1
 #define CONFIG_MSM_QDSP6V2_CODECS 1
 #define CONFIG_SND_EVENT 1
+#define CONFIG_SND_SOC_SA8155 1

+ 34 - 4
dsp/audio_cal_utils.c

@@ -10,6 +10,8 @@
 #include <linux/mutex.h>
 #include <dsp/audio_cal_utils.h>
 
+spinlock_t cal_lock;
+
 static int unmap_memory(struct cal_type_data *cal_type,
 			struct cal_block_data *cal_block);
 
@@ -917,6 +919,7 @@ int cal_utils_dealloc_cal(size_t data_size, void *data,
 	int ret = 0;
 	struct cal_block_data *cal_block;
 	struct audio_cal_type_dealloc *dealloc_data = data;
+	unsigned long flags = 0;
 
 	pr_debug("%s\n", __func__);
 
@@ -964,7 +967,9 @@ int cal_utils_dealloc_cal(size_t data_size, void *data,
 	if (ret < 0)
 		goto err;
 
+	spin_lock_irqsave(&cal_lock, flags);
 	delete_cal_block(cal_block);
+	spin_unlock_irqrestore(&cal_lock, flags);
 err:
 	mutex_unlock(&cal_type->lock);
 done:
@@ -1079,18 +1084,43 @@ void cal_utils_mark_cal_used(struct cal_block_data *cal_block)
 }
 EXPORT_SYMBOL(cal_utils_mark_cal_used);
 
+int __init cal_utils_init(void)
+{
+	spin_lock_init(&cal_lock);
+	return 0;
+}
 /**
  * cal_utils_is_cal_stale
  *
  * @cal_block: pointer to cal block
  *
+ * @cal_type: pointer to the cal type
+ *
  * Returns true if cal block is stale, false otherwise
  */
-bool cal_utils_is_cal_stale(struct cal_block_data *cal_block)
+bool cal_utils_is_cal_stale(struct cal_block_data *cal_block, struct cal_type_data *cal_type)
 {
-	if ((cal_block) && (cal_block->cal_stale))
-		return true;
+	bool ret = false;
+	unsigned long flags = 0;
+
+	if (!cal_type) {
+		pr_err("%s: cal_type is Null", __func__);
+		goto done;
+	}
+
+	spin_lock_irqsave(&cal_lock, flags);
+	cal_block = cal_utils_get_only_cal_block(cal_type);
+	if (!cal_block) {
+		pr_err("%s: cal_block is Null", __func__);
+		goto unlock;
+	}
 
-	return false;
+	if (cal_block->cal_stale)
+	    ret = true;
+
+unlock:
+	spin_unlock_irqrestore(&cal_lock, flags);
+done:
+	return ret;
 }
 EXPORT_SYMBOL(cal_utils_is_cal_stale);

+ 2 - 1
dsp/audio_calibration.c

@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
- * Copyright (c) 2014, 2016-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014, 2016-2017, 2020, The Linux Foundation. All rights reserved.
  */
 #include <linux/slab.h>
 #include <linux/fs.h>
@@ -591,6 +591,7 @@ int __init audio_cal_init(void)
 
 	pr_debug("%s\n", __func__);
 
+	cal_utils_init();
 	memset(&audio_cal, 0, sizeof(audio_cal));
 	mutex_init(&audio_cal.common_lock);
 	for (; i < MAX_CAL_TYPES; i++) {

+ 8 - 1
dsp/msm_audio_ion.c

@@ -69,7 +69,7 @@ static int msm_audio_dma_buf_map(struct dma_buf *dma_buf,
 				 bool cma_mem)
 {
 
-	struct msm_audio_alloc_data *alloc_data;
+	struct msm_audio_alloc_data *alloc_data = NULL;
 	struct device *cb_dev;
 	unsigned long ionflag = 0;
 	int rc = 0;
@@ -138,6 +138,7 @@ detach_dma_buf:
 		       alloc_data->attach);
 free_alloc_data:
 	kfree(alloc_data);
+	alloc_data = NULL;
 
 	return rc;
 }
@@ -179,6 +180,7 @@ static int msm_audio_dma_buf_unmap(struct dma_buf *dma_buf, bool cma_mem)
 
 			list_del(&(alloc_data->list));
 			kfree(alloc_data);
+			alloc_data = NULL;
 			break;
 		}
 	}
@@ -321,6 +323,11 @@ static int msm_audio_ion_map_buf(struct dma_buf *dma_buf, dma_addr_t *paddr,
 {
 	int rc = 0;
 
+	if (!dma_buf || !paddr || !vaddr || !plen) {
+		pr_err("%s: Invalid params\n", __func__);
+		return -EINVAL;
+	}
+
 	rc = msm_audio_ion_get_phys(dma_buf, paddr, plen);
 	if (rc) {
 		pr_err("%s: ION Get Physical for AUDIO failed, rc = %d\n",

+ 11 - 9
dsp/msm_audio_ion_vm.c

@@ -562,12 +562,18 @@ int msm_audio_ion_alloc(struct dma_buf **dma_buf, size_t bufsz,
 		pr_err("%s: Invalid params\n", __func__);
 		return -EINVAL;
 	}
-
+	pr_debug("%s: audio heap is used\n", __func__);
 	if (msm_audio_ion_data.smmu_enabled == true) {
-		pr_debug("%s: system heap is used\n", __func__);
-		*dma_buf = ion_alloc(bufsz, ION_HEAP(ION_SYSTEM_HEAP_ID), 0);
+		*dma_buf = ion_alloc(bufsz, ION_HEAP(ION_AUDIO_HEAP_ID), 0);
+		if (IS_ERR_OR_NULL((void *)(*dma_buf))) {
+			if (IS_ERR((void *)(*dma_buf)))
+				err_ion_ptr = PTR_ERR((int *)(*dma_buf));
+			pr_debug("%s: ION alloc failed for audio heap err ptr=%ld, smmu_enabled=%d,"
+					"trying system heap..\n",
+					__func__, err_ion_ptr, msm_audio_ion_data.smmu_enabled);
+			*dma_buf = ion_alloc(bufsz, ION_HEAP(ION_SYSTEM_HEAP_ID), 0);
+		}
 	} else {
-		pr_debug("%s: audio heap is used\n", __func__);
 		*dma_buf = ion_alloc(bufsz, ION_HEAP(ION_AUDIO_HEAP_ID), 0);
 	}
 	if (IS_ERR_OR_NULL((void *)(*dma_buf))) {
@@ -582,17 +588,13 @@ int msm_audio_ion_alloc(struct dma_buf **dma_buf, size_t bufsz,
 	rc = msm_audio_ion_map_buf(*dma_buf, paddr, plen, vaddr);
 	if (rc) {
 		pr_err("%s: failed to map ION buf, rc = %d\n", __func__, rc);
-		goto err_dma_buf;
+		goto err;
 	}
 	pr_debug("%s: mapped address = %pK, size=%zd\n", __func__,
 		*vaddr, bufsz);
 
 	memset(*vaddr, 0, bufsz);
 
-	return rc;
-
-err_dma_buf:
-	dma_buf_put(*dma_buf);
 err:
 	return rc;
 }

+ 6 - 5
dsp/q6adm.c

@@ -2038,7 +2038,7 @@ static void send_adm_custom_topology(void)
 	this_adm.set_custom_topology = 0;
 
 	cal_block = cal_utils_get_only_cal_block(this_adm.cal_data[cal_index]);
-	if (cal_block == NULL || cal_utils_is_cal_stale(cal_block))
+	if (cal_block == NULL || cal_utils_is_cal_stale(cal_block, this_adm.cal_data[cal_index]))
 		goto unlock;
 
 	pr_debug("%s: Sending cal_index %d\n", __func__, cal_index);
@@ -2178,7 +2178,7 @@ static struct cal_block_data *adm_find_cal_by_path(int cal_index, int path)
 		cal_block = list_entry(ptr,
 			struct cal_block_data, list);
 
-		if (cal_utils_is_cal_stale(cal_block))
+		if (cal_utils_is_cal_stale(cal_block, this_adm.cal_data[cal_index]))
 			continue;
 
 		if (cal_index == ADM_AUDPROC_CAL ||
@@ -2217,7 +2217,7 @@ static struct cal_block_data *adm_find_cal_by_app_type(int cal_index, int path,
 		cal_block = list_entry(ptr,
 			struct cal_block_data, list);
 
-		if (cal_utils_is_cal_stale(cal_block))
+		if (cal_utils_is_cal_stale(cal_block, this_adm.cal_data[cal_index]))
 			continue;
 
 		if (cal_index == ADM_AUDPROC_CAL ||
@@ -2259,7 +2259,7 @@ static struct cal_block_data *adm_find_cal(int cal_index, int path,
 
 		cal_block = list_entry(ptr,
 			struct cal_block_data, list);
-		if (cal_utils_is_cal_stale(cal_block))
+		if (cal_utils_is_cal_stale(cal_block, this_adm.cal_data[cal_index]))
 			continue;
 
 		if (cal_index == ADM_AUDPROC_CAL ||
@@ -4120,7 +4120,8 @@ int send_rtac_audvol_cal(void)
 
 	cal_block = cal_utils_get_only_cal_block(
 		this_adm.cal_data[ADM_RTAC_AUDVOL_CAL]);
-	if (cal_block == NULL || cal_utils_is_cal_stale(cal_block)) {
+	if (cal_block == NULL || cal_utils_is_cal_stale(cal_block,
+		this_adm.cal_data[ADM_RTAC_AUDVOL_CAL])) {
 		pr_err("%s: can't find cal block!\n", __func__);
 		goto unlock;
 	}

+ 21 - 11
dsp/q6afe.c

@@ -236,6 +236,7 @@ struct afe_ctl {
 	int dev_acdb_id[AFE_MAX_PORTS];
 	routing_cb rt_cb;
 	struct audio_uevent_data *uevent_data;
+	uint32_t afe_port_start_failed[AFE_MAX_PORTS];
 	/* cal info for AFE */
 	struct afe_fw_info *fw_data;
 	u32 island_mode[AFE_MAX_PORTS];
@@ -2178,7 +2179,7 @@ static void afe_send_custom_topology(void)
 		goto unlock;
 	this_afe.set_custom_topology = 0;
 	cal_block = cal_utils_get_only_cal_block(this_afe.cal_data[cal_index]);
-	if (cal_block == NULL || cal_utils_is_cal_stale(cal_block)) {
+	if (cal_block == NULL || cal_utils_is_cal_stale(cal_block, this_afe.cal_data[cal_index])) {
 		pr_err("%s cal_block not found!!\n", __func__);
 		goto unlock;
 	}
@@ -2279,6 +2280,10 @@ static int afe_send_cps_config(int src_port)
 			continue;
 		}
 
+		if (i >= this_afe.num_spkrs) {
+			pr_err("%s: invalid ch index %d\n", __func__, i);
+			goto fail_cmd;
+		}
 		memcpy(packed_payload + cpy_size,
 			&this_afe.cps_config->spkr_dep_cfg[i],
 			sizeof(struct lpass_swr_spkr_dep_cfg_t));
@@ -2301,6 +2306,8 @@ static int afe_send_cps_config(int src_port)
 		pr_err("%s: port = 0x%x param = 0x%x failed %d\n", __func__,
 		       src_port, param_info.param_id, ret);
 
+
+fail_cmd:
 	pr_debug("%s: config.pdata.param_id 0x%x status %d 0x%x\n", __func__,
 		 param_info.param_id, ret, src_port);
 	kfree(packed_payload);
@@ -3020,7 +3027,7 @@ static struct cal_block_data *afe_find_cal_topo_id_by_port(
 		cal_block = list_entry(ptr,
 			struct cal_block_data, list);
 		/* Skip cal_block if it is already marked stale */
-		if (cal_utils_is_cal_stale(cal_block))
+		if (cal_utils_is_cal_stale(cal_block, cal_type))
 			continue;
 		pr_debug("%s: port id: 0x%x, dev_acdb_id: %d\n", __func__,
 			 port_id, this_afe.dev_acdb_id[afe_port_index]);
@@ -3595,7 +3602,7 @@ static int send_afe_cal_type(int cal_index, int port_id)
 		cal_block = cal_utils_get_only_cal_block(
 				this_afe.cal_data[cal_index]);
 
-	if (cal_block == NULL || cal_utils_is_cal_stale(cal_block)) {
+	if (cal_block == NULL || cal_utils_is_cal_stale(cal_block, this_afe.cal_data[cal_index])) {
 		pr_err_ratelimited("%s cal_block not found!!\n", __func__);
 		ret = -EINVAL;
 		goto unlock;
@@ -5643,13 +5650,13 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config,
 		/* One time call: only for first time */
 		afe_send_custom_topology();
 		/*
-		 * Deregister existing afe topology before
-		 * sending a new one for VA use cases only
+		 * Deregister existing afe topology before sending a new
+		 * one if the previous afe port start failed for this port
 		 */
-		if (port_id == AFE_PORT_ID_VA_CODEC_DMA_TX_0 ||
-		    port_id == AFE_PORT_ID_VA_CODEC_DMA_TX_1 ||
-		    port_id == AFE_PORT_ID_VA_CODEC_DMA_TX_2)
+		if (this_afe.afe_port_start_failed[port_index] == true) {
 			afe_port_topology_deregister(port_id);
+			this_afe.afe_port_start_failed[port_index] = false;
+		}
 		afe_send_port_topology_id(port_id);
 		afe_send_cal(port_id);
 		afe_send_hw_delay(port_id, rate);
@@ -5966,6 +5973,8 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config,
 	ret = afe_send_cmd_port_start(port_id);
 
 fail_cmd:
+	if (ret)
+		this_afe.afe_port_start_failed[port_index] = true;
 	mutex_unlock(&this_afe.afe_cmd_lock);
 	return ret;
 }
@@ -8122,7 +8131,7 @@ static int afe_sidetone_iir(u16 tx_port_id)
 	}
 	mutex_lock(&this_afe.cal_data[cal_index]->lock);
 	cal_block = cal_utils_get_only_cal_block(this_afe.cal_data[cal_index]);
-	if (cal_block == NULL || cal_utils_is_cal_stale(cal_block)) {
+	if (cal_block == NULL || cal_utils_is_cal_stale(cal_block, this_afe.cal_data[cal_index])) {
 		pr_err("%s: cal_block not found\n ", __func__);
 		mutex_unlock(&this_afe.cal_data[cal_index]->lock);
 		ret = -EINVAL;
@@ -8249,7 +8258,7 @@ static int afe_sidetone(u16 tx_port_id, u16 rx_port_id, bool enable)
 
 	mutex_lock(&this_afe.cal_data[cal_index]->lock);
 	cal_block = cal_utils_get_only_cal_block(this_afe.cal_data[cal_index]);
-	if (cal_block == NULL || cal_utils_is_cal_stale(cal_block)) {
+	if (cal_block == NULL || cal_utils_is_cal_stale(cal_block, this_afe.cal_data[cal_index])) {
 		pr_err("%s: cal_block not found\n", __func__);
 		mutex_unlock(&this_afe.cal_data[cal_index]->lock);
 		ret = -EINVAL;
@@ -10317,7 +10326,7 @@ static struct cal_block_data *afe_find_hw_delay_by_path(
 		cal_block = list_entry(ptr,
 			struct cal_block_data, list);
 
-		if (cal_utils_is_cal_stale(cal_block))
+		if (cal_utils_is_cal_stale(cal_block, cal_type))
 			continue;
 
 		if (((struct audio_cal_info_hw_delay *)cal_block->cal_info)
@@ -11164,6 +11173,7 @@ int __init afe_init(void)
 		this_afe.power_mode[i] = 0;
 		this_afe.vad_cfg[i].is_enable = 0;
 		this_afe.vad_cfg[i].pre_roll = 0;
+		this_afe.afe_port_start_failed[i] = false;
 		init_waitqueue_head(&this_afe.wait[i]);
 	}
 	init_waitqueue_head(&this_afe.wait_wakeup);

+ 9 - 3
dsp/q6asm.c

@@ -806,7 +806,7 @@ int send_asm_custom_topology(struct audio_client *ac)
 	set_custom_topology = 0;
 
 	cal_block = cal_utils_get_only_cal_block(cal_data[ASM_CUSTOM_TOP_CAL]);
-	if (cal_block == NULL || cal_utils_is_cal_stale(cal_block))
+	if (cal_block == NULL || cal_utils_is_cal_stale(cal_block, cal_data[ASM_CUSTOM_TOP_CAL]))
 		goto unlock;
 
 	if (cal_block->cal_data.size == 0) {
@@ -8487,6 +8487,7 @@ static int q6asm_memory_map_regions(struct audio_client *ac, int dir,
 	if (mmap_region_cmd == NULL) {
 		rc = -EINVAL;
 		kfree(buffer_node);
+		buffer_node = NULL;
 		return rc;
 	}
 	mmap_regions = (struct avs_cmd_shared_mem_map_regions *)
@@ -8523,6 +8524,7 @@ static int q6asm_memory_map_regions(struct audio_client *ac, int dir,
 					mmap_regions->hdr.opcode, rc);
 		rc = -EINVAL;
 		kfree(buffer_node);
+		buffer_node = NULL;
 		goto fail_cmd;
 	}
 
@@ -8534,6 +8536,7 @@ static int q6asm_memory_map_regions(struct audio_client *ac, int dir,
 		pr_err("%s: timeout. waited for memory_map\n", __func__);
 		rc = -ETIMEDOUT;
 		kfree(buffer_node);
+		buffer_node = NULL;
 		goto fail_cmd;
 	}
 	if (atomic_read(&ac->mem_state) > 0) {
@@ -8543,6 +8546,7 @@ static int q6asm_memory_map_regions(struct audio_client *ac, int dir,
 		rc = adsp_err_get_lnx_err_code(
 			atomic_read(&ac->mem_state));
 		kfree(buffer_node);
+		buffer_node = NULL;
 		goto fail_cmd;
 	}
 	mutex_lock(&ac->cmd_lock);
@@ -8562,6 +8566,7 @@ static int q6asm_memory_map_regions(struct audio_client *ac, int dir,
 	rc = 0;
 fail_cmd:
 	kfree(mmap_region_cmd);
+	mmap_region_cmd = NULL;
 	return rc;
 }
 EXPORT_SYMBOL(q6asm_memory_map_regions);
@@ -8657,6 +8662,7 @@ fail_cmd:
 		if (buf_node->buf_phys_addr == buf_add) {
 			list_del(&buf_node->list);
 			kfree(buf_node);
+			buf_node = NULL;
 			break;
 		}
 	}
@@ -11004,7 +11010,7 @@ static int q6asm_get_asm_topology_apptype(struct q6asm_cal_info *cal_info)
 
 	mutex_lock(&cal_data[ASM_TOPOLOGY_CAL]->lock);
 	cal_block = cal_utils_get_only_cal_block(cal_data[ASM_TOPOLOGY_CAL]);
-	if (cal_block == NULL || cal_utils_is_cal_stale(cal_block))
+	if (cal_block == NULL || cal_utils_is_cal_stale(cal_block, cal_data[ASM_CUSTOM_TOP_CAL]))
 		goto unlock;
 	cal_info->topology_id = ((struct audio_cal_info_asm_top *)
 		cal_block->cal_info)->topology;
@@ -11064,7 +11070,7 @@ int q6asm_send_cal(struct audio_client *ac)
 		goto unlock;
 	}
 
-	if (cal_utils_is_cal_stale(cal_block)) {
+	if (cal_utils_is_cal_stale(cal_block, cal_data[ASM_AUDSTRM_CAL])) {
 		rc = 0; /* not error case */
 		pr_debug("%s: cal_block is stale\n",
 			__func__);

+ 31 - 2
dsp/q6core.c

@@ -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.
  */
 
 #include <linux/kernel.h>
@@ -33,6 +33,8 @@
 
 #define ADSP_STATE_READY_TIMEOUT_MS 3000
 
+#define ADSP_MODULES_READY_AVS_STATE 5
+
 #define APR_ENOTREADY 10
 #define MEMPOOL_ID_MASK 0xFF
 #define MDF_MAP_TOKEN 0xF000
@@ -973,12 +975,39 @@ int32_t q6core_avcs_load_unload_modules(struct avcs_load_unload_modules_payload
 	size_t packet_size = 0,  payload_size = 0;
 	struct avcs_cmd_dynamic_modules *mod = NULL;
 	int num_modules;
+	unsigned long timeout;
 
 	if (payload == NULL) {
 		pr_err("%s: payload is null\n", __func__);
 		return -EINVAL;
 	}
 
+	if ((q6core_lcl.avs_state != ADSP_MODULES_READY_AVS_STATE)
+		&& (preload_type == AVCS_LOAD_MODULES)) {
+		timeout = jiffies +
+			msecs_to_jiffies(ADSP_STATE_READY_TIMEOUT_MS);
+
+		do {
+			q6core_is_adsp_ready();
+			if (q6core_lcl.param == ADSP_MODULES_READY_AVS_STATE) {
+				pr_debug("%s: ADSP state up with all modules loaded\n",
+					 __func__);
+				q6core_lcl.avs_state = ADSP_MODULES_READY_AVS_STATE;
+				break;
+			}
+
+			/*
+			 * ADSP will be coming up after boot up and AVS might
+			 * not be fully up with all modules when the control reaches here.
+			 * So, wait for 50msec before checking ADSP state again.
+			 */
+			msleep(50);
+		} while (time_after(timeout, jiffies));
+
+		if (q6core_lcl.param != ADSP_MODULES_READY_AVS_STATE)
+			pr_err("%s: all modules might be not loaded yet on ADSP\n",
+				__func__);
+	}
 	mutex_lock(&(q6core_lcl.cmd_lock));
 	num_modules = payload->num_modules;
 	ocm_core_open();
@@ -1989,7 +2018,7 @@ static int q6core_is_avs_up(int32_t *avs_state)
 		msleep(50);
 	} while (time_after(timeout, jiffies));
 
-	*avs_state = adsp_ready;
+	*avs_state = q6core_lcl.param;
 	pr_debug("%s: ADSP Audio is %s\n", __func__,
 	       adsp_ready ? "ready" : "not ready");
 

+ 7 - 1
dsp/q6lsm.c

@@ -2526,6 +2526,7 @@ int q6lsm_get_one_param(struct lsm_client *client,
 {
 	struct param_hdr_v3 param_info;
 	int rc = 0;
+	bool iid_supported = q6common_is_instance_id_supported();
 
 	memset(&param_info, 0, sizeof(param_info));
 
@@ -2534,7 +2535,12 @@ int q6lsm_get_one_param(struct lsm_client *client,
 		param_info.module_id = p_info->module_id;
 		param_info.instance_id = p_info->instance_id;
 		param_info.param_id = p_info->param_id;
-		param_info.param_size = p_info->param_size + sizeof(param_info);
+
+		if (iid_supported)
+			param_info.param_size = p_info->param_size + sizeof(struct param_hdr_v3);
+		else
+			param_info.param_size = p_info->param_size + sizeof(struct param_hdr_v2);
+
 		rc = q6lsm_get_params(client, NULL, &param_info);
 		if (rc) {
 			pr_err("%s: LSM_GET_CUSTOM_PARAMS failed, rc %d\n",

+ 0 - 1
include/asoc/wcd-mbhc-v2.h

@@ -551,7 +551,6 @@ struct wcd_mbhc {
 	wait_queue_head_t wait_btn_press;
 	bool is_btn_press;
 	u8 current_plug;
-	u8 plug_before_ssr;
 	bool in_swch_irq_handler;
 	bool hphl_swh; /*track HPHL switch NC / NO */
 	bool gnd_swh; /*track GND switch NC / NO */

+ 3 - 1
include/dsp/audio_cal_utils.h

@@ -95,5 +95,7 @@ int32_t cal_utils_get_cal_type_version(void *cal_type_data);
 
 void cal_utils_mark_cal_used(struct cal_block_data *cal_block);
 
-bool cal_utils_is_cal_stale(struct cal_block_data *cal_block);
+bool cal_utils_is_cal_stale(struct cal_block_data *cal_block, struct cal_type_data *cal_type);
+
+int cal_utils_init(void);
 #endif

+ 1 - 1
include/soc/soundwire.h

@@ -17,7 +17,7 @@
 #define SWR_CLK_RATE_2P4MHZ      2400000
 #define SWR_CLK_RATE_4P8MHZ      4800000
 #define SWR_CLK_RATE_9P6MHZ      9600000
-#define SWR_CLK_RATE_11P2896MHZ  1128960
+#define SWR_CLK_RATE_11P2896MHZ  11289600
 
 extern struct bus_type soundwire_type;
 struct swr_device;

+ 0 - 2
soc/pinctrl-lpi.c

@@ -181,8 +181,6 @@ static int lpi_gpio_write(struct lpi_gpio_pad *pad, unsigned int addr,
 	int ret = 0;
 
 	if (!lpi_dev_up) {
-		pr_err_ratelimited("%s: ADSP is down due to SSR, return\n",
-				  __func__);
 		return 0;
 	}
 	pm_runtime_get_sync(lpi_dev);

+ 22 - 6
soc/swr-mstr-ctrl.c

@@ -752,6 +752,9 @@ static int swrm_get_port_config(struct swr_mstr_ctrl *swrm)
 	if (swrm->mport_cfg[SWRM_DSD_PARAMS_PORT].port_en &&
 				(swrm->master_id == MASTER_ID_RX))
 		usecase = 1;
+	else if ((swrm->master_id == MASTER_ID_RX) &&
+		(swrm->bus_clk == SWR_CLK_RATE_11P2896MHZ))
+		usecase = 2;
 
 	if (swrm->bus_clk == SWR_CLK_RATE_4P8MHZ)
 		usecase = 1;
@@ -2748,6 +2751,11 @@ static int swrm_probe(struct platform_device *pdev)
 	}
 	devm_kfree(&pdev->dev, temp);
 
+	ret = of_property_read_u32(pdev->dev.of_node, "qcom,is-always-on",
+				&swrm->is_always_on);
+	if (ret)
+		dev_dbg(&pdev->dev, "%s: failed to get is_always_on flag\n", __func__);
+
 	swrm->reg_irq = pdata->reg_irq;
 	swrm->master.read = swrm_read;
 	swrm->master.write = swrm_write;
@@ -2870,7 +2878,7 @@ static int swrm_probe(struct platform_device *pdev)
 	 * controller will be up now
 	 */
 	swr_master_add_boarddevices(&swrm->master);
-	if (swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, true))
+	if (!swrm->is_always_on && swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, true))
 		dev_dbg(&pdev->dev, "%s: Audio HW Vote is failed\n", __func__);
 	mutex_lock(&swrm->mlock);
 	swrm_clk_request(swrm, true);
@@ -3018,7 +3026,7 @@ static int swrm_runtime_resume(struct device *dev)
 	struct swr_mstr_ctrl *swrm = platform_get_drvdata(pdev);
 	int ret = 0;
 	bool swrm_clk_req_err = false;
-	bool hw_core_err = false;
+	bool hw_core_err = false, aud_core_err = false;
 	struct swr_master *mstr = &swrm->master;
 	struct swr_device *swr_dev;
 	u32 temp = 0;
@@ -3034,9 +3042,11 @@ static int swrm_runtime_resume(struct device *dev)
 			__func__);
 		hw_core_err = true;
 	}
-	if (swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, true))
+	if (swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, true)) {
 		dev_err(dev, "%s:lpass audio hw enable failed\n",
 			__func__);
+		aud_core_err = true;
+	}
 
 	if ((swrm->state == SWR_MSTR_DOWN) ||
 	    (swrm->state == SWR_MSTR_SSR && swrm->dev_up)) {
@@ -3127,6 +3137,9 @@ static int swrm_runtime_resume(struct device *dev)
 		swrm->state = SWR_MSTR_UP;
 	}
 exit:
+	if (swrm->is_always_on && !aud_core_err)
+		swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, false);
+
 	if (!hw_core_err)
 		swrm_request_hw_vote(swrm, LPASS_HW_CORE, false);
 	if (swrm_clk_req_err)
@@ -3149,7 +3162,7 @@ static int swrm_runtime_suspend(struct device *dev)
 	struct platform_device *pdev = to_platform_device(dev);
 	struct swr_mstr_ctrl *swrm = platform_get_drvdata(pdev);
 	int ret = 0;
-	bool hw_core_err = false;
+	bool hw_core_err = false, aud_core_err = false;
 	struct swr_master *mstr = &swrm->master;
 	struct swr_device *swr_dev;
 	int current_state = 0;
@@ -3169,6 +3182,8 @@ static int swrm_runtime_suspend(struct device *dev)
 		hw_core_err = true;
 	}
 
+	if (swrm->is_always_on && swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, true))
+		aud_core_err = true;
 	if ((current_state == SWR_MSTR_UP) ||
 	    (current_state == SWR_MSTR_SSR)) {
 
@@ -3250,11 +3265,12 @@ static int swrm_runtime_suspend(struct device *dev)
 		swrm->state = SWR_MSTR_DOWN;
 
 exit:
-	if (swrm->state != SWR_MSTR_UP) {
+	if (!swrm->is_always_on && swrm->state != SWR_MSTR_UP) {
 		if (swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, false))
 			dev_dbg(dev, "%s:lpass audio hw enable failed\n",
 			__func__);
-	}
+	} else if (swrm->is_always_on && !aud_core_err)
+		swrm_request_hw_vote(swrm, LPASS_AUDIO_CORE, false);
 
 	if (!hw_core_err)
 		swrm_request_hw_vote(swrm, LPASS_HW_CORE, false);

+ 1 - 0
soc/swr-mstr-ctrl.h

@@ -194,6 +194,7 @@ struct swr_mstr_ctrl {
 	u32 wr_fifo_depth;
 	bool enable_slave_irq;
 	u64 logical_dev[SWRM_NUM_AUTO_ENUM_SLAVES];
+	u32 is_always_on;
 #ifdef CONFIG_DEBUG_FS
 	struct dentry *debugfs_swrm_dent;
 	struct dentry *debugfs_peek;

Niektoré súbory nie sú zobrazené, pretože je v týchto rozdielových dátach zmenené mnoho súborov