From e675c8ad5198d05b3bdda0a6a73d1ebdc303d1ca Mon Sep 17 00:00:00 2001 From: Manoj Gangwal Date: Mon, 13 Feb 2012 15:11:09 +0530 Subject: 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 Reviewed-on: http://git-master/r/83408 Reviewed-by: Simone Willett Tested-by: Simone Willett --- sound/soc/tegra/tegra_rt5640.c | 57 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) (limited to 'sound') 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) -- cgit v1.2.3