ASoC: wcd9310: Add plug detection through mechanical switch

Use mechanical switch on the phone jack to detect headset/headphone
insertion and removal.  Mechanical switch is beneficial to avoid fake
button press and high impedance microphone headset detection.

CRs-fixed: 341402
Change-Id: Idffba14316ab25e07736d1b7385f0edb16216089
Signed-off-by: Joonwoo Park <joonwoop@codeaurora.org>
diff --git a/sound/soc/msm/mdm9615.c b/sound/soc/msm/mdm9615.c
index fff978f..b122f64 100644
--- a/sound/soc/msm/mdm9615.c
+++ b/sound/soc/msm/mdm9615.c
@@ -75,7 +75,20 @@
 static struct snd_soc_jack hs_jack;
 static struct snd_soc_jack button_jack;
 
-static void *tabla_mbhc_cal;
+static int mdm9615_enable_codec_ext_clk(struct snd_soc_codec *codec, int enable,
+					bool dapm);
+static struct tabla_mbhc_config mbhc_cfg = {
+	.headset_jack = &hs_jack,
+	.button_jack = &button_jack,
+	.read_fw_bin = false,
+	.calibration = NULL,
+	.micbias = TABLA_MICBIAS2,
+	.mclk_cb_fn = mdm9615_enable_codec_ext_clk,
+	.mclk_rate = TABLA_EXT_CLK_RATE,
+	.gpio = 0,
+	.gpio_irq = 0,
+	.gpio_level_insert = 1,
+};
 
 static void mdm9615_enable_ext_spk_amp_gpio(u32 spk_amp_gpio)
 {
@@ -296,8 +309,8 @@
 	}
 	return 0;
 }
-int mdm9615_enable_codec_ext_clk(
-		struct snd_soc_codec *codec, int enable)
+static int mdm9615_enable_codec_ext_clk(struct snd_soc_codec *codec, int enable,
+					bool dapm)
 {
 	pr_debug("%s: enable = %d\n", __func__, enable);
 	if (enable) {
@@ -309,7 +322,7 @@
 		if (codec_clk) {
 			clk_set_rate(codec_clk, TABLA_EXT_CLK_RATE);
 			clk_enable(codec_clk);
-			tabla_mclk_enable(codec, 1);
+			tabla_mclk_enable(codec, 1, dapm);
 		} else {
 			pr_err("%s: Error setting Tabla MCLK\n", __func__);
 			clk_users--;
@@ -324,7 +337,7 @@
 			pr_debug("%s: disabling MCLK. clk_users = %d\n",
 					 __func__, clk_users);
 			clk_disable(codec_clk);
-			tabla_mclk_enable(codec, 0);
+			tabla_mclk_enable(codec, 0, dapm);
 		}
 	}
 	return 0;
@@ -337,9 +350,9 @@
 
 	switch (event) {
 	case SND_SOC_DAPM_PRE_PMU:
-		return mdm9615_enable_codec_ext_clk(w->codec, 1);
+		return mdm9615_enable_codec_ext_clk(w->codec, 1, true);
 	case SND_SOC_DAPM_POST_PMD:
-		return mdm9615_enable_codec_ext_clk(w->codec, 0);
+		return mdm9615_enable_codec_ext_clk(w->codec, 0, true);
 	}
 	return 0;
 }
@@ -742,11 +755,10 @@
 		return err;
 	}
 	codec_clk = clk_get(cpu_dai->dev, "osr_clk");
-	tabla_hs_detect(codec, &hs_jack, &button_jack, tabla_mbhc_cal,
-			TABLA_MICBIAS2, mdm9615_enable_codec_ext_clk, 0,
-			TABLA_EXT_CLK_RATE);
 
-	return 0;
+	err = tabla_hs_detect(codec, &mbhc_cfg);
+
+	return err;
 }
 
 static struct snd_soc_dsp_link fe_media = {
@@ -1185,8 +1197,8 @@
 		return -ENODEV ;
 	}
 
-	tabla_mbhc_cal = def_tabla_mbhc_cal();
-	if (!tabla_mbhc_cal) {
+	mbhc_cfg.calibration = def_tabla_mbhc_cal();
+	if (!mbhc_cfg.calibration) {
 		pr_err("Calibration data allocation failed\n");
 		return -ENOMEM;
 	}
@@ -1194,7 +1206,7 @@
 	mdm9615_snd_device = platform_device_alloc("soc-audio", 0);
 	if (!mdm9615_snd_device) {
 		pr_err("Platform device allocation failed\n");
-		kfree(tabla_mbhc_cal);
+		kfree(mbhc_cfg.calibration);
 		return -ENOMEM;
 	}
 
@@ -1206,7 +1218,7 @@
 	ret = platform_device_add(mdm9615_snd_device);
 	if (ret) {
 		platform_device_put(mdm9615_snd_device);
-		kfree(tabla_mbhc_cal);
+		kfree(mbhc_cfg.calibration);
 		return ret;
 	}
 
@@ -1229,7 +1241,7 @@
 	}
 	mdm9615_free_headset_mic_gpios();
 	platform_device_unregister(mdm9615_snd_device);
-	kfree(tabla_mbhc_cal);
+	kfree(mbhc_cfg.calibration);
 }
 module_exit(mdm9615_audio_exit);