diff options
Diffstat (limited to 'sound/soc/codecs/sn95031.c')
-rw-r--r-- | sound/soc/codecs/sn95031.c | 56 |
1 files changed, 56 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 | ||
653 | static inline void sn95031_disable_jack_btn(struct snd_soc_codec *codec) | ||
654 | { | ||
655 | snd_soc_write(codec, SN95031_BTNCTRL2, 0x00); | ||
656 | } | ||
657 | |||
658 | static 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 | |||
664 | static 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 | |||
676 | void 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 | } | ||
706 | EXPORT_SYMBOL_GPL(sn95031_jack_detection); | ||
707 | |||
652 | /* codec registration */ | 708 | /* codec registration */ |
653 | static int sn95031_codec_probe(struct snd_soc_codec *codec) | 709 | static int sn95031_codec_probe(struct snd_soc_codec *codec) |
654 | { | 710 | { |