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

Commit 9bbac25a 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: Add support moisture detection in headset jack"

parents da100b9a 688c230b
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -249,6 +249,8 @@ static struct wcd_mbhc_register wcd_mbhc_registers[] = {
	WCD_MBHC_REGISTER("WCD_MBHC_SWCH_LEVEL_REMOVE",
			  MSM8X16_WCD_A_ANALOG_MBHC_ZDET_ELECT_RESULT,
			  0x10, 4, 0),
	WCD_MBHC_REGISTER("WCD_MBHC_MOISTURE_VREF",
			  0, 0, 0, 0),
};

struct msm8x16_wcd_spmi {
+16 −12
Original line number Diff line number Diff line
@@ -1238,17 +1238,6 @@ static void wcd_mbhc_swch_irq_handler(struct wcd_mbhc *mbhc)
	WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_MECH_DETECTION_TYPE,
				 !detection_type);

	/*
	 * For faster pull-up, adjust the pull-up current to 3uA.
	 * Possible that some codecs may choose not to update the
	 * pull up current, in which case this callback function
	 * will not be defined.
	 */
	if (mbhc->mbhc_cb->hph_pull_up_control) {
		mbhc->mbhc_cb->hph_pull_up_control(codec,
				(detection_type ? REMOVE : INSERT));
	}

	pr_debug("%s: mbhc->current_plug: %d detection_type: %d\n", __func__,
			mbhc->current_plug, detection_type);
	wcd_cancel_hs_detect_plug(mbhc, &mbhc->correct_plug_swch);
@@ -1799,6 +1788,18 @@ static irqreturn_t wcd_mbhc_hphr_ocp_irq(int irq, void *data)
	return IRQ_HANDLED;
}

static void wcd_mbhc_moisture_config(struct wcd_mbhc *mbhc)
{
	if (mbhc->mbhc_cfg->moist_cfg.m_vref_ctl == V_OFF)
		return;

	WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_MOISTURE_VREF,
				 mbhc->mbhc_cfg->moist_cfg.m_vref_ctl);
	if (mbhc->mbhc_cb->hph_pull_up_control)
		mbhc->mbhc_cb->hph_pull_up_control(mbhc->codec,
				mbhc->mbhc_cfg->moist_cfg.m_iref_ctl);
}

static int wcd_mbhc_initialise(struct wcd_mbhc *mbhc)
{
	int ret = 0;
@@ -1809,9 +1810,12 @@ static int wcd_mbhc_initialise(struct wcd_mbhc *mbhc)

	/* enable HS detection */
	if (mbhc->mbhc_cb->hph_pull_up_control)
		mbhc->mbhc_cb->hph_pull_up_control(codec, INSERT);
		mbhc->mbhc_cb->hph_pull_up_control(codec, I_DEFAULT);
	else
		WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HS_L_DET_PULL_UP_CTRL, 3);

	wcd_mbhc_moisture_config(mbhc);

	WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_HPHL_PLUG_TYPE, mbhc->hphl_swh);
	WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_GND_PLUG_TYPE, mbhc->gnd_swh);
	WCD_MBHC_REG_UPDATE_BITS(WCD_MBHC_SW_HPH_LP_100K_TO_GND, 1);
+53 −21
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ enum wcd_mbhc_register_function {
	WCD_MBHC_HPHL_PA_EN,
	WCD_MBHC_HPH_PA_EN,
	WCD_MBHC_SWCH_LEVEL_REMOVE,
	WCD_MBHC_MOISTURE_VREF,
};

