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

Commit 175db16b authored by NagaRadhesh Yeleswarapu's avatar NagaRadhesh Yeleswarapu Committed by Yeleswarapu Nagaradhesh
Browse files

ASoC: wcd: add support to program button thresholds



Current software hardcodes threshold registers, due to this we can not
detect all buttons properly.So update button threshold
registers to detect buttons with different resistances.

CRs-Fixed: 662091
Change-Id: Ie487163bffbcc57dc1c0cfae78f47d4c21643c7a
Signed-off-by: default avatarYeleswarapu Nagaradhesh <nagaradh@codeaurora.org>
parent e1ce01c5
Loading
Loading
Loading
Loading
+29 −20
Original line number Diff line number Diff line
@@ -61,6 +61,33 @@
		  "%s: BCL should have acquired\n", __func__); \
}

static void wcd_program_btn_threshold(const struct wcd_mbhc *mbhc)
{
	struct wcd_mbhc_btn_detect_cfg *btn_det;
	struct snd_soc_codec *codec = mbhc->codec;
	struct snd_soc_card *card = codec->card;
	u16 i;
	u32 course, fine, reg_val;
	u16 reg_addr = MSM8X16_WCD_A_ANALOG_MBHC_BTN0_ZDETL_CTL;

	if (mbhc->mbhc_cfg->calibration == NULL) {
		dev_err(card->dev, "%s: calibration data is NULL\n", __func__);
		return;
	}

	btn_det = WCD_MBHC_CAL_BTN_DET_PTR(mbhc->mbhc_cfg->calibration);

	for (i = 0; i <  btn_det->num_btn; i++) {
		course = (btn_det->_v_btn_high[i] / 100);
		fine = ((btn_det->_v_btn_high[i] % 100) / 12);
		reg_val = (course << 5) | (fine << 2);
		snd_soc_update_bits(codec, reg_addr, 0xFC, reg_val);
		pr_debug("%s: course: %d fine: %d reg_addr: %x reg_val: %x\n",
				__func__, course, fine, reg_addr, reg_val);
		reg_addr++;
	}
}

