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

Commit cddb38bf 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: Disconnect ANC from RX chain during plug removal"

parents 32c5f658 23b93173
Loading
Loading
Loading
Loading
+35 −0
Original line number Diff line number Diff line
@@ -329,6 +329,7 @@ static int wcd_event_notify(struct notifier_block *self, unsigned long val,
			/* Disable micbias, pullup & enable cs */
			wcd_enable_curr_micbias(mbhc, WCD_MBHC_EN_CS);
		mutex_unlock(&mbhc->hphl_pa_lock);
		clear_bit(WCD_MBHC_ANC0_OFF_ACK, &mbhc->hph_anc_state);
		break;
	case WCD_EVENT_PRE_HPHR_PA_OFF:
		mutex_lock(&mbhc->hphr_pa_lock);
@@ -346,6 +347,7 @@ static int wcd_event_notify(struct notifier_block *self, unsigned long val,
			/* Disable micbias, pullup & enable cs */
			wcd_enable_curr_micbias(mbhc, WCD_MBHC_EN_CS);
		mutex_unlock(&mbhc->hphr_pa_lock);
		clear_bit(WCD_MBHC_ANC1_OFF_ACK, &mbhc->hph_anc_state);
		break;
	case WCD_EVENT_PRE_HPHL_PA_ON:
		set_bit(WCD_MBHC_EVENT_PA_HPHL, &mbhc->event_state);
@@ -439,6 +441,25 @@ static void wcd_mbhc_clr_and_turnon_hph_padac(struct wcd_mbhc *mbhc)
			 __func__);
		usleep_range(wg_time * 1000, wg_time * 1000 + 50);
	}

	if (test_and_clear_bit(WCD_MBHC_ANC0_OFF_ACK,
				&mbhc->hph_anc_state)) {
		usleep_range(20000, 20100);
		pr_debug("%s: HPHL ANC clear flag and enable ANC_EN\n",
			__func__);
		if (mbhc->mbhc_cb->update_anc_state)
			mbhc->mbhc_cb->update_anc_state(mbhc->codec, true, 0);
	}

	if (test_and_clear_bit(WCD_MBHC_ANC1_OFF_ACK,
				&mbhc->hph_anc_state)) {
		usleep_range(20000, 20100);
		pr_debug("%s: HPHR ANC clear flag and enable ANC_EN\n",
			__func__);
		if (mbhc->mbhc_cb->update_anc_state)
			mbhc->mbhc_cb->update_anc_state(mbhc->codec, true, 1);
	}

}

static bool wcd_mbhc_is_hph_pa_on(struct wcd_mbhc *mbhc)
@@ -471,6 +492,20 @@ static void wcd_mbhc_set_and_turnoff_hph_padac(struct wcd_mbhc *mbhc)
	}
	WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HPH_PA_EN, 0);
	usleep_range(wg_time * 1000, wg_time * 1000 + 50);


	if (mbhc->mbhc_cb->is_anc_on && mbhc->mbhc_cb->is_anc_on(mbhc)) {
		usleep_range(20000, 20100);
		pr_debug("%s ANC is on, setting ANC_OFF_ACK\n", __func__);
		set_bit(WCD_MBHC_ANC0_OFF_ACK, &mbhc->hph_anc_state);
		set_bit(WCD_MBHC_ANC1_OFF_ACK, &mbhc->hph_anc_state);
		if (mbhc->mbhc_cb->update_anc_state) {
			mbhc->mbhc_cb->update_anc_state(mbhc->codec, false, 0);
			mbhc->mbhc_cb->update_anc_state(mbhc->codec, false, 1);
		} else {
			pr_debug("%s ANC is off\n", __func__);
		}
	}
}

