Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ef638558 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "ASoC: wcd-mbhc: Fix unbalanced irq enable/disable"

parents 445f0b29 63558768
Loading
Loading
Loading
Loading
+52 −28
Original line number Diff line number Diff line
@@ -513,6 +513,34 @@ int wcd_mbhc_get_impedance(struct wcd_mbhc *mbhc, uint32_t *zl,
		return -EINVAL;
}

static void wcd_mbhc_hs_elec_irq(struct wcd_mbhc *mbhc, int irq_type,
				 bool enable)
{
	int irq;

	WCD_MBHC_RSC_ASSERT_LOCKED(mbhc);

	if (irq_type == WCD_MBHC_ELEC_HS_INS)
		irq = mbhc->intr_ids->mbhc_hs_ins_intr;
	else if (irq_type == WCD_MBHC_ELEC_HS_REM)
		irq = mbhc->intr_ids->mbhc_hs_rem_intr;
	else {
		pr_debug("%s: irq_type: %d, enable: %d\n",
			__func__, irq_type, enable);
		return;
	}

	pr_debug("%s: irq: %d, enable: %d, intr_status:%lu\n",
		 __func__, irq, enable, mbhc->intr_status);
	if ((test_bit(irq_type, &mbhc->intr_status)) != enable) {
		mbhc->mbhc_cb->irq_control(mbhc->codec, irq, enable);
		if (enable)
			set_bit(irq_type, &mbhc->intr_status);
		else
			clear_bit(irq_type, &mbhc->intr_status);
	}
}

