Merge "ASoC: wcd-mbhc: update electrical removal detection logic"
This commit is contained in:

committed by
Gerrit - the friendly Code Review server

commit
50091ca0c6
@@ -915,6 +915,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);
|
||||||
@@ -948,17 +950,59 @@ static irqreturn_t wcd_mbhc_adc_hs_rem_irq(int irq, void *data)
|
|||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
if (mbhc->mbhc_cfg->moisture_en) {
|
||||||
* ADC COMPLETE and ELEC_REM interrupts are both enabled for HEADPHONE,
|
if (mbhc->mbhc_cb->hph_pa_on_status)
|
||||||
* need to reject the ADC COMPLETE interrupt which follows ELEC_REM one
|
if (mbhc->mbhc_cb->hph_pa_on_status(mbhc->codec)) {
|
||||||
* when HEADPHONE is removed.
|
hphpa_on = true;
|
||||||
*/
|
WCD_MBHC_REG_UPDATE_BITS(
|
||||||
if (mbhc->current_plug == MBHC_PLUG_TYPE_HEADPHONE)
|
WCD_MBHC_HPHL_PA_EN, 0);
|
||||||
mbhc->extn_cable_hph_rem = true;
|
WCD_MBHC_REG_UPDATE_BITS(
|
||||||
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_DETECTION_DONE, 0);
|
WCD_MBHC_HPH_PA_EN, 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_HPHR_GND, 1);
|
||||||
wcd_mbhc_elec_hs_report_unplug(mbhc);
|
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, need to reject the ADC COMPLETE interrupt which
|
||||||
|
* follows ELEC_REM one when HEADPHONE is removed.
|
||||||
|
*/
|
||||||
|
if (mbhc->current_plug == MBHC_PLUG_TYPE_HEADPHONE)
|
||||||
|
mbhc->extn_cable_hph_rem = true;
|
||||||
|
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_DETECTION_DONE, 0);
|
||||||
|
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ADC_MODE, 0);
|
||||||
|
WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ADC_EN, 0);
|
||||||
|
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,29 +832,78 @@ 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 (!(hphl_sch && mic_sch && hs_comp_result)) {
|
if (mbhc->mbhc_cfg->moisture_en) {
|
||||||
/*
|
if (mbhc->mbhc_cb->hph_pa_on_status)
|
||||||
* extension cable is still plugged in
|
if (
|
||||||
* report it as LINEOUT device
|
mbhc->mbhc_cb->hph_pa_on_status(mbhc->codec)) {
|
||||||
*/
|
hphpa_on = true;
|
||||||
goto report_unplug;
|
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 {
|
} else {
|
||||||
if (!mic_sch) {
|
if (!(hphl_sch && mic_sch && hs_comp_result)) {
|
||||||
mic_trigerred++;
|
|
||||||
pr_debug("%s: Removal MIC trigerred %d\n",
|
|
||||||
__func__, mic_trigerred);
|
|
||||||
}
|
|
||||||
if (!hphl_sch) {
|
|
||||||
hphl_trigerred++;
|
|
||||||
pr_debug("%s: Removal HPHL trigerred %d\n",
|
|
||||||
__func__, hphl_trigerred);
|
|
||||||
}
|
|
||||||
if (mic_trigerred && hphl_trigerred) {
|
|
||||||
/*
|
/*
|
||||||
* extension cable is still plugged in
|
* extension cable is still plugged in
|
||||||
* report it as LINEOUT device
|
* report it as LINEOUT device
|
||||||
*/
|
*/
|
||||||
goto report_unplug;
|
goto report_unplug;
|
||||||
|
} else {
|
||||||
|
if (!mic_sch) {
|
||||||
|
mic_trigerred++;
|
||||||
|
pr_debug(
|
||||||
|
"%s: Removal MIC trigerred %d\n",
|
||||||
|
__func__, mic_trigerred);
|
||||||
|
}
|
||||||
|
if (!hphl_sch) {
|
||||||
|
hphl_trigerred++;
|
||||||
|
pr_debug(
|
||||||
|
"%s: Removal HPHL trigerred %d\n",
|
||||||
|
__func__, hphl_trigerred);
|
||||||
|
}
|
||||||
|
if (mic_trigerred && hphl_trigerred) {
|
||||||
|
/*
|
||||||
|
* extension cable is still plugged in
|
||||||
|
* report it as LINEOUT device
|
||||||
|
*/
|
||||||
|
goto report_unplug;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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,
|
||||||
@@ -596,5 +600,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