Merge "ASoC: bolero: Use TX MCLK for non-island mode usecase"
diff --git a/asoc/bengal.c b/asoc/bengal.c
index d60698d..f2a2ece 100644
--- a/asoc/bengal.c
+++ b/asoc/bengal.c
@@ -14,6 +14,7 @@
#include <linux/input.h>
#include <linux/of_device.h>
#include <linux/soc/qcom/fsa4480-i2c.h>
+#include <linux/nvmem-consumer.h>
#include <sound/core.h>
#include <sound/soc.h>
#include <sound/soc-dapm.h>
@@ -260,6 +261,7 @@
};
static struct mi2s_conf mi2s_intf_conf[MI2S_MAX];
+static bool va_disable;
/* Default configuration of TDM channels */
static struct dev_config tdm_rx_cfg[TDM_INTERFACE_MAX][TDM_PORT_MAX] = {
@@ -3465,6 +3467,8 @@
break;
case MSM_BACKEND_DAI_SLIMBUS_7_TX:
+ param_set_mask(params, SNDRV_PCM_HW_PARAM_FORMAT,
+ slim_tx_cfg[SLIM_TX_7].bit_format);
rate->min = rate->max = slim_tx_cfg[SLIM_TX_7].sample_rate;
channels->min = channels->max =
slim_tx_cfg[SLIM_TX_7].channels;
@@ -3816,6 +3820,8 @@
case MSM_BACKEND_DAI_VA_CDC_DMA_TX_0:
case MSM_BACKEND_DAI_VA_CDC_DMA_TX_1:
case MSM_BACKEND_DAI_VA_CDC_DMA_TX_2:
+ if (va_disable)
+ break;
ret = bengal_send_island_va_config(dai_link->id);
if (ret)
pr_err("%s: send island va cfg failed, err: %d\n",
@@ -6443,6 +6449,10 @@
const char *mbhc_audio_jack_type = NULL;
int ret = 0;
uint index = 0;
+ struct nvmem_cell *cell;
+ size_t len;
+ u32 *buf;
+ u32 adsp_var_idx = 0;
if (!pdev->dev.of_node) {
dev_err(&pdev->dev,
@@ -6592,7 +6602,23 @@
__func__, ret);
is_initial_boot = true;
+ /* get adsp variant idx */
+ cell = nvmem_cell_get(&pdev->dev, "adsp_variant");
+ if (IS_ERR_OR_NULL(cell)) {
+ dev_dbg(&pdev->dev, "%s: FAILED to get nvmem cell \n", __func__);
+ goto ret;
+ }
+ buf = nvmem_cell_read(cell, &len);
+ nvmem_cell_put(cell);
+ if (IS_ERR_OR_NULL(buf) || len <= 0 || len > sizeof(32)) {
+ dev_dbg(&pdev->dev, "%s: FAILED to read nvmem cell \n", __func__);
+ goto ret;
+ }
+ memcpy(&adsp_var_idx, buf, len);
+ kfree(buf);
+ va_disable = adsp_var_idx;
+ret:
return 0;
err:
devm_kfree(&pdev->dev, pdata);
diff --git a/asoc/codecs/bolero/bolero-cdc-regmap.c b/asoc/codecs/bolero/bolero-cdc-regmap.c
index 77f5420..b1a263f 100644
--- a/asoc/codecs/bolero/bolero-cdc-regmap.c
+++ b/asoc/codecs/bolero/bolero-cdc-regmap.c
@@ -797,6 +797,10 @@
case BOLERO_CDC_VA_TOP_CSR_CORE_ID_1:
case BOLERO_CDC_VA_TOP_CSR_CORE_ID_2:
case BOLERO_CDC_VA_TOP_CSR_CORE_ID_3:
+ case BOLERO_CDC_TX_TOP_CSR_SWR_DMIC0_CTL:
+ case BOLERO_CDC_TX_TOP_CSR_SWR_DMIC1_CTL:
+ case BOLERO_CDC_TX_TOP_CSR_SWR_DMIC2_CTL:
+ case BOLERO_CDC_TX_TOP_CSR_SWR_DMIC3_CTL:
case BOLERO_CDC_WSA_VBAT_BCL_VBAT_GAIN_MON_VAL:
case BOLERO_CDC_WSA_VBAT_BCL_VBAT_DECODE_ST:
case BOLERO_CDC_WSA_INTR_CTRL_PIN1_STATUS0:
diff --git a/asoc/codecs/bolero/bolero-clk-rsc.c b/asoc/codecs/bolero/bolero-clk-rsc.c
index b80a267..b8ed664 100644
--- a/asoc/codecs/bolero/bolero-clk-rsc.c
+++ b/asoc/codecs/bolero/bolero-clk-rsc.c
@@ -32,6 +32,7 @@
struct bolero_clk_rsc {
struct device *dev;
struct mutex rsc_clk_lock;
+ struct mutex fs_gen_lock;
struct clk *clk[MAX_CLK];
int clk_cnt[MAX_CLK];
int reg_seq_en_cnt;
@@ -422,6 +423,7 @@
pr_err("%s: regmap is null\n", __func__);
return;
}
+ mutex_lock(&priv->fs_gen_lock);
if (enable) {
if (priv->reg_seq_en_cnt++ == 0) {
for (i = 0; i < (priv->num_fs_reg * 2); i += 2) {
@@ -439,6 +441,7 @@
dev_err_ratelimited(priv->dev, "%s: req_seq_cnt: %d is already disabled\n",
__func__, priv->reg_seq_en_cnt);
priv->reg_seq_en_cnt = 0;
+ mutex_unlock(&priv->fs_gen_lock);
return;
}
if (--priv->reg_seq_en_cnt == 0) {
@@ -451,6 +454,7 @@
}
}
}
+ mutex_unlock(&priv->fs_gen_lock);
}
EXPORT_SYMBOL(bolero_clk_rsc_fs_gen_request);
@@ -665,6 +669,7 @@
priv->dev = &pdev->dev;
priv->dev_up = true;
mutex_init(&priv->rsc_clk_lock);
+ mutex_init(&priv->fs_gen_lock);
dev_set_drvdata(&pdev->dev, priv);
err:
@@ -680,6 +685,7 @@
if (!priv)
return -EINVAL;
mutex_destroy(&priv->rsc_clk_lock);
+ mutex_destroy(&priv->fs_gen_lock);
return 0;
}
diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c
index f32c43a..b2b4753 100644
--- a/asoc/codecs/bolero/tx-macro.c
+++ b/asoc/codecs/bolero/tx-macro.c
@@ -40,12 +40,15 @@
#define TX_MACRO_MCLK_FREQ 9600000
#define TX_MACRO_TX_PATH_OFFSET 0x80
#define TX_MACRO_SWR_MIC_MUX_SEL_MASK 0xF
-#define TX_MACRO_ADC_MUX_CFG_OFFSET 0x2
+#define TX_MACRO_ADC_MUX_CFG_OFFSET 0x8
#define TX_MACRO_ADC_MODE_CFG0_SHIFT 1
-#define TX_MACRO_TX_UNMUTE_DELAY_MS 40
+#define TX_MACRO_DMIC_UNMUTE_DELAY_MS 40
+#define TX_MACRO_AMIC_UNMUTE_DELAY_MS 100
+#define TX_MACRO_DMIC_HPF_DELAY_MS 300
+#define TX_MACRO_AMIC_HPF_DELAY_MS 300
-static int tx_unmute_delay = TX_MACRO_TX_UNMUTE_DELAY_MS;
+static int tx_unmute_delay = TX_MACRO_DMIC_UNMUTE_DELAY_MS;
module_param(tx_unmute_delay, int, 0664);
MODULE_PARM_DESC(tx_unmute_delay, "delay to unmute the tx path");
@@ -218,19 +221,19 @@
mutex_lock(&tx_priv->mclk_lock);
if (mclk_enable) {
+ ret = bolero_clk_rsc_request_clock(tx_priv->dev,
+ TX_CORE_CLK,
+ TX_CORE_CLK,
+ true);
+ if (ret < 0) {
+ dev_err_ratelimited(tx_priv->dev,
+ "%s: request clock enable failed\n",
+ __func__);
+ goto exit;
+ }
+ bolero_clk_rsc_fs_gen_request(tx_priv->dev,
+ true);
if (tx_priv->tx_mclk_users == 0) {
- ret = bolero_clk_rsc_request_clock(tx_priv->dev,
- TX_CORE_CLK,
- TX_CORE_CLK,
- true);
- if (ret < 0) {
- dev_err_ratelimited(tx_priv->dev,
- "%s: request clock enable failed\n",
- __func__);
- goto exit;
- }
- bolero_clk_rsc_fs_gen_request(tx_priv->dev,
- true);
regcache_mark_dirty(regmap);
regcache_sync_region(regmap,
TX_START_OFFSET,
@@ -261,14 +264,14 @@
regmap_update_bits(regmap,
BOLERO_CDC_TX_CLK_RST_CTRL_MCLK_CONTROL,
0x01, 0x00);
- bolero_clk_rsc_fs_gen_request(tx_priv->dev,
- false);
-
- bolero_clk_rsc_request_clock(tx_priv->dev,
- TX_CORE_CLK,
- TX_CORE_CLK,
- false);
}
+
+ bolero_clk_rsc_fs_gen_request(tx_priv->dev,
+ false);
+ bolero_clk_rsc_request_clock(tx_priv->dev,
+ TX_CORE_CLK,
+ TX_CORE_CLK,
+ false);
}
exit:
mutex_unlock(&tx_priv->mclk_lock);
@@ -431,6 +434,25 @@
return ret;
}
+static int is_amic_enabled(struct snd_soc_component *component, int decimator)
+{
+ u16 adc_mux_reg = 0, adc_reg = 0;
+ u16 adc_n = BOLERO_ADC_MAX;
+
+ adc_mux_reg = BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG1 +
+ TX_MACRO_ADC_MUX_CFG_OFFSET * decimator;
+ if (snd_soc_component_read32(component, adc_mux_reg) & SWR_MIC) {
+ adc_reg = BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG0 +
+ TX_MACRO_ADC_MUX_CFG_OFFSET * decimator;
+ adc_n = snd_soc_component_read32(component, adc_reg) &
+ TX_MACRO_SWR_MIC_MUX_SEL_MASK;
+ if (adc_n >= BOLERO_ADC_MAX)
+ adc_n = BOLERO_ADC_MAX;
+ }
+
+ return adc_n;
+}
+
static void tx_macro_tx_hpf_corner_freq_callback(struct work_struct *work)
{
struct delayed_work *hpf_delayed_work = NULL;
@@ -439,7 +461,7 @@
struct snd_soc_component *component = NULL;
u16 dec_cfg_reg = 0, hpf_gate_reg = 0;
u8 hpf_cut_off_freq = 0;
- u16 adc_mux_reg = 0, adc_n = 0, adc_reg = 0;
+ u16 adc_n = 0;
hpf_delayed_work = to_delayed_work(work);
hpf_work = container_of(hpf_delayed_work, struct hpf_work, dwork);
@@ -455,26 +477,30 @@
dev_dbg(component->dev, "%s: decimator %u hpf_cut_of_freq 0x%x\n",
__func__, hpf_work->decimator, hpf_cut_off_freq);
- adc_mux_reg = BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG1 +
- TX_MACRO_ADC_MUX_CFG_OFFSET * hpf_work->decimator;
- if (snd_soc_component_read32(component, adc_mux_reg) & SWR_MIC) {
- adc_reg = BOLERO_CDC_TX_INP_MUX_ADC_MUX0_CFG0 +
- TX_MACRO_ADC_MUX_CFG_OFFSET * hpf_work->decimator;
- adc_n = snd_soc_component_read32(component, adc_reg) &
- TX_MACRO_SWR_MIC_MUX_SEL_MASK;
- if (adc_n >= BOLERO_ADC_MAX)
- goto tx_hpf_set;
+ adc_n = is_amic_enabled(component, hpf_work->decimator);
+ if (adc_n < BOLERO_ADC_MAX) {
/* analog mic clear TX hold */
bolero_clear_amic_tx_hold(component->dev, adc_n);
+ 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);
+ /* 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);
+ } else {
+ 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,
+ 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,
+ 0x02, 0x00);
}
-tx_hpf_set:
- 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, 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, 0x02, 0x00);
}
static void tx_macro_mute_update_callback(struct work_struct *work)
@@ -805,6 +831,8 @@
u16 hpf_gate_reg = 0;
u16 tx_gain_ctl_reg = 0;
u8 hpf_cut_off_freq = 0;
+ int hpf_delay = TX_MACRO_DMIC_HPF_DELAY_MS;
+ int unmute_delay = TX_MACRO_DMIC_UNMUTE_DELAY_MS;
struct device *tx_dev = NULL;
struct tx_macro_priv *tx_priv = NULL;
@@ -856,14 +884,20 @@
TX_HPF_CUT_OFF_FREQ_MASK,
CF_MIN_3DB_150HZ << 5);
+ if (is_amic_enabled(component, decimator) < BOLERO_ADC_MAX) {
+ hpf_delay = TX_MACRO_AMIC_HPF_DELAY_MS;
+ unmute_delay = TX_MACRO_AMIC_UNMUTE_DELAY_MS;
+ }
+ if (tx_unmute_delay < unmute_delay)
+ tx_unmute_delay = unmute_delay;
/* schedule work queue to Remove Mute */
schedule_delayed_work(&tx_priv->tx_mute_dwork[decimator].dwork,
msecs_to_jiffies(tx_unmute_delay));
if (tx_priv->tx_hpf_work[decimator].hpf_cut_off_freq !=
CF_MIN_3DB_150HZ) {
schedule_delayed_work(
- &tx_priv->tx_hpf_work[decimator].dwork,
- msecs_to_jiffies(300));
+ &tx_priv->tx_hpf_work[decimator].dwork,
+ msecs_to_jiffies(hpf_delay));
snd_soc_component_update_bits(component,
hpf_gate_reg, 0x03, 0x03);
/*
@@ -2357,12 +2391,13 @@
BOLERO_CDC_TX_TOP_CSR_FREQ_MCLK,
0x01, 0x01);
regmap_update_bits(regmap,
- BOLERO_CDC_TX_CLK_RST_CTRL_MCLK_CONTROL,
+ BOLERO_CDC_TX_CLK_RST_CTRL_MCLK_CONTROL,
0x01, 0x01);
regmap_update_bits(regmap,
- BOLERO_CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL,
+ BOLERO_CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL,
0x01, 0x01);
}
+ tx_priv->tx_mclk_users++;
}
if (tx_priv->swr_clk_users == 0) {
dev_dbg(tx_priv->dev, "%s: reset_swr: %d\n",
@@ -2405,16 +2440,24 @@
if (clk_type == TX_MCLK)
tx_macro_mclk_enable(tx_priv, 0);
if (clk_type == VA_MCLK) {
+ if (tx_priv->tx_mclk_users <= 0) {
+ dev_err(tx_priv->dev, "%s: clock already disabled\n",
+ __func__);
+ tx_priv->tx_mclk_users = 0;
+ goto tx_clk;
+ }
+ tx_priv->tx_mclk_users--;
if (tx_priv->tx_mclk_users == 0) {
regmap_update_bits(regmap,
- BOLERO_CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL,
+ BOLERO_CDC_TX_CLK_RST_CTRL_FS_CNT_CONTROL,
0x01, 0x00);
regmap_update_bits(regmap,
- BOLERO_CDC_TX_CLK_RST_CTRL_MCLK_CONTROL,
+ BOLERO_CDC_TX_CLK_RST_CTRL_MCLK_CONTROL,
0x01, 0x00);
}
+
bolero_clk_rsc_fs_gen_request(tx_priv->dev,
- false);
+ false);
ret = bolero_clk_rsc_request_clock(tx_priv->dev,
TX_CORE_CLK,
VA_CORE_CLK,
@@ -2426,6 +2469,7 @@
goto done;
}
}
+tx_clk:
if (!clk_tx_ret)
ret = bolero_clk_rsc_request_clock(tx_priv->dev,
TX_CORE_CLK,
diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c
index 77957d1..c595cad 100644
--- a/asoc/codecs/bolero/va-macro.c
+++ b/asoc/codecs/bolero/va-macro.c
@@ -44,16 +44,18 @@
#define VA_MACRO_TX_DMIC_CLK_DIV_MASK 0x0E
#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 0x2
+#define VA_MACRO_ADC_MUX_CFG_OFFSET 0x8
-#define BOLERO_CDC_VA_TX_UNMUTE_DELAY_MS 40
+#define BOLERO_CDC_VA_TX_DMIC_UNMUTE_DELAY_MS 40
+#define BOLERO_CDC_VA_TX_AMIC_UNMUTE_DELAY_MS 100
+#define BOLERO_CDC_VA_TX_DMIC_HPF_DELAY_MS 300
+#define BOLERO_CDC_VA_TX_AMIC_HPF_DELAY_MS 300
#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;
+static int va_tx_unmute_delay = BOLERO_CDC_VA_TX_DMIC_UNMUTE_DELAY_MS;
module_param(va_tx_unmute_delay, int, 0664);
MODULE_PARM_DESC(va_tx_unmute_delay, "delay to unmute the tx path");
@@ -723,6 +725,25 @@
return ret;
}
+static int is_amic_enabled(struct snd_soc_component *component, int decimator)
+{
+ u16 adc_mux_reg = 0, adc_reg = 0;
+ u16 adc_n = BOLERO_ADC_MAX;
+
+ adc_mux_reg = BOLERO_CDC_VA_INP_MUX_ADC_MUX0_CFG1 +
+ VA_MACRO_ADC_MUX_CFG_OFFSET * decimator;
+ if (snd_soc_component_read32(component, adc_mux_reg) & SWR_MIC) {
+ adc_reg = BOLERO_CDC_VA_INP_MUX_ADC_MUX0_CFG0 +
+ VA_MACRO_ADC_MUX_CFG_OFFSET * decimator;
+ adc_n = snd_soc_component_read32(component, adc_reg) &
+ VA_MACRO_SWR_MIC_MUX_SEL_MASK;
+ if (adc_n >= BOLERO_ADC_MAX)
+ adc_n = BOLERO_ADC_MAX;
+ }
+
+ return adc_n;
+}
+
static void va_macro_tx_hpf_corner_freq_callback(struct work_struct *work)
{
struct delayed_work *hpf_delayed_work;
@@ -731,7 +752,7 @@
struct snd_soc_component *component;
u16 dec_cfg_reg, hpf_gate_reg;
u8 hpf_cut_off_freq;
- u16 adc_mux_reg = 0, adc_n = 0, adc_reg = 0;
+ u16 adc_n = 0;
hpf_delayed_work = to_delayed_work(work);
hpf_work = container_of(hpf_delayed_work, struct hpf_work, dwork);
@@ -747,26 +768,30 @@
dev_dbg(va_priv->dev, "%s: decimator %u hpf_cut_of_freq 0x%x\n",
__func__, hpf_work->decimator, hpf_cut_off_freq);
- adc_mux_reg = BOLERO_CDC_VA_INP_MUX_ADC_MUX0_CFG1 +
- VA_MACRO_ADC_MUX_CFG_OFFSET * hpf_work->decimator;
- if (snd_soc_component_read32(component, adc_mux_reg) & SWR_MIC) {
- adc_reg = BOLERO_CDC_VA_INP_MUX_ADC_MUX0_CFG0 +
- VA_MACRO_ADC_MUX_CFG_OFFSET * hpf_work->decimator;
- adc_n = snd_soc_component_read32(component, adc_reg) &
- VA_MACRO_SWR_MIC_MUX_SEL_MASK;
- if (adc_n >= BOLERO_ADC_MAX)
- goto va_hpf_set;
+ adc_n = is_amic_enabled(component, hpf_work->decimator);
+ if (adc_n < BOLERO_ADC_MAX) {
/* analog mic clear TX hold */
bolero_clear_amic_tx_hold(component->dev, adc_n);
+ 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);
+ /* 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);
+ } else {
+ 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,
+ 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,
+ 0x02, 0x00);
}
-va_hpf_set:
- 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, 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, 0x02, 0x00);
}
static void va_macro_mute_update_callback(struct work_struct *work)
@@ -1011,6 +1036,8 @@
u8 hpf_cut_off_freq;
struct device *va_dev = NULL;
struct va_macro_priv *va_priv = NULL;
+ int hpf_delay = BOLERO_CDC_VA_TX_DMIC_HPF_DELAY_MS;
+ int unmute_delay = BOLERO_CDC_VA_TX_DMIC_UNMUTE_DELAY_MS;
if (!va_macro_get_data(component, &va_dev, &va_priv, __func__))
return -EINVAL;
@@ -1056,21 +1083,27 @@
snd_soc_component_update_bits(component, dec_cfg_reg,
TX_HPF_CUT_OFF_FREQ_MASK,
CF_MIN_3DB_150HZ << 5);
- snd_soc_component_update_bits(component,
- hpf_gate_reg, 0x03, 0x03);
- /*
- * Minimum 1 clk cycle delay is required as per HW spec
- */
- usleep_range(1000, 1010);
- snd_soc_component_update_bits(component,
- hpf_gate_reg, 0x02, 0x00);
- snd_soc_component_update_bits(component,
- hpf_gate_reg, 0x01, 0x01);
- /*
- * 6ms delay is required as per HW spec
- */
- usleep_range(6000, 6010);
}
+ if (is_amic_enabled(component, decimator) < BOLERO_ADC_MAX) {
+ hpf_delay = BOLERO_CDC_VA_TX_AMIC_HPF_DELAY_MS;
+ unmute_delay = BOLERO_CDC_VA_TX_AMIC_UNMUTE_DELAY_MS;
+ if (va_tx_unmute_delay < unmute_delay)
+ va_tx_unmute_delay = unmute_delay;
+ }
+ snd_soc_component_update_bits(component,
+ hpf_gate_reg, 0x03, 0x03);
+ /*
+ * Minimum 1 clk cycle delay is required as per HW spec
+ */
+ usleep_range(1000, 1010);
+ snd_soc_component_update_bits(component,
+ hpf_gate_reg, 0x02, 0x00);
+ snd_soc_component_update_bits(component,
+ hpf_gate_reg, 0x01, 0x01);
+ /*
+ * 6ms delay is required as per HW spec
+ */
+ usleep_range(6000, 6010);
/* schedule work queue to Remove Mute */
schedule_delayed_work(&va_priv->va_mute_dwork[decimator].dwork,
msecs_to_jiffies(va_tx_unmute_delay));
@@ -1078,7 +1111,7 @@
CF_MIN_3DB_150HZ)
schedule_delayed_work(
&va_priv->va_hpf_work[decimator].dwork,
- msecs_to_jiffies(50));
+ msecs_to_jiffies(hpf_delay));
/* apply gain after decimator is enabled */
snd_soc_component_write(component, tx_gain_ctl_reg,
snd_soc_component_read32(component, tx_gain_ctl_reg));
diff --git a/asoc/codecs/bolero/wsa-macro.c b/asoc/codecs/bolero/wsa-macro.c
index 03bea4e..38c075f 100644
--- a/asoc/codecs/bolero/wsa-macro.c
+++ b/asoc/codecs/bolero/wsa-macro.c
@@ -41,7 +41,7 @@
#define NUM_INTERPOLATORS 2
#define WSA_MACRO_MUX_INP_SHFT 0x3
-#define WSA_MACRO_MUX_INP_MASK1 0x38
+#define WSA_MACRO_MUX_INP_MASK1 0x07
#define WSA_MACRO_MUX_INP_MASK2 0x38
#define WSA_MACRO_MUX_CFG_OFFSET 0x8
#define WSA_MACRO_MUX_CFG1_OFFSET 0x4
@@ -620,10 +620,10 @@
inp0_sel = int_mux_cfg0_val & WSA_MACRO_MUX_INP_MASK1;
inp1_sel = (int_mux_cfg0_val >>
WSA_MACRO_MUX_INP_SHFT) &
- WSA_MACRO_MUX_INP_MASK2;
+ WSA_MACRO_MUX_INP_MASK1;
inp2_sel = (int_mux_cfg1_val >>
WSA_MACRO_MUX_INP_SHFT) &
- WSA_MACRO_MUX_INP_MASK2;
+ WSA_MACRO_MUX_INP_MASK1;
if ((inp0_sel == int_1_mix1_inp + INTn_1_INP_SEL_RX0) ||
(inp1_sel == int_1_mix1_inp + INTn_1_INP_SEL_RX0) ||
(inp2_sel == int_1_mix1_inp + INTn_1_INP_SEL_RX0)) {
diff --git a/asoc/codecs/wcd937x/wcd937x.c b/asoc/codecs/wcd937x/wcd937x.c
index e962067..cf1f5c9 100644
--- a/asoc/codecs/wcd937x/wcd937x.c
+++ b/asoc/codecs/wcd937x/wcd937x.c
@@ -1580,6 +1580,7 @@
0x80, 0x00);
break;
case BOLERO_WCD_EVT_SSR_DOWN:
+ wcd937x->mbhc->wcd_mbhc.deinit_in_progress = true;
mbhc = &wcd937x->mbhc->wcd_mbhc;
wcd937x_mbhc_ssr_down(wcd937x->mbhc, component);
wcd937x_reset_low(wcd937x->dev);
@@ -1603,6 +1604,7 @@
} else {
wcd937x_mbhc_hs_detect(component, mbhc->mbhc_cfg);
}
+ wcd937x->mbhc->wcd_mbhc.deinit_in_progress = false;
break;
default:
dev_err(component->dev, "%s: invalid event %d\n", __func__,
diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c
index 3db8fc5..aa62a46 100644
--- a/asoc/codecs/wcd938x/wcd938x.c
+++ b/asoc/codecs/wcd938x/wcd938x.c
@@ -1903,6 +1903,7 @@
break;
case BOLERO_WCD_EVT_SSR_DOWN:
wcd938x->dev_up = false;
+ wcd938x->mbhc->wcd_mbhc.deinit_in_progress = true;
mbhc = &wcd938x->mbhc->wcd_mbhc;
wcd938x_mbhc_ssr_down(wcd938x->mbhc, component);
wcd938x_reset_low(wcd938x->dev);
@@ -1927,6 +1928,7 @@
} else {
wcd938x_mbhc_hs_detect(component, mbhc->mbhc_cfg);
}
+ wcd938x->mbhc->wcd_mbhc.deinit_in_progress = false;
wcd938x->dev_up = true;
break;
case BOLERO_WCD_EVT_CLK_NOTIFY:
diff --git a/asoc/msm-compress-q6-v2.c b/asoc/msm-compress-q6-v2.c
index cfb560b..f01a23e 100644
--- a/asoc/msm-compress-q6-v2.c
+++ b/asoc/msm-compress-q6-v2.c
@@ -1511,6 +1511,7 @@
struct audio_client *ac = prtd->audio_client;
uint32_t stream_index;
uint32_t enc_cfg_id = ENC_CFG_ID_NONE;
+ bool compress_ts = false;
switch (prtd->codec_param.codec.format) {
case SNDRV_PCM_FORMAT_S24_LE:
@@ -1560,22 +1561,19 @@
return ret;
}
} else {
- if (prtd->codec_param.codec.flags & COMPRESSED_TIMESTAMP_FLAG) {
+ if (prtd->codec_param.codec.flags & COMPRESSED_TIMESTAMP_FLAG)
+ compress_ts = true;
+
+ if (q6core_get_avcs_api_version_per_service(
+ APRV2_IDS_SERVICE_ID_ADSP_ASM_V) >=
+ ADSP_ASM_API_VERSION_V2)
+ ret = q6asm_open_read_v5(prtd->audio_client,
+ prtd->codec, bits_per_sample,
+ compress_ts, enc_cfg_id);
+ else
ret = q6asm_open_read_v4(prtd->audio_client,
- prtd->codec,
- bits_per_sample, true, enc_cfg_id);
- } else {
- if (q6core_get_avcs_api_version_per_service(
- APRV2_IDS_SERVICE_ID_ADSP_ASM_V) >=
- ADSP_ASM_API_VERSION_V2)
- ret = q6asm_open_read_v5(prtd->audio_client,
- prtd->codec, bits_per_sample,
- false, enc_cfg_id);
- else
- ret = q6asm_open_read_v4(prtd->audio_client,
- prtd->codec, bits_per_sample,
- false, enc_cfg_id);
- }
+ prtd->codec, bits_per_sample,
+ compress_ts, enc_cfg_id);
if (ret < 0) {
pr_err("%s: q6asm_open_read failed:%d\n",
__func__, ret);
diff --git a/asoc/msm-pcm-routing-v2.c b/asoc/msm-pcm-routing-v2.c
index 394ef47..d37a58d 100644
--- a/asoc/msm-pcm-routing-v2.c
+++ b/asoc/msm-pcm-routing-v2.c
@@ -13246,6 +13246,14 @@
MSM_BACKEND_DAI_QUATERNARY_MI2S_TX,
MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("QUIN_MI2S_TX", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_QUINARY_MI2S_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_DOUBLE_EXT("SENARY_MI2S_TX", SND_SOC_NOPM,
+ MSM_BACKEND_DAI_SENARY_MI2S_TX,
+ MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
SOC_DOUBLE_EXT("SLIM_7_TX", SND_SOC_NOPM,
MSM_BACKEND_DAI_SLIMBUS_7_TX,
MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
@@ -26234,12 +26242,15 @@
{"MultiMedia28 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"},
{"MultiMedia29 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"},
{"MultiMedia30 Mixer", "INT3_MI2S_TX", "INT3_MI2S_TX"},
+ {"MultiMedia5 Mixer", "QUAT_MI2S_TX", "QUAT_MI2S_TX"},
{"MultiMedia6 Mixer", "PRI_MI2S_TX", "PRI_MI2S_TX"},
{"MultiMedia6 Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"},
{"MultiMedia6 Mixer", "SEC_AUX_PCM_UL_TX", "SEC_AUX_PCM_TX"},
{"MultiMedia6 Mixer", "SEC_MI2S_TX", "SEC_MI2S_TX"},
{"MultiMedia6 Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"},
+ {"MultiMedia5 Mixer", "QUIN_MI2S_TX", "QUIN_MI2S_TX"},
{"MultiMedia6 Mixer", "SENARY_MI2S_TX", "SENARY_MI2S_TX"},
+ {"MultiMedia5 Mixer", "SENARY_MI2S_TX", "SENARY_MI2S_TX"},
{"MultiMedia1 Mixer", "PRI_TDM_TX_0", "PRI_TDM_TX_0"},
{"MultiMedia1 Mixer", "PRI_TDM_TX_1", "PRI_TDM_TX_1"},
diff --git a/asoc/sa6155.c b/asoc/sa6155.c
index 7335d4f..a69005c 100644
--- a/asoc/sa6155.c
+++ b/asoc/sa6155.c
@@ -213,7 +213,7 @@
},
{ /* QUAT TDM */
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 8}, /* RX_0 */
- {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 8}, /* RX_1 */
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */
@@ -222,10 +222,10 @@
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */
},
{ /* QUIN TDM */
- {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_0 */
- {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_1 */
- {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_2 */
- {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_3 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 6}, /* RX_0 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */
@@ -276,9 +276,9 @@
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */
},
{ /* QUIN TDM */
- {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 6}, /* TX_0 */
- {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */
- {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 4}, /* TX_0 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* TX_1 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* TX_2 */
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_4 */
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_5 */
@@ -415,20 +415,20 @@
{0xFFFF}, /* not used */
},
{/* QUAT TDM */
- {0, 4, 8, 12, 16, 20, 24, 28, 0xFFFF},/*AMP OUT*/
+ {0, 8, 16, 24, 32, 40, 48, 56, 0xFFFF}, /*8 CH SPKR*/
+ {4, 12, 20, 28, 36, 44, 52, 60, 0xFFFF}, /*8 CH SPKR*/
{0xFFFF}, /* not used */
{0xFFFF}, /* not used */
{0xFFFF}, /* not used */
{0xFFFF}, /* not used */
{0xFFFF}, /* not used */
- {0xFFFF}, /* not used */
- {28,0xFFFF},
+ {60,0xFFFF},
},
{/* QUIN TDM */
- {0, 4, 0xFFFF},/*STEREO SPKR1*/
- {8, 12, 0xFFFF},/*STEREO SPKR2*/
- {16, 20, 0xFFFF},/*STEREO SPKR3*/
- {24, 28, 0xFFFF},/*STEREO SPKR4*/
+ {0, 4, 8, 12, 16, 20, 0xFFFF},
+ {24, 0xFFFF},
+ {28, 0xFFFF},
+ {0xFFFF}, /* not used */
{0xFFFF}, /* not used */
{0xFFFF}, /* not used */
{0xFFFF}, /* not used */
@@ -480,14 +480,14 @@
{60,0xFFFF},
},
{/* QUIN TDM */
- {0, 4, 8, 12, 16, 20, 0xFFFF},/*EC/ANC REF*/
+ {0, 4, 8, 12, 0xFFFF},
+ {16, 20, 0xFFFF},
+ {24, 28, 0xFFFF},
{0xFFFF}, /* not used */
{0xFFFF}, /* not used */
{0xFFFF}, /* not used */
{0xFFFF}, /* not used */
- {0xFFFF}, /* not used */
- {0xFFFF}, /* not used */
- {20, 0xFFFF},
+ {28, 0xFFFF},
}
};
diff --git a/asoc/sa8155.c b/asoc/sa8155.c
index 2939fc2..17cc775 100644
--- a/asoc/sa8155.c
+++ b/asoc/sa8155.c
@@ -205,7 +205,7 @@
},
{ /* QUAT TDM */
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 8}, /* RX_0 */
- {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 8}, /* RX_1 */
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */
@@ -214,10 +214,10 @@
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_7 */
},
{ /* QUIN TDM */
- {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_0 */
- {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_1 */
- {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_2 */
- {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 2}, /* RX_3 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 16}, /* RX_0 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_1 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_2 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_3 */
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_4 */
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_5 */
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* RX_6 */
@@ -268,7 +268,7 @@
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_7 */
},
{ /* QUIN TDM */
- {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 6}, /* TX_0 */
+ {SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 16}, /* TX_0 */
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_1 */
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_2 */
{SAMPLING_RATE_48KHZ, SNDRV_PCM_FORMAT_S16_LE, 1}, /* TX_3 */
@@ -407,24 +407,25 @@
{0xFFFF}, /* not used */
},
{/* QUAT TDM */
- {0, 4, 8, 12, 16, 20, 24, 28, 0xFFFF},/*AMP OUT*/
+ {0, 8, 16, 24, 32, 40, 48, 56, 0xFFFF}, /*8 CH SPKR*/
+ {4, 12, 20, 28, 36, 44, 52, 60, 0xFFFF}, /*8 CH SPKR*/
{0xFFFF}, /* not used */
{0xFFFF}, /* not used */
{0xFFFF}, /* not used */
{0xFFFF}, /* not used */
{0xFFFF}, /* not used */
- {0xFFFF}, /* not used */
- {28,0xFFFF},
+ {60,0xFFFF},
},
{/* QUIN TDM */
- {0, 4, 0xFFFF},/*STEREO SPKR1*/
- {8, 12, 0xFFFF},/*STEREO SPKR2*/
- {16, 20, 0xFFFF},/*STEREO SPKR3*/
- {24, 28, 0xFFFF},/*STEREO SPKR4*/
+ {0, 8, 16, 24, 32, 40, 48, 56,
+ 4, 12, 20, 28, 36, 44, 52, 60, 0xFFFF}, /*16 CH SPKR*/
{0xFFFF}, /* not used */
{0xFFFF}, /* not used */
{0xFFFF}, /* not used */
- {28, 0xFFFF},
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {0xFFFF}, /* not used */
+ {60, 0xFFFF},
}
};
@@ -462,7 +463,7 @@
},
{/* QUAT TDM */
{0, 4, 8, 12, 16, 20, 24, 28,
- 32, 36, 40, 44, 48, 52, 56, 60, 0xFFFF},/*MIC ARR*/
+ 32, 36, 40, 44, 48, 52, 56, 60, 0xFFFF},/*16 CH MIC ARR1*/
{0xFFFF}, /* not used */
{0xFFFF}, /* not used */
{0xFFFF}, /* not used */
@@ -472,14 +473,15 @@
{60,0xFFFF},
},
{/* QUIN TDM */
- {0, 4, 8, 12, 16, 20, 0xFFFF},/*EC/ANC REF*/
+ {0, 4, 8, 12, 16, 20, 24, 28,
+ 32, 36, 40, 44, 48, 52, 56, 60, 0xFFFF},/*16 CH MIC ARR2*/
{0xFFFF}, /* not used */
{0xFFFF}, /* not used */
{0xFFFF}, /* not used */
{0xFFFF}, /* not used */
{0xFFFF}, /* not used */
{0xFFFF}, /* not used */
- {20, 0xFFFF},
+ {60, 0xFFFF},
}
};
@@ -5879,6 +5881,23 @@
.ignore_pmdown_time = 1,
.id = MSM_FRONTEND_DAI_MULTIMEDIA22
},
+ {
+ .name = MSM_DAILINK_NAME(Media23),
+ .stream_name = "MultiMedia23",
+ .cpu_dai_name = "MultiMedia23",
+ .platform_name = "msm-pcm-dsp.1",
+ .dynamic = 1,
+ .async_ops = ASYNC_DPCM_SND_SOC_PREPARE,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .trigger = {SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST},
+ .codec_dai_name = "snd-soc-dummy-dai",
+ .codec_name = "snd-soc-dummy",
+ .ignore_suspend = 1,
+ .ignore_pmdown_time = 1,
+ .id = MSM_FRONTEND_DAI_MULTIMEDIA23
+ },
};
static struct snd_soc_dai_link msm_custom_fe_dai_links[] = {
diff --git a/dsp/q6afe.c b/dsp/q6afe.c
index b65cc98..75ce5b0 100644
--- a/dsp/q6afe.c
+++ b/dsp/q6afe.c
@@ -23,6 +23,7 @@
#include "q6afecal-hwdep.h"
#define WAKELOCK_TIMEOUT 5000
+#define AFE_CLK_TOKEN 1024
enum {
AFE_COMMON_RX_CAL = 0,
AFE_COMMON_TX_CAL,
@@ -106,8 +107,11 @@
void *apr;
atomic_t state;
atomic_t status;
+ atomic_t clk_state;
+ atomic_t clk_status;
wait_queue_head_t wait[AFE_MAX_PORTS];
wait_queue_head_t wait_wakeup;
+ wait_queue_head_t clk_wait;
struct task_struct *task;
wait_queue_head_t lpass_core_hw_wait;
uint32_t lpass_hw_core_client_hdl[AFE_LPASS_CORE_HW_VOTE_MAX];
@@ -154,6 +158,7 @@
struct aanc_data aanc_info;
struct mutex afe_cmd_lock;
struct mutex afe_apr_lock;
+ struct mutex afe_clk_lock;
int set_custom_topology;
int dev_acdb_id[AFE_MAX_PORTS];
routing_cb rt_cb;
@@ -680,8 +685,8 @@
if (data->token < AFE_LPASS_CORE_HW_VOTE_MAX)
this_afe.lpass_hw_core_client_hdl[data->token] =
payload[0];
- atomic_set(&this_afe.state, 0);
- atomic_set(&this_afe.status, 0);
+ atomic_set(&this_afe.clk_state, 0);
+ atomic_set(&this_afe.clk_status, 0);
wake_up(&this_afe.lpass_core_hw_wait);
} else if (data->payload_size) {
uint32_t *payload;
@@ -720,11 +725,16 @@
case AFE_SVC_CMD_SET_PARAM:
case AFE_SVC_CMD_SET_PARAM_V2:
case AFE_PORT_CMD_MOD_EVENT_CFG:
- atomic_set(&this_afe.state, 0);
- if (afe_token_is_valid(data->token))
- wake_up(&this_afe.wait[data->token]);
- else
- return -EINVAL;
+ if(data->token == AFE_CLK_TOKEN) {
+ atomic_set(&this_afe.clk_state, 0);
+ wake_up(&this_afe.clk_wait);
+ } else {
+ atomic_set(&this_afe.state, 0);
+ if (afe_token_is_valid(data->token))
+ wake_up(&this_afe.wait[data->token]);
+ else
+ return -EINVAL;
+ }
break;
case AFE_SERVICE_CMD_REGISTER_RT_PORT_DRIVER:
break;
@@ -770,7 +780,7 @@
break;
case AFE_CMD_REMOTE_LPASS_CORE_HW_VOTE_REQUEST:
case AFE_CMD_REMOTE_LPASS_CORE_HW_DEVOTE_REQUEST:
- atomic_set(&this_afe.state, 0);
+ atomic_set(&this_afe.clk_state, 0);
wake_up(&this_afe.lpass_core_hw_wait);
break;
case AFE_SVC_CMD_EVENT_CFG:
@@ -1090,6 +1100,46 @@
mutex_unlock(&this_afe.afe_apr_lock);
return ret;
}
+/*
+ * afe_apr_send_clk_pkt : returns 0 on success, negative otherwise.
+ */
+static int afe_apr_send_clk_pkt(void *data, wait_queue_head_t *wait)
+{
+ int ret;
+
+ if (wait)
+ atomic_set(&this_afe.clk_state, 1);
+ atomic_set(&this_afe.clk_status, 0);
+ ret = apr_send_pkt(this_afe.apr, data);
+ if (ret > 0) {
+ if (wait) {
+ ret = wait_event_timeout(*wait,
+ (atomic_read(&this_afe.clk_state) == 0),
+ msecs_to_jiffies(2 * TIMEOUT_MS));
+ if (!ret) {
+ pr_err("%s: timeout\n", __func__);
+ ret = -ETIMEDOUT;
+ } else if (atomic_read(&this_afe.clk_status) > 0) {
+ pr_err("%s: DSP returned error[%s]\n", __func__,
+ adsp_err_get_err_str(atomic_read(
+ &this_afe.clk_status)));
+ ret = adsp_err_get_lnx_err_code(
+ atomic_read(&this_afe.clk_status));
+ } else {
+ ret = 0;
+ }
+ } else {
+ ret = 0;
+ }
+ } else if (ret == 0) {
+ pr_err("%s: packet not transmitted\n", __func__);
+ /* apr_send_pkt can return 0 when nothing is transmitted */
+ ret = -EINVAL;
+ }
+
+ pr_debug("%s: leave %d\n", __func__, ret);
+ return ret;
+}
/* This function shouldn't be called directly. Instead call q6afe_set_params. */
static int q6afe_set_params_v2(u16 port_id, int index,
@@ -1486,6 +1536,122 @@
return rc;
}
+/*
+ * This function shouldn't be called directly. Instead call
+ * q6afe_clk_set_params.
+ */
+static int q6afe_clk_set_params_v1(int index, struct mem_mapping_hdr *mem_hdr,
+ u8 *packed_param_data, u32 packed_data_size)
+{
+ struct afe_svc_cmd_set_param_v1 *svc_set_param = NULL;
+ uint32_t size = sizeof(struct afe_svc_cmd_set_param_v1);
+ int rc = 0;
+
+ if (packed_param_data != NULL)
+ size += packed_data_size;
+ svc_set_param = kzalloc(size, GFP_KERNEL);
+ if (svc_set_param == NULL)
+ return -ENOMEM;
+
+ svc_set_param->apr_hdr.hdr_field =
+ APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE),
+ APR_PKT_VER);
+ svc_set_param->apr_hdr.pkt_size = size;
+ svc_set_param->apr_hdr.src_port = 0;
+ svc_set_param->apr_hdr.dest_port = 0;
+ svc_set_param->apr_hdr.token = AFE_CLK_TOKEN;
+ svc_set_param->apr_hdr.opcode = AFE_SVC_CMD_SET_PARAM;
+ svc_set_param->payload_size = packed_data_size;
+
+ if (mem_hdr != NULL) {
+ /* Out of band case. */
+ svc_set_param->mem_hdr = *mem_hdr;
+ } else if (packed_param_data != NULL) {
+ /* In band case. */
+ memcpy(&svc_set_param->param_data, packed_param_data,
+ packed_data_size);
+ } else {
+ pr_err("%s: Both memory header and param data are NULL\n",
+ __func__);
+ rc = -EINVAL;
+ goto done;
+ }
+
+ rc = afe_apr_send_clk_pkt(svc_set_param, &this_afe.clk_wait);
+done:
+ kfree(svc_set_param);
+ return rc;
+}
+
+/*
+ * This function shouldn't be called directly. Instead call
+ * q6afe_clk_set_params.
+ */
+static int q6afe_clk_set_params_v2(int index, struct mem_mapping_hdr *mem_hdr,
+ u8 *packed_param_data, u32 packed_data_size)
+{
+ struct afe_svc_cmd_set_param_v2 *svc_set_param = NULL;
+ uint16_t size = sizeof(struct afe_svc_cmd_set_param_v2);
+ int rc = 0;
+
+ if (packed_param_data != NULL)
+ size += packed_data_size;
+ svc_set_param = kzalloc(size, GFP_KERNEL);
+ if (svc_set_param == NULL)
+ return -ENOMEM;
+
+ svc_set_param->apr_hdr.hdr_field =
+ APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE),
+ APR_PKT_VER);
+ svc_set_param->apr_hdr.pkt_size = size;
+ svc_set_param->apr_hdr.src_port = 0;
+ svc_set_param->apr_hdr.dest_port = 0;
+ svc_set_param->apr_hdr.token = AFE_CLK_TOKEN;
+ svc_set_param->apr_hdr.opcode = AFE_SVC_CMD_SET_PARAM_V2;
+ svc_set_param->payload_size = packed_data_size;
+
+ if (mem_hdr != NULL) {
+ /* Out of band case. */
+ svc_set_param->mem_hdr = *mem_hdr;
+ } else if (packed_param_data != NULL) {
+ /* In band case. */
+ memcpy(&svc_set_param->param_data, packed_param_data,
+ packed_data_size);
+ } else {
+ pr_err("%s: Both memory header and param data are NULL\n",
+ __func__);
+ rc = -EINVAL;
+ goto done;
+ }
+
+ rc = afe_apr_send_clk_pkt(svc_set_param, &this_afe.clk_wait);
+done:
+ kfree(svc_set_param);
+ return rc;
+}
+
+static int q6afe_clk_set_params(int index, struct mem_mapping_hdr *mem_hdr,
+ u8 *packed_param_data, u32 packed_data_size,
+ bool is_iid_supported)
+{
+ int ret;
+
+ ret = afe_q6_interface_prepare();
+ if (ret != 0) {
+ pr_err("%s: Q6 interface prepare failed %d\n", __func__, ret);
+ return ret;
+ }
+
+ if (is_iid_supported)
+ return q6afe_clk_set_params_v2(index, mem_hdr,
+ packed_param_data,
+ packed_data_size);
+ else
+ return q6afe_clk_set_params_v1(index, mem_hdr,
+ packed_param_data,
+ packed_data_size);
+}
+
static int q6afe_svc_set_params(int index, struct mem_mapping_hdr *mem_hdr,
u8 *packed_param_data, u32 packed_data_size,
bool is_iid_supported)
@@ -1530,9 +1696,12 @@
__func__, ret);
goto done;
}
-
- ret = q6afe_svc_set_params(index, NULL, packed_param_data,
- packed_data_size, is_iid_supported);
+ if (param_hdr.module_id == AFE_MODULE_CLOCK_SET)
+ ret = q6afe_clk_set_params(index, NULL, packed_param_data,
+ packed_data_size, is_iid_supported);
+ else
+ ret = q6afe_svc_set_params(index, NULL, packed_param_data,
+ packed_data_size, is_iid_supported);
done:
kfree(packed_param_data);
@@ -7628,13 +7797,7 @@
memset(¶m_hdr, 0, sizeof(param_hdr));
- ret = afe_q6_interface_prepare();
- if (ret != 0) {
- pr_err_ratelimited("%s: Q6 interface prepare failed %d\n", __func__, ret);
- return ret;
- }
-
- mutex_lock(&this_afe.afe_cmd_lock);
+ mutex_lock(&this_afe.afe_clk_lock);
param_hdr.module_id = AFE_MODULE_CLOCK_SET;
param_hdr.instance_id = INSTANCE_ID_0;
param_hdr.param_id = AFE_PARAM_ID_CLOCK_SET;
@@ -7654,7 +7817,7 @@
pr_err_ratelimited("%s: AFE clk cfg failed with ret %d\n",
__func__, ret);
- mutex_unlock(&this_afe.afe_cmd_lock);
+ mutex_unlock(&this_afe.afe_clk_lock);
return ret;
}
EXPORT_SYMBOL(afe_set_lpass_clk_cfg);
@@ -9001,6 +9164,8 @@
atomic_set(&this_afe.state, 0);
atomic_set(&this_afe.status, 0);
+ atomic_set(&this_afe.clk_state, 0);
+ atomic_set(&this_afe.clk_status, 0);
atomic_set(&this_afe.mem_map_cal_index, -1);
this_afe.apr = NULL;
this_afe.dtmf_gen_rx_portid = -1;
@@ -9014,6 +9179,7 @@
this_afe.ex_ftm_cfg.mode = MSM_SPKR_PROT_DISABLED;
mutex_init(&this_afe.afe_cmd_lock);
mutex_init(&this_afe.afe_apr_lock);
+ mutex_init(&this_afe.afe_clk_lock);
for (i = 0; i < AFE_MAX_PORTS; i++) {
this_afe.afe_cal_mode[i] = AFE_CAL_MODE_DEFAULT;
this_afe.afe_sample_rates[i] = 0;
@@ -9025,6 +9191,7 @@
}
init_waitqueue_head(&this_afe.wait_wakeup);
init_waitqueue_head(&this_afe.lpass_core_hw_wait);
+ init_waitqueue_head(&this_afe.clk_wait);
wakeup_source_init(&wl.ws, "spkr-prot");
ret = afe_init_cal_data();
if (ret)
@@ -9069,6 +9236,7 @@
config_debug_fs_exit();
mutex_destroy(&this_afe.afe_cmd_lock);
mutex_destroy(&this_afe.afe_apr_lock);
+ mutex_destroy(&this_afe.afe_clk_lock);
wakeup_source_trash(&wl.ws);
}
@@ -9132,7 +9300,7 @@
return ret;
}
- mutex_lock(&this_afe.afe_cmd_lock);
+ mutex_lock(&this_afe.afe_clk_lock);
memset(cmd_ptr, 0, sizeof(hw_vote_cfg));
@@ -9152,15 +9320,15 @@
__func__, cmd_ptr->hdr.opcode, cmd_ptr->hw_block_id);
*client_handle = 0;
- ret = afe_apr_send_pkt((uint32_t *) cmd_ptr,
- &this_afe.lpass_core_hw_wait);
+
+ ret = afe_apr_send_clk_pkt((uint32_t *)cmd_ptr,
+ &this_afe.lpass_core_hw_wait);
if (ret == 0) {
*client_handle = this_afe.lpass_hw_core_client_hdl[hw_block_id];
pr_debug("%s: lpass_hw_core_client_hdl %d\n", __func__,
this_afe.lpass_hw_core_client_hdl[hw_block_id]);
}
-
- mutex_unlock(&this_afe.afe_cmd_lock);
+ mutex_unlock(&this_afe.afe_clk_lock);
return ret;
}
EXPORT_SYMBOL(afe_vote_lpass_core_hw);
@@ -9186,7 +9354,7 @@
return ret;
}
- mutex_lock(&this_afe.afe_cmd_lock);
+ mutex_lock(&this_afe.afe_clk_lock);
if (!this_afe.lpass_hw_core_client_hdl[hw_block_id]) {
pr_debug("%s: SSR in progress, return\n", __func__);
@@ -9215,10 +9383,10 @@
goto done;
}
- ret = afe_apr_send_pkt((uint32_t *) cmd_ptr,
- &this_afe.lpass_core_hw_wait);
+ ret = afe_apr_send_clk_pkt((uint32_t *)cmd_ptr,
+ &this_afe.lpass_core_hw_wait);
done:
- mutex_unlock(&this_afe.afe_cmd_lock);
+ mutex_unlock(&this_afe.afe_clk_lock);
return ret;
}
EXPORT_SYMBOL(afe_unvote_lpass_core_hw);
diff --git a/soc/swr-mstr-ctrl.c b/soc/swr-mstr-ctrl.c
index 598b269..6f5979b 100644
--- a/soc/swr-mstr-ctrl.c
+++ b/soc/swr-mstr-ctrl.c
@@ -45,7 +45,7 @@
#define ERR_AUTO_SUSPEND_TIMER_VAL 0x1
#define SWRM_INTERRUPT_STATUS_MASK 0x1FDFD
-#define SWRM_LINK_STATUS_RETRY_CNT 0x5
+#define SWRM_LINK_STATUS_RETRY_CNT 100
#define SWRM_ROW_48 48
#define SWRM_ROW_50 50
@@ -2582,7 +2582,7 @@
"%s: Error in master Initialization , err %d\n",
__func__, ret);
mutex_unlock(&swrm->mlock);
- goto err_mstr_fail;
+ goto err_mstr_init_fail;
}
mutex_unlock(&swrm->mlock);
@@ -2627,6 +2627,8 @@
return 0;
err_irq_wakeup_fail:
device_init_wakeup(swrm->dev, false);
+err_mstr_init_fail:
+ swr_unregister_master(&swrm->master);
err_mstr_fail:
if (swrm->reg_irq)
swrm->reg_irq(swrm->handle, swr_mstr_interrupt,