static void wcd_mbhc_report_plug(struct wcd_mbhc *mbhc, int insertion,
				enum snd_jack_types jack_type)
{
@@ -600,8 +628,8 @@ static void wcd_mbhc_report_plug(struct wcd_mbhc *mbhc, int insertion,
						WCD_MBHC_ELECT_DETECTION_TYPE,
						0);
				usleep_range(200, 210);
				mbhc->mbhc_cb->irq_control(mbhc->codec,
					mbhc->intr_ids->mbhc_hs_rem_intr,
				wcd_mbhc_hs_elec_irq(mbhc,
						     WCD_MBHC_ELEC_HS_REM,
						     true);
			}
			mbhc->hph_status &= ~(SND_JACK_HEADSET |
@@ -713,8 +741,7 @@ static void wcd_mbhc_find_plug_and_report(struct wcd_mbhc *mbhc,
			 */
			WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ELECT_SCHMT_ISRC,
						 3);
			mbhc->mbhc_cb->irq_control(mbhc->codec,
					mbhc->intr_ids->mbhc_hs_ins_intr,
			wcd_mbhc_hs_elec_irq(mbhc, WCD_MBHC_ELEC_HS_INS,
					     true);
		} else {
			wcd_mbhc_report_plug(mbhc, 1, SND_JACK_LINEOUT);
@@ -992,8 +1019,9 @@ static void wcd_correct_swch_plug(struct work_struct *work)

	pr_debug("%s: Valid plug found, plug type is %d\n",
			 __func__, plug_type);
	if (plug_type == MBHC_PLUG_TYPE_HEADSET ||
	    plug_type == MBHC_PLUG_TYPE_HEADPHONE) {
	if ((plug_type == MBHC_PLUG_TYPE_HEADSET ||
	     plug_type == MBHC_PLUG_TYPE_HEADPHONE) &&
	    (!wcd_swch_level_remove(mbhc))) {
		WCD_MBHC_RSC_LOCK(mbhc);
		wcd_mbhc_find_plug_and_report(mbhc, plug_type);
		WCD_MBHC_RSC_UNLOCK(mbhc);
@@ -1304,11 +1332,9 @@ static void wcd_mbhc_swch_irq_handler(struct wcd_mbhc *mbhc)

			/* Pulldown micbias */
			WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_PULLDOWN_CTRL, 1);
			mbhc->mbhc_cb->irq_control(codec,
					mbhc->intr_ids->mbhc_hs_rem_intr,
			wcd_mbhc_hs_elec_irq(mbhc, WCD_MBHC_ELEC_HS_REM,
					     false);
			mbhc->mbhc_cb->irq_control(codec,
					mbhc->intr_ids->mbhc_hs_ins_intr,
			wcd_mbhc_hs_elec_irq(mbhc, WCD_MBHC_ELEC_HS_INS,
					     false);
			WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ELECT_DETECTION_TYPE,
						 1);
@@ -1316,11 +1342,9 @@ static void wcd_mbhc_swch_irq_handler(struct wcd_mbhc *mbhc)
			wcd_mbhc_report_plug(mbhc, 0, SND_JACK_HEADSET);
		} else if (mbhc->current_plug == MBHC_PLUG_TYPE_HIGH_HPH) {
			mbhc->is_extn_cable = false;
			mbhc->mbhc_cb->irq_control(codec,
					mbhc->intr_ids->mbhc_hs_rem_intr,
			wcd_mbhc_hs_elec_irq(mbhc, WCD_MBHC_ELEC_HS_REM,
					     false);
			mbhc->mbhc_cb->irq_control(codec,
					mbhc->intr_ids->mbhc_hs_ins_intr,
			wcd_mbhc_hs_elec_irq(mbhc, WCD_MBHC_ELEC_HS_INS,
					     false);
			WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ELECT_DETECTION_TYPE,
						 1);
@@ -1465,8 +1489,7 @@ determine_plug:
	 * Setup for insertion detection.
	 */
	pr_debug("%s: Disable insertion interrupt\n", __func__);
	mbhc->mbhc_cb->irq_control(mbhc->codec,
				   mbhc->intr_ids->mbhc_hs_ins_intr,
	wcd_mbhc_hs_elec_irq(mbhc, WCD_MBHC_ELEC_HS_INS,
			     false);

	WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ELECT_SCHMT_ISRC, 0);
@@ -1572,8 +1595,7 @@ report_unplug:
	 * Disable HPHL trigger and MIC Schmitt triggers.
	 * Setup for insertion detection.
	 */
	mbhc->mbhc_cb->irq_control(mbhc->codec,
				   mbhc->intr_ids->mbhc_hs_rem_intr,
	wcd_mbhc_hs_elec_irq(mbhc, WCD_MBHC_ELEC_HS_REM,
			     false);
	wcd_enable_curr_micbias(mbhc, WCD_MBHC_EN_NONE);
	/* Disable HW FSM */
@@ -1582,8 +1604,8 @@ report_unplug:

	/* Set the detection type appropriately */
	WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_ELECT_DETECTION_TYPE, 1);
	mbhc->mbhc_cb->irq_control(mbhc->codec,
				   mbhc->intr_ids->mbhc_hs_ins_intr, true);
	wcd_mbhc_hs_elec_irq(mbhc, WCD_MBHC_ELEC_HS_INS,
			     true);
	hphl_trigerred = 0;
	mic_trigerred = 0;
	WCD_MBHC_RSC_UNLOCK(mbhc);
@@ -2220,6 +2242,7 @@ int wcd_mbhc_init(struct wcd_mbhc *mbhc, struct snd_soc_codec *codec,
	}
	mbhc->mbhc_cb->irq_control(codec, mbhc->intr_ids->mbhc_hs_ins_intr,
				   false);
	clear_bit(WCD_MBHC_ELEC_HS_INS, &mbhc->intr_status);

	ret = mbhc->mbhc_cb->request_irq(codec,
					 mbhc->intr_ids->mbhc_hs_rem_intr,
@@ -2232,6 +2255,7 @@ int wcd_mbhc_init(struct wcd_mbhc *mbhc, struct snd_soc_codec *codec,
	}
	mbhc->mbhc_cb->irq_control(codec, mbhc->intr_ids->mbhc_hs_rem_intr,
				   false);
	clear_bit(WCD_MBHC_ELEC_HS_REM, &mbhc->intr_status);

	ret = mbhc->mbhc_cb->request_irq(codec, mbhc->intr_ids->hph_left_ocp,
				  wcd_mbhc_hphl_ocp_irq, "HPH_L OCP detect",
+7 −0
Original line number Diff line number Diff line
@@ -26,6 +26,11 @@
#define WCD_MONO_HS_MIN_THR	2
#define WCD_MBHC_STRINGIFY(s)  __stringify(s)

enum {
	WCD_MBHC_ELEC_HS_INS,
	WCD_MBHC_ELEC_HS_REM,
};

struct wcd_mbhc;
enum wcd_mbhc_register_function {
	WCD_MBHC_L_DET_EN,
@@ -414,6 +419,8 @@ struct wcd_mbhc {
	struct completion btn_press_compl;
	struct mutex hphl_pa_lock;
	struct mutex hphr_pa_lock;

	unsigned long intr_status;
};
#define WCD_MBHC_CAL_SIZE(buttons, rload) ( \
	sizeof(struct wcd_mbhc_general_cfg) + \