[alsa-devel] [PATCH] ASoC: rt5640: add headset detection function
bardliao at realtek.com
bardliao at realtek.com
Tue Jul 23 08:54:29 CEST 2013
From: Bard Liao <bardliao at realtek.com>
Add headset detection function to rt5640 codec driver.
Signed-off-by: Bard Liao <bardliao at realtek.com>
---
sound/soc/codecs/rt5640.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++
sound/soc/codecs/rt5640.h | 3 +++
2 files changed, 64 insertions(+)
diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c
index ce585e3..dc0d063 100644
--- a/sound/soc/codecs/rt5640.c
+++ b/sound/soc/codecs/rt5640.c
@@ -1911,6 +1911,67 @@ static int rt5640_resume(struct snd_soc_codec *codec)
#define rt5640_resume NULL
#endif
+/**
+ * rt5640_headset_detect - Detect headset.
+ * @codec: SoC audio codec device.
+ * @jack_insert: Jack insert or not.
+ *
+ * Detect whether is headset or not when jack inserted.
+ *
+ * Returns detect status.
+ */
+int rt5640_headset_detect(struct snd_soc_codec *codec,
+ struct snd_soc_jack *jack, int jack_insert)
+{
+ int jack_type = 0;
+ int sclk_src = 0;
+ int reg63, reg64;
+
+ if (jack_insert) {
+ reg63 = snd_soc_read(codec, RT5640_PWR_ANLG1);
+ reg64 = snd_soc_read(codec, RT5640_PWR_ANLG2);
+ if (SND_SOC_BIAS_OFF == codec->dapm.bias_level) {
+ snd_soc_write(codec, RT5640_PWR_ANLG1, 0xa814);
+ sclk_src = snd_soc_read(codec, RT5640_GLB_CLK) &
+ RT5640_SCLK_SRC_MASK;
+ snd_soc_update_bits(codec, RT5640_GLB_CLK,
+ RT5640_SCLK_SRC_MASK,
+ 0x2 << RT5640_SCLK_SRC_SFT);
+ }
+ snd_soc_update_bits(codec, RT5640_PWR_ANLG1,
+ RT5640_PWR_LDO2, RT5640_PWR_LDO2);
+ snd_soc_update_bits(codec, RT5640_PWR_ANLG2,
+ RT5640_PWR_MB1, RT5640_PWR_MB1);
+ snd_soc_update_bits(codec, RT5640_MICBIAS,
+ RT5640_MIC1_OVCD_MASK | RT5640_MIC1_OVTH_MASK |
+ RT5640_PWR_CLK25M_MASK | RT5640_PWR_MB_MASK,
+ RT5640_MIC1_OVCD_EN | RT5640_MIC1_OVTH_600UA |
+ RT5640_PWR_MB_PU | RT5640_PWR_CLK25M_PU);
+ snd_soc_update_bits(codec, RT5640_DUMMY1, 0x1, 0x1);
+ msleep(100);
+ if (snd_soc_read(codec, RT5640_IRQ_CTRL2) & 0x8)
+ jack_type = SND_JACK_HEADPHONE;
+ else
+ jack_type = SND_JACK_HEADSET;
+ snd_soc_update_bits(codec, RT5640_IRQ_CTRL2,
+ RT5640_MB1_OC_CLR, 0);
+ if (SND_SOC_BIAS_OFF == codec->dapm.bias_level)
+ snd_soc_update_bits(codec, RT5640_GLB_CLK,
+ RT5640_SCLK_SRC_MASK, sclk_src);
+ snd_soc_write(codec, RT5640_PWR_ANLG1, reg63);
+ snd_soc_write(codec, RT5640_PWR_ANLG2, reg64);
+ snd_soc_jack_report(jack, jack_type, SND_JACK_HEADSET);
+ } else {
+ snd_soc_update_bits(codec, RT5640_MICBIAS,
+ RT5640_MIC1_OVCD_MASK,
+ RT5640_MIC1_OVCD_DIS);
+ snd_soc_jack_report(jack, 0, jack->jack->type);
+ }
+
+ return jack_type;
+}
+EXPORT_SYMBOL_GPL(rt5640_headset_detect);
+
#define RT5640_STEREO_RATES SNDRV_PCM_RATE_8000_96000
#define RT5640_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8)
diff --git a/sound/soc/codecs/rt5640.h b/sound/soc/codecs/rt5640.h
index c48286d..263615b 100644
--- a/sound/soc/codecs/rt5640.h
+++ b/sound/soc/codecs/rt5640.h
@@ -2089,4 +2089,7 @@ struct rt5640_priv {
int dmic_en;
};
+int rt5640_headset_detect(struct snd_soc_codec *codec,
+ struct snd_soc_jack *jack, int jack_insert);
+
#endif
--
1.8.1.1.439.g50a6b54
More information about the Alsa-devel
mailing list