ASoC: wcd-mbhc: update electrical removal detection logic
when moisture is in jack, removing of the plug result in electrical removal interrupt. So, update electrical interrupt handler to handle mechanical removal based on moisture status. CRs-Fixed: 2058106 Change-Id: I9cfbfbaf04783f0edcadb14d7828759020745289 Signed-off-by: Meng Wang <mwang@codeaurora.org>
This commit is contained in:
@@ -895,6 +895,8 @@ static irqreturn_t wcd_mbhc_adc_hs_rem_irq(int irq, void *data)
|
|||||||
struct wcd_mbhc *mbhc = data;
|
struct wcd_mbhc *mbhc = data;
|
||||||
unsigned long timeout;
|
unsigned long timeout;
|
||||||
int adc_threshold, output_mv, retry = 0;
|
int adc_threshold, output_mv, retry = 0;
|
||||||
|
bool hphpa_on = false;
|
||||||
|
u8 moisture_status = 0;
|
||||||
|
|
||||||
pr_debug("%s: enter\n", __func__);
|
pr_debug("%s: enter\n", __func__);
|
||||||
WCD_MBHC_RSC_LOCK(mbhc);
|
WCD_MBHC_RSC_LOCK(mbhc);
|
||||||
@@ -928,10 +930,45 @@ static irqreturn_t wcd_mbhc_adc_hs_rem_irq(int irq, void *data)
|
|||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mbhc->mbhc_cfg->moisture_en) {
|
||||||
|
if (mbhc->mbhc_cb->hph_pa_on_status)
|
||||||
|
if (mbhc->mbhc_cb->hph_pa_on_status(mbhc->codec)) {
|
||||||
|
hphpa_on = true;
|
||||||
|
WCD_MBHC_REG_UPDATE_BITS(
|
||||||
|
WCD_MBHC_HPHL_PA_EN, 0);
|
||||||
|
WCD_MBHC_REG_UPDATE_BITS(
|
||||||
|
WCD_MBHC_HPH_PA_EN, 0);
|
||||||
|
}
|
||||||
|
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HPHR_GND, 1);
|
||||||
|
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HPHL_GND, 1);
|
||||||
|
/* wait for 50ms to get moisture status */
|
||||||
|
usleep_range(50000, 50100);
|
||||||
|
|
||||||
|
WCD_MBHC_REG_READ(WCD_MBHC_MOISTURE_STATUS, moisture_status);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mbhc->mbhc_cfg->moisture_en && !moisture_status) {
|
||||||
|
pr_debug("%s: moisture present in jack\n", __func__);
|
||||||
|
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_L_DET_EN, 0);
|
||||||
|
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_MECH_DETECTION_TYPE, 1);
|
||||||
|
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_L_DET_EN, 1);
|
||||||
|
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, 0);
|
||||||
|
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_BTN_ISRC_CTL, 0);
|
||||||
|
mbhc->btn_press_intr = false;
|
||||||
|
mbhc->is_btn_press = false;
|
||||||
|
if (mbhc->current_plug == MBHC_PLUG_TYPE_HEADSET)
|
||||||
|
wcd_mbhc_report_plug(mbhc, 0, SND_JACK_HEADSET);
|
||||||
|
else if (mbhc->current_plug == MBHC_PLUG_TYPE_HEADPHONE)
|
||||||
|
wcd_mbhc_report_plug(mbhc, 0, SND_JACK_HEADPHONE);
|
||||||
|
else if (mbhc->current_plug == MBHC_PLUG_TYPE_GND_MIC_SWAP)
|
||||||
|
wcd_mbhc_report_plug(mbhc, 0, SND_JACK_UNSUPPORTED);
|
||||||
|
else if (mbhc->current_plug == MBHC_PLUG_TYPE_HIGH_HPH)
|
||||||
|
wcd_mbhc_report_plug(mbhc, 0, SND_JACK_LINEOUT);
|
||||||
|
} else {
|
||||||
/*
|
/*
|
||||||
* ADC COMPLETE and ELEC_REM interrupts are both enabled for HEADPHONE,
|
* ADC COMPLETE and ELEC_REM interrupts are both enabled for
|
||||||
* need to reject the ADC COMPLETE interrupt which follows ELEC_REM one
|
* HEADPHONE, need to reject the ADC COMPLETE interrupt which
|
||||||
* when HEADPHONE is removed.
|
* follows ELEC_REM one when HEADPHONE is removed.
|
||||||
*/
|
*/
|
||||||
if (mbhc->current_plug == MBHC_PLUG_TYPE_HEADPHONE)
|
if (mbhc->current_plug == MBHC_PLUG_TYPE_HEADPHONE)
|
||||||
mbhc->extn_cable_hph_rem = true;
|
mbhc->extn_cable_hph_rem = true;
|
||||||
@@ -939,6 +976,13 @@ static irqreturn_t wcd_mbhc_adc_hs_rem_irq(int irq, void *data)
|
|||||||
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ADC_MODE, 0);
|
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ADC_MODE, 0);
|
||||||
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ADC_EN, 0);
|
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ADC_EN, 0);
|
||||||
wcd_mbhc_elec_hs_report_unplug(mbhc);
|
wcd_mbhc_elec_hs_report_unplug(mbhc);
|
||||||
|
|
||||||
|
if (hphpa_on) {
|
||||||
|
hphpa_on = false;
|
||||||
|
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HPHL_PA_EN, 1);
|
||||||
|
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HPH_PA_EN, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
exit:
|
exit:
|
||||||
WCD_MBHC_RSC_UNLOCK(mbhc);
|
WCD_MBHC_RSC_UNLOCK(mbhc);
|
||||||
pr_debug("%s: leave\n", __func__);
|
pr_debug("%s: leave\n", __func__);
|
||||||
|
@@ -794,6 +794,8 @@ static irqreturn_t wcd_mbhc_hs_rem_irq(int irq, void *data)
|
|||||||
unsigned long timeout;
|
unsigned long timeout;
|
||||||
bool removed = true;
|
bool removed = true;
|
||||||
int retry = 0;
|
int retry = 0;
|
||||||
|
bool hphpa_on = false;
|
||||||
|
u8 moisture_status = 0;
|
||||||
|
|
||||||
pr_debug("%s: enter\n", __func__);
|
pr_debug("%s: enter\n", __func__);
|
||||||
|
|
||||||
@@ -830,6 +832,52 @@ static irqreturn_t wcd_mbhc_hs_rem_irq(int irq, void *data)
|
|||||||
WCD_MBHC_REG_READ(WCD_MBHC_HS_COMP_RESULT, hs_comp_result);
|
WCD_MBHC_REG_READ(WCD_MBHC_HS_COMP_RESULT, hs_comp_result);
|
||||||
|
|
||||||
if (removed) {
|
if (removed) {
|
||||||
|
if (mbhc->mbhc_cfg->moisture_en) {
|
||||||
|
if (mbhc->mbhc_cb->hph_pa_on_status)
|
||||||
|
if (
|
||||||
|
mbhc->mbhc_cb->hph_pa_on_status(mbhc->codec)) {
|
||||||
|
hphpa_on = true;
|
||||||
|
WCD_MBHC_REG_UPDATE_BITS(
|
||||||
|
WCD_MBHC_HPHL_PA_EN, 0);
|
||||||
|
WCD_MBHC_REG_UPDATE_BITS(
|
||||||
|
WCD_MBHC_HPH_PA_EN, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HPHR_GND, 1);
|
||||||
|
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HPHL_GND, 1);
|
||||||
|
/* wait for 50ms to get moisture status */
|
||||||
|
usleep_range(50000, 50100);
|
||||||
|
|
||||||
|
WCD_MBHC_REG_READ(
|
||||||
|
WCD_MBHC_MOISTURE_STATUS, moisture_status);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mbhc->mbhc_cfg->moisture_en && !moisture_status) {
|
||||||
|
pr_debug("%s: moisture present in jack\n", __func__);
|
||||||
|
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_L_DET_EN, 0);
|
||||||
|
WCD_MBHC_REG_UPDATE_BITS(
|
||||||
|
WCD_MBHC_MECH_DETECTION_TYPE, 1);
|
||||||
|
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_L_DET_EN, 1);
|
||||||
|
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_FSM_EN, 0);
|
||||||
|
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_BTN_ISRC_CTL, 0);
|
||||||
|
mbhc->btn_press_intr = false;
|
||||||
|
mbhc->is_btn_press = false;
|
||||||
|
if (mbhc->current_plug == MBHC_PLUG_TYPE_HEADSET)
|
||||||
|
wcd_mbhc_report_plug(
|
||||||
|
mbhc, 0, SND_JACK_HEADSET);
|
||||||
|
else if (mbhc->current_plug ==
|
||||||
|
MBHC_PLUG_TYPE_HEADPHONE)
|
||||||
|
wcd_mbhc_report_plug(
|
||||||
|
mbhc, 0, SND_JACK_HEADPHONE);
|
||||||
|
else if (mbhc->current_plug ==
|
||||||
|
MBHC_PLUG_TYPE_GND_MIC_SWAP)
|
||||||
|
wcd_mbhc_report_plug(
|
||||||
|
mbhc, 0, SND_JACK_UNSUPPORTED);
|
||||||
|
else if (mbhc->current_plug ==
|
||||||
|
MBHC_PLUG_TYPE_HIGH_HPH)
|
||||||
|
wcd_mbhc_report_plug(
|
||||||
|
mbhc, 0, SND_JACK_LINEOUT);
|
||||||
|
} else {
|
||||||
if (!(hphl_sch && mic_sch && hs_comp_result)) {
|
if (!(hphl_sch && mic_sch && hs_comp_result)) {
|
||||||
/*
|
/*
|
||||||
* extension cable is still plugged in
|
* extension cable is still plugged in
|
||||||
@@ -839,12 +887,14 @@ static irqreturn_t wcd_mbhc_hs_rem_irq(int irq, void *data)
|
|||||||
} else {
|
} else {
|
||||||
if (!mic_sch) {
|
if (!mic_sch) {
|
||||||
mic_trigerred++;
|
mic_trigerred++;
|
||||||
pr_debug("%s: Removal MIC trigerred %d\n",
|
pr_debug(
|
||||||
|
"%s: Removal MIC trigerred %d\n",
|
||||||
__func__, mic_trigerred);
|
__func__, mic_trigerred);
|
||||||
}
|
}
|
||||||
if (!hphl_sch) {
|
if (!hphl_sch) {
|
||||||
hphl_trigerred++;
|
hphl_trigerred++;
|
||||||
pr_debug("%s: Removal HPHL trigerred %d\n",
|
pr_debug(
|
||||||
|
"%s: Removal HPHL trigerred %d\n",
|
||||||
__func__, hphl_trigerred);
|
__func__, hphl_trigerred);
|
||||||
}
|
}
|
||||||
if (mic_trigerred && hphl_trigerred) {
|
if (mic_trigerred && hphl_trigerred) {
|
||||||
@@ -856,6 +906,7 @@ static irqreturn_t wcd_mbhc_hs_rem_irq(int irq, void *data)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
exit:
|
exit:
|
||||||
WCD_MBHC_RSC_UNLOCK(mbhc);
|
WCD_MBHC_RSC_UNLOCK(mbhc);
|
||||||
pr_debug("%s: leave\n", __func__);
|
pr_debug("%s: leave\n", __func__);
|
||||||
@@ -863,6 +914,11 @@ exit:
|
|||||||
|
|
||||||
report_unplug:
|
report_unplug:
|
||||||
wcd_mbhc_elec_hs_report_unplug(mbhc);
|
wcd_mbhc_elec_hs_report_unplug(mbhc);
|
||||||
|
if (hphpa_on) {
|
||||||
|
hphpa_on = false;
|
||||||
|
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HPHL_PA_EN, 1);
|
||||||
|
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HPH_PA_EN, 1);
|
||||||
|
}
|
||||||
hphl_trigerred = 0;
|
hphl_trigerred = 0;
|
||||||
mic_trigerred = 0;
|
mic_trigerred = 0;
|
||||||
WCD_MBHC_RSC_UNLOCK(mbhc);
|
WCD_MBHC_RSC_UNLOCK(mbhc);
|
||||||
|
@@ -550,7 +550,7 @@ void wcd_mbhc_hs_elec_irq(struct wcd_mbhc *mbhc, int irq_type,
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(wcd_mbhc_hs_elec_irq);
|
EXPORT_SYMBOL(wcd_mbhc_hs_elec_irq);
|
||||||
|
|
||||||
static void wcd_mbhc_report_plug(struct wcd_mbhc *mbhc, int insertion,
|
void wcd_mbhc_report_plug(struct wcd_mbhc *mbhc, int insertion,
|
||||||
enum snd_jack_types jack_type)
|
enum snd_jack_types jack_type)
|
||||||
{
|
{
|
||||||
struct snd_soc_codec *codec = mbhc->codec;
|
struct snd_soc_codec *codec = mbhc->codec;
|
||||||
@@ -725,6 +725,7 @@ static void wcd_mbhc_report_plug(struct wcd_mbhc *mbhc, int insertion,
|
|||||||
}
|
}
|
||||||
pr_debug("%s: leave hph_status %x\n", __func__, mbhc->hph_status);
|
pr_debug("%s: leave hph_status %x\n", __func__, mbhc->hph_status);
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(wcd_mbhc_report_plug);
|
||||||
|
|
||||||
void wcd_mbhc_elec_hs_report_unplug(struct wcd_mbhc *mbhc)
|
void wcd_mbhc_elec_hs_report_unplug(struct wcd_mbhc *mbhc)
|
||||||
{
|
{
|
||||||
|
@@ -16,6 +16,7 @@
|
|||||||
#include <linux/stringify.h>
|
#include <linux/stringify.h>
|
||||||
#include <linux/power_supply.h>
|
#include <linux/power_supply.h>
|
||||||
#include "wcdcal-hwdep.h"
|
#include "wcdcal-hwdep.h"
|
||||||
|
#include <sound/jack.h>
|
||||||
|
|
||||||
#define TOMBAK_MBHC_NC 0
|
#define TOMBAK_MBHC_NC 0
|
||||||
#define TOMBAK_MBHC_NO 1
|
#define TOMBAK_MBHC_NO 1
|
||||||
@@ -204,6 +205,9 @@ enum wcd_mbhc_register_function {
|
|||||||
WCD_MBHC_ANC_DET_EN,
|
WCD_MBHC_ANC_DET_EN,
|
||||||
WCD_MBHC_FSM_STATUS,
|
WCD_MBHC_FSM_STATUS,
|
||||||
WCD_MBHC_MUX_CTL,
|
WCD_MBHC_MUX_CTL,
|
||||||
|
WCD_MBHC_MOISTURE_STATUS,
|
||||||
|
WCD_MBHC_HPHR_GND,
|
||||||
|
WCD_MBHC_HPHL_GND,
|
||||||
WCD_MBHC_HPHL_OCP_DET_EN,
|
WCD_MBHC_HPHL_OCP_DET_EN,
|
||||||
WCD_MBHC_HPHR_OCP_DET_EN,
|
WCD_MBHC_HPHR_OCP_DET_EN,
|
||||||
WCD_MBHC_HPHL_OCP_STATUS,
|
WCD_MBHC_HPHL_OCP_STATUS,
|
||||||
@@ -594,5 +598,7 @@ void wcd_mbhc_jack_report(struct wcd_mbhc *mbhc,
|
|||||||
struct snd_soc_jack *jack, int status, int mask);
|
struct snd_soc_jack *jack, int status, int mask);
|
||||||
int wcd_cancel_btn_work(struct wcd_mbhc *mbhc);
|
int wcd_cancel_btn_work(struct wcd_mbhc *mbhc);
|
||||||
int wcd_mbhc_get_button_mask(struct wcd_mbhc *mbhc);
|
int wcd_mbhc_get_button_mask(struct wcd_mbhc *mbhc);
|
||||||
|
void wcd_mbhc_report_plug(struct wcd_mbhc *mbhc, int insertion,
|
||||||
|
enum snd_jack_types jack_type);
|
||||||
|
|
||||||
#endif /* __WCD_MBHC_V2_H__ */
|
#endif /* __WCD_MBHC_V2_H__ */
|
||||||
|
@@ -650,6 +650,12 @@ static struct wcd_mbhc_register
|
|||||||
0, 0, 0, 0),
|
0, 0, 0, 0),
|
||||||
WCD_MBHC_REGISTER("WCD_MBHC_MUX_CTL",
|
WCD_MBHC_REGISTER("WCD_MBHC_MUX_CTL",
|
||||||
WCD9335_MBHC_CTL_2, 0x70, 4, 0),
|
WCD9335_MBHC_CTL_2, 0x70, 4, 0),
|
||||||
|
WCD_MBHC_REGISTER("WCD_MBHC_MOISTURE_STATUS",
|
||||||
|
WCD9335_MBHC_FSM_STATUS, 0X20, 5, 0),
|
||||||
|
WCD_MBHC_REGISTER("WCD_MBHC_HPHR_GND",
|
||||||
|
WCD9335_HPH_PA_CTL2, 0x40, 6, 0),
|
||||||
|
WCD_MBHC_REGISTER("WCD_MBHC_HPHL_GND",
|
||||||
|
WCD9335_HPH_PA_CTL2, 0x10, 4, 0),
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct wcd_mbhc_intr intr_ids = {
|
static const struct wcd_mbhc_intr intr_ids = {
|
||||||
|
@@ -120,6 +120,12 @@ static struct wcd_mbhc_register
|
|||||||
WCD934X_MBHC_STATUS_SPARE_1, 0x01, 0, 0),
|
WCD934X_MBHC_STATUS_SPARE_1, 0x01, 0, 0),
|
||||||
WCD_MBHC_REGISTER("WCD_MBHC_MUX_CTL",
|
WCD_MBHC_REGISTER("WCD_MBHC_MUX_CTL",
|
||||||
WCD934X_MBHC_NEW_CTL_2, 0x70, 4, 0),
|
WCD934X_MBHC_NEW_CTL_2, 0x70, 4, 0),
|
||||||
|
WCD_MBHC_REGISTER("WCD_MBHC_MOISTURE_STATUS",
|
||||||
|
WCD934X_MBHC_NEW_FSM_STATUS, 0x20, 5, 0),
|
||||||
|
WCD_MBHC_REGISTER("WCD_MBHC_HPHR_GND",
|
||||||
|
WCD934X_HPH_PA_CTL2, 0x40, 6, 0),
|
||||||
|
WCD_MBHC_REGISTER("WCD_MBHC_HPHL_GND",
|
||||||
|
WCD934X_HPH_PA_CTL2, 0x10, 4, 0),
|
||||||
WCD_MBHC_REGISTER("WCD_MBHC_HPHL_OCP_DET_EN",
|
WCD_MBHC_REGISTER("WCD_MBHC_HPHL_OCP_DET_EN",
|
||||||
WCD934X_HPH_L_TEST, 0x01, 0, 0),
|
WCD934X_HPH_L_TEST, 0x01, 0, 0),
|
||||||
WCD_MBHC_REGISTER("WCD_MBHC_HPHR_OCP_DET_EN",
|
WCD_MBHC_REGISTER("WCD_MBHC_HPHR_OCP_DET_EN",
|
||||||
|
Reference in New Issue
Block a user