alsa-devel.alsa-project.org archive mirror
 help / color / mirror / Atom feed
From: Curtis Malainey <cujomalainey@chromium.org>
To: alsa-devel@alsa-project.org
Cc: Oder Chiou <oder_chiou@realtek.com>,
	Takashi Iwai <tiwai@suse.com>,
	Liam Girdwood <lgirdwood@gmail.com>,
	Ben Zhang <benzh@chromium.org>, Mark Brown <broonie@kernel.org>,
	Bard Liao <bardliao@realtek.com>,
	Curtis Malainey <cujomalainey@chromium.org>
Subject: [alsa-devel] [RFC 13/15] ASoC: rt5677: Disable irq at suspend
Date: Fri,  6 Sep 2019 12:46:35 -0700	[thread overview]
Message-ID: <20190906194636.217881-14-cujomalainey@chromium.org> (raw)
In-Reply-To: <20190906194636.217881-1-cujomalainey@chromium.org>

From: Ben Zhang <benzh@chromium.org>

The irq is disabled at suspend to avoid running the threaded irq
handler after the codec has been powered off. At resume, codec irq is
re-enabled and the interrupt status register is checked to see if
headphone has been pluggnd/unplugged while the device is suspended.

There is still a chance that the headphone gets enabled or disabled
after the codec is suspended. disable_irq syncs the threaded irq
handler, but soc-jack's threaded irq handler schedules a delayed
work to poll gpios (for debounce). This is still OK. The codec won't
be powered back on again because all audio paths have been suspended,
and there are no force enabled supply widgets (MICBIAS1 is disabled).
The gpio status read after codec power off could be wrong, so the
gpio values are checked again after resume.

Signed-off-by: Ben Zhang <benzh@chromium.org>
Signed-off-by: Curtis Malainey <cujomalainey@chromium.org>
---
 sound/soc/codecs/rt5677.c | 46 +++++++++++++++++++++++++++++++++++++++
 sound/soc/codecs/rt5677.h |  2 ++
 2 files changed, 48 insertions(+)

diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c
index 098dcbaa4539..a262a3dfbe2b 100644
--- a/sound/soc/codecs/rt5677.c
+++ b/sound/soc/codecs/rt5677.c
@@ -4993,6 +4993,11 @@ static int rt5677_suspend(struct snd_soc_component *component)
 {
 	struct rt5677_priv *rt5677 = snd_soc_component_get_drvdata(component);
 
+	if (rt5677->irq) {
+		cancel_delayed_work_sync(&rt5677->resume_irq_check);
+		disable_irq(rt5677->irq);
+	}
+
 	if (!rt5677->dsp_vad_en) {
 		regcache_cache_only(rt5677->regmap, true);
 		regcache_mark_dirty(rt5677->regmap);
@@ -5021,6 +5026,11 @@ static int rt5677_resume(struct snd_soc_component *component)
 		regcache_sync(rt5677->regmap);
 	}
 
+	if (rt5677->irq) {
+		enable_irq(rt5677->irq);
+		schedule_delayed_work(&rt5677->resume_irq_check, 0);
+	}
+
 	return 0;
 }
 #else
@@ -5419,6 +5429,39 @@ static irqreturn_t rt5677_irq(int unused, void *data)
 		return IRQ_NONE;
 }
 
+static void rt5677_resume_irq_check(struct work_struct *work)
+{
+	int i, virq;
+	struct rt5677_priv *rt5677 =
+		container_of(work, struct rt5677_priv, resume_irq_check.work);
+
+	/* This is needed to check and clear the interrupt status register
+	 * at resume. If the headset is plugged/unplugged when the device is
+	 * fully suspended, there won't be a rising edge at resume to trigger
+	 * the interrupt. Without this, we miss the next unplug/plug event.
+	 */
+	rt5677_irq(0, rt5677);
+
+	/* Call all enabled jack detect irq handlers again. This is needed in
+	 * addition to the above check for a corner case caused by jack gpio
+	 * debounce. After codec irq is disabled at suspend, the delayed work
+	 * scheduled by soc-jack may run and read wrong jack gpio values, since
+	 * the regmap is in cache only mode. At resume, there is no irq because
+	 * rt5677_irq has already ran and cleared the irq status at suspend.
+	 * Without this explicit check, unplug the headset right after suspend
+	 * starts, then after resume the headset is still shown as plugged in.
+	 */
+	mutex_lock(&rt5677->irq_lock);
+	for (i = 0; i < RT5677_IRQ_NUM; i++) {
+		if (rt5677->irq_en & rt5677_irq_descs[i].enable_mask) {
+			virq = irq_find_mapping(rt5677->domain, i);
+			if (virq)
+				handle_nested_irq(virq);
+		}
+	}
+	mutex_unlock(&rt5677->irq_lock);
+}
+
 static void rt5677_irq_bus_lock(struct irq_data *data)
 {
 	struct rt5677_priv *rt5677 = irq_data_get_irq_chip_data(data);
@@ -5494,6 +5537,7 @@ static int rt5677_init_irq(struct i2c_client *i2c)
 	}
 
 	mutex_init(&rt5677->irq_lock);
