summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorManoj Gangwal <mgangwal@nvidia.com>2012-02-13 15:11:09 +0530
committerSimone Willett <swillett@nvidia.com>2012-02-16 13:36:03 -0800
commite675c8ad5198d05b3bdda0a6a73d1ebdc303d1ca (patch)
treed7de0a6b9d4792f962ee4aed8d541252cdd47a36 /sound
parentac8422116d898566c0892ce2faf32b59e76e1f33 (diff)
asoc: tegra: ALC5640 machine: Add support for HP detect
Add support for Headphone detect on Kai. Bug 928046 Change-Id: Ieffb3aed32e57ca3e43f6a1c8d049ac1b433867f Signed-off-by: Manoj Gangwal <mgangwal@nvidia.com> Reviewed-on: http://git-master/r/83408 Reviewed-by: Simone Willett <swillett@nvidia.com> Tested-by: Simone Willett <swillett@nvidia.com>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/tegra/tegra_rt5640.c57
1 files changed, 57 insertions, 0 deletions
diff --git a/sound/soc/tegra/tegra_rt5640.c b/sound/soc/tegra/tegra_rt5640.c
index 8735c149ba40..2f1cee297c6b 100644
--- a/sound/soc/tegra/tegra_rt5640.c
+++ b/sound/soc/tegra/tegra_rt5640.c
@@ -268,6 +268,45 @@ enum headset_state {
static struct switch_dev tegra_rt5640_headset_switch = {
.name = "h2w1",
};
+
+static int tegra_rt5640_jack_notifier(struct notifier_block *self,
+ unsigned long action, void *dev)
+{
+ struct snd_soc_jack *jack = dev;
+ struct snd_soc_codec *codec = jack->codec;
+ struct snd_soc_card *card = codec->card;
+ struct tegra_rt5640 *machine = snd_soc_card_get_drvdata(card);
+ enum headset_state state = BIT_NO_HEADSET;
+
+ if (jack == &tegra_rt5640_hp_jack) {
+ machine->jack_status &= ~SND_JACK_HEADPHONE;
+ machine->jack_status |= (action & SND_JACK_HEADPHONE);
+ } else {
+ machine->jack_status &= ~SND_JACK_MICROPHONE;
+ machine->jack_status |= (action & SND_JACK_MICROPHONE);
+ }
+
+ switch (machine->jack_status) {
+ case SND_JACK_HEADPHONE:
+ state = BIT_HEADSET_NO_MIC;
+ break;
+ case SND_JACK_HEADSET:
+ state = BIT_HEADSET;
+ break;
+ case SND_JACK_MICROPHONE:
+ /* mic: would not report */
+ default:
+ state = BIT_NO_HEADSET;
+ }
+
+ switch_set_state(&tegra_rt5640_headset_switch, state);
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block tegra_rt5640_jack_detect_nb = {
+ .notifier_call = tegra_rt5640_jack_notifier,
+};
#else
static struct snd_soc_jack_pin tegra_rt5640_hp_jack_pins[] = {
{
@@ -449,6 +488,24 @@ static int tegra_rt5640_init(struct snd_soc_pcm_runtime *rtd)
gpio_direction_output(pdata->gpio_ext_mic_en, 0);
}
+ if (gpio_is_valid(pdata->gpio_hp_det)) {
+ tegra_rt5640_hp_jack_gpio.gpio = pdata->gpio_hp_det;
+ snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE,
+ &tegra_rt5640_hp_jack);
+#ifndef CONFIG_SWITCH
+ snd_soc_jack_add_pins(&tegra_rt5640_hp_jack,
+ ARRAY_SIZE(tegra_rt5640_hp_jack_pins),
+ tegra_rt5640_hp_jack_pins);
+#else
+ snd_soc_jack_notifier_register(&tegra_rt5640_hp_jack,
+ &tegra_rt5640_jack_detect_nb);
+#endif
+ snd_soc_jack_add_gpios(&tegra_rt5640_hp_jack,
+ 1,
+ &tegra_rt5640_hp_jack_gpio);
+ machine->gpio_requested |= GPIO_HP_DET;
+ }
+
ret = snd_soc_add_controls(codec, cardhu_controls,
ARRAY_SIZE(cardhu_controls));
if (ret < 0)