enum wcd_mbhc_plug_type {
@@ -83,11 +84,6 @@ enum {
	MIC_BIAS_4
};

enum {
	REMOVE = 0,
	INSERT,
};

enum {
	MICB_PULLUP_ENABLE,
	MICB_PULLUP_DISABLE,
@@ -209,6 +205,30 @@ enum wcd_mbhc_hph_type {
	WCD_MBHC_HPH_STEREO,
};

/*
 * These enum definitions are directly mapped to the register
 * definitions
 */
enum mbhc_moisture_vref {
	V_OFF,
	V_45_MV,
	V_100_MV,
	V_225_MV,
};

enum mbhc_hs_pullup_iref {
	I_DEFAULT = -1,
	I_OFF = 0,
	I_1P0_UA,
	I_2P0_UA,
	I_3P0_UA,
};

struct wcd_mbhc_moisture_cfg {
	enum mbhc_moisture_vref m_vref_ctl;
	enum mbhc_hs_pullup_iref m_iref_ctl;
};

struct wcd_mbhc_config {
	bool read_fw_bin;
	void *calibration;
@@ -219,6 +239,7 @@ struct wcd_mbhc_config {
	bool gnd_det_en;
	int key_code[WCD_MBHC_KEYCODE_NUM];
	uint32_t linein_th;
	struct wcd_mbhc_moisture_cfg moist_cfg;
};

struct wcd_mbhc_intr {
@@ -261,21 +282,31 @@ struct wcd_mbhc_register {
		  "%s: BCL should have acquired\n", __func__); \
}

/*
 * Macros to update and read mbhc register bits. Check for
 * "0" before updating or reading the register, because it
 * is possible that one codec wants to write to that bit and
 * other codec does not.
 */
#define WCD_MBHC_REG_UPDATE_BITS(function, val)         \
{						\
do {                                                    \
	if (mbhc->wcd_mbhc_regs[function].reg) {        \
		snd_soc_update_bits(mbhc->codec,	\
		mbhc->wcd_mbhc_regs[function].reg,	\
		mbhc->wcd_mbhc_regs[function].mask,	\
		val << (mbhc->wcd_mbhc_regs[function].offset)); \
}
	}                                               \
} while (0)

#define WCD_MBHC_REG_READ(function, val)	        \
{						\
do {                                                    \
	if (mbhc->wcd_mbhc_regs[function].reg) {        \
		val = (((snd_soc_read(mbhc->codec,	\
		mbhc->wcd_mbhc_regs[function].reg)) &	\
		(mbhc->wcd_mbhc_regs[function].mask)) >> \
		(mbhc->wcd_mbhc_regs[function].offset)); \
}
	}                                               \
} while (0)

struct wcd_mbhc_cb {
	int (*enable_mb_source)(struct snd_soc_codec *, bool);
@@ -307,7 +338,8 @@ struct wcd_mbhc_cb {
	bool (*hph_pa_on_status)(struct snd_soc_codec *);
	void (*set_btn_thr)(struct snd_soc_codec *, s16 *, s16 *,
			    int num_btn, bool);
	void (*hph_pull_up_control)(struct snd_soc_codec *, bool);
	void (*hph_pull_up_control)(struct snd_soc_codec *,
				    enum mbhc_hs_pullup_iref);
	int (*mbhc_micbias_control)(struct snd_soc_codec *, int req);
	void (*mbhc_micb_ramp_control)(struct snd_soc_codec *, bool);
	bool (*extn_use_mb)(struct snd_soc_codec *);
+34 −2
Original line number Diff line number Diff line
@@ -495,6 +495,13 @@ static struct wcd_mbhc_register wcd_mbhc_registers[] = {
			  WCD9335_ANA_HPH, 0xC0, 6, 0),
	WCD_MBHC_REGISTER("WCD_MBHC_SWCH_LEVEL_REMOVE",
			  WCD9335_ANA_MBHC_RESULT_3, 0x10, 4, 0),
	/*
	 * Initialize moisture register as "0" and based on codec
	 * version, the register, mask fields get populated.
	 * Register "0" is not a valid register for MBHC.
	 */
	WCD_MBHC_REGISTER("WCD_MBHC_MOISTURE_VREF",
			  0, 0, 0, 0),
};

static const struct wcd_mbhc_intr intr_ids = {
@@ -899,8 +906,25 @@ static bool tasha_mbhc_hph_pa_on_status(struct snd_soc_codec *codec)
}

static void tasha_mbhc_hph_l_pull_up_control(struct snd_soc_codec *codec,
					     bool is_insert)
					enum mbhc_hs_pullup_iref pull_up_cur)
{
	struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);

	if (!tasha)
		return;

	/* Default pull up current to 2uA */
	if (pull_up_cur < I_OFF || pull_up_cur > I_3P0_UA ||
	    pull_up_cur == I_DEFAULT)
		pull_up_cur = I_2P0_UA;

	dev_dbg(codec->dev, "%s: HS pull up current:%d\n",
		__func__, pull_up_cur);

	if (TASHA_IS_2_0(tasha->wcd9xxx->version))
		snd_soc_update_bits(codec, WCD9335_MBHC_PLUG_DETECT_CTL,
			    0xC0, pull_up_cur << 6);
	else
		snd_soc_update_bits(codec, WCD9335_MBHC_PLUG_DETECT_CTL,
			    0xC0, 0x40);
}
@@ -9855,6 +9879,14 @@ static int tasha_codec_probe(struct snd_soc_codec *codec)
	}

	/* Initialize MBHC module */
	if (TASHA_IS_2_0(tasha->wcd9xxx->version)) {
		wcd_mbhc_registers[WCD_MBHC_MOISTURE_VREF].reg =
			WCD9335_MBHC_CTL_2;
		wcd_mbhc_registers[WCD_MBHC_MOISTURE_VREF].mask =
			0x0C;
		wcd_mbhc_registers[WCD_MBHC_MOISTURE_VREF].offset =
			2;
	}
	ret = wcd_mbhc_init(&tasha->mbhc, codec, &mbhc_cb, &intr_ids,
		      wcd_mbhc_registers, TASHA_ZDET_SUPPORTED);
	if (ret) {