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);