Merge "asoc: codecs: bolero: leave frame sync to default value"
diff --git a/asoc/codecs/audio-ext-clk-up.c b/asoc/codecs/audio-ext-clk-up.c
index e86b30e..6ed5ddd 100644
--- a/asoc/codecs/audio-ext-clk-up.c
+++ b/asoc/codecs/audio-ext-clk-up.c
@@ -194,6 +194,7 @@
"qpnp_clkdiv_1",
"pms405_div_clk1",
"pm6150_div_clk1",
+ "pm6125_div_clk1",
};
static int audio_ext_clk_dummy_prepare(struct clk_hw *hw)
diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c
index 4d9ccb4..535a336 100644
--- a/asoc/codecs/bolero/rx-macro.c
+++ b/asoc/codecs/bolero/rx-macro.c
@@ -453,6 +453,10 @@
SOC_DAPM_SINGLE("RX AUX VBAT Enable", SND_SOC_NOPM, 0, 1, 0)
};
+static const char * const hph_idle_detect_text[] = {"OFF", "ON"};
+
+static SOC_ENUM_SINGLE_EXT_DECL(hph_idle_detect_enum, hph_idle_detect_text);
+
RX_MACRO_DAPM_ENUM(rx_int0_2, BOLERO_CDC_RX_INP_MUX_RX_INT0_CFG1, 0,
rx_int_mix_mux_text);
RX_MACRO_DAPM_ENUM(rx_int1_2, BOLERO_CDC_RX_INP_MUX_RX_INT1_CFG1, 0,
@@ -1684,6 +1688,40 @@
}
}
+static int rx_macro_hph_idle_detect_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *component =
+ snd_soc_kcontrol_component(kcontrol);
+ struct rx_macro_priv *rx_priv = NULL;
+ struct device *rx_dev = NULL;
+
+ if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
+ return -EINVAL;
+
+ ucontrol->value.integer.value[0] =
+ rx_priv->idle_det_cfg.hph_idle_detect_en;
+
+ return 0;
+}
+
+static int rx_macro_hph_idle_detect_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *component =
+ snd_soc_kcontrol_component(kcontrol);
+ struct rx_macro_priv *rx_priv = NULL;
+ struct device *rx_dev = NULL;
+
+ if (!rx_macro_get_data(component, &rx_dev, &rx_priv, __func__))
+ return -EINVAL;
+
+ rx_priv->idle_det_cfg.hph_idle_detect_en =
+ ucontrol->value.integer.value[0];
+
+ return 0;
+}
+
static int rx_macro_get_compander(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@@ -2611,6 +2649,9 @@
SOC_SINGLE_EXT("RX_COMP2 Switch", SND_SOC_NOPM, RX_MACRO_COMP2, 1, 0,
rx_macro_get_compander, rx_macro_set_compander),
+ SOC_ENUM_EXT("HPH Idle Detect", hph_idle_detect_enum,
+ rx_macro_hph_idle_detect_get, rx_macro_hph_idle_detect_put),
+
SOC_ENUM_EXT("RX_EAR Mode", rx_macro_ear_mode_enum,
rx_macro_get_ear_mode, rx_macro_put_ear_mode),
diff --git a/asoc/codecs/wcd-mbhc-v2.c b/asoc/codecs/wcd-mbhc-v2.c
index 6839203..1159b11 100644
--- a/asoc/codecs/wcd-mbhc-v2.c
+++ b/asoc/codecs/wcd-mbhc-v2.c
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-only
-/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
*/
#include <linux/module.h>
#include <linux/init.h>
@@ -850,7 +850,7 @@
{
bool ret = false;
- if (!mbhc->mbhc_cfg->moisture_en ||
+ if (!mbhc->mbhc_cfg->moisture_en &&
!mbhc->mbhc_cfg->moisture_duty_cycle_en)
return ret;
@@ -1342,9 +1342,15 @@
else
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HS_L_DET_PULL_UP_CTRL, 3);
+ /* Configure for moisture detection when duty cycle is not enabled.
+ * Otherwise disable moisture detection.
+ */
if (mbhc->mbhc_cfg->moisture_en && mbhc->mbhc_cb->mbhc_moisture_config
&& !mbhc->mbhc_cfg->moisture_duty_cycle_en)
mbhc->mbhc_cb->mbhc_moisture_config(mbhc);
+ else if (mbhc->mbhc_cfg->moisture_duty_cycle_en &&
+ mbhc->mbhc_cb->mbhc_moisture_detect_en)
+ mbhc->mbhc_cb->mbhc_moisture_detect_en(mbhc, false);
/*
* For USB analog we need to override the switch configuration.
diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c
index ae286bd..beb4b17 100644
--- a/asoc/codecs/wcd937x/wcd937x.c
+++ b/asoc/codecs/wcd937x/wcd937x.c
@@ -131,7 +131,9 @@
0xFF, 0x3A);
snd_soc_component_update_bits(component, WCD937X_RX_OCP_CTL,
0x0F, 0x02);
-
+ snd_soc_component_update_bits(component,
+ WCD937X_HPH_SURGE_HPHLR_SURGE_EN,
+ 0xFF, 0xD9);
return 0;
}
@@ -1507,6 +1509,10 @@
wcd937x_get_logical_addr(wcd937x->rx_swr_dev);
regcache_mark_dirty(wcd937x->regmap);
regcache_sync(wcd937x->regmap);
+ /* Enable surge protection */
+ snd_soc_component_update_bits(component,
+ WCD937X_HPH_SURGE_HPHLR_SURGE_EN,
+ 0xFF, 0xD9);
/* Initialize MBHC module */
mbhc = &wcd937x->mbhc->wcd_mbhc;
ret = wcd937x_mbhc_post_ssr_init(wcd937x->mbhc, component);
diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c
index 8ebef1f..8a5622f 100644
--- a/asoc/codecs/wcd938x/wcd938x.c
+++ b/asoc/codecs/wcd938x/wcd938x.c
@@ -49,6 +49,10 @@
};
enum {
+ WCD_ADC1 = 0,
+ WCD_ADC2,
+ WCD_ADC3,
+ WCD_ADC4,
ALLOW_BUCK_DISABLE,
HPH_COMP_DELAY,
HPH_PA_DELAY,
@@ -1227,12 +1231,14 @@
default:
break;
}
+ set_bit(w->shift, &wcd938x->status_mask);
wcd938x_tx_connect_port(component, ADC1 + (w->shift), true);
break;
case SND_SOC_DAPM_POST_PMD:
wcd938x_tx_connect_port(component, ADC1 + (w->shift), false);
snd_soc_component_update_bits(component,
WCD938X_DIGITAL_CDC_ANA_CLK_CTL, 0x08, 0x00);
+ clear_bit(w->shift, &wcd938x->status_mask);
break;
};
@@ -1469,8 +1475,6 @@
void *data)
{
u16 event = (val & 0xffff);
- u16 amic;
- u16 mask = 0x40, reg = 0x0;
int ret = 0;
struct wcd938x_priv *wcd938x = dev_get_drvdata((struct device *)data);
struct snd_soc_component *component = wcd938x->component;
@@ -1478,16 +1482,26 @@
switch (event) {
case BOLERO_WCD_EVT_TX_CH_HOLD_CLEAR:
- amic = (val >> 0x10);
- if (amic == 0x1 || amic == 0x2)
- reg = WCD938X_ANA_TX_CH2;
- else if (amic == 0x3)
- reg = WCD938X_ANA_TX_CH4;
- else
- return 0;
- if (amic == 0x2)
- mask = 0x20;
- snd_soc_component_update_bits(component, reg, mask, 0x00);
+ if (test_bit(WCD_ADC1, &wcd938x->status_mask)) {
+ snd_soc_component_update_bits(component,
+ WCD938X_ANA_TX_CH2, 0x40, 0x00);
+ clear_bit(WCD_ADC1, &wcd938x->status_mask);
+ }
+ if (test_bit(WCD_ADC2, &wcd938x->status_mask)) {
+ snd_soc_component_update_bits(component,
+ WCD938X_ANA_TX_CH2, 0x20, 0x00);
+ clear_bit(WCD_ADC2, &wcd938x->status_mask);
+ }
+ if (test_bit(WCD_ADC3, &wcd938x->status_mask)) {
+ snd_soc_component_update_bits(component,
+ WCD938X_ANA_TX_CH4, 0x40, 0x00);
+ clear_bit(WCD_ADC3, &wcd938x->status_mask);
+ }
+ if (test_bit(WCD_ADC4, &wcd938x->status_mask)) {
+ snd_soc_component_update_bits(component,
+ WCD938X_ANA_TX_CH4, 0x20, 0x00);
+ clear_bit(WCD_ADC4, &wcd938x->status_mask);
+ }
break;
case BOLERO_WCD_EVT_PA_OFF_PRE_SSR:
snd_soc_component_update_bits(component, WCD938X_ANA_HPH,
diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c
index 10acd50..c2be85b 100644
--- a/asoc/msm-dai-q6-v2.c
+++ b/asoc/msm-dai-q6-v2.c
@@ -3226,11 +3226,64 @@
return 0;
}
+static int msm_dai_q6_afe_feedback_dec_cfg_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data;
+ u32 format_size = 0;
+
+ if (!dai_data) {
+ pr_err("%s: Invalid dai data\n", __func__);
+ return -EINVAL;
+ }
+
+ format_size = sizeof(dai_data->dec_config.format);
+ memcpy(ucontrol->value.bytes.data,
+ &dai_data->dec_config.format,
+ format_size);
+
+ pr_debug("%s: abr_dec_cfg for %d format\n",
+ __func__, dai_data->dec_config.format);
+ memcpy(ucontrol->value.bytes.data + format_size,
+ &dai_data->dec_config.abr_dec_cfg,
+ sizeof(struct afe_imc_dec_enc_info));
+
+ return 0;
+}
+
+static int msm_dai_q6_afe_feedback_dec_cfg_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data;
+ u32 format_size = 0;
+
+ if (!dai_data) {
+ pr_err("%s: Invalid dai data\n", __func__);
+ return -EINVAL;
+ }
+
+ memset(&dai_data->dec_config, 0x0,
+ sizeof(struct afe_dec_config));
+ format_size = sizeof(dai_data->dec_config.format);
+ memcpy(&dai_data->dec_config.format,
+ ucontrol->value.bytes.data,
+ format_size);
+
+ pr_debug("%s: abr_dec_cfg for %d format\n",
+ __func__, dai_data->dec_config.format);
+ memcpy(&dai_data->dec_config.abr_dec_cfg,
+ ucontrol->value.bytes.data + format_size,
+ sizeof(struct afe_imc_dec_enc_info));
+ dai_data->dec_config.abr_dec_cfg.is_abr_enabled = true;
+ return 0;
+}
+
static int msm_dai_q6_afe_dec_cfg_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data;
u32 format_size = 0;
+ int ret = 0;
if (!dai_data) {
pr_err("%s: Invalid dai data\n", __func__);
@@ -3247,20 +3300,23 @@
&dai_data->dec_config.data,
sizeof(struct asm_aac_dec_cfg_v2_t));
break;
+ case DEC_FMT_APTX_ADAPTIVE:
+ memcpy(ucontrol->value.bytes.data + format_size,
+ &dai_data->dec_config.data,
+ sizeof(struct asm_aptx_ad_dec_cfg_t));
+ break;
case DEC_FMT_SBC:
case DEC_FMT_MP3:
/* No decoder specific data available */
break;
default:
- pr_debug("%s: Default decoder config for %d format: Expect abr_dec_cfg\n",
+ pr_err("%s: Invalid format %d\n",
__func__, dai_data->dec_config.format);
- memcpy(ucontrol->value.bytes.data + format_size,
- &dai_data->dec_config.abr_dec_cfg,
- sizeof(struct afe_abr_dec_cfg_t));
-
+ ret = -EINVAL;
break;
}
- return 0;
+
+ return ret;
}
static int msm_dai_q6_afe_dec_cfg_put(struct snd_kcontrol *kcontrol,
@@ -3268,6 +3324,7 @@
{
struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data;
u32 format_size = 0;
+ int ret = 0;
if (!dai_data) {
pr_err("%s: Invalid dai data\n", __func__);
@@ -3293,15 +3350,19 @@
ucontrol->value.bytes.data + format_size,
sizeof(struct asm_sbc_dec_cfg_t));
break;
- default:
- pr_debug("%s: Default decoder config for %d format: Expect abr_dec_cfg\n",
- __func__, dai_data->dec_config.format);
- memcpy(&dai_data->dec_config.abr_dec_cfg,
+ case DEC_FMT_APTX_ADAPTIVE:
+ memcpy(&dai_data->dec_config.data,
ucontrol->value.bytes.data + format_size,
- sizeof(struct afe_abr_dec_cfg_t));
+ sizeof(struct asm_aptx_ad_dec_cfg_t));
+ break;
+ default:
+ pr_err("%s: Invalid format %d\n",
+ __func__, dai_data->dec_config.format);
+ ret = -EINVAL;
break;
}
- return 0;
+
+ return ret;
}
static const struct snd_kcontrol_new afe_dec_config_controls[] = {
@@ -3311,8 +3372,8 @@
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
.name = "SLIM_7_TX Decoder Config",
.info = msm_dai_q6_afe_dec_cfg_info,
- .get = msm_dai_q6_afe_dec_cfg_get,
- .put = msm_dai_q6_afe_dec_cfg_put,
+ .get = msm_dai_q6_afe_feedback_dec_cfg_get,
+ .put = msm_dai_q6_afe_feedback_dec_cfg_put,
},
{
.access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c
index c49a757..00f603e 100644
--- a/asoc/msm-pcm-routing-v2.c
+++ b/asoc/msm-pcm-routing-v2.c
@@ -1537,7 +1537,7 @@
fe_id, be_id, msm_bedais[be_id].channel,
copp_idx);
ret = adm_programable_channel_mixer(
- msm_bedais[be_id].port_id,
+ get_port_id(msm_bedais[be_id].port_id),
copp_idx, dspst_id, sess_type,
channel_mixer + fe_id, i);
}
@@ -3104,20 +3104,21 @@
"QUIN_TDM_RX_2", "QUIN_TDM_TX_2", "QUIN_TDM_RX_3", "QUIN_TDM_TX_3",
"QUIN_TDM_RX_4", "QUIN_TDM_TX_4", "QUIN_TDM_RX_5", "QUIN_TDM_TX_5",
"QUIN_TDM_RX_6", "QUIN_TDM_TX_6", "QUIN_TDM_RX_7", "QUIN_TDM_TX_7",
-"INT_BT_A2DP_RX", "USB_RX", "USB_TX", "DISPLAY_PORT_RX", "DISPLAY_PORT_RX1",
-"TERT_AUXPCM_RX", "TERT_AUXPCM_TX", "QUAT_AUXPCM_RX", "QUAT_AUXPCM_TX",
-"QUIN_AUXPCM_RX", "QUIN_AUXPCM_TX",
-"INT0_MI2S_RX", "INT0_MI2S_TX", "INT1_MI2S_RX", "INT1_MI2S_TX",
-"INT2_MI2S_RX", "INT2_MI2S_TX", "INT3_MI2S_RX", "INT3_MI2S_TX",
-"INT4_MI2S_RX", "INT4_MI2S_TX", "INT5_MI2S_RX", "INT5_MI2S_TX",
-"INT6_MI2S_RX", "INT6_MI2S_TX", "WSA_CDC_DMA_RX_0",
-"WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_RX_1", "WSA_CDC_DMA_TX_1",
+"INT_BT_A2DP_RX", "USB_RX", "USB_TX", "DISPLAY_PORT_RX",
+"DISPLAY_PORT_RX1", "TERT_AUXPCM_RX", "TERT_AUXPCM_TX", "QUAT_AUXPCM_RX",
+"QUAT_AUXPCM_TX", "QUIN_AUXPCM_RX", "QUIN_AUXPCM_TX", "INT0_MI2S_RX",
+"INT0_MI2S_TX", "INT1_MI2S_RX", "INT1_MI2S_TX", "INT2_MI2S_RX",
+"INT2_MI2S_TX", "INT3_MI2S_RX", "INT3_MI2S_TX", "INT4_MI2S_RX",
+"INT4_MI2S_TX", "INT5_MI2S_RX", "INT5_MI2S_TX", "INT6_MI2S_RX",
+"INT6_MI2S_TX", "SEN_AUXPCM_RX", "SEN_AUXPCM_TX", "SENARY_MI2S_RX",
+"WSA_CDC_DMA_RX_0", "WSA_CDC_DMA_TX_0", "WSA_CDC_DMA_RX_1","WSA_CDC_DMA_TX_1",
"WSA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_0", "VA_CDC_DMA_TX_1", "VA_CDC_DMA_TX_2",
"RX_CDC_DMA_RX_0", "TX_CDC_DMA_TX_0", "RX_CDC_DMA_RX_1", "TX_CDC_DMA_TX_1",
"RX_CDC_DMA_RX_2", "TX_CDC_DMA_TX_2", "RX_CDC_DMA_RX_3", "TX_CDC_DMA_TX_3",
"RX_CDC_DMA_RX_4", "TX_CDC_DMA_TX_4", "RX_CDC_DMA_RX_5", "TX_CDC_DMA_TX_5",
"RX_CDC_DMA_RX_6", "RX_CDC_DMA_RX_7",
"PRI_SPDIF_TX", "SEC_SPDIF_RX", "SEC_SPDIF_TX",
+"SLIM_9_RX", "SLIM_9_TX", "AFE_LOOPBACK_TX"
};
static SOC_ENUM_SINGLE_DECL(mm1_channel_mux,
@@ -9373,6 +9374,10 @@
MSM_BACKEND_DAI_SLIMBUS_0_TX,
MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_SLIMBUS_1_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("AUX_PCM_UL_TX", SND_SOC_NOPM,
MSM_BACKEND_DAI_AUXPCM_TX,
MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
@@ -9791,6 +9796,10 @@
MSM_BACKEND_DAI_SLIMBUS_0_TX,
MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_SLIMBUS_1_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM,
MSM_BACKEND_DAI_INT_FM_TX,
MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
@@ -9990,6 +9999,10 @@
MSM_BACKEND_DAI_SLIMBUS_0_TX,
MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_SLIMBUS_1_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM,
MSM_BACKEND_DAI_PRI_MI2S_TX,
MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
@@ -10185,6 +10198,10 @@
MSM_BACKEND_DAI_SLIMBUS_0_TX,
MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_SLIMBUS_1_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("INTERNAL_FM_TX", SND_SOC_NOPM,
MSM_BACKEND_DAI_INT_FM_TX,
MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
@@ -10412,6 +10429,10 @@
MSM_BACKEND_DAI_SLIMBUS_0_TX,
MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_SLIMBUS_1_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM,
MSM_BACKEND_DAI_PRI_MI2S_TX,
MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
@@ -10607,6 +10628,10 @@
MSM_BACKEND_DAI_SLIMBUS_0_TX,
MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_SLIMBUS_1_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM,
MSM_BACKEND_DAI_PRI_MI2S_TX,
MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
@@ -10814,6 +10839,10 @@
MSM_BACKEND_DAI_SLIMBUS_0_TX,
MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_SLIMBUS_1_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM,
MSM_BACKEND_DAI_PRI_MI2S_TX,
MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer,
@@ -11027,6 +11056,10 @@
MSM_BACKEND_DAI_SLIMBUS_0_TX,
MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_SLIMBUS_1_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM,
MSM_BACKEND_DAI_PRI_MI2S_TX,
MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
@@ -11170,6 +11203,10 @@
MSM_BACKEND_DAI_SLIMBUS_0_TX,
MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_SLIMBUS_1_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM,
MSM_BACKEND_DAI_PRI_MI2S_TX,
MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer,
@@ -11346,6 +11383,10 @@
MSM_BACKEND_DAI_SLIMBUS_0_TX,
MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_SLIMBUS_1_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM,
MSM_BACKEND_DAI_PRI_MI2S_TX,
MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer,
@@ -11455,6 +11496,10 @@
MSM_BACKEND_DAI_SLIMBUS_0_TX,
MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_SLIMBUS_1_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM,
MSM_BACKEND_DAI_PRI_MI2S_TX,
MSM_FRONTEND_DAI_MULTIMEDIA18, 1, 0, msm_routing_get_audio_mixer,
@@ -11568,6 +11613,10 @@
MSM_BACKEND_DAI_SLIMBUS_0_TX,
MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_SLIMBUS_1_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM,
MSM_BACKEND_DAI_PRI_MI2S_TX,
MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer,
@@ -11596,6 +11645,10 @@
MSM_BACKEND_DAI_INCALL_RECORD_TX,
MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_SECONDARY_MI2S_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM,
MSM_BACKEND_DAI_TERTIARY_MI2S_TX,
MSM_FRONTEND_DAI_MULTIMEDIA19, 1, 0, msm_routing_get_audio_mixer,
@@ -11991,6 +12044,10 @@
MSM_BACKEND_DAI_SLIMBUS_0_TX,
MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_SLIMBUS_1_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("SLIM_6_TX", SND_SOC_NOPM,
MSM_BACKEND_DAI_SLIMBUS_6_TX,
MSM_FRONTEND_DAI_MULTIMEDIA27, 1, 0, msm_routing_get_audio_mixer,
@@ -12042,6 +12099,10 @@
MSM_BACKEND_DAI_SLIMBUS_0_TX,
MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_SLIMBUS_1_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM,
MSM_BACKEND_DAI_PRI_MI2S_TX,
MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer,
@@ -12070,6 +12131,10 @@
MSM_BACKEND_DAI_INCALL_RECORD_TX,
MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_SECONDARY_MI2S_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM,
MSM_BACKEND_DAI_TERTIARY_MI2S_TX,
MSM_FRONTEND_DAI_MULTIMEDIA28, 1, 0, msm_routing_get_audio_mixer,
@@ -12151,6 +12216,10 @@
MSM_BACKEND_DAI_SLIMBUS_0_TX,
MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("SLIM_1_TX", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_SLIMBUS_1_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("PRI_MI2S_TX", SND_SOC_NOPM,
MSM_BACKEND_DAI_PRI_MI2S_TX,
MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer,
@@ -12179,6 +12248,10 @@
MSM_BACKEND_DAI_INCALL_RECORD_TX,
MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("SEC_MI2S_TX", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_SECONDARY_MI2S_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("TERT_MI2S_TX", SND_SOC_NOPM,
MSM_BACKEND_DAI_TERTIARY_MI2S_TX,
MSM_FRONTEND_DAI_MULTIMEDIA29, 1, 0, msm_routing_get_audio_mixer,
@@ -20255,12 +20328,19 @@
{"MultiMedia8 Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"},
{"MultiMedia8 Mixer", "SLIM_9_TX", "SLIMBUS_9_TX"},
{"MultiMedia4 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
+ {"MultiMedia4 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"},
{"MultiMedia17 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
+ {"MultiMedia17 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"},
{"MultiMedia18 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
+ {"MultiMedia18 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"},
{"MultiMedia19 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
+ {"MultiMedia19 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"},
{"MultiMedia28 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
+ {"MultiMedia28 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"},
{"MultiMedia29 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
+ {"MultiMedia29 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"},
{"MultiMedia8 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
+ {"MultiMedia8 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"},
{"MultiMedia2 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"},
{"MultiMedia4 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"},
{"MultiMedia17 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"},
@@ -20270,6 +20350,9 @@
{"MultiMedia29 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"},
{"MultiMedia8 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"},
{"MultiMedia18 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"},
+ {"MultiMedia19 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"},
+ {"MultiMedia28 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"},
+ {"MultiMedia29 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"},
{"MultiMedia17 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"},
{"MultiMedia18 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"},
{"MultiMedia19 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"},
@@ -20282,16 +20365,26 @@
{"MultiMedia29 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"},
{"MultiMedia8 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"},
{"MultiMedia3 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
+ {"MultiMedia3 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"},
{"MultiMedia5 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
+ {"MultiMedia5 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"},
{"MultiMedia10 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
+ {"MultiMedia10 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"},
{"MultiMedia16 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
+ {"MultiMedia16 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"},
{"MultiMedia5 Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"},
{"MultiMedia5 Mixer", "SLIM_8_TX", "SLIMBUS_8_TX"},
{"MultiMedia5 Mixer", "SLIM_9_TX", "SLIMBUS_9_TX"},
{"MultiMedia10 Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"},
{"MultiMedia10 Mixer", "SLIM_9_TX", "SLIMBUS_9_TX"},
{"MultiMedia18 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"},
+ {"MultiMedia19 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"},
+ {"MultiMedia28 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"},
+ {"MultiMedia29 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"},
{"MultiMedia18 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"},
+ {"MultiMedia19 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"},
+ {"MultiMedia28 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"},
+ {"MultiMedia29 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"},
{"MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
{"MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
@@ -20957,6 +21050,7 @@
{"MultiMedia1 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"},
{"MultiMedia2 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"},
{"MultiMedia1 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
+ {"MultiMedia1 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"},
{"MultiMedia1 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"},
{"MultiMedia3 Mixer", "AUX_PCM_TX", "AUX_PCM_TX"},
{"MultiMedia5 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"},
@@ -20987,6 +21081,7 @@
{"MultiMedia1 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"},
{"MultiMedia2 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"},
{"MultiMedia6 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
+ {"MultiMedia6 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"},
{"MultiMedia6 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"},
{"MultiMedia3 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"},
{"MultiMedia5 Mixer", "TERT_MI2S_TX", "TERT_MI2S_TX"},
@@ -21264,6 +21359,7 @@
{"MultiMedia8 Mixer", "PRI_SPDIF_TX", "PRI_SPDIF_TX"},
{"MultiMedia8 Mixer", "SEC_SPDIF_TX", "SEC_SPDIF_TX"},
+ {"MultiMedia9 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"},
{"MultiMedia9 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"},
{"MultiMedia9 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"},
{"MultiMedia9 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"},
@@ -21388,6 +21484,7 @@
{"MultiMedia21 Mixer", "AFE_LOOPBACK_TX", "AFE_LOOPBACK_TX"},
{"MultiMedia27 Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
+ {"MultiMedia27 Mixer", "SLIM_1_TX", "SLIMBUS_1_TX"},
{"MultiMedia27 Mixer", "SLIM_6_TX", "SLIMBUS_6_TX"},
{"MultiMedia27 Mixer", "SLIM_7_TX", "SLIMBUS_7_TX"},
{"MultiMedia27 Mixer", "SLIM_9_TX", "SLIMBUS_9_TX"},
diff --git a/asoc/qcs405.c b/asoc/qcs405.c
index 6e4596f..4d60c6e 100644
--- a/asoc/qcs405.c
+++ b/asoc/qcs405.c
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-only
-/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
*/
#include <linux/clk.h>
#include <linux/delay.h>
@@ -179,6 +179,7 @@
struct device_node *dmic_23_gpio_p; /* used by pinctrl API */
struct device_node *dmic_45_gpio_p; /* used by pinctrl API */
struct device_node *dmic_67_gpio_p; /* used by pinctrl API */
+ struct device_node *lineout_booster_gpio_p; /* used by pinctrl API */
struct device_node *mi2s_gpio_p[MI2S_MAX]; /* used by pinctrl API */
int dmic_01_gpio_cnt;
int dmic_23_gpio_cnt;
@@ -3838,6 +3839,30 @@
return 0;
}
+static int msm_lineout_booster_ctrl_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *k, int event)
+{
+ struct snd_soc_component *component =
+ snd_soc_dapm_to_component(w->dapm);
+ struct snd_soc_card *card = component->card;
+ struct msm_asoc_mach_data *pdata =
+ snd_soc_card_get_drvdata(card);
+
+ pr_debug("%s: event = %d\n", __func__, event);
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMU:
+ msm_cdc_pinctrl_select_active_state(
+ pdata->lineout_booster_gpio_p);
+ break;
+ case SND_SOC_DAPM_PRE_PMD:
+ msm_cdc_pinctrl_select_sleep_state(
+ pdata->lineout_booster_gpio_p);
+ break;
+ }
+
+ return 0;
+}
+
static const struct snd_soc_dapm_widget msm_dapm_widgets[] = {
SND_SOC_DAPM_SUPPLY("MCLK", SND_SOC_NOPM, 0, 0,
@@ -3847,6 +3872,7 @@
SND_SOC_DAPM_SUPPLY("MCLK TX", SND_SOC_NOPM, 0, 0,
msm_mclk_tx_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_SPK("lineout booster", msm_lineout_booster_ctrl_event),
SND_SOC_DAPM_MIC("Analog Mic3", NULL),
SND_SOC_DAPM_MIC("Analog Mic4", NULL),
@@ -5047,7 +5073,6 @@
return ret;
}
-
static int msm_snd_cdc_dma_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
@@ -8603,6 +8628,8 @@
"qcom,cdc-dmic45-gpios", 0);
pdata->dmic_67_gpio_p = of_parse_phandle(pdev->dev.of_node,
"qcom,cdc-dmic67-gpios", 0);
+ pdata->lineout_booster_gpio_p = of_parse_phandle(pdev->dev.of_node,
+ "qcom,lineout-booster-gpio", 0);
pdata->mi2s_gpio_p[PRIM_MI2S] = of_parse_phandle(pdev->dev.of_node,
"qcom,pri-mi2s-gpios", 0);
diff --git a/asoc/sm6150.c b/asoc/sm6150.c
index 55fe178..84e05c8 100644
--- a/asoc/sm6150.c
+++ b/asoc/sm6150.c
@@ -29,6 +29,7 @@
#include "msm-pcm-routing-v2.h"
#include <asoc/msm-cdc-pinctrl.h>
#include "codecs/wcd934x/wcd934x.h"
+#include "codecs/wcd9335.h"
#include "codecs/wcd934x/wcd934x-mbhc.h"
#include "codecs/wcd937x/wcd937x-mbhc.h"
#include "codecs/wsa881x.h"
@@ -204,6 +205,8 @@
struct snd_info_entry *codec_root;
int usbc_en2_gpio; /* used by gpio driver API */
struct device_node *mi2s_gpio_p[MI2S_MAX]; /* used by pinctrl API */
+ int hph_en1_gpio;
+ int hph_en0_gpio;
struct device_node *dmic01_gpio_p; /* used by pinctrl API */
struct device_node *dmic23_gpio_p; /* used by pinctrl API */
struct device_node *us_euro_gpio_p; /* used by pinctrl API */
@@ -653,13 +656,14 @@
.key_code[6] = 0,
.key_code[7] = 0,
.linein_th = 5000,
- .moisture_en = true,
+ .moisture_en = false,
.mbhc_micbias = MIC_BIAS_2,
.anc_micbias = MIC_BIAS_2,
.enable_anc_mic_detect = false,
+ .moisture_duty_cycle_en = true,
};
-static struct snd_soc_dapm_route wcd_audio_paths_tavil[] = {
+static struct snd_soc_dapm_route wcd_audio_paths[] = {
{"MIC BIAS1", NULL, "MCLK TX"},
{"MIC BIAS2", NULL, "MCLK TX"},
{"MIC BIAS3", NULL, "MCLK TX"},
@@ -3578,7 +3582,7 @@
cdc_dma_tx_sample_rate_put),
};
-static const struct snd_kcontrol_new msm_tavil_snd_controls[] = {
+static const struct snd_kcontrol_new msm_ext_snd_controls[] = {
SOC_ENUM_EXT("SLIM_0_RX Channels", slim_0_rx_chs,
slim_rx_ch_get, slim_rx_ch_put),
SOC_ENUM_EXT("SLIM_2_RX Channels", slim_2_rx_chs,
@@ -3867,6 +3871,8 @@
if (!strcmp(component->name, "tavil_codec")) {
ret = tavil_cdc_mclk_enable(component, enable);
+ } else if (!strcmp(dev_name(component->dev), "tasha_codec")) {
+ ret = tasha_cdc_mclk_enable(component, enable, dapm);
} else {
dev_err(component->dev, "%s: unknown codec to enable ext clk\n",
__func__);
@@ -3882,6 +3888,8 @@
if (!strcmp(component->name, "tavil_codec")) {
ret = tavil_cdc_mclk_tx_enable(component, enable);
+ } else if (!strcmp(dev_name(component->dev), "tasha_codec")) {
+ ret = tasha_cdc_mclk_tx_enable(component, enable, dapm);
} else {
dev_err(component->dev, "%s: unknown codec to enable TX ext clk\n",
__func__);
@@ -3961,7 +3969,7 @@
return 0;
}
-static const struct snd_soc_dapm_widget msm_dapm_widgets_tavil[] = {
+static const struct snd_soc_dapm_widget msm_ext_dapm_widgets[] = {
SND_SOC_DAPM_SUPPLY("MCLK", SND_SOC_NOPM, 0, 0,
msm_mclk_event,
@@ -3972,12 +3980,19 @@
SND_SOC_DAPM_SPK("Lineout_1 amp", NULL),
SND_SOC_DAPM_SPK("Lineout_2 amp", NULL),
+ SND_SOC_DAPM_SPK("Lineout_3 amp", NULL),
+ SND_SOC_DAPM_SPK("Lineout_4 amp", NULL),
SND_SOC_DAPM_SPK("hifi amp", msm_hifi_ctrl_event),
SND_SOC_DAPM_MIC("Handset Mic", NULL),
SND_SOC_DAPM_MIC("Headset Mic", NULL),
+ SND_SOC_DAPM_MIC("Secondary Mic", NULL),
SND_SOC_DAPM_MIC("ANCRight Headset Mic", NULL),
SND_SOC_DAPM_MIC("ANCLeft Headset Mic", NULL),
+ SND_SOC_DAPM_MIC("Analog Mic4", NULL),
SND_SOC_DAPM_MIC("Analog Mic5", NULL),
+ SND_SOC_DAPM_MIC("Analog Mic6", NULL),
+ SND_SOC_DAPM_MIC("Analog Mic7", NULL),
+ SND_SOC_DAPM_MIC("Analog Mic8", NULL),
SND_SOC_DAPM_MIC("Digital Mic0", NULL),
SND_SOC_DAPM_MIC("Digital Mic1", NULL),
@@ -3985,6 +4000,7 @@
SND_SOC_DAPM_MIC("Digital Mic3", NULL),
SND_SOC_DAPM_MIC("Digital Mic4", NULL),
SND_SOC_DAPM_MIC("Digital Mic5", NULL),
+ SND_SOC_DAPM_MIC("Digital Mic6", NULL),
};
static int msm_dmic_event(struct snd_soc_dapm_widget *w,
@@ -4744,6 +4760,28 @@
afe_clear_config(AFE_SLIMBUS_SLAVE_CONFIG);
}
+static int msm_config_hph_en0_gpio(struct snd_soc_component *component, bool high)
+{
+ struct snd_soc_card *card = component->card;
+ struct msm_asoc_mach_data *pdata;
+ int val;
+
+ if (!card)
+ return 0;
+
+ pdata = snd_soc_card_get_drvdata(card);
+ if (!pdata || !gpio_is_valid(pdata->hph_en0_gpio))
+ return 0;
+
+ val = gpio_get_value_cansleep(pdata->hph_en0_gpio);
+ if ((!!val) == high)
+ return 0;
+
+ gpio_direction_output(pdata->hph_en0_gpio, (int)high);
+
+ return 1;
+}
+
static int msm_audrx_tavil_init(struct snd_soc_pcm_runtime *rtd)
{
int ret = 0;
@@ -4781,8 +4819,8 @@
}
dapm = snd_soc_component_get_dapm(component);
- ret = snd_soc_add_component_controls(component, msm_tavil_snd_controls,
- ARRAY_SIZE(msm_tavil_snd_controls));
+ ret = snd_soc_add_component_controls(component, msm_ext_snd_controls,
+ ARRAY_SIZE(msm_ext_snd_controls));
if (ret < 0) {
pr_err("%s: add_codec_controls failed, err %d\n",
__func__, ret);
@@ -4797,11 +4835,11 @@
return ret;
}
- snd_soc_dapm_new_controls(dapm, msm_dapm_widgets_tavil,
- ARRAY_SIZE(msm_dapm_widgets_tavil));
+ snd_soc_dapm_new_controls(dapm, msm_ext_dapm_widgets,
+ ARRAY_SIZE(msm_ext_dapm_widgets));
- snd_soc_dapm_add_routes(dapm, wcd_audio_paths_tavil,
- ARRAY_SIZE(wcd_audio_paths_tavil));
+ snd_soc_dapm_add_routes(dapm, wcd_audio_paths,
+ ARRAY_SIZE(wcd_audio_paths));
snd_soc_dapm_ignore_suspend(dapm, "Handset Mic");
snd_soc_dapm_ignore_suspend(dapm, "Headset Mic");
@@ -4875,16 +4913,197 @@
}
card = rtd->card->snd_card;
- entry = snd_info_create_subdir(card->module, "codecs",
- card->proc_root);
- if (!entry) {
- pr_debug("%s: Cannot create codecs module entry\n",
- __func__);
- ret = 0;
+ if (!pdata->codec_root) {
+ entry = snd_info_create_subdir(card->module, "codecs",
+ card->proc_root);
+ if (!entry) {
+ pr_debug("%s: Cannot create codecs module entry\n",
+ __func__);
+ ret = 0;
+ goto err;
+ }
+ pdata->codec_root = entry;
+ }
+ tavil_codec_info_create_codec_entry(pdata->codec_root, component);
+
+ codec_reg_done = true;
+ return 0;
+err:
+ return ret;
+}
+
+static int msm_audrx_tasha_init(struct snd_soc_pcm_runtime *rtd)
+{
+ int ret = 0;
+ void *config_data;
+ struct snd_soc_component *component = NULL;
+ struct snd_soc_dapm_context *dapm;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct snd_soc_component *aux_comp;
+ struct snd_card *card;
+ struct snd_info_entry *entry;
+ struct msm_asoc_mach_data *pdata =
+ snd_soc_card_get_drvdata(rtd->card);
+
+ /* Codec SLIMBUS configuration
+ * RX1, RX2, RX3, RX4, RX5, RX6, RX7, RX8, RX9, RX10, RX11, RX12, RX13
+ * TX1, TX2, TX3, TX4, TX5, TX6, TX7, TX8, TX9, TX10, TX11, TX12, TX13
+ * TX14, TX15, TX16
+ */
+ unsigned int rx_ch[TASHA_RX_MAX] = {144, 145, 146, 147, 148, 149, 150,
+ 151, 152, 153, 154, 155, 156};
+ unsigned int tx_ch[TASHA_TX_MAX] = {128, 129, 130, 131, 132, 133,
+ 134, 135, 136, 137, 138, 139,
+ 140, 141, 142, 143};
+
+ pr_info("%s: dev_name:%s\n", __func__, dev_name(cpu_dai->dev));
+
+ rtd->pmdown_time = 0;
+
+ component = snd_soc_rtdcom_lookup(rtd, "tasha_codec");
+ if (!component) {
+ pr_err("%s: component is NULL\n", __func__);
+ return -EINVAL;
+ }
+
+ dapm = snd_soc_component_get_dapm(component);
+
+ ret = snd_soc_add_component_controls(component, msm_ext_snd_controls,
+ ARRAY_SIZE(msm_ext_snd_controls));
+ if (ret < 0) {
+ pr_err("%s: add_component_controls failed, err %d\n",
+ __func__, ret);
+ return ret;
+ }
+
+ ret = snd_soc_add_component_controls(component, msm_common_snd_controls,
+ ARRAY_SIZE(msm_common_snd_controls));
+ if (ret < 0) {
+ pr_err("%s: add_component_controls failed, err %d\n",
+ __func__, ret);
+ return ret;
+ }
+
+ snd_soc_dapm_new_controls(dapm, msm_ext_dapm_widgets,
+ ARRAY_SIZE(msm_ext_dapm_widgets));
+
+ snd_soc_dapm_add_routes(dapm, wcd_audio_paths,
+ ARRAY_SIZE(wcd_audio_paths));
+
+ snd_soc_dapm_enable_pin(dapm, "Lineout_1 amp");
+ snd_soc_dapm_enable_pin(dapm, "Lineout_2 amp");
+ snd_soc_dapm_enable_pin(dapm, "Lineout_3 amp");
+ snd_soc_dapm_enable_pin(dapm, "Lineout_4 amp");
+
+ snd_soc_dapm_ignore_suspend(dapm, "MADINPUT");
+ snd_soc_dapm_ignore_suspend(dapm, "MAD_CPE_INPUT");
+ snd_soc_dapm_ignore_suspend(dapm, "Handset Mic");
+ snd_soc_dapm_ignore_suspend(dapm, "Headset Mic");
+ snd_soc_dapm_ignore_suspend(dapm, "Secondary Mic");
+ snd_soc_dapm_ignore_suspend(dapm, "Lineout_1 amp");
+ snd_soc_dapm_ignore_suspend(dapm, "Lineout_2 amp");
+ snd_soc_dapm_ignore_suspend(dapm, "Lineout_3 amp");
+ snd_soc_dapm_ignore_suspend(dapm, "Lineout_4 amp");
+ snd_soc_dapm_ignore_suspend(dapm, "ANCRight Headset Mic");
+ snd_soc_dapm_ignore_suspend(dapm, "ANCLeft Headset Mic");
+ snd_soc_dapm_ignore_suspend(dapm, "Digital Mic0");
+ snd_soc_dapm_ignore_suspend(dapm, "Digital Mic1");
+ snd_soc_dapm_ignore_suspend(dapm, "Digital Mic2");
+ snd_soc_dapm_ignore_suspend(dapm, "Digital Mic3");
+ snd_soc_dapm_ignore_suspend(dapm, "Digital Mic4");
+ snd_soc_dapm_ignore_suspend(dapm, "Digital Mic5");
+ snd_soc_dapm_ignore_suspend(dapm, "Analog Mic4");
+ snd_soc_dapm_ignore_suspend(dapm, "Analog Mic6");
+ snd_soc_dapm_ignore_suspend(dapm, "Analog Mic7");
+ snd_soc_dapm_ignore_suspend(dapm, "Analog Mic8");
+
+ snd_soc_dapm_ignore_suspend(dapm, "EAR");
+ snd_soc_dapm_ignore_suspend(dapm, "LINEOUT1");
+ snd_soc_dapm_ignore_suspend(dapm, "LINEOUT2");
+ snd_soc_dapm_ignore_suspend(dapm, "AMIC1");
+ snd_soc_dapm_ignore_suspend(dapm, "AMIC2");
+ snd_soc_dapm_ignore_suspend(dapm, "AMIC3");
+ snd_soc_dapm_ignore_suspend(dapm, "AMIC4");
+ snd_soc_dapm_ignore_suspend(dapm, "AMIC5");
+ snd_soc_dapm_ignore_suspend(dapm, "DMIC0");
+ snd_soc_dapm_ignore_suspend(dapm, "DMIC1");
+ snd_soc_dapm_ignore_suspend(dapm, "DMIC2");
+ snd_soc_dapm_ignore_suspend(dapm, "DMIC3");
+ snd_soc_dapm_ignore_suspend(dapm, "DMIC4");
+ snd_soc_dapm_ignore_suspend(dapm, "DMIC5");
+ snd_soc_dapm_ignore_suspend(dapm, "ANC EAR");
+ snd_soc_dapm_ignore_suspend(dapm, "SPK1 OUT");
+ snd_soc_dapm_ignore_suspend(dapm, "SPK2 OUT");
+ snd_soc_dapm_ignore_suspend(dapm, "HPHL");
+ snd_soc_dapm_ignore_suspend(dapm, "HPHR");
+ snd_soc_dapm_ignore_suspend(dapm, "AIF4 VI");
+ snd_soc_dapm_ignore_suspend(dapm, "VIINPUT");
+
+ snd_soc_dapm_ignore_suspend(dapm, "LINEOUT3");
+ snd_soc_dapm_ignore_suspend(dapm, "LINEOUT4");
+ snd_soc_dapm_ignore_suspend(dapm, "ANC HPHL");
+ snd_soc_dapm_ignore_suspend(dapm, "ANC HPHR");
+ snd_soc_dapm_ignore_suspend(dapm, "ANC LINEOUT1");
+ snd_soc_dapm_ignore_suspend(dapm, "ANC LINEOUT2");
+
+ snd_soc_dapm_sync(dapm);
+
+ snd_soc_dai_set_channel_map(codec_dai, ARRAY_SIZE(tx_ch),
+ tx_ch, ARRAY_SIZE(rx_ch), rx_ch);
+
+ msm_codec_fn.get_afe_config_fn = tasha_get_afe_config;
+
+ ret = msm_afe_set_config(component);
+ if (ret) {
+ pr_err("%s: Failed to set AFE config %d\n", __func__, ret);
goto err;
}
- pdata->codec_root = entry;
- tavil_codec_info_create_codec_entry(pdata->codec_root, component);
+ pdata->is_afe_config_done = true;
+
+ config_data = msm_codec_fn.get_afe_config_fn(component,
+ AFE_AANC_VERSION);
+ if (config_data) {
+ ret = afe_set_config(AFE_AANC_VERSION, config_data, 0);
+ if (ret) {
+ pr_err("%s: Failed to set aanc version %d\n",
+ __func__, ret);
+ goto err;
+ }
+ }
+
+ /*
+ * Send speaker configuration only for WSA8810.
+ * Default configuration is for WSA8815.
+ */
+ pr_debug("%s: Number of aux devices: %d\n",
+ __func__, rtd->card->num_aux_devs);
+ if (rtd->card->num_aux_devs &&
+ !list_empty(&rtd->card->aux_comp_list)) {
+ aux_comp = list_first_entry(&rtd->card->aux_comp_list,
+ struct snd_soc_component, card_aux_list);
+ if (!strcmp(aux_comp->name, WSA8810_NAME_1) ||
+ !strcmp(aux_comp->name, WSA8810_NAME_2)) {
+ tasha_set_spkr_mode(component, SPKR_MODE_1);
+ tasha_set_spkr_gain_offset(component,
+ RX_GAIN_OFFSET_M1P5_DB);
+ }
+ }
+
+ card = rtd->card->snd_card;
+ if (!pdata->codec_root) {
+ entry = snd_info_create_subdir(card->module, "codecs",
+ card->proc_root);
+ if (!entry) {
+ pr_debug("%s: Cannot create codecs module entry\n",
+ __func__);
+ ret = 0;
+ goto err;
+ }
+ pdata->codec_root = entry;
+ }
+ tasha_codec_info_create_codec_entry(pdata->codec_root, component);
+ tasha_mbhc_zdet_gpio_ctrl(msm_config_hph_en0_gpio, component);
codec_reg_done = true;
return 0;
@@ -5297,6 +5516,48 @@
return ret;
}
+int msm_snd_cpe_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
+ struct snd_soc_dai_link *dai_link = rtd->dai_link;
+ int ret = 0;
+ u32 tx_ch[SLIM_MAX_TX_PORTS];
+ u32 tx_ch_cnt = 0;
+
+ if (substream->stream != SNDRV_PCM_STREAM_CAPTURE) {
+ pr_err("%s: Invalid stream type %d\n",
+ __func__, substream->stream);
+ ret = -EINVAL;
+ goto end;
+ }
+
+ pr_debug("%s: %s_tx_dai_id_%d\n", __func__,
+ codec_dai->name, codec_dai->id);
+ ret = snd_soc_dai_get_channel_map(codec_dai,
+ &tx_ch_cnt, tx_ch, NULL, NULL);
+ if (ret < 0) {
+ pr_err("%s: failed to get codec chan map\n, err:%d\n",
+ __func__, ret);
+ goto end;
+ }
+
+ pr_debug("%s: tx_ch_cnt(%d) id %d\n",
+ __func__, tx_ch_cnt, dai_link->id);
+
+ ret = snd_soc_dai_set_channel_map(cpu_dai,
+ tx_ch_cnt, tx_ch, 0, 0);
+ if (ret < 0) {
+ pr_err("%s: failed to set cpu chan map, err:%d\n",
+ __func__, ret);
+ goto end;
+ }
+end:
+ return ret;
+}
+
static int msm_get_port_id(int be_id)
{
int afe_port_id;
@@ -5780,6 +6041,9 @@
.hw_params = msm_wcn_hw_params,
};
+static struct snd_soc_ops msm_ext_cpe_ops = {
+ .hw_params = msm_snd_cpe_hw_params,
+};
/* Digital audio interface glue - connects codec <---> CPU */
static struct snd_soc_dai_link msm_common_dai_links[] = {
@@ -6382,7 +6646,6 @@
},
};
-
static struct snd_soc_dai_link msm_tavil_fe_dai_links[] = {
{/* hw:x,37 */
.name = LPASS_BE_SLIMBUS_4_TX,
@@ -6513,6 +6776,96 @@
},
};
+static struct snd_soc_dai_link msm_tasha_fe_dai_links[] = {
+ /* tasha_vifeedback for speaker protection */
+ {
+ .name = LPASS_BE_SLIMBUS_4_TX,
+ .stream_name = "Slimbus4 Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.16393",
+ .platform_name = "msm-pcm-hostless",
+ .codec_name = "tasha_codec",
+ .codec_dai_name = "tasha_vifeedback",
+ .id = MSM_BACKEND_DAI_SLIMBUS_4_TX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &msm_be_ops,
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ },
+ /* Ultrasound RX DAI Link */
+ {
+ .name = "SLIMBUS_2 Hostless Playback",
+ .stream_name = "SLIMBUS_2 Hostless Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.16388",
+ .platform_name = "msm-pcm-hostless",
+ .codec_name = "tasha_codec",
+ .codec_dai_name = "tasha_rx2",
+ .ignore_suspend = 1,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .ignore_pmdown_time = 1,
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ops = &msm_slimbus_2_be_ops,
+ },
+ /* Ultrasound TX DAI Link */
+ {
+ .name = "SLIMBUS_2 Hostless Capture",
+ .stream_name = "SLIMBUS_2 Hostless Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.16389",
+ .platform_name = "msm-pcm-hostless",
+ .codec_name = "tasha_codec",
+ .codec_dai_name = "tasha_tx2",
+ .ignore_suspend = 1,
+ .dpcm_capture = 1,
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ops = &msm_slimbus_2_be_ops,
+ },
+ /* CPE LSM direct dai-link */
+ {
+ .name = "CPE Listen service",
+ .stream_name = "CPE Listen Audio Service",
+ .cpu_dai_name = "msm-dai-slim",
+ .platform_name = "msm-cpe-lsm",
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .dpcm_capture = 1,
+ .codec_dai_name = "tasha_mad1",
+ .codec_name = "tasha_codec",
+ .ops = &msm_ext_cpe_ops,
+ },
+ {
+ .name = "SLIMBUS_6 Hostless Playback",
+ .stream_name = "SLIMBUS_6 Hostless",
+ .cpu_dai_name = "SLIMBUS6_HOSTLESS",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ /* this dailink has playback support */
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ },
+ /* CPE LSM EC PP direct dai-link */
+ {
+ .name = "CPE Listen service ECPP",
+ .stream_name = "CPE Listen Audio Service ECPP",
+ .cpu_dai_name = "CPE_LSM_NOHOST",
+ .platform_name = "msm-cpe-lsm.3",
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .codec_dai_name = "tasha_cpe",
+ .codec_name = "tasha_codec",
+ },
+};
+
static struct snd_soc_dai_link msm_common_misc_fe_dai_links[] = {
{
.name = MSM_DAILINK_NAME(ASM Loopback),
@@ -6998,6 +7351,165 @@
},
};
+static struct snd_soc_dai_link msm_tasha_be_dai_links[] = {
+ /* Backend DAI Links */
+ {
+ .name = LPASS_BE_SLIMBUS_0_RX,
+ .stream_name = "Slimbus Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.16384",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "tasha_codec",
+ .codec_dai_name = "tasha_mix_rx1",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .id = MSM_BACKEND_DAI_SLIMBUS_0_RX,
+ .init = &msm_audrx_tasha_init,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ /* this dainlink has playback support */
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ .ops = &msm_be_ops,
+ },
+ {
+ .name = LPASS_BE_SLIMBUS_0_TX,
+ .stream_name = "Slimbus Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.16385",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "tasha_codec",
+ .codec_dai_name = "tasha_tx1",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .id = MSM_BACKEND_DAI_SLIMBUS_0_TX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ignore_suspend = 1,
+ .ops = &msm_be_ops,
+ },
+ {
+ .name = LPASS_BE_SLIMBUS_1_RX,
+ .stream_name = "Slimbus1 Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.16386",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "tasha_codec",
+ .codec_dai_name = "tasha_mix_rx1",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .id = MSM_BACKEND_DAI_SLIMBUS_1_RX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &msm_be_ops,
+ /* dai link has playback support */
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SLIMBUS_1_TX,
+ .stream_name = "Slimbus1 Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.16387",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "tasha_codec",
+ .codec_dai_name = "tasha_tx3",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .id = MSM_BACKEND_DAI_SLIMBUS_1_TX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &msm_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SLIMBUS_3_RX,
+ .stream_name = "Slimbus3 Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.16390",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "tasha_codec",
+ .codec_dai_name = "tasha_mix_rx1",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .id = MSM_BACKEND_DAI_SLIMBUS_3_RX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &msm_be_ops,
+ /* dai link has playback support */
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SLIMBUS_3_TX,
+ .stream_name = "Slimbus3 Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.16391",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "tasha_codec",
+ .codec_dai_name = "tasha_tx1",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .dpcm_playback = 1,
+ .id = MSM_BACKEND_DAI_SLIMBUS_3_TX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &msm_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SLIMBUS_4_RX,
+ .stream_name = "Slimbus4 Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.16392",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "tasha_codec",
+ .codec_dai_name = "tasha_mix_rx1",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .id = MSM_BACKEND_DAI_SLIMBUS_4_RX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &msm_be_ops,
+ /* dai link has playback support */
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SLIMBUS_5_RX,
+ .stream_name = "Slimbus5 Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.16394",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "tasha_codec",
+ .codec_dai_name = "tasha_rx3",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .id = MSM_BACKEND_DAI_SLIMBUS_5_RX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &msm_be_ops,
+ /* dai link has playback support */
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ },
+ /* MAD BE */
+ {
+ .name = LPASS_BE_SLIMBUS_5_TX,
+ .stream_name = "Slimbus5 Capture",
+ .cpu_dai_name = "msm-dai-q6-dev.16395",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "tasha_codec",
+ .codec_dai_name = "tasha_mad1",
+ .no_pcm = 1,
+ .dpcm_capture = 1,
+ .id = MSM_BACKEND_DAI_SLIMBUS_5_TX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &msm_be_ops,
+ .ignore_suspend = 1,
+ },
+ {
+ .name = LPASS_BE_SLIMBUS_6_RX,
+ .stream_name = "Slimbus6 Playback",
+ .cpu_dai_name = "msm-dai-q6-dev.16396",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "tasha_codec",
+ .codec_dai_name = "tasha_rx4",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .id = MSM_BACKEND_DAI_SLIMBUS_6_RX,
+ .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .ops = &msm_be_ops,
+ /* dai link has playback support */
+ .ignore_pmdown_time = 1,
+ .ignore_suspend = 1,
+ },
+};
+
static struct snd_soc_dai_link msm_wcn_be_dai_links[] = {
{
.name = LPASS_BE_SLIMBUS_7_RX,
@@ -7519,10 +8031,12 @@
ARRAY_SIZE(msm_common_dai_links) +
ARRAY_SIZE(msm_tavil_fe_dai_links) +
ARRAY_SIZE(msm_bolero_fe_dai_links) +
+ ARRAY_SIZE(msm_tasha_fe_dai_links) +
ARRAY_SIZE(msm_common_misc_fe_dai_links) +
ARRAY_SIZE(msm_int_compress_capture_dai) +
ARRAY_SIZE(msm_common_be_dai_links) +
ARRAY_SIZE(msm_tavil_be_dai_links) +
+ ARRAY_SIZE(msm_tasha_be_dai_links) +
ARRAY_SIZE(msm_wcn_be_dai_links) +
ARRAY_SIZE(ext_disp_be_dai_link) +
ARRAY_SIZE(msm_mi2s_be_dai_links) +
@@ -7574,6 +8088,50 @@
return ret;
}
+static int msm_snd_card_tasha_late_probe(struct snd_soc_card *card)
+{
+ const char *be_dl_name = LPASS_BE_SLIMBUS_0_RX;
+ struct snd_soc_pcm_runtime *rtd;
+ struct snd_soc_component *component;
+ int ret = 0;
+ void *mbhc_calibration;
+
+ rtd = snd_soc_get_pcm_runtime(card, be_dl_name);
+ if (!rtd) {
+ dev_err(card->dev,
+ "%s: snd_soc_get_pcm_runtime for %s failed!\n",
+ __func__, be_dl_name);
+ ret = -EINVAL;
+ goto err_pcm_runtime;
+ }
+
+ component = snd_soc_rtdcom_lookup(rtd, "tasha_codec");
+ if (!component) {
+ pr_err("%s: component is NULL\n", __func__);
+ ret = -EINVAL;
+ goto err_pcm_runtime;
+ }
+
+ mbhc_calibration = def_wcd_mbhc_cal();
+ if (!mbhc_calibration) {
+ ret = -ENOMEM;
+ goto err_mbhc_cal;
+ }
+ wcd_mbhc_cfg.calibration = mbhc_calibration;
+ ret = tasha_mbhc_hs_detect(component, &wcd_mbhc_cfg);
+ if (ret) {
+ dev_err(card->dev, "%s: mbhc hs detect failed, err:%d\n",
+ __func__, ret);
+ goto err_hs_detect;
+ }
+ return 0;
+
+err_hs_detect:
+ kfree(mbhc_calibration);
+err_mbhc_cal:
+err_pcm_runtime:
+ return ret;
+}
static int msm_populate_dai_link_component_of_node(
struct snd_soc_card *card)
@@ -7667,8 +8225,8 @@
struct snd_soc_component *component =
snd_soc_rtdcom_lookup(rtd, "msm-stub-codec");
- ret = snd_soc_add_component_controls(component, msm_tavil_snd_controls,
- ARRAY_SIZE(msm_tavil_snd_controls));
+ ret = snd_soc_add_component_controls(component, msm_ext_snd_controls,
+ ARRAY_SIZE(msm_ext_snd_controls));
if (ret < 0) {
dev_err(component->dev,
"%s: add_codec_controls failed, err = %d\n",
@@ -7798,6 +8356,7 @@
u32 mi2s_audio_intf = 0, ext_disp_audio_intf = 0;
u32 wcn_btfm_intf = 0;
const struct of_device_id *match;
+ u32 tasha_codec = 0;
match = of_match_node(sm6150_asoc_machine_of_match, dev->of_node);
if (!match) {
@@ -7822,22 +8381,33 @@
rc = of_property_read_u32(dev->of_node, "qcom,tavil_codec",
&tavil_codec);
- if (rc) {
+ if (rc)
dev_dbg(dev, "%s: No DT match for tavil codec\n",
__func__);
- } else {
- if (tavil_codec) {
- card->late_probe =
- msm_snd_card_tavil_late_probe;
- memcpy(msm_sm6150_dai_links + total_links,
- msm_tavil_fe_dai_links,
- sizeof(msm_tavil_fe_dai_links));
- total_links +=
- ARRAY_SIZE(msm_tavil_fe_dai_links);
- }
- }
- if (!tavil_codec) {
+ rc = of_property_read_u32(dev->of_node, "qcom,tasha_codec",
+ &tasha_codec);
+ if (rc)
+ dev_dbg(dev, "%s: No DT match for tasha codec\n",
+ __func__);
+
+ if (tavil_codec) {
+ card->late_probe =
+ msm_snd_card_tavil_late_probe;
+ memcpy(msm_sm6150_dai_links + total_links,
+ msm_tavil_fe_dai_links,
+ sizeof(msm_tavil_fe_dai_links));
+ total_links +=
+ ARRAY_SIZE(msm_tavil_fe_dai_links);
+ } else if (tasha_codec) {
+ card->late_probe =
+ msm_snd_card_tasha_late_probe;
+ memcpy(msm_sm6150_dai_links + total_links,
+ msm_tasha_fe_dai_links,
+ sizeof(msm_tasha_fe_dai_links));
+ total_links +=
+ ARRAY_SIZE(msm_tasha_fe_dai_links);
+ } else {
memcpy(msm_sm6150_dai_links + total_links,
msm_bolero_fe_dai_links,
sizeof(msm_bolero_fe_dai_links));
@@ -7862,6 +8432,11 @@
msm_tavil_be_dai_links,
sizeof(msm_tavil_be_dai_links));
total_links += ARRAY_SIZE(msm_tavil_be_dai_links);
+ } else if (tasha_codec) {
+ memcpy(msm_sm6150_dai_links + total_links,
+ msm_tasha_be_dai_links,
+ sizeof(msm_tasha_be_dai_links));
+ total_links += ARRAY_SIZE(msm_tasha_be_dai_links);
} else {
memcpy(msm_sm6150_dai_links + total_links,
msm_wsa_cdc_dma_be_dai_links,
@@ -8196,7 +8771,8 @@
__func__, found);
codec_aux_dev:
- if (strcmp(card->name, "sm6150-tavil-snd-card")) {
+ if (!strnstr(card->name, "tavil", strlen(card->name)) &&
+ !strnstr(card->name, "tasha", strlen(card->name))) {
/* Get maximum aux codec device count for this platform */
ret = of_property_read_u32(pdev->dev.of_node,
"qcom,codec-max-aux-devs",
@@ -8431,7 +9007,8 @@
goto err;
}
- if (!strcmp(card->name, "sm6150-tavil-snd-card")) {
+ if (strnstr(card->name, "tavil", strlen(card->name)) ||
+ strnstr(card->name, "tasha", strlen(card->name))) {
pdata = snd_soc_card_get_drvdata(card);
if (!pdata->is_afe_config_done) {
const char *be_dl_name = LPASS_BE_SLIMBUS_0_RX;
@@ -8481,13 +9058,41 @@
dev_dbg(dev, "%s: setting snd_card to OFFLINE\n", __func__);
snd_soc_card_change_online_state(card, 0);
- if (!strcmp(card->name, "sm6150-tavil-snd-card")) {
+ if (strnstr(card->name, "tavil", strlen(card->name)) ||
+ strnstr(card->name, "tasha", strlen(card->name))) {
pdata = snd_soc_card_get_drvdata(card);
msm_afe_clear_config();
pdata->is_afe_config_done = false;
}
}
+static int msm_ext_prepare_hifi(struct msm_asoc_mach_data *pdata)
+{
+ int ret = 0;
+
+ if (gpio_is_valid(pdata->hph_en1_gpio)) {
+ pr_debug("%s: hph_en1_gpio request %d\n", __func__,
+ pdata->hph_en1_gpio);
+ ret = gpio_request(pdata->hph_en1_gpio, "hph_en1_gpio");
+ if (ret) {
+ pr_err("%s: hph_en1_gpio request failed, ret:%d\n",
+ __func__, ret);
+ goto err;
+ }
+ }
+ if (gpio_is_valid(pdata->hph_en0_gpio)) {
+ pr_debug("%s: hph_en0_gpio request %d\n", __func__,
+ pdata->hph_en0_gpio);
+ ret = gpio_request(pdata->hph_en0_gpio, "hph_en0_gpio");
+ if (ret)
+ pr_err("%s: hph_en0_gpio request failed, ret:%d\n",
+ __func__, ret);
+ }
+
+err:
+ return ret;
+}
+
static const struct snd_event_ops sm6150_ssr_ops = {
.enable = sm6150_ssr_enable,
.disable = sm6150_ssr_disable,
@@ -8589,20 +9194,31 @@
}
dev_info(&pdev->dev, "Sound card %s registered\n", card->name);
- pdata->hph_en1_gpio_p = of_parse_phandle(pdev->dev.of_node,
+ pdata->hph_en1_gpio = of_get_named_gpio(pdev->dev.of_node,
"qcom,hph-en1-gpio", 0);
- if (!pdata->hph_en1_gpio_p) {
- dev_dbg(&pdev->dev, "property %s not detected in node %s\n",
- "qcom,hph-en1-gpio",
- pdev->dev.of_node->full_name);
+ if (!gpio_is_valid(pdata->hph_en1_gpio))
+ pdata->hph_en1_gpio_p = of_parse_phandle(pdev->dev.of_node,
+ "qcom,hph-en1-gpio", 0);
+ if (!gpio_is_valid(pdata->hph_en1_gpio) && (!pdata->hph_en1_gpio_p)) {
+ dev_dbg(&pdev->dev, "property %s not detected in node %s",
+ "qcom,hph-en1-gpio", pdev->dev.of_node->full_name);
}
- pdata->hph_en0_gpio_p = of_parse_phandle(pdev->dev.of_node,
+ pdata->hph_en0_gpio = of_get_named_gpio(pdev->dev.of_node,
"qcom,hph-en0-gpio", 0);
- if (!pdata->hph_en0_gpio_p) {
- dev_dbg(&pdev->dev, "property %s not detected in node %s\n",
- "qcom,hph-en0-gpio",
- pdev->dev.of_node->full_name);
+ if (!gpio_is_valid(pdata->hph_en0_gpio))
+ pdata->hph_en0_gpio_p = of_parse_phandle(pdev->dev.of_node,
+ "qcom,hph-en0-gpio", 0);
+ if (!gpio_is_valid(pdata->hph_en0_gpio) && (!pdata->hph_en0_gpio_p)) {
+ dev_dbg(&pdev->dev, "property %s not detected in node %s",
+ "qcom,hph-en0-gpio", pdev->dev.of_node->full_name);
+ }
+
+ ret = msm_ext_prepare_hifi(pdata);
+ if (ret) {
+ dev_dbg(&pdev->dev, "msm_ext_prepare_hifi failed (%d)\n",
+ ret);
+ ret = 0;
}
ret = of_property_read_string(pdev->dev.of_node,
@@ -8669,7 +9285,8 @@
}
msm_i2s_auxpcm_init(pdev);
- if (strcmp(card->name, "sm6150-tavil-snd-card")) {
+ if (!strnstr(card->name, "tavil", strlen(card->name)) &&
+ !strnstr(card->name, "tasha", strlen(card->name))) {
pdata->dmic01_gpio_p = of_parse_phandle(pdev->dev.of_node,
"qcom,cdc-dmic01-gpios",
0);
diff --git a/dsp/codecs/audio_aac.c b/dsp/codecs/audio_aac.c
index cf3d448..32106e5 100644
--- a/dsp/codecs/audio_aac.c
+++ b/dsp/codecs/audio_aac.c
@@ -3,7 +3,17 @@
*
* Copyright (C) 2008 Google, Inc.
* Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2010-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2010-2019, The Linux Foundation. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
*/
#include <linux/msm_audio_aac.h>
@@ -383,7 +393,7 @@
}
rc = audio_aio_open(audio, file);
if (rc < 0) {
- pr_err("%s: audio_aio_open rc=%d\n",
+ pr_err_ratelimited("%s: audio_aio_open rc=%d\n",
__func__, rc);
goto fail;
}
diff --git a/dsp/codecs/audio_alac.c b/dsp/codecs/audio_alac.c
index ea05d71..f7e0932 100644
--- a/dsp/codecs/audio_alac.c
+++ b/dsp/codecs/audio_alac.c
@@ -1,6 +1,15 @@
// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
*/
#include <linux/types.h>
@@ -290,7 +299,7 @@
}
rc = audio_aio_open(audio, file);
if (rc < 0) {
- pr_err("%s: audio_aio_open rc=%d\n",
+ pr_err_ratelimited("%s: audio_aio_open rc=%d\n",
__func__, rc);
goto fail;
}
diff --git a/dsp/codecs/audio_amrnb.c b/dsp/codecs/audio_amrnb.c
index efec4d2..ea6d02f 100644
--- a/dsp/codecs/audio_amrnb.c
+++ b/dsp/codecs/audio_amrnb.c
@@ -3,7 +3,17 @@
*
* Copyright (C) 2008 Google, Inc.
* Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2017, 2019 The Linux Foundation. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
*/
#include <linux/types.h>
@@ -137,7 +147,7 @@
}
rc = audio_aio_open(audio, file);
if (rc < 0) {
- pr_err("%s: audio_aio_open rc=%d\n",
+ pr_err_ratelimited("%s: audio_aio_open rc=%d\n",
__func__, rc);
goto fail;
}
@@ -178,7 +188,7 @@
if (IS_ERR(audio->dentry))
pr_debug("debugfs_create_file failed\n");
#endif
- pr_info("%s:amrnb decoder open success, session_id = %d\n", __func__,
+ pr_info_ratelimited("%s:amrnb decoder open success, session_id = %d\n", __func__,
audio->ac->session);
return rc;
fail:
diff --git a/dsp/codecs/audio_amrwbplus.c b/dsp/codecs/audio_amrwbplus.c
index d06b054..6cadab7 100644
--- a/dsp/codecs/audio_amrwbplus.c
+++ b/dsp/codecs/audio_amrwbplus.c
@@ -3,7 +3,17 @@
*
* Copyright (C) 2008 Google, Inc.
* Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2010-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2010-2017, 2019 The Linux Foundation. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
*/
#include <linux/msm_audio_amrwbplus.h>
#include <linux/compat.h>
@@ -313,7 +323,7 @@
}
rc = audio_aio_open(audio, file);
if (rc < 0) {
- pr_err("%s: audio_aio_open rc=%d\n",
+ pr_err_ratelimited("%s: audio_aio_open rc=%d\n",
__func__, rc);
goto fail;
}
diff --git a/dsp/codecs/audio_ape.c b/dsp/codecs/audio_ape.c
index 219df40..1e12981 100644
--- a/dsp/codecs/audio_ape.c
+++ b/dsp/codecs/audio_ape.c
@@ -1,5 +1,15 @@
// SPDX-License-Identifier: GPL-2.0-only
-/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
*/
#include <linux/types.h>
@@ -271,7 +281,7 @@
}
rc = audio_aio_open(audio, file);
if (rc < 0) {
- pr_err("%s: audio_aio_open rc=%d\n",
+ pr_err_ratelimited("%s: audio_aio_open rc=%d\n",
__func__, rc);
goto fail;
}
diff --git a/dsp/codecs/audio_evrc.c b/dsp/codecs/audio_evrc.c
index c3bf9b8..48d2652 100644
--- a/dsp/codecs/audio_evrc.c
+++ b/dsp/codecs/audio_evrc.c
@@ -3,7 +3,17 @@
*
* Copyright (C) 2008 Google, Inc.
* Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2017, 2019 The Linux Foundation. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
*/
#include "audio_utils_aio.h"
@@ -94,7 +104,7 @@
}
rc = audio_aio_open(audio, file);
if (rc < 0) {
- pr_err("%s: audio_aio_open rc=%d\n",
+ pr_err_ratelimited("%s: audio_aio_open rc=%d\n",
__func__, rc);
goto fail;
}
diff --git a/dsp/codecs/audio_g711alaw.c b/dsp/codecs/audio_g711alaw.c
index 3dac27d..b4a1d7e 100644
--- a/dsp/codecs/audio_g711alaw.c
+++ b/dsp/codecs/audio_g711alaw.c
@@ -1,5 +1,15 @@
// SPDX-License-Identifier: GPL-2.0-only
-/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2017, 2019 The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
*/
#include <linux/types.h>
@@ -245,7 +255,7 @@
}
rc = audio_aio_open(audio, file);
if (rc < 0) {
- pr_err("%s: audio_aio_open rc=%d\n",
+ pr_err_ratelimited("%s: audio_aio_open rc=%d\n",
__func__, rc);
goto fail;
}
diff --git a/dsp/codecs/audio_g711mlaw.c b/dsp/codecs/audio_g711mlaw.c
index c0102d0..1cf8a97 100644
--- a/dsp/codecs/audio_g711mlaw.c
+++ b/dsp/codecs/audio_g711mlaw.c
@@ -1,5 +1,15 @@
// SPDX-License-Identifier: GPL-2.0-only
-/* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2016-2017, 2019 The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
*/
#include <linux/types.h>
@@ -244,7 +254,7 @@
}
rc = audio_aio_open(audio, file);
if (rc < 0) {
- pr_err("%s: audio_aio_open rc=%d\n",
+ pr_err_ratelimited("%s: audio_aio_open rc=%d\n",
__func__, rc);
goto fail;
}
diff --git a/dsp/codecs/audio_mp3.c b/dsp/codecs/audio_mp3.c
index 47446d3..7228cba 100644
--- a/dsp/codecs/audio_mp3.c
+++ b/dsp/codecs/audio_mp3.c
@@ -3,7 +3,17 @@
*
* Copyright (C) 2008 Google, Inc.
* Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2017, 2019 The Linux Foundation. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
*/
#include "audio_utils_aio.h"
@@ -96,7 +106,7 @@
}
rc = audio_aio_open(audio, file);
if (rc < 0) {
- pr_err("%s: audio_aio_open rc=%d\n",
+ pr_err_ratelimited("%s: audio_aio_open rc=%d\n",
__func__, rc);
goto fail;
}
diff --git a/dsp/codecs/audio_multi_aac.c b/dsp/codecs/audio_multi_aac.c
index fc3f492..2c88ebf 100644
--- a/dsp/codecs/audio_multi_aac.c
+++ b/dsp/codecs/audio_multi_aac.c
@@ -3,7 +3,17 @@
*
* Copyright (C) 2008 Google, Inc.
* Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2011-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2019, The Linux Foundation. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
*/
#include <linux/msm_audio_aac.h>
@@ -437,7 +447,7 @@
}
rc = audio_aio_open(audio, file);
if (rc < 0) {
- pr_err("%s: audio_aio_open rc=%d\n",
+ pr_err_ratelimited("%s: audio_aio_open rc=%d\n",
__func__, rc);
goto fail;
}
diff --git a/dsp/codecs/audio_qcelp.c b/dsp/codecs/audio_qcelp.c
index fcf39f5..7e88cfd 100644
--- a/dsp/codecs/audio_qcelp.c
+++ b/dsp/codecs/audio_qcelp.c
@@ -3,7 +3,17 @@
*
* Copyright (C) 2008 Google, Inc.
* Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2017, 2019 The Linux Foundation. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
*/
#include "audio_utils_aio.h"
@@ -101,7 +111,7 @@
}
rc = audio_aio_open(audio, file);
if (rc < 0) {
- pr_err("%s: audio_aio_open rc=%d\n",
+ pr_err_ratelimited("%s: audio_aio_open rc=%d\n",
__func__, rc);
goto fail;
}
diff --git a/dsp/codecs/audio_utils_aio.c b/dsp/codecs/audio_utils_aio.c
index eabf170..f221635 100644
--- a/dsp/codecs/audio_utils_aio.c
+++ b/dsp/codecs/audio_utils_aio.c
@@ -1,7 +1,17 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (C) 2008 Google, Inc.
* Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2009-2019, The Linux Foundation. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
*/
#include <linux/module.h>
@@ -1335,7 +1345,7 @@
audio->drv_ops.in_flush = audio_aio_async_in_flush;
q6asm_set_io_mode(audio->ac, ASYNC_IO_MODE);
} else {
- pr_err("%s[%pK]:SIO interface not supported\n",
+ pr_err_ratelimited("%s[%pK]:SIO interface not supported\n",
__func__, audio);
rc = -EACCES;
goto fail;
@@ -1548,7 +1558,7 @@
break;
}
default:
- pr_err("%s: Unknown ioctl cmd = %d", __func__, cmd);
+ pr_err_ratelimited("%s: Unknown ioctl cmd = %d", __func__, cmd);
rc = -EINVAL;
}
return rc;
diff --git a/dsp/codecs/audio_wma.c b/dsp/codecs/audio_wma.c
index cdd23ff..66c818d 100644
--- a/dsp/codecs/audio_wma.c
+++ b/dsp/codecs/audio_wma.c
@@ -3,7 +3,17 @@
*
* Copyright (C) 2008 Google, Inc.
* Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2009-2019, The Linux Foundation. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
*/
#include <linux/types.h>
@@ -253,7 +263,7 @@
}
rc = audio_aio_open(audio, file);
if (rc < 0) {
- pr_err("%s: audio_aio_open rc=%d\n",
+ pr_err_ratelimited("%s: audio_aio_open rc=%d\n",
__func__, rc);
goto fail;
}
diff --git a/dsp/codecs/audio_wmapro.c b/dsp/codecs/audio_wmapro.c
index c0a2757..4fc3312 100644
--- a/dsp/codecs/audio_wmapro.c
+++ b/dsp/codecs/audio_wmapro.c
@@ -3,7 +3,17 @@
*
* Copyright (C) 2008 Google, Inc.
* Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2009-2019, The Linux Foundation. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
*/
#include <linux/types.h>
@@ -327,7 +337,7 @@
rc = audio_aio_open(audio, file);
if (rc < 0) {
- pr_err("%s: audio_aio_open rc=%d\n",
+ pr_err_ratelimited("%s: audio_aio_open rc=%d\n",
__func__, rc);
goto fail;
}
diff --git a/dsp/q6adm.c b/dsp/q6adm.c
index 688012f..2a3a47f 100644
--- a/dsp/q6adm.c
+++ b/dsp/q6adm.c
@@ -2784,8 +2784,14 @@
if ((topology == VPM_TX_SM_ECNS_V2_COPP_TOPOLOGY) ||
(topology == VPM_TX_DM_FLUENCE_COPP_TOPOLOGY) ||
- (topology == VPM_TX_DM_RFECNS_COPP_TOPOLOGY))
+ (topology == VPM_TX_DM_RFECNS_COPP_TOPOLOGY)||
+ (topology == VPM_TX_DM_FLUENCE_EF_COPP_TOPOLOGY)) {
+ if ((rate != ADM_CMD_COPP_OPEN_SAMPLE_RATE_8K) &&
+ (rate != ADM_CMD_COPP_OPEN_SAMPLE_RATE_16K) &&
+ (rate != ADM_CMD_COPP_OPEN_SAMPLE_RATE_32K) &&
+ (rate != ADM_CMD_COPP_OPEN_SAMPLE_RATE_48K))
rate = 16000;
+ }
if (topology == VPM_TX_VOICE_SMECNS_V2_COPP_TOPOLOGY)
channel_mode = 1;
@@ -2895,8 +2901,9 @@
open_v8.endpoint_id_2 = 0xFFFF;
open_v8.endpoint_id_3 = 0xFFFF;
- if ((this_adm.ec_ref_rx != -1) &&
- (path != ADM_PATH_PLAYBACK)) {
+ if (((this_adm.ec_ref_rx & AFE_PORT_INVALID) !=
+ AFE_PORT_INVALID) &&
+ (path != ADM_PATH_PLAYBACK)) {
if (this_adm.num_ec_ref_rx_chans != 0) {
open_v8.endpoint_id_2 =
this_adm.ec_ref_rx;
diff --git a/dsp/q6afe.c b/dsp/q6afe.c
index 1b5c94d..7f170ea 100644
--- a/dsp/q6afe.c
+++ b/dsp/q6afe.c
@@ -1,6 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
*/
#include <linux/slab.h>
#include <linux/debugfs.h>
@@ -76,6 +75,11 @@
Q6AFE_MSM_SPKR_FTM_MODE
};
+enum {
+ APTX_AD_48 = 0,
+ APTX_AD_44_1 = 1
+};
+
struct wlock {
struct wakeup_source ws;
};
@@ -460,6 +464,15 @@
schedule_work(&this_afe.afe_spdif_work);
}
+static bool afe_token_is_valid(uint32_t token)
+{
+ if (token >= AFE_MAX_PORTS) {
+ pr_err("%s: token %d is invalid.\n", __func__, token);
+ return false;
+ }
+ return true;
+}
+
static int32_t afe_callback(struct apr_client_data *data, void *priv)
{
if (!data) {
@@ -536,7 +549,10 @@
data->payload_size))
return -EINVAL;
}
- wake_up(&this_afe.wait[data->token]);
+ if (afe_token_is_valid(data->token))
+ wake_up(&this_afe.wait[data->token]);
+ else
+ return -EINVAL;
} else if (data->opcode == AFE_EVENT_MBHC_DETECTION_SW_WA) {
msm_aud_evt_notifier_call_chain(SWR_WAKE_IRQ_EVENT, NULL);
} else if (data->payload_size) {
@@ -572,7 +588,10 @@
case AFE_SVC_CMD_SET_PARAM_V2:
case AFE_PORT_CMD_MOD_EVENT_CFG:
atomic_set(&this_afe.state, 0);
- wake_up(&this_afe.wait[data->token]);
+ if (afe_token_is_valid(data->token))
+ wake_up(&this_afe.wait[data->token]);
+ else
+ return -EINVAL;
break;
case AFE_SERVICE_CMD_REGISTER_RT_PORT_DRIVER:
break;
@@ -584,7 +603,10 @@
break;
case AFE_CMD_ADD_TOPOLOGIES:
atomic_set(&this_afe.state, 0);
- wake_up(&this_afe.wait[data->token]);
+ if (afe_token_is_valid(data->token))
+ wake_up(&this_afe.wait[data->token]);
+ else
+ return -EINVAL;
pr_debug("%s: AFE_CMD_ADD_TOPOLOGIES cmd 0x%x\n",
__func__, payload[1]);
break;
@@ -608,7 +630,10 @@
return 0;
}
atomic_set(&this_afe.state, payload[1]);
- wake_up(&this_afe.wait[data->token]);
+ if (afe_token_is_valid(data->token))
+ wake_up(&this_afe.wait[data->token]);
+ else
+ return -EINVAL;
break;
case AFE_SVC_CMD_EVENT_CFG:
atomic_set(&this_afe.state, payload[1]);
@@ -632,7 +657,10 @@
else
this_afe.mmap_handle = payload[0];
atomic_set(&this_afe.state, 0);
- wake_up(&this_afe.wait[data->token]);
+ if (afe_token_is_valid(data->token))
+ wake_up(&this_afe.wait[data->token]);
+ else
+ return -EINVAL;
} else if (data->opcode == AFE_EVENT_RT_PROXY_PORT_STATUS) {
port_id = (uint16_t)(0x0000FFFF & payload[0]);
} else if (data->opcode == AFE_PORT_MOD_EVENT) {
@@ -3541,6 +3569,29 @@
goto exit;
}
break;
+ case ASM_MEDIA_FMT_APTX_ADAPTIVE:
+ if (!cfg->abr_dec_cfg.is_abr_enabled) {
+ pr_debug("%s: sending aptx adaptive congestion buffer size to dsp\n",
+ __func__);
+ param_hdr.param_id =
+ AFE_DECODER_PARAM_ID_CONGESTION_BUFFER_SIZE;
+ param_hdr.param_size =
+ sizeof(struct avs_dec_congestion_buffer_param_t);
+ dec_buffer_id_param.version = 0;
+ dec_buffer_id_param.max_nr_buffers = 226;
+ dec_buffer_id_param.pre_buffer_size = 226;
+ ret = q6afe_pack_and_set_param_in_band(port_id,
+ q6audio_get_port_index(port_id),
+ param_hdr,
+ (u8 *) &dec_buffer_id_param);
+ if (ret) {
+ pr_err("%s: aptx adaptive congestion buffer size for port 0x%x failed %d\n",
+ __func__, port_id, ret);
+ goto exit;
+ }
+ break;
+ }
+ /* fall through for abr enabled case */
default:
pr_debug("%s:sending AFE_ENCDEC_PARAM_ID_DEC_TO_ENC_COMMUNICATION to DSP payload\n",
__func__);
@@ -3561,7 +3612,7 @@
break;
}
- pr_debug("%s:Sending AFE_API_VERSION_PORT_MEDIA_TYPE to DSP", __func__);
+ pr_debug("%s: Send AFE_API_VERSION_PORT_MEDIA_TYPE to DSP\n", __func__);
param_hdr.module_id = AFE_MODULE_PORT;
param_hdr.param_id = AFE_PARAM_ID_PORT_MEDIA_TYPE;
param_hdr.param_size = sizeof(struct afe_port_media_type_t);
@@ -3575,6 +3626,15 @@
media_type.sample_rate =
cfg->data.sbc_config.sample_rate;
break;
+ case ASM_MEDIA_FMT_APTX_ADAPTIVE:
+ if (!cfg->abr_dec_cfg.is_abr_enabled) {
+ media_type.sample_rate =
+ (cfg->data.aptx_ad_config.sample_rate == APTX_AD_44_1) ?
+ AFE_PORT_SAMPLE_RATE_44_1K :
+ AFE_PORT_SAMPLE_RATE_48K;
+ break;
+ }
+ /* fall through for abr enabled case */
default:
media_type.sample_rate =
afe_config.slim_sch.sample_rate;
@@ -3600,11 +3660,19 @@
goto exit;
}
- if (format != ASM_MEDIA_FMT_SBC && format != ASM_MEDIA_FMT_AAC_V2) {
+ if (format != ASM_MEDIA_FMT_SBC && format != ASM_MEDIA_FMT_AAC_V2 &&
+ format != ASM_MEDIA_FMT_APTX_ADAPTIVE) {
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;
+ }
+
pr_debug("%s: sending AFE_DECODER_PARAM_ID_DEC_MEDIA_FMT to DSP payload\n",
__func__);
param_hdr.module_id = AFE_MODULE_ID_DECODER;
@@ -3623,9 +3691,10 @@
switch (cfg->format) {
case ASM_MEDIA_FMT_AAC_V2:
+ case ASM_MEDIA_FMT_APTX_ADAPTIVE:
param_hdr.param_size = sizeof(struct afe_dec_media_fmt_t);
- pr_debug("%s:send AFE_DECODER_PARAM_ID DEC_MEDIA_FMT to DSP payload\n",
+ pr_debug("%s:send AVS_DECODER_PARAM_ID DEC_MEDIA_FMT to DSP payload\n",
__func__);
param_hdr.param_id = AVS_DECODER_PARAM_ID_DEC_MEDIA_FMT;
dec_media_fmt.dec_media_config = cfg->data;
@@ -3634,7 +3703,7 @@
param_hdr,
(u8 *) &dec_media_fmt);
if (ret) {
- pr_err("%s: AFE_DECODER_PARAM_ID DEC_MEDIA_FMT for port 0x%x failed %d\n",
+ pr_err("%s: AVS_DECODER_PARAM_ID DEC_MEDIA_FMT for port 0x%x failed %d\n",
__func__, port_id, ret);
goto exit;
}
@@ -7282,7 +7351,16 @@
return ret;
}
-
+/**
+ * afe_enable_lpass_core_shared_clock -
+ * Configures the core clk on LPASS.
+ * Need on targets where lpass provides
+ * clocks
+ * @port_id: afe port id
+ * @enable: enable or disable clk
+ *
+ * Returns success or failure of call.
+ */
int afe_enable_lpass_core_shared_clock(u16 port_id, u32 enable)
{
struct afe_param_id_lpass_core_shared_clk_cfg clk_cfg;
@@ -7321,7 +7399,16 @@
mutex_unlock(&this_afe.afe_cmd_lock);
return ret;
}
+EXPORT_SYMBOL(afe_enable_lpass_core_shared_clock);
+/**
+ * q6afe_check_osr_clk_freq -
+ * Gets supported OSR CLK frequencies
+ *
+ * @freq: frequency to check
+ *
+ * Returns success if freq is supported.
+ */
int q6afe_check_osr_clk_freq(u32 freq)
{
int ret = 0;
@@ -7346,6 +7433,7 @@
}
return ret;
}
+EXPORT_SYMBOL(q6afe_check_osr_clk_freq);
int afe_get_sp_th_vi_ftm_data(struct afe_sp_th_vi_get_param *th_vi)
{
diff --git a/include/dsp/apr_audio-v2.h b/include/dsp/apr_audio-v2.h
index 9daebe5..1e643e4 100644
--- a/include/dsp/apr_audio-v2.h
+++ b/include/dsp/apr_audio-v2.h
@@ -254,6 +254,9 @@
/* Sample rate is 16000 Hz.*/
#define ADM_CMD_COPP_OPEN_SAMPLE_RATE_16K 16000
+/* Sample rate is 32000 Hz.*/
+#define ADM_CMD_COPP_OPEN_SAMPLE_RATE_32K 32000
+
/* Sample rate is 48000 Hz.*/
#define ADM_CMD_COPP_OPEN_SAMPLE_RATE_48K 48000
@@ -2477,6 +2480,7 @@
#define AFE_MODULE_AUDIO_DEV_INTERFACE 0x0001020C
#define AFE_PORT_SAMPLE_RATE_8K 8000
#define AFE_PORT_SAMPLE_RATE_16K 16000
+#define AFE_PORT_SAMPLE_RATE_44_1K 44100
#define AFE_PORT_SAMPLE_RATE_48K 48000
#define AFE_PORT_SAMPLE_RATE_96K 96000
#define AFE_PORT_SAMPLE_RATE_176P4K 176400
@@ -3795,6 +3799,7 @@
struct afe_abr_dec_cfg_t {
struct afe_imc_dec_enc_info imc_info;
+ bool is_abr_enabled;
} __packed;
struct afe_abr_enc_cfg_t {
@@ -4437,6 +4442,19 @@
*/
} __packed;
+/*
+ * Payload of the APTX AD decoder configuration parameters in the
+ * #ASM_MEDIA_FMT_APTX_ADAPTIVE media format.
+ */
+struct asm_aptx_ad_dec_cfg_t {
+ uint32_t sample_rate;
+ /*
+ * Number of samples per second.
+ *
+ * @values 0x0(48000Hz), 0x1(44100Hz)
+ */
+} __packed;
+
union afe_enc_config_data {
struct asm_sbc_enc_cfg_t sbc_config;
struct asm_aac_enc_cfg_t aac_config;
@@ -4458,6 +4476,7 @@
struct asm_sbc_dec_cfg_t sbc_config;
struct asm_aac_dec_cfg_v2_t aac_config;
struct asm_mp3_dec_cfg_t mp3_config;
+ struct asm_aptx_ad_dec_cfg_t aptx_ad_config;
};
struct afe_dec_config {
@@ -5082,6 +5101,7 @@
#define VPM_TX_DM_RFECNS_COPP_TOPOLOGY 0x00010F86
#define ADM_CMD_COPP_OPEN_TOPOLOGY_ID_DTS_HPX 0x10015002
#define ADM_CMD_COPP_OPEN_TOPOLOGY_ID_AUDIOSPHERE 0x10028000
+#define VPM_TX_DM_FLUENCE_EF_COPP_TOPOLOGY 0x10000005
/* Memory map regions command payload used by the
* #ASM_CMD_SHARED_MEM_MAP_REGIONS ,#ADM_CMD_SHARED_MEM_MAP_REGIONS
diff --git a/ipc/apr_tal_rpmsg.c b/ipc/apr_tal_rpmsg.c
index 723de56..c8830d1 100644
--- a/ipc/apr_tal_rpmsg.c
+++ b/ipc/apr_tal_rpmsg.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved.
*/
#include <linux/module.h>
@@ -10,6 +10,7 @@
#include <linux/delay.h>
#include <linux/rpmsg.h>
#include <ipc/apr_tal.h>
+#include <linux/of_device.h>
enum apr_channel_state {
APR_CH_DISCONNECTED,
@@ -125,14 +126,13 @@
int rc = 0;
struct apr_svc_ch_dev *apr_ch = NULL;
- if ((clnt != APR_CLIENT_AUDIO) || (dest != APR_DEST_QDSP6) ||
+ if ((clnt != APR_CLIENT_AUDIO) || (dest >= APR_DEST_MAX) ||
(dl != APR_DL_SMD)) {
pr_err("%s: Invalid params, clnt:%d, dest:%d, dl:%d\n",
__func__, clnt, dest, dl);
return NULL;
}
-
- apr_ch = &apr_svc_ch[APR_DL_SMD][APR_DEST_QDSP6][APR_CLIENT_AUDIO];
+ apr_ch = &apr_svc_ch[dl][dest][clnt];
mutex_lock(&apr_ch->m_lock);
if (!apr_ch->handle) {
rc = wait_event_timeout(apr_ch->wait,
@@ -207,24 +207,46 @@
static int apr_tal_rpmsg_probe(struct rpmsg_device *rpdev)
{
struct apr_svc_ch_dev *apr_ch = NULL;
+ int ret = 0;
+ const char* dest;
+
+ ret = of_property_read_string(rpdev->dev.parent->of_node,
+ "mbox-names", &dest);
+
+ if(ret < 0){
+ pr_err("%s no parent source pid found\n", __func__);
+ return -EINVAL;
+ }
if (!strcmp(rpdev->id.name, "apr_audio_svc")) {
dev_info(&rpdev->dev, "%s: Channel[%s] state[Up]\n",
__func__, rpdev->id.name);
-
+ } else {
+ dev_err(&rpdev->dev, "%s, Invalid Channel [%s]\n",
+ __func__, rpdev->id.name);
+ return -EINVAL;
+ }
+ if(strstr(dest, "adsp")) {
apr_ch =
&apr_svc_ch[APR_DL_SMD][APR_DEST_QDSP6][APR_CLIENT_AUDIO];
apr_ch->handle = rpdev;
apr_ch->channel_state = APR_CH_CONNECTED;
dev_set_drvdata(&rpdev->dev, apr_ch);
wake_up(&apr_ch->wait);
+ } else if(strstr(dest, "mpss")) {
+ apr_ch =
+ &apr_svc_ch[APR_DL_SMD][APR_DEST_MODEM][APR_CLIENT_AUDIO];
+ apr_ch->handle = rpdev;
+ apr_ch->channel_state = APR_CH_CONNECTED;
+ dev_set_drvdata(&rpdev->dev, apr_ch);
+ wake_up(&apr_ch->wait);
} else {
- dev_err(&rpdev->dev, "%s, Invalid Channel [%s]\n",
- __func__, rpdev->id.name);
+ dev_err(&rpdev->dev, "%s, unsupported dest %s\n",
+ __func__, dest);
return -EINVAL;
}
- return 0;
+ return ret;
}
static void apr_tal_rpmsg_remove(struct rpmsg_device *rpdev)
diff --git a/ipc/apr_v3.c b/ipc/apr_v3.c
index 7bf4774..4160bee 100644
--- a/ipc/apr_v3.c
+++ b/ipc/apr_v3.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
- * Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2016, 2019 The Linux Foundation. All rights reserved.
*/
#include <linux/types.h>
@@ -13,10 +13,16 @@
#define DEST_ID APR_DEST_MODEM
+/**
+ * apr_get_subsys_state - get modem subsys status
+ *
+ * Returns apr_subsys_state
+ */
enum apr_subsys_state apr_get_subsys_state(void)
{
return apr_get_modem_state();
}
+EXPORT_SYMBOL(apr_get_subsys_state);
void apr_set_subsys_state(void)
{
diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c
index 2235934..f9dbc24 100644
--- a/soc/swr-mstr-ctrl.c
+++ b/soc/swr-mstr-ctrl.c
@@ -1415,6 +1415,195 @@
return ret;
}
+static irqreturn_t swr_mstr_interrupt_v2(int irq, void *dev)
+{
+ struct swr_mstr_ctrl *swrm = dev;
+ u32 value, intr_sts, intr_sts_masked;
+ u32 temp = 0;
+ u32 status, chg_sts, i;
+ u8 devnum = 0;
+ int ret = IRQ_HANDLED;
+ struct swr_device *swr_dev;
+ struct swr_master *mstr = &swrm->master;
+
+ if (unlikely(swrm_lock_sleep(swrm) == false)) {
+ dev_err(swrm->dev, "%s Failed to hold suspend\n", __func__);
+ return IRQ_NONE;
+ }
+
+ mutex_lock(&swrm->reslock);
+ swrm_clk_request(swrm, true);
+ mutex_unlock(&swrm->reslock);
+
+ intr_sts = swr_master_read(swrm, SWRM_INTERRUPT_STATUS);
+ intr_sts_masked = intr_sts & swrm->intr_mask;
+handle_irq:
+ for (i = 0; i < SWRM_INTERRUPT_MAX; i++) {
+ value = intr_sts_masked & (1 << i);
+ if (!value)
+ continue;
+
+ switch (value) {
+ case SWRM_INTERRUPT_STATUS_SLAVE_PEND_IRQ:
+ dev_dbg(swrm->dev, "%s: Trigger irq to slave device\n",
+ __func__);
+ status = swr_master_read(swrm, SWRM_MCP_SLV_STATUS);
+ ret = swrm_find_alert_slave(swrm, status, &devnum);
+ if (ret) {
+ dev_err_ratelimited(swrm->dev,
+ "%s: no slave alert found.spurious interrupt\n",
+ __func__);
+ break;
+ }
+ swrm_cmd_fifo_rd_cmd(swrm, &temp, devnum, 0x0,
+ SWRS_SCP_INT_STATUS_CLEAR_1, 1);
+ swrm_cmd_fifo_wr_cmd(swrm, 0x4, devnum, 0x0,
+ SWRS_SCP_INT_STATUS_CLEAR_1);
+ swrm_cmd_fifo_wr_cmd(swrm, 0x0, devnum, 0x0,
+ SWRS_SCP_INT_STATUS_CLEAR_1);
+
+
+ list_for_each_entry(swr_dev, &mstr->devices, dev_list) {
+ if (swr_dev->dev_num != devnum)
+ continue;
+ if (swr_dev->slave_irq) {
+ do {
+ handle_nested_irq(
+ irq_find_mapping(
+ swr_dev->slave_irq, 0));
+ } while (swr_dev->slave_irq_pending);
+ }
+
+ }
+ break;
+ case SWRM_INTERRUPT_STATUS_NEW_SLAVE_ATTACHED:
+ dev_dbg(swrm->dev, "%s: SWR new slave attached\n",
+ __func__);
+ break;
+ case SWRM_INTERRUPT_STATUS_CHANGE_ENUM_SLAVE_STATUS:
+ status = swr_master_read(swrm, SWRM_MCP_SLV_STATUS);
+ if (status == swrm->slave_status) {
+ dev_dbg(swrm->dev,
+ "%s: No change in slave status: %d\n",
+ __func__, status);
+ break;
+ }
+ chg_sts = swrm_check_slave_change_status(swrm, status,
+ &devnum);
+ switch (chg_sts) {
+ case SWR_NOT_PRESENT:
+ dev_dbg(swrm->dev,
+ "%s: device %d got detached\n",
+ __func__, devnum);
+ break;
+ case SWR_ATTACHED_OK:
+ dev_dbg(swrm->dev,
+ "%s: device %d got attached\n",
+ __func__, devnum);
+ /* enable host irq from slave device*/
+ swrm_cmd_fifo_wr_cmd(swrm, 0xFF, devnum, 0x0,
+ SWRS_SCP_INT_STATUS_CLEAR_1);
+ swrm_cmd_fifo_wr_cmd(swrm, 0x4, devnum, 0x0,
+ SWRS_SCP_INT_STATUS_MASK_1);
+
+ break;
+ case SWR_ALERT:
+ dev_dbg(swrm->dev,
+ "%s: device %d has pending interrupt\n",
+ __func__, devnum);
+ break;
+ }
+ break;
+ case SWRM_INTERRUPT_STATUS_MASTER_CLASH_DET:
+ dev_err_ratelimited(swrm->dev,
+ "%s: SWR bus clsh detected\n",
+ __func__);
+ break;
+ case SWRM_INTERRUPT_STATUS_RD_FIFO_OVERFLOW:
+ dev_dbg(swrm->dev, "%s: SWR read FIFO overflow\n",
+ __func__);
+ break;
+ case SWRM_INTERRUPT_STATUS_RD_FIFO_UNDERFLOW:
+ dev_dbg(swrm->dev, "%s: SWR read FIFO underflow\n",
+ __func__);
+ break;
+ case SWRM_INTERRUPT_STATUS_WR_CMD_FIFO_OVERFLOW:
+ dev_dbg(swrm->dev, "%s: SWR write FIFO overflow\n",
+ __func__);
+ break;
+ case SWRM_INTERRUPT_STATUS_CMD_ERROR:
+ value = swr_master_read(swrm, SWRM_CMD_FIFO_STATUS);
+ dev_err_ratelimited(swrm->dev,
+ "%s: SWR CMD error, fifo status 0x%x, flushing fifo\n",
+ __func__, value);
+ swr_master_write(swrm, SWRM_CMD_FIFO_CMD, 0x1);
+ break;
+ case SWRM_INTERRUPT_STATUS_DOUT_PORT_COLLISION:
+ dev_err_ratelimited(swrm->dev,
+ "%s: SWR Port collision detected\n",
+ __func__);
+ swrm->intr_mask &= ~SWRM_INTERRUPT_STATUS_DOUT_PORT_COLLISION;
+ swr_master_write(swrm,
+ SWR_MSTR_RX_SWRM_CPU_INTERRUPT_EN, swrm->intr_mask);
+ break;
+ case SWRM_INTERRUPT_STATUS_READ_EN_RD_VALID_MISMATCH:
+ dev_dbg(swrm->dev,
+ "%s: SWR read enable valid mismatch\n",
+ __func__);
+ swrm->intr_mask &=
+ ~SWRM_INTERRUPT_STATUS_READ_EN_RD_VALID_MISMATCH;
+ swr_master_write(swrm,
+ SWR_MSTR_RX_SWRM_CPU_INTERRUPT_EN, swrm->intr_mask);
+ break;
+ case SWRM_INTERRUPT_STATUS_SPECIAL_CMD_ID_FINISHED:
+ complete(&swrm->broadcast);
+ dev_dbg(swrm->dev, "%s: SWR cmd id finished\n",
+ __func__);
+ break;
+ case SWRM_INTERRUPT_STATUS_AUTO_ENUM_FAILED_V2:
+ break;
+ case SWRM_INTERRUPT_STATUS_AUTO_ENUM_TABLE_IS_FULL_V2:
+ break;
+ case SWRM_INTERRUPT_STATUS_BUS_RESET_FINISHED_V2:
+ break;
+ case SWRM_INTERRUPT_STATUS_CLK_STOP_FINISHED_V2:
+ break;
+ case SWRM_INTERRUPT_STATUS_EXT_CLK_STOP_WAKEUP:
+ if (swrm->state == SWR_MSTR_UP)
+ dev_dbg(swrm->dev,
+ "%s:SWR Master is already up\n",
+ __func__);
+ else
+ dev_err_ratelimited(swrm->dev,
+ "%s: SWR wokeup during clock stop\n",
+ __func__);
+ break;
+ default:
+ dev_err_ratelimited(swrm->dev,
+ "%s: SWR unknown interrupt value: %d\n",
+ __func__, value);
+ ret = IRQ_NONE;
+ break;
+ }
+ }
+ swr_master_write(swrm, SWRM_INTERRUPT_CLEAR, intr_sts);
+ swr_master_write(swrm, SWRM_INTERRUPT_CLEAR, 0x0);
+
+ intr_sts = swr_master_read(swrm, SWRM_INTERRUPT_STATUS);
+ intr_sts_masked = intr_sts & swrm->intr_mask;
+
+ if (intr_sts_masked) {
+ dev_dbg(swrm->dev, "%s: new interrupt received\n", __func__);
+ goto handle_irq;
+ }
+
+ mutex_lock(&swrm->reslock);
+ swrm_clk_request(swrm, false);
+ mutex_unlock(&swrm->reslock);
+ swrm_unlock_sleep(swrm);
+ return ret;
+}
+
static irqreturn_t swrm_wakeup_interrupt(int irq, void *dev)
{
struct swr_mstr_ctrl *swrm = dev;
@@ -1899,7 +2088,7 @@
}
ret = request_threaded_irq(swrm->irq, NULL,
- swr_mstr_interrupt,
+ swr_mstr_interrupt_v2,
IRQF_TRIGGER_RISING | IRQF_ONESHOT,
"swr_master_irq", swrm);
if (ret) {
diff --git a/soc/swrm_registers.h b/soc/swrm_registers.h
index c53d37b..6f2544b 100644
--- a/soc/swrm_registers.h
+++ b/soc/swrm_registers.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
- * Copyright (c) 2015, 2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2015, 2018-2019 The Linux Foundation. All rights reserved.
*/
#ifndef _SWRM_REGISTERS_H
@@ -49,6 +49,13 @@
#define SWRM_INTERRUPT_STATUS_CLK_STOP_FINISHED 0x8000
#define SWRM_INTERRUPT_STATUS_ERROR_PORT_TEST 0x10000
+#define SWRM_INTERRUPT_STATUS_AUTO_ENUM_FAILED_V2 0x800
+#define SWRM_INTERRUPT_STATUS_AUTO_ENUM_TABLE_IS_FULL_V2 0x1000
+#define SWRM_INTERRUPT_STATUS_BUS_RESET_FINISHED_V2 0x2000
+#define SWRM_INTERRUPT_STATUS_CLK_STOP_FINISHED_V2 0x4000
+#define SWRM_INTERRUPT_STATUS_ERROR_PORT_TEST_V2 0x8000
+#define SWRM_INTERRUPT_STATUS_EXT_CLK_STOP_WAKEUP 0x10000
+
#define SWRM_INTERRUPT_MASK_ADDR (SWRM_BASE_ADDRESS+0x00000204)
#define SWRM_INTERRUPT_MASK_RMSK 0x1FFFF