Merge "dsp: Add afe_close in locked context"
diff --git a/asoc/codecs/bolero/bolero-cdc.c b/asoc/codecs/bolero/bolero-cdc.c
index fb182a2..460a725 100644
--- a/asoc/codecs/bolero/bolero-cdc.c
+++ b/asoc/codecs/bolero/bolero-cdc.c
@@ -470,6 +470,129 @@
}
EXPORT_SYMBOL(bolero_unregister_res_clk);
+static u8 bolero_dmic_clk_div_get(struct snd_soc_component *component,
+ int mode)
+{
+ struct bolero_priv* priv = snd_soc_component_get_drvdata(component);
+ int macro = (mode ? VA_MACRO : TX_MACRO);
+ int ret = 0;
+
+ if (priv->macro_params[macro].clk_div_get) {
+ ret = priv->macro_params[macro].clk_div_get(component);
+ if (ret > 0)
+ return ret;
+ }
+
+ return 1;
+}
+
+int bolero_dmic_clk_enable(struct snd_soc_component *component,
+ u32 dmic, u32 tx_mode, bool enable)
+{
+ struct bolero_priv* priv = snd_soc_component_get_drvdata(component);
+ u8 dmic_clk_en = 0x01;
+ u16 dmic_clk_reg = 0;
+ s32 *dmic_clk_cnt = NULL;
+ u8 *dmic_clk_div = NULL;
+ u8 freq_change_mask = 0;
+ u8 clk_div = 0;
+
+ dev_dbg(component->dev, "%s: enable: %d, tx_mode:%d, dmic: %d\n",
+ __func__, enable, tx_mode, dmic);
+
+ switch (dmic) {
+ case 0:
+ case 1:
+ dmic_clk_cnt = &(priv->dmic_0_1_clk_cnt);
+ dmic_clk_div = &(priv->dmic_0_1_clk_div);
+ dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC0_CTL;
+ freq_change_mask = 0x01;
+ break;
+ case 2:
+ case 3:
+ dmic_clk_cnt = &(priv->dmic_2_3_clk_cnt);
+ dmic_clk_div = &(priv->dmic_2_3_clk_div);
+ dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC1_CTL;
+ freq_change_mask = 0x02;
+ break;
+ case 4:
+ case 5:
+ dmic_clk_cnt = &(priv->dmic_4_5_clk_cnt);
+ dmic_clk_div = &(priv->dmic_4_5_clk_div);
+ dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC2_CTL;
+ freq_change_mask = 0x04;
+ break;
+ case 6:
+ case 7:
+ dmic_clk_cnt = &(priv->dmic_6_7_clk_cnt);
+ dmic_clk_div = &(priv->dmic_6_7_clk_div);
+ dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC3_CTL;
+ freq_change_mask = 0x08;
+ break;
+ default:
+ dev_err(component->dev, "%s: Invalid DMIC Selection\n",
+ __func__);
+ return -EINVAL;
+ }
+ dev_dbg(component->dev, "%s: DMIC%d dmic_clk_cnt %d\n",
+ __func__, dmic, *dmic_clk_cnt);
+ if (enable) {
+ clk_div = bolero_dmic_clk_div_get(component, tx_mode);
+ (*dmic_clk_cnt)++;
+ if (*dmic_clk_cnt == 1) {
+ snd_soc_component_update_bits(component,
+ BOLERO_CDC_VA_TOP_CSR_DMIC_CFG,
+ 0x80, 0x00);
+ snd_soc_component_update_bits(component, dmic_clk_reg,
+ 0x0E, clk_div << 0x1);
+ snd_soc_component_update_bits(component, dmic_clk_reg,
+ dmic_clk_en, dmic_clk_en);
+ } else {
+ if (*dmic_clk_div > clk_div) {
+ snd_soc_component_update_bits(component,
+ BOLERO_CDC_VA_TOP_CSR_DMIC_CFG,
+ freq_change_mask, freq_change_mask);
+ snd_soc_component_update_bits(component, dmic_clk_reg,
+ 0x0E, clk_div << 0x1);
+ snd_soc_component_update_bits(component,
+ BOLERO_CDC_VA_TOP_CSR_DMIC_CFG,
+ freq_change_mask, 0x00);
+ } else {
+ clk_div = *dmic_clk_div;
+ }
+ }
+ *dmic_clk_div = clk_div;
+ } else {
+ (*dmic_clk_cnt)--;
+ if (*dmic_clk_cnt == 0) {
+ snd_soc_component_update_bits(component, dmic_clk_reg,
+ dmic_clk_en, 0);
+ clk_div = 0;
+ snd_soc_component_update_bits(component, dmic_clk_reg,
+ 0x0E, clk_div << 0x1);
+ } else {
+ clk_div = bolero_dmic_clk_div_get(component, tx_mode);
+ if (*dmic_clk_div > clk_div) {
+ clk_div = bolero_dmic_clk_div_get(component, !tx_mode);
+ snd_soc_component_update_bits(component,
+ BOLERO_CDC_VA_TOP_CSR_DMIC_CFG,
+ freq_change_mask, freq_change_mask);
+ snd_soc_component_update_bits(component, dmic_clk_reg,
+ 0x0E, clk_div << 0x1);
+ snd_soc_component_update_bits(component,
+ BOLERO_CDC_VA_TOP_CSR_DMIC_CFG,
+ freq_change_mask, 0x00);
+ } else {
+ clk_div = *dmic_clk_div;
+ }
+ }
+ *dmic_clk_div = clk_div;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(bolero_dmic_clk_enable);
+
/**
* bolero_register_macro - Registers macro to bolero
*
@@ -517,7 +640,11 @@
priv->macro_params[macro_id].clk_switch = ops->clk_switch;
priv->macro_params[macro_id].reg_evt_listener =
ops->reg_evt_listener;
+ priv->macro_params[macro_id].clk_enable = ops->clk_enable;
}
+ if (macro_id == TX_MACRO || macro_id == VA_MACRO)
+ priv->macro_params[macro_id].clk_div_get = ops->clk_div_get;
+
if (priv->version == BOLERO_VERSION_2_1) {
if (macro_id == VA_MACRO)
priv->macro_params[macro_id].reg_wake_irq =
@@ -587,7 +714,10 @@
priv->macro_params[macro_id].reg_wake_irq = NULL;
priv->macro_params[macro_id].clk_switch = NULL;
priv->macro_params[macro_id].reg_evt_listener = NULL;
+ priv->macro_params[macro_id].clk_enable = NULL;
}
+ if (macro_id == TX_MACRO || macro_id == VA_MACRO)
+ priv->macro_params[macro_id].clk_div_get = NULL;
priv->num_dais -= priv->macro_params[macro_id].num_dais;
priv->num_macros_registered--;
@@ -888,6 +1018,40 @@
EXPORT_SYMBOL(bolero_tx_clk_switch);
/**
+ * bolero_tx_mclk_enable - Enable/Disable TX Macro mclk
+ *
+ * @component: pointer to codec component instance.
+ * @enable: set true to enable, otherwise false.
+ *
+ * Returns 0 on success or -EINVAL on error.
+ */
+int bolero_tx_mclk_enable(struct snd_soc_component *component,
+ bool enable)
+{
+ struct bolero_priv *priv = NULL;
+ int ret = 0;
+
+ if (!component)
+ return -EINVAL;
+
+ priv = snd_soc_component_get_drvdata(component);
+ if (!priv)
+ return -EINVAL;
+
+ if (!bolero_is_valid_codec_dev(priv->dev)) {
+ dev_err(component->dev, "%s: invalid codec\n", __func__);
+ return -EINVAL;
+ }
+
+ if (priv->macro_params[TX_MACRO].clk_enable)
+ ret = priv->macro_params[TX_MACRO].clk_enable(component,
+ enable);
+
+ return ret;
+}
+EXPORT_SYMBOL(bolero_tx_mclk_enable);
+
+/**
* bolero_register_event_listener - Register/Deregister to event listener
*
* @component: pointer to codec component instance.
diff --git a/asoc/codecs/bolero/bolero-cdc.h b/asoc/codecs/bolero/bolero-cdc.h
index 2ec4617..2294594 100644
--- a/asoc/codecs/bolero/bolero-cdc.h
+++ b/asoc/codecs/bolero/bolero-cdc.h
@@ -50,6 +50,24 @@
BOLERO_MACRO_EVT_BCS_CLK_OFF
};
+enum {
+ DMIC_TX = 0,
+ DMIC_VA = 1,
+
+};
+
+enum {
+ DMIC0 = 0,
+ DMIC1,
+ DMIC2,
+ DMIC3,
+ DMIC4,
+ DMIC5,
+ DMIC6,
+ DMIC7,
+ DMIC_MAX
+};
+
struct macro_ops {
int (*init)(struct snd_soc_component *component);
int (*exit)(struct snd_soc_component *component);
@@ -63,7 +81,9 @@
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 (*reg_evt_listener)(struct snd_soc_component *component, bool en);
+ int (*clk_enable)(struct snd_soc_component *c, bool en);
char __iomem *io_base;
u16 clk_id_req;
u16 default_clk_id;
@@ -92,7 +112,10 @@
bool enable);
void bolero_wsa_pa_on(struct device *dev);
bool bolero_check_core_votes(struct device *dev);
+int bolero_tx_mclk_enable(struct snd_soc_component *c, bool enable);
int bolero_get_version(struct device *dev);
+int bolero_dmic_clk_enable(struct snd_soc_component *component,
+ u32 dmic, u32 tx_mode, bool enable);
#else
static inline int bolero_register_res_clk(struct device *dev, rsc_clk_cb_t cb)
{
@@ -177,5 +200,15 @@
{
return 0;
}
+
+static int bolero_dmic_clk_enable(struct snd_soc_component *component,
+ u32 dmic, u32 tx_mode, bool enable)
+{
+ return 0;
+}
+static int bolero_tx_mclk_enable(struct snd_soc_component *c, bool enable)
+{
+ 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 d18568b..5b3dd49 100644
--- a/asoc/codecs/bolero/internal.h
+++ b/asoc/codecs/bolero/internal.h
@@ -82,6 +82,14 @@
struct blocking_notifier_head notifier;
struct device *clk_dev;
rsc_clk_cb_t rsc_clk_cb;
+ s32 dmic_0_1_clk_cnt;
+ s32 dmic_2_3_clk_cnt;
+ s32 dmic_4_5_clk_cnt;
+ s32 dmic_6_7_clk_cnt;
+ u8 dmic_0_1_clk_div;
+ u8 dmic_2_3_clk_div;
+ u8 dmic_4_5_clk_div;
+ u8 dmic_6_7_clk_div;
};
struct regmap *bolero_regmap_init(struct device *dev,
diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c
index 3295aac..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");
@@ -155,10 +158,6 @@
struct work_struct tx_macro_add_child_devices_work;
struct hpf_work tx_hpf_work[NUM_DECIMATORS];
struct tx_mute_work tx_mute_dwork[NUM_DECIMATORS];
- s32 dmic_0_1_clk_cnt;
- s32 dmic_2_3_clk_cnt;
- s32 dmic_4_5_clk_cnt;
- s32 dmic_6_7_clk_cnt;
u16 dmic_clk_div;
u32 version;
u32 is_used_tx_swr_gpio;
@@ -222,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,
@@ -265,20 +264,32 @@
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);
return ret;
}
+static int __tx_macro_mclk_enable(struct snd_soc_component *component,
+ bool enable)
+{
+ struct device *tx_dev = NULL;
+ struct tx_macro_priv *tx_priv = NULL;
+
+ if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
+ return -EINVAL;
+
+ return tx_macro_mclk_enable(tx_priv, enable);
+}
+
static int tx_macro_va_swr_clk_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event)
{
@@ -423,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;
@@ -431,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);
@@ -447,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)
@@ -754,17 +788,9 @@
{
struct snd_soc_component *component =
snd_soc_dapm_to_component(w->dapm);
- u8 dmic_clk_en = 0x01;
- u16 dmic_clk_reg = 0;
- s32 *dmic_clk_cnt = NULL;
unsigned int dmic = 0;
int ret = 0;
char *wname = NULL;
- struct device *tx_dev = NULL;
- struct tx_macro_priv *tx_priv = NULL;
-
- if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
- return -EINVAL;
wname = strpbrk(w->name, "01234567");
if (!wname) {
@@ -779,54 +805,15 @@
return -EINVAL;
}
- switch (dmic) {
- case 0:
- case 1:
- dmic_clk_cnt = &(tx_priv->dmic_0_1_clk_cnt);
- dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC0_CTL;
- break;
- case 2:
- case 3:
- dmic_clk_cnt = &(tx_priv->dmic_2_3_clk_cnt);
- dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC1_CTL;
- break;
- case 4:
- case 5:
- dmic_clk_cnt = &(tx_priv->dmic_4_5_clk_cnt);
- dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC2_CTL;
- break;
- case 6:
- case 7:
- dmic_clk_cnt = &(tx_priv->dmic_6_7_clk_cnt);
- dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC3_CTL;
- break;
- default:
- dev_err(component->dev, "%s: Invalid DMIC Selection\n",
- __func__);
- return -EINVAL;
- }
- dev_dbg(component->dev, "%s: event %d DMIC%d dmic_clk_cnt %d\n",
- __func__, event, dmic, *dmic_clk_cnt);
+ dev_dbg(component->dev, "%s: event %d DMIC%d\n",
+ __func__, event, dmic);
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
- (*dmic_clk_cnt)++;
- if (*dmic_clk_cnt == 1) {
- snd_soc_component_update_bits(component,
- BOLERO_CDC_VA_TOP_CSR_DMIC_CFG,
- 0x80, 0x00);
-
- snd_soc_component_update_bits(component, dmic_clk_reg,
- 0x0E, tx_priv->dmic_clk_div << 0x1);
- snd_soc_component_update_bits(component, dmic_clk_reg,
- dmic_clk_en, dmic_clk_en);
- }
+ bolero_dmic_clk_enable(component, dmic, DMIC_TX, true);
break;
case SND_SOC_DAPM_POST_PMD:
- (*dmic_clk_cnt)--;
- if (*dmic_clk_cnt == 0)
- snd_soc_component_update_bits(component, dmic_clk_reg,
- dmic_clk_en, 0);
+ bolero_dmic_clk_enable(component, dmic, DMIC_TX, false);
break;
}
@@ -844,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;
@@ -895,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);
/*
@@ -2317,7 +2312,7 @@
"%s: priv is null for macro!\n", __func__);
return -EINVAL;
}
- if (tx_priv->swr_ctrl_data) {
+ if (tx_priv->swr_ctrl_data && !tx_priv->tx_swr_clk_cnt) {
if (enable) {
ret = swrm_wcd_notify(
tx_priv->swr_ctrl_data[0].tx_swr_pdev,
@@ -2396,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",
@@ -2444,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,
@@ -2465,6 +2469,7 @@
goto done;
}
}
+tx_clk:
if (!clk_tx_ret)
ret = bolero_clk_rsc_request_clock(tx_priv->dev,
TX_CORE_CLK,
@@ -2493,6 +2498,17 @@
return ret;
}
+static int tx_macro_clk_div_get(struct snd_soc_component *component)
+{
+ struct device *tx_dev = NULL;
+ struct tx_macro_priv *tx_priv = NULL;
+
+ if (!tx_macro_get_data(component, &tx_dev, &tx_priv, __func__))
+ return -EINVAL;
+
+ return tx_priv->dmic_clk_div;
+}
+
static int tx_macro_clk_switch(struct snd_soc_component *component)
{
struct device *tx_dev = NULL;
@@ -3014,8 +3030,10 @@
ops->event_handler = tx_macro_event_handler;
ops->reg_wake_irq = tx_macro_reg_wake_irq;
ops->set_port_map = tx_macro_set_port_map;
+ ops->clk_div_get = tx_macro_clk_div_get;
ops->clk_switch = tx_macro_clk_switch;
ops->reg_evt_listener = tx_macro_register_event_listener;
+ ops->clk_enable = __tx_macro_mclk_enable;
}
static int tx_macro_probe(struct platform_device *pdev)
diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c
index 26475e6..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");
@@ -140,10 +142,6 @@
struct va_mute_work va_mute_dwork[VA_MACRO_NUM_DECIMATORS];
unsigned long active_ch_mask[VA_MACRO_MAX_DAIS];
unsigned long active_ch_cnt[VA_MACRO_MAX_DAIS];
- s32 dmic_0_1_clk_cnt;
- s32 dmic_2_3_clk_cnt;
- s32 dmic_4_5_clk_cnt;
- s32 dmic_6_7_clk_cnt;
u16 dmic_clk_div;
u16 va_mclk_users;
int swr_clk_users;
@@ -194,6 +192,17 @@
return true;
}
+static int va_macro_clk_div_get(struct snd_soc_component *component)
+{
+ 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;
+
+ return va_priv->dmic_clk_div;
+}
+
static int va_macro_mclk_enable(struct va_macro_priv *va_priv,
bool mclk_enable, bool dapm)
{
@@ -468,12 +477,20 @@
true);
if (!ret)
va_priv->tx_clk_status++;
- ret = va_macro_mclk_enable(va_priv, 1, true);
+
+ if (va_priv->lpi_enable)
+ ret = va_macro_mclk_enable(va_priv, 1, true);
+ else
+ 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__);
- va_macro_mclk_enable(va_priv, 0, true);
+ if (va_priv->lpi_enable)
+ va_macro_mclk_enable(va_priv, 0, true);
+ else
+ bolero_tx_mclk_enable(component, 0);
+
if (va_priv->tx_clk_status > 0) {
bolero_clk_rsc_request_clock(va_priv->dev,
va_priv->default_clk_id,
@@ -708,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;
@@ -716,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);
@@ -732,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)
@@ -953,81 +993,32 @@
{
struct snd_soc_component *component =
snd_soc_dapm_to_component(w->dapm);
- u8 dmic_clk_en = 0x01;
- u16 dmic_clk_reg;
- s32 *dmic_clk_cnt;
- unsigned int dmic;
- int ret;
+ unsigned int dmic = 0;
+ int ret = 0;
char *wname;
- 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;
wname = strpbrk(w->name, "01234567");
if (!wname) {
- dev_err(va_dev, "%s: widget not found\n", __func__);
+ dev_err(component->dev, "%s: widget not found\n", __func__);
return -EINVAL;
}
ret = kstrtouint(wname, 10, &dmic);
if (ret < 0) {
- dev_err(va_dev, "%s: Invalid DMIC line on the codec\n",
+ dev_err(component->dev, "%s: Invalid DMIC line on the codec\n",
__func__);
return -EINVAL;
}
- switch (dmic) {
- case 0:
- case 1:
- dmic_clk_cnt = &(va_priv->dmic_0_1_clk_cnt);
- dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC0_CTL;
- break;
- case 2:
- case 3:
- dmic_clk_cnt = &(va_priv->dmic_2_3_clk_cnt);
- dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC1_CTL;
- break;
- case 4:
- case 5:
- dmic_clk_cnt = &(va_priv->dmic_4_5_clk_cnt);
- dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC2_CTL;
- break;
- case 6:
- case 7:
- dmic_clk_cnt = &(va_priv->dmic_6_7_clk_cnt);
- dmic_clk_reg = BOLERO_CDC_VA_TOP_CSR_DMIC3_CTL;
- break;
- default:
- dev_err(va_dev, "%s: Invalid DMIC Selection\n",
- __func__);
- return -EINVAL;
- }
- dev_dbg(va_dev, "%s: event %d DMIC%d dmic_clk_cnt %d\n",
- __func__, event, dmic, *dmic_clk_cnt);
+ dev_dbg(component->dev, "%s: event %d DMIC%d\n",
+ __func__, event, dmic);
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
- (*dmic_clk_cnt)++;
- if (*dmic_clk_cnt == 1) {
- snd_soc_component_update_bits(component,
- BOLERO_CDC_VA_TOP_CSR_DMIC_CFG,
- 0x80, 0x00);
- snd_soc_component_update_bits(component, dmic_clk_reg,
- VA_MACRO_TX_DMIC_CLK_DIV_MASK,
- va_priv->dmic_clk_div <<
- VA_MACRO_TX_DMIC_CLK_DIV_SHFT);
- snd_soc_component_update_bits(component, dmic_clk_reg,
- dmic_clk_en, dmic_clk_en);
- }
+ bolero_dmic_clk_enable(component, dmic, DMIC_VA, true);
break;
case SND_SOC_DAPM_POST_PMD:
- (*dmic_clk_cnt)--;
- if (*dmic_clk_cnt == 0) {
- snd_soc_component_update_bits(component, dmic_clk_reg,
- dmic_clk_en, 0);
- }
+ bolero_dmic_clk_enable(component, dmic, DMIC_VA, false);
break;
}
@@ -1045,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;
@@ -1090,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));
@@ -1112,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));
@@ -2784,6 +2783,7 @@
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;
+ ops->clk_div_get = va_macro_clk_div_get;
}
static int va_macro_probe(struct platform_device *pdev)
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-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 b479042..2ac90a3 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);
@@ -7630,13 +7799,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;
@@ -7656,7 +7819,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);
@@ -9003,6 +9166,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;
@@ -9016,6 +9181,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;
@@ -9027,6 +9193,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)
@@ -9071,6 +9238,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);
}
@@ -9134,7 +9302,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));
@@ -9154,15 +9322,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);
@@ -9188,7 +9356,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__);
@@ -9217,10 +9385,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,