From 4d1a9042f20c24de47323d0c1631d4ffeb81370a Mon Sep 17 00:00:00 2001 From: Sudheer Papothi Date: Fri, 13 Dec 2019 00:49:16 +0530 Subject: [PATCH] ASoC: bolero: Update TX HPF sequence for AMIC Update TX HPF sequence for AMIC to avoid pop during audio capture. Change-Id: Ib70fc5cd05f67c97977db96487294bfe14f554ad Signed-off-by: Sudheer Papothi --- asoc/codecs/bolero/tx-macro.c | 80 +++++++++++++++++-------- asoc/codecs/bolero/va-macro.c | 107 ++++++++++++++++++++++------------ 2 files changed, 127 insertions(+), 60 deletions(-) diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c index d9603587b185..589f989144c9 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"); @@ -424,6 +427,25 @@ static int tx_macro_reg_wake_irq(struct snd_soc_component *component, 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; @@ -432,7 +454,7 @@ static void tx_macro_tx_hpf_corner_freq_callback(struct work_struct *work) 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); @@ -448,26 +470,30 @@ static void tx_macro_tx_hpf_corner_freq_callback(struct work_struct *work) 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) @@ -878,6 +904,8 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w, 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; @@ -929,14 +957,20 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w, 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); /* diff --git a/asoc/codecs/bolero/va-macro.c b/asoc/codecs/bolero/va-macro.c index 0288c148dc5c..4e12540d11bd 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"); @@ -708,6 +710,25 @@ done: 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 +737,7 @@ static void va_macro_tx_hpf_corner_freq_callback(struct work_struct *work) 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 +753,30 @@ static void va_macro_tx_hpf_corner_freq_callback(struct work_struct *work) 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) @@ -1045,6 +1070,8 @@ static int va_macro_enable_dec(struct snd_soc_dapm_widget *w, 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 +1117,27 @@ static int va_macro_enable_dec(struct snd_soc_dapm_widget *w, 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 +1145,7 @@ static int va_macro_enable_dec(struct snd_soc_dapm_widget *w, 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));