aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/soc/codecs/sn95031.c56
-rw-r--r--sound/soc/codecs/sn95031.h9
2 files changed, 65 insertions, 0 deletions
diff --git a/sound/soc/codecs/sn95031.c b/sound/soc/codecs/sn95031.c
index 40e285df9ae5..b49d79017d3a 100644
--- a/sound/soc/codecs/sn95031.c
+++ b/sound/soc/codecs/sn95031.c
@@ -34,6 +34,7 @@
34#include <sound/soc-dapm.h> 34#include <sound/soc-dapm.h>
35#include <sound/initval.h> 35#include <sound/initval.h>
36#include <sound/tlv.h> 36#include <sound/tlv.h>
37#include <sound/jack.h>
37#include "sn95031.h" 38#include "sn95031.h"
38 39
39#define SN95031_RATES (SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_44100) 40#define SN95031_RATES (SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_44100)
@@ -649,6 +650,61 @@ struct snd_soc_dai_driver sn95031_dais[] = {
649}, 650},
650}; 651};
651 652
653static inline void sn95031_disable_jack_btn(struct snd_soc_codec *codec)
654{
655 snd_soc_write(codec, SN95031_BTNCTRL2, 0x00);
656}
657
658static inline void sn95031_enable_jack_btn(struct snd_soc_codec *codec)
659{
660 snd_soc_write(codec, SN95031_BTNCTRL1, 0x77);
661 snd_soc_write(codec, SN95031_BTNCTRL2, 0x01);
662}
663
664static int sn95031_get_headset_state(struct snd_soc_jack *mfld_jack)
665{
666 /* Defaulting to HEADSET for now.
667 * will change after adding soc-jack detection apis */
668 int jack_type = SND_JACK_HEADSET;
669
670 pr_debug("jack type detected = %d\n", jack_type);
671 if (jack_type == SND_JACK_HEADSET)
672 sn95031_enable_jack_btn(mfld_jack->codec);
673 return jack_type;
674}
675
676void sn95031_jack_detection(struct mfld_jack_data *jack_data)
677{
678 unsigned int status;
679 unsigned int mask = SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_HEADSET;
680
681 pr_debug("interrupt id read in sram = 0x%x\n", jack_data->intr_id);
682 if (jack_data->intr_id & 0x1) {
683 pr_debug("short_push detected\n");
684 status = SND_JACK_HEADSET | SND_JACK_BTN_0;
685 } else if (jack_data->intr_id & 0x2) {
686 pr_debug("long_push detected\n");
687 status = SND_JACK_HEADSET | SND_JACK_BTN_1;
688 } else if (jack_data->intr_id & 0x4) {
689 pr_debug("headset or headphones inserted\n");
690 status = sn95031_get_headset_state(jack_data->mfld_jack);
691 } else if (jack_data->intr_id & 0x8) {
692 pr_debug("headset or headphones removed\n");
693 status = 0;
694 sn95031_disable_jack_btn(jack_data->mfld_jack->codec);
695 } else {
696 pr_err("unidentified interrupt\n");
697 return;
698 }
699
700 snd_soc_jack_report(jack_data->mfld_jack, status, mask);
701 /*button pressed and released so we send explicit button release */
702 if ((status & SND_JACK_BTN_0) | (status & SND_JACK_BTN_1))
703 snd_soc_jack_report(jack_data->mfld_jack,
704 SND_JACK_HEADSET, mask);
705}
706EXPORT_SYMBOL_GPL(sn95031_jack_detection);
707
652/* codec registration */ 708/* codec registration */
653static int sn95031_codec_probe(struct snd_soc_codec *codec) 709static int sn95031_codec_probe(struct snd_soc_codec *codec)
654{ 710{
diff --git a/sound/soc/codecs/sn95031.h b/sound/soc/codecs/sn95031.h
index e2b17d908aeb..2dbae614bac2 100644
--- a/sound/soc/codecs/sn95031.h
+++ b/sound/soc/codecs/sn95031.h
@@ -96,4 +96,13 @@
96#define SN95031_SSR5 0x384 96#define SN95031_SSR5 0x384
97#define SN95031_SSR6 0x385 97#define SN95031_SSR6 0x385
98 98
99#define SN95031_AUDIO_GPIO_CTRL 0x070
100struct mfld_jack_data {
101 int intr_id;
102 int micbias_vol;
103 struct snd_soc_jack *mfld_jack;
104};
105
106extern void sn95031_jack_detection(struct mfld_jack_data *jack_data);
107
99#endif 108#endif