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

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

Merge "ASoC: wcd9xxx: Refactor interrupt mapping per codec"

parents b84cf427 9bde6f91
Loading
Loading
Loading
Loading
+12 −17
Original line number Diff line number Diff line
@@ -2612,12 +2612,6 @@ static void msm8x10_wcd_codec_specific_cal_setup(
			0xE0, 0xE0);
}

static int msm8x10_wcd_get_jack_detect_irq(
		struct snd_soc_codec *codec)
{
	return MSM8X10_WCD_IRQ_MBHC_HS_DET;
}

static struct wcd9xxx_cfilt_mode msm8x10_wcd_switch_cfilt_mode(
	struct wcd9xxx_mbhc *mbhc, bool fast)
{
@@ -2642,14 +2636,6 @@ static void msm8x10_wcd_select_cfilt(struct snd_soc_codec *codec,
			mbhc->mbhc_bias_regs.ctl_reg, 0x60, 0x00);
}

static void msm8x10_wcd_free_irq(struct wcd9xxx_mbhc *mbhc)
{
	struct msm8x10_wcd *msm8x10_wcd = mbhc->codec->control_data;
	struct wcd9xxx_core_resource *core_res =
			&msm8x10_wcd->wcd9xxx_res;
	wcd9xxx_free_irq(core_res, MSM8X10_WCD_IRQ_MBHC_HS_DET, mbhc);
}

