From aa6214d5c4f9e0e2aea9a3f923255bda29c2f447 Mon Sep 17 00:00:00 2001 From: Manjula Gupta Date: Wed, 6 Apr 2011 15:59:11 +0530 Subject: ASOC: tegra: Restore jack switch state after Suspend Adds a function to restore jack state after suspend, it will notify the upper layer about the current states of the jack after suspend. In suspend state the notifier function doesn't get triggered, leaving the system in an unknown state. This function will be called on resume after suspend. Fix for Bug: 804328 Change-Id: I89ab32a6d775904fb1a71725d4e1fbda89002431 Reviewed-on: http://git-master/r/26853 Reviewed-by: Sumit Bhattacharya Tested-by: Sumit Bhattacharya Reviewed-by: Boris Suvorov Tested-by: Boris Suvorov Reviewed-by: Varun Colbert --- sound/soc/tegra/tegra_i2s.c | 1 + sound/soc/tegra/tegra_soc.h | 1 + sound/soc/tegra/tegra_wired_jack.c | 28 ++++++++++++++++++++++------ 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/sound/soc/tegra/tegra_i2s.c b/sound/soc/tegra/tegra_i2s.c index 004384041e99..e460a76968f6 100644 --- a/sound/soc/tegra/tegra_i2s.c +++ b/sound/soc/tegra/tegra_i2s.c @@ -366,6 +366,7 @@ int tegra_i2s_resume(struct snd_soc_dai *cpu_dai) tegra_das_set_all_regs(&info->das_regs); i2s_set_all_regs(cpu_dai->id, &info->i2s_regs); + tegra_jack_resume(); return 0; } diff --git a/sound/soc/tegra/tegra_soc.h b/sound/soc/tegra/tegra_soc.h index 817aed035d89..8dd2efaa6d13 100644 --- a/sound/soc/tegra/tegra_soc.h +++ b/sound/soc/tegra/tegra_soc.h @@ -118,6 +118,7 @@ void tegra_controls_exit(void); int tegra_jack_init(struct snd_soc_codec *codec); void tegra_jack_exit(void); +void tegra_jack_resume(void); void tegra_switch_set_state(int state); void setup_i2s_dma_request(struct snd_pcm_substream *substream, diff --git a/sound/soc/tegra/tegra_wired_jack.c b/sound/soc/tegra/tegra_wired_jack.c index a3c5fa7afc08..211d69e45818 100644 --- a/sound/soc/tegra/tegra_wired_jack.c +++ b/sound/soc/tegra/tegra_wired_jack.c @@ -38,6 +38,14 @@ struct wired_jack_conf tegra_wired_jack_conf = { -1, -1, -1, -1, 0, NULL, NULL }; +/* Based on hp_gpio and mic_gpio, hp_gpio is active low */ +enum { + HEADSET_WITHOUT_MIC = 0x00, + HEADSET_WITH_MIC = 0x01, + NO_DEVICE = 0x10, + MIC = 0x11, +}; + /* jack */ static struct snd_soc_jack *tegra_wired_jack; @@ -83,7 +91,7 @@ void tegra_switch_set_state(int state) switch_set_state(&wired_switch_dev, state); } -static int wired_swith_notify(struct notifier_block *self, +static int wired_switch_notify(struct notifier_block *self, unsigned long action, void* dev) { int state = 0; @@ -97,6 +105,8 @@ static int wired_swith_notify(struct notifier_block *self, if (tegra_wired_jack_conf.cdc_irq != -1) mic_gpio = gpio_get_value(tegra_wired_jack_conf.cdc_irq); + pr_debug("hp_gpio:%d, mic_gpio:%d\n", hp_gpio, mic_gpio); + flag = (hp_gpio << 4) | mic_gpio; switch (action) { @@ -115,16 +125,16 @@ static int wired_swith_notify(struct notifier_block *self, break; default: switch (flag) { - case 0x010: + case NO_DEVICE: state = 0; break; - case 0x01: + case HEADSET_WITH_MIC: state = 1; break; - case 0x11: + case MIC: /* mic: would not report */ break; - case 0x00: + case HEADSET_WITHOUT_MIC: state = 2; break; default: @@ -137,8 +147,14 @@ static int wired_swith_notify(struct notifier_block *self, return NOTIFY_OK; } + +void tegra_jack_resume(void) +{ + wired_switch_notify(NULL, SND_JACK_NO_TYPE_SPECIFIED, NULL); +} + static struct notifier_block wired_switch_nb = { - .notifier_call = wired_swith_notify, + .notifier_call = wired_switch_notify, }; #endif -- cgit v1.2.3