Merge "asoc: bengal: Fail SVA for fuse variant"
diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c
index 460a725..af22bb2 100644
--- a/asoc/codecs/bolero/bolero-cdc.c
+++ b/asoc/codecs/bolero/bolero-cdc.c
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-only
-/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
*/
#include <linux/of_platform.h>
@@ -991,9 +991,11 @@
*
* @component: pointer to codec component instance.
*
+ * @clk_src: 0 for TX_RCG and 1 for VA_RCG
+ *
* Returns 0 on success or -EINVAL on error.
*/
-int bolero_tx_clk_switch(struct snd_soc_component *component)
+int bolero_tx_clk_switch(struct snd_soc_component *component, int clk_src)
{
struct bolero_priv *priv = NULL;
int ret = 0;
@@ -1011,7 +1013,8 @@
}
if (priv->macro_params[TX_MACRO].clk_switch)
- ret = priv->macro_params[TX_MACRO].clk_switch(component);
+ ret = priv->macro_params[TX_MACRO].clk_switch(component,
+ clk_src);
return ret;
}
diff --git a/asoc/codecs/bolero/bolero-cdc.h b/asoc/codecs/bolero/bolero-cdc.h
index 2294594..3144d88 100644
--- a/asoc/codecs/bolero/bolero-cdc.h
+++ b/asoc/codecs/bolero/bolero-cdc.h
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0-only */
-/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
*/
#ifndef BOLERO_CDC_H
@@ -38,6 +38,11 @@
};
enum {
+ CLK_SRC_TX_RCG = 0,
+ CLK_SRC_VA_RCG,
+};
+
+enum {
BOLERO_MACRO_EVT_RX_MUTE = 1, /* for RX mute/unmute */
BOLERO_MACRO_EVT_IMPED_TRUE, /* for imped true */
BOLERO_MACRO_EVT_IMPED_FALSE, /* for imped false */
@@ -80,8 +85,8 @@
int (*reg_wake_irq)(struct snd_soc_component *component, u32 data);
int (*set_port_map)(struct snd_soc_component *component, u32 uc,
u32 size, void *data);
- int (*clk_switch)(struct snd_soc_component *component);
int (*clk_div_get)(struct snd_soc_component *component);
+ int (*clk_switch)(struct snd_soc_component *component, int clk_src);
int (*reg_evt_listener)(struct snd_soc_component *component, bool en);
int (*clk_enable)(struct snd_soc_component *c, bool en);
char __iomem *io_base;
@@ -107,7 +112,7 @@
int bolero_runtime_resume(struct device *dev);
int bolero_runtime_suspend(struct device *dev);
int bolero_set_port_map(struct snd_soc_component *component, u32 size, void *data);
-int bolero_tx_clk_switch(struct snd_soc_component *component);
+int bolero_tx_clk_switch(struct snd_soc_component *component, int clk_src);
int bolero_register_event_listener(struct snd_soc_component *component,
bool enable);
void bolero_wsa_pa_on(struct device *dev);
@@ -175,7 +180,8 @@
return 0;
}
-static inline int bolero_tx_clk_switch(struct snd_soc_component *component)
+static inline int bolero_tx_clk_switch(struct snd_soc_component *component,
+ int clk_src)
{
return 0;
}
diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c
index b2b4753..a27c3e1 100644
--- a/asoc/codecs/bolero/tx-macro.c
+++ b/asoc/codecs/bolero/tx-macro.c
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-only
-/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
*/
#include <linux/module.h>
@@ -2509,7 +2509,7 @@
return tx_priv->dmic_clk_div;
}
-static int tx_macro_clk_switch(struct snd_soc_component *component)
+static int tx_macro_clk_switch(struct snd_soc_component *component, int clk_src)
{
struct device *tx_dev = NULL;
struct tx_macro_priv *tx_priv = NULL;
@@ -2533,7 +2533,7 @@
if (tx_priv->swr_ctrl_data) {
ret = swrm_wcd_notify(
tx_priv->swr_ctrl_data[0].tx_swr_pdev,
- SWR_REQ_CLK_SWITCH, NULL);
+ SWR_REQ_CLK_SWITCH, &clk_src);
}
return ret;
diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c
index c595cad..3493a65 100644
--- a/asoc/codecs/bolero/va-macro.c
+++ b/asoc/codecs/bolero/va-macro.c
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-only
-/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
*/
#include <linux/module.h>
@@ -45,6 +45,7 @@
#define VA_MACRO_TX_DMIC_CLK_DIV_SHFT 0x01
#define VA_MACRO_SWR_MIC_MUX_SEL_MASK 0xF
#define VA_MACRO_ADC_MUX_CFG_OFFSET 0x8
+#define VA_MACRO_ADC_MODE_CFG0_SHIFT 1
#define BOLERO_CDC_VA_TX_DMIC_UNMUTE_DELAY_MS 40
#define BOLERO_CDC_VA_TX_AMIC_UNMUTE_DELAY_MS 100
@@ -170,6 +171,7 @@
int tx_clk_status;
bool lpi_enable;
bool register_event_listener;
+ int dec_mode[VA_MACRO_NUM_DECIMATORS];
};
static bool va_macro_get_data(struct snd_soc_component *component,
@@ -400,7 +402,12 @@
if (!va_macro_get_data(component, &va_dev, &va_priv, __func__))
return -EINVAL;
- dev_dbg(va_dev, "%s: event = %d\n", __func__, event);
+ dev_dbg(va_dev, "%s: event = %d, lpi_enable = %d\n",
+ __func__, event, va_priv->lpi_enable);
+
+ if (!va_priv->lpi_enable)
+ return ret;
+
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
if (va_priv->lpass_audio_hw_vote) {
@@ -411,7 +418,7 @@
__func__);
}
if (!ret)
- if (bolero_tx_clk_switch(component))
+ if (bolero_tx_clk_switch(component, CLK_SRC_VA_RCG))
dev_dbg(va_dev, "%s: clock switch failed\n",
__func__);
if (va_priv->lpi_enable) {
@@ -424,7 +431,7 @@
va_priv->register_event_listener = false;
bolero_register_event_listener(component, false);
}
- if (bolero_tx_clk_switch(component))
+ if (bolero_tx_clk_switch(component, CLK_SRC_TX_RCG))
dev_dbg(va_dev, "%s: clock switch failed\n",__func__);
if (va_priv->lpass_audio_hw_vote)
clk_disable_unprepare(va_priv->lpass_audio_hw_vote);
@@ -484,12 +491,14 @@
ret = bolero_tx_mclk_enable(component, 1);
break;
case SND_SOC_DAPM_POST_PMD:
- if (bolero_tx_clk_switch(component))
- dev_dbg(va_dev, "%s: clock switch failed\n",__func__);
- if (va_priv->lpi_enable)
+ if (va_priv->lpi_enable) {
+ if (bolero_tx_clk_switch(component, CLK_SRC_TX_RCG))
+ dev_dbg(va_dev, "%s: clock switch failed\n",
+ __func__);
va_macro_mclk_enable(va_priv, 0, true);
- else
+ } else {
bolero_tx_mclk_enable(component, 0);
+ }
if (va_priv->tx_clk_status > 0) {
bolero_clk_rsc_request_clock(va_priv->dev,
@@ -1058,6 +1067,9 @@
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
+ snd_soc_component_update_bits(component,
+ dec_cfg_reg, 0x06, va_priv->dec_mode[decimator] <<
+ VA_MACRO_ADC_MODE_CFG0_SHIFT);
/* Enable TX PGA Mute */
snd_soc_component_update_bits(component,
tx_vol_ctl_reg, 0x10, 0x10);
@@ -1171,8 +1183,6 @@
switch (event) {
case SND_SOC_DAPM_POST_PMU:
- if (bolero_tx_clk_switch(component))
- dev_dbg(va_dev, "%s: clock switch failed\n",__func__);
if (va_priv->tx_clk_status > 0) {
ret = bolero_clk_rsc_request_clock(va_priv->dev,
va_priv->default_clk_id,
@@ -1265,6 +1275,90 @@
return 0;
}
+static inline int va_macro_path_get(const char *wname,
+ unsigned int *path_num)
+{
+ int ret = 0;
+ char *widget_name = NULL;
+ char *w_name = NULL;
+ char *path_num_char = NULL;
+ char *path_name = NULL;
+
+ widget_name = kstrndup(wname, 10, GFP_KERNEL);
+ if (!widget_name)
+ return -EINVAL;
+
+ w_name = widget_name;
+
+ path_name = strsep(&widget_name, " ");
+ if (!path_name) {
+ pr_err("%s: Invalid widget name = %s\n",
+ __func__, widget_name);
+ ret = -EINVAL;
+ goto err;
+ }
+ path_num_char = strpbrk(path_name, "01234567");
+ if (!path_num_char) {
+ pr_err("%s: va path index not found\n",
+ __func__);
+ ret = -EINVAL;
+ goto err;
+ }
+ ret = kstrtouint(path_num_char, 10, path_num);
+ if (ret < 0)
+ pr_err("%s: Invalid tx path = %s\n",
+ __func__, w_name);
+
+err:
+ kfree(w_name);
+ return ret;
+}
+
+static int va_macro_dec_mode_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *component =
+ snd_soc_kcontrol_component(kcontrol);
+ struct va_macro_priv *priv = NULL;
+ struct device *va_dev = NULL;
+ int ret = 0;
+ int path = 0;
+
+ if (!va_macro_get_data(component, &va_dev, &priv, __func__))
+ return -EINVAL;
+
+ ret = va_macro_path_get(kcontrol->id.name, &path);
+ if (ret)
+ return ret;
+
+ ucontrol->value.integer.value[0] = priv->dec_mode[path];
+
+ return 0;
+}
+
+static int va_macro_dec_mode_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *component =
+ snd_soc_kcontrol_component(kcontrol);
+ struct va_macro_priv *priv = NULL;
+ struct device *va_dev = NULL;
+ int value = ucontrol->value.integer.value[0];
+ int ret = 0;
+ int path = 0;
+
+ if (!va_macro_get_data(component, &va_dev, &priv, __func__))
+ return -EINVAL;
+
+ ret = va_macro_path_get(kcontrol->id.name, &path);
+ if (ret)
+ return ret;
+
+ priv->dec_mode[path] = value;
+
+ return 0;
+}
+
static int va_macro_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
@@ -2313,8 +2407,24 @@
{"VA SWR_ADC1", NULL, "VA_SWR_PWR"},
{"VA SWR_ADC2", NULL, "VA_SWR_PWR"},
{"VA SWR_ADC3", NULL, "VA_SWR_PWR"},
+ {"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"},
};
+static const char * const dec_mode_mux_text[] = {
+ "ADC_DEFAULT", "ADC_LOW_PWR", "ADC_HIGH_PERF",
+};
+
+static const struct soc_enum dec_mode_mux_enum =
+ SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(dec_mode_mux_text),
+ dec_mode_mux_text);
+
static const struct snd_kcontrol_new va_macro_snd_controls[] = {
SOC_SINGLE_SX_TLV("VA_DEC0 Volume",
BOLERO_CDC_VA_TX0_TX_VOL_CTL,
@@ -2342,6 +2452,18 @@
0, -84, 40, digital_gain),
SOC_SINGLE_EXT("LPI Enable", 0, 0, 1, 0,
va_macro_lpi_get, va_macro_lpi_put),
+
+ SOC_ENUM_EXT("VA_DEC0 MODE", dec_mode_mux_enum,
+ va_macro_dec_mode_get, va_macro_dec_mode_put),
+
+ SOC_ENUM_EXT("VA_DEC1 MODE", dec_mode_mux_enum,
+ va_macro_dec_mode_get, va_macro_dec_mode_put),
+
+ SOC_ENUM_EXT("VA_DEC2 MODE", dec_mode_mux_enum,
+ va_macro_dec_mode_get, va_macro_dec_mode_put),
+
+ SOC_ENUM_EXT("VA_DEC3 MODE", dec_mode_mux_enum,
+ va_macro_dec_mode_get, va_macro_dec_mode_put),
};
static const struct snd_kcontrol_new va_macro_snd_controls_common[] = {