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 <spapothi@codeaurora.org>
diff --git a/asoc/codecs/bolero/tx-macro.c b/asoc/codecs/bolero/tx-macro.c
index 3295aac..e269498 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");
@@ -423,6 +426,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 +453,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 +469,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)
@@ -844,6 +870,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 +923,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);
/*