Loading asoc/codecs/wcd-mbhc-adc.c +55 −11 Original line number Diff line number Diff line Loading @@ -915,6 +915,8 @@ static irqreturn_t wcd_mbhc_adc_hs_rem_irq(int irq, void *data) struct wcd_mbhc *mbhc = data; unsigned long timeout; int adc_threshold, output_mv, retry = 0; bool hphpa_on = false; u8 moisture_status = 0; pr_debug("%s: enter\n", __func__); WCD_MBHC_RSC_LOCK(mbhc); Loading Loading @@ -948,10 +950,45 @@ static irqreturn_t wcd_mbhc_adc_hs_rem_irq(int irq, void *data) 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, * need to reject the ADC COMPLETE interrupt which follows ELEC_REM one * when HEADPHONE is removed. * 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; Loading @@ -959,6 +996,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_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: WCD_MBHC_RSC_UNLOCK(mbhc); pr_debug("%s: leave\n", __func__); Loading asoc/codecs/wcd-mbhc-legacy.c +73 −17 Original line number Diff line number Diff line Loading @@ -794,6 +794,8 @@ static irqreturn_t wcd_mbhc_hs_rem_irq(int irq, void *data) unsigned long timeout; bool removed = true; int retry = 0; bool hphpa_on = false; u8 moisture_status = 0; pr_debug("%s: enter\n", __func__); Loading Loading @@ -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); 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)) { /* * extension cable is still plugged in Loading @@ -839,12 +887,14 @@ static irqreturn_t wcd_mbhc_hs_rem_irq(int irq, void *data) } else { if (!mic_sch) { mic_trigerred++; pr_debug("%s: Removal MIC trigerred %d\n", pr_debug( "%s: Removal MIC trigerred %d\n", __func__, mic_trigerred); } if (!hphl_sch) { hphl_trigerred++; pr_debug("%s: Removal HPHL trigerred %d\n", pr_debug( "%s: Removal HPHL trigerred %d\n", __func__, hphl_trigerred); } if (mic_trigerred && hphl_trigerred) { Loading @@ -856,6 +906,7 @@ static irqreturn_t wcd_mbhc_hs_rem_irq(int irq, void *data) } } } } exit: WCD_MBHC_RSC_UNLOCK(mbhc); pr_debug("%s: leave\n", __func__); Loading @@ -863,6 +914,11 @@ static irqreturn_t wcd_mbhc_hs_rem_irq(int irq, void *data) report_unplug: 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; mic_trigerred = 0; WCD_MBHC_RSC_UNLOCK(mbhc); Loading asoc/codecs/wcd-mbhc-v2.c +2 −1 Original line number Diff line number Diff line Loading @@ -550,7 +550,7 @@ void wcd_mbhc_hs_elec_irq(struct wcd_mbhc *mbhc, int irq_type, } 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) { struct snd_soc_codec *codec = mbhc->codec; Loading Loading @@ -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); } EXPORT_SYMBOL(wcd_mbhc_report_plug); void wcd_mbhc_elec_hs_report_unplug(struct wcd_mbhc *mbhc) { Loading asoc/codecs/wcd-mbhc-v2.h +6 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ #include <linux/stringify.h> #include <linux/power_supply.h> #include "wcdcal-hwdep.h" #include <sound/jack.h> #define TOMBAK_MBHC_NC 0 #define TOMBAK_MBHC_NO 1 Loading Loading @@ -204,6 +205,9 @@ enum wcd_mbhc_register_function { WCD_MBHC_ANC_DET_EN, WCD_MBHC_FSM_STATUS, WCD_MBHC_MUX_CTL, WCD_MBHC_MOISTURE_STATUS, WCD_MBHC_HPHR_GND, WCD_MBHC_HPHL_GND, WCD_MBHC_HPHL_OCP_DET_EN, WCD_MBHC_HPHR_OCP_DET_EN, WCD_MBHC_HPHL_OCP_STATUS, Loading Loading @@ -596,5 +600,7 @@ void wcd_mbhc_jack_report(struct wcd_mbhc *mbhc, struct snd_soc_jack *jack, int status, int mask); int wcd_cancel_btn_work(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__ */ asoc/codecs/wcd9335.c +6 −0 Original line number Diff line number Diff line Loading @@ -650,6 +650,12 @@ static struct wcd_mbhc_register 0, 0, 0, 0), WCD_MBHC_REGISTER("WCD_MBHC_MUX_CTL", 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 = { Loading Loading
asoc/codecs/wcd-mbhc-adc.c +55 −11 Original line number Diff line number Diff line Loading @@ -915,6 +915,8 @@ static irqreturn_t wcd_mbhc_adc_hs_rem_irq(int irq, void *data) struct wcd_mbhc *mbhc = data; unsigned long timeout; int adc_threshold, output_mv, retry = 0; bool hphpa_on = false; u8 moisture_status = 0; pr_debug("%s: enter\n", __func__); WCD_MBHC_RSC_LOCK(mbhc); Loading Loading @@ -948,10 +950,45 @@ static irqreturn_t wcd_mbhc_adc_hs_rem_irq(int irq, void *data) 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, * need to reject the ADC COMPLETE interrupt which follows ELEC_REM one * when HEADPHONE is removed. * 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; Loading @@ -959,6 +996,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_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: WCD_MBHC_RSC_UNLOCK(mbhc); pr_debug("%s: leave\n", __func__); Loading
asoc/codecs/wcd-mbhc-legacy.c +73 −17 Original line number Diff line number Diff line Loading @@ -794,6 +794,8 @@ static irqreturn_t wcd_mbhc_hs_rem_irq(int irq, void *data) unsigned long timeout; bool removed = true; int retry = 0; bool hphpa_on = false; u8 moisture_status = 0; pr_debug("%s: enter\n", __func__); Loading Loading @@ -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); 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)) { /* * extension cable is still plugged in Loading @@ -839,12 +887,14 @@ static irqreturn_t wcd_mbhc_hs_rem_irq(int irq, void *data) } else { if (!mic_sch) { mic_trigerred++; pr_debug("%s: Removal MIC trigerred %d\n", pr_debug( "%s: Removal MIC trigerred %d\n", __func__, mic_trigerred); } if (!hphl_sch) { hphl_trigerred++; pr_debug("%s: Removal HPHL trigerred %d\n", pr_debug( "%s: Removal HPHL trigerred %d\n", __func__, hphl_trigerred); } if (mic_trigerred && hphl_trigerred) { Loading @@ -856,6 +906,7 @@ static irqreturn_t wcd_mbhc_hs_rem_irq(int irq, void *data) } } } } exit: WCD_MBHC_RSC_UNLOCK(mbhc); pr_debug("%s: leave\n", __func__); Loading @@ -863,6 +914,11 @@ static irqreturn_t wcd_mbhc_hs_rem_irq(int irq, void *data) report_unplug: 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; mic_trigerred = 0; WCD_MBHC_RSC_UNLOCK(mbhc); Loading
asoc/codecs/wcd-mbhc-v2.c +2 −1 Original line number Diff line number Diff line Loading @@ -550,7 +550,7 @@ void wcd_mbhc_hs_elec_irq(struct wcd_mbhc *mbhc, int irq_type, } 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) { struct snd_soc_codec *codec = mbhc->codec; Loading Loading @@ -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); } EXPORT_SYMBOL(wcd_mbhc_report_plug); void wcd_mbhc_elec_hs_report_unplug(struct wcd_mbhc *mbhc) { Loading
asoc/codecs/wcd-mbhc-v2.h +6 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ #include <linux/stringify.h> #include <linux/power_supply.h> #include "wcdcal-hwdep.h" #include <sound/jack.h> #define TOMBAK_MBHC_NC 0 #define TOMBAK_MBHC_NO 1 Loading Loading @@ -204,6 +205,9 @@ enum wcd_mbhc_register_function { WCD_MBHC_ANC_DET_EN, WCD_MBHC_FSM_STATUS, WCD_MBHC_MUX_CTL, WCD_MBHC_MOISTURE_STATUS, WCD_MBHC_HPHR_GND, WCD_MBHC_HPHL_GND, WCD_MBHC_HPHL_OCP_DET_EN, WCD_MBHC_HPHR_OCP_DET_EN, WCD_MBHC_HPHL_OCP_STATUS, Loading Loading @@ -596,5 +600,7 @@ void wcd_mbhc_jack_report(struct wcd_mbhc *mbhc, struct snd_soc_jack *jack, int status, int mask); int wcd_cancel_btn_work(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__ */
asoc/codecs/wcd9335.c +6 −0 Original line number Diff line number Diff line Loading @@ -650,6 +650,12 @@ static struct wcd_mbhc_register 0, 0, 0, 0), WCD_MBHC_REGISTER("WCD_MBHC_MUX_CTL", 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 = { Loading