Merge "asoc: codecs: bolero: suspend swr at VA use case switch"
diff --git a/asoc/bengal-port-config.h b/asoc/bengal-port-config.h
index 9989963..4ac7e10 100644
--- a/asoc/bengal-port-config.h
+++ b/asoc/bengal-port-config.h
@@ -37,7 +37,7 @@
};
static struct swr_mstr_port_map sm_port_map[] = {
- {TX_MACRO, SWR_UC0, tx_frame_params_default},
+ {VA_MACRO, SWR_UC0, tx_frame_params_default},
{RX_MACRO, SWR_UC0, rx_frame_params_default},
{RX_MACRO, SWR_UC1, rx_frame_params_dsd},
};
diff --git a/asoc/codecs/bolero/bolero-cdc-registers.h b/asoc/codecs/bolero/bolero-cdc-registers.h
index 99890cc..c59bb86 100644
--- a/asoc/codecs/bolero/bolero-cdc-registers.h
+++ b/asoc/codecs/bolero/bolero-cdc-registers.h
@@ -696,6 +696,7 @@
#define BOLERO_CDC_VA_CLK_RST_CTRL_MCLK_CONTROL (VA_START_OFFSET + 0x0000)
#define BOLERO_CDC_VA_CLK_RST_CTRL_FS_CNT_CONTROL \
(VA_START_OFFSET + 0x0004)
+#define BOLERO_CDC_VA_CLK_RST_CTRL_SWR_CONTROL (VA_START_OFFSET + 0x0008)
#define BOLERO_CDC_VA_TOP_CSR_TOP_CFG0 (VA_START_OFFSET + 0x0080)
#define BOLERO_CDC_VA_TOP_CSR_DMIC0_CTL (VA_START_OFFSET + 0x0084)
#define BOLERO_CDC_VA_TOP_CSR_DMIC1_CTL (VA_START_OFFSET + 0x0088)
diff --git a/asoc/codecs/bolero/bolero-cdc-regmap.c b/asoc/codecs/bolero/bolero-cdc-regmap.c
index 037f9aa..9082966 100644
--- a/asoc/codecs/bolero/bolero-cdc-regmap.c
+++ b/asoc/codecs/bolero/bolero-cdc-regmap.c
@@ -609,6 +609,7 @@
/* VA macro */
{ BOLERO_CDC_VA_CLK_RST_CTRL_MCLK_CONTROL, 0x00},
{ BOLERO_CDC_VA_CLK_RST_CTRL_FS_CNT_CONTROL, 0x00},
+ { BOLERO_CDC_VA_CLK_RST_CTRL_SWR_CONTROL, 0x00},
{ BOLERO_CDC_VA_TOP_CSR_TOP_CFG0, 0x00},
{ BOLERO_CDC_VA_TOP_CSR_DMIC0_CTL, 0x00},
{ BOLERO_CDC_VA_TOP_CSR_DMIC1_CTL, 0x00},
diff --git a/asoc/codecs/bolero/bolero-cdc-tables.c b/asoc/codecs/bolero/bolero-cdc-tables.c
index 5298763..81639b3 100644
--- a/asoc/codecs/bolero/bolero-cdc-tables.c
+++ b/asoc/codecs/bolero/bolero-cdc-tables.c
@@ -442,6 +442,7 @@
u8 bolero_va_reg_access[BOLERO_CDC_VA_MACRO_MAX] = {
[BOLERO_REG(BOLERO_CDC_VA_CLK_RST_CTRL_MCLK_CONTROL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_CLK_RST_CTRL_FS_CNT_CONTROL)] = RD_WR_REG,
+ [BOLERO_REG(BOLERO_CDC_VA_CLK_RST_CTRL_SWR_CONTROL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_TOP_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DMIC0_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DMIC1_CTL)] = RD_WR_REG,
@@ -567,6 +568,7 @@
u8 bolero_va_top_reg_access[BOLERO_CDC_VA_MACRO_TOP_MAX] = {
[BOLERO_REG(BOLERO_CDC_VA_CLK_RST_CTRL_MCLK_CONTROL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_CLK_RST_CTRL_FS_CNT_CONTROL)] = RD_WR_REG,
+ [BOLERO_REG(BOLERO_CDC_VA_CLK_RST_CTRL_SWR_CONTROL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_TOP_CFG0)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DMIC0_CTL)] = RD_WR_REG,
[BOLERO_REG(BOLERO_CDC_VA_TOP_CSR_DMIC1_CTL)] = RD_WR_REG,
diff --git a/asoc/codecs/bolero/bolero-cdc-utils.c b/asoc/codecs/bolero/bolero-cdc-utils.c
index b2fd153..f2e4ec4 100644
--- a/asoc/codecs/bolero/bolero-cdc-utils.c
+++ b/asoc/codecs/bolero/bolero-cdc-utils.c
@@ -68,12 +68,9 @@
reg_p = (u16 *)reg;
macro_id = bolero_get_macro_id(priv->va_without_decimation,
reg_p[0]);
- if (macro_id < 0 || !priv->macros_supported[macro_id]) {
- dev_err_ratelimited(dev,
- "%s: Unsupported macro %d or reg 0x%x is invalid\n",
- __func__, macro_id, reg_p[0]);
- return ret;
- }
+ if (macro_id < 0 || !priv->macros_supported[macro_id])
+ return 0;
+
mutex_lock(&priv->io_lock);
for (i = 0; i < val_size; i++) {
__reg = (reg_p[0] + i * 4) - macro_id_base_offset[macro_id];
@@ -121,12 +118,9 @@
reg_p = (u16 *)reg;
macro_id = bolero_get_macro_id(priv->va_without_decimation,
reg_p[0]);
- if (macro_id < 0 || !priv->macros_supported[macro_id]) {
- dev_err_ratelimited(dev,
- "%s: Unsupported macro-id %d or reg 0x%x is invalid\n",
- __func__, macro_id, reg_p[0]);
- return ret;
- }
+ if (macro_id < 0 || !priv->macros_supported[macro_id])
+ return 0;
+
mutex_lock(&priv->io_lock);
for (i = 0; i < val_size; i++) {
__reg = (reg_p[0] + i * 4) - macro_id_base_offset[macro_id];
diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c
index fdf0445..dde4719 100644
--- a/asoc/codecs/bolero/bolero-cdc.c
+++ b/asoc/codecs/bolero/bolero-cdc.c
@@ -20,9 +20,6 @@
#define DRV_NAME "bolero_codec"
-#define BOLERO_VERSION_1_0 0x0001
-#define BOLERO_VERSION_1_1 0x0002
-#define BOLERO_VERSION_1_2 0x0003
#define BOLERO_VERSION_ENTRY_SIZE 32
#define BOLERO_CDC_STRING_LEN 80
@@ -214,6 +211,12 @@
priv->component,
BOLERO_MACRO_EVT_RX_COMPANDER_SOFT_RST, data);
break;
+ case WCD_BOLERO_EVT_BCS_CLK_OFF:
+ if (priv->macro_params[TX_MACRO].event_handler)
+ priv->macro_params[TX_MACRO].event_handler(
+ priv->component,
+ BOLERO_MACRO_EVT_BCS_CLK_OFF, data);
+ break;
default:
dev_err(priv->dev, "%s: Invalid event %d trigger from wcd\n",
__func__, event);
@@ -507,11 +510,17 @@
priv->macro_params[macro_id].reg_evt_listener =
ops->reg_evt_listener;
}
-
+ if (priv->version == BOLERO_VERSION_2_1) {
+ if (macro_id == VA_MACRO)
+ priv->macro_params[macro_id].reg_wake_irq =
+ ops->reg_wake_irq;
+ }
priv->num_dais += ops->num_dais;
priv->num_macros_registered++;
priv->macros_supported[macro_id] = true;
+ dev_dbg(dev, "%s: register macro successful:%d\n", macro_id);
+
if (priv->num_macros_registered == priv->num_macros) {
ret = bolero_copy_dais_from_macro(priv);
if (ret < 0) {
@@ -604,6 +613,28 @@
}
EXPORT_SYMBOL(bolero_wsa_pa_on);
+int bolero_get_version(struct device *dev)
+{
+ struct bolero_priv *priv;
+
+ if (!dev) {
+ pr_err("%s: dev is null\n", __func__);
+ return -EINVAL;
+ }
+ if (!bolero_is_valid_child_dev(dev)) {
+ dev_err(dev, "%s: child device for macro not added yet\n",
+ __func__);
+ return -EINVAL;
+ }
+ priv = dev_get_drvdata(dev->parent);
+ if (!priv) {
+ dev_err(dev, "%s: priv is null\n", __func__);
+ return -EINVAL;
+ }
+ return priv->version;
+}
+EXPORT_SYMBOL(bolero_get_version);
+
static ssize_t bolero_version_read(struct snd_info_entry *entry,
void *file_private_data,
struct file *file,
@@ -630,6 +661,9 @@
case BOLERO_VERSION_1_2:
len = snprintf(buffer, sizeof(buffer), "BOLERO_1_2\n");
break;
+ case BOLERO_VERSION_2_1:
+ len = snprintf(buffer, sizeof(buffer), "BOLERO_2_1\n");
+ break;
default:
len = snprintf(buffer, sizeof(buffer), "VER_UNDEFINED\n");
}
@@ -794,9 +828,15 @@
return -EINVAL;
}
- if (priv->macro_params[TX_MACRO].reg_wake_irq)
- priv->macro_params[TX_MACRO].reg_wake_irq(
- component, ipc_wakeup);
+ if (priv->version == BOLERO_VERSION_2_1) {
+ if (priv->macro_params[VA_MACRO].reg_wake_irq)
+ priv->macro_params[VA_MACRO].reg_wake_irq(
+ component, ipc_wakeup);
+ } else {
+ if (priv->macro_params[TX_MACRO].reg_wake_irq)
+ priv->macro_params[TX_MACRO].reg_wake_irq(
+ component, ipc_wakeup);
+ }
return 0;
}
@@ -875,6 +915,29 @@
snd_soc_component_init_regmap(component, priv->regmap);
+ if (!priv->version) {
+ /*
+ * In order for the ADIE RTC to differentiate between targets
+ * version info is used.
+ * Assign 1.0 for target with only one macro
+ * Assign 1.1 for target with two macros
+ * Assign 1.2 for target with more than two macros
+ */
+ if (priv->num_macros_registered == 1)
+ priv->version = BOLERO_VERSION_1_0;
+ else if (priv->num_macros_registered == 2)
+ priv->version = BOLERO_VERSION_1_1;
+ else if (priv->num_macros_registered > 2)
+ priv->version = BOLERO_VERSION_1_2;
+ }
+
+ /* Assign bolero version 2.1 for bolero 2.1 */
+ if ((snd_soc_component_read32(component,
+ BOLERO_CDC_VA_TOP_CSR_CORE_ID_0) == 0x2) &&
+ (snd_soc_component_read32(component,
+ BOLERO_CDC_VA_TOP_CSR_CORE_ID_1) == 0xE))
+ priv->version = BOLERO_VERSION_2_1;
+
/* call init for supported macros */
for (macro_idx = START_MACRO; macro_idx < MAX_MACRO; macro_idx++) {
if (priv->macro_params[macro_idx].init) {
@@ -888,19 +951,6 @@
}
}
priv->component = component;
- /*
- * In order for the ADIE RTC to differentiate between targets
- * version info is used.
- * Assign 1.0 for target with only one macro
- * Assign 1.1 for target with two macros
- * Assign 1.2 for target with more than two macros
- */
- if (priv->num_macros_registered == 1)
- priv->version = BOLERO_VERSION_1_0;
- else if (priv->num_macros_registered == 2)
- priv->version = BOLERO_VERSION_1_1;
- else if (priv->num_macros_registered > 2)
- priv->version = BOLERO_VERSION_1_2;
ret = snd_event_client_register(priv->dev, &bolero_ssr_ops, priv);
if (!ret) {
@@ -1044,6 +1094,13 @@
if (priv->va_without_decimation)
bolero_reg_access[VA_MACRO] = bolero_va_top_reg_access;
+ ret = of_property_read_u32(pdev->dev.of_node,
+ "qcom,bolero-version", &priv->version);
+ if (ret) {
+ dev_dbg(&pdev->dev, "%s:bolero version not specified\n",
+ __func__);
+ ret = 0;
+ }
priv->dev = &pdev->dev;
priv->dev_up = true;
priv->initial_boot = true;
diff --git a/asoc/codecs/bolero/bolero-cdc.h b/asoc/codecs/bolero/bolero-cdc.h
index f104f88..2ec4617 100644
--- a/asoc/codecs/bolero/bolero-cdc.h
+++ b/asoc/codecs/bolero/bolero-cdc.h
@@ -8,6 +8,12 @@
#include <sound/soc.h>
#include <linux/regmap.h>
+#define BOLERO_VERSION_1_0 0x0001
+#define BOLERO_VERSION_1_1 0x0002
+#define BOLERO_VERSION_1_2 0x0003
+#define BOLERO_VERSION_2_0 0x0004
+#define BOLERO_VERSION_2_1 0x0005
+
enum {
START_MACRO,
TX_MACRO = START_MACRO,
@@ -40,7 +46,8 @@
BOLERO_MACRO_EVT_WAIT_VA_CLK_RESET,
BOLERO_MACRO_EVT_CLK_RESET,
BOLERO_MACRO_EVT_REG_WAKE_IRQ,
- BOLERO_MACRO_EVT_RX_COMPANDER_SOFT_RST
+ BOLERO_MACRO_EVT_RX_COMPANDER_SOFT_RST,
+ BOLERO_MACRO_EVT_BCS_CLK_OFF
};
struct macro_ops {
@@ -85,6 +92,7 @@
bool enable);
void bolero_wsa_pa_on(struct device *dev);
bool bolero_check_core_votes(struct device *dev);
+int bolero_get_version(struct device *dev);
#else
static inline int bolero_register_res_clk(struct device *dev, rsc_clk_cb_t cb)
{
@@ -164,5 +172,10 @@
{
return false;
}
+
+static int bolero_get_version(struct device *dev)
+{
+ return 0;
+}
#endif /* CONFIG_SND_SOC_BOLERO */
#endif /* BOLERO_CDC_H */
diff --git a/asoc/codecs/bolero/internal.h b/asoc/codecs/bolero/internal.h
index d3f6894..ba89832 100644
--- a/asoc/codecs/bolero/internal.h
+++ b/asoc/codecs/bolero/internal.h
@@ -31,6 +31,7 @@
WCD_BOLERO_EVT_IMPED_TRUE, /* for imped true */
WCD_BOLERO_EVT_IMPED_FALSE, /* for imped false */
WCD_BOLERO_EVT_RX_COMPANDER_SOFT_RST,
+ WCD_BOLERO_EVT_BCS_CLK_OFF,
};
struct wcd_ctrl_platform_data {
diff --git a/asoc/codecs/bolero/rx-macro.c b/asoc/codecs/bolero/rx-macro.c
index ec71d4a..ffcd734 100644
--- a/asoc/codecs/bolero/rx-macro.c
+++ b/asoc/codecs/bolero/rx-macro.c
@@ -1350,10 +1350,8 @@
goto done;
reg = BOLERO_CDC_RX_COMPANDER0_CTL0 +
(rx_idx * RX_MACRO_COMP_OFFSET);
- snd_soc_component_update_bits(component, reg,
- 0x20, 0x20);
- snd_soc_component_update_bits(component, reg,
- 0x20, 0x00);
+ snd_soc_component_write(component, reg,
+ snd_soc_component_read32(component, reg));
break;
case BOLERO_MACRO_EVT_IMPED_TRUE:
rx_macro_wcd_clsh_imped_config(component, data, true);
diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c
index ca88bfa..d27a5cf 100644
--- a/asoc/codecs/bolero/tx-macro.c
+++ b/asoc/codecs/bolero/tx-macro.c
@@ -160,6 +160,8 @@
s32 dmic_4_5_clk_cnt;
s32 dmic_6_7_clk_cnt;
u16 dmic_clk_div;
+ u32 version;
+ u32 is_used_tx_swr_gpio;
unsigned long active_ch_mask[TX_MACRO_MAX_DAIS];
unsigned long active_ch_cnt[TX_MACRO_MAX_DAIS];
char __iomem *tx_io_base;
@@ -172,6 +174,8 @@
int tx_clk_status;
bool bcs_enable;
int dec_mode[NUM_DECIMATORS];
+ bool bcs_clk_en;
+ bool hs_slow_insert_complete;
};
static bool tx_macro_get_data(struct snd_soc_component *component,
@@ -387,6 +391,15 @@
case BOLERO_MACRO_EVT_CLK_RESET:
bolero_rsc_clk_reset(tx_dev, TX_CORE_CLK);
break;
+ case BOLERO_MACRO_EVT_BCS_CLK_OFF:
+ if (tx_priv->bcs_clk_en)
+ snd_soc_component_update_bits(component,
+ BOLERO_CDC_TX0_TX_PATH_SEC7, 0x40, data << 6);
+ if (data)
+ tx_priv->hs_slow_insert_complete = true;
+ else
+ tx_priv->hs_slow_insert_complete = false;
+ break;
}
return 0;
}
@@ -450,10 +463,10 @@
snd_soc_component_update_bits(component,
dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK,
hpf_cut_off_freq << 5);
- snd_soc_component_update_bits(component, hpf_gate_reg, 0x03, 0x02);
+ snd_soc_component_update_bits(component, hpf_gate_reg, 0x02, 0x02);
/* Minimum 1 clk cycle delay is required as per HW spec */
usleep_range(1000, 1010);
- snd_soc_component_update_bits(component, hpf_gate_reg, 0x03, 0x01);
+ snd_soc_component_update_bits(component, hpf_gate_reg, 0x02, 0x00);
}
static void tx_macro_mute_update_callback(struct work_struct *work)
@@ -865,6 +878,10 @@
tx_vol_ctl_reg, 0x20, 0x20);
snd_soc_component_update_bits(component,
hpf_gate_reg, 0x01, 0x00);
+ /*
+ * Minimum 1 clk cycle delay is required as per HW spec
+ */
+ usleep_range(1000, 1010);
hpf_cut_off_freq = (
snd_soc_component_read32(component, dec_cfg_reg) &
@@ -887,7 +904,7 @@
&tx_priv->tx_hpf_work[decimator].dwork,
msecs_to_jiffies(300));
snd_soc_component_update_bits(component,
- hpf_gate_reg, 0x02, 0x02);
+ hpf_gate_reg, 0x03, 0x03);
/*
* Minimum 1 clk cycle delay is required as per HW spec
*/
@@ -902,8 +919,11 @@
if (tx_priv->bcs_enable) {
snd_soc_component_update_bits(component, dec_cfg_reg,
0x01, 0x01);
- snd_soc_component_update_bits(component,
- BOLERO_CDC_TX0_TX_PATH_SEC7, 0x40, 0x40);
+ tx_priv->bcs_clk_en = true;
+ if (tx_priv->hs_slow_insert_complete)
+ snd_soc_component_update_bits(component,
+ BOLERO_CDC_TX0_TX_PATH_SEC7, 0x40,
+ 0x40);
}
break;
case SND_SOC_DAPM_PRE_PMD:
@@ -946,6 +966,7 @@
0x01, 0x00);
snd_soc_component_update_bits(component,
BOLERO_CDC_TX0_TX_PATH_SEC7, 0x40, 0x00);
+ tx_priv->bcs_clk_en = false;
}
break;
}
@@ -1210,6 +1231,44 @@
0, smic_mux_text, snd_soc_dapm_get_enum_double,
tx_macro_put_dec_enum);
+static const char * const smic_mux_text_v2[] = {
+ "ZERO", "SWR_MIC0", "SWR_MIC1", "SWR_MIC2", "SWR_MIC3",
+ "SWR_MIC4", "SWR_MIC5", "SWR_MIC6", "SWR_MIC7",
+ "SWR_MIC8", "SWR_MIC9", "SWR_MIC10", "SWR_MIC11"
+};
+
+TX_MACRO_DAPM_ENUM_EXT(tx_smic0_v2, BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG0,
+ 0, smic_mux_text_v2, snd_soc_dapm_get_enum_double,
+ tx_macro_put_dec_enum);
+
+TX_MACRO_DAPM_ENUM_EXT(tx_smic1_v2, BOLERO_CDC_TX_INP_MUX_ADC_MUX1_CFG0,
+ 0, smic_mux_text_v2, snd_soc_dapm_get_enum_double,
+ tx_macro_put_dec_enum);
+
+TX_MACRO_DAPM_ENUM_EXT(tx_smic2_v2, BOLERO_CDC_TX_INP_MUX_ADC_MUX2_CFG0,
+ 0, smic_mux_text_v2, snd_soc_dapm_get_enum_double,
+ tx_macro_put_dec_enum);
+
+TX_MACRO_DAPM_ENUM_EXT(tx_smic3_v2, BOLERO_CDC_TX_INP_MUX_ADC_MUX3_CFG0,
+ 0, smic_mux_text_v2, snd_soc_dapm_get_enum_double,
+ tx_macro_put_dec_enum);
+
+TX_MACRO_DAPM_ENUM_EXT(tx_smic4_v3, BOLERO_CDC_TX_INP_MUX_ADC_MUX4_CFG0,
+ 0, smic_mux_text_v2, snd_soc_dapm_get_enum_double,
+ tx_macro_put_dec_enum);
+
+TX_MACRO_DAPM_ENUM_EXT(tx_smic5_v3, BOLERO_CDC_TX_INP_MUX_ADC_MUX5_CFG0,
+ 0, smic_mux_text_v2, snd_soc_dapm_get_enum_double,
+ tx_macro_put_dec_enum);
+
+TX_MACRO_DAPM_ENUM_EXT(tx_smic6_v3, BOLERO_CDC_TX_INP_MUX_ADC_MUX6_CFG0,
+ 0, smic_mux_text_v2, snd_soc_dapm_get_enum_double,
+ tx_macro_put_dec_enum);
+
+TX_MACRO_DAPM_ENUM_EXT(tx_smic7_v3, BOLERO_CDC_TX_INP_MUX_ADC_MUX7_CFG0,
+ 0, smic_mux_text_v2, snd_soc_dapm_get_enum_double,
+ tx_macro_put_dec_enum);
+
static const char * const dec_mode_mux_text[] = {
"ADC_DEFAULT", "ADC_LOW_PWR", "ADC_HIGH_PERF",
};
@@ -1275,6 +1334,205 @@
tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
};
+static const struct snd_kcontrol_new tx_aif1_cap_mixer_v2[] = {
+ SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, TX_MACRO_DEC0, 1, 0,
+ tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
+ SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, TX_MACRO_DEC1, 1, 0,
+ tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
+ SOC_SINGLE_EXT("DEC2", SND_SOC_NOPM, TX_MACRO_DEC2, 1, 0,
+ tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
+ SOC_SINGLE_EXT("DEC3", SND_SOC_NOPM, TX_MACRO_DEC3, 1, 0,
+ tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
+};
+
+static const struct snd_kcontrol_new tx_aif2_cap_mixer_v2[] = {
+ SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, TX_MACRO_DEC0, 1, 0,
+ tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
+ SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, TX_MACRO_DEC1, 1, 0,
+ tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
+ SOC_SINGLE_EXT("DEC2", SND_SOC_NOPM, TX_MACRO_DEC2, 1, 0,
+ tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
+ SOC_SINGLE_EXT("DEC3", SND_SOC_NOPM, TX_MACRO_DEC3, 1, 0,
+ tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
+};
+
+static const struct snd_kcontrol_new tx_aif3_cap_mixer_v2[] = {
+ SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, TX_MACRO_DEC0, 1, 0,
+ tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
+ SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, TX_MACRO_DEC1, 1, 0,
+ tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
+ SOC_SINGLE_EXT("DEC2", SND_SOC_NOPM, TX_MACRO_DEC2, 1, 0,
+ tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
+ SOC_SINGLE_EXT("DEC3", SND_SOC_NOPM, TX_MACRO_DEC3, 1, 0,
+ tx_macro_tx_mixer_get, tx_macro_tx_mixer_put),
+};
+
+static const struct snd_soc_dapm_widget tx_macro_dapm_widgets_common[] = {
+ SND_SOC_DAPM_AIF_OUT("TX_AIF1 CAP", "TX_AIF1 Capture", 0,
+ SND_SOC_NOPM, TX_MACRO_AIF1_CAP, 0),
+
+ SND_SOC_DAPM_AIF_OUT("TX_AIF2 CAP", "TX_AIF2 Capture", 0,
+ SND_SOC_NOPM, TX_MACRO_AIF2_CAP, 0),
+
+ SND_SOC_DAPM_AIF_OUT("TX_AIF3 CAP", "TX_AIF3 Capture", 0,
+ SND_SOC_NOPM, TX_MACRO_AIF3_CAP, 0),
+
+ TX_MACRO_DAPM_MUX("TX DMIC MUX0", 0, tx_dmic0),
+ TX_MACRO_DAPM_MUX("TX DMIC MUX1", 0, tx_dmic1),
+ TX_MACRO_DAPM_MUX("TX DMIC MUX2", 0, tx_dmic2),
+ TX_MACRO_DAPM_MUX("TX DMIC MUX3", 0, tx_dmic3),
+
+ TX_MACRO_DAPM_MUX("TX SMIC MUX0", 0, tx_smic0_v2),
+ TX_MACRO_DAPM_MUX("TX SMIC MUX1", 0, tx_smic1_v2),
+ TX_MACRO_DAPM_MUX("TX SMIC MUX2", 0, tx_smic2_v2),
+ TX_MACRO_DAPM_MUX("TX SMIC MUX3", 0, tx_smic3_v2),
+
+ SND_SOC_DAPM_MICBIAS_E("TX MIC BIAS1", SND_SOC_NOPM, 0, 0,
+ tx_macro_enable_micbias,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_ADC_E("TX DMIC0", NULL, SND_SOC_NOPM, 0, 0,
+ tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_ADC_E("TX DMIC1", NULL, SND_SOC_NOPM, 0, 0,
+ tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_ADC_E("TX DMIC2", NULL, SND_SOC_NOPM, 0, 0,
+ tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_ADC_E("TX DMIC3", NULL, SND_SOC_NOPM, 0, 0,
+ tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_ADC_E("TX DMIC4", NULL, SND_SOC_NOPM, 0, 0,
+ tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_ADC_E("TX DMIC5", NULL, SND_SOC_NOPM, 0, 0,
+ tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_ADC_E("TX DMIC6", NULL, SND_SOC_NOPM, 0, 0,
+ tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_ADC_E("TX DMIC7", NULL, SND_SOC_NOPM, 0, 0,
+ tx_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_INPUT("TX SWR_MIC0"),
+ SND_SOC_DAPM_INPUT("TX SWR_MIC1"),
+ SND_SOC_DAPM_INPUT("TX SWR_MIC2"),
+ SND_SOC_DAPM_INPUT("TX SWR_MIC3"),
+ SND_SOC_DAPM_INPUT("TX SWR_MIC4"),
+ SND_SOC_DAPM_INPUT("TX SWR_MIC5"),
+ SND_SOC_DAPM_INPUT("TX SWR_MIC6"),
+ SND_SOC_DAPM_INPUT("TX SWR_MIC7"),
+ SND_SOC_DAPM_INPUT("TX SWR_MIC8"),
+ SND_SOC_DAPM_INPUT("TX SWR_MIC9"),
+ SND_SOC_DAPM_INPUT("TX SWR_MIC10"),
+ SND_SOC_DAPM_INPUT("TX SWR_MIC11"),
+
+ SND_SOC_DAPM_MUX_E("TX DEC0 MUX", SND_SOC_NOPM,
+ TX_MACRO_DEC0, 0,
+ &tx_dec0_mux, tx_macro_enable_dec,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_MUX_E("TX DEC1 MUX", SND_SOC_NOPM,
+ TX_MACRO_DEC1, 0,
+ &tx_dec1_mux, tx_macro_enable_dec,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_MUX_E("TX DEC2 MUX", SND_SOC_NOPM,
+ TX_MACRO_DEC2, 0,
+ &tx_dec2_mux, tx_macro_enable_dec,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_MUX_E("TX DEC3 MUX", SND_SOC_NOPM,
+ TX_MACRO_DEC3, 0,
+ &tx_dec3_mux, tx_macro_enable_dec,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_SUPPLY_S("TX_MCLK", 0, SND_SOC_NOPM, 0, 0,
+ tx_macro_mclk_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+};
+
+static const struct snd_soc_dapm_widget tx_macro_dapm_widgets_v2[] = {
+ SND_SOC_DAPM_MIXER("TX_AIF1_CAP Mixer", SND_SOC_NOPM,
+ TX_MACRO_AIF1_CAP, 0,
+ tx_aif1_cap_mixer_v2, ARRAY_SIZE(tx_aif1_cap_mixer_v2)),
+
+ SND_SOC_DAPM_MIXER("TX_AIF2_CAP Mixer", SND_SOC_NOPM,
+ TX_MACRO_AIF2_CAP, 0,
+ tx_aif2_cap_mixer_v2, ARRAY_SIZE(tx_aif2_cap_mixer_v2)),
+
+ SND_SOC_DAPM_MIXER("TX_AIF3_CAP Mixer", SND_SOC_NOPM,
+ TX_MACRO_AIF3_CAP, 0,
+ tx_aif3_cap_mixer_v2, ARRAY_SIZE(tx_aif3_cap_mixer_v2)),
+
+ SND_SOC_DAPM_SUPPLY_S("TX_SWR_CLK", 0, SND_SOC_NOPM, 0, 0,
+ tx_macro_tx_swr_clk_event,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+};
+
+static const struct snd_soc_dapm_widget tx_macro_dapm_widgets_v3[] = {
+ SND_SOC_DAPM_MIXER("TX_AIF1_CAP Mixer", SND_SOC_NOPM,
+ TX_MACRO_AIF1_CAP, 0,
+ tx_aif1_cap_mixer, ARRAY_SIZE(tx_aif1_cap_mixer)),
+
+ SND_SOC_DAPM_MIXER("TX_AIF2_CAP Mixer", SND_SOC_NOPM,
+ TX_MACRO_AIF2_CAP, 0,
+ tx_aif2_cap_mixer, ARRAY_SIZE(tx_aif2_cap_mixer)),
+
+ SND_SOC_DAPM_MIXER("TX_AIF3_CAP Mixer", SND_SOC_NOPM,
+ TX_MACRO_AIF3_CAP, 0,
+ tx_aif3_cap_mixer, ARRAY_SIZE(tx_aif3_cap_mixer)),
+
+ TX_MACRO_DAPM_MUX("TX DMIC MUX4", 0, tx_dmic4),
+ TX_MACRO_DAPM_MUX("TX DMIC MUX5", 0, tx_dmic5),
+ TX_MACRO_DAPM_MUX("TX DMIC MUX6", 0, tx_dmic6),
+ TX_MACRO_DAPM_MUX("TX DMIC MUX7", 0, tx_dmic7),
+
+ TX_MACRO_DAPM_MUX("TX SMIC MUX4", 0, tx_smic4_v3),
+ TX_MACRO_DAPM_MUX("TX SMIC MUX5", 0, tx_smic5_v3),
+ TX_MACRO_DAPM_MUX("TX SMIC MUX6", 0, tx_smic6_v3),
+ TX_MACRO_DAPM_MUX("TX SMIC MUX7", 0, tx_smic7_v3),
+
+ SND_SOC_DAPM_MUX_E("TX DEC4 MUX", SND_SOC_NOPM,
+ TX_MACRO_DEC4, 0,
+ &tx_dec4_mux, tx_macro_enable_dec,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_MUX_E("TX DEC5 MUX", SND_SOC_NOPM,
+ TX_MACRO_DEC5, 0,
+ &tx_dec5_mux, tx_macro_enable_dec,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_MUX_E("TX DEC6 MUX", SND_SOC_NOPM,
+ TX_MACRO_DEC6, 0,
+ &tx_dec6_mux, tx_macro_enable_dec,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_MUX_E("TX DEC7 MUX", SND_SOC_NOPM,
+ TX_MACRO_DEC7, 0,
+ &tx_dec7_mux, tx_macro_enable_dec,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_SUPPLY_S("VA_SWR_CLK", 0, SND_SOC_NOPM, 0, 0,
+ tx_macro_va_swr_clk_event,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+};
+
static const struct snd_soc_dapm_widget tx_macro_dapm_widgets[] = {
SND_SOC_DAPM_AIF_OUT("TX_AIF1 CAP", "TX_AIF1 Capture", 0,
SND_SOC_NOPM, TX_MACRO_AIF1_CAP, 0),
@@ -1421,6 +1679,250 @@
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
};
+static const struct snd_soc_dapm_route tx_audio_map_common[] = {
+ {"TX_AIF1 CAP", NULL, "TX_MCLK"},
+ {"TX_AIF2 CAP", NULL, "TX_MCLK"},
+ {"TX_AIF3 CAP", NULL, "TX_MCLK"},
+
+ {"TX_AIF1 CAP", NULL, "TX_AIF1_CAP Mixer"},
+ {"TX_AIF2 CAP", NULL, "TX_AIF2_CAP Mixer"},
+ {"TX_AIF3 CAP", NULL, "TX_AIF3_CAP Mixer"},
+
+ {"TX_AIF1_CAP Mixer", "DEC0", "TX DEC0 MUX"},
+ {"TX_AIF1_CAP Mixer", "DEC1", "TX DEC1 MUX"},
+ {"TX_AIF1_CAP Mixer", "DEC2", "TX DEC2 MUX"},
+ {"TX_AIF1_CAP Mixer", "DEC3", "TX DEC3 MUX"},
+
+ {"TX_AIF2_CAP Mixer", "DEC0", "TX DEC0 MUX"},
+ {"TX_AIF2_CAP Mixer", "DEC1", "TX DEC1 MUX"},
+ {"TX_AIF2_CAP Mixer", "DEC2", "TX DEC2 MUX"},
+ {"TX_AIF2_CAP Mixer", "DEC3", "TX DEC3 MUX"},
+
+ {"TX_AIF3_CAP Mixer", "DEC0", "TX DEC0 MUX"},
+ {"TX_AIF3_CAP Mixer", "DEC1", "TX DEC1 MUX"},
+ {"TX_AIF3_CAP Mixer", "DEC2", "TX DEC2 MUX"},
+ {"TX_AIF3_CAP Mixer", "DEC3", "TX DEC3 MUX"},
+
+ {"TX DEC0 MUX", NULL, "TX_MCLK"},
+ {"TX DEC1 MUX", NULL, "TX_MCLK"},
+ {"TX DEC2 MUX", NULL, "TX_MCLK"},
+ {"TX DEC3 MUX", NULL, "TX_MCLK"},
+
+ {"TX DEC0 MUX", "MSM_DMIC", "TX DMIC MUX0"},
+ {"TX DMIC MUX0", "DMIC0", "TX DMIC0"},
+ {"TX DMIC MUX0", "DMIC1", "TX DMIC1"},
+ {"TX DMIC MUX0", "DMIC2", "TX DMIC2"},
+ {"TX DMIC MUX0", "DMIC3", "TX DMIC3"},
+ {"TX DMIC MUX0", "DMIC4", "TX DMIC4"},
+ {"TX DMIC MUX0", "DMIC5", "TX DMIC5"},
+ {"TX DMIC MUX0", "DMIC6", "TX DMIC6"},
+ {"TX DMIC MUX0", "DMIC7", "TX DMIC7"},
+
+ {"TX DEC0 MUX", "SWR_MIC", "TX SMIC MUX0"},
+ {"TX SMIC MUX0", "SWR_MIC0", "TX SWR_MIC0"},
+ {"TX SMIC MUX0", "SWR_MIC1", "TX SWR_MIC1"},
+ {"TX SMIC MUX0", "SWR_MIC2", "TX SWR_MIC2"},
+ {"TX SMIC MUX0", "SWR_MIC3", "TX SWR_MIC3"},
+ {"TX SMIC MUX0", "SWR_MIC4", "TX SWR_MIC4"},
+ {"TX SMIC MUX0", "SWR_MIC5", "TX SWR_MIC5"},
+ {"TX SMIC MUX0", "SWR_MIC6", "TX SWR_MIC6"},
+ {"TX SMIC MUX0", "SWR_MIC7", "TX SWR_MIC7"},
+ {"TX SMIC MUX0", "SWR_MIC8", "TX SWR_MIC8"},
+ {"TX SMIC MUX0", "SWR_MIC9", "TX SWR_MIC9"},
+ {"TX SMIC MUX0", "SWR_MIC10", "TX SWR_MIC10"},
+ {"TX SMIC MUX0", "SWR_MIC11", "TX SWR_MIC11"},
+
+ {"TX DEC1 MUX", "MSM_DMIC", "TX DMIC MUX1"},
+ {"TX DMIC MUX1", "DMIC0", "TX DMIC0"},
+ {"TX DMIC MUX1", "DMIC1", "TX DMIC1"},
+ {"TX DMIC MUX1", "DMIC2", "TX DMIC2"},
+ {"TX DMIC MUX1", "DMIC3", "TX DMIC3"},
+ {"TX DMIC MUX1", "DMIC4", "TX DMIC4"},
+ {"TX DMIC MUX1", "DMIC5", "TX DMIC5"},
+ {"TX DMIC MUX1", "DMIC6", "TX DMIC6"},
+ {"TX DMIC MUX1", "DMIC7", "TX DMIC7"},
+
+ {"TX DEC1 MUX", "SWR_MIC", "TX SMIC MUX1"},
+ {"TX SMIC MUX1", "SWR_MIC0", "TX SWR_MIC0"},
+ {"TX SMIC MUX1", "SWR_MIC1", "TX SWR_MIC1"},
+ {"TX SMIC MUX1", "SWR_MIC2", "TX SWR_MIC2"},
+ {"TX SMIC MUX1", "SWR_MIC3", "TX SWR_MIC3"},
+ {"TX SMIC MUX1", "SWR_MIC4", "TX SWR_MIC4"},
+ {"TX SMIC MUX1", "SWR_MIC5", "TX SWR_MIC5"},
+ {"TX SMIC MUX1", "SWR_MIC6", "TX SWR_MIC6"},
+ {"TX SMIC MUX1", "SWR_MIC7", "TX SWR_MIC7"},
+ {"TX SMIC MUX1", "SWR_MIC8", "TX SWR_MIC8"},
+ {"TX SMIC MUX1", "SWR_MIC9", "TX SWR_MIC9"},
+ {"TX SMIC MUX1", "SWR_MIC10", "TX SWR_MIC10"},
+ {"TX SMIC MUX1", "SWR_MIC11", "TX SWR_MIC11"},
+
+ {"TX DEC2 MUX", "MSM_DMIC", "TX DMIC MUX2"},
+ {"TX DMIC MUX2", "DMIC0", "TX DMIC0"},
+ {"TX DMIC MUX2", "DMIC1", "TX DMIC1"},
+ {"TX DMIC MUX2", "DMIC2", "TX DMIC2"},
+ {"TX DMIC MUX2", "DMIC3", "TX DMIC3"},
+ {"TX DMIC MUX2", "DMIC4", "TX DMIC4"},
+ {"TX DMIC MUX2", "DMIC5", "TX DMIC5"},
+ {"TX DMIC MUX2", "DMIC6", "TX DMIC6"},
+ {"TX DMIC MUX2", "DMIC7", "TX DMIC7"},
+
+ {"TX DEC2 MUX", "SWR_MIC", "TX SMIC MUX2"},
+ {"TX SMIC MUX2", "SWR_MIC0", "TX SWR_MIC0"},
+ {"TX SMIC MUX2", "SWR_MIC1", "TX SWR_MIC1"},
+ {"TX SMIC MUX2", "SWR_MIC2", "TX SWR_MIC2"},
+ {"TX SMIC MUX2", "SWR_MIC3", "TX SWR_MIC3"},
+ {"TX SMIC MUX2", "SWR_MIC4", "TX SWR_MIC4"},
+ {"TX SMIC MUX2", "SWR_MIC5", "TX SWR_MIC5"},
+ {"TX SMIC MUX2", "SWR_MIC6", "TX SWR_MIC6"},
+ {"TX SMIC MUX2", "SWR_MIC7", "TX SWR_MIC7"},
+ {"TX SMIC MUX2", "SWR_MIC8", "TX SWR_MIC8"},
+ {"TX SMIC MUX2", "SWR_MIC9", "TX SWR_MIC9"},
+ {"TX SMIC MUX2", "SWR_MIC10", "TX SWR_MIC10"},
+ {"TX SMIC MUX2", "SWR_MIC11", "TX SWR_MIC11"},
+
+ {"TX DEC3 MUX", "MSM_DMIC", "TX DMIC MUX3"},
+ {"TX DMIC MUX3", "DMIC0", "TX DMIC0"},
+ {"TX DMIC MUX3", "DMIC1", "TX DMIC1"},
+ {"TX DMIC MUX3", "DMIC2", "TX DMIC2"},
+ {"TX DMIC MUX3", "DMIC3", "TX DMIC3"},
+ {"TX DMIC MUX3", "DMIC4", "TX DMIC4"},
+ {"TX DMIC MUX3", "DMIC5", "TX DMIC5"},
+ {"TX DMIC MUX3", "DMIC6", "TX DMIC6"},
+ {"TX DMIC MUX3", "DMIC7", "TX DMIC7"},
+
+ {"TX DEC3 MUX", "SWR_MIC", "TX SMIC MUX3"},
+ {"TX SMIC MUX3", "SWR_MIC0", "TX SWR_MIC0"},
+ {"TX SMIC MUX3", "SWR_MIC1", "TX SWR_MIC1"},
+ {"TX SMIC MUX3", "SWR_MIC2", "TX SWR_MIC2"},
+ {"TX SMIC MUX3", "SWR_MIC3", "TX SWR_MIC3"},
+ {"TX SMIC MUX3", "SWR_MIC4", "TX SWR_MIC4"},
+ {"TX SMIC MUX3", "SWR_MIC5", "TX SWR_MIC5"},
+ {"TX SMIC MUX3", "SWR_MIC6", "TX SWR_MIC6"},
+ {"TX SMIC MUX3", "SWR_MIC7", "TX SWR_MIC7"},
+ {"TX SMIC MUX3", "SWR_MIC8", "TX SWR_MIC8"},
+ {"TX SMIC MUX3", "SWR_MIC9", "TX SWR_MIC9"},
+ {"TX SMIC MUX3", "SWR_MIC10", "TX SWR_MIC10"},
+ {"TX SMIC MUX3", "SWR_MIC11", "TX SWR_MIC11"},
+};
+
+static const struct snd_soc_dapm_route tx_audio_map_v3[] = {
+ {"TX_AIF1_CAP Mixer", "DEC4", "TX DEC4 MUX"},
+ {"TX_AIF1_CAP Mixer", "DEC5", "TX DEC5 MUX"},
+ {"TX_AIF1_CAP Mixer", "DEC6", "TX DEC6 MUX"},
+ {"TX_AIF1_CAP Mixer", "DEC7", "TX DEC7 MUX"},
+
+ {"TX_AIF2_CAP Mixer", "DEC4", "TX DEC4 MUX"},
+ {"TX_AIF2_CAP Mixer", "DEC5", "TX DEC5 MUX"},
+ {"TX_AIF2_CAP Mixer", "DEC6", "TX DEC6 MUX"},
+ {"TX_AIF2_CAP Mixer", "DEC7", "TX DEC7 MUX"},
+
+ {"TX_AIF3_CAP Mixer", "DEC4", "TX DEC4 MUX"},
+ {"TX_AIF3_CAP Mixer", "DEC5", "TX DEC5 MUX"},
+ {"TX_AIF3_CAP Mixer", "DEC6", "TX DEC6 MUX"},
+ {"TX_AIF3_CAP Mixer", "DEC7", "TX DEC7 MUX"},
+
+ {"TX DEC4 MUX", NULL, "TX_MCLK"},
+ {"TX DEC5 MUX", NULL, "TX_MCLK"},
+ {"TX DEC6 MUX", NULL, "TX_MCLK"},
+ {"TX DEC7 MUX", NULL, "TX_MCLK"},
+
+ {"TX DEC4 MUX", "MSM_DMIC", "TX DMIC MUX4"},
+ {"TX DMIC MUX4", "DMIC0", "TX DMIC0"},
+ {"TX DMIC MUX4", "DMIC1", "TX DMIC1"},
+ {"TX DMIC MUX4", "DMIC2", "TX DMIC2"},
+ {"TX DMIC MUX4", "DMIC3", "TX DMIC3"},
+ {"TX DMIC MUX4", "DMIC4", "TX DMIC4"},
+ {"TX DMIC MUX4", "DMIC5", "TX DMIC5"},
+ {"TX DMIC MUX4", "DMIC6", "TX DMIC6"},
+ {"TX DMIC MUX4", "DMIC7", "TX DMIC7"},
+
+ {"TX DEC4 MUX", "SWR_MIC", "TX SMIC MUX4"},
+ {"TX SMIC MUX4", "SWR_MIC0", "TX SWR_MIC0"},
+ {"TX SMIC MUX4", "SWR_MIC1", "TX SWR_MIC1"},
+ {"TX SMIC MUX4", "SWR_MIC2", "TX SWR_MIC2"},
+ {"TX SMIC MUX4", "SWR_MIC3", "TX SWR_MIC3"},
+ {"TX SMIC MUX4", "SWR_MIC4", "TX SWR_MIC4"},
+ {"TX SMIC MUX4", "SWR_MIC5", "TX SWR_MIC5"},
+ {"TX SMIC MUX4", "SWR_MIC6", "TX SWR_MIC6"},
+ {"TX SMIC MUX4", "SWR_MIC7", "TX SWR_MIC7"},
+ {"TX SMIC MUX4", "SWR_MIC8", "TX SWR_MIC8"},
+ {"TX SMIC MUX4", "SWR_MIC9", "TX SWR_MIC9"},
+ {"TX SMIC MUX4", "SWR_MIC10", "TX SWR_MIC10"},
+ {"TX SMIC MUX4", "SWR_MIC11", "TX SWR_MIC11"},
+
+ {"TX DEC5 MUX", "MSM_DMIC", "TX DMIC MUX5"},
+ {"TX DMIC MUX5", "DMIC0", "TX DMIC0"},
+ {"TX DMIC MUX5", "DMIC1", "TX DMIC1"},
+ {"TX DMIC MUX5", "DMIC2", "TX DMIC2"},
+ {"TX DMIC MUX5", "DMIC3", "TX DMIC3"},
+ {"TX DMIC MUX5", "DMIC4", "TX DMIC4"},
+ {"TX DMIC MUX5", "DMIC5", "TX DMIC5"},
+ {"TX DMIC MUX5", "DMIC6", "TX DMIC6"},
+ {"TX DMIC MUX5", "DMIC7", "TX DMIC7"},
+
+ {"TX DEC5 MUX", "SWR_MIC", "TX SMIC MUX5"},
+ {"TX SMIC MUX5", "SWR_MIC0", "TX SWR_MIC0"},
+ {"TX SMIC MUX5", "SWR_MIC1", "TX SWR_MIC1"},
+ {"TX SMIC MUX5", "SWR_MIC2", "TX SWR_MIC2"},
+ {"TX SMIC MUX5", "SWR_MIC3", "TX SWR_MIC3"},
+ {"TX SMIC MUX5", "SWR_MIC4", "TX SWR_MIC4"},
+ {"TX SMIC MUX5", "SWR_MIC5", "TX SWR_MIC5"},
+ {"TX SMIC MUX5", "SWR_MIC6", "TX SWR_MIC6"},
+ {"TX SMIC MUX5", "SWR_MIC7", "TX SWR_MIC7"},
+ {"TX SMIC MUX5", "SWR_MIC8", "TX SWR_MIC8"},
+ {"TX SMIC MUX5", "SWR_MIC9", "TX SWR_MIC9"},
+ {"TX SMIC MUX5", "SWR_MIC10", "TX SWR_MIC10"},
+ {"TX SMIC MUX5", "SWR_MIC11", "TX SWR_MIC11"},
+
+ {"TX DEC6 MUX", "MSM_DMIC", "TX DMIC MUX6"},
+ {"TX DMIC MUX6", "DMIC0", "TX DMIC0"},
+ {"TX DMIC MUX6", "DMIC1", "TX DMIC1"},
+ {"TX DMIC MUX6", "DMIC2", "TX DMIC2"},
+ {"TX DMIC MUX6", "DMIC3", "TX DMIC3"},
+ {"TX DMIC MUX6", "DMIC4", "TX DMIC4"},
+ {"TX DMIC MUX6", "DMIC5", "TX DMIC5"},
+ {"TX DMIC MUX6", "DMIC6", "TX DMIC6"},
+ {"TX DMIC MUX6", "DMIC7", "TX DMIC7"},
+
+ {"TX DEC6 MUX", "SWR_MIC", "TX SMIC MUX6"},
+ {"TX SMIC MUX6", "SWR_MIC0", "TX SWR_MIC0"},
+ {"TX SMIC MUX6", "SWR_MIC1", "TX SWR_MIC1"},
+ {"TX SMIC MUX6", "SWR_MIC2", "TX SWR_MIC2"},
+ {"TX SMIC MUX6", "SWR_MIC3", "TX SWR_MIC3"},
+ {"TX SMIC MUX6", "SWR_MIC4", "TX SWR_MIC4"},
+ {"TX SMIC MUX6", "SWR_MIC5", "TX SWR_MIC5"},
+ {"TX SMIC MUX6", "SWR_MIC6", "TX SWR_MIC6"},
+ {"TX SMIC MUX6", "SWR_MIC7", "TX SWR_MIC7"},
+ {"TX SMIC MUX6", "SWR_MIC8", "TX SWR_MIC8"},
+ {"TX SMIC MUX6", "SWR_MIC9", "TX SWR_MIC9"},
+ {"TX SMIC MUX6", "SWR_MIC10", "TX SWR_MIC10"},
+ {"TX SMIC MUX6", "SWR_MIC11", "TX SWR_MIC11"},
+
+ {"TX DEC7 MUX", "MSM_DMIC", "TX DMIC MUX7"},
+ {"TX DMIC MUX7", "DMIC0", "TX DMIC0"},
+ {"TX DMIC MUX7", "DMIC1", "TX DMIC1"},
+ {"TX DMIC MUX7", "DMIC2", "TX DMIC2"},
+ {"TX DMIC MUX7", "DMIC3", "TX DMIC3"},
+ {"TX DMIC MUX7", "DMIC4", "TX DMIC4"},
+ {"TX DMIC MUX7", "DMIC5", "TX DMIC5"},
+ {"TX DMIC MUX7", "DMIC6", "TX DMIC6"},
+ {"TX DMIC MUX7", "DMIC7", "TX DMIC7"},
+
+ {"TX DEC7 MUX", "SWR_MIC", "TX SMIC MUX7"},
+ {"TX SMIC MUX7", "SWR_MIC0", "TX SWR_MIC0"},
+ {"TX SMIC MUX7", "SWR_MIC1", "TX SWR_MIC1"},
+ {"TX SMIC MUX7", "SWR_MIC2", "TX SWR_MIC2"},
+ {"TX SMIC MUX7", "SWR_MIC3", "TX SWR_MIC3"},
+ {"TX SMIC MUX7", "SWR_MIC4", "TX SWR_MIC4"},
+ {"TX SMIC MUX7", "SWR_MIC5", "TX SWR_MIC5"},
+ {"TX SMIC MUX7", "SWR_MIC6", "TX SWR_MIC6"},
+ {"TX SMIC MUX7", "SWR_MIC7", "TX SWR_MIC7"},
+ {"TX SMIC MUX7", "SWR_MIC8", "TX SWR_MIC8"},
+ {"TX SMIC MUX7", "SWR_MIC9", "TX SWR_MIC9"},
+ {"TX SMIC MUX7", "SWR_MIC10", "TX SWR_MIC10"},
+ {"TX SMIC MUX7", "SWR_MIC11", "TX SWR_MIC11"},
+};
+
static const struct snd_soc_dapm_route tx_audio_map[] = {
{"TX_AIF1 CAP", NULL, "TX_MCLK"},
{"TX_AIF2 CAP", NULL, "TX_MCLK"},
@@ -1667,6 +2169,63 @@
{"TX SMIC MUX7", "SWR_DMIC7", "TX SWR_DMIC7"},
};
+static const struct snd_kcontrol_new tx_macro_snd_controls_common[] = {
+ SOC_SINGLE_SX_TLV("TX_DEC0 Volume",
+ BOLERO_CDC_TX0_TX_VOL_CTL,
+ 0, -84, 40, digital_gain),
+ SOC_SINGLE_SX_TLV("TX_DEC1 Volume",
+ BOLERO_CDC_TX1_TX_VOL_CTL,
+ 0, -84, 40, digital_gain),
+ SOC_SINGLE_SX_TLV("TX_DEC2 Volume",
+ BOLERO_CDC_TX2_TX_VOL_CTL,
+ 0, -84, 40, digital_gain),
+ SOC_SINGLE_SX_TLV("TX_DEC3 Volume",
+ BOLERO_CDC_TX3_TX_VOL_CTL,
+ 0, -84, 40, digital_gain),
+
+ SOC_ENUM_EXT("DEC0 MODE", dec_mode_mux_enum,
+ tx_macro_dec_mode_get, tx_macro_dec_mode_put),
+
+ SOC_ENUM_EXT("DEC1 MODE", dec_mode_mux_enum,
+ tx_macro_dec_mode_get, tx_macro_dec_mode_put),
+
+ SOC_ENUM_EXT("DEC2 MODE", dec_mode_mux_enum,
+ tx_macro_dec_mode_get, tx_macro_dec_mode_put),
+
+ SOC_ENUM_EXT("DEC3 MODE", dec_mode_mux_enum,
+ tx_macro_dec_mode_get, tx_macro_dec_mode_put),
+
+ SOC_SINGLE_EXT("DEC0_BCS Switch", SND_SOC_NOPM, 0, 1, 0,
+ tx_macro_get_bcs, tx_macro_set_bcs),
+};
+
+static const struct snd_kcontrol_new tx_macro_snd_controls_v3[] = {
+ SOC_SINGLE_SX_TLV("TX_DEC4 Volume",
+ BOLERO_CDC_TX4_TX_VOL_CTL,
+ 0, -84, 40, digital_gain),
+ SOC_SINGLE_SX_TLV("TX_DEC5 Volume",
+ BOLERO_CDC_TX5_TX_VOL_CTL,
+ 0, -84, 40, digital_gain),
+ SOC_SINGLE_SX_TLV("TX_DEC6 Volume",
+ BOLERO_CDC_TX6_TX_VOL_CTL,
+ 0, -84, 40, digital_gain),
+ SOC_SINGLE_SX_TLV("TX_DEC7 Volume",
+ BOLERO_CDC_TX7_TX_VOL_CTL,
+ 0, -84, 40, digital_gain),
+
+ SOC_ENUM_EXT("DEC4 MODE", dec_mode_mux_enum,
+ tx_macro_dec_mode_get, tx_macro_dec_mode_put),
+
+ SOC_ENUM_EXT("DEC5 MODE", dec_mode_mux_enum,
+ tx_macro_dec_mode_get, tx_macro_dec_mode_put),
+
+ SOC_ENUM_EXT("DEC6 MODE", dec_mode_mux_enum,
+ tx_macro_dec_mode_get, tx_macro_dec_mode_put),
+
+ SOC_ENUM_EXT("DEC7 MODE", dec_mode_mux_enum,
+ tx_macro_dec_mode_get, tx_macro_dec_mode_put),
+};
+
static const struct snd_kcontrol_new tx_macro_snd_controls[] = {
SOC_SINGLE_SX_TLV("TX_DEC0 Volume",
BOLERO_CDC_TX0_TX_VOL_CTL,
@@ -2126,18 +2685,65 @@
"%s: priv is null for macro!\n", __func__);
return -EINVAL;
}
- ret = snd_soc_dapm_new_controls(dapm, tx_macro_dapm_widgets,
+ tx_priv->version = bolero_get_version(tx_dev);
+ if (tx_priv->version >= BOLERO_VERSION_2_0) {
+ ret = snd_soc_dapm_new_controls(dapm,
+ tx_macro_dapm_widgets_common,
+ ARRAY_SIZE(tx_macro_dapm_widgets_common));
+ if (ret < 0) {
+ dev_err(tx_dev, "%s: Failed to add controls\n",
+ __func__);
+ return ret;
+ }
+ if (tx_priv->version == BOLERO_VERSION_2_1)
+ ret = snd_soc_dapm_new_controls(dapm,
+ tx_macro_dapm_widgets_v2,
+ ARRAY_SIZE(tx_macro_dapm_widgets_v2));
+ else if (tx_priv->version == BOLERO_VERSION_2_0)
+ ret = snd_soc_dapm_new_controls(dapm,
+ tx_macro_dapm_widgets_v3,
+ ARRAY_SIZE(tx_macro_dapm_widgets_v3));
+ if (ret < 0) {
+ dev_err(tx_dev, "%s: Failed to add controls\n",
+ __func__);
+ return ret;
+ }
+ } else {
+ ret = snd_soc_dapm_new_controls(dapm, tx_macro_dapm_widgets,
ARRAY_SIZE(tx_macro_dapm_widgets));
- if (ret < 0) {
- dev_err(tx_dev, "%s: Failed to add controls\n", __func__);
- return ret;
+ if (ret < 0) {
+ dev_err(tx_dev, "%s: Failed to add controls\n",
+ __func__);
+ return ret;
+ }
}
- ret = snd_soc_dapm_add_routes(dapm, tx_audio_map,
+ if (tx_priv->version >= BOLERO_VERSION_2_0) {
+ ret = snd_soc_dapm_add_routes(dapm,
+ tx_audio_map_common,
+ ARRAY_SIZE(tx_audio_map_common));
+ if (ret < 0) {
+ dev_err(tx_dev, "%s: Failed to add routes\n",
+ __func__);
+ return ret;
+ }
+ if (tx_priv->version == BOLERO_VERSION_2_0)
+ ret = snd_soc_dapm_add_routes(dapm,
+ tx_audio_map_v3,
+ ARRAY_SIZE(tx_audio_map_v3));
+ if (ret < 0) {
+ dev_err(tx_dev, "%s: Failed to add routes\n",
+ __func__);
+ return ret;
+ }
+ } else {
+ ret = snd_soc_dapm_add_routes(dapm, tx_audio_map,
ARRAY_SIZE(tx_audio_map));
- if (ret < 0) {
- dev_err(tx_dev, "%s: Failed to add routes\n", __func__);
- return ret;
+ if (ret < 0) {
+ dev_err(tx_dev, "%s: Failed to add routes\n",
+ __func__);
+ return ret;
+ }
}
ret = snd_soc_dapm_new_widgets(dapm->card);
@@ -2146,28 +2752,65 @@
return ret;
}
- ret = snd_soc_add_component_controls(component, tx_macro_snd_controls,
- ARRAY_SIZE(tx_macro_snd_controls));
- if (ret < 0) {
- dev_err(tx_dev, "%s: Failed to add snd_ctls\n", __func__);
- return ret;
+ if (tx_priv->version >= BOLERO_VERSION_2_0) {
+ ret = snd_soc_add_component_controls(component,
+ tx_macro_snd_controls_common,
+ ARRAY_SIZE(tx_macro_snd_controls_common));
+ if (ret < 0) {
+ dev_err(tx_dev, "%s: Failed to add snd_ctls\n",
+ __func__);
+ return ret;
+ }
+ if (tx_priv->version == BOLERO_VERSION_2_0)
+ ret = snd_soc_add_component_controls(component,
+ tx_macro_snd_controls_v3,
+ ARRAY_SIZE(tx_macro_snd_controls_v3));
+ if (ret < 0) {
+ dev_err(tx_dev, "%s: Failed to add snd_ctls\n",
+ __func__);
+ return ret;
+ }
+ } else {
+ ret = snd_soc_add_component_controls(component,
+ tx_macro_snd_controls,
+ ARRAY_SIZE(tx_macro_snd_controls));
+ if (ret < 0) {
+ dev_err(tx_dev, "%s: Failed to add snd_ctls\n",
+ __func__);
+ return ret;
+ }
}
snd_soc_dapm_ignore_suspend(dapm, "TX_AIF1 Capture");
snd_soc_dapm_ignore_suspend(dapm, "TX_AIF2 Capture");
snd_soc_dapm_ignore_suspend(dapm, "TX_AIF3 Capture");
- snd_soc_dapm_ignore_suspend(dapm, "TX SWR_ADC0");
- snd_soc_dapm_ignore_suspend(dapm, "TX SWR_ADC1");
- snd_soc_dapm_ignore_suspend(dapm, "TX SWR_ADC2");
- snd_soc_dapm_ignore_suspend(dapm, "TX SWR_ADC3");
- snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC0");
- snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC1");
- snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC2");
- snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC3");
- snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC4");
- snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC5");
- snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC6");
- snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC7");
+ if (tx_priv->version >= BOLERO_VERSION_2_0) {
+ snd_soc_dapm_ignore_suspend(dapm, "TX SWR_MIC0");
+ snd_soc_dapm_ignore_suspend(dapm, "TX SWR_MIC1");
+ snd_soc_dapm_ignore_suspend(dapm, "TX SWR_MIC2");
+ snd_soc_dapm_ignore_suspend(dapm, "TX SWR_MIC3");
+ snd_soc_dapm_ignore_suspend(dapm, "TX SWR_MIC4");
+ snd_soc_dapm_ignore_suspend(dapm, "TX SWR_MIC5");
+ snd_soc_dapm_ignore_suspend(dapm, "TX SWR_MIC6");
+ snd_soc_dapm_ignore_suspend(dapm, "TX SWR_MIC7");
+ snd_soc_dapm_ignore_suspend(dapm, "TX SWR_MIC8");
+ snd_soc_dapm_ignore_suspend(dapm, "TX SWR_MIC9");
+ snd_soc_dapm_ignore_suspend(dapm, "TX SWR_MIC10");
+ snd_soc_dapm_ignore_suspend(dapm, "TX SWR_MIC11");
+ } else {
+ snd_soc_dapm_ignore_suspend(dapm, "TX SWR_ADC0");
+ snd_soc_dapm_ignore_suspend(dapm, "TX SWR_ADC1");
+ snd_soc_dapm_ignore_suspend(dapm, "TX SWR_ADC2");
+ snd_soc_dapm_ignore_suspend(dapm, "TX SWR_ADC3");
+ snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC0");
+ snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC1");
+ snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC2");
+ snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC3");
+ snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC4");
+ snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC5");
+ snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC6");
+ snd_soc_dapm_ignore_suspend(dapm, "TX SWR_DMIC7");
+ }
snd_soc_dapm_sync(dapm);
for (i = 0; i < NUM_DECIMATORS; i++) {
@@ -2423,19 +3066,21 @@
sample_rate, tx_priv) == TX_MACRO_DMIC_SAMPLE_RATE_UNDEFINED)
return -EINVAL;
}
- tx_priv->reset_swr = true;
- INIT_WORK(&tx_priv->tx_macro_add_child_devices_work,
- tx_macro_add_child_devices);
- tx_priv->swr_plat_data.handle = (void *) tx_priv;
- tx_priv->swr_plat_data.read = NULL;
- tx_priv->swr_plat_data.write = NULL;
- tx_priv->swr_plat_data.bulk_write = NULL;
- tx_priv->swr_plat_data.clk = tx_macro_swrm_clock;
- tx_priv->swr_plat_data.core_vote = tx_macro_core_vote;
- tx_priv->swr_plat_data.handle_irq = NULL;
-
+ if (is_used_tx_swr_gpio) {
+ tx_priv->reset_swr = true;
+ INIT_WORK(&tx_priv->tx_macro_add_child_devices_work,
+ tx_macro_add_child_devices);
+ tx_priv->swr_plat_data.handle = (void *) tx_priv;
+ tx_priv->swr_plat_data.read = NULL;
+ tx_priv->swr_plat_data.write = NULL;
+ tx_priv->swr_plat_data.bulk_write = NULL;
+ tx_priv->swr_plat_data.clk = tx_macro_swrm_clock;
+ tx_priv->swr_plat_data.core_vote = tx_macro_core_vote;
+ tx_priv->swr_plat_data.handle_irq = NULL;
+ mutex_init(&tx_priv->swr_clk_lock);
+ }
+ tx_priv->is_used_tx_swr_gpio = is_used_tx_swr_gpio;
mutex_init(&tx_priv->mclk_lock);
- mutex_init(&tx_priv->swr_clk_lock);
tx_macro_init_ops(&ops, tx_io_base);
ops.clk_id_req = TX_CORE_CLK;
ops.default_clk_id = TX_CORE_CLK;
@@ -2445,8 +3090,8 @@
"%s: register macro failed\n", __func__);
goto err_reg_macro;
}
-
- schedule_work(&tx_priv->tx_macro_add_child_devices_work);
+ if (is_used_tx_swr_gpio)
+ schedule_work(&tx_priv->tx_macro_add_child_devices_work);
pm_runtime_set_autosuspend_delay(&pdev->dev, AUTO_SUSPEND_DELAY);
pm_runtime_use_autosuspend(&pdev->dev);
pm_runtime_set_suspended(&pdev->dev);
@@ -2456,7 +3101,8 @@
return 0;
err_reg_macro:
mutex_destroy(&tx_priv->mclk_lock);
- mutex_destroy(&tx_priv->swr_clk_lock);
+ if (is_used_tx_swr_gpio)
+ mutex_destroy(&tx_priv->swr_clk_lock);
return ret;
}
@@ -2470,16 +3116,20 @@
if (!tx_priv)
return -EINVAL;
- if (tx_priv->swr_ctrl_data)
- kfree(tx_priv->swr_ctrl_data);
- for (count = 0; count < tx_priv->child_count &&
- count < TX_MACRO_CHILD_DEVICES_MAX; count++)
- platform_device_unregister(tx_priv->pdev_child_devices[count]);
+ if (tx_priv->is_used_tx_swr_gpio) {
+ if (tx_priv->swr_ctrl_data)
+ kfree(tx_priv->swr_ctrl_data);
+ for (count = 0; count < tx_priv->child_count &&
+ count < TX_MACRO_CHILD_DEVICES_MAX; count++)
+ platform_device_unregister(
+ tx_priv->pdev_child_devices[count]);
+ }
pm_runtime_disable(&pdev->dev);
pm_runtime_set_suspended(&pdev->dev);
mutex_destroy(&tx_priv->mclk_lock);
- mutex_destroy(&tx_priv->swr_clk_lock);
+ if (tx_priv->is_used_tx_swr_gpio)
+ mutex_destroy(&tx_priv->swr_clk_lock);
bolero_unregister_macro(&pdev->dev, TX_MACRO);
return 0;
}
diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c
index 782c00e..c5f0ef9 100644
--- a/asoc/codecs/bolero/va-macro.c
+++ b/asoc/codecs/bolero/va-macro.c
@@ -13,6 +13,9 @@
#include <sound/soc-dapm.h>
#include <sound/tlv.h>
#include <linux/pm_runtime.h>
+#include <asoc/msm-cdc-pinctrl.h>
+#include <soc/swr-common.h>
+#include <soc/swr-wcd.h>
#include "bolero-cdc.h"
#include "bolero-cdc-registers.h"
#include "bolero-clk-rsc.h"
@@ -46,6 +49,9 @@
#define BOLERO_CDC_VA_TX_UNMUTE_DELAY_MS 40
#define MAX_RETRY_ATTEMPTS 500
+#define VA_MACRO_SWR_STRING_LEN 80
+#define VA_MACRO_CHILD_DEVICES_MAX 3
+
static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0);
static int va_tx_unmute_delay = BOLERO_CDC_VA_TX_UNMUTE_DELAY_MS;
module_param(va_tx_unmute_delay, int, 0664);
@@ -85,6 +91,11 @@
SWR_MIC,
};
+enum {
+ TX_MCLK,
+ VA_MCLK,
+};
+
struct va_mute_work {
struct va_macro_priv *va_priv;
u32 decimator;
@@ -98,12 +109,31 @@
struct delayed_work dwork;
};
+/* Hold instance to soundwire platform device */
+struct va_macro_swr_ctrl_data {
+ struct platform_device *va_swr_pdev;
+};
+
+struct va_macro_swr_ctrl_platform_data {
+ void *handle; /* holds codec private data */
+ int (*read)(void *handle, int reg);
+ int (*write)(void *handle, int reg, int val);
+ int (*bulk_write)(void *handle, u32 *reg, u32 *val, size_t len);
+ int (*clk)(void *handle, bool enable);
+ int (*handle_irq)(void *handle,
+ irqreturn_t (*swrm_irq_handler)(int irq,
+ void *data),
+ void *swrm_handle,
+ int action);
+};
+
struct va_macro_priv {
struct device *dev;
bool dec_active[VA_MACRO_NUM_DECIMATORS];
bool va_without_decimation;
struct clk *lpass_audio_hw_vote;
struct mutex mclk_lock;
+ struct mutex swr_clk_lock;
struct snd_soc_component *component;
struct hpf_work va_hpf_work[VA_MACRO_NUM_DECIMATORS];
struct va_mute_work va_mute_dwork[VA_MACRO_NUM_DECIMATORS];
@@ -115,15 +145,29 @@
s32 dmic_6_7_clk_cnt;
u16 dmic_clk_div;
u16 va_mclk_users;
+ int swr_clk_users;
+ bool reset_swr;
+ struct device_node *va_swr_gpio_p;
+ struct va_macro_swr_ctrl_data *swr_ctrl_data;
+ struct va_macro_swr_ctrl_platform_data swr_plat_data;
+ struct work_struct va_macro_add_child_devices_work;
+ int child_count;
u16 mclk_mux_sel;
char __iomem *va_io_base;
char __iomem *va_island_mode_muxsel;
+ struct platform_device *pdev_child_devices
+ [VA_MACRO_CHILD_DEVICES_MAX];
struct regulator *micb_supply;
u32 micb_voltage;
u32 micb_current;
+ u32 version;
+ u32 is_used_va_swr_gpio;
int micb_users;
u16 default_clk_id;
u16 clk_id;
+ int tx_swr_clk_cnt;
+ int va_swr_clk_cnt;
+ int va_clk_status;
int tx_clk_status;
};
@@ -249,10 +293,25 @@
bolero_clk_rsc_request_clock(va_priv->dev,
va_priv->default_clk_id,
VA_CORE_CLK, false);
+ /* reset swr after ssr/pdr */
+ va_priv->reset_swr = true;
+ if (va_priv->swr_ctrl_data)
+ swrm_wcd_notify(
+ va_priv->swr_ctrl_data[0].va_swr_pdev,
+ SWR_DEVICE_SSR_UP, NULL);
+ break;
case BOLERO_MACRO_EVT_CLK_RESET:
bolero_rsc_clk_reset(va_dev, VA_CORE_CLK);
break;
case BOLERO_MACRO_EVT_SSR_DOWN:
+ if (va_priv->swr_ctrl_data) {
+ swrm_wcd_notify(
+ va_priv->swr_ctrl_data[0].va_swr_pdev,
+ SWR_DEVICE_DOWN, NULL);
+ swrm_wcd_notify(
+ va_priv->swr_ctrl_data[0].va_swr_pdev,
+ SWR_DEVICE_SSR_DOWN, NULL);
+ }
if ((!pm_runtime_enabled(va_dev) ||
!pm_runtime_suspended(va_dev))) {
ret = bolero_runtime_suspend(va_dev);
@@ -269,6 +328,54 @@
return 0;
}
+static int va_macro_swr_pwr_event_v2(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct snd_soc_component *component =
+ snd_soc_dapm_to_component(w->dapm);
+ int ret = 0;
+ struct device *va_dev = NULL;
+ struct va_macro_priv *va_priv = NULL;
+
+ if (!va_macro_get_data(component, &va_dev, &va_priv, __func__))
+ return -EINVAL;
+
+ dev_dbg(va_dev, "%s: event = %d\n", __func__, event);
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ va_priv->va_swr_clk_cnt++;
+ if (va_priv->swr_ctrl_data) {
+ ret = swrm_wcd_notify(
+ va_priv->swr_ctrl_data[0].va_swr_pdev,
+ SWR_REQ_CLK_SWITCH, NULL);
+ if (ret)
+ dev_dbg(va_dev, "%s: clock switch failed\n",
+ __func__);
+ }
+ 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->swr_ctrl_data) {
+ ret = swrm_wcd_notify(
+ va_priv->swr_ctrl_data[0].va_swr_pdev,
+ SWR_REQ_CLK_SWITCH, NULL);
+ if (ret)
+ dev_dbg(va_dev, "%s: clock switch failed\n",
+ __func__);
+ }
+ va_priv->va_swr_clk_cnt--;
+ break;
+ default:
+ dev_err(va_priv->dev,
+ "%s: invalid DAPM event %d\n", __func__, event);
+ ret = -EINVAL;
+ }
+ return ret;
+}
+
static int va_macro_swr_pwr_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
@@ -312,6 +419,25 @@
return ret;
}
+static int va_macro_tx_swr_clk_event_v2(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
+{
+ struct device *va_dev = NULL;
+ struct va_macro_priv *va_priv = NULL;
+ struct snd_soc_component *component =
+ snd_soc_dapm_to_component(w->dapm);
+
+ if (!va_macro_get_data(component, &va_dev, &va_priv, __func__))
+ return -EINVAL;
+
+ if (SND_SOC_DAPM_EVENT_ON(event))
+ ++va_priv->tx_swr_clk_cnt;
+ if (SND_SOC_DAPM_EVENT_OFF(event))
+ --va_priv->tx_swr_clk_cnt;
+
+ return 0;
+}
+
static int va_macro_mclk_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
@@ -355,6 +481,204 @@
return ret;
}
+static int va_macro_tx_va_mclk_enable(struct va_macro_priv *va_priv,
+ struct regmap *regmap, int clk_type,
+ bool enable)
+{
+ int ret = 0, clk_tx_ret = 0;
+
+ dev_dbg(va_priv->dev,
+ "%s: clock type %s, enable: %s tx_mclk_users: %d\n",
+ __func__, (clk_type ? "VA_MCLK" : "TX_MCLK"),
+ (enable ? "enable" : "disable"), va_priv->va_mclk_users);
+
+ if (enable) {
+ if (va_priv->swr_clk_users == 0)
+ msm_cdc_pinctrl_select_active_state(
+ va_priv->va_swr_gpio_p);
+ clk_tx_ret = bolero_clk_rsc_request_clock(va_priv->dev,
+ TX_CORE_CLK,
+ TX_CORE_CLK,
+ true);
+ if (clk_type == TX_MCLK) {
+ ret = bolero_clk_rsc_request_clock(va_priv->dev,
+ TX_CORE_CLK,
+ TX_CORE_CLK,
+ true);
+ if (ret < 0) {
+ if (va_priv->swr_clk_users == 0)
+ msm_cdc_pinctrl_select_sleep_state(
+ va_priv->va_swr_gpio_p);
+ dev_err_ratelimited(va_priv->dev,
+ "%s: swr request clk failed\n",
+ __func__);
+ goto done;
+ }
+ bolero_clk_rsc_fs_gen_request(va_priv->dev,
+ true);
+ }
+ if (clk_type == VA_MCLK) {
+ ret = va_macro_mclk_enable(va_priv, 1, true);
+ if (ret < 0) {
+ if (va_priv->swr_clk_users == 0)
+ msm_cdc_pinctrl_select_sleep_state(
+ va_priv->va_swr_gpio_p);
+ dev_err_ratelimited(va_priv->dev,
+ "%s: request clock enable failed\n",
+ __func__);
+ goto done;
+ }
+ }
+ if (va_priv->swr_clk_users == 0) {
+ dev_dbg(va_priv->dev, "%s: reset_swr: %d\n",
+ __func__, va_priv->reset_swr);
+ if (va_priv->reset_swr)
+ regmap_update_bits(regmap,
+ BOLERO_CDC_VA_CLK_RST_CTRL_SWR_CONTROL,
+ 0x02, 0x02);
+ regmap_update_bits(regmap,
+ BOLERO_CDC_VA_CLK_RST_CTRL_SWR_CONTROL,
+ 0x01, 0x01);
+ if (va_priv->reset_swr)
+ regmap_update_bits(regmap,
+ BOLERO_CDC_VA_CLK_RST_CTRL_SWR_CONTROL,
+ 0x02, 0x00);
+ va_priv->reset_swr = false;
+ }
+ if (!clk_tx_ret)
+ ret = bolero_clk_rsc_request_clock(va_priv->dev,
+ TX_CORE_CLK,
+ TX_CORE_CLK,
+ false);
+ va_priv->swr_clk_users++;
+ } else {
+ if (va_priv->swr_clk_users <= 0) {
+ dev_err_ratelimited(va_priv->dev,
+ "va swrm clock users already 0\n");
+ va_priv->swr_clk_users = 0;
+ return 0;
+ }
+ clk_tx_ret = bolero_clk_rsc_request_clock(va_priv->dev,
+ TX_CORE_CLK,
+ TX_CORE_CLK,
+ true);
+ va_priv->swr_clk_users--;
+ if (va_priv->swr_clk_users == 0)
+ regmap_update_bits(regmap,
+ BOLERO_CDC_VA_CLK_RST_CTRL_SWR_CONTROL,
+ 0x01, 0x00);
+ if (clk_type == VA_MCLK)
+ va_macro_mclk_enable(va_priv, 0, true);
+ if (clk_type == TX_MCLK) {
+ bolero_clk_rsc_fs_gen_request(va_priv->dev,
+ false);
+ ret = bolero_clk_rsc_request_clock(va_priv->dev,
+ TX_CORE_CLK,
+ TX_CORE_CLK,
+ false);
+ if (ret < 0) {
+ dev_err_ratelimited(va_priv->dev,
+ "%s: swr request clk failed\n",
+ __func__);
+ goto done;
+ }
+ }
+ if (!clk_tx_ret)
+ ret = bolero_clk_rsc_request_clock(va_priv->dev,
+ TX_CORE_CLK,
+ TX_CORE_CLK,
+ false);
+ if (va_priv->swr_clk_users == 0)
+ msm_cdc_pinctrl_select_sleep_state(
+ va_priv->va_swr_gpio_p);
+ }
+ return 0;
+
+done:
+ if (!clk_tx_ret)
+ bolero_clk_rsc_request_clock(va_priv->dev,
+ TX_CORE_CLK,
+ TX_CORE_CLK,
+ false);
+ return ret;
+}
+
+static int va_macro_swrm_clock(void *handle, bool enable)
+{
+ struct va_macro_priv *va_priv = (struct va_macro_priv *) handle;
+ struct regmap *regmap = dev_get_regmap(va_priv->dev->parent, NULL);
+ int ret = 0;
+
+ if (regmap == NULL) {
+ dev_err(va_priv->dev, "%s: regmap is NULL\n", __func__);
+ return -EINVAL;
+ }
+
+ mutex_lock(&va_priv->swr_clk_lock);
+ dev_dbg(va_priv->dev,
+ "%s: swrm clock %s tx_swr_clk_cnt: %d va_swr_clk_cnt: %d\n",
+ __func__, (enable ? "enable" : "disable"),
+ va_priv->tx_swr_clk_cnt, va_priv->va_swr_clk_cnt);
+
+ if (enable) {
+ pm_runtime_get_sync(va_priv->dev);
+ if (va_priv->va_swr_clk_cnt && !va_priv->tx_swr_clk_cnt) {
+ ret = va_macro_tx_va_mclk_enable(va_priv, regmap,
+ VA_MCLK, enable);
+ if (ret)
+ goto done;
+ va_priv->va_clk_status++;
+ } else {
+ ret = va_macro_tx_va_mclk_enable(va_priv, regmap,
+ TX_MCLK, enable);
+ if (ret)
+ goto done;
+ va_priv->tx_clk_status++;
+ }
+ pm_runtime_mark_last_busy(va_priv->dev);
+ pm_runtime_put_autosuspend(va_priv->dev);
+ } else {
+ if (va_priv->va_clk_status && !va_priv->tx_clk_status) {
+ ret = va_macro_tx_va_mclk_enable(va_priv, regmap,
+ VA_MCLK, enable);
+ if (ret)
+ goto done;
+ --va_priv->va_clk_status;
+ } else if (!va_priv->va_clk_status && va_priv->tx_clk_status) {
+ ret = va_macro_tx_va_mclk_enable(va_priv, regmap,
+ TX_MCLK, enable);
+ if (ret)
+ goto done;
+ --va_priv->tx_clk_status;
+ } else if (va_priv->va_clk_status && va_priv->tx_clk_status) {
+ if (!va_priv->va_swr_clk_cnt && va_priv->tx_swr_clk_cnt) {
+ ret = va_macro_tx_va_mclk_enable(va_priv, regmap,
+ VA_MCLK, enable);
+ if (ret)
+ goto done;
+ --va_priv->va_clk_status;
+ } else {
+ ret = va_macro_tx_va_mclk_enable(va_priv, regmap,
+ TX_MCLK, enable);
+ if (ret)
+ goto done;
+ --va_priv->tx_clk_status;
+ }
+
+ } else {
+ dev_dbg(va_priv->dev,
+ "%s: Both clocks are disabled\n", __func__);
+ }
+ }
+ dev_dbg(va_priv->dev,
+ "%s: swrm clock users %d tx_clk_sts_cnt: %d va_clk_sts_cnt: %d\n",
+ __func__, va_priv->swr_clk_users, va_priv->tx_clk_status,
+ va_priv->va_clk_status);
+done:
+ mutex_unlock(&va_priv->swr_clk_lock);
+ return ret;
+}
+
static void va_macro_tx_hpf_corner_freq_callback(struct work_struct *work)
{
struct delayed_work *hpf_delayed_work;
@@ -395,10 +719,10 @@
snd_soc_component_update_bits(component,
dec_cfg_reg, TX_HPF_CUT_OFF_FREQ_MASK,
hpf_cut_off_freq << 5);
- snd_soc_component_update_bits(component, hpf_gate_reg, 0x03, 0x02);
+ snd_soc_component_update_bits(component, hpf_gate_reg, 0x02, 0x02);
/* Minimum 1 clk cycle delay is required as per HW spec */
usleep_range(1000, 1010);
- snd_soc_component_update_bits(component, hpf_gate_reg, 0x03, 0x01);
+ snd_soc_component_update_bits(component, hpf_gate_reg, 0x02, 0x00);
}
static void va_macro_mute_update_callback(struct work_struct *work)
@@ -690,6 +1014,10 @@
tx_vol_ctl_reg, 0x20, 0x20);
snd_soc_component_update_bits(component,
hpf_gate_reg, 0x01, 0x00);
+ /*
+ * Minimum 1 clk cycle delay is required as per HW spec
+ */
+ usleep_range(1000, 1010);
hpf_cut_off_freq = (snd_soc_component_read32(
component, dec_cfg_reg) &
@@ -702,7 +1030,7 @@
TX_HPF_CUT_OFF_FREQ_MASK,
CF_MIN_3DB_150HZ << 5);
snd_soc_component_update_bits(component,
- hpf_gate_reg, 0x02, 0x02);
+ hpf_gate_reg, 0x03, 0x03);
/*
* Minimum 1 clk cycle delay is required as per HW spec
*/
@@ -1122,6 +1450,28 @@
0, smic_mux_text, snd_soc_dapm_get_enum_double,
va_macro_put_dec_enum);
+static const char * const smic_mux_text_v2[] = {
+ "ZERO", "SWR_MIC0", "SWR_MIC1", "SWR_MIC2", "SWR_MIC3",
+ "SWR_MIC4", "SWR_MIC5", "SWR_MIC6", "SWR_MIC7",
+ "SWR_MIC8", "SWR_MIC9", "SWR_MIC10", "SWR_MIC11"
+};
+
+VA_MACRO_DAPM_ENUM_EXT(va_smic0_v2, BOLERO_CDC_VA_INP_MUX_ADC_MUX0_CFG0,
+ 0, smic_mux_text_v2, snd_soc_dapm_get_enum_double,
+ va_macro_put_dec_enum);
+
+VA_MACRO_DAPM_ENUM_EXT(va_smic1_v2, BOLERO_CDC_VA_INP_MUX_ADC_MUX1_CFG0,
+ 0, smic_mux_text_v2, snd_soc_dapm_get_enum_double,
+ va_macro_put_dec_enum);
+
+VA_MACRO_DAPM_ENUM_EXT(va_smic2_v3, BOLERO_CDC_VA_INP_MUX_ADC_MUX2_CFG0,
+ 0, smic_mux_text_v2, snd_soc_dapm_get_enum_double,
+ va_macro_put_dec_enum);
+
+VA_MACRO_DAPM_ENUM_EXT(va_smic3_v3, BOLERO_CDC_VA_INP_MUX_ADC_MUX3_CFG0,
+ 0, smic_mux_text_v2, snd_soc_dapm_get_enum_double,
+ va_macro_put_dec_enum);
+
static const struct snd_kcontrol_new va_aif1_cap_mixer[] = {
SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, VA_MACRO_DEC0, 1, 0,
va_macro_tx_mixer_get, va_macro_tx_mixer_put),
@@ -1179,6 +1529,202 @@
va_macro_tx_mixer_get, va_macro_tx_mixer_put),
};
+static const struct snd_kcontrol_new va_aif1_cap_mixer_v2[] = {
+ SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, VA_MACRO_DEC0, 1, 0,
+ va_macro_tx_mixer_get, va_macro_tx_mixer_put),
+ SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, VA_MACRO_DEC1, 1, 0,
+ va_macro_tx_mixer_get, va_macro_tx_mixer_put),
+};
+
+static const struct snd_kcontrol_new va_aif2_cap_mixer_v2[] = {
+ SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, VA_MACRO_DEC0, 1, 0,
+ va_macro_tx_mixer_get, va_macro_tx_mixer_put),
+ SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, VA_MACRO_DEC1, 1, 0,
+ va_macro_tx_mixer_get, va_macro_tx_mixer_put),
+};
+
+static const struct snd_kcontrol_new va_aif3_cap_mixer_v2[] = {
+ SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, VA_MACRO_DEC0, 1, 0,
+ va_macro_tx_mixer_get, va_macro_tx_mixer_put),
+ SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, VA_MACRO_DEC1, 1, 0,
+ va_macro_tx_mixer_get, va_macro_tx_mixer_put),
+};
+
+static const struct snd_kcontrol_new va_aif1_cap_mixer_v3[] = {
+ SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, VA_MACRO_DEC0, 1, 0,
+ va_macro_tx_mixer_get, va_macro_tx_mixer_put),
+ SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, VA_MACRO_DEC1, 1, 0,
+ va_macro_tx_mixer_get, va_macro_tx_mixer_put),
+ SOC_SINGLE_EXT("DEC2", SND_SOC_NOPM, VA_MACRO_DEC2, 1, 0,
+ va_macro_tx_mixer_get, va_macro_tx_mixer_put),
+ SOC_SINGLE_EXT("DEC3", SND_SOC_NOPM, VA_MACRO_DEC3, 1, 0,
+ va_macro_tx_mixer_get, va_macro_tx_mixer_put),
+};
+
+static const struct snd_kcontrol_new va_aif2_cap_mixer_v3[] = {
+ SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, VA_MACRO_DEC0, 1, 0,
+ va_macro_tx_mixer_get, va_macro_tx_mixer_put),
+ SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, VA_MACRO_DEC1, 1, 0,
+ va_macro_tx_mixer_get, va_macro_tx_mixer_put),
+ SOC_SINGLE_EXT("DEC2", SND_SOC_NOPM, VA_MACRO_DEC2, 1, 0,
+ va_macro_tx_mixer_get, va_macro_tx_mixer_put),
+ SOC_SINGLE_EXT("DEC3", SND_SOC_NOPM, VA_MACRO_DEC3, 1, 0,
+ va_macro_tx_mixer_get, va_macro_tx_mixer_put),
+};
+
+static const struct snd_kcontrol_new va_aif3_cap_mixer_v3[] = {
+ SOC_SINGLE_EXT("DEC0", SND_SOC_NOPM, VA_MACRO_DEC0, 1, 0,
+ va_macro_tx_mixer_get, va_macro_tx_mixer_put),
+ SOC_SINGLE_EXT("DEC1", SND_SOC_NOPM, VA_MACRO_DEC1, 1, 0,
+ va_macro_tx_mixer_get, va_macro_tx_mixer_put),
+ SOC_SINGLE_EXT("DEC2", SND_SOC_NOPM, VA_MACRO_DEC2, 1, 0,
+ va_macro_tx_mixer_get, va_macro_tx_mixer_put),
+ SOC_SINGLE_EXT("DEC3", SND_SOC_NOPM, VA_MACRO_DEC3, 1, 0,
+ va_macro_tx_mixer_get, va_macro_tx_mixer_put),
+};
+
+static const struct snd_soc_dapm_widget va_macro_dapm_widgets_common[] = {
+ SND_SOC_DAPM_AIF_OUT_E("VA_AIF1 CAP", "VA_AIF1 Capture", 0,
+ SND_SOC_NOPM, VA_MACRO_AIF1_CAP, 0,
+ va_macro_enable_tx, SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD),
+
+ SND_SOC_DAPM_AIF_OUT_E("VA_AIF2 CAP", "VA_AIF2 Capture", 0,
+ SND_SOC_NOPM, VA_MACRO_AIF2_CAP, 0,
+ va_macro_enable_tx, SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD),
+
+ SND_SOC_DAPM_AIF_OUT_E("VA_AIF3 CAP", "VA_AIF3 Capture", 0,
+ SND_SOC_NOPM, VA_MACRO_AIF3_CAP, 0,
+ va_macro_enable_tx, SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD),
+
+ VA_MACRO_DAPM_MUX("VA DMIC MUX0", 0, va_dmic0),
+ VA_MACRO_DAPM_MUX("VA DMIC MUX1", 0, va_dmic1),
+
+ VA_MACRO_DAPM_MUX("VA SMIC MUX0", 0, va_smic0_v2),
+ VA_MACRO_DAPM_MUX("VA SMIC MUX1", 0, va_smic1_v2),
+
+ SND_SOC_DAPM_INPUT("VA SWR_MIC0"),
+ SND_SOC_DAPM_INPUT("VA SWR_MIC1"),
+ SND_SOC_DAPM_INPUT("VA SWR_MIC2"),
+ SND_SOC_DAPM_INPUT("VA SWR_MIC3"),
+ SND_SOC_DAPM_INPUT("VA SWR_MIC4"),
+ SND_SOC_DAPM_INPUT("VA SWR_MIC5"),
+ SND_SOC_DAPM_INPUT("VA SWR_MIC6"),
+ SND_SOC_DAPM_INPUT("VA SWR_MIC7"),
+ SND_SOC_DAPM_INPUT("VA SWR_MIC8"),
+ SND_SOC_DAPM_INPUT("VA SWR_MIC9"),
+ SND_SOC_DAPM_INPUT("VA SWR_MIC10"),
+ SND_SOC_DAPM_INPUT("VA SWR_MIC11"),
+
+ SND_SOC_DAPM_MICBIAS_E("VA MIC BIAS1", SND_SOC_NOPM, 0, 0,
+ va_macro_enable_micbias,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_ADC_E("VA DMIC0", NULL, SND_SOC_NOPM, 0, 0,
+ va_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_ADC_E("VA DMIC1", NULL, SND_SOC_NOPM, 0, 0,
+ va_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_ADC_E("VA DMIC2", NULL, SND_SOC_NOPM, 0, 0,
+ va_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_ADC_E("VA DMIC3", NULL, SND_SOC_NOPM, 0, 0,
+ va_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_ADC_E("VA DMIC4", NULL, SND_SOC_NOPM, 0, 0,
+ va_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_ADC_E("VA DMIC5", NULL, SND_SOC_NOPM, 0, 0,
+ va_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_ADC_E("VA DMIC6", NULL, SND_SOC_NOPM, 0, 0,
+ va_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_ADC_E("VA DMIC7", NULL, SND_SOC_NOPM, 0, 0,
+ va_macro_enable_dmic, SND_SOC_DAPM_PRE_PMU |
+ SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_MUX_E("VA DEC0 MUX", SND_SOC_NOPM, VA_MACRO_DEC0, 0,
+ &va_dec0_mux, va_macro_enable_dec,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_MUX_E("VA DEC1 MUX", SND_SOC_NOPM, VA_MACRO_DEC1, 0,
+ &va_dec1_mux, va_macro_enable_dec,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_SUPPLY_S("VA_MCLK", -1, SND_SOC_NOPM, 0, 0,
+ va_macro_mclk_event,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+};
+
+static const struct snd_soc_dapm_widget va_macro_dapm_widgets_v2[] = {
+ SND_SOC_DAPM_MIXER("VA_AIF1_CAP Mixer", SND_SOC_NOPM,
+ VA_MACRO_AIF1_CAP, 0,
+ va_aif1_cap_mixer_v2, ARRAY_SIZE(va_aif1_cap_mixer_v2)),
+
+ SND_SOC_DAPM_MIXER("VA_AIF2_CAP Mixer", SND_SOC_NOPM,
+ VA_MACRO_AIF2_CAP, 0,
+ va_aif2_cap_mixer_v2, ARRAY_SIZE(va_aif2_cap_mixer_v2)),
+
+ SND_SOC_DAPM_MIXER("VA_AIF3_CAP Mixer", SND_SOC_NOPM,
+ VA_MACRO_AIF3_CAP, 0,
+ va_aif3_cap_mixer_v2, ARRAY_SIZE(va_aif3_cap_mixer_v2)),
+
+ SND_SOC_DAPM_SUPPLY_S("VA_SWR_PWR", -1, SND_SOC_NOPM, 0, 0,
+ va_macro_swr_pwr_event_v2,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_SUPPLY_S("VA_TX_SWR_CLK", 0, SND_SOC_NOPM, 0, 0,
+ va_macro_tx_swr_clk_event_v2,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+};
+
+static const struct snd_soc_dapm_widget va_macro_dapm_widgets_v3[] = {
+ SND_SOC_DAPM_MIXER("VA_AIF1_CAP Mixer", SND_SOC_NOPM,
+ VA_MACRO_AIF1_CAP, 0,
+ va_aif1_cap_mixer_v3, ARRAY_SIZE(va_aif1_cap_mixer_v3)),
+
+ SND_SOC_DAPM_MIXER("VA_AIF2_CAP Mixer", SND_SOC_NOPM,
+ VA_MACRO_AIF2_CAP, 0,
+ va_aif2_cap_mixer_v3, ARRAY_SIZE(va_aif2_cap_mixer_v3)),
+
+ SND_SOC_DAPM_MIXER("VA_AIF3_CAP Mixer", SND_SOC_NOPM,
+ VA_MACRO_AIF3_CAP, 0,
+ va_aif3_cap_mixer_v3, ARRAY_SIZE(va_aif3_cap_mixer_v3)),
+
+ VA_MACRO_DAPM_MUX("VA DMIC MUX2", 0, va_dmic2),
+ VA_MACRO_DAPM_MUX("VA DMIC MUX3", 0, va_dmic3),
+
+ VA_MACRO_DAPM_MUX("VA SMIC MUX2", 0, va_smic2_v3),
+ VA_MACRO_DAPM_MUX("VA SMIC MUX3", 0, va_smic3_v3),
+
+ SND_SOC_DAPM_MUX_E("VA DEC2 MUX", SND_SOC_NOPM, VA_MACRO_DEC2, 0,
+ &va_dec2_mux, va_macro_enable_dec,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_MUX_E("VA DEC3 MUX", SND_SOC_NOPM, VA_MACRO_DEC3, 0,
+ &va_dec3_mux, va_macro_enable_dec,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
+ SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_SUPPLY_S("VA_SWR_PWR", -1, SND_SOC_NOPM, 0, 0,
+ va_macro_swr_pwr_event,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+};
+
static const struct snd_soc_dapm_widget va_macro_dapm_widgets[] = {
SND_SOC_DAPM_AIF_OUT_E("VA_AIF1 CAP", "VA_AIF1 Capture", 0,
SND_SOC_NOPM, VA_MACRO_AIF1_CAP, 0,
@@ -1329,6 +1875,146 @@
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
};
+static const struct snd_soc_dapm_route va_audio_map_common[] = {
+ {"VA_AIF1 CAP", NULL, "VA_MCLK"},
+ {"VA_AIF2 CAP", NULL, "VA_MCLK"},
+ {"VA_AIF3 CAP", NULL, "VA_MCLK"},
+
+ {"VA_AIF1 CAP", NULL, "VA_AIF1_CAP Mixer"},
+ {"VA_AIF2 CAP", NULL, "VA_AIF2_CAP Mixer"},
+ {"VA_AIF3 CAP", NULL, "VA_AIF3_CAP Mixer"},
+
+ {"VA_AIF1_CAP Mixer", "DEC0", "VA DEC0 MUX"},
+ {"VA_AIF1_CAP Mixer", "DEC1", "VA DEC1 MUX"},
+
+ {"VA_AIF2_CAP Mixer", "DEC0", "VA DEC0 MUX"},
+ {"VA_AIF2_CAP Mixer", "DEC1", "VA DEC1 MUX"},
+
+ {"VA_AIF3_CAP Mixer", "DEC0", "VA DEC0 MUX"},
+ {"VA_AIF3_CAP Mixer", "DEC1", "VA DEC1 MUX"},
+
+ {"VA DEC0 MUX", "MSM_DMIC", "VA DMIC MUX0"},
+ {"VA DMIC MUX0", "DMIC0", "VA DMIC0"},
+ {"VA DMIC MUX0", "DMIC1", "VA DMIC1"},
+ {"VA DMIC MUX0", "DMIC2", "VA DMIC2"},
+ {"VA DMIC MUX0", "DMIC3", "VA DMIC3"},
+ {"VA DMIC MUX0", "DMIC4", "VA DMIC4"},
+ {"VA DMIC MUX0", "DMIC5", "VA DMIC5"},
+ {"VA DMIC MUX0", "DMIC6", "VA DMIC6"},
+ {"VA DMIC MUX0", "DMIC7", "VA DMIC7"},
+
+ {"VA DEC0 MUX", "SWR_MIC", "VA SMIC MUX0"},
+ {"VA SMIC MUX0", "SWR_MIC0", "VA SWR_MIC0"},
+ {"VA SMIC MUX0", "SWR_MIC1", "VA SWR_MIC1"},
+ {"VA SMIC MUX0", "SWR_MIC2", "VA SWR_MIC2"},
+ {"VA SMIC MUX0", "SWR_MIC3", "VA SWR_MIC3"},
+ {"VA SMIC MUX0", "SWR_MIC4", "VA SWR_MIC4"},
+ {"VA SMIC MUX0", "SWR_MIC5", "VA SWR_MIC5"},
+ {"VA SMIC MUX0", "SWR_MIC6", "VA SWR_MIC6"},
+ {"VA SMIC MUX0", "SWR_MIC7", "VA SWR_MIC7"},
+ {"VA SMIC MUX0", "SWR_MIC8", "VA SWR_MIC8"},
+ {"VA SMIC MUX0", "SWR_MIC9", "VA SWR_MIC9"},
+ {"VA SMIC MUX0", "SWR_MIC10", "VA SWR_MIC10"},
+ {"VA SMIC MUX0", "SWR_MIC11", "VA SWR_MIC11"},
+
+ {"VA DEC1 MUX", "MSM_DMIC", "VA DMIC MUX1"},
+ {"VA DMIC MUX1", "DMIC0", "VA DMIC0"},
+ {"VA DMIC MUX1", "DMIC1", "VA DMIC1"},
+ {"VA DMIC MUX1", "DMIC2", "VA DMIC2"},
+ {"VA DMIC MUX1", "DMIC3", "VA DMIC3"},
+ {"VA DMIC MUX1", "DMIC4", "VA DMIC4"},
+ {"VA DMIC MUX1", "DMIC5", "VA DMIC5"},
+ {"VA DMIC MUX1", "DMIC6", "VA DMIC6"},
+ {"VA DMIC MUX1", "DMIC7", "VA DMIC7"},
+
+ {"VA DEC1 MUX", "SWR_MIC", "VA SMIC MUX1"},
+ {"VA SMIC MUX1", "SWR_MIC0", "VA SWR_MIC0"},
+ {"VA SMIC MUX1", "SWR_MIC1", "VA SWR_MIC1"},
+ {"VA SMIC MUX1", "SWR_MIC2", "VA SWR_MIC2"},
+ {"VA SMIC MUX1", "SWR_MIC3", "VA SWR_MIC3"},
+ {"VA SMIC MUX1", "SWR_MIC4", "VA SWR_MIC4"},
+ {"VA SMIC MUX1", "SWR_MIC5", "VA SWR_MIC5"},
+ {"VA SMIC MUX1", "SWR_MIC6", "VA SWR_MIC6"},
+ {"VA SMIC MUX1", "SWR_MIC7", "VA SWR_MIC7"},
+ {"VA SMIC MUX1", "SWR_MIC8", "VA SWR_MIC8"},
+ {"VA SMIC MUX1", "SWR_MIC9", "VA SWR_MIC9"},
+ {"VA SMIC MUX1", "SWR_MIC10", "VA SWR_MIC10"},
+ {"VA SMIC MUX1", "SWR_MIC11", "VA SWR_MIC11"},
+
+ {"VA SWR_MIC0", NULL, "VA_SWR_PWR"},
+ {"VA SWR_MIC1", NULL, "VA_SWR_PWR"},
+ {"VA SWR_MIC2", NULL, "VA_SWR_PWR"},
+ {"VA SWR_MIC3", NULL, "VA_SWR_PWR"},
+ {"VA SWR_MIC4", NULL, "VA_SWR_PWR"},
+ {"VA SWR_MIC5", NULL, "VA_SWR_PWR"},
+ {"VA SWR_MIC6", NULL, "VA_SWR_PWR"},
+ {"VA SWR_MIC7", NULL, "VA_SWR_PWR"},
+ {"VA SWR_MIC8", NULL, "VA_SWR_PWR"},
+ {"VA SWR_MIC9", NULL, "VA_SWR_PWR"},
+ {"VA SWR_MIC10", NULL, "VA_SWR_PWR"},
+ {"VA SWR_MIC11", NULL, "VA_SWR_PWR"},
+
+};
+
+static const struct snd_soc_dapm_route va_audio_map_v3[] = {
+ {"VA_AIF1_CAP Mixer", "DEC2", "VA DEC2 MUX"},
+ {"VA_AIF1_CAP Mixer", "DEC3", "VA DEC3 MUX"},
+
+ {"VA_AIF2_CAP Mixer", "DEC2", "VA DEC2 MUX"},
+ {"VA_AIF2_CAP Mixer", "DEC3", "VA DEC3 MUX"},
+
+ {"VA_AIF3_CAP Mixer", "DEC2", "VA DEC2 MUX"},
+ {"VA_AIF3_CAP Mixer", "DEC3", "VA DEC3 MUX"},
+
+ {"VA DEC2 MUX", "MSM_DMIC", "VA DMIC MUX2"},
+ {"VA DMIC MUX2", "DMIC0", "VA DMIC0"},
+ {"VA DMIC MUX2", "DMIC1", "VA DMIC1"},
+ {"VA DMIC MUX2", "DMIC2", "VA DMIC2"},
+ {"VA DMIC MUX2", "DMIC3", "VA DMIC3"},
+ {"VA DMIC MUX2", "DMIC4", "VA DMIC4"},
+ {"VA DMIC MUX2", "DMIC5", "VA DMIC5"},
+ {"VA DMIC MUX2", "DMIC6", "VA DMIC6"},
+ {"VA DMIC MUX2", "DMIC7", "VA DMIC7"},
+
+ {"VA DEC2 MUX", "SWR_MIC", "VA SMIC MUX2"},
+ {"VA SMIC MUX2", "SWR_MIC0", "VA SWR_MIC0"},
+ {"VA SMIC MUX2", "SWR_MIC1", "VA SWR_MIC1"},
+ {"VA SMIC MUX2", "SWR_MIC2", "VA SWR_MIC2"},
+ {"VA SMIC MUX2", "SWR_MIC3", "VA SWR_MIC3"},
+ {"VA SMIC MUX2", "SWR_MIC4", "VA SWR_MIC4"},
+ {"VA SMIC MUX2", "SWR_MIC5", "VA SWR_MIC5"},
+ {"VA SMIC MUX2", "SWR_MIC6", "VA SWR_MIC6"},
+ {"VA SMIC MUX2", "SWR_MIC7", "VA SWR_MIC7"},
+ {"VA SMIC MUX2", "SWR_MIC8", "VA SWR_MIC8"},
+ {"VA SMIC MUX2", "SWR_MIC9", "VA SWR_MIC9"},
+ {"VA SMIC MUX2", "SWR_MIC10", "VA SWR_MIC10"},
+ {"VA SMIC MUX2", "SWR_MIC11", "VA SWR_MIC11"},
+
+ {"VA DEC3 MUX", "MSM_DMIC", "VA DMIC MUX3"},
+ {"VA DMIC MUX3", "DMIC0", "VA DMIC0"},
+ {"VA DMIC MUX3", "DMIC1", "VA DMIC1"},
+ {"VA DMIC MUX3", "DMIC2", "VA DMIC2"},
+ {"VA DMIC MUX3", "DMIC3", "VA DMIC3"},
+ {"VA DMIC MUX3", "DMIC4", "VA DMIC4"},
+ {"VA DMIC MUX3", "DMIC5", "VA DMIC5"},
+ {"VA DMIC MUX3", "DMIC6", "VA DMIC6"},
+ {"VA DMIC MUX3", "DMIC7", "VA DMIC7"},
+
+ {"VA DEC3 MUX", "SWR_MIC", "VA SMIC MUX3"},
+ {"VA SMIC MUX3", "SWR_MIC0", "VA SWR_MIC0"},
+ {"VA SMIC MUX3", "SWR_MIC1", "VA SWR_MIC1"},
+ {"VA SMIC MUX3", "SWR_MIC2", "VA SWR_MIC2"},
+ {"VA SMIC MUX3", "SWR_MIC3", "VA SWR_MIC3"},
+ {"VA SMIC MUX3", "SWR_MIC4", "VA SWR_MIC4"},
+ {"VA SMIC MUX3", "SWR_MIC5", "VA SWR_MIC5"},
+ {"VA SMIC MUX3", "SWR_MIC6", "VA SWR_MIC6"},
+ {"VA SMIC MUX3", "SWR_MIC7", "VA SWR_MIC7"},
+ {"VA SMIC MUX3", "SWR_MIC8", "VA SWR_MIC8"},
+ {"VA SMIC MUX3", "SWR_MIC9", "VA SWR_MIC9"},
+ {"VA SMIC MUX3", "SWR_MIC10", "VA SWR_MIC10"},
+ {"VA SMIC MUX3", "SWR_MIC11", "VA SWR_MIC11"},
+};
+
static const struct snd_soc_dapm_route va_audio_map[] = {
{"VA_AIF1 CAP", NULL, "VA_MCLK"},
{"VA_AIF2 CAP", NULL, "VA_MCLK"},
@@ -1590,6 +2276,24 @@
0, -84, 40, digital_gain),
};
+static const struct snd_kcontrol_new va_macro_snd_controls_common[] = {
+ SOC_SINGLE_SX_TLV("VA_DEC0 Volume",
+ BOLERO_CDC_VA_TX0_TX_VOL_CTL,
+ 0, -84, 40, digital_gain),
+ SOC_SINGLE_SX_TLV("VA_DEC1 Volume",
+ BOLERO_CDC_VA_TX1_TX_VOL_CTL,
+ 0, -84, 40, digital_gain),
+};
+
+static const struct snd_kcontrol_new va_macro_snd_controls_v3[] = {
+ SOC_SINGLE_SX_TLV("VA_DEC2 Volume",
+ BOLERO_CDC_VA_TX2_TX_VOL_CTL,
+ 0, -84, 40, digital_gain),
+ SOC_SINGLE_SX_TLV("VA_DEC3 Volume",
+ BOLERO_CDC_VA_TX3_TX_VOL_CTL,
+ 0, -84, 40, digital_gain),
+};
+
static int va_macro_validate_dmic_sample_rate(u32 dmic_sample_rate,
struct va_macro_priv *va_priv)
{
@@ -1674,18 +2378,65 @@
return 0;
}
- ret = snd_soc_dapm_new_controls(dapm, va_macro_dapm_widgets,
+ va_priv->version = bolero_get_version(va_dev);
+ if (va_priv->version >= BOLERO_VERSION_2_0) {
+ ret = snd_soc_dapm_new_controls(dapm,
+ va_macro_dapm_widgets_common,
+ ARRAY_SIZE(va_macro_dapm_widgets_common));
+ if (ret < 0) {
+ dev_err(va_dev, "%s: Failed to add controls\n",
+ __func__);
+ return ret;
+ }
+ if (va_priv->version == BOLERO_VERSION_2_1)
+ ret = snd_soc_dapm_new_controls(dapm,
+ va_macro_dapm_widgets_v2,
+ ARRAY_SIZE(va_macro_dapm_widgets_v2));
+ else if (va_priv->version == BOLERO_VERSION_2_0)
+ ret = snd_soc_dapm_new_controls(dapm,
+ va_macro_dapm_widgets_v3,
+ ARRAY_SIZE(va_macro_dapm_widgets_v3));
+ if (ret < 0) {
+ dev_err(va_dev, "%s: Failed to add controls\n",
+ __func__);
+ return ret;
+ }
+ } else {
+ ret = snd_soc_dapm_new_controls(dapm, va_macro_dapm_widgets,
ARRAY_SIZE(va_macro_dapm_widgets));
- if (ret < 0) {
- dev_err(va_dev, "%s: Failed to add controls\n", __func__);
- return ret;
+ if (ret < 0) {
+ dev_err(va_dev, "%s: Failed to add controls\n",
+ __func__);
+ return ret;
+ }
}
- ret = snd_soc_dapm_add_routes(dapm, va_audio_map,
+ if (va_priv->version >= BOLERO_VERSION_2_0) {
+ ret = snd_soc_dapm_add_routes(dapm,
+ va_audio_map_common,
+ ARRAY_SIZE(va_audio_map_common));
+ if (ret < 0) {
+ dev_err(va_dev, "%s: Failed to add routes\n",
+ __func__);
+ return ret;
+ }
+ if (va_priv->version == BOLERO_VERSION_2_0)
+ ret = snd_soc_dapm_add_routes(dapm,
+ va_audio_map_v3,
+ ARRAY_SIZE(va_audio_map_v3));
+ if (ret < 0) {
+ dev_err(va_dev, "%s: Failed to add routes\n",
+ __func__);
+ return ret;
+ }
+ } else {
+ ret = snd_soc_dapm_add_routes(dapm, va_audio_map,
ARRAY_SIZE(va_audio_map));
- if (ret < 0) {
- dev_err(va_dev, "%s: Failed to add routes\n", __func__);
- return ret;
+ if (ret < 0) {
+ dev_err(va_dev, "%s: Failed to add routes\n",
+ __func__);
+ return ret;
+ }
}
ret = snd_soc_dapm_new_widgets(dapm->card);
@@ -1693,28 +2444,65 @@
dev_err(va_dev, "%s: Failed to add widgets\n", __func__);
return ret;
}
- ret = snd_soc_add_component_controls(component, va_macro_snd_controls,
- ARRAY_SIZE(va_macro_snd_controls));
- if (ret < 0) {
- dev_err(va_dev, "%s: Failed to add snd_ctls\n", __func__);
- return ret;
+ if (va_priv->version >= BOLERO_VERSION_2_0) {
+ ret = snd_soc_add_component_controls(component,
+ va_macro_snd_controls_common,
+ ARRAY_SIZE(va_macro_snd_controls_common));
+ if (ret < 0) {
+ dev_err(va_dev, "%s: Failed to add snd_ctls\n",
+ __func__);
+ return ret;
+ }
+ if (va_priv->version == BOLERO_VERSION_2_0)
+ ret = snd_soc_add_component_controls(component,
+ va_macro_snd_controls_v3,
+ ARRAY_SIZE(va_macro_snd_controls_v3));
+ if (ret < 0) {
+ dev_err(va_dev, "%s: Failed to add snd_ctls\n",
+ __func__);
+ return ret;
+ }
+ } else {
+ ret = snd_soc_add_component_controls(component,
+ va_macro_snd_controls,
+ ARRAY_SIZE(va_macro_snd_controls));
+ if (ret < 0) {
+ dev_err(va_dev, "%s: Failed to add snd_ctls\n",
+ __func__);
+ return ret;
+ }
}
snd_soc_dapm_ignore_suspend(dapm, "VA_AIF1 Capture");
snd_soc_dapm_ignore_suspend(dapm, "VA_AIF2 Capture");
snd_soc_dapm_ignore_suspend(dapm, "VA_AIF3 Capture");
- snd_soc_dapm_ignore_suspend(dapm, "VA SWR_ADC0");
- snd_soc_dapm_ignore_suspend(dapm, "VA SWR_ADC1");
- snd_soc_dapm_ignore_suspend(dapm, "VA SWR_ADC2");
- snd_soc_dapm_ignore_suspend(dapm, "VA SWR_ADC3");
- snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC0");
- snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC1");
- snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC2");
- snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC3");
- snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC4");
- snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC5");
- snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC6");
- snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC7");
+ if (va_priv->version >= BOLERO_VERSION_2_0) {
+ snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC0");
+ snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC1");
+ snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC2");
+ snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC3");
+ snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC4");
+ snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC5");
+ snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC6");
+ snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC7");
+ snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC8");
+ snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC9");
+ snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC10");
+ snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC11");
+ } else {
+ snd_soc_dapm_ignore_suspend(dapm, "VA SWR_ADC0");
+ snd_soc_dapm_ignore_suspend(dapm, "VA SWR_ADC1");
+ snd_soc_dapm_ignore_suspend(dapm, "VA SWR_ADC2");
+ snd_soc_dapm_ignore_suspend(dapm, "VA SWR_ADC3");
+ snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC0");
+ snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC1");
+ snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC2");
+ snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC3");
+ snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC4");
+ snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC5");
+ snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC6");
+ snd_soc_dapm_ignore_suspend(dapm, "VA SWR_MIC7");
+ }
snd_soc_dapm_sync(dapm);
for (i = 0; i < VA_MACRO_NUM_DECIMATORS; i++) {
@@ -1747,6 +2535,156 @@
return 0;
}
+static void va_macro_add_child_devices(struct work_struct *work)
+{
+ struct va_macro_priv *va_priv = NULL;
+ struct platform_device *pdev = NULL;
+ struct device_node *node = NULL;
+ struct va_macro_swr_ctrl_data *swr_ctrl_data = NULL, *temp = NULL;
+ int ret = 0;
+ u16 count = 0, ctrl_num = 0;
+ struct va_macro_swr_ctrl_platform_data *platdata = NULL;
+ char plat_dev_name[VA_MACRO_SWR_STRING_LEN] = "";
+ bool va_swr_master_node = false;
+
+ va_priv = container_of(work, struct va_macro_priv,
+ va_macro_add_child_devices_work);
+ if (!va_priv) {
+ pr_err("%s: Memory for va_priv does not exist\n",
+ __func__);
+ return;
+ }
+
+ if (!va_priv->dev) {
+ pr_err("%s: VA dev does not exist\n", __func__);
+ return;
+ }
+
+ if (!va_priv->dev->of_node) {
+ dev_err(va_priv->dev,
+ "%s: DT node for va_priv does not exist\n", __func__);
+ return;
+ }
+
+ platdata = &va_priv->swr_plat_data;
+ va_priv->child_count = 0;
+
+ for_each_available_child_of_node(va_priv->dev->of_node, node) {
+ va_swr_master_node = false;
+ if (strnstr(node->name, "va_swr_master",
+ strlen("va_swr_master")) != NULL)
+ va_swr_master_node = true;
+
+ if (va_swr_master_node)
+ strlcpy(plat_dev_name, "va_swr_ctrl",
+ (VA_MACRO_SWR_STRING_LEN - 1));
+ else
+ strlcpy(plat_dev_name, node->name,
+ (VA_MACRO_SWR_STRING_LEN - 1));
+
+ pdev = platform_device_alloc(plat_dev_name, -1);
+ if (!pdev) {
+ dev_err(va_priv->dev, "%s: pdev memory alloc failed\n",
+ __func__);
+ ret = -ENOMEM;
+ goto err;
+ }
+ pdev->dev.parent = va_priv->dev;
+ pdev->dev.of_node = node;
+
+ if (va_swr_master_node) {
+ ret = platform_device_add_data(pdev, platdata,
+ sizeof(*platdata));
+ if (ret) {
+ dev_err(&pdev->dev,
+ "%s: cannot add plat data ctrl:%d\n",
+ __func__, ctrl_num);
+ goto fail_pdev_add;
+ }
+ }
+
+ ret = platform_device_add(pdev);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "%s: Cannot add platform device\n",
+ __func__);
+ goto fail_pdev_add;
+ }
+
+ if (va_swr_master_node) {
+ temp = krealloc(swr_ctrl_data,
+ (ctrl_num + 1) * sizeof(
+ struct va_macro_swr_ctrl_data),
+ GFP_KERNEL);
+ if (!temp) {
+ ret = -ENOMEM;
+ goto fail_pdev_add;
+ }
+ swr_ctrl_data = temp;
+ swr_ctrl_data[ctrl_num].va_swr_pdev = pdev;
+ ctrl_num++;
+ dev_dbg(&pdev->dev,
+ "%s: Added soundwire ctrl device(s)\n",
+ __func__);
+ va_priv->swr_ctrl_data = swr_ctrl_data;
+ }
+ if (va_priv->child_count < VA_MACRO_CHILD_DEVICES_MAX)
+ va_priv->pdev_child_devices[
+ va_priv->child_count++] = pdev;
+ else
+ goto err;
+ }
+ return;
+fail_pdev_add:
+ for (count = 0; count < va_priv->child_count; count++)
+ platform_device_put(va_priv->pdev_child_devices[count]);
+err:
+ return;
+}
+
+static int va_macro_set_port_map(struct snd_soc_component *component,
+ u32 usecase, u32 size, void *data)
+{
+ struct device *va_dev = NULL;
+ struct va_macro_priv *va_priv = NULL;
+ struct swrm_port_config port_cfg;
+ int ret = 0;
+
+ if (!va_macro_get_data(component, &va_dev, &va_priv, __func__))
+ return -EINVAL;
+
+ memset(&port_cfg, 0, sizeof(port_cfg));
+ port_cfg.uc = usecase;
+ port_cfg.size = size;
+ port_cfg.params = data;
+
+ if (va_priv->swr_ctrl_data)
+ ret = swrm_wcd_notify(
+ va_priv->swr_ctrl_data[0].va_swr_pdev,
+ SWR_SET_PORT_MAP, &port_cfg);
+
+ return ret;
+}
+
+static int va_macro_reg_wake_irq(struct snd_soc_component *component,
+ u32 data)
+{
+ struct device *va_dev = NULL;
+ struct va_macro_priv *va_priv = NULL;
+ u32 ipc_wakeup = data;
+ int ret = 0;
+
+ if (!va_macro_get_data(component, &va_dev, &va_priv, __func__))
+ return -EINVAL;
+
+ if (va_priv->swr_ctrl_data)
+ ret = swrm_wcd_notify(
+ va_priv->swr_ctrl_data[0].va_swr_pdev,
+ SWR_REGISTER_WAKE_IRQ, &ipc_wakeup);
+
+ return ret;
+}
+
static void va_macro_init_ops(struct macro_ops *ops,
char __iomem *va_io_base,
bool va_without_decimation)
@@ -1763,6 +2701,8 @@
ops->exit = va_macro_deinit;
ops->io_base = va_io_base;
ops->event_handler = va_macro_event_handler;
+ ops->set_port_map = va_macro_set_port_map;
+ ops->reg_wake_irq = va_macro_reg_wake_irq;
}
static int va_macro_probe(struct platform_device *pdev)
@@ -1780,6 +2720,8 @@
const char *dmic_sample_rate = "qcom,va-dmic-sample-rate";
u32 default_clk_id = 0;
struct clk *lpass_audio_hw_vote = NULL;
+ u32 is_used_va_swr_gpio = 0;
+ const char *is_used_va_swr_gpio_dt = "qcom,is-used-swr-gpio";
va_priv = devm_kzalloc(&pdev->dev, sizeof(struct va_macro_priv),
GFP_KERNEL);
@@ -1810,6 +2752,31 @@
return -EINVAL;
}
+ if (of_find_property(pdev->dev.of_node, is_used_va_swr_gpio_dt,
+ NULL)) {
+ ret = of_property_read_u32(pdev->dev.of_node,
+ is_used_va_swr_gpio_dt,
+ &is_used_va_swr_gpio);
+ if (ret) {
+ dev_err(&pdev->dev, "%s: error reading %s in dt\n",
+ __func__, is_used_va_swr_gpio_dt);
+ is_used_va_swr_gpio = 0;
+ }
+ }
+ va_priv->va_swr_gpio_p = of_parse_phandle(pdev->dev.of_node,
+ "qcom,va-swr-gpios", 0);
+ if (!va_priv->va_swr_gpio_p && is_used_va_swr_gpio) {
+ dev_err(&pdev->dev, "%s: swr_gpios handle not provided!\n",
+ __func__);
+ return -EINVAL;
+ }
+ if ((msm_cdc_pinctrl_get_state(va_priv->va_swr_gpio_p) < 0) &&
+ is_used_va_swr_gpio) {
+ dev_err(&pdev->dev, "%s: failed to get swr pin state\n",
+ __func__);
+ return -EPROBE_DEFER;
+ }
+
va_io_base = devm_ioremap(&pdev->dev, va_base_addr,
VA_MACRO_MAX_OFFSET);
if (!va_io_base) {
@@ -1869,6 +2836,20 @@
va_priv->clk_id = VA_CORE_CLK;
va_priv->default_clk_id = default_clk_id;
+ if (is_used_va_swr_gpio) {
+ va_priv->reset_swr = true;
+ INIT_WORK(&va_priv->va_macro_add_child_devices_work,
+ va_macro_add_child_devices);
+ va_priv->swr_plat_data.handle = (void *) va_priv;
+ va_priv->swr_plat_data.read = NULL;
+ va_priv->swr_plat_data.write = NULL;
+ va_priv->swr_plat_data.bulk_write = NULL;
+ va_priv->swr_plat_data.clk = va_macro_swrm_clock;
+ va_priv->swr_plat_data.handle_irq = NULL;
+ mutex_init(&va_priv->swr_clk_lock);
+ }
+ va_priv->is_used_va_swr_gpio = is_used_va_swr_gpio;
+
mutex_init(&va_priv->mclk_lock);
dev_set_drvdata(&pdev->dev, va_priv);
va_macro_init_ops(&ops, va_io_base, va_without_decimation);
@@ -1879,29 +2860,46 @@
dev_err(&pdev->dev, "%s: register macro failed\n", __func__);
goto reg_macro_fail;
}
+ if (is_used_va_swr_gpio)
+ schedule_work(&va_priv->va_macro_add_child_devices_work);
pm_runtime_set_autosuspend_delay(&pdev->dev, VA_AUTO_SUSPEND_DELAY);
pm_runtime_use_autosuspend(&pdev->dev);
pm_runtime_set_suspended(&pdev->dev);
+ pm_suspend_ignore_children(&pdev->dev, true);
pm_runtime_enable(&pdev->dev);
return ret;
reg_macro_fail:
mutex_destroy(&va_priv->mclk_lock);
+ if (is_used_va_swr_gpio)
+ mutex_destroy(&va_priv->swr_clk_lock);
return ret;
}
static int va_macro_remove(struct platform_device *pdev)
{
struct va_macro_priv *va_priv;
+ int count = 0;
va_priv = dev_get_drvdata(&pdev->dev);
if (!va_priv)
return -EINVAL;
+ if (va_priv->is_used_va_swr_gpio) {
+ if (va_priv->swr_ctrl_data)
+ kfree(va_priv->swr_ctrl_data);
+ for (count = 0; count < va_priv->child_count &&
+ count < VA_MACRO_CHILD_DEVICES_MAX; count++)
+ platform_device_unregister(
+ va_priv->pdev_child_devices[count]);
+ }
+
pm_runtime_disable(&pdev->dev);
pm_runtime_set_suspended(&pdev->dev);
bolero_unregister_macro(&pdev->dev, VA_MACRO);
mutex_destroy(&va_priv->mclk_lock);
+ if (va_priv->is_used_va_swr_gpio)
+ mutex_destroy(&va_priv->swr_clk_lock);
return 0;
}
diff --git a/asoc/codecs/msm-cdc-pinctrl.c b/asoc/codecs/msm-cdc-pinctrl.c
index a10a681..cb7a52b 100644
--- a/asoc/codecs/msm-cdc-pinctrl.c
+++ b/asoc/codecs/msm-cdc-pinctrl.c
@@ -4,6 +4,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
+#include <linux/io.h>
#include <linux/err.h>
#include <linux/module.h>
#include <linux/of.h>
@@ -23,8 +24,12 @@
int gpio;
bool state;
u32 tlmm_gpio[MAX_GPIOS];
+ char __iomem *chip_wakeup_register[MAX_GPIOS];
+ u32 chip_wakeup_maskbit[MAX_GPIOS];
u32 count;
+ u32 wakeup_reg_count;
bool wakeup_capable;
+ bool chip_wakeup_reg;
};
static struct msm_cdc_pinctrl_info *msm_cdc_pinctrl_get_gpiodata(
@@ -154,7 +159,7 @@
{
struct msm_cdc_pinctrl_info *gpio_data;
int ret = 0;
- u32 i = 0;
+ u32 i = 0, temp = 0;
gpio_data = msm_cdc_pinctrl_get_gpiodata(np);
if (!gpio_data)
@@ -168,6 +173,18 @@
goto exit;
}
}
+ if (gpio_data->chip_wakeup_reg) {
+ for (i = 0; i < gpio_data->wakeup_reg_count; i++) {
+ temp = ioread32(gpio_data->chip_wakeup_register[i]);
+ if (enable)
+ temp |= (1 <<
+ gpio_data->chip_wakeup_maskbit[i]);
+ else
+ temp &= ~(1 <<
+ gpio_data->chip_wakeup_maskbit[i]);
+ iowrite32(temp, gpio_data->chip_wakeup_register[i]);
+ }
+ }
exit:
return ret;
}
@@ -178,6 +195,7 @@
int ret = 0;
struct msm_cdc_pinctrl_info *gpio_data;
u32 tlmm_gpio[MAX_GPIOS] = {0};
+ u32 chip_wakeup_reg[MAX_GPIOS] = {0};
u32 i = 0;
int count = 0;
@@ -223,6 +241,27 @@
}
+ count = of_property_count_u32_elems(pdev->dev.of_node, "qcom,chip-wakeup-reg");
+ if (count <= 0)
+ goto cdc_tlmm_gpio;
+ if (!of_property_read_u32_array(pdev->dev.of_node, "qcom,chip-wakeup-reg",
+ chip_wakeup_reg, count)) {
+ if (of_property_read_u32_array(pdev->dev.of_node,
+ "qcom,chip-wakeup-maskbit",
+ gpio_data->chip_wakeup_maskbit, count)) {
+ dev_err(&pdev->dev,
+ "chip-wakeup-maskbit needed if chip-wakeup-reg is defined!\n");
+ goto cdc_tlmm_gpio;
+ }
+ gpio_data->chip_wakeup_reg = true;
+ for (i = 0; i < count; i++) {
+ gpio_data->chip_wakeup_register[i] =
+ devm_ioremap(&pdev->dev, chip_wakeup_reg[i], 0x4);
+ }
+ gpio_data->wakeup_reg_count = count;
+ }
+
+cdc_tlmm_gpio:
count = of_property_count_u32_elems(pdev->dev.of_node, "qcom,tlmm-gpio");
if (count <= 0)
goto cdc_rst;
diff --git a/asoc/codecs/wcd-mbhc-adc.c b/asoc/codecs/wcd-mbhc-adc.c
index 4de19de..9652d11 100644
--- a/asoc/codecs/wcd-mbhc-adc.c
+++ b/asoc/codecs/wcd-mbhc-adc.c
@@ -689,6 +689,13 @@
}
correct_plug_type:
+ /*
+ * Callback to disable BCS slow insertion detection
+ */
+ if (plug_type == MBHC_PLUG_TYPE_HEADSET ||
+ plug_type == MBHC_PLUG_TYPE_HEADPHONE)
+ mbhc->mbhc_cb->bcs_enable(mbhc, false);
+
timeout = jiffies + msecs_to_jiffies(HS_DETECT_PLUG_TIME_MS);
while (!time_after(jiffies, timeout)) {
if (mbhc->hs_detect_work_stop) {
@@ -833,6 +840,10 @@
wrk_complete = false;
}
}
+ if ((plug_type == MBHC_PLUG_TYPE_HEADSET ||
+ plug_type == MBHC_PLUG_TYPE_HEADPHONE))
+ mbhc->mbhc_cb->bcs_enable(mbhc, true);
+
if (!wrk_complete) {
/*
* If plug_tye is headset, we might have already reported either
diff --git a/asoc/codecs/wcd-mbhc-v2.c b/asoc/codecs/wcd-mbhc-v2.c
index 01544aa..ed98deb 100644
--- a/asoc/codecs/wcd-mbhc-v2.c
+++ b/asoc/codecs/wcd-mbhc-v2.c
@@ -1055,6 +1055,10 @@
struct wcd_mbhc *mbhc = data;
pr_debug("%s: enter\n", __func__);
+ if (mbhc == NULL) {
+ pr_err("%s: NULL irq data\n", __func__);
+ return IRQ_NONE;
+ }
if (unlikely((mbhc->mbhc_cb->lock_sleep(mbhc, true)) == false)) {
pr_warn("%s: failed to hold suspend\n", __func__);
r = IRQ_NONE;
diff --git a/asoc/codecs/wcd-spi.c b/asoc/codecs/wcd-spi.c
index 0173e15..4c7a853 100644
--- a/asoc/codecs/wcd-spi.c
+++ b/asoc/codecs/wcd-spi.c
@@ -815,6 +815,15 @@
return -EINVAL;
}
+ WCD_SPI_MUTEX_LOCK(spi, wcd_spi->clk_mutex);
+ if (wcd_spi_is_suspended(wcd_spi)) {
+ dev_dbg(&spi->dev,
+ "%s: SPI suspended, cannot perform transfer\n",
+ __func__);
+ ret = -EIO;
+ goto done;
+ }
+
WCD_SPI_MUTEX_LOCK(spi, wcd_spi->xfer_mutex);
if (msg->len == WCD_SPI_WORD_BYTE_CNT) {
if (xfer_req == WCD_SPI_XFER_WRITE)
@@ -827,7 +836,8 @@
ret = wcd_spi_transfer_split(spi, msg, xfer_req);
}
WCD_SPI_MUTEX_UNLOCK(spi, wcd_spi->xfer_mutex);
-
+done:
+ WCD_SPI_MUTEX_UNLOCK(spi, wcd_spi->clk_mutex);
return ret;
}
diff --git a/asoc/codecs/wcd938x/internal.h b/asoc/codecs/wcd938x/internal.h
index 098a60d..46d61a0 100644
--- a/asoc/codecs/wcd938x/internal.h
+++ b/asoc/codecs/wcd938x/internal.h
@@ -149,6 +149,7 @@
WCD_BOLERO_EVT_IMPED_TRUE, /* for imped true */
WCD_BOLERO_EVT_IMPED_FALSE, /* for imped false */
WCD_BOLERO_EVT_RX_COMPANDER_SOFT_RST,
+ WCD_BOLERO_EVT_BCS_CLK_OFF,
};
enum {
@@ -182,6 +183,9 @@
extern struct wcd938x_mbhc *wcd938x_soc_get_mbhc(
struct snd_soc_component *component);
+extern void wcd938x_disable_bcs_before_slow_insert(
+ struct snd_soc_component *component,
+ bool bcs_disable);
extern int wcd938x_mbhc_micb_adjust_voltage(struct snd_soc_component *component,
int volt, int micb_num);
extern int wcd938x_get_micb_vout_ctl_val(u32 micb_mv);
diff --git a/asoc/codecs/wcd938x/wcd938x-mbhc.c b/asoc/codecs/wcd938x/wcd938x-mbhc.c
index 27566ee..0687de6 100644
--- a/asoc/codecs/wcd938x/wcd938x-mbhc.c
+++ b/asoc/codecs/wcd938x/wcd938x-mbhc.c
@@ -803,6 +803,15 @@
0x04, (enable << 2));
}
+static void wcd938x_mbhc_bcs_enable(struct wcd_mbhc *mbhc,
+ bool bcs_enable)
+{
+ if (bcs_enable)
+ wcd938x_disable_bcs_before_slow_insert(mbhc->component, false);
+ else
+ wcd938x_disable_bcs_before_slow_insert(mbhc->component, true);
+}
+
static const struct wcd_mbhc_cb mbhc_cb = {
.request_irq = wcd938x_mbhc_request_irq,
.irq_control = wcd938x_mbhc_irq_control,
@@ -827,6 +836,7 @@
.mbhc_get_moisture_status = wcd938x_mbhc_get_moisture_status,
.mbhc_moisture_polling_ctrl = wcd938x_mbhc_moisture_polling_ctrl,
.mbhc_moisture_detect_en = wcd938x_mbhc_moisture_detect_en,
+ .bcs_enable = wcd938x_mbhc_bcs_enable,
};
static int wcd938x_get_hph_type(struct snd_kcontrol *kcontrol,
diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c
index 04954d9..ae88d7c 100644
--- a/asoc/codecs/wcd938x/wcd938x.c
+++ b/asoc/codecs/wcd938x/wcd938x.c
@@ -1523,6 +1523,21 @@
return 0;
}
+void wcd938x_disable_bcs_before_slow_insert(struct snd_soc_component *component,
+ bool bcs_disable)
+{
+ struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
+
+ if (wcd938x->update_wcd_event) {
+ if (bcs_disable)
+ wcd938x->update_wcd_event(wcd938x->handle,
+ WCD_BOLERO_EVT_BCS_CLK_OFF, 0);
+ else
+ wcd938x->update_wcd_event(wcd938x->handle,
+ WCD_BOLERO_EVT_BCS_CLK_OFF, 1);
+ }
+}
+
int wcd938x_tx_channel_config(struct snd_soc_component *component,
int channel, int mode)
{
@@ -1627,18 +1642,30 @@
switch (w->shift) {
case 0:
snd_soc_component_update_bits(component,
+ WCD938X_DIGITAL_CDC_TX_ANA_MODE_0_1, 0x0F,
+ 0x00);
+ snd_soc_component_update_bits(component,
WCD938X_DIGITAL_CDC_DIG_CLK_CTL, 0x10, 0x00);
break;
case 1:
snd_soc_component_update_bits(component,
+ WCD938X_DIGITAL_CDC_TX_ANA_MODE_0_1, 0xF0,
+ 0x00);
+ snd_soc_component_update_bits(component,
WCD938X_DIGITAL_CDC_DIG_CLK_CTL, 0x20, 0x00);
break;
case 2:
snd_soc_component_update_bits(component,
+ WCD938X_DIGITAL_CDC_TX_ANA_MODE_2_3, 0x0F,
+ 0x00);
+ snd_soc_component_update_bits(component,
WCD938X_DIGITAL_CDC_DIG_CLK_CTL, 0x40, 0x00);
break;
case 3:
snd_soc_component_update_bits(component,
+ WCD938X_DIGITAL_CDC_TX_ANA_MODE_2_3, 0xF0,
+ 0x00);
+ snd_soc_component_update_bits(component,
WCD938X_DIGITAL_CDC_DIG_CLK_CTL, 0x80, 0x00);
break;
default:
diff --git a/asoc/codecs/wcd_cpe_core.c b/asoc/codecs/wcd_cpe_core.c
index 4c776d1..5b5291f 100644
--- a/asoc/codecs/wcd_cpe_core.c
+++ b/asoc/codecs/wcd_cpe_core.c
@@ -2896,6 +2896,7 @@
struct cmi_obm_msg obm_msg;
struct cpe_param_data *param_d;
+ memset(&obm_msg, 0, sizeof(obm_msg));
ret = fill_cmi_header(&obm_msg.hdr, session->id,
CMI_CPE_LSM_SERVICE_ID, 0, 20,
diff --git a/asoc/msm-dai-q6-v2.c b/asoc/msm-dai-q6-v2.c
index 12fbf35..b35a1e8 100644
--- a/asoc/msm-dai-q6-v2.c
+++ b/asoc/msm-dai-q6-v2.c
@@ -5510,6 +5510,10 @@
dai_data->port_config.i2s.bit_width = 24;
dai_data->bitwidth = 24;
break;
+ case SNDRV_PCM_FORMAT_S32_LE:
+ dai_data->port_config.i2s.bit_width = 32;
+ dai_data->bitwidth = 32;
+ break;
default:
pr_err("%s: format %d\n",
__func__, params_format(params));
diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c
index 79ddd89..ae86f7a 100644
--- a/asoc/msm-pcm-routing-v2.c
+++ b/asoc/msm-pcm-routing-v2.c
@@ -123,6 +123,7 @@
#define VA_CDC_DMA_TX_2_TEXT "VA_CDC_DMA_TX_2"
#define TX_CDC_DMA_TX_3_TEXT "TX_CDC_DMA_TX_3"
#define QUIN_TDM_TX_TEXT "QUIN_TDM_TX_0"
+#define TERT_TDM_TX_TEXT "TERT_TDM_TX_0"
#define LSM_FUNCTION_TEXT "LSM Function"
static const char * const lsm_port_text[] = {
@@ -131,7 +132,8 @@
SLIMBUS_3_TX_TEXT, SLIMBUS_4_TX_TEXT, SLIMBUS_5_TX_TEXT,
TERT_MI2S_TX_TEXT, QUAT_MI2S_TX_TEXT, ADM_LSM_TX_TEXT,
INT3_MI2S_TX_TEXT, VA_CDC_DMA_TX_0_TEXT, VA_CDC_DMA_TX_1_TEXT,
- VA_CDC_DMA_TX_2_TEXT, TX_CDC_DMA_TX_3_TEXT, QUIN_TDM_TX_TEXT
+ VA_CDC_DMA_TX_2_TEXT, TX_CDC_DMA_TX_3_TEXT, QUIN_TDM_TX_TEXT,
+ TERT_TDM_TX_TEXT
};
struct msm_pcm_route_bdai_pp_params {
@@ -2056,7 +2058,13 @@
pr_debug("%s: reg %x val %x set %x\n", __func__, reg, val, set);
- if (!is_mm_lsm_fe_id(val)) {
+ if (val == MSM_FRONTEND_DAI_DTMF_RX &&
+ afe_get_port_type(msm_bedais[reg].port_id) ==
+ MSM_AFE_PORT_TYPE_RX) {
+ pr_debug("%s(): set=%d port id=0x%x for dtmf generation\n",
+ __func__, set, msm_bedais[reg].port_id);
+ afe_set_dtmf_gen_rx_portid(msm_bedais[reg].port_id, set);
+ } else if (!is_mm_lsm_fe_id(val)) {
/* recheck FE ID in the mixer control defined in this file */
pr_err("%s: bad MM ID\n", __func__);
return;
@@ -3026,6 +3034,9 @@
case 15:
lsm_port = AFE_PORT_ID_QUINARY_TDM_TX;
break;
+ case 16:
+ lsm_port = AFE_PORT_ID_TERTIARY_TDM_TX;
+ break;
default:
pr_err("Default lsm port");
break;
@@ -3043,7 +3054,7 @@
u16 port_id;
enum afe_mad_type mad_type;
- pr_debug("%s: enter\n", __func__);
+ pr_debug("%s: id name %s\n", __func__, kcontrol->id.name);
for (i = 0; i < ARRAY_SIZE(lsm_port_text); i++)
if (!strnstr(kcontrol->id.name, lsm_port_text[i],
strlen(lsm_port_text[i])))
@@ -3070,14 +3081,18 @@
strlen(lsm_port_text[10])))
port_id = AFE_PORT_ID_INT3_MI2S_TX;
- if (strnstr(kcontrol->id.name, lsm_port_text[13],
- strlen(lsm_port_text[13])))
- port_id = AFE_PORT_ID_TX_CODEC_DMA_TX_3;
-
if (strnstr(kcontrol->id.name, lsm_port_text[14],
strlen(lsm_port_text[14])))
+ port_id = AFE_PORT_ID_TX_CODEC_DMA_TX_3;
+
+ if (strnstr(kcontrol->id.name, lsm_port_text[15],
+ strlen(lsm_port_text[15])))
port_id = AFE_PORT_ID_QUINARY_TDM_TX;
+ if (strnstr(kcontrol->id.name, lsm_port_text[16],
+ strlen(lsm_port_text[16])))
+ port_id = AFE_PORT_ID_TERTIARY_TDM_TX;
+
mad_type = afe_port_get_mad_type(port_id);
pr_debug("%s: port_id 0x%x, mad_type %d\n", __func__, port_id,
mad_type);
@@ -3111,7 +3126,7 @@
u16 port_id;
enum afe_mad_type mad_type;
- pr_debug("%s: enter\n", __func__);
+ pr_debug("%s: id name %s\n", __func__, kcontrol->id.name);
for (i = 0; i < ARRAY_SIZE(lsm_port_text); i++)
if (strnstr(kcontrol->id.name, lsm_port_text[i],
strlen(lsm_port_text[i])))
@@ -3158,14 +3173,18 @@
strlen(lsm_port_text[10])))
port_id = AFE_PORT_ID_INT3_MI2S_TX;
- if (strnstr(kcontrol->id.name, lsm_port_text[13],
- strlen(lsm_port_text[13])))
- port_id = AFE_PORT_ID_TX_CODEC_DMA_TX_3;
-
if (strnstr(kcontrol->id.name, lsm_port_text[14],
strlen(lsm_port_text[14])))
+ port_id = AFE_PORT_ID_TX_CODEC_DMA_TX_3;
+
+ if (strnstr(kcontrol->id.name, lsm_port_text[15],
+ strlen(lsm_port_text[15])))
port_id = AFE_PORT_ID_QUINARY_TDM_TX;
+ if (strnstr(kcontrol->id.name, lsm_port_text[16],
+ strlen(lsm_port_text[16])))
+ port_id = AFE_PORT_ID_TERTIARY_TDM_TX;
+
pr_debug("%s: port_id 0x%x, mad_type %d\n", __func__, port_id,
mad_type);
return afe_port_set_mad_type(port_id, mad_type);
@@ -7040,7 +7059,10 @@
MSM_BACKEND_DAI_PRI_MI2S_RX,
MSM_FRONTEND_DAI_MULTIMEDIA30, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
-
+ SOC_DOUBLE_EXT("DTMF", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_PRI_MI2S_RX,
+ MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
};
static const struct snd_kcontrol_new int0_mi2s_rx_mixer_controls[] = {
@@ -7607,6 +7629,10 @@
MSM_BACKEND_DAI_VOICE_PLAYBACK_TX,
MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_VOICE_PLAYBACK_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM,
MSM_BACKEND_DAI_VOICE_PLAYBACK_TX,
MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
@@ -11191,6 +11217,73 @@
msm_routing_put_audio_mixer),
};
+static const struct snd_kcontrol_new quin_tdm_tx_1_mixer_controls[] = {
+ SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_QUIN_TDM_TX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_QUIN_TDM_TX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_QUIN_TDM_TX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_QUIN_TDM_TX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_QUIN_TDM_TX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_QUIN_TDM_TX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_QUIN_TDM_TX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_QUIN_TDM_TX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_QUIN_TDM_TX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_QUIN_TDM_TX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_QUIN_TDM_TX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_QUIN_TDM_TX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_QUIN_TDM_TX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_QUIN_TDM_TX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_QUIN_TDM_TX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_QUIN_TDM_TX_1,
+ MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+};
+
static const struct snd_kcontrol_new quin_tdm_rx_1_mixer_controls[] = {
SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM,
MSM_BACKEND_DAI_QUIN_TDM_RX_1,
@@ -11270,6 +11363,73 @@
msm_routing_put_audio_mixer),
};
+static const struct snd_kcontrol_new quin_tdm_tx_2_mixer_controls[] = {
+ SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_QUIN_TDM_TX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_QUIN_TDM_TX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_QUIN_TDM_TX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_QUIN_TDM_TX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_QUIN_TDM_TX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_QUIN_TDM_TX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_QUIN_TDM_TX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_QUIN_TDM_TX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_QUIN_TDM_TX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_QUIN_TDM_TX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_QUIN_TDM_TX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_QUIN_TDM_TX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_QUIN_TDM_TX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_QUIN_TDM_TX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_QUIN_TDM_TX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_QUIN_TDM_TX_2,
+ MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+};
+
static const struct snd_kcontrol_new quin_tdm_rx_2_mixer_controls[] = {
SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM,
MSM_BACKEND_DAI_QUIN_TDM_RX_2,
@@ -11349,6 +11509,73 @@
msm_routing_put_audio_mixer),
};
+static const struct snd_kcontrol_new quin_tdm_tx_3_mixer_controls[] = {
+ SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_QUIN_TDM_TX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("MultiMedia2", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_QUIN_TDM_TX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("MultiMedia3", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_QUIN_TDM_TX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("MultiMedia4", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_QUIN_TDM_TX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("MultiMedia5", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_QUIN_TDM_TX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("MultiMedia6", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_QUIN_TDM_TX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("MultiMedia7", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_QUIN_TDM_TX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("MultiMedia8", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_QUIN_TDM_TX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("MultiMedia9", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_QUIN_TDM_TX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("MultiMedia10", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_QUIN_TDM_TX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("MultiMedia11", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_QUIN_TDM_TX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("MultiMedia12", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_QUIN_TDM_TX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("MultiMedia13", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_QUIN_TDM_TX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("MultiMedia14", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_QUIN_TDM_TX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("MultiMedia15", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_QUIN_TDM_TX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("MultiMedia16", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_QUIN_TDM_TX_3,
+ MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+};
+
static const struct snd_kcontrol_new quin_tdm_rx_3_mixer_controls[] = {
SOC_DOUBLE_EXT("MultiMedia1", SND_SOC_NOPM,
MSM_BACKEND_DAI_QUIN_TDM_RX_3,
@@ -15843,6 +16070,13 @@
msm_routing_put_voice_mixer),
};
+static const struct snd_kcontrol_new quin_tdm_rx_2_voice_mixer_controls[] = {
+ SOC_DOUBLE_EXT("VoiceMMode1", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_QUIN_TDM_RX_2,
+ MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer,
+ msm_routing_put_voice_mixer),
+};
+
static const struct snd_kcontrol_new wsa_cdc_dma_rx_0_voice_mixer_controls[] = {
SOC_DOUBLE_EXT("Voip", SND_SOC_NOPM,
MSM_BACKEND_DAI_WSA_CDC_DMA_RX_0,
@@ -20786,6 +21020,10 @@
MSM_BACKEND_DAI_QUIN_TDM_TX_0,
MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer,
msm_routing_put_listen_mixer),
+ SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_TERT_TDM_TX_0,
+ MSM_FRONTEND_DAI_LSM1, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
};
static const struct snd_kcontrol_new lsm2_mixer_controls[] = {
@@ -20842,6 +21080,10 @@
MSM_BACKEND_DAI_QUIN_TDM_TX_0,
MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer,
msm_routing_put_listen_mixer),
+ SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_TERT_TDM_TX_0,
+ MSM_FRONTEND_DAI_LSM2, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
};
static const struct snd_kcontrol_new lsm3_mixer_controls[] = {
@@ -20897,6 +21139,10 @@
MSM_BACKEND_DAI_QUIN_TDM_TX_0,
MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer,
msm_routing_put_listen_mixer),
+ SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_TERT_TDM_TX_0,
+ MSM_FRONTEND_DAI_LSM3, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
};
static const struct snd_kcontrol_new lsm4_mixer_controls[] = {
@@ -20952,6 +21198,10 @@
MSM_BACKEND_DAI_QUIN_TDM_TX_0,
MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer,
msm_routing_put_listen_mixer),
+ SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_TERT_TDM_TX_0,
+ MSM_FRONTEND_DAI_LSM4, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
};
static const struct snd_kcontrol_new lsm5_mixer_controls[] = {
@@ -21007,6 +21257,10 @@
MSM_BACKEND_DAI_QUIN_TDM_TX_0,
MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer,
msm_routing_put_listen_mixer),
+ SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_TERT_TDM_TX_0,
+ MSM_FRONTEND_DAI_LSM5, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
};
static const struct snd_kcontrol_new lsm6_mixer_controls[] = {
@@ -21062,6 +21316,10 @@
MSM_BACKEND_DAI_QUIN_TDM_TX_0,
MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer,
msm_routing_put_listen_mixer),
+ SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_TERT_TDM_TX_0,
+ MSM_FRONTEND_DAI_LSM6, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
};
static const struct snd_kcontrol_new lsm7_mixer_controls[] = {
@@ -21117,6 +21375,10 @@
MSM_BACKEND_DAI_QUIN_TDM_TX_0,
MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer,
msm_routing_put_listen_mixer),
+ SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_TERT_TDM_TX_0,
+ MSM_FRONTEND_DAI_LSM7, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
};
static const struct snd_kcontrol_new lsm8_mixer_controls[] = {
@@ -21172,6 +21434,10 @@
MSM_BACKEND_DAI_QUIN_TDM_TX_0,
MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer,
msm_routing_put_listen_mixer),
+ SOC_DOUBLE_EXT("TERT_TDM_TX_0", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_TERT_TDM_TX_0,
+ MSM_FRONTEND_DAI_LSM8, 1, 0, msm_routing_get_listen_mixer,
+ msm_routing_put_listen_mixer),
};
static const struct snd_kcontrol_new slim_fm_switch_mixer_controls =
@@ -21322,6 +21588,8 @@
msm_routing_lsm_func_get, msm_routing_lsm_func_put),
SOC_ENUM_EXT(QUIN_TDM_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum,
msm_routing_lsm_func_get, msm_routing_lsm_func_put),
+ SOC_ENUM_EXT(TERT_TDM_TX_TEXT" "LSM_FUNCTION_TEXT, lsm_func_enum,
+ msm_routing_lsm_func_get, msm_routing_lsm_func_put),
/* kcontrol of lsm_port */
SOC_ENUM_EXT("LSM1 Port", lsm_port_enum,
msm_routing_lsm_port_get,
@@ -23701,12 +23969,21 @@
SND_SOC_DAPM_MIXER("QUIN_TDM_RX_1 Audio Mixer", SND_SOC_NOPM, 0, 0,
quin_tdm_rx_1_mixer_controls,
ARRAY_SIZE(quin_tdm_rx_1_mixer_controls)),
+ SND_SOC_DAPM_MIXER("QUIN_TDM_TX_1 Audio Mixer", SND_SOC_NOPM, 0, 0,
+ quin_tdm_tx_1_mixer_controls,
+ ARRAY_SIZE(quin_tdm_tx_1_mixer_controls)),
SND_SOC_DAPM_MIXER("QUIN_TDM_RX_2 Audio Mixer", SND_SOC_NOPM, 0, 0,
quin_tdm_rx_2_mixer_controls,
ARRAY_SIZE(quin_tdm_rx_2_mixer_controls)),
+ SND_SOC_DAPM_MIXER("QUIN_TDM_TX_2 Audio Mixer", SND_SOC_NOPM, 0, 0,
+ quin_tdm_tx_2_mixer_controls,
+ ARRAY_SIZE(quin_tdm_tx_2_mixer_controls)),
SND_SOC_DAPM_MIXER("QUIN_TDM_RX_3 Audio Mixer", SND_SOC_NOPM, 0, 0,
quin_tdm_rx_3_mixer_controls,
ARRAY_SIZE(quin_tdm_rx_3_mixer_controls)),
+ SND_SOC_DAPM_MIXER("QUIN_TDM_TX_3 Audio Mixer", SND_SOC_NOPM, 0, 0,
+ quin_tdm_tx_3_mixer_controls,
+ ARRAY_SIZE(quin_tdm_tx_3_mixer_controls)),
SND_SOC_DAPM_MIXER("SEN_TDM_TX_0 Audio Mixer", SND_SOC_NOPM, 0, 0,
sen_tdm_tx_0_mixer_controls,
ARRAY_SIZE(sen_tdm_tx_0_mixer_controls)),
@@ -23934,6 +24211,10 @@
SND_SOC_NOPM, 0, 0,
quat_tdm_rx_2_voice_mixer_controls,
ARRAY_SIZE(quat_tdm_rx_2_voice_mixer_controls)),
+ SND_SOC_DAPM_MIXER("QUIN_TDM_RX_2_Voice Mixer",
+ SND_SOC_NOPM, 0, 0,
+ quin_tdm_rx_2_voice_mixer_controls,
+ ARRAY_SIZE(quin_tdm_rx_2_voice_mixer_controls)),
SND_SOC_DAPM_MIXER("WSA_CDC_DMA_RX_0_Voice Mixer",
SND_SOC_NOPM, 0, 0,
wsa_cdc_dma_rx_0_voice_mixer_controls,
@@ -24614,6 +24895,7 @@
/* incall */
{"Incall_Music Audio Mixer", "MultiMedia1", "MM_DL1"},
{"Incall_Music Audio Mixer", "MultiMedia2", "MM_DL2"},
+ {"Incall_Music Audio Mixer", "MultiMedia4", "MM_DL4"},
{"Incall_Music Audio Mixer", "MultiMedia5", "MM_DL5"},
{"Incall_Music Audio Mixer", "MultiMedia9", "MM_DL9"},
{"VOICE_PLAYBACK_TX", NULL, "Incall_Music Audio Mixer"},
@@ -24880,6 +25162,7 @@
{"PRI_MI2S_RX Audio Mixer", "MultiMedia16", "MM_DL16"},
{"PRI_MI2S_RX Audio Mixer", "MultiMedia26", "MM_DL26"},
{"PRI_MI2S_RX", NULL, "PRI_MI2S_RX Audio Mixer"},
+ {"PRI_MI2S_RX Audio Mixer", "DTMF", "DTMF_DL_HL"},
{"INT0_MI2S_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
{"INT0_MI2S_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
@@ -26712,6 +26995,9 @@
{"QUAT_TDM_RX_2_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"},
{"QUAT_TDM_RX_2", NULL, "QUAT_TDM_RX_2_Voice Mixer"},
+ {"QUIN_TDM_RX_2_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"},
+ {"QUIN_TDM_RX_2", NULL, "QUIN_TDM_RX_2_Voice Mixer"},
+
{"WSA_CDC_DMA_RX_0_Voice Mixer", "Voip", "VOIP_DL"},
{"WSA_CDC_DMA_RX_0_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"},
{"WSA_CDC_DMA_RX_0_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"},
@@ -26974,6 +27260,7 @@
{"LSM1 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"},
{"LSM1 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"},
{"LSM1 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"},
+ {"LSM1 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"},
{"LSM1_UL_HL", NULL, "LSM1 Mixer"},
{"LSM2 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"},
@@ -26989,6 +27276,7 @@
{"LSM2 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"},
{"LSM2 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"},
{"LSM2 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"},
+ {"LSM2 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"},
{"LSM2_UL_HL", NULL, "LSM2 Mixer"},
@@ -27005,6 +27293,7 @@
{"LSM3 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"},
{"LSM3 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"},
{"LSM3 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"},
+ {"LSM3 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"},
{"LSM3_UL_HL", NULL, "LSM3 Mixer"},
@@ -27021,6 +27310,7 @@
{"LSM4 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"},
{"LSM4 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"},
{"LSM4 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"},
+ {"LSM4 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"},
{"LSM4_UL_HL", NULL, "LSM4 Mixer"},
{"LSM5 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"},
@@ -27036,6 +27326,7 @@
{"LSM5 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"},
{"LSM5 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"},
{"LSM5 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"},
+ {"LSM5 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"},
{"LSM5_UL_HL", NULL, "LSM5 Mixer"},
{"LSM6 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"},
@@ -27049,6 +27340,7 @@
{"LSM6 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"},
{"LSM6 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"},
{"LSM6 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"},
+ {"LSM6 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"},
{"LSM6_UL_HL", NULL, "LSM6 Mixer"},
{"LSM7 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"},
@@ -27062,6 +27354,7 @@
{"LSM7 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"},
{"LSM7 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"},
{"LSM7 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"},
+ {"LSM7 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"},
{"LSM7_UL_HL", NULL, "LSM7 Mixer"},
{"LSM8 Mixer", "SLIMBUS_0_TX", "SLIMBUS_0_TX"},
@@ -27075,6 +27368,7 @@
{"LSM8 Mixer", "VA_CDC_DMA_TX_2", "VA_CDC_DMA_TX_2"},
{"LSM8 Mixer", "TX_CDC_DMA_TX_3", "TX_CDC_DMA_TX_3"},
{"LSM8 Mixer", "QUIN_TDM_TX_0", "QUIN_TDM_TX_0"},
+ {"LSM8 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"},
{"LSM8_UL_HL", NULL, "LSM8 Mixer"},
@@ -28871,6 +29165,11 @@
uint32_t be_idx = ucontrol->value.integer.value[0];
int i;
+ if (be_idx >= MSM_BACKEND_DAI_MAX) {
+ pr_err("%s: Invalid Backend index %d\n", __func__, be_idx);
+ return -EINVAL;
+ }
+
for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL_V8; i++) {
channel_map[i] = (char)(ucontrol->value.integer.value[i + 1]);
if (channel_map[i] > PCM_MAX_CHMAP_ID) {
diff --git a/asoc/msm-pcm-voice-v2.c b/asoc/msm-pcm-voice-v2.c
index f8acc30..5a25b3e 100644
--- a/asoc/msm-pcm-voice-v2.c
+++ b/asoc/msm-pcm-voice-v2.c
@@ -582,6 +582,20 @@
return 0;
}
+static int msm_voice_ecns_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ uint32_t enable = ucontrol->value.integer.value[0];
+ uint32_t session_id = ucontrol->value.integer.value[1];
+ uint32_t module_id = ucontrol->value.integer.value[2];
+
+ pr_debug("%s: ecns enable=%d session_id=%#x\n", __func__, enable,
+ session_id);
+ voc_set_ecns_enable(session_id, module_id, enable);
+
+ return 0;
+}
+
static int msm_voice_hd_voice_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
@@ -695,6 +709,8 @@
msm_voice_tty_mode_put),
SOC_SINGLE_MULTI_EXT("Slowtalk Enable", SND_SOC_NOPM, 0, VSID_MAX, 0, 2,
NULL, msm_voice_slowtalk_put),
+ SOC_SINGLE_MULTI_EXT("Voice ECNS Enable", SND_SOC_NOPM, 0, VSID_MAX, 0, 3,
+ NULL, msm_voice_ecns_put),
SOC_SINGLE_MULTI_EXT("Voice Topology Disable", SND_SOC_NOPM, 0,
VSID_MAX, 0, 2, NULL,
msm_voice_topology_disable_put),
diff --git a/dsp/avtimer.c b/dsp/avtimer.c
index ad5e13a..e1d032d 100644
--- a/dsp/avtimer.c
+++ b/dsp/avtimer.c
@@ -271,6 +271,7 @@
rc = avcs_core_disable_avtimer(
avtimer.timer_handle);
avtimer.timer_handle = 0;
+ atomic_set(&avtimer.adsp_ready, 0);
}
}
}
diff --git a/dsp/q6afe.c b/dsp/q6afe.c
index ccc91cf..6111832 100644
--- a/dsp/q6afe.c
+++ b/dsp/q6afe.c
@@ -2897,7 +2897,8 @@
if (port_id == AFE_PORT_ID_TERTIARY_MI2S_TX ||
port_id == AFE_PORT_ID_INT3_MI2S_TX ||
- port_id == AFE_PORT_ID_TX_CODEC_DMA_TX_3) {
+ port_id == AFE_PORT_ID_TX_CODEC_DMA_TX_3 ||
+ port_id == AFE_PORT_ID_TERTIARY_TDM_TX) {
mad_type = MAD_SW_AUDIO;
return 0;
}
@@ -2926,7 +2927,8 @@
if (port_id == AFE_PORT_ID_TERTIARY_MI2S_TX ||
port_id == AFE_PORT_ID_INT3_MI2S_TX ||
- port_id == AFE_PORT_ID_TX_CODEC_DMA_TX_3)
+ port_id == AFE_PORT_ID_TX_CODEC_DMA_TX_3 ||
+ port_id == AFE_PORT_ID_TERTIARY_TDM_TX)
return MAD_SW_AUDIO;
i = port_id - SLIMBUS_0_RX;
diff --git a/dsp/q6voice.c b/dsp/q6voice.c
index 3db75d0..77a08ee 100644
--- a/dsp/q6voice.c
+++ b/dsp/q6voice.c
@@ -110,6 +110,10 @@
static int voice_send_set_pp_enable_cmd(
struct voice_data *v, struct module_instance_info mod_inst_info,
int enable);
+
+static int voice_send_cvp_ecns_enable_cmd(struct voice_data *v,
+ uint32_t module_id, int enable);
+
static int is_cal_memory_allocated(void);
static bool is_cvd_version_queried(void);
static int is_voip_memory_allocated(void);
@@ -1544,6 +1548,124 @@
return ret;
}
+static int voice_send_cvp_ecns_enable_cmd(struct voice_data *v,
+ uint32_t module_id, int enable)
+{
+ int ret;
+ struct cvp_set_channel_ecns_cmd_v2 cvp_set_ch_ecns_cmd;
+ void *apr_cvp;
+ u16 cvp_handle;
+ struct vss_icommon_param_data_ecns_t *cvp_config_param_data =
+ &cvp_set_ch_ecns_cmd.
+ cvp_set_ecns.param_data;
+
+ if (v == NULL) {
+ pr_err("%s: v is NULL\n", __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ apr_cvp = common.apr_q6_cvp;
+
+ if (!apr_cvp) {
+ pr_err("%s: apr_cvp is NULL\n", __func__);
+ ret = -EINVAL;
+ goto done;
+ }
+
+ cvp_handle = voice_get_cvp_handle(v);
+ memset(&cvp_set_ch_ecns_cmd, 0,
+ sizeof(cvp_set_ch_ecns_cmd));
+
+ cvp_set_ch_ecns_cmd.hdr.hdr_field =
+ APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
+ APR_HDR_LEN(APR_HDR_SIZE),
+ APR_PKT_VER);
+ cvp_set_ch_ecns_cmd.hdr.pkt_size =
+ APR_PKT_SIZE(APR_HDR_SIZE,
+ sizeof(cvp_set_ch_ecns_cmd) - APR_HDR_SIZE);
+ cvp_set_ch_ecns_cmd.hdr.src_svc = 0;
+ cvp_set_ch_ecns_cmd.hdr.src_domain = APR_DOMAIN_APPS;
+ cvp_set_ch_ecns_cmd.hdr.src_port =
+ voice_get_idx_for_session(v->session_id);
+ cvp_set_ch_ecns_cmd.hdr.dest_svc = 0;
+ cvp_set_ch_ecns_cmd.hdr.dest_domain = APR_DOMAIN_ADSP;
+ cvp_set_ch_ecns_cmd.hdr.dest_port = cvp_handle;
+ cvp_set_ch_ecns_cmd.hdr.token = 0;
+ cvp_set_ch_ecns_cmd.hdr.opcode = VSS_ICOMMON_CMD_SET_PARAM_V2;
+ cvp_set_ch_ecns_cmd.cvp_set_ecns.mem_size =
+ sizeof(struct vss_icommon_param_data_ecns_t);
+
+ cvp_config_param_data->module_id = module_id;
+ cvp_config_param_data->param_id = VOICE_PARAM_MOD_ENABLE;
+ cvp_config_param_data->param_size = MOD_ENABLE_PARAM_LEN;
+ cvp_config_param_data->reserved = 0;
+ cvp_config_param_data->enable = enable;
+
+ v->cvp_state = CMD_STATUS_FAIL;
+ v->async_err = 0;
+ ret = apr_send_pkt(apr_cvp, (uint32_t *)&cvp_set_ch_ecns_cmd);
+
+ if (ret < 0) {
+ pr_err("%s: Failed to send VSS_ICOMMON_CMD_SET_PARAM_V2 %d\n",
+ __func__, ret);
+ goto done;
+ }
+ ret = wait_event_timeout(v->cvp_wait,
+ (v->cvp_state == CMD_STATUS_SUCCESS),
+ msecs_to_jiffies(TIMEOUT_MS));
+
+ if (!ret) {
+ pr_err("%s: wait_event timeout\n", __func__);
+ ret = -ETIMEDOUT;
+ goto done;
+ }
+
+ if (v->async_err > 0) {
+ pr_err("%s: DSP returned error[%s] handle = %d\n", __func__,
+ adsp_err_get_err_str(v->async_err), cvp_handle);
+ ret = adsp_err_get_lnx_err_code(v->async_err);
+ goto done;
+ }
+ ret = 0;
+done:
+ return ret;
+}
+
+/**
+ * voc_set_ecns_enable -
+ * Command to set ECNS for voice module
+ *
+ * @session_id: voice session ID to send this command
+ * @module_id: voice module id
+ * @enable: enable/disable flag
+ *
+ * Returns 0 on success or error on failure
+ */
+int voc_set_ecns_enable(uint32_t session_id, uint32_t module_id,
+ uint32_t enable)
+{
+ struct voice_data *v = voice_get_session(session_id);
+ int ret = 0;
+
+ if (v == NULL) {
+ pr_err("%s: invalid session_id 0x%x\n", __func__, session_id);
+ return -EINVAL;
+ }
+ mutex_lock(&v->lock);
+ v->ecns_enable = enable;
+ v->ecns_module_id = module_id;
+
+ if (is_voc_state_active(v->voc_state))
+ ret = voice_send_cvp_ecns_enable_cmd(v,
+ v->ecns_module_id, v->ecns_enable);
+
+ mutex_unlock(&v->lock);
+
+ return ret;
+}
+EXPORT_SYMBOL(voc_set_ecns_enable);
+
static int voice_send_set_pp_enable_cmd(
struct voice_data *v, struct module_instance_info mod_inst_info,
int enable)
@@ -4420,6 +4542,10 @@
if (v->dtmf_rx_detect_en)
voice_send_dtmf_rx_detection_cmd(v, v->dtmf_rx_detect_en);
+ if (v->ecns_enable)
+ voice_send_cvp_ecns_enable_cmd(v, v->ecns_module_id,
+ v->ecns_enable);
+
if (v->hd_enable)
voice_send_hd_cmd(v, v->hd_enable);
@@ -5076,6 +5202,9 @@
if (v->dtmf_rx_detect_en)
voice_send_dtmf_rx_detection_cmd(v, 0);
+ if (v->ecns_enable)
+ voice_send_cvp_ecns_enable_cmd(v, v->ecns_module_id, 0);
+
/* detach VOCPROC and wait for response from mvm */
mvm_d_vocproc_cmd.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD,
APR_HDR_LEN(APR_HDR_SIZE),
diff --git a/include/asoc/wcd-mbhc-v2.h b/include/asoc/wcd-mbhc-v2.h
index 1f9d64e..f3ee728 100644
--- a/include/asoc/wcd-mbhc-v2.h
+++ b/include/asoc/wcd-mbhc-v2.h
@@ -451,6 +451,8 @@
};
struct wcd_mbhc_cb {
+ void (*bcs_enable)
+ (struct wcd_mbhc *mbhc, bool bcs_enable);
int (*enable_mb_source)(struct wcd_mbhc *mbhc, bool turn_on);
void (*trim_btn_reg)(struct snd_soc_component *component);
void (*compute_impedance)(struct wcd_mbhc *mbhc,
diff --git a/include/dsp/q6voice.h b/include/dsp/q6voice.h
index 2edfbe2..35ace4e 100644
--- a/include/dsp/q6voice.h
+++ b/include/dsp/q6voice.h
@@ -312,6 +312,21 @@
struct vss_param_channel_mixer_info_t ch_mixer_info;
} __packed;
+struct vss_icommon_param_data_ecns_t {
+ /* Valid ID of the module. */
+ uint32_t module_id;
+ /* Valid ID of the parameter. */
+ uint32_t param_id;
+ /*
+ * Data size of the structure relating to the param_id/module_id
+ * combination in uint8_t bytes.
+ */
+ uint16_t param_size;
+ /* This field must be set to zero. */
+ uint16_t reserved;
+ uint32_t enable;
+} __packed;
+
struct vss_icommon_cmd_set_param_ch_mixer_v2_t {
/*
* Pointer to the unique identifier for an address (physical/virtual).
@@ -338,6 +353,33 @@
struct vss_icommon_param_data_ch_mixer_v2_t param_data;
} __packed;
+
+struct vss_icommon_cmd_set_ecns_enable_t {
+ /*
+ * Pointer to the unique identifier for an address (physical/virtual).
+ *
+ * If the parameter data payload is within the message payload
+ * (in-band), set this field to 0. The parameter data begins at the
+ * specified data payload address.
+ *
+ * If the parameter data is out-of-band, this field is the handle to
+ * the physical address in the shared memory that holds the parameter
+ * data.
+ */
+ uint32_t mem_handle;
+ /*
+ * Location of the parameter data payload.
+ *
+ * The payload is an array of vss_icommon_param_data_t. If the
+ * mem_handle is 0, this field is ignored.
+ */
+ uint64_t mem_address;
+ /* Size of the parameter data payload in bytes. */
+ uint32_t mem_size;
+
+ struct vss_icommon_param_data_ecns_t param_data;
+} __packed;
+
struct vss_icommon_param_data_mfc_config_v2_t {
/* Valid ID of the module. */
uint32_t module_id;
@@ -809,6 +851,7 @@
#define MODULE_ID_VOICE_MODULE_ST 0x00010EE3
#define VOICE_PARAM_MOD_ENABLE 0x00010E00
+#define MOD_ENABLE_PARAM_LEN 4
#define VSS_IPLAYBACK_CMD_START 0x000112BD
/* Start in-call music delivery on the Tx voice path. */
@@ -1679,6 +1722,11 @@
struct apr_hdr hdr;
} __packed;
+struct cvp_set_channel_ecns_cmd_v2 {
+ struct apr_hdr hdr;
+ struct vss_icommon_cmd_set_ecns_enable_t cvp_set_ecns;
+} __packed;
+
struct cvp_set_rx_volume_index_cmd {
struct apr_hdr hdr;
struct vss_ivocproc_cmd_set_volume_index_t cvp_set_vol_idx;
@@ -1894,6 +1942,10 @@
bool mic_break_status;
struct work_struct voice_mic_break_work;
+
+ uint32_t ecns_enable;
+ uint32_t ecns_module_id;
+
};
#define MAX_VOC_SESSIONS 8
@@ -2042,6 +2094,8 @@
int voc_set_route_flag(uint32_t session_id, uint8_t path_dir, uint8_t set);
uint8_t voc_get_route_flag(uint32_t session_id, uint8_t path_dir);
bool voc_get_mbd_enable(void);
+int voc_set_ecns_enable(uint32_t session_id, uint32_t module_id,
+ uint32_t enable);
uint8_t voc_set_mbd_enable(bool enable);
int voc_enable_dtmf_rx_detection(uint32_t session_id, uint32_t enable);
void voc_disable_dtmf_det_on_active_sessions(void);
diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c
index a3934a5..008801f 100644
--- a/soc/swr-mstr-ctrl.c
+++ b/soc/swr-mstr-ctrl.c
@@ -25,6 +25,7 @@
#include "swrm_registers.h"
#include "swr-mstr-ctrl.h"
+#define SWRM_FRAME_SYNC_SEL 4000 /* 4KHz */
#define SWRM_SYSTEM_RESUME_TIMEOUT_MS 700
#define SWRM_SYS_SUSPEND_WAIT 1
@@ -43,6 +44,13 @@
#define ERR_AUTO_SUSPEND_TIMER_VAL 0x1
#define SWRM_INTERRUPT_STATUS_MASK 0x1FDFD
+
+#define SWRM_ROW_48 48
+#define SWRM_ROW_50 50
+#define SWRM_ROW_64 64
+#define SWRM_COL_02 02
+#define SWRM_COL_16 16
+
/* pm runtime auto suspend timer in msecs */
static int auto_suspend_timer = SWR_AUTO_SUSPEND_DELAY * 1000;
module_param(auto_suspend_timer, int, 0664);
@@ -341,6 +349,16 @@
return ret;
}
+static int swrm_get_ssp_period(struct swr_mstr_ctrl *swrm,
+ int row, int col,
+ int frame_sync)
+{
+ if (!swrm || !row || !col || !frame_sync)
+ return 1;
+
+ return ((swrm->bus_clk * 2) / ((row * col) * frame_sync));
+}
+
static int swrm_clk_request(struct swr_mstr_ctrl *swrm, bool enable)
{
int ret = 0;
@@ -591,6 +609,10 @@
if (retry_attempt < MAX_FIFO_RD_FAIL_RETRY) {
/* wait 500 us before retry on fifo read failure */
usleep_range(500, 505);
+ if (retry_attempt == (MAX_FIFO_RD_FAIL_RETRY - 1)) {
+ swr_master_write(swrm, SWRM_CMD_FIFO_CMD, 0x1);
+ swr_master_write(swrm, SWRM_CMD_FIFO_RD_CMD, val);
+ }
retry_attempt++;
goto retry_read;
} else {
@@ -1093,7 +1115,9 @@
{
u8 bank;
u32 value, n_row, n_col;
+ u32 row = 0, col = 0;
int ret;
+ u8 ssp_period = 0;
struct swr_mstr_ctrl *swrm = swr_get_ctrl_data(master);
int mask = (SWRM_MCP_FRAME_CTRL_BANK_ROW_CTRL_BMSK |
SWRM_MCP_FRAME_CTRL_BANK_COL_CTRL_BMSK |
@@ -1162,30 +1186,39 @@
if (enable) {
/* set col = 16 */
n_col = SWR_MAX_COL;
+ col = SWRM_COL_16;
} else {
/*
* Do not change to col = 2 if there are still active ports
*/
- if (!master->num_port)
+ if (!master->num_port) {
n_col = SWR_MIN_COL;
- else
+ col = SWRM_COL_02;
+ } else {
n_col = SWR_MAX_COL;
+ col = SWRM_COL_16;
+ }
}
/* Use default 50 * x, frame shape. Change based on mclk */
if (swrm->mclk_freq == MCLK_FREQ_NATIVE) {
dev_dbg(swrm->dev, "setting 64 x %d frameshape\n",
n_col ? 16 : 2);
n_row = SWR_ROW_64;
+ row = SWRM_ROW_64;
} else {
dev_dbg(swrm->dev, "setting 50 x %d frameshape\n",
n_col ? 16 : 2);
n_row = SWR_ROW_50;
+ row = SWRM_ROW_50;
}
+ ssp_period = swrm_get_ssp_period(swrm, row, col, SWRM_FRAME_SYNC_SEL);
+ dev_dbg(swrm->dev, "%s: ssp_period: %d\n", __func__, ssp_period);
+
value = swr_master_read(swrm, SWRM_MCP_FRAME_CTRL_BANK_ADDR(bank));
value &= (~mask);
value |= ((n_row << SWRM_MCP_FRAME_CTRL_BANK_ROW_CTRL_SHFT) |
(n_col << SWRM_MCP_FRAME_CTRL_BANK_COL_CTRL_SHFT) |
- (0 << SWRM_MCP_FRAME_CTRL_BANK_SSP_PERIOD_SHFT));
+ ((ssp_period - 1) << SWRM_MCP_FRAME_CTRL_BANK_SSP_PERIOD_SHFT));
swr_master_write(swrm, SWRM_MCP_FRAME_CTRL_BANK_ADDR(bank), value);
dev_dbg(swrm->dev, "%s: regaddr: 0x%x, value: 0x%x\n", __func__,
@@ -1726,6 +1759,7 @@
case SWRM_INTERRUPT_STATUS_WR_CMD_FIFO_OVERFLOW:
dev_dbg(swrm->dev, "%s: SWR write FIFO overflow\n",
__func__);
+ swr_master_write(swrm, SWRM_CMD_FIFO_CMD, 0x1);
break;
case SWRM_INTERRUPT_STATUS_CMD_ERROR:
value = swr_master_read(swrm, SWRM_CMD_FIFO_STATUS);
@@ -2019,10 +2053,14 @@
u32 temp = 0;
int len = 0;
+ ssp_period = swrm_get_ssp_period(swrm, SWRM_ROW_50,
+ SWRM_COL_02, SWRM_FRAME_SYNC_SEL);
+ dev_dbg(swrm->dev, "%s: ssp_period: %d\n", __func__, ssp_period);
+
/* Clear Rows and Cols */
val = ((row_ctrl << SWRM_MCP_FRAME_CTRL_BANK_ROW_CTRL_SHFT) |
(col_ctrl << SWRM_MCP_FRAME_CTRL_BANK_COL_CTRL_SHFT) |
- (ssp_period << SWRM_MCP_FRAME_CTRL_BANK_SSP_PERIOD_SHFT));
+ ((ssp_period - 1) << SWRM_MCP_FRAME_CTRL_BANK_SSP_PERIOD_SHFT));
reg[len] = SWRM_MCP_FRAME_CTRL_BANK_ADDR(0);
value[len++] = val;
@@ -2303,6 +2341,7 @@
swrm->clk_ref_count = 0;
swrm->swr_irq_wakeup_capable = 0;
swrm->mclk_freq = MCLK_FREQ;
+ swrm->bus_clk = MCLK_FREQ;
swrm->dev_up = true;
swrm->state = SWR_MSTR_UP;
swrm->ipc_wakeup = false;
@@ -2882,6 +2921,7 @@
usleep_range(10000, 10500);
}
swrm->mclk_freq = *(int *)data;
+ swrm->bus_clk = swrm->mclk_freq;
mutex_unlock(&swrm->mlock);
}
break;
diff --git a/soc/swr-mstr-ctrl.h b/soc/swr-mstr-ctrl.h
index 43bf227..b07a80d 100644
--- a/soc/swr-mstr-ctrl.h
+++ b/soc/swr-mstr-ctrl.h
@@ -142,6 +142,7 @@
int wake_irq;
int version;
int mclk_freq;
+ int bus_clk;
u32 num_dev;
int slave_status;
struct swrm_mports mport_cfg[SWR_MAX_MSTR_PORT_NUM];