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

Commit ffee286d 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: add support to program button thresholds"

parents f032be61 175db16b
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;
}