ASoC: Fix audio distortion issue during headset record
Audio is distorted during first 3 secs on headset record while doing device switch from dmic to headset mic. Disable BCS before slow insertion detection and enable it afterwards to resolve the issue. Change-Id: Ie5bc4b5292e5f69066760cab44d78989a74f13f4 Signed-off-by: Vatsal Bucha <vbucha@codeaurora.org>
This commit is contained in:

committed by
Gerrit - the friendly Code Review server

parent
731807e0a2
commit
d06525fa68
@@ -214,6 +214,12 @@ static int bolero_cdc_update_wcd_event(void *handle, u16 event, u32 data)
|
|||||||
priv->component,
|
priv->component,
|
||||||
BOLERO_MACRO_EVT_RX_COMPANDER_SOFT_RST, data);
|
BOLERO_MACRO_EVT_RX_COMPANDER_SOFT_RST, data);
|
||||||
break;
|
break;
|
||||||
|
case WCD_BOLERO_EVT_BCS_CLK_OFF:
|
||||||
|
if (priv->macro_params[TX_MACRO].event_handler)
|
||||||
|
priv->macro_params[TX_MACRO].event_handler(
|
||||||
|
priv->component,
|
||||||
|
BOLERO_MACRO_EVT_BCS_CLK_OFF, data);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
dev_err(priv->dev, "%s: Invalid event %d trigger from wcd\n",
|
dev_err(priv->dev, "%s: Invalid event %d trigger from wcd\n",
|
||||||
__func__, event);
|
__func__, event);
|
||||||
|
@@ -40,7 +40,8 @@ enum {
|
|||||||
BOLERO_MACRO_EVT_WAIT_VA_CLK_RESET,
|
BOLERO_MACRO_EVT_WAIT_VA_CLK_RESET,
|
||||||
BOLERO_MACRO_EVT_CLK_RESET,
|
BOLERO_MACRO_EVT_CLK_RESET,
|
||||||
BOLERO_MACRO_EVT_REG_WAKE_IRQ,
|
BOLERO_MACRO_EVT_REG_WAKE_IRQ,
|
||||||
BOLERO_MACRO_EVT_RX_COMPANDER_SOFT_RST
|
BOLERO_MACRO_EVT_RX_COMPANDER_SOFT_RST,
|
||||||
|
BOLERO_MACRO_EVT_BCS_CLK_OFF
|
||||||
};
|
};
|
||||||
|
|
||||||
struct macro_ops {
|
struct macro_ops {
|
||||||
|
@@ -31,6 +31,7 @@ enum {
|
|||||||
WCD_BOLERO_EVT_IMPED_TRUE, /* for imped true */
|
WCD_BOLERO_EVT_IMPED_TRUE, /* for imped true */
|
||||||
WCD_BOLERO_EVT_IMPED_FALSE, /* for imped false */
|
WCD_BOLERO_EVT_IMPED_FALSE, /* for imped false */
|
||||||
WCD_BOLERO_EVT_RX_COMPANDER_SOFT_RST,
|
WCD_BOLERO_EVT_RX_COMPANDER_SOFT_RST,
|
||||||
|
WCD_BOLERO_EVT_BCS_CLK_OFF,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wcd_ctrl_platform_data {
|
struct wcd_ctrl_platform_data {
|
||||||
|
@@ -172,6 +172,8 @@ struct tx_macro_priv {
|
|||||||
int tx_clk_status;
|
int tx_clk_status;
|
||||||
bool bcs_enable;
|
bool bcs_enable;
|
||||||
int dec_mode[NUM_DECIMATORS];
|
int dec_mode[NUM_DECIMATORS];
|
||||||
|
bool bcs_clk_en;
|
||||||
|
bool hs_slow_insert_complete;
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool tx_macro_get_data(struct snd_soc_component *component,
|
static bool tx_macro_get_data(struct snd_soc_component *component,
|
||||||
@@ -387,6 +389,15 @@ static int tx_macro_event_handler(struct snd_soc_component *component,
|
|||||||
case BOLERO_MACRO_EVT_CLK_RESET:
|
case BOLERO_MACRO_EVT_CLK_RESET:
|
||||||
bolero_rsc_clk_reset(tx_dev, TX_CORE_CLK);
|
bolero_rsc_clk_reset(tx_dev, TX_CORE_CLK);
|
||||||
break;
|
break;
|
||||||
|
case BOLERO_MACRO_EVT_BCS_CLK_OFF:
|
||||||
|
if (tx_priv->bcs_clk_en)
|
||||||
|
snd_soc_component_update_bits(component,
|
||||||
|
BOLERO_CDC_TX0_TX_PATH_SEC7, 0x40, data << 6);
|
||||||
|
if (data)
|
||||||
|
tx_priv->hs_slow_insert_complete = true;
|
||||||
|
else
|
||||||
|
tx_priv->hs_slow_insert_complete = false;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -902,8 +913,11 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w,
|
|||||||
if (tx_priv->bcs_enable) {
|
if (tx_priv->bcs_enable) {
|
||||||
snd_soc_component_update_bits(component, dec_cfg_reg,
|
snd_soc_component_update_bits(component, dec_cfg_reg,
|
||||||
0x01, 0x01);
|
0x01, 0x01);
|
||||||
snd_soc_component_update_bits(component,
|
tx_priv->bcs_clk_en = true;
|
||||||
BOLERO_CDC_TX0_TX_PATH_SEC7, 0x40, 0x40);
|
if (tx_priv->hs_slow_insert_complete)
|
||||||
|
snd_soc_component_update_bits(component,
|
||||||
|
BOLERO_CDC_TX0_TX_PATH_SEC7, 0x40,
|
||||||
|
0x40);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SND_SOC_DAPM_PRE_PMD:
|
case SND_SOC_DAPM_PRE_PMD:
|
||||||
@@ -946,6 +960,7 @@ static int tx_macro_enable_dec(struct snd_soc_dapm_widget *w,
|
|||||||
0x01, 0x00);
|
0x01, 0x00);
|
||||||
snd_soc_component_update_bits(component,
|
snd_soc_component_update_bits(component,
|
||||||
BOLERO_CDC_TX0_TX_PATH_SEC7, 0x40, 0x00);
|
BOLERO_CDC_TX0_TX_PATH_SEC7, 0x40, 0x00);
|
||||||
|
tx_priv->bcs_clk_en = false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@@ -689,6 +689,13 @@ static void wcd_correct_swch_plug(struct work_struct *work)
|
|||||||
}
|
}
|
||||||
|
|
||||||
correct_plug_type:
|
correct_plug_type:
|
||||||
|
/*
|
||||||
|
* Callback to disable BCS slow insertion detection
|
||||||
|
*/
|
||||||
|
if (plug_type == MBHC_PLUG_TYPE_HEADSET ||
|
||||||
|
plug_type == MBHC_PLUG_TYPE_HEADPHONE)
|
||||||
|
mbhc->mbhc_cb->bcs_enable(mbhc, false);
|
||||||
|
|
||||||
timeout = jiffies + msecs_to_jiffies(HS_DETECT_PLUG_TIME_MS);
|
timeout = jiffies + msecs_to_jiffies(HS_DETECT_PLUG_TIME_MS);
|
||||||
while (!time_after(jiffies, timeout)) {
|
while (!time_after(jiffies, timeout)) {
|
||||||
if (mbhc->hs_detect_work_stop) {
|
if (mbhc->hs_detect_work_stop) {
|
||||||
@@ -833,6 +840,10 @@ correct_plug_type:
|
|||||||
wrk_complete = false;
|
wrk_complete = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ((plug_type == MBHC_PLUG_TYPE_HEADSET ||
|
||||||
|
plug_type == MBHC_PLUG_TYPE_HEADPHONE))
|
||||||
|
mbhc->mbhc_cb->bcs_enable(mbhc, true);
|
||||||
|
|
||||||
if (!wrk_complete) {
|
if (!wrk_complete) {
|
||||||
/*
|
/*
|
||||||
* If plug_tye is headset, we might have already reported either
|
* If plug_tye is headset, we might have already reported either
|
||||||
|
@@ -149,6 +149,7 @@ enum {
|
|||||||
WCD_BOLERO_EVT_IMPED_TRUE, /* for imped true */
|
WCD_BOLERO_EVT_IMPED_TRUE, /* for imped true */
|
||||||
WCD_BOLERO_EVT_IMPED_FALSE, /* for imped false */
|
WCD_BOLERO_EVT_IMPED_FALSE, /* for imped false */
|
||||||
WCD_BOLERO_EVT_RX_COMPANDER_SOFT_RST,
|
WCD_BOLERO_EVT_RX_COMPANDER_SOFT_RST,
|
||||||
|
WCD_BOLERO_EVT_BCS_CLK_OFF,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@@ -182,6 +183,9 @@ enum {
|
|||||||
|
|
||||||
extern struct wcd938x_mbhc *wcd938x_soc_get_mbhc(
|
extern struct wcd938x_mbhc *wcd938x_soc_get_mbhc(
|
||||||
struct snd_soc_component *component);
|
struct snd_soc_component *component);
|
||||||
|
extern void wcd938x_disable_bcs_before_slow_insert(
|
||||||
|
struct snd_soc_component *component,
|
||||||
|
bool bcs_disable);
|
||||||
extern int wcd938x_mbhc_micb_adjust_voltage(struct snd_soc_component *component,
|
extern int wcd938x_mbhc_micb_adjust_voltage(struct snd_soc_component *component,
|
||||||
int volt, int micb_num);
|
int volt, int micb_num);
|
||||||
extern int wcd938x_get_micb_vout_ctl_val(u32 micb_mv);
|
extern int wcd938x_get_micb_vout_ctl_val(u32 micb_mv);
|
||||||
|
@@ -803,6 +803,15 @@ static void wcd938x_mbhc_moisture_polling_ctrl(struct wcd_mbhc *mbhc,
|
|||||||
0x04, (enable << 2));
|
0x04, (enable << 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void wcd938x_mbhc_bcs_enable(struct wcd_mbhc *mbhc,
|
||||||
|
bool bcs_enable)
|
||||||
|
{
|
||||||
|
if (bcs_enable)
|
||||||
|
wcd938x_disable_bcs_before_slow_insert(mbhc->component, false);
|
||||||
|
else
|
||||||
|
wcd938x_disable_bcs_before_slow_insert(mbhc->component, true);
|
||||||
|
}
|
||||||
|
|
||||||
static const struct wcd_mbhc_cb mbhc_cb = {
|
static const struct wcd_mbhc_cb mbhc_cb = {
|
||||||
.request_irq = wcd938x_mbhc_request_irq,
|
.request_irq = wcd938x_mbhc_request_irq,
|
||||||
.irq_control = wcd938x_mbhc_irq_control,
|
.irq_control = wcd938x_mbhc_irq_control,
|
||||||
@@ -827,6 +836,7 @@ static const struct wcd_mbhc_cb mbhc_cb = {
|
|||||||
.mbhc_get_moisture_status = wcd938x_mbhc_get_moisture_status,
|
.mbhc_get_moisture_status = wcd938x_mbhc_get_moisture_status,
|
||||||
.mbhc_moisture_polling_ctrl = wcd938x_mbhc_moisture_polling_ctrl,
|
.mbhc_moisture_polling_ctrl = wcd938x_mbhc_moisture_polling_ctrl,
|
||||||
.mbhc_moisture_detect_en = wcd938x_mbhc_moisture_detect_en,
|
.mbhc_moisture_detect_en = wcd938x_mbhc_moisture_detect_en,
|
||||||
|
.bcs_enable = wcd938x_mbhc_bcs_enable,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int wcd938x_get_hph_type(struct snd_kcontrol *kcontrol,
|
static int wcd938x_get_hph_type(struct snd_kcontrol *kcontrol,
|
||||||
|
@@ -1523,6 +1523,21 @@ static int wcd938x_codec_enable_adc(struct snd_soc_dapm_widget *w,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wcd938x_disable_bcs_before_slow_insert(struct snd_soc_component *component,
|
||||||
|
bool bcs_disable)
|
||||||
|
{
|
||||||
|
struct wcd938x_priv *wcd938x = snd_soc_component_get_drvdata(component);
|
||||||
|
|
||||||
|
if (wcd938x->update_wcd_event) {
|
||||||
|
if (bcs_disable)
|
||||||
|
wcd938x->update_wcd_event(wcd938x->handle,
|
||||||
|
WCD_BOLERO_EVT_BCS_CLK_OFF, 0);
|
||||||
|
else
|
||||||
|
wcd938x->update_wcd_event(wcd938x->handle,
|
||||||
|
WCD_BOLERO_EVT_BCS_CLK_OFF, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int wcd938x_tx_channel_config(struct snd_soc_component *component,
|
int wcd938x_tx_channel_config(struct snd_soc_component *component,
|
||||||
int channel, int mode)
|
int channel, int mode)
|
||||||
{
|
{
|
||||||
|
@@ -451,6 +451,8 @@ struct wcd_mbhc_register {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct wcd_mbhc_cb {
|
struct wcd_mbhc_cb {
|
||||||
|
void (*bcs_enable)
|
||||||
|
(struct wcd_mbhc *mbhc, bool bcs_enable);
|
||||||
int (*enable_mb_source)(struct wcd_mbhc *mbhc, bool turn_on);
|
int (*enable_mb_source)(struct wcd_mbhc *mbhc, bool turn_on);
|
||||||
void (*trim_btn_reg)(struct snd_soc_component *component);
|
void (*trim_btn_reg)(struct snd_soc_component *component);
|
||||||
void (*compute_impedance)(struct wcd_mbhc *mbhc,
|
void (*compute_impedance)(struct wcd_mbhc *mbhc,
|
||||||
|
Reference in New Issue
Block a user