Browse Source

Merge 19df8856be8387b35e2b1bacfecd85dc4991be15 on remote branch

Change-Id: I32ad940827f96569a1f1fcc3d43d9e48caa85433
Linux Build Service Account 4 years ago
parent
commit
ddeac0d77f

+ 13 - 5
asoc/codecs/audio-ext-clk-up.c

@@ -1,5 +1,5 @@
 // SPDX-License-Identifier: GPL-2.0-only
-/* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
  */
 
 #include <linux/kernel.h>
@@ -14,6 +14,7 @@
 #include <linux/pinctrl/consumer.h>
 #include <linux/platform_device.h>
 #include <dt-bindings/clock/qcom,audio-ext-clk.h>
+#include <linux/ratelimit.h>
 #include <dsp/q6afe-v2.h>
 #include "audio-ext-clk-up.h"
 
@@ -67,6 +68,7 @@ static int audio_ext_clk_prepare(struct clk_hw *hw)
 	struct audio_ext_clk_priv *clk_priv = to_audio_clk(hw);
 	struct pinctrl_info *pnctrl_info = &clk_priv->audio_clk.pnctrl_info;
 	int ret;
+	static DEFINE_RATELIMIT_STATE(rtl, 1 * HZ, 1);
 
 	if ((clk_priv->clk_src >= AUDIO_EXT_CLK_LPASS) &&
 		(clk_priv->clk_src < AUDIO_EXT_CLK_LPASS_MAX))  {
@@ -75,7 +77,8 @@ static int audio_ext_clk_prepare(struct clk_hw *hw)
 			__func__, clk_priv->clk_src);
 		ret = afe_set_lpass_clk_cfg(IDX_RSVD_3, &clk_priv->clk_cfg);
 		if (ret < 0) {
-			pr_err_ratelimited("%s afe_set_digital_codec_core_clock failed\n",
+			if (__ratelimit(&rtl))
+				pr_err_ratelimited("%s afe_set_digital_codec_core_clock failed\n",
 				__func__);
 			return ret;
 		}
@@ -101,6 +104,7 @@ static void audio_ext_clk_unprepare(struct clk_hw *hw)
 	struct audio_ext_clk_priv *clk_priv = to_audio_clk(hw);
 	struct pinctrl_info *pnctrl_info = &clk_priv->audio_clk.pnctrl_info;
 	int ret;
+	static DEFINE_RATELIMIT_STATE(rtl, 1 * HZ, 1);
 
 	if (pnctrl_info->pinctrl) {
 		ret = pinctrl_select_state(pnctrl_info->pinctrl,
@@ -118,9 +122,11 @@ static void audio_ext_clk_unprepare(struct clk_hw *hw)
 		trace_printk("%s: unvote for %d clock\n",
 			__func__, clk_priv->clk_src);
 		ret = afe_set_lpass_clk_cfg(IDX_RSVD_3, &clk_priv->clk_cfg);
-		if (ret < 0)
-			pr_err_ratelimited("%s: afe_set_lpass_clk_cfg failed, ret = %d\n",
+		if (ret < 0) {
+			if (__ratelimit(&rtl))
+				pr_err_ratelimited("%s: afe_set_lpass_clk_cfg failed, ret = %d\n",
 				__func__, ret);
+		}
 	}
 
 	if (pnctrl_info->base)
@@ -149,6 +155,7 @@ static int lpass_hw_vote_prepare(struct clk_hw *hw)
 {
 	struct audio_ext_clk_priv *clk_priv = to_audio_clk(hw);
 	int ret;
+	static DEFINE_RATELIMIT_STATE(rtl, 1 * HZ, 1);
 
 	if (clk_priv->clk_src == AUDIO_EXT_CLK_LPASS_CORE_HW_VOTE)  {
 		trace_printk("%s: vote for %d clock\n",
@@ -170,7 +177,8 @@ static int lpass_hw_vote_prepare(struct clk_hw *hw)
 			"LPASS_HW_DCODEC",
 			&clk_priv->lpass_audio_hwvote_client_handle);
 		if (ret < 0) {
-			pr_err("%s lpass audio hw vote failed %d\n",
+			if (__ratelimit(&rtl))
+				pr_err("%s lpass audio hw vote failed %d\n",
 				__func__, ret);
 			return ret;
 		}

+ 6 - 2
asoc/codecs/bolero/bolero-cdc.c

@@ -15,6 +15,7 @@
 #include <linux/pm_runtime.h>
 #include <soc/swr-common.h>
 #include <dsp/digital-cdc-rsc-mgr.h>
+#include <linux/ratelimit.h>
 #include "bolero-cdc.h"
 #include "internal.h"
 #include "bolero-clk-rsc.h"
@@ -1373,6 +1374,7 @@ static int bolero_probe(struct platform_device *pdev)
 		bolero_reg_access[VA_MACRO] = bolero_va_reg_access_v3;
 	}
 
+	BLOCKING_INIT_NOTIFIER_HEAD(&priv->notifier);
 	priv->dev = &pdev->dev;
 	priv->dev_up = true;
 	priv->initial_boot = true;
@@ -1444,6 +1446,7 @@ int bolero_runtime_resume(struct device *dev)
 {
 	struct bolero_priv *priv = dev_get_drvdata(dev->parent);
 	int ret = 0;
+	static DEFINE_RATELIMIT_STATE(rtl, 1 * HZ, 1);
 
 	mutex_lock(&priv->vote_lock);
 	if (priv->lpass_core_hw_vote == NULL) {
@@ -1472,8 +1475,9 @@ audio_vote:
 	if (priv->core_audio_vote_count == 0) {
 		ret = digital_cdc_rsc_mgr_hw_vote_enable(priv->lpass_audio_hw_vote);
 		if (ret < 0) {
-			dev_err(dev, "%s:lpass audio hw enable failed\n",
-				__func__);
+			if (__ratelimit(&rtl))
+				dev_err(dev, "%s:lpass audio hw enable failed\n",
+					__func__);
 			goto done;
 		}
 	}

+ 12 - 5
asoc/codecs/bolero/bolero-clk-rsc.c

@@ -11,6 +11,7 @@
 #include <linux/kernel.h>
 #include <linux/clk.h>
 #include <linux/clk-provider.h>
+#include <linux/ratelimit.h>
 #include "bolero-cdc.h"
 #include "bolero-clk-rsc.h"
 
@@ -193,13 +194,15 @@ static int bolero_clk_rsc_mux0_clk_request(struct bolero_clk_rsc *priv,
 					   bool enable)
 {
 	int ret = 0;
+	static DEFINE_RATELIMIT_STATE(rtl, 1 * HZ, 1);
 
 	if (enable) {
 		/* Enable Requested Core clk */
 		if (priv->clk_cnt[clk_id] == 0) {
 			ret = clk_prepare_enable(priv->clk[clk_id]);
 			if (ret < 0) {
-				dev_err_ratelimited(priv->dev, "%s:clk_id %d enable failed\n",
+				if (__ratelimit(&rtl))
+					dev_err_ratelimited(priv->dev, "%s:clk_id %d enable failed\n",
 							__func__, clk_id);
 				goto done;
 			}
@@ -207,7 +210,8 @@ static int bolero_clk_rsc_mux0_clk_request(struct bolero_clk_rsc *priv,
 				ret = clk_prepare_enable(
 					priv->clk[clk_id + NPL_CLK_OFFSET]);
 				if (ret < 0) {
-					dev_err_ratelimited(priv->dev, "%s:clk_id %d enable failed\n",
+					if (__ratelimit(&rtl))
+						dev_err_ratelimited(priv->dev, "%s:clk_id %d enable failed\n",
 						__func__,
 						clk_id + NPL_CLK_OFFSET);
 					goto err;
@@ -246,6 +250,7 @@ static int bolero_clk_rsc_mux1_clk_request(struct bolero_clk_rsc *priv,
 	int ret = 0;
 	int default_clk_id = priv->default_clk_id[clk_id];
 	u32 muxsel = 0;
+	static DEFINE_RATELIMIT_STATE(rtl, 1 * HZ, 1);
 
 	clk_muxsel = bolero_clk_rsc_get_clk_muxsel(priv, clk_id);
 	if (!clk_muxsel) {
@@ -265,15 +270,17 @@ static int bolero_clk_rsc_mux1_clk_request(struct bolero_clk_rsc *priv,
 
 			ret = clk_prepare_enable(priv->clk[clk_id]);
 			if (ret < 0) {
-				dev_err_ratelimited(priv->dev, "%s:clk_id %d enable failed\n",
-					__func__, clk_id);
+				if (__ratelimit(&rtl))
+					dev_err_ratelimited(priv->dev, "%s:clk_id %d enable failed\n",
+						__func__, clk_id);
 				goto err_clk;
 			}
 			if (priv->clk[clk_id + NPL_CLK_OFFSET]) {
 				ret = clk_prepare_enable(
 					priv->clk[clk_id + NPL_CLK_OFFSET]);
 				if (ret < 0) {
-					dev_err_ratelimited(priv->dev, "%s:clk_id %d enable failed\n",
+					if (__ratelimit(&rtl))
+						dev_err_ratelimited(priv->dev, "%s:clk_id %d enable failed\n",
 						__func__,
 						clk_id + NPL_CLK_OFFSET);
 					goto err_npl_clk;

+ 4 - 4
asoc/codecs/bolero/tx-macro.c

@@ -2650,11 +2650,7 @@ static int tx_macro_register_event_listener(struct snd_soc_component *component,
 				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);
 			if (!tx_priv->disable_afe_wakeup_event_listener)
 				ret = swrm_wcd_notify(
 					tx_priv->swr_ctrl_data[0].tx_swr_pdev,
@@ -2690,6 +2686,8 @@ static int tx_macro_tx_va_mclk_enable(struct tx_macro_priv *tx_priv,
 					__func__);
 				goto exit;
 			}
+			msm_cdc_pinctrl_set_wakeup_capable(
+					tx_priv->tx_swr_gpio_p, false);
 		}
 
 		clk_tx_ret = bolero_clk_rsc_request_clock(tx_priv->dev,
@@ -2818,6 +2816,8 @@ tx_clk:
 						   TX_CORE_CLK,
 						   false);
 		if (tx_priv->swr_clk_users == 0) {
+			msm_cdc_pinctrl_set_wakeup_capable(
+					tx_priv->tx_swr_gpio_p, true);
 			ret = msm_cdc_pinctrl_select_sleep_state(
 						tx_priv->tx_swr_gpio_p);
 			if (ret < 0) {

+ 31 - 29
asoc/codecs/bolero/va-macro.c

@@ -170,9 +170,11 @@ struct va_macro_priv {
 	int va_swr_clk_cnt;
 	int va_clk_status;
 	int tx_clk_status;
+	int dapm_tx_clk_status;
 	bool lpi_enable;
 	bool register_event_listener;
 	int dec_mode[VA_MACRO_NUM_DECIMATORS];
+	u16 current_clk_id;
 };
 
 static bool va_macro_get_data(struct snd_soc_component *component,
@@ -392,7 +394,14 @@ 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) {
+		dev_dbg(component->dev,
+			"%s: va_swr_clk_cnt %d, tx_swr_clk_cnt %d, tx_clk_status %d\n",
+			__func__, va_priv->va_swr_clk_cnt,
+			va_priv->tx_swr_clk_cnt, va_priv->tx_clk_status);
+		if (va_priv->current_clk_id == VA_CORE_CLK) {
+			return 0;
+		} else if ( va_priv->va_swr_clk_cnt != 0 &&
+				va_priv->tx_clk_status) {
 			ret = bolero_clk_rsc_request_clock(va_priv->dev,
 					va_priv->default_clk_id,
 					VA_CORE_CLK,
@@ -417,14 +426,13 @@ static int va_macro_swr_pwr_event_v2(struct snd_soc_dapm_widget *w,
 					false);
 				break;
 			}
+			va_priv->current_clk_id = VA_CORE_CLK;
 		}
-		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) {
+		if (va_priv->current_clk_id == VA_CORE_CLK &&
+			va_priv->va_swr_clk_cnt != 0 &&
+			va_priv->tx_clk_status) {
 			ret = bolero_clk_rsc_request_clock(va_priv->dev,
 					va_priv->default_clk_id,
 					TX_CORE_CLK,
@@ -449,6 +457,7 @@ static int va_macro_swr_pwr_event_v2(struct snd_soc_dapm_widget *w,
 					false);
 				break;
 			}
+			va_priv->current_clk_id = TX_CORE_CLK;
 		}
 		break;
 	default:
@@ -555,7 +564,7 @@ static int va_macro_mclk_event(struct snd_soc_dapm_widget *w,
 						   TX_CORE_CLK,
 						   true);
 		if (!ret)
-			va_priv->tx_clk_status++;
+			va_priv->dapm_tx_clk_status++;
 
 		if (va_priv->lpi_enable)
 			ret = va_macro_mclk_enable(va_priv, 1, true);
@@ -569,12 +578,12 @@ static int va_macro_mclk_event(struct snd_soc_dapm_widget *w,
 			bolero_tx_mclk_enable(component, 0);
 		}
 
-		if (va_priv->tx_clk_status > 0) {
+		if (va_priv->dapm_tx_clk_status > 0) {
 			bolero_clk_rsc_request_clock(va_priv->dev,
 					   va_priv->default_clk_id,
 					   TX_CORE_CLK,
 					   false);
-			va_priv->tx_clk_status--;
+			va_priv->dapm_tx_clk_status--;
 		}
 		break;
 	default:
@@ -597,9 +606,12 @@ static int va_macro_tx_va_mclk_enable(struct va_macro_priv *va_priv,
 		(enable ? "enable" : "disable"), va_priv->va_mclk_users);
 
 	if (enable) {
-		if (va_priv->swr_clk_users == 0)
+		if (va_priv->swr_clk_users == 0) {
 			msm_cdc_pinctrl_select_active_state(
 						va_priv->va_swr_gpio_p);
+			msm_cdc_pinctrl_set_wakeup_capable(
+					va_priv->va_swr_gpio_p, false);
+		}
 		clk_tx_ret = bolero_clk_rsc_request_clock(va_priv->dev,
 						   TX_CORE_CLK,
 						   TX_CORE_CLK,
@@ -692,9 +704,12 @@ static int va_macro_tx_va_mclk_enable(struct va_macro_priv *va_priv,
 						   TX_CORE_CLK,
 						   TX_CORE_CLK,
 						   false);
-		if (va_priv->swr_clk_users == 0)
+		if (va_priv->swr_clk_users == 0) {
+			msm_cdc_pinctrl_set_wakeup_capable(
+					va_priv->va_swr_gpio_p, true);
 			msm_cdc_pinctrl_select_sleep_state(
 						va_priv->va_swr_gpio_p);
+		}
 	}
 	return 0;
 
@@ -1313,12 +1328,12 @@ static int va_macro_enable_tx(struct snd_soc_dapm_widget *w,
 
 	switch (event) {
 	case SND_SOC_DAPM_POST_PMU:
-		if (va_priv->tx_clk_status > 0) {
+		if (va_priv->dapm_tx_clk_status > 0) {
 			ret = bolero_clk_rsc_request_clock(va_priv->dev,
 						   va_priv->default_clk_id,
 						   TX_CORE_CLK,
 						   false);
-			va_priv->tx_clk_status--;
+			va_priv->dapm_tx_clk_status--;
 		}
 		break;
 	case SND_SOC_DAPM_PRE_PMD:
@@ -1327,7 +1342,7 @@ static int va_macro_enable_tx(struct snd_soc_dapm_widget *w,
 						   TX_CORE_CLK,
 						   true);
 		if (!ret)
-			va_priv->tx_clk_status++;
+			va_priv->dapm_tx_clk_status++;
 		break;
 	default:
 		dev_err(va_priv->dev,
@@ -2225,18 +2240,6 @@ static const struct snd_soc_dapm_route va_audio_map_common[] = {
 	{"VA SMIC MUX1", "SWR_MIC11", "VA SWR_INPUT"},
 
 	{"VA SWR_INPUT", NULL, "VA_SWR_PWR"},
-	{"VA SWR_INPUT", NULL, "VA_SWR_PWR"},
-	{"VA SWR_INPUT", NULL, "VA_SWR_PWR"},
-	{"VA SWR_INPUT", NULL, "VA_SWR_PWR"},
-	{"VA SWR_INPUT", NULL, "VA_SWR_PWR"},
-	{"VA SWR_INPUT", NULL, "VA_SWR_PWR"},
-	{"VA SWR_INPUT", NULL, "VA_SWR_PWR"},
-	{"VA SWR_INPUT", NULL, "VA_SWR_PWR"},
-	{"VA SWR_INPUT", NULL, "VA_SWR_PWR"},
-	{"VA SWR_INPUT", NULL, "VA_SWR_PWR"},
-	{"VA SWR_INPUT", NULL, "VA_SWR_PWR"},
-	{"VA SWR_INPUT", NULL, "VA_SWR_PWR"},
-
 };
 
 static const struct snd_soc_dapm_route va_audio_map_v3[] = {
@@ -2299,9 +2302,7 @@ static const struct snd_soc_dapm_route va_audio_map_v3[] = {
 };
 
 static const struct snd_soc_dapm_route va_audio_map_v2[] = {
-	{"VA_AIF1 CAP", NULL, "VA_SWR_CLK"},
-	{"VA_AIF2 CAP", NULL, "VA_SWR_CLK"},
-	{"VA_AIF3 CAP", NULL, "VA_SWR_CLK"},
+	{"VA SWR_INPUT", NULL, "VA_SWR_CLK"},
 };
 
 static const struct snd_soc_dapm_route va_audio_map[] = {
@@ -3170,6 +3171,7 @@ static int va_macro_probe(struct platform_device *pdev)
 	}
 	va_priv->clk_id = VA_CORE_CLK;
 	va_priv->default_clk_id = default_clk_id;
+	va_priv->current_clk_id = TX_CORE_CLK;
 
 	if (is_used_va_swr_gpio) {
 		va_priv->reset_swr = true;

+ 2 - 1
asoc/holi.c

@@ -4343,7 +4343,8 @@ err:
 
 static int msm_fe_qos_prepare(struct snd_pcm_substream *substream)
 {
-	(void)substream;
+	if (pm_qos_request_active(&substream->latency_pm_qos_req))
+		pm_qos_remove_request(&substream->latency_pm_qos_req);
 
 	qos_client_active_cnt++;
 	if (qos_client_active_cnt == 1)

+ 106 - 2
asoc/msm-dai-q6-v2.c

@@ -31,6 +31,9 @@
 #define MSM_DAI_TWS_CHANNEL_MODE_ONE 1
 #define MSM_DAI_TWS_CHANNEL_MODE_TWO 2
 
+#define MSM_DAI_LC3_CHANNEL_MODE_ONE 1
+#define MSM_DAI_LC3_CHANNEL_MODE_TWO 2
+
 #define spdif_clock_value(rate) (2*rate*32*2)
 #define CHANNEL_STATUS_SIZE 24
 #define CHANNEL_STATUS_MASK_INIT 0x0
@@ -63,6 +66,7 @@ enum {
 	DEC_FMT_MP3 = ASM_MEDIA_FMT_MP3,
 	ENC_FMT_APTX_AD_SPEECH = ASM_MEDIA_FMT_APTX_AD_SPEECH,
 	DEC_FMT_APTX_AD_SPEECH = ASM_MEDIA_FMT_APTX_AD_SPEECH,
+	ENC_FMT_LC3 = ASM_MEDIA_FMT_LC3,
 };
 
 enum {
@@ -3234,7 +3238,11 @@ static int msm_dai_q6_afe_enc_cfg_get(struct snd_kcontrol *kcontrol,
 				&dai_data->enc_config.data,
 				sizeof(struct asm_aptx_ad_speech_enc_cfg_t));
 			break;
-
+		case ENC_FMT_LC3:
+			memcpy(ucontrol->value.bytes.data + format_size,
+				&dai_data->enc_config.data,
+				sizeof(struct asm_enc_lc3_cfg_t));
+			break;
 		default:
 			pr_debug("%s: unknown format = %d\n",
 				 __func__, dai_data->enc_config.format);
@@ -3303,6 +3311,11 @@ static int msm_dai_q6_afe_enc_cfg_put(struct snd_kcontrol *kcontrol,
 				ucontrol->value.bytes.data + format_size,
 				sizeof(struct asm_aptx_ad_speech_enc_cfg_t));
 			break;
+		case ENC_FMT_LC3:
+			memcpy(&dai_data->enc_config.data,
+				ucontrol->value.bytes.data + format_size,
+				sizeof(struct asm_enc_lc3_cfg_t));
+			break;
 
 		default:
 			pr_debug("%s: Ignore enc config for unknown format = %d\n",
@@ -3335,6 +3348,12 @@ static const struct soc_enum tws_chs_mode_enum[] = {
 	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(tws_chs_mode_text), tws_chs_mode_text),
 };
 
+static const char *const lc3_chs_mode_text[] = {"Zero", "One", "Two"};
+
+static const struct soc_enum lc3_chs_mode_enum[] = {
+	SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(lc3_chs_mode_text), lc3_chs_mode_text),
+};
+
 static int msm_dai_q6_afe_input_channel_get(struct snd_kcontrol *kcontrol,
 			struct snd_ctl_elem_value *ucontrol)
 {
@@ -3424,6 +3443,67 @@ exit:
 	return ret;
 }
 
+static int msm_dai_q6_lc3_channel_mode_get(struct snd_kcontrol *kcontrol,
+			struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_dai *dai = kcontrol->private_data;
+	struct msm_dai_q6_dai_data *dai_data = NULL;
+
+	if (dai)
+		dai_data = dev_get_drvdata(dai->dev);
+
+	if (dai_data) {
+		ucontrol->value.integer.value[0] =
+				dai_data->enc_config.lc3_mono_mode;
+		pr_debug("%s:lc3 channel mode = %d\n",
+			 __func__, dai_data->enc_config.lc3_mono_mode);
+	}
+
+	return 0;
+}
+
+static int msm_dai_q6_lc3_channel_mode_put(struct snd_kcontrol *kcontrol,
+			struct snd_ctl_elem_value *ucontrol)
+{
+	struct snd_soc_dai *dai = kcontrol->private_data;
+	struct msm_dai_q6_dai_data *dai_data = NULL;
+	int ret = 0;
+	u32 format = 0;
+
+	if (dai)
+		dai_data = dev_get_drvdata(dai->dev);
+
+	if (dai_data)
+		format = dai_data->enc_config.format;
+	else
+		goto exit;
+
+	if (format == ENC_FMT_LC3) {
+		if (test_bit(STATUS_PORT_STARTED, dai_data->status_mask)) {
+			ret = afe_set_lc3_channel_mode(format,
+				dai->id, ucontrol->value.integer.value[0]);
+			if (ret < 0) {
+				pr_err("%s: channel mode setting failed for LC3\n",
+				__func__);
+				goto exit;
+			} else {
+				pr_debug("%s: updating lc3 channel mode : %d\n",
+				__func__, dai_data->enc_config.lc3_mono_mode);
+			}
+		}
+		if (ucontrol->value.integer.value[0] ==
+			MSM_DAI_LC3_CHANNEL_MODE_ONE ||
+			ucontrol->value.integer.value[0] ==
+			MSM_DAI_LC3_CHANNEL_MODE_TWO)
+			dai_data->enc_config.lc3_mono_mode =
+				ucontrol->value.integer.value[0];
+		else
+			return -EINVAL;
+	}
+exit:
+	return ret;
+}
+
 static int msm_dai_q6_afe_input_bit_format_get(
 			struct snd_kcontrol *kcontrol,
 			struct snd_ctl_elem_value *ucontrol)
@@ -3628,7 +3708,10 @@ static const struct snd_kcontrol_new afe_enc_config_controls[] = {
 		.info = msm_dai_q6_afe_enc_cfg_info,
 		.get = msm_dai_q6_afe_enc_cfg_get,
 		.put = msm_dai_q6_afe_enc_cfg_put,
-	}
+	},
+	SOC_ENUM_EXT("LC3 Channel Mode", lc3_chs_mode_enum[0],
+			msm_dai_q6_lc3_channel_mode_get,
+			msm_dai_q6_lc3_channel_mode_put)
 };
 
 static int  msm_dai_q6_afe_dec_cfg_info(struct snd_kcontrol *kcontrol,
@@ -3672,6 +3755,13 @@ static int msm_dai_q6_afe_feedback_dec_cfg_get(struct snd_kcontrol *kcontrol,
 			&dai_data->dec_config.data,
 			sizeof(struct asm_aptx_ad_speech_dec_cfg_t));
 		break;
+	case ASM_MEDIA_FMT_LC3:
+		pr_debug("%s: afe_dec_cfg for %d format\n",
+				__func__, dai_data->dec_config.format);
+		memcpy(ucontrol->value.bytes.data + format_size + abr_size,
+			&dai_data->dec_config.data,
+			sizeof(struct asm_lc3_dec_cfg_t));
+		break;
 	default:
 		pr_debug("%s: no afe_dec_cfg for format %d\n",
 				__func__, dai_data->dec_config.format);
@@ -3716,6 +3806,13 @@ static int msm_dai_q6_afe_feedback_dec_cfg_put(struct snd_kcontrol *kcontrol,
 			ucontrol->value.bytes.data + format_size + abr_size,
 			sizeof(struct asm_aptx_ad_speech_dec_cfg_t));
 		break;
+	case ASM_MEDIA_FMT_LC3:
+		pr_debug("%s: afe_dec_cfg for %d format\n",
+				__func__, dai_data->dec_config.format);
+		memcpy(&dai_data->dec_config.data,
+			ucontrol->value.bytes.data + format_size + abr_size,
+			sizeof(struct asm_lc3_dec_cfg_t));
+		break;
 	default:
 		pr_debug("%s: no afe_dec_cfg for format %d\n",
 				__func__, dai_data->dec_config.format);
@@ -4148,6 +4245,9 @@ static int msm_dai_q6_dai_probe(struct snd_soc_dai *dai)
 		rc = snd_ctl_add(dai->component->card->snd_card,
 				 snd_ctl_new1(&afe_enc_config_controls[5],
 				 dai_data));
+		rc = snd_ctl_add(dai->component->card->snd_card,
+				snd_ctl_new1(&afe_enc_config_controls[6],
+				dai));
 		rc = snd_ctl_add(dai->component->card->snd_card,
 				snd_ctl_new1(&avd_drift_config_controls[2],
 					dai));
@@ -7021,6 +7121,10 @@ static int msm_dai_q6_meta_mi2s_hw_params(struct snd_pcm_substream *substream,
 		port_cfg->bit_width = 24;
 		dai_data->bitwidth = 24;
 		break;
+	case SNDRV_PCM_FORMAT_S32_LE:
+		port_cfg->bit_width = 32;
+		dai_data->bitwidth = 32;
+		break;
 	default:
 		pr_err("%s: format %d\n",
 			__func__, params_format(params));

+ 1 - 144
asoc/msm-pcm-routing-v2.c

@@ -22428,11 +22428,11 @@ static const struct snd_kcontrol_new lsm2_mixer_controls[] = {
 		MSM_BACKEND_DAI_INT3_MI2S_TX,
 		MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer,
 		msm_routing_put_listen_mixer),
+#endif
 	SOC_DOUBLE_EXT("VA_CDC_DMA_TX_0", SND_SOC_NOPM,
 		MSM_BACKEND_DAI_VA_CDC_DMA_TX_0,
 		MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer,
 		msm_routing_put_listen_mixer),
-#endif
 	SOC_DOUBLE_EXT("VA_CDC_DMA_TX_1", SND_SOC_NOPM,
 		MSM_BACKEND_DAI_VA_CDC_DMA_TX_1,
 		MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer,
@@ -27882,31 +27882,6 @@ static const struct snd_soc_dapm_route intercon_tdm[] = {
 	{"PRI_TDM_RX_3 Audio Mixer", "MultiMedia34", "MM_DL34"},
 	{"PRI_TDM_RX_3", NULL, "PRI_TDM_RX_3 Audio Mixer"},
 
-	{"PRI_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"},
-	{"PRI_TDM_TX_0 Audio Mixer", "MultiMedia2", "MM_DL2"},
-	{"PRI_TDM_TX_0 Audio Mixer", "MultiMedia3", "MM_DL3"},
-	{"PRI_TDM_TX_0 Audio Mixer", "MultiMedia4", "MM_DL4"},
-	{"PRI_TDM_TX_0 Audio Mixer", "MultiMedia5", "MM_DL5"},
-	{"PRI_TDM_TX_0 Audio Mixer", "MultiMedia6", "MM_DL6"},
-	{"PRI_TDM_TX_0 Audio Mixer", "MultiMedia7", "MM_DL7"},
-	{"PRI_TDM_TX_0 Audio Mixer", "MultiMedia8", "MM_DL8"},
-	{"PRI_TDM_TX_0 Audio Mixer", "MultiMedia9", "MM_DL9"},
-	{"PRI_TDM_TX_0 Audio Mixer", "MultiMedia10", "MM_DL10"},
-	{"PRI_TDM_TX_0 Audio Mixer", "MultiMedia11", "MM_DL11"},
-	{"PRI_TDM_TX_0 Audio Mixer", "MultiMedia12", "MM_DL12"},
-	{"PRI_TDM_TX_0 Audio Mixer", "MultiMedia13", "MM_DL13"},
-	{"PRI_TDM_TX_0 Audio Mixer", "MultiMedia14", "MM_DL14"},
-	{"PRI_TDM_TX_0 Audio Mixer", "MultiMedia15", "MM_DL15"},
-	{"PRI_TDM_TX_0 Audio Mixer", "MultiMedia16", "MM_DL16"},
-	{"PRI_TDM_TX_0 Audio Mixer", "MultiMedia23", "MM_DL23"},
-	{"PRI_TDM_TX_0 Audio Mixer", "MultiMedia24", "MM_DL24"},
-	{"PRI_TDM_TX_0 Audio Mixer", "MultiMedia25", "MM_DL25"},
-	{"PRI_TDM_TX_0 Audio Mixer", "MultiMedia31", "MM_DL31"},
-	{"PRI_TDM_TX_0 Audio Mixer", "MultiMedia32", "MM_DL32"},
-	{"PRI_TDM_TX_0 Audio Mixer", "MultiMedia33", "MM_DL33"},
-	{"PRI_TDM_TX_0 Audio Mixer", "MultiMedia34", "MM_DL34"},
-	{"PRI_TDM_TX_0", NULL, "PRI_TDM_TX_0 Audio Mixer"},
-
 	{"SEC_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"},
 	{"SEC_TDM_RX_0 Audio Mixer", "MultiMedia2", "MM_DL2"},
 	{"SEC_TDM_RX_0 Audio Mixer", "MultiMedia3", "MM_DL3"},
@@ -28015,31 +27990,6 @@ static const struct snd_soc_dapm_route intercon_tdm[] = {
 	{"SEC_TDM_RX_3 Audio Mixer", "MultiMedia34", "MM_DL34"},
 	{"SEC_TDM_RX_3", NULL, "SEC_TDM_RX_3 Audio Mixer"},
 
-	{"SEC_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"},
-	{"SEC_TDM_TX_0 Audio Mixer", "MultiMedia2", "MM_DL2"},
-	{"SEC_TDM_TX_0 Audio Mixer", "MultiMedia3", "MM_DL3"},
-	{"SEC_TDM_TX_0 Audio Mixer", "MultiMedia4", "MM_DL4"},
-	{"SEC_TDM_TX_0 Audio Mixer", "MultiMedia5", "MM_DL5"},
-	{"SEC_TDM_TX_0 Audio Mixer", "MultiMedia6", "MM_DL6"},
-	{"SEC_TDM_TX_0 Audio Mixer", "MultiMedia7", "MM_DL7"},
-	{"SEC_TDM_TX_0 Audio Mixer", "MultiMedia8", "MM_DL8"},
-	{"SEC_TDM_TX_0 Audio Mixer", "MultiMedia9", "MM_DL9"},
-	{"SEC_TDM_TX_0 Audio Mixer", "MultiMedia10", "MM_DL10"},
-	{"SEC_TDM_TX_0 Audio Mixer", "MultiMedia11", "MM_DL11"},
-	{"SEC_TDM_TX_0 Audio Mixer", "MultiMedia12", "MM_DL12"},
-	{"SEC_TDM_TX_0 Audio Mixer", "MultiMedia13", "MM_DL13"},
-	{"SEC_TDM_TX_0 Audio Mixer", "MultiMedia14", "MM_DL14"},
-	{"SEC_TDM_TX_0 Audio Mixer", "MultiMedia15", "MM_DL15"},
-	{"SEC_TDM_TX_0 Audio Mixer", "MultiMedia16", "MM_DL16"},
-	{"SEC_TDM_TX_0 Audio Mixer", "MultiMedia23", "MM_DL23"},
-	{"SEC_TDM_TX_0 Audio Mixer", "MultiMedia24", "MM_DL24"},
-	{"SEC_TDM_TX_0 Audio Mixer", "MultiMedia25", "MM_DL25"},
-	{"SEC_TDM_TX_0 Audio Mixer", "MultiMedia31", "MM_DL31"},
-	{"SEC_TDM_TX_0 Audio Mixer", "MultiMedia32", "MM_DL32"},
-	{"SEC_TDM_TX_0 Audio Mixer", "MultiMedia33", "MM_DL33"},
-	{"SEC_TDM_TX_0 Audio Mixer", "MultiMedia34", "MM_DL34"},
-	{"SEC_TDM_TX_0", NULL, "SEC_TDM_TX_0 Audio Mixer"},
-
 	{"TERT_TDM_RX_0 Audio Mixer", "MultiMedia1", "MM_DL1"},
 	{"TERT_TDM_RX_0 Audio Mixer", "MultiMedia2", "MM_DL2"},
 	{"TERT_TDM_RX_0 Audio Mixer", "MultiMedia3", "MM_DL3"},
@@ -28067,31 +28017,6 @@ static const struct snd_soc_dapm_route intercon_tdm[] = {
 	{"TERT_TDM_RX_0 Audio Mixer", "MultiMedia34", "MM_DL34"},
 	{"TERT_TDM_RX_0", NULL, "TERT_TDM_RX_0 Audio Mixer"},
 
-	{"TERT_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"},
-	{"TERT_TDM_TX_0 Audio Mixer", "MultiMedia2", "MM_DL2"},
-	{"TERT_TDM_TX_0 Audio Mixer", "MultiMedia3", "MM_DL3"},
-	{"TERT_TDM_TX_0 Audio Mixer", "MultiMedia4", "MM_DL4"},
-	{"TERT_TDM_TX_0 Audio Mixer", "MultiMedia5", "MM_DL5"},
-	{"TERT_TDM_TX_0 Audio Mixer", "MultiMedia6", "MM_DL6"},
-	{"TERT_TDM_TX_0 Audio Mixer", "MultiMedia7", "MM_DL7"},
-	{"TERT_TDM_TX_0 Audio Mixer", "MultiMedia8", "MM_DL8"},
-	{"TERT_TDM_TX_0 Audio Mixer", "MultiMedia9", "MM_DL9"},
-	{"TERT_TDM_TX_0 Audio Mixer", "MultiMedia10", "MM_DL10"},
-	{"TERT_TDM_TX_0 Audio Mixer", "MultiMedia11", "MM_DL11"},
-	{"TERT_TDM_TX_0 Audio Mixer", "MultiMedia12", "MM_DL12"},
-	{"TERT_TDM_TX_0 Audio Mixer", "MultiMedia13", "MM_DL13"},
-	{"TERT_TDM_TX_0 Audio Mixer", "MultiMedia14", "MM_DL14"},
-	{"TERT_TDM_TX_0 Audio Mixer", "MultiMedia15", "MM_DL15"},
-	{"TERT_TDM_TX_0 Audio Mixer", "MultiMedia16", "MM_DL16"},
-	{"TERT_TDM_TX_0 Audio Mixer", "MultiMedia23", "MM_DL23"},
-	{"TERT_TDM_TX_0 Audio Mixer", "MultiMedia24", "MM_DL24"},
-	{"TERT_TDM_TX_0 Audio Mixer", "MultiMedia25", "MM_DL25"},
-	{"TERT_TDM_TX_0 Audio Mixer", "MultiMedia31", "MM_DL31"},
-	{"TERT_TDM_TX_0 Audio Mixer", "MultiMedia32", "MM_DL32"},
-	{"TERT_TDM_TX_0 Audio Mixer", "MultiMedia33", "MM_DL33"},
-	{"TERT_TDM_TX_0 Audio Mixer", "MultiMedia34", "MM_DL34"},
-	{"TERT_TDM_TX_0", NULL, "TERT_TDM_TX_0 Audio Mixer"},
-
 	{"TERT_TDM_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"},
 	{"TERT_TDM_RX_1 Audio Mixer", "MultiMedia2", "MM_DL2"},
 	{"TERT_TDM_RX_1 Audio Mixer", "MultiMedia3", "MM_DL3"},
@@ -28228,31 +28153,6 @@ static const struct snd_soc_dapm_route intercon_tdm[] = {
 	{"QUAT_TDM_RX_0 Audio Mixer", "MultiMedia34", "MM_DL34"},
 	{"QUAT_TDM_RX_0", NULL, "QUAT_TDM_RX_0 Audio Mixer"},
 
-	{"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"},
-	{"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia2", "MM_DL2"},
-	{"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia3", "MM_DL3"},
-	{"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia4", "MM_DL4"},
-	{"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia5", "MM_DL5"},
-	{"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia6", "MM_DL6"},
-	{"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia7", "MM_DL7"},
-	{"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia8", "MM_DL8"},
-	{"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia9", "MM_DL9"},
-	{"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia10", "MM_DL10"},
-	{"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia11", "MM_DL11"},
-	{"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia12", "MM_DL12"},
-	{"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia13", "MM_DL13"},
-	{"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia14", "MM_DL14"},
-	{"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia15", "MM_DL15"},
-	{"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia16", "MM_DL16"},
-	{"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia23", "MM_DL23"},
-	{"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia24", "MM_DL24"},
-	{"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia25", "MM_DL25"},
-	{"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia31", "MM_DL31"},
-	{"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia32", "MM_DL32"},
-	{"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia33", "MM_DL33"},
-	{"QUAT_TDM_TX_0 Audio Mixer", "MultiMedia34", "MM_DL34"},
-	{"QUAT_TDM_TX_0", NULL, "QUAT_TDM_TX_0 Audio Mixer"},
-
 	{"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"},
 	{"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia2", "MM_DL2"},
 	{"QUAT_TDM_RX_1 Audio Mixer", "MultiMedia3", "MM_DL3"},
@@ -28365,31 +28265,6 @@ static const struct snd_soc_dapm_route intercon_tdm[] = {
 	{"QUIN_TDM_RX_0 Audio Mixer", "MultiMedia34", "MM_DL34"},
 	{"QUIN_TDM_RX_0", NULL, "QUIN_TDM_RX_0 Audio Mixer"},
 
-	{"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"},
-	{"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia2", "MM_DL2"},
-	{"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia3", "MM_DL3"},
-	{"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia4", "MM_DL4"},
-	{"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia5", "MM_DL5"},
-	{"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia6", "MM_DL6"},
-	{"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia7", "MM_DL7"},
-	{"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia8", "MM_DL8"},
-	{"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia9", "MM_DL9"},
-	{"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia10", "MM_DL10"},
-	{"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia11", "MM_DL11"},
-	{"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia12", "MM_DL12"},
-	{"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia13", "MM_DL13"},
-	{"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia14", "MM_DL14"},
-	{"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia15", "MM_DL15"},
-	{"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia16", "MM_DL16"},
-	{"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia23", "MM_DL23"},
-	{"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia24", "MM_DL24"},
-	{"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia25", "MM_DL25"},
-	{"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia31", "MM_DL31"},
-	{"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia32", "MM_DL32"},
-	{"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia33", "MM_DL33"},
-	{"QUIN_TDM_TX_0 Audio Mixer", "MultiMedia34", "MM_DL34"},
-	{"QUIN_TDM_TX_0", NULL, "QUIN_TDM_TX_0 Audio Mixer"},
-
 	{"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"},
 	{"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia2", "MM_DL2"},
 	{"QUIN_TDM_RX_1 Audio Mixer", "MultiMedia3", "MM_DL3"},
@@ -28494,24 +28369,6 @@ static const struct snd_soc_dapm_route intercon_tdm[] = {
 	{"SEN_TDM_RX_0 Audio Mixer", "MultiMedia21", "MM_DL21"},
 	{"SEN_TDM_RX_0", NULL, "SEN_TDM_RX_0 Audio Mixer"},
 
-	{"SEN_TDM_TX_0 Audio Mixer", "MultiMedia1", "MM_DL1"},
-	{"SEN_TDM_TX_0 Audio Mixer", "MultiMedia2", "MM_DL2"},
-	{"SEN_TDM_TX_0 Audio Mixer", "MultiMedia3", "MM_DL3"},
-	{"SEN_TDM_TX_0 Audio Mixer", "MultiMedia4", "MM_DL4"},
-	{"SEN_TDM_TX_0 Audio Mixer", "MultiMedia5", "MM_DL5"},
-	{"SEN_TDM_TX_0 Audio Mixer", "MultiMedia6", "MM_DL6"},
-	{"SEN_TDM_TX_0 Audio Mixer", "MultiMedia7", "MM_DL7"},
-	{"SEN_TDM_TX_0 Audio Mixer", "MultiMedia8", "MM_DL8"},
-	{"SEN_TDM_TX_0 Audio Mixer", "MultiMedia9", "MM_DL9"},
-	{"SEN_TDM_TX_0 Audio Mixer", "MultiMedia10", "MM_DL10"},
-	{"SEN_TDM_TX_0 Audio Mixer", "MultiMedia11", "MM_DL11"},
-	{"SEN_TDM_TX_0 Audio Mixer", "MultiMedia12", "MM_DL12"},
-	{"SEN_TDM_TX_0 Audio Mixer", "MultiMedia13", "MM_DL13"},
-	{"SEN_TDM_TX_0 Audio Mixer", "MultiMedia14", "MM_DL14"},
-	{"SEN_TDM_TX_0 Audio Mixer", "MultiMedia15", "MM_DL15"},
-	{"SEN_TDM_TX_0 Audio Mixer", "MultiMedia16", "MM_DL16"},
-	{"SEN_TDM_TX_0", NULL, "SEN_TDM_TX_0 Audio Mixer"},
-
 	{"SEN_TDM_RX_1 Audio Mixer", "MultiMedia1", "MM_DL1"},
 	{"SEN_TDM_RX_1 Audio Mixer", "MultiMedia2", "MM_DL2"},
 	{"SEN_TDM_RX_1 Audio Mixer", "MultiMedia3", "MM_DL3"},

+ 2 - 3
asoc/sa6155.c

@@ -257,7 +257,7 @@ static struct dev_config tdm_tx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = {
 		{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */
 	},
 	{ /* QUAT TDM */
-		{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 16}, /* TX_0 */
+		{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 8}, /* 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 */
@@ -460,8 +460,7 @@ static unsigned int tdm_tx_slot_offset
 		{28, 0xFFFF},
 	},
 	{/* QUAT TDM */
-		{0, 4, 8, 12, 16, 20, 24, 28,
-			32, 36, 40, 44, 48, 52, 56, 60, 0xFFFF},/*MIC ARR*/
+		{0, 8, 16, 24, 4, 12, 20, 28, 0xFFFF}, /*8 CH MIC ARR*/
 		{0xFFFF}, /* not used */
 		{0xFFFF}, /* not used */
 		{0xFFFF}, /* not used */

+ 6 - 8
asoc/sa8155.c

@@ -259,7 +259,7 @@ static struct dev_config tdm_tx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = {
 		{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */
 	},
 	{ /* QUAT TDM */
-		{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 16}, /* TX_0 */
+		{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 8}, /* 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 */
@@ -269,7 +269,7 @@ 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, 16}, /* TX_0 */
+		{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 8}, /* 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 */
@@ -418,8 +418,8 @@ static unsigned int tdm_rx_slot_offset
 		{60,0xFFFF},
 	},
 	{/* QUIN TDM */
-		{0, 8, 16, 24, 32, 40, 48, 56,
-			4, 12, 20, 28, 36, 44, 52, 60, 0xFFFF}, /*16 CH SPKR*/
+		{0, 4, 8, 12, 16, 20, 24, 28,
+			32, 36, 40, 44, 48, 52, 56, 60, 0xFFFF}, /*16 CH SPKR*/
 		{0xFFFF}, /* not used */
 		{0xFFFF}, /* not used */
 		{0xFFFF}, /* not used */
@@ -463,8 +463,7 @@ static unsigned int tdm_tx_slot_offset
 		{28, 0xFFFF},
 	},
 	{/* QUAT TDM */
-		{0, 4, 8, 12, 16, 20, 24, 28,
-			32, 36, 40, 44, 48, 52, 56, 60, 0xFFFF},/*16 CH MIC ARR1*/
+		{0, 8, 16, 24, 4, 12, 20, 28, 0xFFFF}, /*8 CH MIC ARR1*/
 		{0xFFFF}, /* not used */
 		{0xFFFF}, /* not used */
 		{0xFFFF}, /* not used */
@@ -474,8 +473,7 @@ static unsigned int tdm_tx_slot_offset
 		{60,0xFFFF},
 	},
 	{/* QUIN TDM */
-		{0, 4, 8, 12, 16, 20, 24, 28,
-			32, 36, 40, 44, 48, 52, 56, 60, 0xFFFF},/*16 CH MIC ARR2*/
+		{0, 4, 8, 12, 16, 20, 24, 28, 0xFFFF}, /*8 CH MIC ARR2*/
 		{0xFFFF}, /* not used */
 		{0xFFFF}, /* not used */
 		{0xFFFF}, /* not used */

+ 170 - 32
dsp/q6afe.c

@@ -17,6 +17,7 @@
 #include <dsp/q6audio-v2.h>
 #include <dsp/q6common.h>
 #include <dsp/q6core.h>
+#include <linux/ratelimit.h>
 #include <dsp/msm-audio-event-notify.h>
 #include <ipc/apr_tal.h>
 #include "adsp_err.h"
@@ -400,6 +401,10 @@ static int q6afe_load_avcs_modules(int num_modules, u16 port_id,
 						AMDB_MODULE_TYPE_PACKETIZER;
 				pm[i]->payload->load_unload_info[0].id1 =
 						AVS_MODULE_ID_PACKETIZER_COP;
+				if (format_id == ASM_MEDIA_FMT_LC3)
+					pm[i]->payload->load_unload_info[0].id1 =
+					AVS_MODULE_ID_PACKETIZER_COP_V2;
+
 				pm[i]->payload->load_unload_info[1].module_type =
 						AMDB_MODULE_TYPE_ENCODER;
 				pm[i]->payload->load_unload_info[1].id1 =
@@ -415,6 +420,11 @@ static int q6afe_load_avcs_modules(int num_modules, u16 port_id,
 						AVS_MODULE_ID_DEPACKETIZER_COP;
 					goto load_unload;
 				}
+				if (format_id == ASM_MEDIA_FMT_LC3) {
+					pm[i]->payload->load_unload_info[0].id1 =
+					AVS_MODULE_ID_DEPACKETIZER_COP_V2;
+					goto load_unload;
+				}
 
 				pm[i]->payload->load_unload_info[1].module_type =
 						AMDB_MODULE_TYPE_DECODER;
@@ -4897,6 +4907,7 @@ static int q6afe_send_dec_config(u16 port_id,
 	struct afe_matched_port_t matched_port_param;
 	struct asm_aptx_ad_speech_mode_cfg_t speech_codec_init_param;
 	struct param_hdr_v3 param_hdr;
+	struct avs_cop_v2_param_id_stream_info_t lc3_enc_stream_info;
 	int ret;
 	u32 dec_fmt;
 
@@ -4906,6 +4917,7 @@ static int q6afe_send_dec_config(u16 port_id,
 	memset(&media_type, 0, sizeof(media_type));
 	memset(&matched_port_param, 0, sizeof(matched_port_param));
 	memset(&speech_codec_init_param, 0, sizeof(speech_codec_init_param));
+	memset(&lc3_enc_stream_info, 0, sizeof(lc3_enc_stream_info));
 	memset(&param_hdr, 0, sizeof(param_hdr));
 
 	param_hdr.module_id = AFE_MODULE_ID_DECODER;
@@ -4920,6 +4932,12 @@ static int q6afe_send_dec_config(u16 port_id,
 	if (cfg->format == ENC_CODEC_TYPE_LDAC)
 		dec_depkt_id_param.dec_depacketizer_id =
 					       AFE_MODULE_ID_DEPACKETIZER_COP;
+	if (format == ASM_MEDIA_FMT_LC3) {
+		pr_debug("%s: sending AFE_MODULE_ID_DEPACKETIZER_COP_V2 to DSP payload\n",
+			  __func__);
+		dec_depkt_id_param.dec_depacketizer_id =
+				AFE_MODULE_ID_DEPACKETIZER_COP_V2;
+	}
 	ret = q6afe_pack_and_set_param_in_band(port_id,
 					       q6audio_get_port_index(port_id),
 					       param_hdr,
@@ -5027,6 +5045,9 @@ static int q6afe_send_dec_config(u16 port_id,
 	case ASM_MEDIA_FMT_APTX_AD_SPEECH:
 		media_type.sample_rate = AFE_PORT_SAMPLE_RATE_32K;
 		break;
+	case ASM_MEDIA_FMT_LC3:
+		media_type.sample_rate = AFE_PORT_SAMPLE_RATE_48K;
+		break;
 	default:
 		media_type.sample_rate =
 			afe_config.slim_sch.sample_rate;
@@ -5054,18 +5075,15 @@ static int q6afe_send_dec_config(u16 port_id,
 
 	if (format != ASM_MEDIA_FMT_SBC && format != ASM_MEDIA_FMT_AAC_V2 &&
 		format != ASM_MEDIA_FMT_APTX_ADAPTIVE &&
-		format != ASM_MEDIA_FMT_APTX_AD_SPEECH) {
+		format != ASM_MEDIA_FMT_APTX_AD_SPEECH &&
+		format != ASM_MEDIA_FMT_LC3) {
 		pr_debug("%s:Unsuppported dec format. Ignore AFE config %u\n",
 				__func__, format);
 		goto exit;
 	}
 
-	if (format == ASM_MEDIA_FMT_APTX_ADAPTIVE &&
-		cfg->abr_dec_cfg.is_abr_enabled) {
-		pr_debug("%s: Ignore AFE config for abr case\n", __func__);
-		goto exit;
-	}
-	if (format == ASM_MEDIA_FMT_APTX_AD_SPEECH) {
+	if (format == ASM_MEDIA_FMT_APTX_AD_SPEECH ||
+		format == ASM_MEDIA_FMT_LC3) {
 		pr_debug("%s: sending AFE_PARAM_ID_RATE_MATCHED_PORT to DSP payload\n",
 			__func__);
 		param_hdr.param_id = AFE_PARAM_ID_RATE_MATCHED_PORT;
@@ -5084,6 +5102,32 @@ static int q6afe_send_dec_config(u16 port_id,
 		}
 	}
 
+	if (format == ASM_MEDIA_FMT_LC3) {
+		pr_debug("%s: sending AVS_COP_V2_PARAM_ID_STREAM_INFO to DSP\n",
+			 __func__);
+		param_hdr.module_id = AFE_MODULE_ID_DECODER;
+		param_hdr.instance_id = INSTANCE_ID_0;
+		param_hdr.param_id = AVS_COP_V2_PARAM_ID_STREAM_INFO;
+		param_hdr.param_size =
+			sizeof(struct avs_cop_v2_param_id_stream_info_t);
+		lc3_enc_stream_info = cfg->data.lc3_dec_config.dec_codec.streamMapToAir;
+		ret = q6afe_pack_and_set_param_in_band(port_id,
+				q6audio_get_port_index(port_id),
+							param_hdr,
+					(u8 *) &lc3_enc_stream_info);
+		if (ret) {
+			pr_err("%s: AVS_COP_V2_PARAM_ID_STREAM_INFO for port 0x%x failed %d\n",
+			__func__, port_id, ret);
+			goto exit;
+		}
+	}
+
+	if ((format == ASM_MEDIA_FMT_APTX_ADAPTIVE || format == ASM_MEDIA_FMT_LC3) &&
+		cfg->abr_dec_cfg.is_abr_enabled) {
+		pr_debug("%s: Ignore AFE config for abr case\n", __func__);
+		goto exit;
+	}
+
 	pr_debug("%s: sending AFE_DECODER_PARAM_ID_DEC_MEDIA_FMT to DSP payload\n",
 		  __func__);
 	param_hdr.module_id = AFE_MODULE_ID_DECODER;
@@ -5167,6 +5211,8 @@ static int q6afe_send_enc_config(u16 port_id,
 	struct aptx_channel_mode_param_t channel_mode_param;
 	struct afe_matched_port_t matched_port_param;
 	struct asm_aptx_ad_speech_mode_cfg_t speech_codec_init_param;
+	struct avs_cop_v2_param_id_stream_info_t lc3_enc_stream_info;
+	struct afe_lc3_enc_cfg_t lc3_enc_config_init;
 	struct param_hdr_v3 param_hdr;
 	int ret;
 	uint32_t frame_size_ctl_value_v2;
@@ -5184,13 +5230,16 @@ static int q6afe_send_enc_config(u16 port_id,
 	memset(&media_type, 0, sizeof(media_type));
 	memset(&matched_port_param, 0, sizeof(matched_port_param));
 	memset(&speech_codec_init_param, 0, sizeof(speech_codec_init_param));
+	memset(&lc3_enc_stream_info, 0, sizeof(lc3_enc_stream_info));
+	memset(&lc3_enc_config_init, 0, sizeof(lc3_enc_config_init));
 	memset(&param_hdr, 0, sizeof(param_hdr));
 
 	if (format != ASM_MEDIA_FMT_SBC && format != ASM_MEDIA_FMT_AAC_V2 &&
 		format != ASM_MEDIA_FMT_APTX && format != ASM_MEDIA_FMT_APTX_HD &&
 		format != ASM_MEDIA_FMT_CELT && format != ASM_MEDIA_FMT_LDAC &&
 		format != ASM_MEDIA_FMT_APTX_ADAPTIVE &&
-		format != ASM_MEDIA_FMT_APTX_AD_SPEECH) {
+		format != ASM_MEDIA_FMT_APTX_AD_SPEECH &&
+		format != ASM_MEDIA_FMT_LC3) {
 		pr_err("%s:Unsuppported enc format. Ignore AFE config\n",
 				__func__);
 		return 0;
@@ -5228,23 +5277,26 @@ static int q6afe_send_enc_config(u16 port_id,
 	} else if (format == ASM_MEDIA_FMT_APTX_AD_SPEECH) {
 		param_hdr.param_size = sizeof(struct afe_enc_aptx_ad_speech_cfg_blk_param_t);
 		enc_blk_param.enc_cfg_blk_size = sizeof(struct asm_custom_enc_cfg_t);
-	} else {
+	} else if (format != ASM_MEDIA_FMT_LC3) {
 		param_hdr.param_size = sizeof(struct afe_enc_cfg_blk_param_t);
 		enc_blk_param.enc_cfg_blk_size =
 			sizeof(union afe_enc_config_data);
 	}
-	pr_debug("%s:send AFE_ENCODER_PARAM_ID_ENC_CFG_BLK to DSP payload\n",
-		 __func__);
-	param_hdr.param_id = AFE_ENCODER_PARAM_ID_ENC_CFG_BLK;
-	enc_blk_param.enc_blk_config = *cfg;
-	ret = q6afe_pack_and_set_param_in_band(port_id,
-					       q6audio_get_port_index(port_id),
-					       param_hdr,
-					       (u8 *) &enc_blk_param);
-	if (ret) {
-		pr_err("%s: AFE_ENCODER_PARAM_ID_ENC_CFG_BLK for port 0x%x failed %d\n",
-			__func__, port_id, ret);
-		goto exit;
+
+	if (format != ASM_MEDIA_FMT_LC3) {
+		pr_debug("%s:send AFE_ENCODER_PARAM_ID_ENC_CFG_BLK to DSP payload\n",
+			 __func__);
+		param_hdr.param_id = AFE_ENCODER_PARAM_ID_ENC_CFG_BLK;
+		enc_blk_param.enc_blk_config = *cfg;
+		ret = q6afe_pack_and_set_param_in_band(port_id,
+				q6audio_get_port_index(port_id),
+							param_hdr,
+						(u8 *) &enc_blk_param);
+		if (ret) {
+			pr_err("%s: AFE_ENCODER_PARAM_ID_ENC_CFG_BLK for port 0x%x failed %d\n",
+				__func__, port_id, ret);
+			goto exit;
+		}
 	}
 
 	if (format == ASM_MEDIA_FMT_AAC_V2) {
@@ -5352,21 +5404,59 @@ static int q6afe_send_enc_config(u16 port_id,
 	}
 
 	pr_debug("%s:sending AFE_ENCODER_PARAM_ID_PACKETIZER to DSP\n",
-		 __func__);
+		__func__);
 	param_hdr.param_id = AFE_ENCODER_PARAM_ID_PACKETIZER_ID;
 	param_hdr.param_size = sizeof(struct avs_enc_packetizer_id_param_t);
 	enc_pkt_id_param.enc_packetizer_id = AFE_MODULE_ID_PACKETIZER_COP;
+	if (format == ASM_MEDIA_FMT_LC3)
+		enc_pkt_id_param.enc_packetizer_id = AFE_MODULE_ID_PACKETIZER_COP_V2;
 	ret = q6afe_pack_and_set_param_in_band(port_id,
-					       q6audio_get_port_index(port_id),
-					       param_hdr,
-					       (u8 *) &enc_pkt_id_param);
+				q6audio_get_port_index(port_id),
+						param_hdr,
+					(u8 *) &enc_pkt_id_param);
 	if (ret) {
 		pr_err("%s: AFE_ENCODER_PARAM_ID_PACKETIZER for port 0x%x failed %d\n",
-			__func__, port_id, ret);
+		__func__, port_id, ret);
 		goto exit;
 	}
 
-	if (format != ASM_MEDIA_FMT_APTX_AD_SPEECH) {
+	if (format == ASM_MEDIA_FMT_LC3) {
+		pr_debug("%s: sending CAPI_V2_PARAM_LC3_ENC_INIT to DSP\n",
+			__func__);
+		param_hdr.param_id = CAPI_V2_PARAM_LC3_ENC_INIT;
+		param_hdr.param_size =
+			sizeof(struct afe_lc3_enc_cfg_t);
+		lc3_enc_config_init = cfg->lc3_enc_config.enc_codec.to_Air_cfg;
+		ret = q6afe_pack_and_set_param_in_band(port_id,
+					q6audio_get_port_index(port_id),
+					param_hdr,
+					(u8 *) &lc3_enc_config_init);
+		if (ret) {
+			pr_err("%s: CAPI_V2_PARAM_LC3_ENC_INIT for port 0x%x failed %d\n",
+				__func__, port_id, ret);
+			goto exit;
+		}
+
+		pr_debug("%s: sending AVS_COP_V2_PARAM_ID_STREAM_INFO to DSP\n",
+			__func__);
+		param_hdr.param_id = AVS_COP_V2_PARAM_ID_STREAM_INFO;
+		param_hdr.param_size =
+			sizeof(struct avs_cop_v2_param_id_stream_info_t);
+		lc3_enc_stream_info = cfg->lc3_enc_config.enc_codec.streamMapToAir;
+
+		ret = q6afe_pack_and_set_param_in_band(port_id,
+					q6audio_get_port_index(port_id),
+					param_hdr,
+					(u8 *) &lc3_enc_stream_info);
+		if (ret) {
+			pr_err("%s: AVS_COP_V2_PARAM_ID_STREAM_INFO for port 0x%x failed %d\n",
+				__func__, port_id, ret);
+			goto exit;
+		}
+	}
+
+	if (format != ASM_MEDIA_FMT_APTX_AD_SPEECH &&
+		format != ASM_MEDIA_FMT_LC3) {
 		pr_debug("%s:sending AFE_ENCODER_PARAM_ID_ENABLE_SCRAMBLING mode= %d to DSP payload\n",
 			  __func__, scrambler_mode);
 		param_hdr.param_id = AFE_ENCODER_PARAM_ID_ENABLE_SCRAMBLING;
@@ -5403,8 +5493,10 @@ static int q6afe_send_enc_config(u16 port_id,
 	if ((format == ASM_MEDIA_FMT_LDAC &&
 	     cfg->ldac_config.abr_config.is_abr_enabled) ||
 	     format == ASM_MEDIA_FMT_APTX_ADAPTIVE ||
-	     format == ASM_MEDIA_FMT_APTX_AD_SPEECH) {
-		if (format != ASM_MEDIA_FMT_APTX_AD_SPEECH) {
+	     format == ASM_MEDIA_FMT_APTX_AD_SPEECH ||
+		 format == ASM_MEDIA_FMT_LC3) {
+		if (format != ASM_MEDIA_FMT_APTX_AD_SPEECH &&
+			format != ASM_MEDIA_FMT_LC3) {
 			pr_debug("%s:sending AFE_ENCODER_PARAM_ID_BIT_RATE_LEVEL_MAP to DSP payload",
 				__func__);
 			param_hdr.param_id = AFE_ENCODER_PARAM_ID_BIT_RATE_LEVEL_MAP;
@@ -5435,6 +5527,9 @@ static int q6afe_send_enc_config(u16 port_id,
 		else if (format == ASM_MEDIA_FMT_APTX_AD_SPEECH)
 			imc_info_param.imc_info =
 			cfg->aptx_ad_speech_config.imc_info;
+		else if (format == ASM_MEDIA_FMT_LC3)
+			imc_info_param.imc_info =
+			cfg->lc3_enc_config.imc_info;
 		else
 			imc_info_param.imc_info =
 			cfg->ldac_config.abr_config.imc_info;
@@ -5463,6 +5558,9 @@ static int q6afe_send_enc_config(u16 port_id,
 	else if (format == ASM_MEDIA_FMT_APTX_AD_SPEECH)
 		media_type.sample_rate =
 			cfg->aptx_ad_speech_config.custom_cfg.sample_rate;
+	else if (format == ASM_MEDIA_FMT_LC3)
+		media_type.sample_rate =
+		cfg->lc3_enc_config.enc_codec.to_Air_cfg.toAirConfig.sampling_freq;
 	else
 		media_type.sample_rate =
 			afe_config.slim_sch.sample_rate;
@@ -5488,7 +5586,8 @@ static int q6afe_send_enc_config(u16 port_id,
 		goto exit;
 	}
 
-	if (format == ASM_MEDIA_FMT_APTX_AD_SPEECH) {
+	if (format == ASM_MEDIA_FMT_APTX_AD_SPEECH ||
+		format == ASM_MEDIA_FMT_LC3) {
 		pr_debug("%s: sending AFE_PARAM_ID_RATE_MATCHED_PORT to DSP payload",
 			__func__);
 		param_hdr.param_id = AFE_PARAM_ID_RATE_MATCHED_PORT;
@@ -5549,6 +5648,42 @@ int afe_set_tws_channel_mode(u32 format, u16 port_id, u32 channel_mode)
 }
 EXPORT_SYMBOL(afe_set_tws_channel_mode);
 
+int afe_set_lc3_channel_mode(u32 format, u16 port_id, u32 channel_mode)
+{
+	struct lc3_channel_mode_param_t channel_mode_param;
+	struct param_hdr_v3 param_info;
+	int ret = 0;
+	u32 param_id = 0;
+
+	if (format == ASM_MEDIA_FMT_LC3) {
+		param_id = CAPI_V2_PARAM_SET_LC3_ENC_DOWNMIX_2_MONO;
+	} else {
+		pr_err("%s: Not supported format 0x%x\n", __func__, format);
+		return -EINVAL;
+	}
+
+	memset(&param_info, 0, sizeof(param_info));
+	memset(&channel_mode_param, 0, sizeof(channel_mode_param));
+
+	param_info.module_id = AFE_MODULE_ID_ENCODER;
+	param_info.instance_id = INSTANCE_ID_0;
+	param_info.param_id = param_id;
+	param_info.param_size = sizeof(channel_mode_param);
+
+	channel_mode_param.channel_mode = channel_mode;
+
+	ret = q6afe_pack_and_set_param_in_band(port_id,
+			q6audio_get_port_index(port_id),
+						param_info,
+				(u8 *) &channel_mode_param);
+	if (ret)
+		pr_err("%s: AFE set channel mode cfg for port 0x%x failed %d\n",
+			 __func__, port_id, ret);
+
+	return ret;
+}
+EXPORT_SYMBOL(afe_set_lc3_channel_mode);
+
 static int __afe_port_start(u16 port_id, union afe_port_config *afe_config,
 			    u32 rate, u16 afe_in_channels, u16 afe_in_bit_width,
 			    union afe_enc_config_data *enc_cfg,
@@ -5913,7 +6048,8 @@ static int __afe_port_start(u16 port_id, union afe_port_config *afe_config,
 				 * Only loading de-packetizer module.
 				 */
 				if (codec_format == ENC_CODEC_TYPE_LDAC ||
-					codec_format == ASM_MEDIA_FMT_APTX_ADAPTIVE)
+					codec_format == ASM_MEDIA_FMT_APTX_ADAPTIVE ||
+					codec_format == ASM_MEDIA_FMT_LC3)
 					ret = q6afe_load_avcs_modules(1, port_id,
 						DECODER_CASE, codec_format);
 				else
@@ -9222,6 +9358,7 @@ int afe_set_lpass_clk_cfg(int index, struct afe_clk_set *cfg)
 {
 	struct param_hdr_v3 param_hdr;
 	int ret = 0;
+	static DEFINE_RATELIMIT_STATE(rtl, 1 * HZ, 1);
 
 	if (!cfg) {
 		pr_err("%s: clock cfg is NULL\n", __func__);
@@ -9260,7 +9397,8 @@ int afe_set_lpass_clk_cfg(int index, struct afe_clk_set *cfg)
 	ret = q6afe_svc_pack_and_set_param_in_band(index, param_hdr,
 						   (u8 *) cfg);
 	if (ret < 0) {
-		pr_err_ratelimited("%s: AFE clk cfg failed with ret %d\n",
+		if (__ratelimit(&rtl))
+			pr_err_ratelimited("%s: AFE clk cfg failed with ret %d\n",
 				__func__, ret);
 		trace_printk("%s: AFE clk cfg failed with ret %d\n",
 		       __func__, ret);

+ 20 - 19
dsp/q6voice.c

@@ -3423,14 +3423,13 @@ static int voice_send_cvp_deregister_cal_cmd(struct voice_data *v)
 		goto done;
 	}
 
-	mutex_lock(&common.cal_data[cal_index]->lock);
 	cal_block = cal_utils_get_only_cal_block(
 			common.cal_data[cal_index]);
 	if (cal_block == NULL) {
 		pr_err("%s: Cal block is NULL, index %d!\n",
 			__func__, cal_index);
 		ret = -EINVAL;
-		goto unlock;
+		goto done;
 	}
 	pr_debug("%s: use hyp assigned %d\n",__func__, hyp_assigned);
 	if (cal_block->cma_mem && hyp_assigned) {
@@ -3438,7 +3437,7 @@ static int voice_send_cvp_deregister_cal_cmd(struct voice_data *v)
 		    cal_block->map_data.map_size <= 0) {
 			pr_err("%s: No address to map!\n", __func__);
 			ret = -EINVAL;
-			goto unlock;
+			goto done;
 		}
 		ret = hyp_assign_phys(cal_block->cal_data.paddr,
 				      cal_block->map_data.map_size,
@@ -3448,7 +3447,7 @@ static int voice_send_cvp_deregister_cal_cmd(struct voice_data *v)
 				__func__, ret, cal_block->cal_data.paddr,
 				cal_block->map_data.map_size);
 			ret = -EINVAL;
-			goto unlock;
+			goto done;
 		} else {
 			hyp_assigned = false;
 			pr_debug("%s: hyp_assign_phys success\n", __func__);
@@ -3461,11 +3460,9 @@ static int voice_send_cvp_deregister_cal_cmd(struct voice_data *v)
 				v->async_err));
 		ret = adsp_err_get_lnx_err_code(
 				v->async_err);
-		goto unlock;
+		goto done;
 	}
 
-unlock:
-	mutex_unlock(&common.cal_data[cal_index]->lock);
 done:
 	return ret;
 }
@@ -3948,20 +3945,20 @@ static int voice_unmap_cal_memory(int32_t cal_type,
 					__func__, v->session_id, result2);
 
 				result = result2;
+			} else {
+				if (cal_type == CVP_VOCPROC_DYNAMIC_CAL_TYPE)
+					voice_send_cvp_deregister_vol_cal_cmd(v);
+				else if (cal_type == CVP_VOCPROC_STATIC_CAL_TYPE)
+					voice_send_cvp_deregister_cal_cmd(v);
+				else if (cal_type == CVP_VOCDEV_CFG_CAL_TYPE)
+					voice_send_cvp_deregister_dev_cfg_cmd(v);
+				else if (cal_type == CVS_VOCSTRM_STATIC_CAL_TYPE)
+					voice_send_cvs_deregister_cal_cmd(v);
+				else
+					pr_err("%s: Invalid cal type %d!\n",
+						__func__, cal_type);
 			}
 
-			if (cal_type == CVP_VOCPROC_DYNAMIC_CAL_TYPE)
-				voice_send_cvp_deregister_vol_cal_cmd(v);
-			else if (cal_type == CVP_VOCPROC_STATIC_CAL_TYPE)
-				voice_send_cvp_deregister_cal_cmd(v);
-			else if (cal_type == CVP_VOCDEV_CFG_CAL_TYPE)
-				voice_send_cvp_deregister_dev_cfg_cmd(v);
-			else if (cal_type == CVS_VOCSTRM_STATIC_CAL_TYPE)
-				voice_send_cvs_deregister_cal_cmd(v);
-			else
-				pr_err("%s: Invalid cal type %d!\n",
-					__func__, cal_type);
-
 			result2 = voice_send_start_voice_cmd(v);
 			if (result2) {
 				pr_err("%s: Voice_send_start_voice_cmd failed for session 0x%x, err %d!\n",
@@ -5383,7 +5380,9 @@ static int voice_destroy_vocproc(struct voice_data *v)
 	}
 
 	voice_send_cvp_deregister_vol_cal_cmd(v);
+	mutex_lock(&common.cal_data[CVP_VOCPROC_CAL]->lock);
 	voice_send_cvp_deregister_cal_cmd(v);
+	mutex_unlock(&common.cal_data[CVP_VOCPROC_CAL]->lock);
 	voice_send_cvp_deregister_dev_cfg_cmd(v);
 	voice_send_cvs_deregister_cal_cmd(v);
 
@@ -7233,7 +7232,9 @@ int voc_disable_device(uint32_t session_id)
 		}
 		rtac_remove_voice(voice_get_cvs_handle(v));
 		voice_send_cvp_deregister_vol_cal_cmd(v);
+		mutex_lock(&common.cal_data[CVP_VOCPROC_CAL]->lock);
 		voice_send_cvp_deregister_cal_cmd(v);
+		mutex_unlock(&common.cal_data[CVP_VOCPROC_CAL]->lock);
 		voice_send_cvp_deregister_dev_cfg_cmd(v);
 
 		/* Unload topology modules */

+ 93 - 0
include/dsp/apr_audio-v2.h

@@ -4103,6 +4103,9 @@ struct afe_id_aptx_adaptive_enc_init
 /* Macro for defining the packetizer ID: COP. */
 #define AFE_MODULE_ID_PACKETIZER_COP 0x0001322A
 
+/* Macro for defining the packetizer ID: COP V2 */
+#define AFE_MODULE_ID_PACKETIZER_COP_V2     0x000132F9
+
 /*
  * Packetizer type parameter for the #AVS_MODULE_ID_ENCODER module.
  * This parameter cannot be set runtime.
@@ -4168,6 +4171,7 @@ struct afe_id_aptx_adaptive_enc_init
  */
 #define AFE_MODULE_ID_DEPACKETIZER_COP        0x00013233
 #define AFE_MODULE_ID_DEPACKETIZER_COP_V1     0x000132E9
+#define AFE_MODULE_ID_DEPACKETIZER_COP_V2     0x000132FC
 
 /* Macros for dynamic loading of modules by AVCS */
 
@@ -4175,10 +4179,22 @@ struct afe_id_aptx_adaptive_enc_init
 
 #define AVS_MODULE_ID_PACKETIZER_COP_V1     0x000132E8
 
+#define AVS_MODULE_ID_PACKETIZER_COP_V2     0x000132F9
+
 #define AVS_MODULE_ID_DEPACKETIZER_COP      0x00013233
 
 #define AVS_MODULE_ID_DEPACKETIZER_COP_V1   0x000132E9
 
+#define AVS_MODULE_ID_DEPACKETIZER_COP_V2   0x000132FC
+
+/*
+ * Depacketizer and packetizer type parameter for the
+ * #AVS_MODULE_ID_DEPACKETIZER_COP_V2 module and
+ * #AVS_MODULE_ID_PACKETIZER_COP_V2 module.
+ */
+
+#define AVS_COP_V2_PARAM_ID_STREAM_INFO     0x000132FD
+
 /*
  * Depacketizer type parameter for the #AVS_MODULE_ID_DECODER module.
  * This parameter cannot be set runtime.
@@ -4192,6 +4208,12 @@ struct afe_id_aptx_adaptive_enc_init
 struct aptx_channel_mode_param_t {
 	u32 channel_mode;
 } __packed;
+
+#define CAPI_V2_PARAM_SET_LC3_ENC_DOWNMIX_2_MONO    0x00013384
+struct lc3_channel_mode_param_t {
+	u32 channel_mode;
+} __packed;
+
 /*
  * Decoder buffer ID parameter for the #AVS_MODULE_ID_DECODER module.
  * This parameter cannot be set runtime.
@@ -4410,6 +4432,10 @@ struct asm_aac_enc_cfg_t {
 /* FMT ID for apt-X Adaptive speech */
 #define ASM_MEDIA_FMT_APTX_AD_SPEECH 0x00013208
 
+/* FMT ID for lc3 codec */
+#define ASM_MEDIA_FMT_LC3 0x0001337E
+#define ENC_CODEC_TYPE_LC3 0x2B000000
+
 #define PCM_CHANNEL_L         1
 #define PCM_CHANNEL_R         2
 #define PCM_CHANNEL_C         3
@@ -4470,6 +4496,70 @@ struct asm_aptx_ad_speech_enc_cfg_t
 	struct asm_aptx_ad_speech_mode_cfg_t speech_mode;
 } __attribute__ ((packed));
 
+
+#define CAPI_V2_PARAM_LC3_ENC_INIT 0x00013381
+#define CAPI_V2_PARAM_LC3_DEC_MODULE_INIT 0x00013391
+struct afe_lc3_stream_map_t {
+	uint32_t stream_id;
+	uint32_t direction;
+	uint32_t channel_mask_lsw;
+	uint32_t channel_mask_msw;
+} __packed;
+
+struct afe_stream_map_t {
+	uint32_t audio_location;
+	uint8_t stream_id;
+	uint8_t direction;
+} __packed;
+
+struct afe_lc3_cfg_t {
+	uint32_t api_version;
+	uint32_t sampling_freq;
+	uint32_t max_octets_per_frame;
+	uint32_t frame_duration;
+	uint32_t bit_depth;
+	uint32_t num_blocks;
+	uint8_t  default_q_level;
+	uint8_t  vendor_specific[16];
+	uint32_t mode;
+} __packed;
+
+struct afe_lc3_enc_cfg_t {
+	struct afe_lc3_cfg_t toAirConfig;
+	uint32_t stream_map_size;
+	struct afe_stream_map_t streamMapOut[16];
+} __packed;
+
+struct afe_lc3_dec_cfg_t {
+	struct afe_lc3_cfg_t FromAir;
+	uint32_t decoder_output_channel;
+	uint32_t stream_map_size;
+	struct afe_stream_map_t streamMapIn[16];
+} __packed;
+
+struct avs_cop_v2_param_id_stream_info_t {
+	uint32_t stream_map_size;
+	struct afe_lc3_stream_map_t streamMap[16];
+} __packed;
+
+struct afe_lc3_dec_config_t {
+	struct avs_cop_v2_param_id_stream_info_t streamMapToAir;
+} __packed;
+
+struct afe_lc3_enc_config_t {
+	struct afe_lc3_enc_cfg_t to_Air_cfg;
+	struct avs_cop_v2_param_id_stream_info_t streamMapToAir;
+} __packed;
+
+struct asm_enc_lc3_cfg_t {
+	struct afe_imc_dec_enc_info imc_info;
+	struct afe_lc3_enc_config_t enc_codec;
+} __packed;
+
+struct asm_lc3_dec_cfg_t {
+	struct afe_lc3_dec_config_t dec_codec;
+} __packed;
+
 struct afe_matched_port_t
 {
 	uint32_t  minor_version;
@@ -4765,12 +4855,14 @@ union afe_enc_config_data {
 	struct asm_ldac_enc_cfg_t  ldac_config;
 	struct asm_aptx_ad_enc_cfg_t  aptx_ad_config;
 	struct asm_aptx_ad_speech_enc_cfg_t aptx_ad_speech_config;
+	struct asm_enc_lc3_cfg_t lc3_enc_config;
 };
 
 struct afe_enc_config {
 	u32 format;
 	u32 scrambler_mode;
 	u32 mono_mode;
+	u32 lc3_mono_mode;
 	union afe_enc_config_data data;
 };
 
@@ -4830,6 +4922,7 @@ union afe_dec_config_data {
 	struct asm_mp3_dec_cfg_t mp3_config;
 	struct asm_aptx_ad_dec_cfg_t aptx_ad_config;
 	struct asm_aptx_ad_speech_dec_cfg_t aptx_ad_speech_config;
+	struct asm_lc3_dec_cfg_t lc3_dec_config;
 };
 
 struct afe_dec_config {

+ 7 - 0
include/dsp/q6afe-v2.h

@@ -54,6 +54,12 @@
 #define AFE_API_VERSION_V8		8
 
 
+/* the different modes for data*/
+#define BAP_UNICAST          1
+#define BAP_BROADCAST        2
+#define BAP_BA_SIMULCAST     3
+
+
 typedef int (*routing_cb)(int port);
 
 enum {
@@ -426,6 +432,7 @@ int afe_get_power_mode_cfg(u16 port_id, u32 *enable_flag);
 int afe_port_start(u16 port_id, union afe_port_config *afe_config,
 	u32 rate);
 int afe_set_tws_channel_mode(u32 foramt, u16 port_id, u32 channel_mode);
+int afe_set_lc3_channel_mode(u32 foramt, u16 port_id, u32 channel_mode);
 int afe_port_start_v2(u16 port_id, union afe_port_config *afe_config,
 		      u32 rate, u16 afe_in_channels, u16 afe_in_bit_width,
 		      struct afe_enc_config *enc_config,

+ 4 - 1
ipc/apr.c

@@ -22,6 +22,7 @@
 #include <linux/slab.h>
 #include <linux/ipc_logging.h>
 #include <linux/of_platform.h>
+#include <linux/ratelimit.h>
 #include <soc/qcom/subsystem_restart.h>
 #include <linux/qcom_scm.h>
 #include <soc/snd_event.h>
@@ -370,6 +371,7 @@ int apr_send_pkt(void *handle, uint32_t *buf)
 	uint16_t w_len;
 	int rc;
 	unsigned long flags;
+	static DEFINE_RATELIMIT_STATE(rtl, 1 * HZ, 1);
 
 	if (!handle || !buf) {
 		pr_err("APR: Wrong parameters for %s\n",
@@ -383,7 +385,8 @@ int apr_send_pkt(void *handle, uint32_t *buf)
 
 	if ((svc->dest_id == APR_DEST_QDSP6) &&
 	    (apr_get_q6_state() != APR_SUBSYS_LOADED)) {
-		pr_err_ratelimited("%s: Still dsp is not Up\n", __func__);
+		if (__ratelimit(&rtl))
+			pr_err_ratelimited("%s: Still dsp is not Up\n", __func__);
 		return -ENETRESET;
 	} else if ((svc->dest_id == APR_DEST_MODEM) &&
 		   (apr_get_modem_state() == APR_SUBSYS_DOWN)) {

+ 9 - 3
soc/pinctrl-lpi.c

@@ -13,6 +13,7 @@
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/types.h>
+#include <linux/ratelimit.h>
 #include <linux/clk.h>
 #include <linux/bitops.h>
 #include <linux/delay.h>
@@ -148,16 +149,19 @@ static int lpi_gpio_read(struct lpi_gpio_pad *pad, unsigned int addr)
 {
 	int ret = 0;
 	struct lpi_gpio_state *state = dev_get_drvdata(lpi_dev);
+	static DEFINE_RATELIMIT_STATE(rtl, 1 * HZ, 1);
 
 	if (!lpi_dev_up) {
-		pr_err_ratelimited("%s: ADSP is down due to SSR, return\n",
+		if (__ratelimit(&rtl))
+			pr_err("%s: ADSP is down due to SSR, return\n",
 				   __func__);
 		return 0;
 	}
 	pm_runtime_get_sync(lpi_dev);
 	mutex_lock(&state->core_hw_vote_lock);
 	if (!state->core_hw_vote_status) {
-		pr_err_ratelimited("%s: core hw vote clk is not enabled\n",
+		if (__ratelimit(&rtl))
+			pr_err("%s: core hw vote clk is not enabled\n",
 				__func__);
 		ret = -EINVAL;
 		goto err;
@@ -179,6 +183,7 @@ static int lpi_gpio_write(struct lpi_gpio_pad *pad, unsigned int addr,
 {
 	struct lpi_gpio_state *state = dev_get_drvdata(lpi_dev);
 	int ret = 0;
+	static DEFINE_RATELIMIT_STATE(rtl, 1 * HZ, 1);
 
 	if (!lpi_dev_up) {
 		return 0;
@@ -186,7 +191,8 @@ static int lpi_gpio_write(struct lpi_gpio_pad *pad, unsigned int addr,
 	pm_runtime_get_sync(lpi_dev);
 	mutex_lock(&state->core_hw_vote_lock);
 	if (!state->core_hw_vote_status) {
-		pr_err_ratelimited("%s: core hw vote clk is not enabled\n",
+		if (__ratelimit(&rtl))
+			pr_err("%s: core hw vote clk is not enabled\n",
 				__func__);
 		ret = -EINVAL;
 		goto err;