static void wcd_mbhc_jack_report(struct wcd_mbhc *mbhc,
				struct snd_soc_jack *jack, int status, int mask)
{
@@ -597,26 +624,6 @@ static void wcd_mbhc_swch_irq_handler(struct wcd_mbhc *mbhc)
		snd_soc_update_bits(codec,
				 MSM8X16_WCD_A_ANALOG_MICB_2_EN,
				0x20, 0x00);
		/*
		 * Set button ref values actually the values
		 * should be taken from the config data through
		 * ACDB
		 */
		snd_soc_update_bits(codec,
			MSM8X16_WCD_A_ANALOG_MBHC_BTN0_ZDETL_CTL,
				0xFC, 0x08);
		snd_soc_update_bits(codec,
			MSM8X16_WCD_A_ANALOG_MBHC_BTN1_ZDETM_CTL,
				0xFC, 0x10);
		snd_soc_update_bits(codec,
			MSM8X16_WCD_A_ANALOG_MBHC_BTN2_ZDETH_CTL,
				0xFC, 0x18);
		snd_soc_update_bits(codec,
			MSM8X16_WCD_A_ANALOG_MBHC_BTN3_CTL,
				0xFC, 0x24);
		snd_soc_update_bits(codec,
			MSM8X16_WCD_A_ANALOG_MBHC_BTN4_CTL,
				0xFC, 0x2C);
		/* Enable HW FSM and current source */
		snd_soc_update_bits(codec,
				MSM8X16_WCD_A_ANALOG_MBHC_FSM_CTL,
@@ -909,6 +916,8 @@ static int wcd_mbhc_initialise(struct wcd_mbhc *mbhc)
	snd_soc_update_bits(codec,
			MSM8X16_WCD_A_DIGITAL_CDC_DIG_CLK_CTL,
			0x08, 0x08);
	/* Program Button threshold registers */
	wcd_program_btn_threshold(mbhc);
	/* enable the WCD MBHC IRQ's */
	wcd9xxx_enable_irq(mbhc->intr_ids->mbhc_sw_intr);
	wcd9xxx_enable_irq(mbhc->intr_ids->mbhc_btn_press_intr);
+16 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

#define TOMBAK_MBHC_NC	0
#define TOMBAK_MBHC_NO	1
#define WCD_MBHC_DEF_BUTTONS 5

enum wcd_mbhc_plug_type {
	PLUG_TYPE_INVALID = -1,
@@ -31,6 +32,17 @@ enum pa_dac_ack_flags {
	WCD_MBHC_HPHR_PA_OFF_ACK,
};

enum wcd_mbhc_btn_det_mem {
	WCD_MBHC_BTN_DET_V_BTN_LOW,
	WCD_MBHC_BTN_DET_V_BTN_HIGH
};

struct wcd_mbhc_btn_detect_cfg {
	u8 num_btn;
	s16 _v_btn_low[WCD_MBHC_DEF_BUTTONS];
	s16 _v_btn_high[WCD_MBHC_DEF_BUTTONS];
} __packed;

struct wcd_mbhc_config {
	bool read_fw_bin;
	void *calibration;
@@ -81,6 +93,10 @@ struct wcd_mbhc {
	/* Holds codec specific interrupt mapping */
	const struct wcd_mbhc_intr *intr_ids;
};

#define WCD_MBHC_CAL_BTN_DET_PTR(cali) ( \
	    (struct wcd_mbhc_btn_detect_cfg *) cali)

int wcd_mbhc_start(struct wcd_mbhc *mbhc,
		       struct wcd_mbhc_config *mbhc_cfg);
void wcd_mbhc_stop(struct wcd_mbhc *mbhc);
+42 −2
Original line number Diff line number Diff line
@@ -495,13 +495,45 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream)
	return ret;
}

static void *def_msm8x16_wcd_mbhc_cal(void)
{
	void *msm8x16_wcd_cal;
	struct wcd_mbhc_btn_detect_cfg *btn_cfg;
	u16 *btn_low, *btn_high;

	msm8x16_wcd_cal = kzalloc(sizeof(struct wcd_mbhc_btn_detect_cfg),
					GFP_KERNEL);
	if (!msm8x16_wcd_cal) {
		pr_err("%s: out of memory\n", __func__);
		return NULL;
	}

	btn_cfg = WCD_MBHC_CAL_BTN_DET_PTR(msm8x16_wcd_cal);
	btn_cfg->num_btn = WCD_MBHC_DEF_BUTTONS;
	btn_low = btn_cfg->_v_btn_low;
	btn_high = btn_cfg->_v_btn_high;

	btn_low[0] = 0;
	btn_high[0] = 25;
	btn_low[1] = 25;
	btn_high[1] = 50;
	btn_low[2] = 50;
	btn_high[2] = 75;
	btn_low[3] = 75;
	btn_high[3] = 112;
	btn_low[4] = 112;
	btn_high[4] = 137;

	return msm8x16_wcd_cal;
}

static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd)
{

	struct snd_soc_codec *codec = rtd->codec;
	struct snd_soc_dapm_context *dapm = &codec->dapm;
	struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
	int ret = 0;
	int ret = -ENOMEM;

	pr_debug("%s(),dev_name%s\n", __func__, dev_name(cpu_dai->dev));

@@ -528,7 +560,15 @@ static int msm_audrx_init(struct snd_soc_pcm_runtime *rtd)

	snd_soc_dapm_sync(dapm);

	mbhc_cfg.calibration = def_msm8x16_wcd_mbhc_cal();
	if (mbhc_cfg.calibration) {
		ret = msm8x16_wcd_hs_detect(codec, &mbhc_cfg);
		if (ret) {
			pr_err("%s: msm8x16_wcd_hs_detect failed\n", __func__);
			kfree(mbhc_cfg.calibration);
			return ret;
		}
	}

	return ret;
}