ASoC: WCD9310: Detect fake insertion during headset removal
When the headset is removed slowly, there is a possibility
for MBHC state machine to raise a fake headset insert interrupt
after the removal interrupt. Add check to identify this fake
interrupt and ignore it.
CRs-Fixed:298938
Signed-off-by: Bhalchandra Gajare <gajare@codeaurora.org>
diff --git a/sound/soc/codecs/wcd9310.c b/sound/soc/codecs/wcd9310.c
index 53080d4..fa171ab 100644
--- a/sound/soc/codecs/wcd9310.c
+++ b/sound/soc/codecs/wcd9310.c
@@ -1961,13 +1961,13 @@
return bias_value;
}
-static int tabla_codec_setup_hs_polling(struct snd_soc_codec *codec)
+static short tabla_codec_setup_hs_polling(struct snd_soc_codec *codec)
{
struct tabla_priv *tabla = snd_soc_codec_get_drvdata(codec);
struct tabla_mbhc_calibration *calibration = tabla->calibration;
int micbias_ctl_reg, micbias_cfilt_ctl_reg,
micbias_mbhc_reg;
- short bias_value, threshold_no_mic;
+ short bias_value;
unsigned int cfilt_sel;
if (!calibration) {
@@ -2053,16 +2053,8 @@
bias_value = tabla_codec_measure_micbias_voltage(codec, 0);
snd_soc_write(codec, micbias_cfilt_ctl_reg, 0x40);
snd_soc_update_bits(codec, TABLA_A_MBHC_HPH, 0x13, 0x00);
- threshold_no_mic = 0xF7F6;
- if ((bias_value < threshold_no_mic) &&
- !tabla->no_mic_headset_override) {
- pr_debug("headphone detected, micbias %x\n", bias_value);
- return 0;
- } else {
- pr_debug("headset detected, micbias %x\n", bias_value);
- return 1;
- }
+ return bias_value;
}
static int tabla_codec_enable_hs_detect(struct snd_soc_codec *codec,
@@ -2348,9 +2340,12 @@
{
struct tabla_priv *priv = data;
struct snd_soc_codec *codec = priv->codec;
- int microphone_present;
int ldo_h_on, micb_cfilt_on;
int micbias_cfilt_ctl_reg, cfilt_sel;
+ short mic_voltage;
+ short threshold_no_mic = 0xF7F6;
+ short threshold_fake_insert = 0xFD30;
+
pr_debug("%s\n", __func__);
tabla_disable_irq(codec->control_data, TABLA_IRQ_MBHC_INSERTION);
@@ -2409,15 +2404,21 @@
return IRQ_HANDLED;
}
- microphone_present = tabla_codec_setup_hs_polling(codec);
-
if (!ldo_h_on)
snd_soc_update_bits(codec, TABLA_A_LDO_H_MODE_1, 0x80, 0x0);
if (!micb_cfilt_on)
snd_soc_update_bits(codec, micbias_cfilt_ctl_reg, 0x80, 0x0);
+ mic_voltage = tabla_codec_setup_hs_polling(codec);
- if (microphone_present == 0) {
+ if (mic_voltage > threshold_fake_insert) {
+ pr_debug("%s: Fake insertion interrupt, mic_voltage = %x\n",
+ __func__, mic_voltage);
+ tabla_codec_enable_hs_detect(codec, 1);
+ } else if (mic_voltage < threshold_no_mic) {
+ pr_debug("%s: Headphone Detected, mic_voltage = %x\n",
+ __func__, mic_voltage);
+
if (priv->headset_jack) {
pr_debug("%s: Reporting insertion %d\n", __func__,
SND_JACK_HEADPHONE);
@@ -2426,7 +2427,10 @@
}
tabla_codec_shutdown_hs_polling(codec);
tabla_codec_enable_hs_detect(codec, 0);
- } else if (microphone_present == 1) {
+
+ } else {
+ pr_debug("%s: Headset detected, mic_voltage = %x\n",
+ __func__, mic_voltage);
if (priv->headset_jack) {
pr_debug("%s: Reporting insertion %d\n", __func__,
SND_JACK_HEADSET);