int wcd_mbhc_get_impedance(struct wcd_mbhc *mbhc, uint32_t *zl,
+9 −0
Original line number Diff line number Diff line
@@ -234,6 +234,11 @@ enum pa_dac_ack_flags {
	WCD_MBHC_HPHR_PA_OFF_ACK,
};

enum anc_ack_flags {
	WCD_MBHC_ANC0_OFF_ACK = 0,
	WCD_MBHC_ANC1_OFF_ACK,
};

enum wcd_mbhc_btn_det_mem {
	WCD_MBHC_BTN_DET_V_BTN_LOW,
	WCD_MBHC_BTN_DET_V_BTN_HIGH
@@ -482,6 +487,9 @@ struct wcd_mbhc_cb {
	void (*hph_pull_down_ctrl)(struct snd_soc_codec *, bool);
	void (*mbhc_moisture_config)(struct wcd_mbhc *);
	bool (*hph_register_recovery)(struct wcd_mbhc *);
	void (*update_anc_state)(struct snd_soc_codec *codec,
				 bool enable, int anc_num);
	bool (*is_anc_on)(struct wcd_mbhc *mbhc);
};

struct wcd_mbhc_fn {
@@ -532,6 +540,7 @@ struct wcd_mbhc {

	/* track PA/DAC state to sync with userspace */
	unsigned long hph_pa_dac_state;
	unsigned long hph_anc_state;
	unsigned long event_state;
	unsigned long jiffies_atreport;

+28 −0
Original line number Diff line number Diff line
@@ -2014,6 +2014,32 @@ static void tasha_mbhc_moisture_config(struct wcd_mbhc *mbhc)
	tasha_mbhc_hph_l_pull_up_control(codec, mbhc->moist_iref);
}

static void tasha_update_anc_state(struct snd_soc_codec *codec, bool enable,
				   int anc_num)
{
	if (enable)
		snd_soc_update_bits(codec, WCD9335_CDC_RX1_RX_PATH_CFG0 +
				(20 * anc_num), 0x10, 0x10);
	else
		snd_soc_update_bits(codec, WCD9335_CDC_RX1_RX_PATH_CFG0 +
				(20 * anc_num), 0x10, 0x00);
}

static bool tasha_is_anc_on(struct wcd_mbhc *mbhc)
{
	bool anc_on = false;
	u16 ancl, ancr;

	ancl =
	(snd_soc_read(mbhc->codec, WCD9335_CDC_RX1_RX_PATH_CFG0)) & 0x10;
	ancr =
	(snd_soc_read(mbhc->codec, WCD9335_CDC_RX2_RX_PATH_CFG0)) & 0x10;

	anc_on = !!(ancl | ancr);

	return anc_on;
}

static const struct wcd_mbhc_cb mbhc_cb = {
	.request_irq = tasha_mbhc_request_irq,
	.irq_control = tasha_mbhc_irq_control,
@@ -2036,6 +2062,8 @@ static const struct wcd_mbhc_cb mbhc_cb = {
	.mbhc_gnd_det_ctrl = tasha_mbhc_gnd_det_ctrl,
	.hph_pull_down_ctrl = tasha_mbhc_hph_pull_down_ctrl,
	.mbhc_moisture_config = tasha_mbhc_moisture_config,
	.update_anc_state = tasha_update_anc_state,
	.is_anc_on = tasha_is_anc_on,
};

static int tasha_get_anc_slot(struct snd_kcontrol *kcontrol,
+28 −0
Original line number Diff line number Diff line
@@ -829,6 +829,32 @@ static bool tavil_hph_register_recovery(struct wcd_mbhc *mbhc)
	return wcd934x_mbhc->is_hph_recover;
}

static void tavil_update_anc_state(struct snd_soc_codec *codec, bool enable,
				   int anc_num)
{
	if (enable)
		snd_soc_update_bits(codec, WCD934X_CDC_RX1_RX_PATH_CFG0 +
				(20 * anc_num), 0x10, 0x10);
	else
		snd_soc_update_bits(codec, WCD934X_CDC_RX1_RX_PATH_CFG0 +
				(20 * anc_num), 0x10, 0x00);
}

static bool tavil_is_anc_on(struct wcd_mbhc *mbhc)
{
	bool anc_on = false;
	u16 ancl, ancr;

	ancl =
	(snd_soc_read(mbhc->codec, WCD934X_CDC_RX1_RX_PATH_CFG0)) & 0x10;
	ancr =
	(snd_soc_read(mbhc->codec, WCD934X_CDC_RX2_RX_PATH_CFG0)) & 0x10;

	anc_on = !!(ancl | ancr);

	return anc_on;
}

static const struct wcd_mbhc_cb mbhc_cb = {
	.request_irq = tavil_mbhc_request_irq,
	.irq_control = tavil_mbhc_irq_control,
@@ -852,6 +878,8 @@ static const struct wcd_mbhc_cb mbhc_cb = {
	.hph_pull_down_ctrl = tavil_mbhc_hph_pull_down_ctrl,
	.mbhc_moisture_config = tavil_mbhc_moisture_config,
	.hph_register_recovery = tavil_hph_register_recovery,
	.update_anc_state = tavil_update_anc_state,
	.is_anc_on = tavil_is_anc_on,
};

static struct regulator *tavil_codec_find_ondemand_regulator(