enum wcd9xxx_cdc_type msm8x10_wcd_get_cdc_type(void)
{
	return WCD9XXX_CDC_TYPE_HELICON;
@@ -2707,10 +2693,8 @@ static const struct wcd9xxx_mbhc_cb mbhc_cb = {
	.enable_mux_bias_block = msm8x10_wcd_enable_mux_bias_block,
	.cfilt_fast_mode = msm8x10_wcd_put_cfilt_fast_mode,
	.codec_specific_cal = msm8x10_wcd_codec_specific_cal_setup,
	.jack_detect_irq = msm8x10_wcd_get_jack_detect_irq,
	.switch_cfilt_mode = msm8x10_wcd_switch_cfilt_mode,
	.select_cfilt = msm8x10_wcd_select_cfilt,
	.free_irq = msm8x10_wcd_free_irq,
	.get_cdc_type = msm8x10_wcd_get_cdc_type,
	.enable_clock_gate = msm8x10_wcd_mbhc_clk_gate,
	.enable_mbhc_txfe = msm8x10_wcd_mbhc_txfe,
@@ -2825,6 +2809,17 @@ static struct notifier_block adsp_state_notifier_block = {
	.priority = -INT_MAX,
};

static const struct wcd9xxx_mbhc_intr cdc_intr_ids = {
	.poll_plug_rem = MSM8X10_WCD_IRQ_MBHC_REMOVAL,
	.shortavg_complete = MSM8X10_WCD_IRQ_MBHC_SHORT_TERM,
	.potential_button_press = MSM8X10_WCD_IRQ_MBHC_PRESS,
	.button_release = MSM8X10_WCD_IRQ_MBHC_RELEASE,
	.dce_est_complete = MSM8X10_WCD_IRQ_MBHC_POTENTIAL,
	.insertion = MSM8X10_WCD_IRQ_MBHC_INSERTION,
	.hph_left_ocp = MSM8X10_WCD_IRQ_HPH_PA_OCPL_FAULT,
	.hph_right_ocp = MSM8X10_WCD_IRQ_HPH_PA_OCPR_FAULT,
	.hs_jack_switch = MSM8X10_WCD_IRQ_MBHC_HS_DET,
};

static int msm8x10_wcd_codec_probe(struct snd_soc_codec *codec)
{
@@ -2902,7 +2897,7 @@ static int msm8x10_wcd_codec_probe(struct snd_soc_codec *codec)

	ret = wcd9xxx_mbhc_init(&msm8x10_wcd_priv->mbhc,
				&msm8x10_wcd_priv->resmgr,
				codec, NULL, &mbhc_cb,
				codec, NULL, &mbhc_cb, &cdc_intr_ids,
				HELICON_MCLK_CLK_9P6MHZ, false);
	if (ret) {
		pr_err("%s: Failed to initialize mbhc\n", __func__);
+14 −19
Original line number Diff line number Diff line
@@ -97,8 +97,6 @@ MODULE_PARM_DESC(spkr_drv_wrnd,
#define TAPAN_SLIM_IRQ_UNDERFLOW (1 << 1)
#define TAPAN_SLIM_IRQ_PORT_CLOSED (1 << 2)

#define TAPAN_IRQ_MBHC_JACK_SWITCH 21

/*
 * Multiplication factor to compute impedance on Tapan
 * This is computed from (Vx / (m*Ical)) = (10mV/(180*30uA))
@@ -5131,11 +5129,6 @@ static void tapan_codec_specific_cal_setup(struct snd_soc_codec *codec,
	snd_soc_update_bits(codec, WCD9XXX_A_TX_7_MBHC_EN, 0xE0, 0xE0);
}

static int tapan_get_jack_detect_irq(struct snd_soc_codec *codec)
{
	return TAPAN_IRQ_MBHC_JACK_SWITCH;
}

static struct wcd9xxx_cfilt_mode tapan_codec_switch_cfilt_mode(
				 struct wcd9xxx_mbhc *mbhc,
				 bool fast)
@@ -5161,14 +5154,6 @@ static void tapan_select_cfilt(struct snd_soc_codec *codec,
	snd_soc_update_bits(codec, mbhc->mbhc_bias_regs.ctl_reg, 0x60, 0x00);
}

static void tapan_free_irq(struct wcd9xxx_mbhc *mbhc)
{
	struct wcd9xxx *wcd9xxx = mbhc->codec->control_data;
	struct wcd9xxx_core_resource *core_res =
			&wcd9xxx->core_res;
	wcd9xxx_free_irq(core_res, WCD9306_IRQ_MBHC_JACK_SWITCH, mbhc);
}

enum wcd9xxx_cdc_type tapan_get_cdc_type(void)
{
	return WCD9XXX_CDC_TYPE_TAPAN;
@@ -5427,10 +5412,8 @@ static const struct wcd9xxx_mbhc_cb mbhc_cb = {
	.enable_mux_bias_block = tapan_enable_mux_bias_block,
	.cfilt_fast_mode = tapan_put_cfilt_fast_mode,
	.codec_specific_cal = tapan_codec_specific_cal_setup,
	.jack_detect_irq = tapan_get_jack_detect_irq,
	.switch_cfilt_mode = tapan_codec_switch_cfilt_mode,
	.select_cfilt = tapan_select_cfilt,
	.free_irq = tapan_free_irq,
	.get_cdc_type = tapan_get_cdc_type,
	.setup_zdet = tapan_setup_zdet,
	.compute_impedance = tapan_compute_impedance,
@@ -5471,6 +5454,18 @@ static int tapan_device_down(struct wcd9xxx *wcd9xxx)
	return 0;
}

static const struct wcd9xxx_mbhc_intr cdc_intr_ids = {
	.poll_plug_rem = WCD9XXX_IRQ_MBHC_REMOVAL,
	.shortavg_complete = WCD9XXX_IRQ_MBHC_SHORT_TERM,
	.potential_button_press = WCD9XXX_IRQ_MBHC_PRESS,
	.button_release = WCD9XXX_IRQ_MBHC_RELEASE,
	.dce_est_complete = WCD9XXX_IRQ_MBHC_POTENTIAL,
	.insertion = WCD9XXX_IRQ_MBHC_INSERTION,
	.hph_left_ocp = WCD9306_IRQ_HPH_PA_OCPL_FAULT,
	.hph_right_ocp = WCD9306_IRQ_HPH_PA_OCPR_FAULT,
	.hs_jack_switch = WCD9306_IRQ_MBHC_JACK_SWITCH,
};

static int tapan_post_reset_cb(struct wcd9xxx *wcd9xxx)
{
	int ret = 0;
@@ -5518,7 +5513,7 @@ static int tapan_post_reset_cb(struct wcd9xxx *wcd9xxx)
		rco_clk_rate = TAPAN_MCLK_CLK_9P6MHZ;

	ret = wcd9xxx_mbhc_init(&tapan->mbhc, &tapan->resmgr, codec, NULL,
				&mbhc_cb, rco_clk_rate,
				&mbhc_cb, &cdc_intr_ids, rco_clk_rate,
				TAPAN_CDC_ZDET_SUPPORTED);
	if (ret)
		pr_err("%s: mbhc init failed %d\n", __func__, ret);
@@ -5741,7 +5736,7 @@ static int tapan_codec_probe(struct snd_soc_codec *codec)
		rco_clk_rate = TAPAN_MCLK_CLK_9P6MHZ;

	ret = wcd9xxx_mbhc_init(&tapan->mbhc, &tapan->resmgr, codec, NULL,
				&mbhc_cb, rco_clk_rate,
				&mbhc_cb, &cdc_intr_ids, rco_clk_rate,
				TAPAN_CDC_ZDET_SUPPORTED);

	if (ret) {
+16 −2
Original line number Diff line number Diff line
@@ -6538,6 +6538,18 @@ static const struct wcd9xxx_mbhc_cb mbhc_cb = {
	.compute_impedance = taiko_compute_impedance,
};

static const struct wcd9xxx_mbhc_intr cdc_intr_ids = {
	.poll_plug_rem = WCD9XXX_IRQ_MBHC_REMOVAL,
	.shortavg_complete = WCD9XXX_IRQ_MBHC_SHORT_TERM,
	.potential_button_press = WCD9XXX_IRQ_MBHC_PRESS,
	.button_release = WCD9XXX_IRQ_MBHC_RELEASE,
	.dce_est_complete = WCD9XXX_IRQ_MBHC_POTENTIAL,
	.insertion = WCD9XXX_IRQ_MBHC_INSERTION,
	.hph_left_ocp = WCD9XXX_IRQ_HPH_PA_OCPL_FAULT,
	.hph_right_ocp = WCD9XXX_IRQ_HPH_PA_OCPR_FAULT,
	.hs_jack_switch = WCD9320_IRQ_MBHC_JACK_SWITCH,
};

static int taiko_post_reset_cb(struct wcd9xxx *wcd9xxx)
{
	int ret = 0;
@@ -6583,7 +6595,8 @@ static int taiko_post_reset_cb(struct wcd9xxx *wcd9xxx)

		ret = wcd9xxx_mbhc_init(&taiko->mbhc, &taiko->resmgr, codec,
					taiko_enable_mbhc_micbias,
					&mbhc_cb, rco_clk_rate, true);
					&mbhc_cb, &cdc_intr_ids,
					rco_clk_rate, true);
		if (ret)
			pr_err("%s: mbhc init failed %d\n", __func__, ret);
		else
@@ -6772,7 +6785,8 @@ static int taiko_codec_probe(struct snd_soc_codec *codec)
	/* init and start mbhc */
	ret = wcd9xxx_mbhc_init(&taiko->mbhc, &taiko->resmgr, codec,
				taiko_enable_mbhc_micbias,
				&mbhc_cb, rco_clk_rate, true);
				&mbhc_cb, &cdc_intr_ids,
				rco_clk_rate, true);
	if (ret) {
		pr_err("%s: mbhc init failed %d\n", __func__, ret);
		goto err_init;
+57 −60
Original line number Diff line number Diff line
@@ -118,8 +118,6 @@
/* RX_HPH_CNP_WG_TIME increases by 0.24ms */
#define WCD9XXX_WG_TIME_FACTOR_US	240

#define WCD9XXX_IRQ_MBHC_JACK_SWITCH_DEFAULT 28

#define WCD9XXX_V_CS_HS_MAX 500
#define WCD9XXX_V_CS_NO_MIC 5
#define WCD9XXX_MB_MEAS_DELTA_MAX_MV 80
@@ -570,7 +568,7 @@ static void __hphocp_off_report(struct wcd9xxx_mbhc *mbhc, u32 jack_status,
		 * reset retry counter as PA is turned off signifying
		 * start of new OCP detection session
		 */
		if (WCD9XXX_IRQ_HPH_PA_OCPL_FAULT)
		if (mbhc->intr_ids->hph_left_ocp)
			mbhc->hphlocp_cnt = 0;
		else
			mbhc->hphrocp_cnt = 0;
@@ -581,13 +579,13 @@ static void __hphocp_off_report(struct wcd9xxx_mbhc *mbhc, u32 jack_status,
static void hphrocp_off_report(struct wcd9xxx_mbhc *mbhc, u32 jack_status)
{
	__hphocp_off_report(mbhc, SND_JACK_OC_HPHR,
			    WCD9XXX_IRQ_HPH_PA_OCPR_FAULT);
			    mbhc->intr_ids->hph_right_ocp);
}

static void hphlocp_off_report(struct wcd9xxx_mbhc *mbhc, u32 jack_status)
{
	__hphocp_off_report(mbhc, SND_JACK_OC_HPHL,
			    WCD9XXX_IRQ_HPH_PA_OCPL_FAULT);
			    mbhc->intr_ids->hph_left_ocp);
}

static void wcd9xxx_get_mbhc_micbias_regs(struct wcd9xxx_mbhc *mbhc,
@@ -975,7 +973,8 @@ static short __wcd9xxx_codec_sta_dce(struct wcd9xxx_mbhc *mbhc, int dce,
	short bias_value;
	struct snd_soc_codec *codec = mbhc->codec;

	wcd9xxx_disable_irq(mbhc->resmgr->core_res, WCD9XXX_IRQ_MBHC_POTENTIAL);
	wcd9xxx_disable_irq(mbhc->resmgr->core_res,
			    mbhc->intr_ids->dce_est_complete);
	if (noreldetection)
		wcd9xxx_turn_onoff_rel_detection(codec, false);

@@ -1021,7 +1020,8 @@ static short __wcd9xxx_codec_sta_dce(struct wcd9xxx_mbhc *mbhc, int dce,

	if (noreldetection)
		wcd9xxx_turn_onoff_rel_detection(codec, true);
	wcd9xxx_enable_irq(mbhc->resmgr->core_res, WCD9XXX_IRQ_MBHC_POTENTIAL);
	wcd9xxx_enable_irq(mbhc->resmgr->core_res,
			   mbhc->intr_ids->dce_est_complete);

	return bias_value;
}
@@ -1960,7 +1960,7 @@ static int wcd9xxx_enable_hs_detect(struct wcd9xxx_mbhc *mbhc,
		snd_soc_update_bits(codec, mbhc->resmgr->reg_addr->micb_4_mbhc,
				    0x3, mbhc->mbhc_cfg->micbias);

	wcd9xxx_enable_irq(mbhc->resmgr->core_res, WCD9XXX_IRQ_MBHC_INSERTION);
	wcd9xxx_enable_irq(mbhc->resmgr->core_res, mbhc->intr_ids->insertion);
	snd_soc_update_bits(codec, WCD9XXX_A_CDC_MBHC_INT_CTL, 0x1, 0x1);
	pr_debug("%s: leave\n", __func__);

@@ -2435,7 +2435,7 @@ static irqreturn_t wcd9xxx_hs_insert_irq(int irq, void *data)

	pr_debug("%s: enter\n", __func__);
	WCD9XXX_BCL_LOCK(mbhc->resmgr);
	wcd9xxx_disable_irq(mbhc->resmgr->core_res, WCD9XXX_IRQ_MBHC_INSERTION);
	wcd9xxx_disable_irq(mbhc->resmgr->core_res, mbhc->intr_ids->insertion);

	is_mb_trigger = !!(snd_soc_read(codec, mbhc->mbhc_bias_regs.mbhc_reg) &
			   0x10);
@@ -2502,7 +2502,7 @@ static void wcd9xxx_mbhc_insert_work(struct work_struct *work)
	snd_soc_update_bits(codec, mbhc->mbhc_bias_regs.mbhc_reg, 0x90, 0x00);
	snd_soc_update_bits(codec, WCD9XXX_A_MBHC_HPH, 0x13, 0x00);
	snd_soc_update_bits(codec, mbhc->mbhc_bias_regs.ctl_reg, 0x01, 0x00);
	wcd9xxx_disable_irq_sync(core_res, WCD9XXX_IRQ_MBHC_INSERTION);
	wcd9xxx_disable_irq_sync(core_res, mbhc->intr_ids->insertion);
	wcd9xxx_mbhc_detect_plug_type(mbhc);
	wcd9xxx_unlock_sleep(core_res);
}
@@ -3395,7 +3395,7 @@ static irqreturn_t wcd9xxx_hphl_ocp_irq(int irq, void *data)
					    0x10, 0x10);
		} else {
			wcd9xxx_disable_irq(mbhc->resmgr->core_res,
					  WCD9XXX_IRQ_HPH_PA_OCPL_FAULT);
					  mbhc->intr_ids->hph_left_ocp);
			mbhc->hph_status |= SND_JACK_OC_HPHL;
			wcd9xxx_jack_report(mbhc, &mbhc->headset_jack,
					    mbhc->hph_status,
@@ -3425,7 +3425,7 @@ static irqreturn_t wcd9xxx_hphr_ocp_irq(int irq, void *data)
				    0x10);
	} else {
		wcd9xxx_disable_irq(mbhc->resmgr->core_res,
				    WCD9XXX_IRQ_HPH_PA_OCPR_FAULT);
				    mbhc->intr_ids->hph_right_ocp);
		mbhc->hph_status |= SND_JACK_OC_HPHR;
		wcd9xxx_jack_report(mbhc, &mbhc->headset_jack,
				    mbhc->hph_status, WCD9XXX_JACK_MASK);
@@ -3505,7 +3505,8 @@ static void wcd9xxx_mbhc_cal(struct wcd9xxx_mbhc *mbhc)
	struct snd_soc_codec *codec = mbhc->codec;

	pr_debug("%s: enter\n", __func__);
	wcd9xxx_disable_irq(mbhc->resmgr->core_res, WCD9XXX_IRQ_MBHC_POTENTIAL);
	wcd9xxx_disable_irq(mbhc->resmgr->core_res,
			    mbhc->intr_ids->dce_est_complete);
	wcd9xxx_turn_onoff_rel_detection(codec, false);

	/* t_dce and t_sta are updated by wcd9xxx_update_mbhc_clk_rate() */
@@ -3645,7 +3646,8 @@ static void wcd9xxx_mbhc_cal(struct wcd9xxx_mbhc *mbhc)
	if (mbhc->mbhc_cb && mbhc->mbhc_cb->enable_mb_source)
		mbhc->mbhc_cb->enable_mb_source(codec, false);

	wcd9xxx_enable_irq(mbhc->resmgr->core_res, WCD9XXX_IRQ_MBHC_POTENTIAL);
	wcd9xxx_enable_irq(mbhc->resmgr->core_res,
			   mbhc->intr_ids->dce_est_complete);
	wcd9xxx_turn_onoff_rel_detection(codec, true);

	pr_debug("%s: leave\n", __func__);
@@ -3711,14 +3713,7 @@ static void wcd9xxx_mbhc_setup(struct wcd9xxx_mbhc *mbhc)
static int wcd9xxx_setup_jack_detect_irq(struct wcd9xxx_mbhc *mbhc)
{
	int ret = 0;
	struct snd_soc_codec *codec = mbhc->codec;
	void *core_res = mbhc->resmgr->core_res;
	int jack_irq;

	if (mbhc->mbhc_cb && mbhc->mbhc_cb->jack_detect_irq)
		jack_irq = mbhc->mbhc_cb->jack_detect_irq(codec);
	else
		jack_irq = WCD9XXX_IRQ_MBHC_JACK_SWITCH_DEFAULT;

	if (mbhc->mbhc_cfg->gpio) {
		ret = request_threaded_irq(mbhc->mbhc_cfg->gpio_irq, NULL,
@@ -3741,13 +3736,14 @@ static int wcd9xxx_setup_jack_detect_irq(struct wcd9xxx_mbhc *mbhc)
		snd_soc_update_bits(mbhc->codec, WCD9XXX_A_RX_HPH_OCP_CTL,
				    1 << 1, 1 << 1);

		ret = wcd9xxx_request_irq(core_res, jack_irq,
		ret = wcd9xxx_request_irq(core_res,
					  mbhc->intr_ids->hs_jack_switch,
					  wcd9xxx_mech_plug_detect_irq,
					  "Jack Detect",
					  mbhc);
		if (ret)
			pr_err("%s: Failed to request insert detect irq %d\n",
				__func__, jack_irq);
				__func__, mbhc->intr_ids->hs_jack_switch);
	}

	return ret;
@@ -3777,9 +3773,9 @@ static int wcd9xxx_init_and_calibrate(struct wcd9xxx_mbhc *mbhc)
		snd_soc_update_bits(codec, WCD9XXX_A_RX_HPH_OCP_CTL, 0x10,
				    0x10);
		wcd9xxx_enable_irq(mbhc->resmgr->core_res,
				   WCD9XXX_IRQ_HPH_PA_OCPL_FAULT);
				   mbhc->intr_ids->hph_left_ocp);
		wcd9xxx_enable_irq(mbhc->resmgr->core_res,
				   WCD9XXX_IRQ_HPH_PA_OCPR_FAULT);
				   mbhc->intr_ids->hph_right_ocp);

		/* Initialize mechanical mbhc */
		ret = wcd9xxx_setup_jack_detect_irq(mbhc);
@@ -4463,7 +4459,9 @@ int wcd9xxx_mbhc_get_impedance(struct wcd9xxx_mbhc *mbhc, uint32_t *zl,
int wcd9xxx_mbhc_init(struct wcd9xxx_mbhc *mbhc, struct wcd9xxx_resmgr *resmgr,
		      struct snd_soc_codec *codec,
		      int (*micbias_enable_cb) (struct snd_soc_codec*,  bool),
		      const struct wcd9xxx_mbhc_cb *mbhc_cb, int rco_clk_rate,
		      const struct wcd9xxx_mbhc_cb *mbhc_cb,
		      const struct wcd9xxx_mbhc_intr *mbhc_cdc_intr_ids,
		      int rco_clk_rate,
		      bool impedance_det_en)
{
	int ret;
@@ -4490,9 +4488,15 @@ int wcd9xxx_mbhc_init(struct wcd9xxx_mbhc *mbhc, struct wcd9xxx_resmgr *resmgr,
	mbhc->micbias_enable_cb = micbias_enable_cb;
	mbhc->rco_clk_rate = rco_clk_rate;
	mbhc->mbhc_cb = mbhc_cb;
	mbhc->intr_ids = mbhc_cdc_intr_ids;
	mbhc->impedance_detect = impedance_det_en;
	impedance_detect_en = impedance_det_en ? 1 : 0;

	if (mbhc->intr_ids == NULL) {
		pr_err("%s: Interrupt mapping not provided\n", __func__);
		return -EINVAL;
	}

	if (mbhc->headset_jack.jack == NULL) {
		ret = snd_soc_jack_new(codec, "Headset Jack", WCD9XXX_JACK_MASK,
				       &mbhc->headset_jack);
@@ -4536,62 +4540,62 @@ int wcd9xxx_mbhc_init(struct wcd9xxx_mbhc *mbhc, struct wcd9xxx_resmgr *resmgr,
	wcd9xxx_init_debugfs(mbhc);

	core_res = mbhc->resmgr->core_res;
	ret = wcd9xxx_request_irq(core_res, WCD9XXX_IRQ_MBHC_INSERTION,
	ret = wcd9xxx_request_irq(core_res, mbhc->intr_ids->insertion,
				  wcd9xxx_hs_insert_irq,
				  "Headset insert detect", mbhc);
	if (ret) {
		pr_err("%s: Failed to request irq %d, ret = %d\n", __func__,
		       WCD9XXX_IRQ_MBHC_INSERTION, ret);
		       mbhc->intr_ids->insertion, ret);
		goto err_insert_irq;
	}
	wcd9xxx_disable_irq(core_res, WCD9XXX_IRQ_MBHC_INSERTION);
	wcd9xxx_disable_irq(core_res, mbhc->intr_ids->insertion);

	ret = wcd9xxx_request_irq(core_res, WCD9XXX_IRQ_MBHC_REMOVAL,
	ret = wcd9xxx_request_irq(core_res, mbhc->intr_ids->poll_plug_rem,
				  wcd9xxx_hs_remove_irq,
				  "Headset remove detect", mbhc);
	if (ret) {
		pr_err("%s: Failed to request irq %d\n", __func__,
			WCD9XXX_IRQ_MBHC_REMOVAL);
			mbhc->intr_ids->poll_plug_rem);
		goto err_remove_irq;
	}

	ret = wcd9xxx_request_irq(core_res, WCD9XXX_IRQ_MBHC_POTENTIAL,
	ret = wcd9xxx_request_irq(core_res, mbhc->intr_ids->dce_est_complete,
				  wcd9xxx_dce_handler, "DC Estimation detect",
				  mbhc);
	if (ret) {
		pr_err("%s: Failed to request irq %d\n", __func__,
		       WCD9XXX_IRQ_MBHC_POTENTIAL);
		       mbhc->intr_ids->dce_est_complete);
		goto err_potential_irq;
	}

	ret = wcd9xxx_request_irq(core_res, WCD9XXX_IRQ_MBHC_RELEASE,
	ret = wcd9xxx_request_irq(core_res, mbhc->intr_ids->button_release,
				  wcd9xxx_release_handler,
				  "Button Release detect", mbhc);
	if (ret) {
		pr_err("%s: Failed to request irq %d\n", __func__,
			WCD9XXX_IRQ_MBHC_RELEASE);
			mbhc->intr_ids->button_release);
		goto err_release_irq;
	}

	ret = wcd9xxx_request_irq(core_res, WCD9XXX_IRQ_HPH_PA_OCPL_FAULT,
	ret = wcd9xxx_request_irq(core_res, mbhc->intr_ids->hph_left_ocp,
				  wcd9xxx_hphl_ocp_irq, "HPH_L OCP detect",
				  mbhc);
	if (ret) {
		pr_err("%s: Failed to request irq %d\n", __func__,
		       WCD9XXX_IRQ_HPH_PA_OCPL_FAULT);
		       mbhc->intr_ids->hph_left_ocp);
		goto err_hphl_ocp_irq;
	}
	wcd9xxx_disable_irq(core_res, WCD9XXX_IRQ_HPH_PA_OCPL_FAULT);
	wcd9xxx_disable_irq(core_res, mbhc->intr_ids->hph_left_ocp);

	ret = wcd9xxx_request_irq(core_res, WCD9XXX_IRQ_HPH_PA_OCPR_FAULT,
	ret = wcd9xxx_request_irq(core_res, mbhc->intr_ids->hph_right_ocp,
				  wcd9xxx_hphr_ocp_irq, "HPH_R OCP detect",
				  mbhc);
	if (ret) {
		pr_err("%s: Failed to request irq %d\n", __func__,
		       WCD9XXX_IRQ_HPH_PA_OCPR_FAULT);
		       mbhc->intr_ids->hph_right_ocp);
		goto err_hphr_ocp_irq;
	}
	wcd9xxx_disable_irq(core_res, WCD9XXX_IRQ_HPH_PA_OCPR_FAULT);
	wcd9xxx_disable_irq(core_res, mbhc->intr_ids->hph_right_ocp);

	wcd9xxx_regmgr_cond_register(resmgr, 1 << WCD9XXX_COND_HPH_MIC |
					     1 << WCD9XXX_COND_HPH);
@@ -4600,15 +4604,15 @@ int wcd9xxx_mbhc_init(struct wcd9xxx_mbhc *mbhc, struct wcd9xxx_resmgr *resmgr,
	return ret;

err_hphr_ocp_irq:
	wcd9xxx_free_irq(core_res, WCD9XXX_IRQ_HPH_PA_OCPL_FAULT, mbhc);
	wcd9xxx_free_irq(core_res, mbhc->intr_ids->hph_left_ocp, mbhc);
err_hphl_ocp_irq:
	wcd9xxx_free_irq(core_res, WCD9XXX_IRQ_MBHC_RELEASE, mbhc);
	wcd9xxx_free_irq(core_res, mbhc->intr_ids->button_release, mbhc);
err_release_irq:
	wcd9xxx_free_irq(core_res, WCD9XXX_IRQ_MBHC_POTENTIAL, mbhc);
	wcd9xxx_free_irq(core_res, mbhc->intr_ids->dce_est_complete, mbhc);
err_potential_irq:
	wcd9xxx_free_irq(core_res, WCD9XXX_IRQ_MBHC_REMOVAL, mbhc);
	wcd9xxx_free_irq(core_res, mbhc->intr_ids->poll_plug_rem, mbhc);
err_remove_irq:
	wcd9xxx_free_irq(core_res, WCD9XXX_IRQ_MBHC_INSERTION, mbhc);
	wcd9xxx_free_irq(core_res, mbhc->intr_ids->insertion, mbhc);
err_insert_irq:
	wcd9xxx_resmgr_unregister_notifier(mbhc->resmgr, &mbhc->nblock);

@@ -4625,22 +4629,15 @@ void wcd9xxx_mbhc_deinit(struct wcd9xxx_mbhc *mbhc)
	wcd9xxx_regmgr_cond_deregister(mbhc->resmgr, 1 << WCD9XXX_COND_HPH_MIC |
						     1 << WCD9XXX_COND_HPH);

	wcd9xxx_free_irq(core_res, WCD9XXX_IRQ_MBHC_RELEASE, mbhc);
	wcd9xxx_free_irq(core_res, WCD9XXX_IRQ_MBHC_POTENTIAL, mbhc);
	wcd9xxx_free_irq(core_res, WCD9XXX_IRQ_MBHC_REMOVAL, mbhc);
	wcd9xxx_free_irq(core_res, WCD9XXX_IRQ_MBHC_INSERTION, mbhc);

	if (mbhc->mbhc_cb && mbhc->mbhc_cb->free_irq)
		mbhc->mbhc_cb->free_irq(mbhc);
	else
		wcd9xxx_free_irq(core_res, WCD9320_IRQ_MBHC_JACK_SWITCH,
				 mbhc);

	wcd9xxx_free_irq(core_res, WCD9XXX_IRQ_HPH_PA_OCPL_FAULT, mbhc);
	wcd9xxx_free_irq(core_res, WCD9XXX_IRQ_HPH_PA_OCPR_FAULT, mbhc);
	wcd9xxx_free_irq(core_res, mbhc->intr_ids->button_release, mbhc);
	wcd9xxx_free_irq(core_res, mbhc->intr_ids->dce_est_complete, mbhc);
	wcd9xxx_free_irq(core_res, mbhc->intr_ids->poll_plug_rem, mbhc);
	wcd9xxx_free_irq(core_res, mbhc->intr_ids->insertion, mbhc);
	wcd9xxx_free_irq(core_res, mbhc->intr_ids->hs_jack_switch, mbhc);
	wcd9xxx_free_irq(core_res, mbhc->intr_ids->hph_left_ocp, mbhc);
	wcd9xxx_free_irq(core_res, mbhc->intr_ids->hph_right_ocp, mbhc);

	wcd9xxx_resmgr_unregister_notifier(mbhc->resmgr, &mbhc->nblock);

	wcd9xxx_cleanup_debugfs(mbhc);
}
EXPORT_SYMBOL(wcd9xxx_mbhc_deinit);
+16 −2
Original line number Diff line number Diff line
@@ -236,16 +236,26 @@ struct wcd9xxx_cfilt_mode {
	u8 reg_mask;
};

struct wcd9xxx_mbhc_intr {
	int poll_plug_rem;
	int shortavg_complete;
	int potential_button_press;
	int button_release;
	int dce_est_complete;
	int insertion;
	int hph_left_ocp;
	int hph_right_ocp;
	int hs_jack_switch;
};

struct wcd9xxx_mbhc_cb {
	void (*enable_mux_bias_block) (struct snd_soc_codec *);
	void (*cfilt_fast_mode) (struct snd_soc_codec *, struct wcd9xxx_mbhc *);
	void (*codec_specific_cal) (struct snd_soc_codec *,
				    struct wcd9xxx_mbhc *);
	int (*jack_detect_irq) (struct snd_soc_codec *);
	struct wcd9xxx_cfilt_mode (*switch_cfilt_mode) (struct wcd9xxx_mbhc *,
							bool);
	void (*select_cfilt) (struct snd_soc_codec *, struct wcd9xxx_mbhc *);
	void (*free_irq) (struct wcd9xxx_mbhc *);
	enum wcd9xxx_cdc_type (*get_cdc_type) (void);
	void (*enable_clock_gate) (struct snd_soc_codec *, bool);
	int (*setup_zdet) (struct wcd9xxx_mbhc *,
@@ -327,6 +337,9 @@ struct wcd9xxx_mbhc {

	bool update_z;

	/* Holds codec specific interrupt mapping */
	const struct wcd9xxx_mbhc_intr *intr_ids;

#ifdef CONFIG_DEBUG_FS
	struct dentry *debugfs_poke;
	struct dentry *debugfs_mbhc;
@@ -395,6 +408,7 @@ int wcd9xxx_mbhc_init(struct wcd9xxx_mbhc *mbhc, struct wcd9xxx_resmgr *resmgr,
		      struct snd_soc_codec *codec,
		      int (*micbias_enable_cb) (struct snd_soc_codec*,  bool),
		      const struct wcd9xxx_mbhc_cb *mbhc_cb,
		      const struct wcd9xxx_mbhc_intr *mbhc_cdc_intr_ids,
		      int rco_clk_rate,
		      bool impedance_det_en);
void wcd9xxx_mbhc_deinit(struct wcd9xxx_mbhc *mbhc);