+	INIT_DELAYED_WORK(&rt5677->resume_irq_check, rt5677_resume_irq_check);
 
 	/*
 	 * Select RC as the debounce clock so that GPIO works even when
@@ -5539,6 +5583,8 @@ static int rt5677_init_irq(struct i2c_client *i2c)
 	if (ret)
 		dev_err(&i2c->dev, "Failed to request IRQ: %d\n", ret);
 
+	rt5677->irq = i2c->irq;
+
 	return ret;
 }
 
diff --git a/sound/soc/codecs/rt5677.h b/sound/soc/codecs/rt5677.h
index 046ed2ee8e31..f8ada967fdbc 100644
--- a/sound/soc/codecs/rt5677.h
+++ b/sound/soc/codecs/rt5677.h
@@ -1856,6 +1856,8 @@ struct rt5677_priv {
 	struct irq_domain *domain;
 	struct mutex irq_lock;
 	unsigned int irq_en;
+	struct delayed_work resume_irq_check;
+	int irq;
 
 	int (*set_dsp_vad)(struct snd_soc_component *component, bool on);
 };
-- 
2.23.0.187.g17f5b7556c-goog

_______________________________________________
Alsa-devel mailing list
Alsa-devel@alsa-project.org
https://mailman.alsa-project.org/mailman/listinfo/alsa-devel

  parent reply	other threads:[~2019-09-06 19:57 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-09-06 19:46 [alsa-devel] [RFC 00/15] Add Samus Hotwording for RT5677 Curtis Malainey
2019-09-06 19:46 ` [alsa-devel] [RFC 01/15] ASoC: rt5677: Remove magic number register writes Curtis Malainey
2019-09-09 10:07   ` [alsa-devel] Applied "ASoC: rt5677: Remove magic number register writes" to the asoc tree Mark Brown
2019-09-06 19:46 ` [alsa-devel] [RFC 02/15] ASoC: rt5677: keep analog power register at SND_SOC_BIAS_OFF Curtis Malainey
2019-09-09  9:54   ` Mark Brown
2019-09-09 15:50     ` Curtis Malainey
2019-09-09 12:23   ` [alsa-devel] Applied "ASoC: rt5677: keep analog power register at SND_SOC_BIAS_OFF" to the asoc tree Mark Brown
2019-09-06 19:46 ` [alsa-devel] [RFC 03/15] ASoC: rt5677: Add a PCM device for streaming hotword via SPI Curtis Malainey
2019-09-06 19:46 ` [alsa-devel] [RFC 04/15] ASoC: rt5677: Load firmware " Curtis Malainey
2019-09-11 10:24   ` Mark Brown
2019-09-06 19:46 ` [alsa-devel] [RFC 05/15] ASoC: rt5677: Auto enable/disable DSP for hotwording Curtis Malainey
2019-09-11 10:25   ` Mark Brown
2019-09-11 20:22     ` Curtis Malainey
2019-09-12  9:26       ` Mark Brown
2019-09-16 21:29         ` Curtis Malainey
2019-09-16 21:55           ` Mark Brown
2019-09-06 19:46 ` [alsa-devel] [RFC 06/15] ASoC: bdw-rt5677: Add a DAI link for rt5677 SPI PCM device Curtis Malainey
2019-09-09  0:18   ` Kuninori Morimoto
2019-09-09 16:53     ` Curtis Malainey
2019-09-06 19:46 ` [alsa-devel] [RFC 07/15] ASoC: rt5677: Enable jack detect while DSP is running Curtis Malainey
2019-09-06 19:46 ` [alsa-devel] [RFC 08/15] ASoC: rt5677: Use delayed work for DSP firmware load Curtis Malainey
2019-09-11 10:28   ` Mark Brown
2019-09-06 19:46 ` [alsa-devel] [RFC 09/15] ASoC: rt5677: Add DAPM audio path for hotword stream Curtis Malainey
2019-09-06 19:46 ` [alsa-devel] [RFC 10/15] ASoC: rt5677: Mark reg RT5677_PWR_ANLG2 as volatile Curtis Malainey
2019-09-06 19:46 ` [alsa-devel] [RFC 11/15] ASoC: rt5677: Stop and restart DSP over suspend/resume Curtis Malainey
2019-09-06 19:46 ` [alsa-devel] [RFC 12/15] ASoC: rt5677: Transfer one period at a time over SPI Curtis Malainey
2019-09-11 10:54   ` Mark Brown
2019-09-11 18:09     ` Curtis Malainey
2019-09-06 19:46 ` Curtis Malainey [this message]
2019-09-06 19:46 ` [alsa-devel] [RFC 14/15] ASoC: rt5677: Allow VAD to be shut on/off at all times Curtis Malainey
2019-09-06 19:46 ` [alsa-devel] [RFC 15/15] ASoC: rt5677: Turn on MCLK1 for DSP via DAPM Curtis Malainey
2019-09-06 20:40 ` [alsa-devel] [RFC 00/15] Add Samus Hotwording for RT5677 Pierre-Louis Bossart
2019-09-06 21:09   ` Curtis Malainey
2019-09-06 22:13     ` Pierre-Louis Bossart
2019-09-09 16:52       ` Curtis Malainey

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190906194636.217881-14-cujomalainey@chromium.org \
    --to=cujomalainey@chromium.org \
    --cc=alsa-devel@alsa-project.org \
    --cc=bardliao@realtek.com \
    --cc=benzh@chromium.org \
    --cc=broonie@kernel.org \
    --cc=lgirdwood@gmail.com \
    --cc=oder_chiou@realtek.com \
    --cc=tiwai@suse.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).