[alsa-devel] [PATCH] ASoC: rt5640: add headset detection function
![](https://secure.gravatar.com/avatar/c25a563f13eceaabae4e25797a415140.jpg?s=120&d=mm&r=g)
From: Bard Liao bardliao@realtek.com
Add headset detection function to rt5640 codec driver.
Signed-off-by: Bard Liao bardliao@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
![](https://secure.gravatar.com/avatar/d930951cb00393ecf9c3db3a56d78fa9.jpg?s=120&d=mm&r=g)
On Tue, Jul 23, 2013 at 02:54:29PM +0800, bardliao@realtek.com wrote:
- @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)
This doesn't look like it implements jack detection, it looks like it's some sort of callback. I'd expect to see some sort of interrupt for example...
What's going on here?
![](https://secure.gravatar.com/avatar/c25a563f13eceaabae4e25797a415140.jpg?s=120&d=mm&r=g)
-----Original Message----- From: Mark Brown [mailto:broonie@kernel.org] Sent: Tuesday, July 23, 2013 9:00 PM To: Bard Liao Cc: lgirdwood@gmail.com; alsa-devel@alsa-project.org; Flove; Oder Chiou Subject: Re: [PATCH] ASoC: rt5640: add headset detection function
On Tue, Jul 23, 2013 at 02:54:29PM +0800, bardliao@realtek.com wrote:
- @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)
This doesn't look like it implements jack detection, it looks like it's some sort of callback. I'd expect to see some sort of interrupt for example...
What's going on here?
Usually, our customers use cpu's gpio as the interrupt pin of jack insert/remove. So we assume they will handle the interrupt event in machine driver. When machine driver get a jack insert/remove event, it will call this function to know the jack type(headset or headphone). Should I handle the interrupt event in codec driver?
------Please consider the environment before printing this e-mail.
![](https://secure.gravatar.com/avatar/d930951cb00393ecf9c3db3a56d78fa9.jpg?s=120&d=mm&r=g)
On Thu, Jul 25, 2013 at 11:36:42AM +0800, Bard Liao wrote:
Usually, our customers use cpu's gpio as the interrupt pin of jack insert/remove. So we assume they will handle the interrupt event in machine driver. When machine driver get a jack insert/remove event, it will call this function to know the jack type(headset or headphone). Should I handle the interrupt event in codec driver?
Yes, of course. Interrupts are just interrupts on Linux.
participants (3)
-
Bard Liao
-
bardliao@realtek.com
-
Mark Brown